# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1261032463 -7200 # Node ID c8830336c85267f1aa875159edc03a7efbbefe72 Revision: 200949 Kit: 200951 diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_type_api/eap_type_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_type_api/eap_type_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,17 @@ + + + EAP Type API + Generic API for configuring EAP type plugins + c++ + wlaneapol + + + + + + + + yes + no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_type_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_type_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to +: EAP Type API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +../inc/EapType.h MW_LAYER_PLATFORM_EXPORT_PATH(EapType.h) +../inc/EapType.inl MW_LAYER_PLATFORM_EXPORT_PATH(EapType.inl) +../inc/EapSettings.h MW_LAYER_PLATFORM_EXPORT_PATH(EapSettings.h) +../inc/EapSettings.inl MW_LAYER_PLATFORM_EXPORT_PATH(EapSettings.inl) +../inc/EapTypeInfo.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTypeInfo.h) diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_type_api/inc/EapSettings.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_type_api/inc/EapSettings.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,175 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// Refer the document S60_3_1_EAP_Symbian_Adaptation_Design_C.doc for more +// details of using EAPSettings. Refer section 9.2 for code samples. + +#ifndef EAP_SETTINGS_H +#define EAP_SETTINGS_H + +const TUint KGeneralStringMaxLength = 255; +const TUint KKeyIdentifierLength = 255; +const TUint KThumbprintMaxLength = 64; + +class CertificateEntry +{ +public: + + CertificateEntry(); + + enum TCertType { + EUser, + ECA + }; + + // Specifies whether this entry describes user or CA certificate (mandatory) + TCertType iCertType; + + // Subject name in distinguished name ASCII form. This is optional. + // For example "/C=US/O=Some organization/CN=Some common name". + TBool iSubjectNamePresent; + TBuf iSubjectName; + + // Issuer name in distinguished name ASCII form. This is optional. + // For example "/C=US/O=Some organization/CN=Some common name". + TBool iIssuerNamePresent; + TBuf iIssuerName; + + // Serial number in ASCII form. This is optional. + TBool iSerialNumberPresent; + TBuf iSerialNumber; + + // Subject key in binary form. This is mandatory. + TBool iSubjectKeyIDPresent; + TBuf8 iSubjectKeyID; + + // Thumbprint in binary form. This is optional. + TBool iThumbprintPresent; + TBuf iThumbprint; +}; + +class EAPSettings : public CBase +{ +public: + + EAPSettings(); + + enum TEapType + { + EEapNone = 0, + EEapGtc = 6, + EEapTls = 13, + EEapLeap = 17, + EEapSim = 18, + EEapTtls = 21, + EEapAka = 23, + EEapPeap = 25, + EEapMschapv2 = 26, + EEapSecurid = 32, + EEapFast = 43, + ETtlsPlainPap = 98, + EPlainMschapv2 = 99 + }; + + // Specifies the EAP type these settings are for. + // Is not really needed but is here so just some sanity checks can be made + TEapType iEAPType; + + // Username in ASCII format + TBool iUsernamePresent; + TBuf iUsername; + + // Password in ASCII format + TBool iPasswordPresent; + TBuf iPassword; + + // Realm in ASCII format + TBool iRealmPresent; + TBuf iRealm; + + // Use pseudonym identities in EAP-SIM/AKA + TBool iUsePseudonymsPresent; + TBool iUsePseudonyms; + + // Whether EAP-TLS/TTLS/PEAP should verify server realm + TBool iVerifyServerRealmPresent; + TBool iVerifyServerRealm; + + // Whether EAP-TLS/TTLS/PEAP should require client authentication + TBool iRequireClientAuthenticationPresent; + TBool iRequireClientAuthentication; + + // General session validity time (in minutes) + TBool iSessionValidityTimePresent; + TUint iSessionValidityTime; + + // An array of allowed cipher suites for EAP-TLS/TTLS/PEAP. + // Refer to RFC2246 chapter A.5 for the values. + TBool iCipherSuitesPresent; + RArray iCipherSuites; + + // In EAP-PEAP is version 0 allowed + TBool iPEAPVersionsPresent; + TBool iPEAPv0Allowed; + TBool iPEAPv1Allowed; + TBool iPEAPv2Allowed; + + // Array listing the allowed certificates for EAP-TLS/TTLS/PEAP. + // Subject key ID and Certificate type are the only mandatory certificate + // details needed at the moment. + TBool iCertificatesPresent; + CArrayFixFlat iCertificates; + + // Array listing the encapsulated EAP types (in priority order). + // Use EAP type values from TEapType. + TBool iEncapsulatedEAPTypesPresent; + RArray iEncapsulatedEAPTypes; + + // Whether Authenticated provisioning mode allowed or not in EAP-FAST. + TBool iAuthProvModeAllowedPresent; + TBool iAuthProvModeAllowed; + + // Whether Unauthenticated provisioning mode allowed or not in EAP-FAST. + TBool iUnauthProvModeAllowedPresent; + TBool iUnauthProvModeAllowed; + + // PAC group reference in ASCII format for EAP-FAST. + TBool iPACGroupReferencePresent; + TBuf iPACGroupReference; + + // Whether to Warn (or Prompt) for ADHP (Authenticated Diffie-Hellman Protocol) + // auto-provisioning when there is no PAC at all. EAP-FAST specific. + TBool iWarnADHPNoPACPresent; + TBool iWarnADHPNoPAC; + + // Whether to Warn (or Prompt) for ADHP auto-provisioning when + // there is no PAC that matches the A-ID sent by server. EAP-FAST specific. + TBool iWarnADHPNoMatchingPACPresent; + TBool iWarnADHPNoMatchingPAC; + + // Whether to Warn (or Prompt) when client encouters a server that has provisioned + // the client with a PAC before but is not currently selected as the default server. + // EAP-FAST specific. + TBool iWarnNotDefaultServerPresent; + TBool iWarnNotDefaultServer; +}; + +#include "EapSettings.inl" + +#endif +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_type_api/inc/EapSettings.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_type_api/inc/EapSettings.inl Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +inline CertificateEntry::CertificateEntry() +: iCertType(ECA) +, iSubjectNamePresent(EFalse) +, iIssuerNamePresent(EFalse) +, iSerialNumberPresent(EFalse) +, iSubjectKeyIDPresent(EFalse) +, iThumbprintPresent(EFalse) +{ +} + +inline EAPSettings::EAPSettings() +: iUsernamePresent(EFalse) +, iPasswordPresent(EFalse) +, iRealmPresent(EFalse) +, iVerifyServerRealmPresent(EFalse) +, iRequireClientAuthenticationPresent(EFalse) +, iSessionValidityTimePresent(EFalse) +, iCipherSuitesPresent(EFalse) +, iCipherSuites(1) +, iPEAPVersionsPresent(EFalse) +, iCertificatesPresent(EFalse) +, iCertificates(1) +, iEncapsulatedEAPTypesPresent(EFalse) +, iEncapsulatedEAPTypes(1) +{ +} + +// end of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_type_api/inc/EapType.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_type_api/inc/EapType.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,222 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPTYPE_H_ +#define _EAPTYPE_H_ + +// INCLUDES +#include +#include + +#include + +// FORWARD DECLARATIONS +class abs_eap_am_tools_c; +class eap_base_type_c; +class abs_eap_base_type_c; +class CEapTypeInfo; +class eap_am_network_id_c; + +#ifndef RD_WLAN_3_1_BACKPORTING +class abs_eap_configuration_if_c; +#endif + +// LOCAL DATA +// The UID for EAP plugin interface. ECom uses this. +const TUid KEapTypeInterfaceUid = {0x101f8e4a}; + +/// Possible services. +enum TIndexType +{ + EDialoutISP, + EDialinISP, + EOutgoingGPRS, + ELan, + EVpn +}; + +struct SIapInfo { + TIndexType indexType; + TInt index; +}; + +// CLASS DECLARATION + +/** +* The base interface class for EAP plug-in access. +* Includes methods to create either the configuration interface or the EAP protocol interface. +*/ +class CEapType : public CBase +{ +public: + + /** + * Factory function that loads the EAP type implementation DLL (plug-in). + * Uses ECom architecture to load the correct EAP type DLL. Calls the initialization + * function of the EAP type + * @param aCue EAP type id that specifies which plugin is loaded. + * @param aIndexType Indicates the bearer used for this connection. + * @param aIndex Index for the connection. aIndexType and aIndex uniquely specify the connection. + * @return Pointer to the implementation. + */ + inline static CEapType* NewL(const TDesC8& aCue, TIndexType aIndexType, TInt aIndex); + + /** + * Unloads the implementation DLL. + */ + inline virtual ~CEapType(); + +#ifndef RD_WLAN_3_1_BACKPORTING + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @param eap_config_if Pointer used for call back to creater of stack (eapol_am_wlan_authentication_symbian_c class). + * @return Pointer to the implementation. + */ + virtual eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if) = 0; + +#else + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @return Pointer to the implementation. + */ + + virtual eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + +#endif // #ifndef RD_WLAN_3_1_BACKPORTING + + /** + * Invokes the configuration UI. Displays a dialog for configuring the EAP type settings. + */ + virtual TInt InvokeUiL() = 0; + + /** + * Gets information about EAP type. + * @return Pointer to a class that contains the EAP type information. Also pushed to cleanup stack. + */ + virtual CEapTypeInfo* GetInfoLC() = 0; + + /** + * Deletes EAP type configuration + */ + virtual void DeleteConfigurationL() = 0; + + /** + * Returns the version of the interface that the EAP type implements. + * The client-side of the interface must always check the version with this function + * and not call the functions that are not implemented. New functions must be + * added to the end of the interface so that the order of the old functions + * does not change. + * @return Integer indicating the version. + */ + virtual TUint GetInterfaceVersion() = 0; + + /** + * Parses the opaque_data field in CImplementationInformation and returns true if + * string NOT_OUTSIDE_PEAP is found. + * @param aImplInfo Implementation info returned by ListImplementations call + * @return Boolean + */ + inline static TBool IsDisallowedOutsidePEAP(const CImplementationInformation& aImplInfo); + + /** + * Parses the opaque_data field in CImplementationInformation and returns true if + * string NOT_INSIDE_PEAP is found. + * @param aImplInfo Implementation info returned by ListImplementations call + * @return Boolean + */ + inline static TBool IsDisallowedInsidePEAP(const CImplementationInformation& aImplInfo); + + /** + * Parses the opaque_data field in CImplementationInformation and returns true if + * string NOT_INSIDE_TTLS is found. + * @param aImplInfo Implementation info returned by ListImplementations call + * @return Boolean + */ + inline static TBool IsDisallowedInsideTTLS(const CImplementationInformation& aImplInfo); + + /** + * Sets the tunneling type. This is used to indicate that this type is run inside another + * EAP type. + * @param aTunnelingType Type number for the tunneling type + */ + virtual void SetTunnelingType(const TInt aTunnelingType) = 0; + + /** + * Changes the index of the saved parameters. + * @param aIndexType Indicates the bearer used for this connection. + * @param aIndex Index for the connection. aIndexType and aIndex uniquely specify the connection. + */ + virtual void SetIndexL( + const TIndexType aIndexType, + const TInt aIndex) = 0; + + /** + * Sets the EAP types configuration + * @param aSettings Structure containing the settings + */ + virtual void SetConfigurationL(const EAPSettings& aSettings) = 0; + + /** + * Gets the EAP types configuration + * @param aSettings Structure containing the settings + */ + virtual void GetConfigurationL(EAPSettings& aSettings) = 0; + + /** + * Copies the EAP types configuration + * @param aDestinationIndexType index type of the destination, ELan for WLAN. + * @param aDestinationIndex ID to where copy the settings. + */ + virtual void CopySettingsL( + const TIndexType aDestinationIndexType, + const TInt aDestinationIndex) = 0; + + +private: + + /// ECom uses this key to keep track of DLL usage. + TUid iDtor_ID_Key; +}; + +#include "EapType.inl" + +#endif // _EAPTYPE_H_ + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_type_api/inc/EapType.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_type_api/inc/EapType.inl Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,131 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +/* The meaning and bit positions used in "opaque_data" field in ECOM implementation + + 0 0 0 0 0 0 0 0 ---->All 0 means allowed both inside (encapsulated EAP) and outside (Outer EAP) + | | | | | | | | + | | | | | | | |_____ 1 means NOT_INSIDE_TUNNEL (NOT allowed as encapsulated EAP) + | | | | | | | + | | | | | | |_______ 1 means NOT_OUTSIDE_TUNNEL (only allowed as encapsulated EAP, NOT as outer EAP) + | | | | | | + | | | | | |_________ 1 means NOT_INSIDE_PEAP + | | | | | + | | | | |___________ 1 means NOT_OUTSIDE_PEAP + | | | | + | | | |_____________ 1 means NOT_INSIDE_TTLS + | | | + | | |_______________ 1 means NOT_OUTSIDE_TTLS + | | + | |_________________ 1 means NOT_INSIDE_FAST + | + |___________________ 1 means NOT_OUTSIDE_FAST + + + // For historical reasons NOT_OUTSIDE_PEAP is used instead of NOT_OUTSIDE_TUNNEL + // Both of these convey the same meaning. It means if an EAP is not allowed outside PEAP + // (DisallowedOutsidePEAP), it can be used only as an encapsulated EAP. + // EAP-MSCHAPv2 is an example for this. + + // The bits can be ORed. + // "NOT_OUTSIDE|NOT_OUTSIDE_PEAP" is 0x0A (0000 1010). + // "NOT_OUTSIDE|NOT_OUTSIDE_PEAP|NOT_INSIDE_PEAP|NOT_INSIDE_FAST" is 0x4E (0100 1110). + // "NOT_INSIDE|NOT_INSIDE_PEAP|NOT_INSIDE_TTLS|NOT_INSIDE_FAST" is 0x55 (0101 0101). + // "NOT_INSIDE|NOT_INSIDE_PEAP|NOT_INSIDE_TTLS|NOT_INSIDE_FAST|NOT_OUTSIDE_PEAP|NOT_OUTSIDE" is 0x5F (0101 1111). + +*/ + + + +const TUint8 KNotInsideTunnel = 0x01; // Only the last bit position is 1. (0000 0001) +const TUint8 KNotOutsideTunnel = 0x02; // Only the 2nd last bit positions is 1. (0000 0010) + +const TUint8 KNotInsidePEAP = 0x04; // Only the 3rd last bit position is 1. (0000 0100) +const TUint8 KNotOutsidePEAP = 0x08; // Only the 4th last bit positions is 1. (0000 1000) + +const TUint8 KNotInsideTTLS = 0x10; // Only the 5th last bit position is 1. (0001 0000) +const TUint8 KNotOutsideTTLS = 0x20; // Only the 6th last bit position is 1. (0010 0000) + +const TUint8 KNotInsideFAST = 0x40; // Only the 7th last bit position is 1. (0100 0000) +const TUint8 KNotOutsideFAST = 0x80; // Only the first bit position is 1. (1000 0000) + + +inline CEapType* CEapType::NewL(const TDesC8& aCue, TIndexType aIndexType, TInt aIndex) +{ + // The EAP type id (aCue) is passed to ECom as resolver parameters + TEComResolverParams resolverParams; + resolverParams.SetDataType(aCue); + + // The arguments are stored to a iapInfo struct. + SIapInfo iapInfo; + iapInfo.indexType = aIndexType; + iapInfo.index = aIndex; + + // This call finds and loads the correct DLL and after that calls the + // entry function in the interface implementation in the DLL. + TAny* ptr = REComSession::CreateImplementationL( + KEapTypeInterfaceUid, + _FOFF(CEapType, iDtor_ID_Key), + &iapInfo, + resolverParams); + return (CEapType *) ptr; +} + +inline CEapType::~CEapType() +{ + // Unload DLL + REComSession::DestroyedImplementation(iDtor_ID_Key); +} + +inline TBool CEapType::IsDisallowedOutsidePEAP(const CImplementationInformation& aImplInfo) +{ + + const TUint8 pluginOpaqueData = *(aImplInfo.OpaqueData().Ptr()); + + if(pluginOpaqueData & KNotOutsidePEAP) + { + return ETrue; + } + return EFalse; + +} + +inline TBool CEapType::IsDisallowedInsidePEAP(const CImplementationInformation& aImplInfo) +{ + const TUint8 pluginOpaqueData = *(aImplInfo.OpaqueData().Ptr()); + + if(pluginOpaqueData & KNotInsidePEAP) + { + return ETrue; + } + return EFalse; + +} + +inline TBool CEapType::IsDisallowedInsideTTLS(const CImplementationInformation& aImplInfo) +{ + const TUint8 pluginOpaqueData = *(aImplInfo.OpaqueData().Ptr()); + + if(pluginOpaqueData & KNotInsideTTLS) + { + return ETrue; + } + return EFalse; +} + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_type_api/inc/EapTypeInfo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_type_api/inc/EapTypeInfo.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPTYPEINFO_H_ +#define _EAPTYPEINFO_H_ + +// INCLUDES +#include + +// LOCAL DATA +// This is the maximum length of the information strings. +const TUint KMaxInfoStringLength = 32; + +// CLASS DECLARATION +/** +* Class for storing and transferring the EAP type informational parameters. +*/ +class CEapTypeInfo : public CBase +{ +public: + + /** + * Empty constructor + */ + CEapTypeInfo(); + /** + * Constructor that takes the info as arguments. + */ + CEapTypeInfo( + const TDesC& aReleaseDate, + const TDesC& aVersion, + const TDesC& aManufacturer); + /** + * Empty destructor. + */ + virtual ~CEapTypeInfo(); + /** + * Function for setting the info parameters + */ + void Set( + const TDesC& aReleaseDate, + const TDesC& aVersion, + const TDesC& aManufacturer); + /** + * Reads release date + */ + virtual const TDesC& ReleaseDate() const; + + /** + * Reads version + */ + virtual const TDesC& Version() const; + + /** + * Reads manufacturer + */ + virtual const TDesC& Manufacturer() const; + +private: + TBuf iReleaseDate; + TBufC iVersion; + TBufC iManufacturer; +}; + +#endif // _EAPTYPEINFO_H_ + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_vpn_api/eap_vpn_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_vpn_api/eap_vpn_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,17 @@ + + + EAP VPN API + Interface for VPN implementations to request EAP authentication services + c++ + wlaneapol + + + + + + + + yes + no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_vpn_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_vpn_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to +: EAP VPN API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +../inc/abs_eap_vpn_if.h MW_LAYER_PLATFORM_EXPORT_PATH(abs_eap_vpn_if.h) +../inc/eap_vpn_if.h MW_LAYER_PLATFORM_EXPORT_PATH(eap_vpn_if.h) +../inc/eap_vpn_if.inl MW_LAYER_PLATFORM_EXPORT_PATH(eap_vpn_if.inl) +../inc/eap_vpn_if_uids.h MW_LAYER_PLATFORM_EXPORT_PATH(eap_vpn_if_uids.h) + +// End diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_vpn_api/inc/abs_eap_vpn_if.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_vpn_api/inc/abs_eap_vpn_if.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef __EAPPLUGINCALLBACKINTERFACE_H__ +#define __EAPPLUGINCALLBACKINTERFACE_H__ + +// INCLUDES + +// Enums +enum TNotification +{ + ESuccess, + EFailure, + ECancelled, + EFailedCompletely, + ELogoff, + ENoResponse +}; + +/** + * Class: MAbsEapVpnInterface + * + * Description: This interface defines the callback functions required from the CEaplugin user + */ +class MAbsEapVpnInterface +{ + public: + /** + * Function: EapOutbound + * + * Description: Callback function, which returns an outbound EAP message + * + */ + virtual void EapOutboundL(HBufC8* aResponse) = 0; + + /** + * Function: IdentityResponse + * + * Description: Callback function, which returns identity + * + */ + virtual void EapIdentityResponseL(HBufC8* aIdentity) = 0; + + /** + * Function: EapSharedKey + * + * Description: Callback function, which returns a shared key established during EAP session + * + */ + virtual void EapSharedKeyL(HBufC8* aSharedKey) = 0; + + /** + * Function: EapIndication + * + * Description: Callback function, which returns notifications + * + * @param aNotification numeric notification + */ + virtual void EapIndication(TNotification aNotification) = 0; +}; +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_vpn_api/inc/eap_vpn_if.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_vpn_api/inc/eap_vpn_if.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,151 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef __EAPPLUGININTERFACE_H__ +#define __EAPPLUGININTERFACE_H__ + +// INCLUDES +#include +#include "eap_vpn_if_uids.h" + +class MAbsEapVpnInterface; + +class TAbsEapVpnInterfaceParams +{ + public: + MAbsEapVpnInterface* iCaller; + TBool iClient; +}; + +// FORWARD DECLARATIONS + +/** + * Class: CEapVpnInterface + * + * Description: Custom ECOM interface definition. This interface is used by + * clients to load eap_vpn_if instance and use the defined generic functions + */ +class CEapVpnInterface : + public CActive +{ +public: // Constructors and destructor + /** + * Function: NewL + * + * Description: Wraps ECom object instantitation. Will return the + * default interface implementation. + * + * Note: This is not a "normal" NewL method, since normally NewL + * methods are only defined for concrete classes. + * Note that also implementations of this interface + * provide NewL methods. They are the familiar NewL's, + * which create instance of classes. + */ + static CEapVpnInterface* NewL(MAbsEapVpnInterface* aCaller, TBool aClient); + + /** + * Function: NewL + * + * Description: Wraps ECom object instantitation. Will search for + * interface implementation, which matches to given + * aOperationName. + * + * @param aType name of requested implementation. (This is not the eap type!) + * Implementations advertise their "name" as specified + * in their resource file field + * IMPLEMENTATION_INFO::default_data. + * + * Note: This is not a "normal" NewL method, since normally NewL + * methods are only defined for concrete classes. + * Note that also implementations of this interface provide + * NewL methods. They are the familiar NewL's, which create + * instance of classes. + */ + static CEapVpnInterface* NewL(const TDesC8& aType, MAbsEapVpnInterface* aCaller, TBool aClient); + + /** + * Function: ~CEapVpnInterfaceImplementation + * + * Description: Destroy the object + */ + inline virtual ~CEapVpnInterface(); + +protected: + + CEapVpnInterface(); + +public: + + /** + * Function: StartL + * + * Description: Initializes the eap plugin + * + * @param aType name of requested eap type implementation. + * + */ + virtual TInt StartL(const TUint8 aEapType) = 0; + + /** + * Function: EapConfigure + * + * Description: Configures the eap plugin + * + * @param aManualUsername The username, if not zero + * @param aManualRealm The realm, if not zero + * @param aManualRealmPrefix The realm prefix, if not zero + * @param aHideInitialIdentity Scramble username, if true + * + */ + virtual TInt EapConfigure(TDesC8& aManualUsername, TDesC8& aManualRealm, TDesC8& aRealmPrefix, TBool aHideInitialIdentity) = 0; + + /** + * Function: QueryIdentity + * + * Description: Ask the identity + */ + virtual TInt QueryIdentity() = 0; + + /** + * Function: EapInbound + * + * Description: Handle incoming Eap message + * + * @param aMessage incoming eap message. + * + */ + virtual TInt EapInbound(const TDesC8& aMessage) = 0; + + virtual void RunL()=0; + virtual void DoCancel() = 0; + +private: + /** iDtor_ID_Key Instance identifier key. When instance of an + * implementation is created by ECOM framework, the + * framework will assign UID for it. The UID is used in + * destructor to notify framework that this instance is + * being destroyed and resources can be released. + */ + TUid iDtor_ID_Key; + }; + +// This includes the implementation of the instantiation functions and +// destructor +#include "eap_vpn_if.inl" + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_vpn_api/inc/eap_vpn_if.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_vpn_api/inc/eap_vpn_if.inl Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// Interface's (abstract base class's) static factory method implementation. +// Asks ECOM plugin framework to instantiate appropriate concret plugin +// implementation. +inline CEapVpnInterface* CEapVpnInterface::NewL(MAbsEapVpnInterface* aCaller, TBool aClient) + { + // Parameters for the implementation + TAbsEapVpnInterfaceParams params; + params.iCaller = aCaller; + params.iClient = aClient; + // Find implementation for our interface. + // - KCEapVpnInterfaceUid is the UID of our custom ECOM + // interface. + // - This call will leave, if the plugin architecture cannot find + // implementation. + // - The returned pointer points to one of our interface implementation + // instances. + TAny* interface = REComSession::CreateImplementationL ( + KCEapVpnInterfaceImplementationUid, _FOFF (CEapVpnInterface, iDtor_ID_Key), (TAny*) ¶ms); + + return reinterpret_cast (interface); + } + +// Interface's (abstract base class's) static factory method implementation. +// Asks ECOM plugin framework to instantiate appropriate concret plugin +// implementation. + inline CEapVpnInterface* CEapVpnInterface::NewL(const TDesC8& aType, MAbsEapVpnInterface* aCaller, TBool aClient) + { + TEComResolverParams resolverParams; + // Only one interface type + // Remove these lines and uncomment line resolverParams.SetDataType (aType); + // if you really have many possible intance types + // --------------------------------------- + (void) aType; + _LIT8 (KEapPluginText,"EAPVPNIF"); + resolverParams.SetDataType (KEapPluginText); + // --------------------------------------- + // +++++++++++++++++++++++++++++++++++++++ + //resolverParams.SetDataType (aType); + // +++++++++++++++++++++++++++++++++++++++ + resolverParams.SetWildcardMatch (ETrue); + + // Parameters for the implementation + TAbsEapVpnInterfaceParams params; + params.iCaller = aCaller; + params.iClient = aClient; + // Find implementation for our interface. + // - KCEapVpnInterfaceUid is the UID of our custom ECOM + // interface. It is defined in EComInterfaceDefinition.h + // - This call will leave, if the plugin architecture cannot find + // implementation. + // - The returned pointer points to one of our interface implementation + // instances. + TAny* interface = REComSession::CreateImplementationL (KCEapVpnInterfaceUid, + _FOFF (CEapVpnInterface, iDtor_ID_Key), (TAny*) ¶ms, resolverParams, KCEapVpnInterfaceResolverUid); + + return reinterpret_cast (interface); + } + +// Interface's (abstract base class's) destructor +inline CEapVpnInterface::~CEapVpnInterface() + { + // If in the NewL some memory is reserved for member data, it must be + // released here. This interface does not have any instance variables so + // no need to delete anything. + + // Inform the ECOM framework that this specific instance of the + // interface has been destroyed. + REComSession::DestroyedImplementation (iDtor_ID_Key); + } + +// Interface's (abstract base class's) constructor +inline CEapVpnInterface::CEapVpnInterface() +: CActive(CActive::EPriorityStandard) + { + iDtor_ID_Key.Uid(0); + } + +// End diff -r 000000000000 -r c8830336c852 accesssec_plat/eap_vpn_api/inc/eap_vpn_if_uids.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eap_vpn_api/inc/eap_vpn_if_uids.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + +#ifndef __EAPPLUGINUIDS_H__ +#define __EAPPLUGINUIDS_H__ + +const TUid KCEapVpnInterfaceUid = {0x10206999}; +const TUid KCEapVpnInterfaceImplementationUid = {0x1020699A}; +const TUid KCEapVpnInterfaceResolverUid = {0x1020699B}; + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapaka_db_api/eapaka_db_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapaka_db_api/eapaka_db_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,17 @@ + + + EAP-AKA DB API + Interface for the EAP-AKA UI to access the settings in the EAP-AKA DBMS database. + c++ + wlaneapol + + + + + + + + yes + no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/eapaka_db_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapaka_db_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to +: EAP-AKA DB API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +../inc/EapAkaUiAkaData.h MW_LAYER_PLATFORM_EXPORT_PATH(EapAkaUiAkaData.h) +../inc/EapAkaUiDataConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapAkaUiDataConnection.h) +../inc/EapAkaUiConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapAkaUiConnection.h) diff -r 000000000000 -r c8830336c852 accesssec_plat/eapaka_db_api/inc/EapAkaUiAkaData.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapaka_db_api/inc/EapAkaUiAkaData.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPAKAUIAKADATA_H_ +#define _EAPAKAUIAKADATA_H_ + +#include +#include + +const TInt KMaxLengthOfManualUsername = 255; +const TInt KMaxLengthOfManualRealm = 255; + +class CEapAkaUiAkaData : public CBase +{ +public: + + CEapAkaUiAkaData(); + + ~CEapAkaUiAkaData(); + + TDes& GetManualUsername(); + + TDes& GetManualRealm(); + + TBool * GetUseManualUsername(); + + TBool * GetUseManualRealm(); + +private: + + TBuf iManualUsername; + + TBuf iManualRealm; + + TBool iUseManualUsername; + + TBool iUseManualRealm; +}; + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapaka_db_api/inc/EapAkaUiConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapaka_db_api/inc/EapAkaUiConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPAKAUICONNECTION_H_ +#define _EAPAKAUICONNECTION_H_ + +#include +#include +#include +#include + +class CEapAkaUiDataConnection; + +class CEapAkaUiConnection : public CBase +{ + +public: + + CEapAkaUiConnection( + const TIndexType iIndexType, + const TInt iIndex, + const TInt iTunnelingType); + + ~CEapAkaUiConnection(); + + TInt Connect(); + + TInt Close(); + + CEapAkaUiDataConnection * GetDataConnection(); + + TIndexType GetIndexType(); + + TInt GetIndex(); + + TInt GetTunnelingType(); + + TInt GetDatabase(RDbNamedDatabase & aDatabase); + +protected: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // Tunneling type + TInt iTunnelingType; + + TBool iIsConnected; + + // database names, handlers etc... + + CEapAkaUiDataConnection * iDataConn; + + RDbNamedDatabase iDbNamedDatabase; + + RDbs iDbs; +}; + + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapaka_db_api/inc/EapAkaUiDataConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapaka_db_api/inc/EapAkaUiDataConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPAKAUIDATACONNECTION_H_ +#define _EAPAKAUIDATACONNECTION_H_ + +#include +class CEapAkaUiConnection; +class CEapAkaUiAkaData; + + +class CEapAkaUiDataConnection : public CBase +{ + +public: + + CEapAkaUiDataConnection(CEapAkaUiConnection * aUiConn); + + ~CEapAkaUiDataConnection(); + + TInt Open(); + + TInt GetData(CEapAkaUiAkaData ** aDataPtr); + + TInt Update(); + + TInt Close(); + +protected: + + TBool iIsOpened; + + CEapAkaUiConnection * iUiConn; + + RDbNamedDatabase iDatabase; + + RDbView iView; + + CDbColSet* iColSet; + + CEapAkaUiAkaData * iDataPtr; + +private: + + void FetchDataL(); +}; + + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapgtc_db_api/eapgtc_db_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapgtc_db_api/eapgtc_db_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,17 @@ + + + EAP-GTC DB API + Interface for the EAP-GTC UI to access the settings in the EAP-GTC DBMS database. + c++ + wlaneapol + + + + + + + + yes + no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/eapgtc_db_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapgtc_db_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to +: EAP-GTC DB API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +../inc/EapGtcUiConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapGtcUiConnection.h) +../inc/EapGtcUiGtcData.h MW_LAYER_PLATFORM_EXPORT_PATH(EapGtcUiGtcData.h) +../inc/EapGtcUiDataConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapGtcUiDataConnection.h) diff -r 000000000000 -r c8830336c852 accesssec_plat/eapgtc_db_api/inc/EapGtcUiConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapgtc_db_api/inc/EapGtcUiConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPGTCUICONNECTION_H_ +#define _EAPGTCUICONNECTION_H_ + +#include +#include +#include +#include + +class CEapGtcUiDataConnection; + +class CEapGtcUiConnection: public CBase +{ + +public: + + CEapGtcUiConnection( + const TIndexType iIndexType, + const TInt iIndex, + const TInt iTunnelingType); + + ~CEapGtcUiConnection(); + + TInt Connect(); + + TInt Close(); + + CEapGtcUiDataConnection * GetDataConnection(); + + TIndexType GetIndexType(); + + TInt GetIndex(); + + TInt GetTunnelingType(); + + TInt GetDatabase(RDbNamedDatabase & aDatabase); + +protected: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // Tunneling type + TInt iTunnelingType; + + TBool iIsConnected; + + // database names, handlers etc... + + CEapGtcUiDataConnection * iDataConn; + + RDbNamedDatabase iDbNamedDatabase; + + RDbs iDbs; +}; + + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapgtc_db_api/inc/EapGtcUiDataConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapgtc_db_api/inc/EapGtcUiDataConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPGTCUIDATACONNECTION_H_ +#define _EAPGTCUIDATACONNECTION_H_ + +#include + +class CEapGtcUiConnection; +class CEapGtcUiGtcData; + + +class CEapGtcUiDataConnection : public CBase +{ + +public: + + CEapGtcUiDataConnection(CEapGtcUiConnection * aUiConn); + + ~CEapGtcUiDataConnection(); + + TInt Open(); + + TInt GetData(CEapGtcUiGtcData ** aDataPtr); + + TInt Update(); + + TInt Close(); + +protected: + + TBool iIsOpened; + + CEapGtcUiConnection * iUiConn; + + RDbNamedDatabase iDatabase; + + RDbView iView; + + CDbColSet* iColSet; + + CEapGtcUiGtcData * iDataPtr; + +private: + + void FetchDataL(); +}; + + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapgtc_db_api/inc/EapGtcUiGtcData.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapgtc_db_api/inc/EapGtcUiGtcData.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPGTCUIGTCDATA_H_ +#define _EAPGTCUIGTCDATA_H_ + +#include +#include + +const TInt KMaxLengthOfUsername=255; + +class CEapGtcUiGtcData : public CBase +{ +public: + + CEapGtcUiGtcData(); + + ~CEapGtcUiGtcData(); + + TDes& GetIdentity(); + +private: + + TBuf iIdentity; +}; + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapleap_db_api/eapleap_db_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapleap_db_api/eapleap_db_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,17 @@ + + + LEAP DB API + Interface for the LEAP UI to access the settings in the LEAP DBMS database + c++ + wlaneapol + + + + + + + + yes + no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/eapleap_db_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapleap_db_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to +: EAP-LEAP DB API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +../inc/EapLeapUiDataConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapLeapUiDataConnection.h) +../inc/EapLeapUiLeapData.h MW_LAYER_PLATFORM_EXPORT_PATH(EapLeapUiLeapData.h) +../inc/EapLeapUiConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapLeapUiConnection.h) diff -r 000000000000 -r c8830336c852 accesssec_plat/eapleap_db_api/inc/EapLeapUiConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapleap_db_api/inc/EapLeapUiConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,79 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPLEAPUICONNECTION_H_ +#define _EAPLEAPUICONNECTION_H_ + +#include +#include +#include +#include + + +class CEapLeapUiDataConnection; + +class CEapLeapUiConnection : public CBase +{ + +public: + + CEapLeapUiConnection( + const TIndexType iIndexType, + const TInt iIndex, + const TInt iTunnelingType); + + ~CEapLeapUiConnection(); + + TInt Connect(); + + TInt Close(); + + CEapLeapUiDataConnection * GetDataConnection(); + + TIndexType GetIndexType(); + + TInt GetIndex(); + + TInt GetTunnelingType(); + + TInt GetDatabase(RDbNamedDatabase & aDatabase); + +protected: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // Tunneling type + TInt iTunnelingType; + + TBool iIsConnected; + + // database names, handlers etc... + + CEapLeapUiDataConnection * iDataConn; + + RDbNamedDatabase iDbNamedDatabase; + + RDbs iDbs; +}; + + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapleap_db_api/inc/EapLeapUiDataConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapleap_db_api/inc/EapLeapUiDataConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPLEAPUIDATACONNECTION_H_ +#define _EAPLEAPUIDATACONNECTION_H_ + +#include + +class CEapLeapUiConnection; +class CEapLeapUiLeapData; + + +class CEapLeapUiDataConnection : public CBase +{ + +public: + + CEapLeapUiDataConnection(CEapLeapUiConnection * aUiConn); + + ~CEapLeapUiDataConnection(); + + TInt Open(); + + TInt GetData(CEapLeapUiLeapData ** aDataPtr); + + TInt Update(); + + TInt Close(); + +protected: + + TBool iIsOpened; + + CEapLeapUiConnection * iUiConn; + + RDbNamedDatabase iDatabase; + + RDbView iView; + + CDbColSet* iColSet; + + CEapLeapUiLeapData * iDataPtr; + +private: + + void FetchDataL(); +}; + + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapleap_db_api/inc/EapLeapUiLeapData.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapleap_db_api/inc/EapLeapUiLeapData.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPLEAPUILEAPDATA_H_ +#define _EAPLEAPUILEAPDATA_H_ + +#include +#include + +const TInt KMaxLengthOfUsername=255; +const TInt KMaxLengthOfPassword=255; + +class CEapLeapUiLeapData : public CBase +{ +public: + + CEapLeapUiLeapData(); + + ~CEapLeapUiLeapData(); + + TDes& GetUsername(); + + TDes& GetPassword(); + + TBool * GetPasswordPrompt(); + +private: + + TBuf iUsername; + + TBuf iPassword; + + TBool iPasswordPrompt; +}; + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapmschapv2_db_api/eapmschapv2_db_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapmschapv2_db_api/eapmschapv2_db_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,17 @@ + + + EAP-MSCHAPV2 DB API + Interface for the EAP-MSCHAPv2 UI to access the settings in the EAP-MSCHAPv2 DBMS database + c++ + wlaneapol + + + + + + + + yes + no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/eapmschapv2_db_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapmschapv2_db_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to +: EAP-MSCHAPV2 DB API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +../inc/EapMsChapV2UiDataConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapMsChapV2UiDataConnection.h) +../inc/EapMsChapV2UiConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapMsChapV2UiConnection.h) +../inc/EapMsChapV2UiMsChapV2Data.h MW_LAYER_PLATFORM_EXPORT_PATH(EapMsChapV2UiMsChapV2Data.h) diff -r 000000000000 -r c8830336c852 accesssec_plat/eapmschapv2_db_api/inc/EapMsChapV2UiConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapmschapv2_db_api/inc/EapMsChapV2UiConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPMSCHAPV2UICONNECTION_H_ +#define _EAPMSCHAPV2UICONNECTION_H_ + +#include +#include +#include +#include + +class CEapMsChapV2UiDataConnection; + +class CEapMsChapV2UiConnection : public CBase +{ + +public: + + CEapMsChapV2UiConnection( + const TIndexType aIndexType, + const TInt aIndex, + const TInt aTunnelingType, + const TInt aEAPType); + + ~CEapMsChapV2UiConnection(); + + TInt Connect(); + + TInt Close(); + + CEapMsChapV2UiDataConnection * GetDataConnection(); + + TIndexType GetIndexType(); + + TInt GetIndex(); + + TInt GetTunnelingType(); + + TInt GetDatabase(RDbNamedDatabase & aDatabase); + + TInt GetBearerEAPType(); + +protected: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // Tunneling type + TInt iTunnelingType; + + TBool iIsConnected; + + // database names, handlers etc... + + CEapMsChapV2UiDataConnection * iDataConn; + + RDbNamedDatabase iDbNamedDatabase; + + RDbs iDbs; + + // Holds the bearer EAP type. + TInt iEAPType; +}; + + +#endif + +// End of file + diff -r 000000000000 -r c8830336c852 accesssec_plat/eapmschapv2_db_api/inc/EapMsChapV2UiDataConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapmschapv2_db_api/inc/EapMsChapV2UiDataConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPMSCHAPV2UIDATACONNECTION_H_ +#define _EAPMSCHAPV2UIDATACONNECTION_H_ + +#include + +class CEapMsChapV2UiConnection; +class CEapMsChapV2UiMsChapV2Data; + + +class CEapMsChapV2UiDataConnection : public CBase +{ + +public: + + CEapMsChapV2UiDataConnection(CEapMsChapV2UiConnection * aUiConn); + + ~CEapMsChapV2UiDataConnection(); + + TInt Open(); + + TInt GetData(CEapMsChapV2UiMsChapV2Data ** aDataPtr); + + TInt Update(); + + TInt Close(); + +protected: + + TBool iIsOpened; + + CEapMsChapV2UiConnection * iUiConn; + + RDbNamedDatabase iDatabase; + + RDbView iView; + + CDbColSet* iColSet; + + CEapMsChapV2UiMsChapV2Data * iDataPtr; + +private: + + void FetchDataL(); +}; + + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapmschapv2_db_api/inc/EapMsChapV2UiMsChapV2Data.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapmschapv2_db_api/inc/EapMsChapV2UiMsChapV2Data.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPMSCHAPV2UIMSCHAPV2DATA_H_ +#define _EAPMSCHAPV2UIMSCHAPV2DATA_H_ + +#include +#include + +const TInt KMaxLengthOfUsername=255; +const TInt KMaxLengthOfPassword=255; + +class CEapMsChapV2UiMsChapV2Data : public CBase +{ +public: + + CEapMsChapV2UiMsChapV2Data(); + + ~CEapMsChapV2UiMsChapV2Data(); + + TDes& GetUsername(); + + TDes& GetPassword(); + + TBool * GetPasswordPrompt(); + +private: + + TBuf iUsername; + + TBuf iPassword; + + TBool iPasswordPrompt; +}; + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapsim_db_api/eapsim_db_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapsim_db_api/eapsim_db_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,17 @@ + + + EAP-SIM DB API + Interface for the EAP-SIM UI to access the settings in the EAP-SIM DBMS database. + c++ + wlaneapol + + + + + + + + yes + no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/eapsim_db_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapsim_db_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to +: EAP-SIM DB API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +../inc/EapSimUiConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapSimUiConnection.h) +../inc/EapSimUiDataConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapSimUiDataConnection.h) +../inc/EapSimUiSimData.h MW_LAYER_PLATFORM_EXPORT_PATH(EapSimUiSimData.h) diff -r 000000000000 -r c8830336c852 accesssec_plat/eapsim_db_api/inc/EapSimUiConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapsim_db_api/inc/EapSimUiConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPSIMUICONNECTION_H_ +#define _EAPSIMUICONNECTION_H_ + +#include +#include +#include +#include + +class CEapSimUiDataConnection; + +class CEapSimUiConnection : public CBase +{ + +public: + + CEapSimUiConnection( + const TIndexType iIndexType, + const TInt iIndex, + const TInt iTunnelingType); + + ~CEapSimUiConnection(); + + TInt Connect(); + + TInt Close(); + + CEapSimUiDataConnection * GetDataConnection(); + + TIndexType GetIndexType(); + + TInt GetIndex(); + + TInt GetTunnelingType(); + + TInt GetDatabase(RDbNamedDatabase & aDatabase); + +protected: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // Tunneling type + TInt iTunnelingType; + + // database names, handlers etc... + + TBool iIsConnected; + + CEapSimUiDataConnection * iDataConn; + + RDbNamedDatabase iDbNamedDatabase; + + RDbs iDbs; +}; + + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapsim_db_api/inc/EapSimUiDataConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapsim_db_api/inc/EapSimUiDataConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPSIMUIDATACONNECTION_H_ +#define _EAPSIMUIDATACONNECTION_H_ + +#include + +class CEapSimUiConnection; +class CEapSimUiSimData; + + +class CEapSimUiDataConnection : public CBase +{ + +public: + + CEapSimUiDataConnection(CEapSimUiConnection * aUiConn); + + ~CEapSimUiDataConnection(); + + TInt Open(); + + TInt GetData(CEapSimUiSimData ** aDataPtr); + + TInt Update(); + + TInt Close(); + +protected: + + TBool iIsOpened; + + CEapSimUiConnection * iUiConn; + + RDbNamedDatabase iDatabase; + + RDbView iView; + + CDbColSet* iColSet; + + CEapSimUiSimData * iDataPtr; + +private: + + void FetchDataL(); +}; + + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eapsim_db_api/inc/EapSimUiSimData.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eapsim_db_api/inc/EapSimUiSimData.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPSIMUISIMDATA_H_ +#define _EAPSIMUISIMDATA_H_ + +#include +#include + +const TInt KMaxLengthOfManualUsername = 255; +const TInt KMaxLengthOfManualRealm = 255; + +class CEapSimUiSimData : public CBase +{ +public: + + CEapSimUiSimData(); + + ~CEapSimUiSimData(); + + TDes& GetManualUsername(); + + TDes& GetManualRealm(); + + TBool * GetUseManualUsername(); + + TBool * GetUseManualRealm(); + +private: + + TBuf iManualUsername; + + TBuf iManualRealm; + + TBool iUseManualUsername; + + TBool iUseManualRealm; +}; + +#endif diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/eaptlspeap_db_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/eaptlspeap_db_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,17 @@ + + + EAP-TLS-PEAP DB API + Interface for the UI to access the settings in the TLS-based EAP method DBMS databases + c++ + wlaneapol + + + + + + + + yes + no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to +: EAP-TLS-PEAP DB API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +../inc/CertEntry.h MW_LAYER_PLATFORM_EXPORT_PATH(CertEntry.h) +../inc/AbsEapTlsPeapUiCertificates.h MW_LAYER_PLATFORM_EXPORT_PATH(AbsEapTlsPeapUiCertificates.h) +../inc/EapTlsPeapUiCipherSuite.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTlsPeapUiCipherSuite.h) +../inc/EapTlsPeapUiEapType.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTlsPeapUiEapType.h) +../inc/EapTlsPeapUiConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTlsPeapUiConnection.h) +../inc/EapTlsPeapUiCertificate.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTlsPeapUiCertificate.h) +../inc/EapTlsPeapUiCipherSuites.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTlsPeapUiCipherSuites.h) +../inc/EapTlsPeapUiTlsPeapData.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTlsPeapUiTlsPeapData.h) +../inc/EapTlsPeapUiEapTypes.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTlsPeapUiEapTypes.h) +../inc/EapTlsPeapUiDataConnection.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTlsPeapUiDataConnection.h) +../inc/EapTlsPeapUiCertificates.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTlsPeapUiCertificates.h) +../inc/EapFastNotifierStruct.h MW_LAYER_PLATFORM_EXPORT_PATH(EapFastNotifierStruct.h) +../inc/EapTtlsPapNotifierStruct.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTtlsPapNotifierStruct.h) diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/AbsEapTlsPeapUiCertificates.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/AbsEapTlsPeapUiCertificates.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _ABSEAPTLSPEAPUICERTIFICATES_H_ +#define _ABSEAPTLSPEAPUICERTIFICATES_H_ + +// INCLUDES + +// CLASS DECLARATION +/** +* Class for +*/ +class MEapTlsPeapUiCertificates +{ +public: + /** + * + */ + virtual void CompleteReadCertificates(const TInt aResult) = 0; +}; + +#endif // _ABSEAPTLSPEAPUICERTIFICATES_H_ + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/CertEntry.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/CertEntry.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _SCERTENTRY_H_ +#define _SCERTENTRY_H_ + + +#include +#include + +/* This is the maximum length of a certificate primary/secondary name we are interested in. */ +const TUint32 KMaxNameLength = 64; + +struct SCertEntry +{ + TCertLabel iLabel; // This holds only the certificate label. + TKeyIdentifier iSubjectKeyId; + TBuf iPrimaryName; // Primary name of the certificate if any. + TBuf iSecondaryName; // Secondary name of the certificate if any. +}; + +#endif // _SCERTENTRY_H_ + +// End of file + + diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/EapFastNotifierStruct.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/EapFastNotifierStruct.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPFASTNOTIFIERSTRUCT_H +#define EAPFASTNOTIFIERSTRUCT_H + +const TUid KEapFastNotifierUid = {0x2000F8DF}; + +const TUint KMaxEapFastNotifierBufLength = 255; + +enum EEapFastNotifierUiItem +{ + EEapFastNotifierPacStorePwQuery, /* 0 */ + EEapFastNotifierWrongPacStorePwNote, /* 1 */ + EEapFastNotifierAuthProvWaitNote, /* 2 */ + EEapFastNotifierAuthProvWaitNoteEnd, /* 3 */ + EEapFastNotifierUnauthProvWaitNote, /* 4 */ + EEapFastNotifierUnauthProvWaitNoteEnd, /* 5 */ + EEapFastNotifierInstallPacConfirmQuery, /* 6 */ + EEapFastNotifierProvSuccessNote, /* 7 */ + EEapFastNotifierProvNotSuccessNote, /* 8 */ + EEapFastNotifierPacFilePwQuery, /* 9 */ + EEapFastNotifierWrongPacFilePwNote, /* 10 */ + EEapFastNotifierCreateMasterkeyQuery, /* 11 */ + EEapFastNotifierUiItemsNumber /* 12 */ // keep always as last element +}; + +enum EEapFastNotifierUserAction +{ + EEapFastNotifierUserActionOk, + EEapFastNotifierUserActionCancel +}; + +struct TEapFastNotifierStruct +{ + EEapFastNotifierUiItem iEapFastNotifierUiItem; + TBuf iEapFastNotifierBuffer; + EEapFastNotifierUserAction iEapFastNotifierUserAction; +}; + +#endif // EAPFASTNOTIFIERSTRUCT_H + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiCertificate.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiCertificate.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPTLSPEAPUICERTIFICATE_H_ +#define _EAPTLSPEAPUICERTIFICATE_H_ + +#include +#include + +class TEapTlsPeapUiCertificate +{ +public: + SCertEntry iCertEntry; + TBool iIsEnabled; +}; + +#endif // _EAPTLSPEAPUICERTIFICATE_H_ + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiCertificates.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiCertificates.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPTLSPEAPUICERTIFICATES_H_ +#define _EAPTLSPEAPUICERTIFICATES_H_ + +#include +#include + +class CEapTlsPeapUiConnection; +class TEapTlsPeapUiCertificate; +class CEapTlsPeapCertFetcher; +class MEapTlsPeapUiCertificates; + +class CEapTlsPeapUiCertificates : public CBase +{ + +public: + + CEapTlsPeapUiCertificates(CEapTlsPeapUiConnection * const aUiConn, MEapTlsPeapUiCertificates * const aParent); + + ~CEapTlsPeapUiCertificates(); + + TInt Open(); + + TInt GetCertificates(CArrayFixFlat ** aUserCerts, + CArrayFixFlat ** aCACerts); + + TInt Update(); + + TInt Close(); + + void CompleteReadCertificatesL( + const RArray& aUserCerts, + const RArray& aCACerts); + + +private: + + TBool iIsOpened; + + CEapTlsPeapUiConnection * iUiConn; + + RDbNamedDatabase iDatabase; + + CArrayFixFlat * iUserCerts; + + CArrayFixFlat * iCACerts; + + TRequestStatus iStatus; + + CEapTlsPeapCertFetcher* iCertFetcher; + + MEapTlsPeapUiCertificates* iParent; + +private: + + void FetchDataL( + const TDesC& aTableName, + const RArray& aAvailableCerts, + CArrayFixFlat * const aArray); + + void UpdateL(); +}; + +#endif // _EAPTLSPEAPUICERTIFICATES_H_ + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiCipherSuite.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiCipherSuite.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPTLSPEAPUICIPHERSUITE_H_ +#define _EAPTLSPEAPUICIPHERSUITE_H_ + +#include + +class TEapTlsPeapUiCipherSuite +{ +public: + + TBool iIsEnabled; + TUint iCipherSuite; +}; + +#endif //_EAPTLSPEAPUICIPHERSUITE_H_ + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiCipherSuites.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiCipherSuites.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPTLSPEAPUICIPHERSUITES_H_ +#define _EAPTLSPEAPUICIPHERSUITES_H_ + +#include + +class CEapTlsPeapUiConnection; +class TEapTlsPeapUiCipherSuite; + + +class CEapTlsPeapUiCipherSuites : public CBase +{ + +public: + + CEapTlsPeapUiCipherSuites(CEapTlsPeapUiConnection * const aUiConn); + + ~CEapTlsPeapUiCipherSuites(); + + TInt Open(); + + TInt GetCipherSuites(CArrayFixFlat ** aDataPtr); + + TInt Update(); + + TInt Close(); + +private: + + TBool iIsOpened; + + CEapTlsPeapUiConnection * iUiConn; + + RDbNamedDatabase iDatabase; + + CArrayFixFlat* iDataPtr; + +private: + + void FetchDataL(); + + void UpdateL(); +}; + +#endif //_EAPTLSPEAPUICIPHERSUITES_H_ + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,143 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPTLSPEAPUICONNECTION_H_ +#define _EAPTLSPEAPUICONNECTION_H_ + +#include +#include +#include +#include + +class CEapTlsPeapUiDataConnection; +class CEapTlsPeapUiCipherSuites; +class CEapTlsPeapUiCertificates; +class CEapTlsPeapUiEapTypes; +class MEapTlsPeapUiCertificates; +class CPacStoreDatabase; + +class CEapTlsPeapUiConnection : public CBase +{ + +public: + + // This creates a connection between EAP plugin and the EAP UI. + // aTunnelingType - the Vendor-Type of Tunneling EAP type. + // aEapType - the Vendor-Type of the EAP type + // Supported Vendor-ID here is 0x 0 (3 bytes) for both. + + CEapTlsPeapUiConnection( + const TIndexType aIndexType, + const TInt aIndex, + const TInt aTunnelingType, + const TInt aEapType); + + ~CEapTlsPeapUiConnection(); + + TInt Connect(); + + TInt Close(); + + CEapTlsPeapUiDataConnection * GetDataConnection(); + + CEapTlsPeapUiCipherSuites * GetCipherSuiteConnection(); + + CEapTlsPeapUiCertificates * GetCertificateConnection(MEapTlsPeapUiCertificates * const aParent); + + CEapTlsPeapUiEapTypes * GetEapTypeConnection(); + + TIndexType GetIndexType(); + + TInt GetIndex(); + + // Returns the Vendor-Type of Tunneling EAP type, in this EAP type. + // Supported Vendor-ID here is 0x 0 (3 bytes). + TInt GetTunnelingType(); + + // Returns the Vendor-Type of this EAP type. + // Supported Vendor-ID here is 0x 0 (3 bytes). + TInt GetEapType(); + + TInt GetDatabase(RDbNamedDatabase & aDatabase); + + // Check if there's the PAC store master key. + // Call Connect() before doing this and Close() after. + // Returns ETrue if there is master key. EFalse if there is not. + TBool IsPacStoreMasterKeyPresentL(); + + // This destroys the PAC store if it is created already. + // Call Connect() before doing this and Close() after. + // Returns KErrNone if successful. Symbian error code otherwise. + TInt DestroyPacStore(); + + // This check if the PAC store (or PAC store master key) can be decrypted + // with the password provided. + // Call Connect() before doing this and Close() after. + // Returns ETrue if successful. + TBool VerifyPacStorePasswordL(const TDesC& aPacStorePw); + + // This creates the PAC store master key with the password provided. + // Call Connect() before doing this and Close() after. + // Returns KErrNone if successful. Symbian error code otherwise. + TInt CreatePacStoreMasterKey(const TDesC& aPacStorePw); + + CPacStoreDatabase * GetPacStoreDb(); + +protected: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // This stores the Vendor-Type of Tunneling EAP type. Supported Vendor-ID here is 0x 0 (3 bytes). + TInt iTunnelingType; + + // This stores the Vendor-Type of the EAP type. Supported Vendor-ID here is 0x 0 (3 bytes). + TInt iEapType; + + TBool iIsConnected; + + // database names, handlers etc... + + CEapTlsPeapUiDataConnection * iDataConn; + + CEapTlsPeapUiCipherSuites * iCipherSuites; + + CEapTlsPeapUiEapTypes * iEapTypes; + + CEapTlsPeapUiCertificates * iCertificates; + + RDbNamedDatabase iDbNamedDatabase; + + RDbs iDbs; + +private: + + void ConnectL(); + +private: + + CPacStoreDatabase * iPacStoreDb; + +}; + +#endif + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiDataConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiDataConnection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPTLSPEAPUIDATACONNECTION_H_ +#define _EAPTLSPEAPUIDATACONNECTION_H_ + +#include + +class CEapTlsPeapUiConnection; +class CEapTlsPeapUiTlsPeapData; + + +class CEapTlsPeapUiDataConnection : public CBase +{ + +public: + + CEapTlsPeapUiDataConnection(CEapTlsPeapUiConnection * aUiConn); + + ~CEapTlsPeapUiDataConnection(); + + TInt Open(); + + TInt GetData(CEapTlsPeapUiTlsPeapData ** aDataPtr); + + TInt Update(); + + TInt Close(); + +protected: + + TBool iIsOpened; + + CEapTlsPeapUiConnection * iUiConn; + + RDbNamedDatabase iDatabase; + + RDbView iView; + + CDbColSet* iColSet; + + CEapTlsPeapUiTlsPeapData * iDataPtr; + +private: + // Functions. + + void FetchDataL(); + void UpdateDataL(); + +private: + // Member variables. + + // Only used with EAP-FAST. Can't use the falg here. + RDbView iFastSpecificView; + + // Only used with EAP-FAST. Can't use the flag here. + CDbColSet* iFastSpecificColSet; + +}; + +#endif // _EAPTLSPEAPUIDATACONNECTION_H_ + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiEapType.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiEapType.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPTLSPEAPUIEAPTYPE_H_ +#define _EAPTLSPEAPUIEAPTYPE_H_ + +#include + +class TEapTlsPeapUiEapType +{ +public: + TBool iIsEnabled; + TBuf8<8> iEapType; // UID of Expanded EAP type. +}; + +#endif // _EAPTLSPEAPUIEAPTYPE_H_ + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiEapTypes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiEapTypes.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPTLSPEAPUIEAPTYPES_H_ +#define _EAPTLSPEAPUIEAPTYPES_H_ + +#include + +class CEapTlsPeapUiConnection; +class TEapTlsPeapUiEapType; + +class CEapTlsPeapUiEapTypes : public CBase +{ + +public: + + CEapTlsPeapUiEapTypes(CEapTlsPeapUiConnection * const aUiConn); + + ~CEapTlsPeapUiEapTypes(); + + TInt Open(); + + TInt GetEapTypes(CArrayFixFlat ** aDataPtr); + + TInt Update(); + + TInt Close(); + +private: + + TBool iIsOpened; + + CEapTlsPeapUiConnection * iUiConn; + + RDbNamedDatabase iDatabase; + + CArrayFixFlat* iDataPtr; + +private: + + + void FetchExpandedDataL(); + + void UpdateExpandedDataL(); + +}; + +#endif // _EAPTLSPEAPUIEAPTYPES_H_ + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiTlsPeapData.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/EapTlsPeapUiTlsPeapData.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,106 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPTLSPEAPUITLSPEAPDATA_H_ +#define _EAPTLSPEAPUITLSPEAPDATA_H_ + +#include +#include + +const TInt KMaxLengthOfUsername=255; +const TInt KMaxLengthOfPassword=255; + +const TInt KMaxLengthOfPapUserName = 253; // according to UI spec +const TInt KMaxLengthOfPapPassword = 128; // according to UI spec + +class CEapTlsPeapUiTlsPeapData : public CBase +{ +public: + + CEapTlsPeapUiTlsPeapData(); + + ~CEapTlsPeapUiTlsPeapData(); + + TDes& GetManualUsername(); + + TBool * GetUseManualUsername(); + + TDes& GetManualRealm(); + + TBool * GetUseManualRealm(); + + TBool * GetAllowVersion0(); + + TBool * GetAllowVersion1(); + + TBool * GetAllowVersion2(); + + // New member functions for EAP-FAST + + TBool * GetTlsPrivacy(); + + TBool * GetAuthProvModeAllowed(); + + TBool * GetUnauthProvModeAllowed(); + + TDes& GetPacStorePassword(); + +public: // new, for TTLS PAP + + TDes& GetPapUserName(); + + TDes& GetPapPassword(); + + TBool* GetPapPasswordPrompt(); + +private: + + TBuf iManualUsername; + + TBool iUseManualUsername; + + TBuf iManualRealm; + + TBool iUseManualRealm; + + TBool iAllowVersion0; + + TBool iAllowVersion1; + + TBool iAllowVersion2; + + // New member variables for EAP-FAST + TBool iTlsPrivacy; + + TBool iAuthProvModeAllowed; + + TBool iUnauthProvModeAllowed; + + TBuf iPacStorePassword; + + TBuf iPapUserName; + + TBuf iPapPassword; + + TBool iPapPasswordPrompt; + +}; + +#endif + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/eaptlspeap_db_api/inc/EapTtlsPapNotifierStruct.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/eaptlspeap_db_api/inc/EapTtlsPapNotifierStruct.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,108 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPTTLSPAPNOTIFIERSTRUCT_H +#define EAPTTLSPAPNOTIFIERSTRUCT_H + +/** +* UID of PAP notifier to display authentication query dialog. +*/ +const TUid KPapNotifierUid = { 0x200159A9 }; + +/** +* Maximum PAP challenge length. +*/ +const TUint KMaxPapChallengeLength = 4096; + +/** +* Maximum PAP user name. +*/ +const TUint KMaxPapUserNameLength = 253; + +/** +* Maximum PAP password length. +*/ +const TUint KMaxPapPasswordLength = 128; + +/** +* Data structure defines user name, password and password prompt. +*/ +struct TPapUserNamePasswordInfo + { + /** + * True if password prompt is enabled, False - otherwise. + */ + TBool iPasswordPromptEnabled; + + /* + * Buffer for user name. + */ + TBuf16 iUserName; + + /** + * Buffer for password. + */ + TBuf16 iPassword; + }; + +/** +* Data structure used in notifier communication. +*/ +struct TPapUiNotifierInfo + { + enum TPapUiNotifierState + { + EPapUiNotifierAuthQueryDialog, /* 0 */ + EPapUiNotifierPapChallengeSize, /* 1 */ + EPapUiNotifierPapChallengeMsgDialog, /* 2 */ + EPapUiNotifierPapChallengeReplyQueryDialog, /* 3 */ + // ... + EPapUiNotifierStatesNumber /* 4 */ // keep always as last element + }; + + /** + * State defines UI notifier logic. + */ + TPapUiNotifierState iState; + + /** + * Data structure defines user name, password and password prompt. + */ + TPapUserNamePasswordInfo iUsrPwdInfo; + + /** + * PAP challenge message. + */ + TUint iSrvChallengeSize; + TBuf16 iPapChallenge; + }; + +/** +* Defines user action: accepting or cancelling +* authentication query dialog. +*/ +enum EPapNotifierUserAction + { + EPapNotifierUserActionOk, + EPapNotifierUserActionCancel + }; + +#endif // EAPTTLSPAPNOTIFIERSTRUCT_H + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Build information file +* +*/ + + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +PRJ_MMPFILES +#include "../wapi_security_settings_ui_api/group/bld.inf" +#include "../wep_security_settings_ui_api/group/bld.inf" +#include "../wi-fi_protected_setup_ui_api/group/bld.inf" +#include "../wlan_eap_settings_ui_api/group/bld.inf" +#include "../wpa_security_settings_ui_api/group/bld.inf" +#include "../eap_vpn_api/group/bld.inf" +#include "../eapsim_db_api/group/bld.inf" +#include "../eap_type_api/group/bld.inf" +#include "../eaptlspeap_db_api/group/bld.inf" +#include "../eapleap_db_api/group/bld.inf" +#include "../eapgtc_db_api/group/bld.inf" +#include "../eapmschapv2_db_api/group/bld.inf" +#include "../eapaka_db_api/group/bld.inf" +#include "../wapi_db_api/group/bld.inf" + +PRJ_TESTMMPFILES \ No newline at end of file diff -r 000000000000 -r c8830336c852 accesssec_plat/wapi_db_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wapi_db_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to +: WAPI DB API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +../inc/WapiCertificates.h MW_LAYER_PLATFORM_EXPORT_PATH(WapiCertificates.h) \ No newline at end of file diff -r 000000000000 -r c8830336c852 accesssec_plat/wapi_db_api/inc/WapiCertificates.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wapi_db_api/inc/WapiCertificates.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: WAPI authentication protocols. +* +*/ + + +#ifndef _WAPICERTIFICATES_H_ +#define _WAPICERTIFICATES_H_ + +#include +#include + + +const TInt KMaxLabelLength = 255; +const TInt KMaxIdentityLength = 310; +class CCertificateStoreDatabase; +class abs_eap_am_tools_c; +class dummy_wapi_core_c; +class wapi_am_core_symbian_c; +class ec_certificate_store_c; + +/** +* This is a wrapper class which can be used to handle WAPI related certificates +*/ +class CWapiCertificates : /*public CBase,*/ public CActive +{ + +public: + + IMPORT_C CWapiCertificates(); + IMPORT_C ~CWapiCertificates(); + + /** + * Function for creating the CWapiCertificates object + * + */ + IMPORT_C static CWapiCertificates* NewL(); + + /** + * Function for reserving memory for the internal data types + * + */ + void ConstructL(); + + /** + * Gets a list of the available WAPI user and CA certificates + * + * NOTE that the caller is responsible for freeing the memory of the arrays + * + * @param aUserCerts Array of available WAPI User certificate labels + * @param aUserCertData Array of available WAPI User certificate identities + * @param aCACerts Array of available WAPI CA certificate labels + * @param aCACertData Array of available WAPI CA certificate identities + */ + IMPORT_C void GetAllCertificateLabelsL( RArray > **aUserCerts, RArray > **aUserCertData, + RArray > **aCACerts, RArray >**aCACertData ); + + /** + * Resets the WAPI Certificate store + * + */ + IMPORT_C void ResetCertificateStoreL( ); + + /** + * Gets the WAPI certificate configuration of a specific AP + * + * @param aId Service table id + * @param aUserCert Id matching the selected WAPI User certificate + * @param aCACert Id matching the selected WAPI CA certificate + */ + IMPORT_C void GetConfigurationL( const TInt aId, TDes& aCACert, TDes& aUserCert ); + + /** + * Sets the WAPI certificate configuration of a specific AP + * + * @param aId Service table id + * @param aCACertData Selected WAPI CA certificate identity + */ + IMPORT_C void SetCACertL( const TInt aId, const TBuf8 aCACertData ); + + /** + * Sets the WAPI certificate configuration of a specific AP + * + * @param aId Service table id + * @param aUserCertData Selected WAPI User certificate identity + */ + IMPORT_C void SetUserCertL( const TInt aId, const TBuf8 aUserCertData ); + + /** + * Delete AP related data from certificate database tables + * + * @param aId Service table id + */ + IMPORT_C void DeleteAPSpecificDataL( const TInt aId ); + +protected: // from CActive + + /** + * RunL from CActive + */ + void RunL(); + + /** + * DoCancel from CActive + */ + void DoCancel(); +private: + // Pointer to the used certificate store object + CCertificateStoreDatabase* iCertDB; + // amTools is needed for the certificate store object creation + abs_eap_am_tools_c* iAmTools; + dummy_wapi_core_c* iDummyCore; + // The pointer to the ec_certificate_store_c needed to create the wapi_am_core_symbian + ec_certificate_store_c* iEcCertStore; + // The pointer to the object needed to start the certificate import and reading of labels + wapi_am_core_symbian_c* iWapiCore; + + // For wrapping asynchronous calls. + CActiveSchedulerWait iWait; +}; + +#endif // _WAPICERTIFICATES_H_ + +// End of file diff -r 000000000000 -r c8830336c852 accesssec_plat/wapi_db_api/wapi_db_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wapi_db_api/wapi_db_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,13 @@ + + +WAPI DB API +Interface for the WAPI UI to access the settings in the WAPI DBMS database. +c++ +eapol + + + +no +no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/wapi_security_settings_ui_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wapi_security_settings_ui_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to WAPI Security Settings UI API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS +../inc/wapisecuritysettingsui.h MW_LAYER_PLATFORM_EXPORT_PATH( wapisecuritysettingsui.h ) + + + + diff -r 000000000000 -r c8830336c852 accesssec_plat/wapi_security_settings_ui_api/inc/wapisecuritysettingsui.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wapi_security_settings_ui_api/inc/wapisecuritysettingsui.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,170 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declares the main handler CWAPISecuritySettings, UI CWAPISecuritySettingsUI and public API for the WAPI Security Settings. +* +*/ + +#ifndef WAPISECURITYSETTINGSUI_H +#define WAPISECURITYSETTINGSUI_H + +// INCLUDES + +#include +#include + +#include +#include + +using namespace CommsDat; + +// FORWARD DECLARATIONS +class CEikonEnv; +class CWAPISecuritySettingsUi; +class CWAPISecuritySettingsUiImpl; +class CWAPISecuritySettingsImpl; +class CCommsDatabase; + +// CLASS DECLARATION +/* +* WAPI Security Settings. Enables loading, saving and editing the settings +* (editing via CWAPISecuritySettingsUi). +* Proxy around the real implementation in CWAPISecuritySettingsUiImpl. +*/ +NONSHARABLE_CLASS( CWAPISecuritySettings ) : public CBase + { + + public: // Constructors and destructor + + /** + * Two-phased constructor. Leaves on failure. + * @return The constructed CWAPISecuritySettings object. + */ + IMPORT_C static CWAPISecuritySettings* NewL(); + + + /** + * Destructor. + */ + IMPORT_C ~CWAPISecuritySettings(); + + + public: // Types + + enum TEvent // Events happening during edit. + { + ENone = 0x0000, // Nothing happened. + EModified = 0x0001, // Data changed. + EValid = 0x0010, // All data entered are valid, they can be + // saved + + EExitReq = 0x0020, // Exit option requested, also caller + // app should close + EShutDownReq = 0x0040 // ShutDown was requested + }; + + enum TWapiKeyFormat + { + EWapiKeyAscii = 0, + EWapiKeyHex = 1 + }; + + public: // New methods + + + /** + * Edit WAPI certificate settings. + * @param aUi UI to be used. + * @param aTitle Title Pane text to display during edit. + * @return Exit reason. + */ + IMPORT_C TInt EditL( CWAPISecuritySettingsUi& aUi, + const TDesC& aTitle ); + + + /** + * Load WAPI certificate settings and configuration from database. + * @param aIapRecordID + * @param aSession Commsdat session + */ + IMPORT_C void LoadL( TUint32 aIapRecordId, CMDBSession& aSession ); + + /** + * Tells if the settings are valid and can be saved + * @return ETrue if all the compulsory settings have been entered + */ + IMPORT_C TBool IsValid() const; + + /** + * Save WAPI certificate settings of the IAP to the database. + * @param aIapRecordID + * @param aSession Commsdat session + */ + IMPORT_C void SaveL( TUint32 aIapRecordId, CMDBSession& aSession ) const; + + /** + * Sets the Pre-shared key. Also sets Authentication method to PSK. + * @param aKeyFormat Key format + * @param aPreSharedKey The key to be set + */ + IMPORT_C void SetPreSharedKeyL( const TWapiKeyFormat aKeyFormat, const TDesC& aPreSharedKey ); + + /** + * Delete AP related data from certificate database tables + * + * @param aId Service table id + */ + IMPORT_C void DeleteAPSpecificDataL( const TInt aId ); + + private: // Data + + // Implementation. Owned. + CWAPISecuritySettingsImpl* iImpl; + + }; + +/** +* User interface to edit WAPI Security Settings. +* Proxy around the real implementation in CWAPISecuritySettingsUiImpl. +*/ +NONSHARABLE_CLASS( CWAPISecuritySettingsUi ) : public CBase + { + + public: // Constructors and destructor + + /** + * Two-phased constructor. Leaves on failure. + * @param aEikEnv Eikon environment. + * @return The constructed CWAPISecuritySettingsUi object. + */ + IMPORT_C static CWAPISecuritySettingsUi* NewL( CEikonEnv& aEikEnv ); + + /** + * Destructor. + */ + IMPORT_C virtual ~CWAPISecuritySettingsUi(); + + private: // Friends + + friend class CWAPISecuritySettings; + + private: // Data + + // Implementation. Owned. + CWAPISecuritySettingsUiImpl* iImpl; + + }; +#endif + + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wapi_security_settings_ui_api/wapi_security_settings_ui_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wapi_security_settings_ui_api/wapi_security_settings_ui_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,14 @@ + + +WAPI Security Settings UI API +API for accessing WAPI security settings UI +c++ +networkingutilities + + + + +yes +no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/wep_security_settings_ui_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wep_security_settings_ui_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to WEP Security Settings UI API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS +../inc/WEPSecuritySettingsUI.h MW_LAYER_PLATFORM_EXPORT_PATH( WEPSecuritySettingsUI.h ) + + + + diff -r 000000000000 -r c8830336c852 accesssec_plat/wep_security_settings_ui_api/inc/WEPSecuritySettingsUI.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wep_security_settings_ui_api/inc/WEPSecuritySettingsUI.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,243 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declares the main handler CWEPSecuritySettings, UI CWEPSecuritySettingsUI and public API for the WEP Security Settings. +* +*/ + + +#ifndef WEPSECURITYSETTINGSUI_H +#define WEPSECURITYSETTINGSUI_H + +// INCLUDES + +#include + +#include +using namespace CommsDat; + +// FORWARD DECLARATIONS +class CEikonEnv; +class CWEPSecuritySettingsUi; +class CWEPSecuritySettingsUiImpl; +class CWEPSecuritySettingsImpl; +class CCommsDatabase; + + + +// CLASS DECLARATION +/* +* WEP Security Settings. Enables loading, saving and editing the settings +* (editing via CWEPSecuritySettingsUi). +* Proxy around the real implementation in CWEPSecuritySettingsUiImpl. +* No details of the actual data are exposed. +*/ +NONSHARABLE_CLASS( CWEPSecuritySettings ) : public CBase + { + + public: // Constructors and destructor + + /** + * Two-phased constructor. Leaves on failure. + * @return The constructed CWEPSecuritySettings object. + */ + IMPORT_C static CWEPSecuritySettings* NewL(); + + + /** + * Destructor. + */ + IMPORT_C ~CWEPSecuritySettings(); + + + public: // Types + + enum TEvent // Events happening during edit. + { + ENone = 0x0000, // Nothing happened. + EModified = 0x0001, // Data changed. + EValid = 0x0010, // All data entererd are valid, they + // can be saved + EExitReq = 0x0020, // Exit option requested, also caller + // app should close + EShutDownReq = 0x0040 // ShutDown was requested + }; + + + // Members to be showed in the setting pages + enum TWepMember + { + EWepKeyInUse, // To set key in use + EWepAuthentication, // To set authentication type + EWepKeyConfiguration, // To open the other settings (the three below) + + EWepKeyLength, // To set the length of the key + EWepKeyFormat, // To choose the format of the key + EWepKeyData // To set the key + }; + + + // Enumeration of the possible keys in use + enum TWEPKeyInUse + { + EKeyNumber1, // Key number 1 + EKeyNumber2, // Key number 2 + EKeyNumber3, // Key number 3 + EKeyNumber4 // Key number 4 + }; + + + // Enumeration of the possible authentication types + enum TWEPAuthentication + { + EAuthOpen, // Open authentication + EAuthShared // Shared authentication + }; + + + // Possible lengths of the keys + enum TWEPKeyLength + { + E40Bits, // 40 bits + E104Bits, // 104 bits + E232Bits // 232 bits + }; + + + // Possible formats of the keys + enum TWEPKeyFormat + { + EAscii, // Ascii format + EHexadecimal // Hex format + }; + + public: // New methods + + /** + * Load from database. + * @param aIapId Wlan Service Table Id of the IAP to be loaded + * @param aCommsDb Comms database. + */ + IMPORT_C void LoadL( TUint32 aIapId, CCommsDatabase& aCommsDb ); + + /** + * Edit the settings. + * @param aUi UI to be used. + * @param aTitle Title Pane text to display during edit. + * @return Exit reason. + */ + IMPORT_C TInt EditL( CWEPSecuritySettingsUi& aUi, + const TDesC& aTitle ); + + /** + * Save to database. + * @param aIapId Wlan Service Table Id of the IAP to be saved + * @param aCommsDb Comms database. + */ + IMPORT_C void SaveL( TUint32 aIapId, CCommsDatabase& aCommsDb ) const; + + /** + * Tells if the settings are valid and can be saved + * @return ETrue if all the compulsory settings have been entered + */ + IMPORT_C TBool IsValid() const; + + /** + * Sets the new data of the key + * @param aElement Index of the element whose data has to be set. + * @param aKeyData The new value for data of the key. + * @param aHex ETrue if data is in Ascii format + * @return KErrNone if successful, or an error code + */ + IMPORT_C TInt SetKeyDataL( const TInt aElement, const TDesC& aKeyData, + const TBool aHex ); + + /** + * Load from database. + * @param aIapId Wlan Service Table Id of the IAP to be loaded + * @param aSession Session to CommsDat. + */ + IMPORT_C void LoadL( TUint32 aIapId, CMDBSession& aSession ); + + /** + * Save to database. + * @param aIapId Wlan Service Table Id of the IAP to be saved + * @param aSession Session to CommsDat. + */ + IMPORT_C void SaveL( TUint32 aIapId, CMDBSession& aSession ) const; + + /** + * Sets the index of the key to use. + * @param aKey The key to be used for authentication. + */ + IMPORT_C void SetKeyInUse( TWEPKeyInUse aKey ); + + /** + * Sets the authentication type. + * @param aAuthentication The authentication type. + */ + IMPORT_C void SetAuthentication( TWEPAuthentication aAuthentication ); + + + private: // Data + + // Implementation. Owned. + CWEPSecuritySettingsImpl* iImpl; + + }; + + + +/** +* User interface to edit WEP Security Settings. +* Proxy around the real implementation in CWEPSecuritySettingsUiImpl. +*/ +NONSHARABLE_CLASS( CWEPSecuritySettingsUi ) : public CBase + { + + public: // Constructors and destructor + + /** + * Two-phased constructor. Leaves on failure. + * @param aEikEnv Eikon environment. + * @return The constructed CWEPSecuritySettingsUi object. + */ + IMPORT_C static CWEPSecuritySettingsUi* NewL( CEikonEnv& aEikEnv ); + + /** + * Destructor. + */ + IMPORT_C virtual ~CWEPSecuritySettingsUi(); + + public: // New methods + + /** + * Component Validation Test. + * @return KErrNone. + */ + IMPORT_C static TInt Cvt(); + + private: // Friends + + friend class CWEPSecuritySettings; + + private: // Data + + // Implementation. Owned. + CWEPSecuritySettingsUiImpl* iImpl; + + }; +#endif + + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wep_security_settings_ui_api/wep_security_settings_ui_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wep_security_settings_ui_api/wep_security_settings_ui_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,14 @@ + + +WEP Security Settings UI API +API for accessing WEP security settings UI +c++ +networkingutilities + + + + +yes +no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/wi-fi_protected_setup_ui_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wi-fi_protected_setup_ui_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to WiFi Protected Setup UI API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS +../inc/wifiprotuiclient.h MW_LAYER_PLATFORM_EXPORT_PATH( wifiprotuiclient.h ) +../inc/WiFiProtReturn.h MW_LAYER_PLATFORM_EXPORT_PATH( wifiprotreturn.h ) +../inc/wifiprotuiddefs.h MW_LAYER_PLATFORM_EXPORT_PATH( wifiprotuiddefs.h ) +../inc/wifiprotuiinprocess.h MW_LAYER_PLATFORM_EXPORT_PATH( wifiprotuiinprocess.h ) + diff -r 000000000000 -r c8830336c852 accesssec_plat/wi-fi_protected_setup_ui_api/inc/WiFiProtReturn.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wi-fi_protected_setup_ui_api/inc/WiFiProtReturn.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declares the common used constants and types for Wi-Fi Protected Setup. +* +*/ + + +#ifndef T_WIFIRETURN_H +#define T_WIFIRETURN_H + +namespace WiFiProt + { + // Return value of Wi-Fi Protected Setup ( WPS ) Ui process + enum TWiFiReturn + { + // WPS has been cancelled + EWiFiCancel, + // WPS has completed without any errors + EWiFiOK, + // User has selected the option not to use WPS + EWifiNoAuto + }; + } + +#endif // T_WIFIRETURN_H + + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wi-fi_protected_setup_ui_api/inc/wifiprotuiclient.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wi-fi_protected_setup_ui_api/inc/wifiprotuiclient.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,117 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declares the main handler, CWiFiProtUiClient and public API for the Wi-Fi Protected Settings. +* +*/ + + +#ifndef C_WIFIPROTUICLIENT_H +#define C_WIFIPROTUICLIENT_H + +// INCLUDES + +#include +#include +#include + +// FORWARD DECLARATIONS +class CWiFiProtUiClientImpl; + +// CLASS DECLARATION +/* +* WiFi Protected Setup , used to show the user a sequence of dialogs to setup +* a wlan network automatically +* This class is just a proxy, the real implementation is in +* CWiFiProtUiClientImpl. +* No details of the actual data are exposed. +*/ +class CWiFiProtUiClient : public CBase + { + public: // Constructors and destructor + /** + * Two-phased constructor. Leaves on failure. + * @return The constructed CWiFiProtUiClient object. + */ + IMPORT_C static CWiFiProtUiClient* NewL(); + + /** + * Destructor. + */ + IMPORT_C ~CWiFiProtUiClient(); + + // New methods + + /** + * Starts WiFi Protected Setup sequence + * @param aSSid contains SSid of the network we want to configure + * @param aConnectionNeeded - This parameter is not used anymore in + * the current implementation. It is just there to preserve + * compatibility. Please use StartWiFiProtConnL to configure a + * connection using Wi-Fi Protected Setup. + * @param aUidsReturned uids of the configured connection methods + * @param aReturnValue - possible return values are ok, cancel + * process and not use protected setup (No Automatic Setup). + * @param aStatus - Request status of the client + */ + IMPORT_C void StartWiFiProtL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned, + WiFiProt::TWiFiReturn& aReturnValue, + TRequestStatus& aStatus ); + + /** + * Starts WiFi Protected Setup sequence - sync version + * @param aSSid contains SSid of the network we want to configure + * @param aConnectionNeeded - This parameter is not used anymore in + * the current implementation. It is just there to preserve + * compatibility. Please use StartWiFiProtConnL to configure a + * connection using Wi-Fi Protected Setup. + * @param aUidsReturned uids of the configured connection methods + * @return - possible return values are ok, cancel process + * and not use protected setup (No Automatic Setup). + * We can return a value since the call is sychronous. + */ + IMPORT_C WiFiProt::TWiFiReturn StartWiFiProtSyncL( + const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned ); + + /** + * Cancels WiFi Protected Setup sequence + */ + IMPORT_C void CancelWiFiProt( ); + + /** + * Starts WiFi Protected Setup sequence in Connection initiation mode + * (WPS phase 2 implementation) + * @param aSSid contains SSid of the network we want to configure + * @param aNetworkSettings configuration settings of the network to use + * for the connection (returned as the result of Protected Setup) + * @param aReturnValue - possible return values are ok, cancel + * process and not use protected setup (No Automatic Setup). + * @param aStatus - Request status of the client + */ + IMPORT_C void StartWiFiProtConnL( const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& + aNetworkSettings, + WiFiProt::TWiFiReturn& aReturnValue, + TRequestStatus& aStatus ); + + private: // Data + CWiFiProtUiClientImpl* iImpl; ///< Implementation. Owned. + }; + +#endif //C_WIFIPROTUICLIENT_H + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wi-fi_protected_setup_ui_api/inc/wifiprotuiddefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wi-fi_protected_setup_ui_api/inc/wifiprotuiddefs.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of the UIDs used by Connection Dialogs +* +*/ + + +#ifndef WIFIPROTUIDDEFS_H +#define WIFIPROTUIDDEFS_H + +// INCLUDES +#include + +// CONSTANTS + +// UIDs for CConnDlg plugins + +// ID of Wi-Fi protected setup +const TUid KUidWiFiProtSetup = { 0x10281BBF }; + +#endif // WIFIPROTUIDDEFS_H + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wi-fi_protected_setup_ui_api/inc/wifiprotuiinprocess.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wi-fi_protected_setup_ui_api/inc/wifiprotuiinprocess.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of CWifiProtUiInProcess +* +*/ + + + +#ifndef C_WIFIPROTUIINPROCESS_H +#define C_WIFIPROTUIINPROCESS_H + + +// INCLUDES +#include +#include +#include + +class CWiFiProtDlgsPlugin; + +/** + * CWifiProtUiInProcess class + * Private interface class that allows the client to run + * Wi-Fi Protected Setup directly, without using the + * Notifier Framework + */ +class CWifiProtUiInProcess : public CBase + { + +public: + + /** + * NewL function + * @param aCmManagerExt Cm Manager to use during Wi-Fi Protected Setup + * return CWifiProtUiInProcess* + */ + IMPORT_C static CWifiProtUiInProcess* NewL( RCmManagerExt* + aCmManagerExt ); + + /** + * Destructor + */ + ~CWifiProtUiInProcess( ); + + /** + * Starts Wi-Fi Protected Setup + * Private interface to be used by applications with ui + * runs in the same process, so pointers can be passed + * @param aSSid contains SSid of the network we want to configure + * @param aConnectionNeeded ETrue if we need a connection via the + * configured network + * @return possible return values are ok, cancel process and not use + * protected setup (No Auto). + */ + IMPORT_C WiFiProt::TWiFiReturn StartFromUiL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned); + +private: + + /** + * Constructor + */ + CWifiProtUiInProcess( ); + + /** + * Second phase constructor + * @param aCmManagerExt CmManager to use + */ + void ConstructL( RCmManagerExt* aCmManagerExt = NULL ); + +private: + CWiFiProtDlgsPlugin* iWiFiProtDlgsPlugin; // notifier plugin class + }; + + +#endif // C_WIFIPROTUIINPROCESS_H + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wi-fi_protected_setup_ui_api/wi-fi_protected_setup_ui_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wi-fi_protected_setup_ui_api/wi-fi_protected_setup_ui_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,19 @@ + + + Wi-Fi Protected Setup UI API + Provides UI related functionality for Wi-Fi Protected Setup. This API can be called from a process without UI context. + c++ + networkingutilities + + + + + + + + + + yes + no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to WLAN EAP Settings UI API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +../inc/EapAkaUi.h MW_LAYER_PLATFORM_EXPORT_PATH(EapAkaUi.h) +../inc/EapMschapv2Ui.h MW_LAYER_PLATFORM_EXPORT_PATH(EapMschapv2Ui.h) +../inc/EapTtlsUi.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTtlsUi.h) +../inc/EapTlsUi.h MW_LAYER_PLATFORM_EXPORT_PATH(EapTlsUi.h) +../inc/EapSimUi.h MW_LAYER_PLATFORM_EXPORT_PATH(EapSimUi.h) +../inc/EapLeapUi.h MW_LAYER_PLATFORM_EXPORT_PATH(EapLeapUi.h) +../inc/EapPeapUi.h MW_LAYER_PLATFORM_EXPORT_PATH(EapPeapUi.h) +../inc/eapfastui.h MW_LAYER_PLATFORM_EXPORT_PATH(eapfastui.h) +../inc/EapGtcUi.h MW_LAYER_PLATFORM_EXPORT_PATH(EapGtcUi.h) +../inc/papui.h MW_LAYER_PLATFORM_EXPORT_PATH(papui.h) +../inc/EAPPluginConfigurationIf.inl MW_LAYER_PLATFORM_EXPORT_PATH(EAPPluginConfigurationIf.inl) +../inc/EAPPluginConfigurationIf.h MW_LAYER_PLATFORM_EXPORT_PATH(EAPPluginConfigurationIf.h) diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/EAPPluginConfigurationIf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/EAPPluginConfigurationIf.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is the ECOM interface for EAP Plugin Configuration. +* +*/ + + + +#ifndef __EAPPLUGINCONFIGURATIONIF_H__ +#define __EAPPLUGINCONFIGURATIONIF_H__ + + +// INCLUDES +#include +#include + + +// CONSTANTS +const TUid KEapPluginConfigInterfaceUid = {0x102072CA}; + + +// CLASS DECLARATION +/** +* CEAPPluginConfigurationIf class +* ECOM interface for EAP PLugin Configuration. +*/ +class CEAPPluginConfigurationIf : public CBase + { + public: + inline static CEAPPluginConfigurationIf* NewL( + const TDesC8& aMatchString ); + + inline virtual ~CEAPPluginConfigurationIf(); + + /** + * Load the EAP Plugin configuration + * @param aWPAEAPPlugin The list of EAPs in use as it was read from + * WlanEapList column of WLANServiceTable. In + * output it contains the new list as it has + * to be written in the same column of + * database. + * @param aConnectionName The name of the connection. + * @return The ID of the button pressed to close configuration: + * typically EAknSoftkeyBack for back, EAknCmdExit for a + * request of exit or EEikCmdExit for a request of shutdown + */ + virtual TInt EAPPluginConfigurationL( TDes& aWPAEAPPlugin, + const TUint32 aIapID, + const TDes& aConnectionName ) = 0; + + /** + * Load the EAP Plugin configuration (with expanded EAP types) + * @param aWPAEnabledEAPPlugin The list of enabled EAPs in use as + * it was read from WlanEnabledEapList column + * of WLANServiceTable. In output it contains + * the new list as it has to be written in the + * same column of database. + * @param aWPADisabledEAPPlugin The list of disabled EAPs in use as + * it was read from WlanDisabledEapList column + * of WLANServiceTable. In output it contains + * the new list as it has to be written in the + * same column of database. + * @param aConnectionName The name of the connection. + * @return The ID of the button pressed to close configuration: + * typically EAknSoftkeyBack for back, EAknCmdExit for a + * request of exit or EEikCmdExit for a request of shutdown + */ + virtual TInt EAPPluginConfigurationL( TDes8& aWPAEnabledEAPPlugin, + TDes8& aWPADisabledEAPPlugin, + const TUint32 aIapID, + const TDes& aConnectionName ) = 0; + + /** + * Shows the EAP type info. + */ + virtual void ShowEAPTypeInfo() = 0; + + /** + * Deletes all EAP types' settings for + * the given IAP. + */ + virtual void DeleteSettingsL( const TUint32 aIapID ) = 0; + + /** + * Changes the index of the EAP settings for all EAP types + */ + virtual void ChangeIapIDL( const TUint32 aOldIapID, + const TUint32 aNewIapID ) = 0; + + /** + * Copies the EAP type settings to another ID + */ + virtual void CopySettingsL( const TUint32 aSourceIapID, + const TUint32 aDestinationIapID ) = 0; + + + private: // Data + // This variable holds the instance identifier. + TUid iDtor_ID_Key; + }; + + +#include "EAPPluginConfigurationIf.inl" + +#endif // __EAPPLUGINCONFIGURATIONIF_H__ + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/EAPPluginConfigurationIf.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/EAPPluginConfigurationIf.inl Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Inline functions of CEAPPluginConfigurationIf +* +*/ + + + +#ifndef __EAPPLUGINCONFIGURATIONIF_INL__ +#define __EAPPLUGINCONFIGURATIONIF_INL__ + + +// --------------------------------------------------------- +// CEAPPluginConfigurationIf::NewL +// --------------------------------------------------------- +// +inline CEAPPluginConfigurationIf* CEAPPluginConfigurationIf::NewL( + const TDesC8& aMatchString ) + { + TEComResolverParams resolverParams; + resolverParams.SetDataType(aMatchString); + + TAny* ptr = REComSession::CreateImplementationL( + KEapPluginConfigInterfaceUid, + _FOFF( CEAPPluginConfigurationIf, iDtor_ID_Key ), + resolverParams ); + + return REINTERPRET_CAST( CEAPPluginConfigurationIf*, ptr ); + } + + +// --------------------------------------------------------- +// CEAPPluginConfigurationIf::~CEAPPluginConfigurationIf +// --------------------------------------------------------- +// +inline CEAPPluginConfigurationIf::~CEAPPluginConfigurationIf() + { + // Unload DLL + REComSession::DestroyedImplementation( iDtor_ID_Key ); + } + + +#endif // __EAPPLUGINCONFIGURATIONIF_INL__ + +// End of file. diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/EapAkaUi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/EapAkaUi.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP AKA settings UI +* +*/ + + + +#ifndef _EAPAKAUI_H_ +#define _EAPAKAUI_H_ + +// INCLUDES +#include +#include + + +// CLASS DECLARATION + +/** +* Main UI class definition +*/ +class CEapAkaUi : public CCoeControl + { + public: + /** + * Destructor. + */ + ~CEapAkaUi(); + + /** + * Two-phased constructor. + */ + static CEapAkaUi* NewL( CEapAkaUiConnection* aConnection ); + + TInt InvokeUiL(); + + protected: + CEapAkaUi( CEapAkaUiConnection* aConnection ); + + void ConstructL(); + + private: + CEapAkaUiConnection* iConnection; + }; + + +#endif // _EAPAKAUI_H_ + +// End of File + diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/EapGtcUi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/EapGtcUi.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP GTC settings UI +* +*/ + + + +#ifndef _EAPGTCUI_H_ +#define _EAPGTCUI_H_ + +// INCLUDES +#include +#include + + +// CLASS DECLARATION + +/** +* Main UI class definition +*/ +class CEapGtcUi : public CCoeControl + { + public: + /** + * Destructor. + */ + ~CEapGtcUi(); + + /** + * Two-phased constructor. + */ + static CEapGtcUi* NewL( CEapGtcUiConnection* aConnection ); + + TInt InvokeUiL(); + + protected: + /** + * C++ default constructor. + */ + CEapGtcUi( CEapGtcUiConnection* aConnection ); + + void ConstructL(); + + private: + CEapGtcUiConnection* iConnection; + }; + + +#endif // _EAPGTCUI_H_ + +// End of File \ No newline at end of file diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/EapLeapUi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/EapLeapUi.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP LEAP UI +* +*/ + + + +#ifndef _EAPLEAPUI_H_ +#define _EAPLEAPUI_H_ + +// INCLUDES +#include +#include + + +// CLASS DECLARATION + +/** +* Main UI class definition +*/ +class CEapLeapUi : public CCoeControl + { + public: + ~CEapLeapUi(); + static CEapLeapUi* NewL( CEapLeapUiConnection* aConnection ); + TInt InvokeUiL(); + + protected: + CEapLeapUi( CEapLeapUiConnection* aConnection ); + void ConstructL(); + + private: + CEapLeapUiConnection* iConnection; + }; + + +#endif //_EAPLEAPUI_H_ + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/EapMschapv2Ui.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/EapMschapv2Ui.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP MsChapv2 UI +* +*/ + + + +#ifndef _EAPMSCHAPV2UI_H_ +#define _EAPMSCHAPV2UI_H_ + +// INCLUDES +#include +#include + + +// CLASS DECLARATION + +/** +* Main UI class definition +*/ +class CEapMsChapV2Ui : public CCoeControl + { + public: + ~CEapMsChapV2Ui(); + static CEapMsChapV2Ui* NewL( CEapMsChapV2UiConnection* aConnection ); + TInt InvokeUiL(); + + protected: + CEapMsChapV2Ui( CEapMsChapV2UiConnection* aConnection ); + void ConstructL(); + + private: + CEapMsChapV2UiConnection* iConnection; + }; + + +#endif // _EAPMSCHAPV2UI_H_ + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/EapPeapUi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/EapPeapUi.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP PEAP settings UI +* +*/ + + + +#ifndef _EAPPEAPUI_H_ +#define _EAPPEAPUI_H_ + +// INCLUDES +#include "EapTlsPeapUiConnection.h" +#include + + +// CLASS DECLARATION + +/** +* Main UI class definition +*/ +class CEapPeapUi : public CCoeControl + { + public: + ~CEapPeapUi(); + static CEapPeapUi* NewL( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, + TInt aIndex ); + TInt InvokeUiL(); + + protected: + CEapPeapUi( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, + TInt aIndex ); + void ConstructL(); + + private: + CEapTlsPeapUiConnection* iConnection; + TIndexType iIndexType; + TInt iIndex; + }; + + +#endif // _EAPPEAPUI_H_ + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/EapSimUi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/EapSimUi.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP SIM settings UI +* +*/ + + + +#ifndef _EAPSIMUI_H_ +#define _EAPSIMUI_H_ + +// INCLUDES +#include +#include + + +// CLASS DECLARATION + +/** +* Main UI class definition +*/ +class CEapSimUi : public CCoeControl + { + public: + ~CEapSimUi(); + static CEapSimUi* NewL( CEapSimUiConnection* aConnection ); + TInt InvokeUiL(); + + protected: + CEapSimUi( CEapSimUiConnection* aConnection ); + void ConstructL(); + + private: + CEapSimUiConnection* iConnection; + }; + + +#endif // _EAPSIMUI_H_ + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/EapTlsUi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/EapTlsUi.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP TLS settings UI +* +*/ + + + +#ifndef _EAPTLSUI_H_ +#define _EAPTLSUI_H_ + +// INCLUDES +#include +#include "EapTlsPeapUiConnection.h" + + +// CLASS DECLARATION + +/** +* Main UI class definition +*/ +class CEapTlsUi : public CCoeControl + { + public: + ~CEapTlsUi(); + static CEapTlsUi* NewL( CEapTlsPeapUiConnection* aConnection ); + TInt InvokeUiL(); + + protected: + CEapTlsUi( CEapTlsPeapUiConnection* aConnection ); + void ConstructL(); + + private: + CEapTlsPeapUiConnection* iConnection; + }; + + +#endif //_EAPTLSUI_H_ + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/EapTtlsUi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/EapTtlsUi.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP TTLS settings UI +* +*/ + + + +#ifndef _EAPTTLSUI_H_ +#define _EAPTTLSUI_H_ + +// INCLUDES +#include "EapTlsPeapUiConnection.h" +#include + + +// CLASS DECLARATION + +/** +*/ +class CEapTtlsUi : public CCoeControl + { + public: + ~CEapTtlsUi(); + static CEapTtlsUi* NewL( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, + TInt aIndex ); + TInt InvokeUiL(); + + protected: + CEapTtlsUi( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, + TInt aIndex ); + void ConstructL(); + + private: + CEapTlsPeapUiConnection* iConnection; + TIndexType iIndexType; + TInt iIndex; + }; + + +#endif // _EAPTTLSUI_H_ + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/eapfastui.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/eapfastui.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP FAST settings UI +* +*/ + + + +#ifndef _EAPFASTUI_H_ +#define _EAPFASTUI_H_ + +// INCLUDES +#include "EapTlsPeapUiConnection.h" +#include + + +// CLASS DECLARATION + +/** +* Main UI class definition +*/ +class CEapFastUi : public CCoeControl + { + public: + ~CEapFastUi(); + static CEapFastUi* NewL( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, + TInt aIndex ); + TInt InvokeUiL(); + + protected: + CEapFastUi( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, + TInt aIndex ); + void ConstructL(); + + private: + CEapTlsPeapUiConnection* iConnection; + TIndexType iIndexType; + TInt iIndex; + }; + + +#endif // _EAPFASTUI_H_ + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/inc/papui.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/inc/papui.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of PAP Config UI +* +*/ + + + +#ifndef _PAPUI_H_ +#define _PAPUI_H_ + +// INCLUDES +#include +#include + + +// CLASS DECLARATION + +/** +* Main UI class definition +*/ +class CPapUi : public CCoeControl + { + public: + ~CPapUi(); + static CPapUi* NewL( CEapTlsPeapUiConnection* aConnection ); + TInt InvokeUiL(); + + protected: + CPapUi( CEapTlsPeapUiConnection* aConnection ); + void ConstructL(); + + private: + CEapTlsPeapUiConnection* iConnection; + }; + + +#endif // _PAPUI_H_ + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wlan_eap_settings_ui_api/wlan_eap_settings_ui_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wlan_eap_settings_ui_api/wlan_eap_settings_ui_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,25 @@ + + + WLAN EAP Settings UI API + API for accessing EAP settings UI + c++ + networkingutilities + + + + + + + + + + + + + + + + yes + no + + diff -r 000000000000 -r c8830336c852 accesssec_plat/wpa_security_settings_ui_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wpa_security_settings_ui_api/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: File that exports the files belonging to WPA Security Settings UI API +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS +../inc/WPASecuritySettingsUI.h MW_LAYER_PLATFORM_EXPORT_PATH( WPASecuritySettingsUI.h ) + + + + + diff -r 000000000000 -r c8830336c852 accesssec_plat/wpa_security_settings_ui_api/inc/WPASecuritySettingsUI.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wpa_security_settings_ui_api/inc/WPASecuritySettingsUI.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,249 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declares the main handler CWPASecuritySettings, UI CWPASecuritySettingsUI and public API for the WPA Security Settings. +* +*/ + + +#ifndef WPASECURITYSETTINGSUI_H +#define WPASECURITYSETTINGSUI_H + +// INCLUDES + +#include + +#include +using namespace CommsDat; + +// FORWARD DECLARATIONS +class CEikonEnv; +class CWPASecuritySettingsUi; +class CWPASecuritySettingsUiImpl; +class CWPASecuritySettingsImpl; +class CCommsDatabase; + + +// ENUMERATIONS + +// Security mode in use +enum TSecurityMode + { + ESecurityMode8021x = 4, // 802.1x + ESecurityModeWpa = 8 // WPA + }; + + +// Type of saving +enum TTypeOfSaving + { + ESavingEditedAP, // Save an already existing AP that was edited. + ESavingBrandNewAP, // Save a just created AP started from default values + ESavingNewAPAsACopy // Save a new AP as a copy of an already existing AP + }; + + + + +// CLASS DECLARATION +/* +* WPA Security Settings. Enables loading, saving and editing the settings +* (editing via CWPASecuritySettingsUi). +* Proxy around the real implementation in CWPASecuritySettingsUiImpl. +* No details of the actual data are exposed. +*/ +NONSHARABLE_CLASS( CWPASecuritySettings ) : public CBase + { + + public: // Constructors and destructor + + /** + * Two-phased constructor. Leaves on failure. + * @param aSecurityMode The chosen security mode. It can be + * ESecurityMode8021x or ESecurityModeWpa + * @return The constructed CWPASecuritySettings object. + */ + IMPORT_C static CWPASecuritySettings* NewL( + TSecurityMode aSecurityMode ); + + + /** + * Destructor. + */ + IMPORT_C ~CWPASecuritySettings(); + + + public: // Types + + enum TEvent // Events happening during edit. + { + ENone = 0x0000, // Nothing happened. + EModified = 0x0001, // Data changed. + EValid = 0x0010, // All data entererd are valid, they + // can be saved + EExitReq = 0x0020, // Exit option requested, also caller + // app should close + EShutDownReq = 0x0040 // ShutDown was requested + }; + + + public: // New methods + + /** + * Load from database. + * @param Wlan Service Table Id of the IAP to be loaded + * @param aCommsDb Comms database. + */ + IMPORT_C void LoadL( TUint32 aIapId, CCommsDatabase& aCommsDb ); + + + /** + * Edit the settings. + * @param aUi UI to be used. + * @param aTitle Title Pane text to display during edit. + * @return Exit reason. + */ + IMPORT_C TInt EditL( CWPASecuritySettingsUi& aUi, + const TDesC& aTitle ); + + /** + * Save to database. + * @param aIapId Wlan Service Table Id of the IAP to be saved + * @param aCommsDb Comms database. + * @param aTypeOfSaving Tells what kind of AP we are going to save: it + * can be ESavingEditedAP, ESavingBrandNewAP, or + * ESavingNewAPAsACopy + * @param aOldIapId The old Id of the IAP; it is used to save the EAP + * configuration, only when aIsNewAP is ETrue + */ + IMPORT_C void SaveL( TUint32 aIapId, + CCommsDatabase& aCommsDb, + TTypeOfSaving aTypeOfSaving, + TUint32 aOldIapId ) const; + + + /** + * Delete from database. It actually just removes EAP Configuration. + * @param aIapId Id of the IAP to be saved + */ + IMPORT_C void DeleteL( TUint32 aIapId ) const; + + + /** + * Tells if the settings are valid and can be saved + * @return ETrue if all the compulsory settings have been entered + */ + IMPORT_C TBool IsValid() const; + + + /** + * Sets the Pre-shared key + * @param aPreSharedKey The key to be set + * @return KErrNone if successful, or an error code + */ + IMPORT_C TInt SetWPAPreSharedKey( const TDesC& aPreSharedKey ); + + + /** + * Load from database. + * @param aIapId Wlan Service Table Id of the IAP to be loaded + * @param aSession CommsDat session. + */ + IMPORT_C void LoadL( TUint32 aIapId, CMDBSession& aSession ); + + + /** + * Save to database. + * @param aIapId Wlan Service Table Id of the IAP to be saved + * @param aSession CommsDat session. + * @param aTypeOfSaving Tells what kind of AP we are going to save: it + * can be ESavingEditedAP, ESavingBrandNewAP, or + * ESavingNewAPAsACopy + * @param aOldIapId The old Id of the IAP; it is used to save the EAP + * configuration, only when aIsNewAP is ETrue + */ + IMPORT_C void SaveL( TUint32 aIapId, + CMDBSession& aSession, + TTypeOfSaving aTypeOfSaving, + TUint32 aOldIapId ) const; + + /** + * Sets the list of enabled EAP types. + * @param aEnabledPluginList Enumeration of enabled plugins + * in expanded EAP type format + * @return KErrNone if successful, or an error code + */ + IMPORT_C TInt SetWPAEnabledEAPPlugin( const TDesC8& aEnabledPluginList ); + + + /** + * Sets the list of disabled EAP types + * @param aDisabledPluginList Enumeration of disabled plugins + * in expanded EAP type format + * @return KErrNone if successful, or an error code + */ + IMPORT_C TInt SetWPADisabledEAPPlugin( const TDesC8& aDisabledPluginList ); + + + private: // Data + + // Implementation. Owned. + CWPASecuritySettingsImpl* iImpl; + + }; + + + +/** +* User interface to edit WPA Security Settings. +* Proxy around the real implementation in CWPASecuritySettingsUiImpl. +*/ +NONSHARABLE_CLASS( CWPASecuritySettingsUi ) : public CBase + { + + public: // Constructors and destructor + + /** + * Two-phased constructor. Leaves on failure. + * @param aEikEnv Eikon environment. + * @return The constructed CWPASecuritySettingsUi object. + */ + IMPORT_C static CWPASecuritySettingsUi* NewL( CEikonEnv& aEikEnv ); + + /** + * Destructor. + */ + IMPORT_C virtual ~CWPASecuritySettingsUi(); + + public: // New methods + + /** + * Component Validation Test. + * @return KErrNone. + */ + IMPORT_C static TInt Cvt(); + + private: // Friends + + friend class CWPASecuritySettings; + + private: // Data + + // Implementation. Owned. + CWPASecuritySettingsUiImpl* iImpl; + + }; +#endif + + +// End of File diff -r 000000000000 -r c8830336c852 accesssec_plat/wpa_security_settings_ui_api/wpa_security_settings_ui_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accesssec_plat/wpa_security_settings_ui_api/wpa_security_settings_ui_api.metaxml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,14 @@ + + +WPA Security Settings UI API +API for accessing WPA security settings UI +c++ +networkingutilities + + + + +yes +no + + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/DSS_random/dss_random.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/DSS_random/dss_random.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,216 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 8 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" + +#include "dss_random.h" + +#include "eap_am_assert.h" +#include "abs_eap_am_crypto.h" + +#include + +#include "eap_am_crypto_sha1.h" + +/** @file */ + +/** This is the block size in bytes. */ +static const u32_t BLOCK_SIZE = 160/8; + +static const u32_t DEBUG_BUFFER_SIZE = 80; + +/** + * dss_random_G() implements the G() function using modified SHA-1. + * @code + * Copied from "Multiple Examples of DSA" http://csrc.nist.gov/encryption/dss/Examples-1024bit.pdf. + * Using the revised algorithm found in the Change Notice for the generation of x values: + * XKEY= bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6 + * XSEED= 00000000 00000000 00000000 00000000 00000000 + * The first loop through step 3.2 provides: + * XVAL= bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6 + * Using the routine in Appendix 3.3 Constructing The Function G From SHA-1 + * provides: + * w[0]= 2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614 + * The following value is the updated XKEY value from step 3.2.c: + * XKEY= dd734ee0 bd0bcd3b adbaeb27 dd1eaa59 76803ecb + * The second loop through step 3.2 provides: + * XVAL= dd734ee0 bd0bcd3b adbaeb27 dd1eaa59 76803ecb + * Using the routine in Appendix 3.3 Constructing The Function G From SHA-1 + * provides: + * w[1]= 3c6c18ba cb0f6c55 babb1378 8e20d737 a3275116 + * The following value is the updated XKEY value from step 3.2.c: + * XKEY= 19df679b 881b3991 6875fea0 6b3f8191 19a78fe2 + * Step 3.3 provides the following values: + * w[0] || w[1]= 2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614 + * 3c6c18ba cb0f6c55 babb1378 8e20d737 a3275116 + * X= 47c27eb6 16dba413 91e5165b e9c5e397 7e39a15d + * @endcode +*/ +void dss_random_G(abs_eap_am_tools_c * const m_am_tools, u8_t *out, u32_t out_length, u8_t *c, u32_t c_length) +{ + u32_t *out_array = reinterpret_cast(out); + + EAP_ASSERT(out_length == BLOCK_SIZE); + EAP_ASSERT(c_length == BLOCK_SIZE); + + { + eap_am_crypto_sha1_c sha1(m_am_tools); + u32_t output_length = out_length; + + eap_status_e status = sha1.eap_sha1_dss_G_function( + c, + c_length, + out_array, + &output_length + ); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("eap_sha1_dss_G_function(): status = %d"), + status)); + } + } +} + +/** + * dss_pseudo_random() implements pseudo random function for key genearation of EAP/SIM. + * @code + * Random generator becomes as follows: + * Step 1. Choose a new, secret value for the seed-key, XKEY. + * Step 2. In hexadecimal notation let + * t = 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0. + * This is the initial value for H0 || H1 || H2 || H3 || H4 in the SHS. + * Step 3. For j = 0 to m - 1 do + * c. xj = G(t,XKEY). + * d. XKEY = (1 + XKEY + xj) mod 2^b. + * @endcode +*/ +eap_status_e dss_pseudo_random(abs_eap_am_tools_c * const m_am_tools, u8_t *out, u32_t out_length, u8_t *xkey, u32_t xkey_length) +{ + u32_t block_count = out_length/BLOCK_SIZE; + if ((out_length % BLOCK_SIZE) != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: dss_pseudo_random(): out buffer length 0x%08x not aligned to 0x%08x.\n"), + out_length, BLOCK_SIZE)); + return eap_status_data_length_not_aligned_to_block_size; + } + + if (xkey == 0 + || out == 0) + { + return eap_status_illegal_parameter; + } + + u8_t tmp_xkey[BLOCK_SIZE]; + + m_am_tools->memmove(tmp_xkey, xkey, BLOCK_SIZE); + + BN_CTX *ctx; + BIGNUM bn_mod, bn_xkey, bn_xj, bn_one, bn_160, bn_tmp; + + ctx=BN_CTX_new(); + BN_init(&bn_mod); + BN_init(&bn_tmp); + BN_init(&bn_xkey); + BN_init(&bn_xj); + BN_init(&bn_one); + BN_init(&bn_160); + + BN_set_word(&bn_one, 1); + BN_set_word(&bn_mod, 2); + BN_set_word(&bn_160, 160); + + // bn_mod = 2^160 + BN_exp(&bn_mod, &bn_mod, &bn_160, ctx); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("dss_pseudo_random(): mod"), + bn_mod.d, bn_mod.top*sizeof(BN_ULONG))); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("xkey[0]"), + xkey, xkey_length)); + + for (u32_t ind = 0; ind < block_count; ind++) + { + u8_t debug_buffer[DEBUG_BUFFER_SIZE]; + EAP_UNREFERENCED_PARAMETER(debug_buffer); + + dss_random_G(m_am_tools, &(out[ind*BLOCK_SIZE]), BLOCK_SIZE, tmp_xkey, BLOCK_SIZE); + + EAP_TRACE_FORMAT(m_am_tools, (debug_buffer, DEBUG_BUFFER_SIZE, EAPL("w[%d] "), ind)); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("dss_pseudo_random(): %s = G(xkey[%d])\n"), + debug_buffer, + ind)); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (reinterpret_cast(debug_buffer), + &(out[ind*BLOCK_SIZE]), BLOCK_SIZE)); + + if (ind+1u >= block_count) + { + break; + } + + BN_bin2bn(static_cast(tmp_xkey), BLOCK_SIZE, &bn_xkey); + + // tmp = (xkey + 1) % mod + BN_mod_add(&bn_tmp, &bn_xkey, &bn_one, &bn_mod, ctx); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("dss_pseudo_random(): tmp[%d] = (xkey[%d] + 1) % mod\n"), + ind, + ind)); + EAP_TRACE_FORMAT(m_am_tools, (debug_buffer, DEBUG_BUFFER_SIZE, EAPL("tmp[%d] "), ind)); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (reinterpret_cast(debug_buffer), + bn_tmp.d, bn_tmp.top*sizeof(BN_ULONG))); + + BN_bin2bn(static_cast(&(out[ind*BLOCK_SIZE])), BLOCK_SIZE, &bn_xj); + + // xkey = (tmp + xj) % mod + BN_mod_add(&bn_xkey, &bn_tmp, &bn_xj, &bn_mod, ctx); + + BN_bn2bin(&bn_xkey, static_cast(tmp_xkey)); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("dss_pseudo_random(): xkey[%d] = (tmp + x[%d]) % mod\n"), + ind+1u, + ind)); + EAP_TRACE_FORMAT(m_am_tools, (debug_buffer, DEBUG_BUFFER_SIZE, EAPL("xkey[%d]"), ind+1u)); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (reinterpret_cast(debug_buffer), + tmp_xkey, sizeof(tmp_xkey))); + } + + BN_free(&bn_mod); + BN_free(&bn_tmp); + BN_free(&bn_xkey); + BN_free(&bn_xj); + BN_free(&bn_one); + BN_free(&bn_160); + + BN_CTX_free(ctx); + + return eap_status_ok; +} + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/DSS_random/dss_random.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/DSS_random/dss_random.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#include "eap_am_types.h" +#include "eap_am_export.h" +#include "eap_am_tools.h" + +#ifdef __cplusplus +extern "C" { +#endif + +EAP_C_FUNC_IMPORT eap_status_e dss_pseudo_random(abs_eap_am_tools_c * const am_tools, u8_t *out, u32_t out_length, u8_t *xkey, u32_t xkey_length); + +#ifdef __cplusplus +} +#endif + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/abs_eap_am_mutex.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/abs_eap_am_mutex.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,169 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 1 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "abs_eap_am_mutex.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT abs_eap_am_mutex_c::~abs_eap_am_mutex_c() +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT abs_eap_am_mutex_c::abs_eap_am_mutex_c() +{ +} + + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_mutex_reference_c::~eap_am_mutex_reference_c() +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_mutex_reference_c::eap_am_mutex_reference_c() + : m_reference_count(0u) + , m_is_reserved(false) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT void eap_am_mutex_reference_c::add_reference() +{ + ++m_reference_count; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT void eap_am_mutex_reference_c::remove_reference() +{ + --m_reference_count; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT u32_t eap_am_mutex_reference_c::get_reference_count() +{ + return m_reference_count; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT void eap_am_mutex_reference_c::set_is_reserved(const bool is_reserved) +{ + m_is_reserved = is_reserved; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT bool eap_am_mutex_reference_c::get_is_reserved() +{ +#if defined(NO_EAP_MUTEX) + return true; +#else + return m_is_reserved; +#endif +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_mutex_base_c::~eap_am_mutex_base_c() +{ + if (m_reference != 0) + { + m_reference->remove_reference(); + + if (m_reference->get_reference_count() == 0u) + { + delete m_reference; + } + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_mutex_base_c::eap_am_mutex_base_c() + : m_reference(0) + , m_is_valid(false) +{ + m_reference = new eap_am_mutex_reference_c(); + if (m_reference == 0) + { + return; + } + m_reference->add_reference(); + m_is_valid = true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_mutex_base_c::eap_am_mutex_base_c(const eap_am_mutex_base_c * const owner) + : m_reference(0) + , m_is_valid(false) +{ + m_reference = owner->get_reference(); + m_reference->add_reference(); + m_is_valid = true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_mutex_reference_c * eap_am_mutex_base_c::get_reference() const +{ + return m_reference; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +/// This function is used in debug asserts. +/// Those will check the mutex is really reserved when critical code is entered. +EAP_FUNC_EXPORT bool eap_am_mutex_base_c::get_is_reserved() const +{ + // In Symbian we need this object to test reference flag, + // because each thread has own duplicated mutex object. + return m_reference->get_is_reserved(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +/// Returns the validity of the mutex. +EAP_FUNC_EXPORT bool eap_am_mutex_base_c::get_is_valid() const +{ + return m_is_valid; +} + +// --------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/abs_eap_am_semaphore.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/abs_eap_am_semaphore.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,139 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 2 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "abs_eap_am_semaphore.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT abs_eap_am_semaphore_c::~abs_eap_am_semaphore_c() +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT abs_eap_am_semaphore_c::abs_eap_am_semaphore_c() +{ +} + + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_semaphore_reference_c::~eap_am_semaphore_reference_c() +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_semaphore_reference_c::eap_am_semaphore_reference_c() + : m_reference_count(0u) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT void eap_am_semaphore_reference_c::add_reference() +{ + ++m_reference_count; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT void eap_am_semaphore_reference_c::remove_reference() +{ + --m_reference_count; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT u32_t eap_am_semaphore_reference_c::get_reference_count() +{ + return m_reference_count; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_semaphore_base_c::~eap_am_semaphore_base_c() +{ + if (m_reference != 0) + { + m_reference->remove_reference(); + + if (m_reference->get_reference_count() == 0u) + { + delete m_reference; + } + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_semaphore_base_c::eap_am_semaphore_base_c() + : m_reference(0) + , m_is_valid(false) +{ + m_reference = new eap_am_semaphore_reference_c(); + if (m_reference == 0) + { + return; + } + m_reference->add_reference(); + m_is_valid = true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_semaphore_base_c::eap_am_semaphore_base_c(const eap_am_semaphore_base_c * const owner) + : m_reference(0) + , m_is_valid(false) +{ + m_reference = owner->get_reference(); + m_reference->add_reference(); + m_is_valid = true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +EAP_FUNC_EXPORT eap_am_semaphore_reference_c * eap_am_semaphore_base_c::get_reference() const +{ + return m_reference; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - + +/// Returns the validity of the semaphore. +EAP_FUNC_EXPORT bool eap_am_semaphore_base_c::get_is_valid() const +{ + return m_is_valid; +} + +// --------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/bloom_algorithm/eap_am_bloom_algorithm.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/bloom_algorithm/eap_am_bloom_algorithm.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,338 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 3 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_crypto_api.h" +#include "eap_am_bloom_algorithm.h" + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_bloom_algorithm_c::~eap_am_bloom_algorithm_c() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_bloom_algorithm_c::eap_am_bloom_algorithm_c( + abs_eap_am_tools_c * const tools, + abs_eap_am_bloom_algorithm_store_c * const store, + const u32_t bloom_bit_index_size) + : m_am_tools(tools) + , m_store(store) + , m_bloom_bit_index_size(bloom_bit_index_size) + , m_is_valid(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = set_bloom_bit_index_size(bloom_bit_index_size); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: BLOOM: Illegal bit index size %d.\n"), + bloom_bit_index_size)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (m_store == 0 + || m_store->get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: BLOOM: Store is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + status = m_store->set_bloom_bit_index_size(bloom_bit_index_size); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: BLOOM: Illegal bit index size %d.\n"), + bloom_bit_index_size)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +/// This is the count of bits in the index of Bloom algorithm. +EAP_FUNC_EXPORT eap_status_e eap_am_bloom_algorithm_c::set_bloom_bit_index_size(const u32_t bloom_bit_index_size) +{ + if (bloom_bit_index_size > 32ul) + { + // This is absolut maximum value. + // Much smaller value should be used in real application. + // 32 bits long index means 2^32 bit long bit store. + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + else if (bloom_bit_index_size < 4ul) + { + // This is absolut minimum value. + // Much bigger value should be used in real application. + // 4 bits long index means 2^4 bit long bit store. + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + m_bloom_bit_index_size = bloom_bit_index_size; + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * @code + * 0 1 2 3 4 5 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | data 0 | data 1 | data 2 | data 3 | data 4 | data 5 | ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ^ ^ ^ ^ ^ + * | | | | | + * | | | | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | bit_index 0 | bit_index 1 | bit_index 2 | bit_index 3 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ +EAP_FUNC_EXPORT u32_t eap_am_bloom_algorithm_c::bloom_filter_get_index( + const u32_t queried_bit_index, + const void * const message_digest, + const u32_t message_digest_length) +{ + const u8_t * const input_data = static_cast(message_digest); + u32_t bit_index = 0ul; + u32_t start_byte = (queried_bit_index * m_bloom_bit_index_size) / 8ul; + u32_t end_byte = (queried_bit_index * m_bloom_bit_index_size + (m_bloom_bit_index_size - 1ul)) / 8ul; + + for (u32_t data_ind = start_byte; data_ind <= end_byte; data_ind++) + { + i32_t shift = ((data_ind+1ul) * 8ul) - ((queried_bit_index + 1ul) * m_bloom_bit_index_size); + if (shift < 0) + { + const u32_t pre_mask = 0xffffffff >> (32ul - m_bloom_bit_index_size); + const u8_t mask = static_cast(pre_mask >> (-shift)); + bit_index |= (input_data[data_ind] & mask) << (-shift); + } + else + { + const u8_t mask = 0xff << shift; + bit_index |= (input_data[data_ind] & mask) >> (shift); + } + } + + return bit_index; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_bloom_algorithm_c::bloom_filter_create_message_digest( + const void * const blob, + const u32_t blob_length, + void * const message_digest, + u32_t * const message_digest_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + crypto_sha1_c sha1(m_am_tools); + + if (sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = sha1.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (message_digest == 0 + || message_digest_length == 0 + || *message_digest_length < sha1.get_digest_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + *message_digest_length = sha1.get_digest_length(); + + status = sha1.hash_update(blob, blob_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_final( + message_digest, + message_digest_length); + + EAP_ASSERT_ALWAYS(sha1.get_digest_length() == *message_digest_length); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("BLOOM: blob"), + blob, + blob_length)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_bloom_algorithm_c::bloom_filter_check_is_blob_new( + const void * const blob, + const u32_t blob_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_store->bloom_filter_check_does_bit_store_exists() != eap_status_ok) + { + // No valid BIT file. blobs are assumed new. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + static const u32_t DIGEST_LENGTH = 32ul; + + u8_t message_digest[DIGEST_LENGTH]; + u32_t message_digest_length = DIGEST_LENGTH; + + eap_status_e status = bloom_filter_create_message_digest( + blob, + blob_length, + message_digest, + &message_digest_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + for (u32_t ind = 0; ind < (message_digest_length * 8ul)/m_bloom_bit_index_size; ind++) + { + u32_t bit_index = bloom_filter_get_index(ind, message_digest, message_digest_length); + + if (m_store->bloom_filter_get_bit_index(bit_index) == 0) + { + // Because bit is NOT set this blob is new. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + + // Because all bits are set this blob is most probably already used. + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_bloom_algorithm_c::bloom_filter_set_blob_is_used( + const void * const blob, + const u32_t blob_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_store->bloom_filter_check_does_bit_store_exists() != eap_status_ok) + { + // No valid BIT file. blobs are assumed new. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + static const u32_t DIGEST_LENGTH = 32ul; + + u8_t message_digest[DIGEST_LENGTH]; + u32_t message_digest_length = DIGEST_LENGTH; + + eap_status_e status = bloom_filter_create_message_digest( + blob, + blob_length, + message_digest, + &message_digest_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + for (u32_t ind = 0; ind < (message_digest_length * 8ul)/m_bloom_bit_index_size; ind++) + { + u32_t bit_index = bloom_filter_get_index(ind, message_digest, message_digest_length); + + status = m_store->bloom_filter_set_bit_index(bit_index); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_bloom_algorithm_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_bloom_algorithm_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/crypto/md4/eap_am_crypto_md4.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/crypto/md4/eap_am_crypto_md4.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,762 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 4 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_am_crypto_md4.h" + +//-------------------------------------------------- + +#if 1 + #define EAP_MD4_TRACE_DEBUG EAP_TRACE_DEBUG +#else + #define EAP_MD4_TRACE_DEBUG(tools, flags, params) +#endif + +#if defined(USE_EAP_TRACE) + static const u32_t EAP_TRACE_MASK_MD4 = eap_am_tools_c::eap_trace_mask_crypto_md4; +#endif //#if defined(USE_EAP_TRACE) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_crypto_md4_c::~eap_am_crypto_md4_c() +{ + hash_cleanup(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_crypto_md4_c::eap_am_crypto_md4_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_saved_data(tools) + , m_full_hashed_data_length(0ul) + , m_is_valid(false) +{ + m_H[0] = 0; + m_W_in_host_order[0] = 0; + + if (m_saved_data.get_is_valid() == false) + { + return; + } + + eap_status_e status = hash_init(); + if (status != eap_status_ok) + { + return; + } + + set_is_valid(); +} + + +//------------------------------------------------------------ + +/** + * The set_is_invalid() function sets the state of the eap_am_crypto_md4_c + * object invalid. + * The eap_am_crypto_md4_c object calls this function after it is initialized. + */ +EAP_FUNC_EXPORT void eap_am_crypto_md4_c::set_is_invalid() +{ + m_is_valid = false; +} + +//------------------------------------------------------------ + +/** + * The set_is_valid() function sets the state of the eap_am_crypto_md4_c + * object valid. + * The eap_am_crypto_md4_c object calls this function after it is initialized. + */ +EAP_FUNC_EXPORT void eap_am_crypto_md4_c::set_is_valid() +{ + m_is_valid = true; +} + +//------------------------------------------------------------ + +/** + * The get_is_valid() function returns the status of the eap_am_crypto_md4_c + * object. + * True indicates the object is allocated successfully. + */ +EAP_FUNC_EXPORT bool eap_am_crypto_md4_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +inline u32_t eap_am_crypto_md4_c::eap_md4_rotate_left( + const u32_t value, + const u32_t shift + ) +{ + return (value << shift) | (value >> (32ul - shift)); +} + +//-------------------------------------------------- + +inline void eap_am_crypto_md4_c::eap_md4_FF( + const u32_t index, + u32_t * const A, + const u32_t B, + const u32_t C, + const u32_t D, + const u32_t X, + const u32_t S + ) +{ + EAP_UNREFERENCED_PARAMETER(index); + + *A += eap_md4_F(B, C, D) + X; + *A = eap_md4_rotate_left(*A, S); + + EAP_MD4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_MD4, + (EAPL("MD4: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\t% 8d\n"), + index, *A, B, C, D, X, S)); +} + +//-------------------------------------------------- + +inline void eap_am_crypto_md4_c::eap_md4_GG( + const u32_t index, + u32_t * const A, + const u32_t B, + const u32_t C, + const u32_t D, + const u32_t X, + const u32_t S + ) +{ + EAP_UNREFERENCED_PARAMETER(index); + + *A += eap_md4_G(B, C, D) + X + 0x5a827999; + *A = eap_md4_rotate_left(*A, S); + + EAP_MD4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_MD4, + (EAPL("MD4: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\t% 8d\n"), + index, *A, B, C, D, X, S)); +} + +//-------------------------------------------------- + +inline void eap_am_crypto_md4_c::eap_md4_HH( + const u32_t index, + u32_t * const A, + const u32_t B, + const u32_t C, + const u32_t D, + const u32_t X, + const u32_t S + ) +{ + EAP_UNREFERENCED_PARAMETER(index); + + *A += eap_md4_H(B, C, D) + X + 0x6ed9eba1; + *A = eap_md4_rotate_left(*A, S); + + EAP_MD4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_MD4, + (EAPL("MD4: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\t% 8d\n"), + index, *A, B, C, D, X, S)); +} + +//-------------------------------------------------- + +inline u32_t eap_am_crypto_md4_c::eap_md4_F( + const u32_t X, + const u32_t Y, + const u32_t Z + ) +{ + return (X & Y) | ((~X) & Z); +} + +//-------------------------------------------------- + +inline u32_t eap_am_crypto_md4_c::eap_md4_G( + const u32_t X, + const u32_t Y, + const u32_t Z + ) +{ + return (X & Y) | (X & Z) | (Y & Z); +} + + +//-------------------------------------------------- + +inline u32_t eap_am_crypto_md4_c::eap_md4_H( + const u32_t X, + const u32_t Y, + const u32_t Z + ) +{ + return (X ^ Y ^ Z); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_md4_c::eap_md4_process_data( + const u32_t * const W, + const u32_t W_count + ) +{ + if (W == 0 + //|| (reinterpret_cast(W) % sizeof(u32_t)) != 0 + || W_count == 0 + || (W_count % EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT) != 0) + { + EAP_ASSERT_ANYWAY; + EAP_SYSTEM_DEBUG_BREAK(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + eap_status_e status = eap_status_ok; + + // Array of 16 temporary 32-bit unsigned integers. + u32_t count = W_count / EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT; + + for (u32_t ind = 0ul; ind < count; ind++) + { + for (u32_t ind_W = 0ul; ind_W < EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT + ; ind_W++) + { + // Here we must read data in 8-bit blocks bacause W can be aligned at any position. + const u8_t * const data = reinterpret_cast(&W[ind*EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT+ind_W]); + m_W_in_host_order[ind_W] + = (data[0] << 0) + | (data[1] << 8) + | (data[2] << 16) + | (data[3] << 24); + } // for() + + status = eap_md4_transform_host_order( + m_W_in_host_order, + EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } // for() + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_md4_c::eap_md4_transform_host_order( + const u32_t * const W, + const u32_t W_count + ) +{ + u32_t A = m_H[0]; + u32_t B = m_H[1]; + u32_t C = m_H[2]; + u32_t D = m_H[3]; + + if (W == 0 + //|| (reinterpret_cast(W) % sizeof(u32_t)) != 0 + || W_count != EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT) + { + EAP_ASSERT_ANYWAY; + EAP_SYSTEM_DEBUG_BREAK(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t * const X = W; + +#if defined(_DEBUG) + + EAP_MD4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_MD4, + (EAPL("MD4: A=%08x\tB=%08x\tC=%08x\tD=%08x\n"), + A, B, C, D)); + + u32_t ind; + for (ind = 0ul; ind < W_count; ind++) + { + EAP_MD4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_MD4, + (EAPL("MD4: W[%d]=%08x\n"), + ind, + W[ind])); + } // for() + + EAP_MD4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_MD4, + (EAPL("MD4: \n"))); + + for (ind = 0ul; ind < sizeof(X)/sizeof(X[0]); ind++) + { + EAP_MD4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_MD4, + (EAPL("MD4: X[%d]=%08x\n"), + ind, + X[ind])); + } // for() + + EAP_MD4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_MD4, + (EAPL("MD4: % 5s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\n"), + "index", "A", "B", "C", "D", "X", "shift")); + +#endif //#if defined(_DEBUG) + + + eap_md4_FF( 1, &A, B, C, D, X[ 0], eap_md4_const_S11); + eap_md4_FF( 2, &D, A, B, C, X[ 1], eap_md4_const_S12); + eap_md4_FF( 3, &C, D, A, B, X[ 2], eap_md4_const_S13); + eap_md4_FF( 4, &B, C, D, A, X[ 3], eap_md4_const_S14); + eap_md4_FF( 5, &A, B, C, D, X[ 4], eap_md4_const_S11); + eap_md4_FF( 6, &D, A, B, C, X[ 5], eap_md4_const_S12); + eap_md4_FF( 7, &C, D, A, B, X[ 6], eap_md4_const_S13); + eap_md4_FF( 8, &B, C, D, A, X[ 7], eap_md4_const_S14); + eap_md4_FF( 9, &A, B, C, D, X[ 8], eap_md4_const_S11); + eap_md4_FF(10, &D, A, B, C, X[ 9], eap_md4_const_S12); + eap_md4_FF(11, &C, D, A, B, X[10], eap_md4_const_S13); + eap_md4_FF(12, &B, C, D, A, X[11], eap_md4_const_S14); + eap_md4_FF(13, &A, B, C, D, X[12], eap_md4_const_S11); + eap_md4_FF(14, &D, A, B, C, X[13], eap_md4_const_S12); + eap_md4_FF(15, &C, D, A, B, X[14], eap_md4_const_S13); + eap_md4_FF(16, &B, C, D, A, X[15], eap_md4_const_S14); + + eap_md4_GG(17, &A, B, C, D, X[ 0], eap_md4_const_S21); + eap_md4_GG(18, &D, A, B, C, X[ 4], eap_md4_const_S22); + eap_md4_GG(19, &C, D, A, B, X[ 8], eap_md4_const_S23); + eap_md4_GG(20, &B, C, D, A, X[12], eap_md4_const_S24); + eap_md4_GG(21, &A, B, C, D, X[ 1], eap_md4_const_S21); + eap_md4_GG(22, &D, A, B, C, X[ 5], eap_md4_const_S22); + eap_md4_GG(23, &C, D, A, B, X[ 9], eap_md4_const_S23); + eap_md4_GG(24, &B, C, D, A, X[13], eap_md4_const_S24); + eap_md4_GG(25, &A, B, C, D, X[ 2], eap_md4_const_S21); + eap_md4_GG(26, &D, A, B, C, X[ 6], eap_md4_const_S22); + eap_md4_GG(27, &C, D, A, B, X[10], eap_md4_const_S23); + eap_md4_GG(28, &B, C, D, A, X[14], eap_md4_const_S24); + eap_md4_GG(29, &A, B, C, D, X[ 3], eap_md4_const_S21); + eap_md4_GG(30, &D, A, B, C, X[ 7], eap_md4_const_S22); + eap_md4_GG(31, &C, D, A, B, X[11], eap_md4_const_S23); + eap_md4_GG(32, &B, C, D, A, X[15], eap_md4_const_S24); + + eap_md4_HH(33, &A, B, C, D, X[ 0], eap_md4_const_S31); + eap_md4_HH(34, &D, A, B, C, X[ 8], eap_md4_const_S32); + eap_md4_HH(35, &C, D, A, B, X[ 4], eap_md4_const_S33); + eap_md4_HH(36, &B, C, D, A, X[12], eap_md4_const_S34); + eap_md4_HH(37, &A, B, C, D, X[ 2], eap_md4_const_S31); + eap_md4_HH(38, &D, A, B, C, X[10], eap_md4_const_S32); + eap_md4_HH(39, &C, D, A, B, X[ 6], eap_md4_const_S33); + eap_md4_HH(40, &B, C, D, A, X[14], eap_md4_const_S34); + eap_md4_HH(41, &A, B, C, D, X[ 1], eap_md4_const_S31); + eap_md4_HH(42, &D, A, B, C, X[ 9], eap_md4_const_S32); + eap_md4_HH(43, &C, D, A, B, X[ 5], eap_md4_const_S33); + eap_md4_HH(44, &B, C, D, A, X[13], eap_md4_const_S34); + eap_md4_HH(45, &A, B, C, D, X[ 3], eap_md4_const_S31); + eap_md4_HH(46, &D, A, B, C, X[11], eap_md4_const_S32); + eap_md4_HH(47, &C, D, A, B, X[ 7], eap_md4_const_S33); + eap_md4_HH(48, &B, C, D, A, X[15], eap_md4_const_S34); + + m_H[0] += A; + m_H[1] += B; + m_H[2] += C; + m_H[3] += D; + + EAP_MD4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_MD4, + (EAPL("MD4: digest=\t%08x\t%08x\t%08x\t%08x\n"), + m_H[0], m_H[1], m_H[2], m_H[3])); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_md4_c::copy_message_digest( + void * const output, + u32_t * const max_output_size) +{ + if (output == 0 + || max_output_size == 0 + || *max_output_size < EAP_AM_CRYPTO_MD4_DIGEST_BUFFER_BYTE_SIZE) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + +#if defined(EAP_LITTLE_ENDIAN) + + m_am_tools->memmove(output, m_H, EAP_AM_CRYPTO_MD4_DIGEST_BUFFER_BYTE_SIZE); + +#elif defined(EAP_BIG_ENDIAN) + + // We must change the data from host order to network order. + u32_t * const tmp_H = static_cast(output); + for (u32_t ind = 0ul; ind < EAP_AM_CRYPTO_MD4_DIGEST_BUFFER_u32_COUNT + ; ind++) + { + tmp_H[ind] = eap_htonl(m_H[ind]); + } // for() + +#else +#error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant \ +(i386)) or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). +#endif + + *max_output_size = EAP_AM_CRYPTO_MD4_DIGEST_BUFFER_BYTE_SIZE; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------- + +/** + * This function returns the size of message digest of HASH-algorithm. + */ +EAP_FUNC_EXPORT u32_t eap_am_crypto_md4_c::get_digest_length() +{ + return EAP_AM_CRYPTO_MD4_DIGEST_BUFFER_BYTE_SIZE; +} + +//-------------------------------------------------- + +/** + * This function returns the size of block of HASH-algorithm. + */ +EAP_FUNC_EXPORT u32_t eap_am_crypto_md4_c::get_block_size() +{ + return EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE; +} + +//-------------------------------------------------- + +/** + * This function initializes the context of MD4-algorithm. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_md4_c::hash_init() +{ + m_full_hashed_data_length = 0ul; + + m_H[0] = static_cast(EAP_MD4_INIT_H0); + m_H[1] = static_cast(EAP_MD4_INIT_H1); + m_H[2] = static_cast(EAP_MD4_INIT_H2); + m_H[3] = static_cast(EAP_MD4_INIT_H3); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * This function updates the context of MD4-algorithm with data. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_md4_c::hash_update( + const void * const data, + const u32_t data_length) +{ + eap_status_e status = eap_status_ok; + u32_t prosessed_data_length = 0ul; + + m_full_hashed_data_length += data_length; + + EAP_MD4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_MD4, + (EAPL("MD4: Processed data length %u\n"), + m_full_hashed_data_length)); + + if (m_saved_data.get_is_valid_data() == true + && m_saved_data.get_data_length() > 0ul) + { + // Here we have remaining data to process from previous call + // of hash_update(). + u32_t needed_data_length = EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE + - m_saved_data.get_data_length(); + if (needed_data_length > data_length) + { + // Not enough input data. + needed_data_length = data_length; + } + + prosessed_data_length = needed_data_length; + status = m_saved_data.add_data(data, needed_data_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_saved_data.get_data_length() + == EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE) + { + // Enough data to process. + // Just one block of integers in W array. + status = eap_md4_process_data( + reinterpret_cast( + m_saved_data.get_data( + m_saved_data.get_data_length())), + EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT + ); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_saved_data.reset(); + } + + EAP_ASSERT(m_saved_data.get_is_valid_data() == false + || m_saved_data.get_data_length() + <= EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE); + } + + u32_t remaining_data_length = data_length - prosessed_data_length; + u32_t full_block_count = remaining_data_length + / EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE; + + if (full_block_count > 0ul) + { + // Here we have full blocks to process. + status = eap_md4_process_data( + reinterpret_cast( + static_cast(data)+prosessed_data_length), + full_block_count * EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT + ); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + prosessed_data_length += sizeof(u32_t) * full_block_count + * EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT; + } + + if (data_length > prosessed_data_length) + { + // Save the remaining data. + status = m_saved_data.add_data( + static_cast(data)+prosessed_data_length, + data_length-prosessed_data_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +/** + * This function writes the message digest to buffer. + * @param Length is set if md_length_or_null is non-NULL. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_md4_c::hash_final( + void * const message_digest, + u32_t *md_length_or_null) +{ + eap_status_e status = eap_status_ok; + + if (message_digest == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // First add the one bit. We use one byte 0x80. + u8_t bit_pad = 0x80; + status = m_saved_data.add_data(&bit_pad, sizeof(bit_pad)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Here we may have remaining data to process from previous call + // of hash_update(). + u32_t min_data_length = m_saved_data.get_data_length() + sizeof(u64_t); + u32_t padding_zero_count = 0ul; + u32_t block_count = min_data_length / EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE; + if ((min_data_length % EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE) != 0) + { + // Last block is not full. + ++block_count; + } + padding_zero_count = (block_count*EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE) + - min_data_length; + + // Now we need to pad the remaining data. + u32_t data_length = m_saved_data.get_data_length(); + status = m_saved_data.set_buffer_length(data_length+padding_zero_count); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_saved_data.set_data_length(data_length+padding_zero_count); + + u8_t * const padding = m_saved_data.get_data_offset(data_length, padding_zero_count); + if (padding == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + m_am_tools->memset( + padding, + 0, + padding_zero_count); + + // And finally the length of the hashed data is added to block. + // Note the length is in bits. + +#if defined(EAP_LITTLE_ENDIAN) + u64_t full_hashed_data_length = eap_shift_left_64_bit(m_full_hashed_data_length, 3ul); +#elif defined(EAP_BIG_ENDIAN) + u64_t full_hashed_data_length = eap_htonll(eap_shift_left_64_bit(m_full_hashed_data_length, 3ul)); +#else +#error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ +or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). +#endif + status = m_saved_data.add_data( + &full_hashed_data_length, + sizeof(full_hashed_data_length)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT(m_saved_data.get_data_length() + >= EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE + && (m_saved_data.get_data_length() + % EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE) == 0); + + u32_t full_block_count = m_saved_data.get_data_length() + / EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE; + + status = eap_md4_process_data( + reinterpret_cast( + m_saved_data.get_data( + m_saved_data.get_data_length())), + full_block_count * EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT + ); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_saved_data.reset(); + + + u32_t output_length = 0ul; + if (md_length_or_null == 0) + { + // Let's use temporary length variable. + output_length = EAP_AM_CRYPTO_MD4_DIGEST_BUFFER_BYTE_SIZE; + md_length_or_null = &output_length; + } + + status = copy_message_digest( + message_digest, + md_length_or_null); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * This function cleans up the MD4 context. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_md4_c::hash_cleanup() +{ + m_saved_data.reset(); + m_full_hashed_data_length = 0ul; + m_am_tools->memset(m_H, 0, EAP_AM_CRYPTO_MD4_DIGEST_BUFFER_BYTE_SIZE); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * This function copies the context of MD4. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_md4_c::copy_context( + const eap_variable_data_c * const saved_data, + const u64_t full_hashed_data_length, + const u32_t * const H, + const u32_t * const W_in_host_order) +{ + if (saved_data->get_is_valid_data() == true) + { + eap_status_e status = m_saved_data.set_copy_of_buffer(saved_data); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // No saved data. Just reset. + m_saved_data.reset(); + } + + m_full_hashed_data_length = full_hashed_data_length; + + m_am_tools->memmove(m_H, H, sizeof(m_H)); + + m_am_tools->memmove(m_W_in_host_order, W_in_host_order, sizeof(m_W_in_host_order)); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * This function copies the context of MD4. + */ +EAP_FUNC_EXPORT eap_am_crypto_md4_c * eap_am_crypto_md4_c::copy() +{ + eap_am_crypto_md4_c * const md4 = new eap_am_crypto_md4_c(m_am_tools); + if (md4 == 0 + || md4->get_is_valid() == false) + { + delete md4; + return 0; + } + + eap_status_e status = md4->copy_context(&m_saved_data, m_full_hashed_data_length, m_H, m_W_in_host_order); + if (status != eap_status_ok) + { + delete md4; + return 0; + } + + return md4; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/crypto/random/eap_am_random_test.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/crypto/random/eap_am_random_test.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,263 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 5 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_random_test.h" + +//-------------------------------------------------- + +#if 1 + #define EAP_TEST_RANDOM_TRACE_DEBUG EAP_TRACE_DEBUG + #define EAP_TEST_RANDOM_TRACE_DATA_DEBUG EAP_TRACE_DATA_DEBUG +#else + #define EAP_TEST_RANDOM_TRACE_DEBUG(tools, flags, params) + #define EAP_TEST_RANDOM_TRACE_DATA_DEBUG(tools, flags, prefix, data, data_length) +#endif + +static const u32_t EAP_TRACE_MASK_TEST_RANDOM = eap_am_tools_c::eap_trace_mask_crypto_test_random; + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_random_test_c::~eap_am_random_test_c() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_random_test_c::eap_am_random_test_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_state(tools) + , m_hash(tools) + , m_rand_counter(0ul) + , m_do_seeding(false) + , m_is_valid(false) +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_random_test_c::set_do_reseeding(const bool does_reseeding_when_true) +{ + m_do_seeding = does_reseeding_when_true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_random_test_c::init( + const void * const bytes, + const u32_t length) +{ + if (m_is_valid == true) + { + // Already initialized. + return eap_status_ok; + } + + m_state.reset(); + + eap_status_e status = m_state.set_buffer_length(m_hash.get_digest_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_state.set_data_length(m_state.get_buffer_length()); + + if (m_state.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memset(m_state.get_data(m_state.get_data_length()), 0, m_state.get_data_length()); + + m_is_valid = true; + + if (length > 0ul) + { + status = internal_rand_seed( + bytes, + length); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_random_test_c::internal_rand_seed( + const void * const bytes, + const u32_t length) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_ASSERT_ALWAYS(m_is_valid == true); + + status = m_hash.hash_init(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_hash.hash_update( + m_state.get_data(m_state.get_data_length()), + m_state.get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_hash.hash_update( + bytes, + length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t md_length = m_state.get_data_length(); + + status = m_hash.hash_final( + m_state.get_data(m_state.get_data_length()), + &md_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT(md_length == m_state.get_data_length()); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_random_test_c::add_rand_seed( + const void * const bytes, + const u32_t length) +{ + eap_status_e status = eap_status_ok; + + EAP_ASSERT_ALWAYS(m_is_valid == true); + + if (m_do_seeding == true) + { + EAP_TEST_RANDOM_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_MASK_TEST_RANDOM, + (EAPL("PSEUDO RANDOM SEED:"), + bytes, + length)); + + status = internal_rand_seed( + bytes, + length); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_random_test_c::get_rand_bytes( + void * const p_bytes, + const u32_t length) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_ASSERT_ALWAYS(m_is_valid == true); + + if (p_bytes == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (length == 0ul) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + u32_t count = length / m_state.get_data_length(); + if ((length % m_state.get_data_length()) != 0) + { + ++count; + } + + u32_t missing_bytes = length; + u8_t * const bytes = static_cast(p_bytes); + + for (u32_t ind = 0ul; ind < count; ind++) + { + ++m_rand_counter; + + status = internal_rand_seed( + &m_rand_counter, + sizeof(m_rand_counter)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = internal_rand_seed( + m_state.get_data(m_state.get_data_length()), + m_state.get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t copied_data = missing_bytes; + if (copied_data >= m_state.get_data_length()) + { + copied_data = m_state.get_data_length(); + } + + m_am_tools->memmove(bytes+(m_state.get_data_length()*ind), m_state.get_data(copied_data), copied_data); + + missing_bytes -= copied_data; + } + + EAP_TEST_RANDOM_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_MASK_TEST_RANDOM, + (EAPL("PSEUDO RANDOM DATA:"), + p_bytes, + length)); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + +//-------------------------------------------------- +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/crypto/rc4/eap_am_crypto_rc4.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/crypto/rc4/eap_am_crypto_rc4.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,274 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 6 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_am_crypto_rc4.h" + +//------------------------------------------------------------ + +#if 1 + #define EAP_RC4_TRACE_DEBUG EAP_TRACE_DEBUG +#else + #define EAP_RC4_TRACE_DEBUG(tools, flags, params) +#endif + +#if defined(USE_EAP_TRACE) + static const u32_t EAP_TRACE_MASK_RC4 = eap_am_tools_c::eap_trace_mask_crypto_rc4; +#endif //#if defined(USE_EAP_TRACE) + +//------------------------------------------------------------ + +/** + * Destructor resets the used internal buffers. + */ +EAP_FUNC_EXPORT eap_am_crypto_rc4_c::~eap_am_crypto_rc4_c() +{ + cleanup(); +} + +//------------------------------------------------------------ + +/** + * Constructor initializes the used internal buffers. + */ +EAP_FUNC_EXPORT eap_am_crypto_rc4_c::eap_am_crypto_rc4_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_ind_i(0ul) + , m_ind_j(0ul) + , m_is_valid(false) +{ + m_state[0] = 0; + set_is_valid(); +} + +//-------------------------------------------------- + +/** + * This function cleans up the RC4 context. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_rc4_c::cleanup() +{ + m_ind_i = 0ul; + m_ind_j = 0ul; + m_is_valid = false; + m_am_tools->memset(m_state, 0, eap_am_crypto_rc4_constant_state_size); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------------ + +/** + * The set_is_invalid() function sets the state of the eap_am_crypto_rc4_c + * object invalid. + * The eap_am_crypto_rc4_c object calls this function after it is initialized. + */ +EAP_FUNC_EXPORT void eap_am_crypto_rc4_c::set_is_invalid() +{ + m_is_valid = false; +} + +//------------------------------------------------------------ + +/** + * The set_is_valid() function sets the state of the eap_am_crypto_rc4_c + * object valid. + * The eap_am_crypto_rc4_c object calls this function after it is initialized. + */ +EAP_FUNC_EXPORT void eap_am_crypto_rc4_c::set_is_valid() +{ + m_is_valid = true; +} + +//------------------------------------------------------------ + +/** + * The get_is_valid() function returns the status of the eap_am_crypto_rc4_c + * object. + * True indicates the object is allocated successfully. + */ +EAP_FUNC_EXPORT bool eap_am_crypto_rc4_c::get_is_valid() +{ + return m_is_valid; +} + +//------------------------------------------------------------ + +/** + * Function swaps the values. + */ +EAP_FUNC_EXPORT inline void eap_am_crypto_rc4_c::swap( + u8_t * const s_i, + u8_t * const s_j) +{ + const u8_t tmp = *s_i; + *s_i = *s_j; + *s_j = tmp; +} + +//------------------------------------------------------------ + +/** + * This function sets the RC4 key. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_rc4_c::set_key( + const eap_variable_data_c * const p_key) +{ + u32_t ind = 0ul; + + // Note the size of ind must be bigger than 8-bits. + for (ind = 0ul; ind < eap_am_crypto_rc4_constant_state_size + ; ind++) + { + m_state[ind] = static_cast(ind); + + EAP_RC4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_RC4, + (EAPL("RC4: m_state[%d]=0x%02x\n"), + ind, + m_state[ind])); + } // for() + + const u32_t key_length = p_key->get_data_length(); + const u8_t * const key = p_key->get_data(key_length); + + m_ind_i = 0ul; + m_ind_j = 0ul; + + // Note the size of ind must be bigger than 8-bits. + for (ind = 0ul; ind < eap_am_crypto_rc4_constant_state_size + ; ind++) + { + m_ind_j = static_cast( + static_cast(m_ind_j) + + static_cast(m_state[ind]) + + static_cast(key[ind % key_length])); + + swap(&(m_state[ind]), &(m_state[m_ind_j])); + + EAP_RC4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_RC4, + (EAPL("RC4: swapped m_state[%d]=0x%02x and m_state[%d]=0x%02x\n"), + ind, + m_state[ind], + m_ind_j, + m_state[m_ind_j])); + } // for() + + m_ind_i = 0ul; + m_ind_j = 0ul; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------------ + +/** + */ +inline u8_t eap_am_crypto_rc4_c::get_random_byte() +{ + m_ind_i = static_cast(m_ind_i + 1ul); + + m_ind_j = static_cast(m_ind_j + m_state[m_ind_i]); + + swap(&(m_state[m_ind_i]), &(m_state[m_ind_j])); + + u8_t random_byte = m_state[static_cast(m_state[m_ind_i] + + m_state[m_ind_j])]; + + EAP_RC4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_RC4, + (EAPL("RC4: random_byte=0x%02x\n"), + random_byte)); + + return random_byte; +} + +//------------------------------------------------------------ + +/** + * This function does RC4 encryption. + */ +inline eap_status_e eap_am_crypto_rc4_c::process_data( + const void * const p_data_in, + void * const p_data_out, + const u32_t data_length) +{ + const u8_t * const data_in = static_cast(p_data_in); + u8_t * const data_out = static_cast(p_data_out); + + for (u32_t ind = 0ul; ind < data_length; ind++) + { + EAP_RC4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_RC4, + (EAPL("RC4: data_in[%d]=0x%02x\n"), + ind, + data_in[ind])); + + data_out[ind] = static_cast(data_in[ind] ^ get_random_byte()); + + EAP_RC4_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_RC4, + (EAPL("RC4: data_out[%d]=0x%02x\n"), + ind, + data_out[ind])); + } // for() + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------------ + +/** + * This function does RC4 encryption. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_rc4_c::encrypt_data( + const void * const p_data_in, + void * const p_data_out, + const u32_t data_length) +{ + return EAP_STATUS_RETURN( + m_am_tools, + process_data(p_data_in, p_data_out, data_length)); +} + +//------------------------------------------------------------ + +/** + * This function does RC4 decryption. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_rc4_c::decrypt_data( + const void * const p_data_in, + void * const p_data_out, + const u32_t data_length) +{ + return EAP_STATUS_RETURN( + m_am_tools, + process_data(p_data_in, p_data_out, data_length)); +} + +//------------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/crypto/sha-256/eap_am_crypto_sha_256.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/crypto/sha-256/eap_am_crypto_sha_256.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,742 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 578 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_am_crypto_sha_256.h" + +//-------------------------------------------------- + +#if 0 + #define EAP_SHA_256_TRACE_DEBUG EAP_TRACE_DEBUG + #define EAP_SHA_256_TRACE_DATA_DEBUG EAP_TRACE_DATA_DEBUG +#else + #define EAP_SHA_256_TRACE_DEBUG(tools, flags, params) + #define EAP_SHA_256_TRACE_DATA_DEBUG(object_name, flags, _parameter_list_) +#endif + +#if defined(USE_EAP_TRACE) + static const u32_t EAP_TRACE_MASK_SHA_256 = TRACE_FLAGS_DEFAULT; +#endif //#if defined(USE_EAP_TRACE) + + +const unsigned long eap_am_crypto_sha_256_c::m_K[eap_am_crypto_sha_256_c::EAP_AM_CRYPTO_SHA_256_SCHEDULE_u32_COUNT] = +{ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_crypto_sha_256_c::~eap_am_crypto_sha_256_c() +{ + hash_cleanup(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_crypto_sha_256_c::eap_am_crypto_sha_256_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_saved_data(tools) + , m_full_hashed_data_length(0ul) + , m_is_valid(false) +{ + m_H[0] = 0; + m_T[0] = 0; + m_M_in_host_order[0] = 0; + + if (m_saved_data.get_is_valid() == false) + { + #if defined(USE_EAP_TRACE) + EAP_UNREFERENCED_PARAMETER(EAP_TRACE_MASK_SHA_256); + #endif //#if defined(USE_EAP_TRACE) + return; + } + + eap_status_e status = hash_init(); + if (status != eap_status_ok) + { + return; + } + + set_is_valid(); +} + +//------------------------------------------------------------ + +/** + * The set_is_invalid() function sets the state of the eap_am_crypto_sha_256_c + * object invalid. + * The eap_am_crypto_sha_256_c object calls this function after it is initialized. + */ +EAP_FUNC_EXPORT void eap_am_crypto_sha_256_c::set_is_invalid() +{ + m_is_valid = false; +} + +//------------------------------------------------------------ + +/** + * The set_is_valid() function sets the state of the eap_am_crypto_sha_256_c + * object valid. + * The eap_am_crypto_sha_256_c object calls this function after it is initialized. + */ +EAP_FUNC_EXPORT void eap_am_crypto_sha_256_c::set_is_valid() +{ + m_is_valid = true; +} + +//------------------------------------------------------------ + +/** + * The get_is_valid() function returns the status of the eap_am_crypto_sha_256_c + * object. + * True indicates the object is allocated successfully. + */ +EAP_FUNC_EXPORT bool eap_am_crypto_sha_256_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +inline u32_t eap_am_crypto_sha_256_c::eap_sha_256_rotate( + const u32_t value, + const u32_t shift + ) +{ + return (value >> shift) | (value << (32ul - shift)); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e +eap_am_crypto_sha_256_c::eap_sha_256_process_data_host_order( + const u32_t * M, + u32_t M_count + ) +{ + u32_t A; + u32_t B; + u32_t C; + u32_t D; + u32_t E; + u32_t F; + u32_t G; + u32_t H; + + u32_t S0; + u32_t S1; + u32_t T1; + u32_t T2; + + u32_t W[EAP_AM_CRYPTO_SHA_256_SCHEDULE_u32_COUNT]; + + if (M == 0 + || M_count == 0 + || (M_count % EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT) != 0) + { + EAP_ASSERT_ANYWAY; + EAP_SYSTEM_DEBUG_BREAK(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + do + { + m_am_tools->memmove(W, M, sizeof(u32_t) * EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT); // Initialize 16 W words. + + { + // Extend 16 W words to 64 W words. + for (u32_t ind = EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT; ind != EAP_AM_CRYPTO_SHA_256_SCHEDULE_u32_COUNT; ind++) + { + S0 = eap_sha_256_rotate(W[ind-15], 7) ^ eap_sha_256_rotate(W[ind-15], 18) ^ (W[ind-15] >> 3); + S1 = eap_sha_256_rotate(W[ind-2], 17) ^ eap_sha_256_rotate(W[ind-2], 19) ^ (W[ind-2] >> 10); + W[ind] = W[ind-16] + S0 + W[ind-7] + S1; + } + } + + + #if defined(_DEBUG) + { + for (u32_t ind = 0ul; ind != M_count; ind++) + { + EAP_SHA_256_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA_256, + (EAPL("SHA_256: M[%d]=%08x, W[%d]=%08x\n"), + ind, + M[ind], + ind, + W[ind])); + } // for() + + EAP_SHA_256_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA_256, + (EAPL("SHA_256: H[0]=0x%08x, H[1]=0x%08x, H[2]=0x%08x, H[3]=0x%08x, H[4]=0x%08x, H[5]=0x%08x, H[6]=0x%08x, H[7]=0x%08x\n"), + m_H[0], + m_H[1], + m_H[2], + m_H[3], + m_H[4], + m_H[5], + m_H[6], + m_H[7])); + EAP_SHA_256_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA_256, + (EAPL("SHA_256:\t% 4s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\n"), + "t", "A", "B", "C", "D", "E", "F", "G", "H", "T1", "T2", "S0", "S1")); + } + #endif //#if defined(_DEBUG) + + + A = m_H[0]; + B = m_H[1]; + C = m_H[2]; + D = m_H[3]; + E = m_H[4]; + F = m_H[5]; + G = m_H[6]; + H = m_H[7]; + + + { + for(u32_t ind = 0; ind != EAP_AM_CRYPTO_SHA_256_SCHEDULE_u32_COUNT; ind++) + { + S0 = eap_sha_256_rotate(A, 2) ^ eap_sha_256_rotate(A, 13) ^ eap_sha_256_rotate(A, 22); + T2 = S0 + ((A & B) ^ (A & C) ^ (B & C)); + S1 = eap_sha_256_rotate(E, 6) ^ eap_sha_256_rotate(E, 11) ^ eap_sha_256_rotate(E, 25); + T1 = H + S1 + ((E & F) ^ ((~E) & G)) + m_K[ind] + W[ind]; + + H = G; + G = F; + F = E; + E = D + T1; + D = C; + C = B; + B = A; + A = T1 + T2; + + EAP_SHA_256_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_SHA_256, + (EAPL("SHA_256:\tt=%d\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\n"), + ind, A, B, C, D, E, F, G, H, T1, T2, S0, S1)); + } + } + + m_H[0] = m_H[0] + A; + m_H[1] = m_H[1] + B; + m_H[2] = m_H[2] + C; + m_H[3] = m_H[3] + D; + m_H[4] = m_H[4] + E; + m_H[5] = m_H[5] + F; + m_H[6] = m_H[6] + G; + m_H[7] = m_H[7] + H; + + M_count -= EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT; + M += EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT; + + } while(M_count > 0ul); + + EAP_SHA_256_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA_256, + (EAPL("SHA_256: digest=%08x %08x %08x %08x %08x %08x %08x %08x\n"), + m_H[0], m_H[1], m_H[2], m_H[3], m_H[4], m_H[5], m_H[6], m_H[7])); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e +eap_am_crypto_sha_256_c::eap_sha_256_process_data_network_order( + const u32_t * M, + u32_t M_count + ) +{ + if (M == 0 + //|| (reinterpret_cast(M) % sizeof(u32_t)) != 0 + || M_count == 0 + || (M_count % EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT) != 0) + { + EAP_ASSERT_ANYWAY; + EAP_SYSTEM_DEBUG_BREAK(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = eap_status_ok; + + // Array of 16 temporary 32-bit unsigned integers. + u32_t count = M_count / EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT; + + for (u32_t ind = 0ul; ind != count; ind++) + { + for (u32_t ind_M = 0ul; ind_M != EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT + ; ind_M++) + { + // Here we must read data in 8-bit blocks bacause M can be aligned at any position. + const u8_t * const data + = reinterpret_cast( + &M[ind*EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT+ind_M]); + + m_M_in_host_order[ind_M] + = (data[0] << 24) + | (data[1] << 16) + | (data[2] << 8) + | (data[3] << 0); + } // for() + + status = eap_sha_256_process_data_host_order( + m_M_in_host_order, + EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } // for() + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha_256_c::copy_message_digest( + void * const output, + u32_t * const max_output_size) +{ + if (output == 0 + || max_output_size == 0 + || *max_output_size < EAP_AM_CRYPTO_SHA_256_DIGEST_BUFFER_BYTE_SIZE) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + +#if defined(EAP_LITTLE_ENDIAN) + // We must change the data from host order to network order. + u32_t * const tmp_H = static_cast(output); + for (u32_t ind = 0ul; ind != EAP_AM_CRYPTO_SHA_256_DIGEST_BUFFER_u32_COUNT + ; ind++) + { + tmp_H[ind] = eap_htonl(m_H[ind]); + } // for() + +#elif defined(EAP_BIG_ENDIAN) + + m_am_tools->memmove( + output, + m_H, + EAP_AM_CRYPTO_SHA_256_DIGEST_BUFFER_BYTE_SIZE); + +#else +#error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ +or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). +#endif + + *max_output_size = EAP_AM_CRYPTO_SHA_256_DIGEST_BUFFER_BYTE_SIZE; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * This function returns the size of message digest of HASH-algorithm. + */ +EAP_FUNC_EXPORT u32_t eap_am_crypto_sha_256_c::get_digest_length() +{ + return EAP_AM_CRYPTO_SHA_256_DIGEST_BUFFER_BYTE_SIZE; +} + +//-------------------------------------------------- + +/** + * This function returns the size of block of HASH-algorithm. + */ +EAP_FUNC_EXPORT u32_t eap_am_crypto_sha_256_c::get_block_size() +{ + return EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE; +} + +//-------------------------------------------------- + +/** + * This function initializes the context of SHA_256-algorithm. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha_256_c::hash_init() +{ + m_full_hashed_data_length = 0ul; + + m_H[0] = static_cast(EAP_SHA_256_INIT_H0); + m_H[1] = static_cast(EAP_SHA_256_INIT_H1); + m_H[2] = static_cast(EAP_SHA_256_INIT_H2); + m_H[3] = static_cast(EAP_SHA_256_INIT_H3); + m_H[4] = static_cast(EAP_SHA_256_INIT_H4); + m_H[5] = static_cast(EAP_SHA_256_INIT_H5); + m_H[6] = static_cast(EAP_SHA_256_INIT_H6); + m_H[7] = static_cast(EAP_SHA_256_INIT_H7); + + if (m_saved_data.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = m_saved_data.set_data_length(0ul); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- +/** + * This function updates the context of SHA_256-algorithm with data. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha_256_c::hash_update( + const void * const data, + const u32_t data_length) +{ + eap_status_e status = eap_status_ok; + u32_t prosessed_data_length = 0ul; + + + m_full_hashed_data_length += data_length; + + EAP_SHA_256_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA_256, + (EAPL("SHA_256: Processed data length %u\n"), + m_full_hashed_data_length)); + + if (m_saved_data.get_is_valid_data() == true + && m_saved_data.get_data_length() > 0ul) + { + EAP_SHA_256_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_MASK_SHA_256, + (EAPL("SHA_256 saved data"), + m_saved_data.get_data(m_saved_data.get_data_length()), + m_saved_data.get_data_length())); + + // Here we have remaining data to process from previous call + // of hash_update(). + u32_t needed_data_length = EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE + - m_saved_data.get_data_length(); + if (needed_data_length > data_length) + { + // Not enough input data. + needed_data_length = data_length; + } + + prosessed_data_length = needed_data_length; + status = m_saved_data.add_data(data, needed_data_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_saved_data.get_data_length() + == EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE) + { + // Enough data to process. + // Just one block of integers in W array. + + status = eap_sha_256_process_data_network_order( + reinterpret_cast( + m_saved_data.get_data( + m_saved_data.get_data_length())), + EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT + ); + + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This is optimization of buffer allocations. + status = m_saved_data.set_data_length(0ul); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_ASSERT(m_saved_data.get_is_valid_data() == false + || m_saved_data.get_data_length() + <= EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE); + + } + + u32_t remaining_data_length = data_length - prosessed_data_length; + u32_t full_block_count = remaining_data_length + / EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE; + + if (full_block_count > 0ul) + { + // Here we have full blocks to process. + status = eap_sha_256_process_data_network_order( + reinterpret_cast( + static_cast(data)+prosessed_data_length), + full_block_count * EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT + ); + + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + prosessed_data_length += sizeof(u32_t) * full_block_count + * EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT; + } + if (data_length > prosessed_data_length) + { + // Save the remaining data. + status = m_saved_data.add_data( + static_cast(data)+prosessed_data_length, + data_length-prosessed_data_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +/** + * This function writes the message digest to buffer. + * @param Length is set if md_length_or_null is non-NULL. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha_256_c::hash_final( + void * const message_digest, + u32_t *md_length_or_null) +{ + eap_status_e status = eap_status_ok; + + if (message_digest == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_saved_data.get_is_valid_data() == true) + { + EAP_SHA_256_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_MASK_SHA_256, + (EAPL("SHA_256 saved data"), + m_saved_data.get_data(m_saved_data.get_data_length()), + m_saved_data.get_data_length())); + } + + // First add the one bit. We use one byte 0x80. + u8_t bit_pad = 0x80; + status = m_saved_data.add_data(&bit_pad, sizeof(bit_pad)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Here we may have remaining data to process from previous call + // of hash_update(). + u32_t min_data_length = m_saved_data.get_data_length() + sizeof(u64_t); + u32_t padding_zero_count = 0ul; + u32_t block_count = min_data_length / EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE; + if ((min_data_length % EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE) != 0) + { + // Last block is not full. + ++block_count; + } + padding_zero_count = (block_count*EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE) + - min_data_length; + + // Now we need to pad the remaining data. + u32_t data_length = m_saved_data.get_data_length(); + status = m_saved_data.set_buffer_length(data_length+padding_zero_count); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_saved_data.set_data_length(data_length+padding_zero_count); + + u8_t * const padding = m_saved_data.get_data_offset(data_length, padding_zero_count); + if (padding == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + m_am_tools->memset( + padding, + 0, + padding_zero_count); + + // And finally the length of the hashed data is added to block. + // Note the length is in bits. + u64_t full_hashed_data_length_in_network_order + = eap_htonll(eap_shift_left_64_bit(m_full_hashed_data_length, 3ul)); + status = m_saved_data.add_data( + &full_hashed_data_length_in_network_order, + sizeof(full_hashed_data_length_in_network_order)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT(m_saved_data.get_data_length() + >= EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE + && (m_saved_data.get_data_length() + % EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE) == 0); + + u32_t full_block_count = m_saved_data.get_data_length() + / EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE; + + status = eap_sha_256_process_data_network_order( + reinterpret_cast( + m_saved_data.get_data( + m_saved_data.get_data_length())), + full_block_count * EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT + ); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This is optimization of buffer allocations. + status = m_saved_data.set_data_length(0ul); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u32_t output_length = 0ul; + if (md_length_or_null == 0) + { + // Let's use temporary length variable. + output_length = EAP_AM_CRYPTO_SHA_256_DIGEST_BUFFER_BYTE_SIZE; + md_length_or_null = &output_length; + } + + status = copy_message_digest( + message_digest, + md_length_or_null); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * This function cleans up the SHA_256 context. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha_256_c::hash_cleanup() +{ + m_saved_data.reset(); + + m_full_hashed_data_length = 0ul; + + m_am_tools->memset(m_H, 0, EAP_AM_CRYPTO_SHA_256_DIGEST_BUFFER_BYTE_SIZE); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * This function copies the context of SHA_256. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha_256_c::copy_context( + const eap_variable_data_c * const saved_data, + const u64_t full_hashed_data_length, + const u32_t * const H, + const u32_t * const T, + const u32_t * const W_in_host_order) +{ + if (saved_data->get_is_valid_data() == true) + { + eap_status_e status = m_saved_data.set_copy_of_buffer(saved_data); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // No saved data. Just reset. + m_saved_data.reset(); + } + + m_full_hashed_data_length = full_hashed_data_length; + + m_am_tools->memmove(m_H, H, sizeof(m_H)); + + m_am_tools->memmove(m_T, T, sizeof(m_T)); + + m_am_tools->memmove(m_M_in_host_order, W_in_host_order, sizeof(m_M_in_host_order)); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * This function copies the context of SHA_256. + */ +EAP_FUNC_EXPORT eap_am_crypto_sha_256_c * eap_am_crypto_sha_256_c::copy() +{ + eap_am_crypto_sha_256_c * const sha_256 = new eap_am_crypto_sha_256_c(m_am_tools); + if (sha_256 == 0 + || sha_256->get_is_valid() == false) + { + delete sha_256; + return 0; + } + + eap_status_e status = sha_256->copy_context( + &m_saved_data, + m_full_hashed_data_length, + m_H, + m_T, + m_M_in_host_order); + if (status != eap_status_ok) + { + delete sha_256; + return 0; + } + + return sha_256; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/crypto/sha1/eap_am_crypto_sha1.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/crypto/sha1/eap_am_crypto_sha1.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1112 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 7 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_am_crypto_sha1.h" + +//-------------------------------------------------- + +#if 1 + #define EAP_SHA1_TRACE_DEBUG EAP_TRACE_DEBUG + #define EAP_SHA1_TRACE_DATA_DEBUG EAP_TRACE_DATA_DEBUG +#else + #define EAP_SHA1_TRACE_DEBUG(tools, flags, params) + #define EAP_SHA1_TRACE_DATA_DEBUG(object_name, flags, _parameter_list_) +#endif + +#if defined(USE_EAP_TRACE) + static const u32_t EAP_TRACE_MASK_SHA1 = eap_am_tools_c::eap_trace_mask_crypto_sha1; +#endif //#if defined(USE_EAP_TRACE) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_crypto_sha1_c::~eap_am_crypto_sha1_c() +{ + hash_cleanup(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_crypto_sha1_c::eap_am_crypto_sha1_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_saved_data(tools) + , m_full_hashed_data_length(0ul) + , m_is_valid(false) +{ + m_H[0] = 0; + m_T[0] = 0; + m_W_in_host_order[0] = 0; + + if (m_saved_data.get_is_valid() == false) + { + return; + } + + eap_status_e status = hash_init(); + if (status != eap_status_ok) + { + return; + } + + set_is_valid(); +} + +//------------------------------------------------------------ + +/** + * The set_is_invalid() function sets the state of the eap_am_crypto_sha1_c + * object invalid. + * The eap_am_crypto_sha1_c object calls this function after it is initialized. + */ +EAP_FUNC_EXPORT void eap_am_crypto_sha1_c::set_is_invalid() +{ + m_is_valid = false; +} + +//------------------------------------------------------------ + +/** + * The set_is_valid() function sets the state of the eap_am_crypto_sha1_c + * object valid. + * The eap_am_crypto_sha1_c object calls this function after it is initialized. + */ +EAP_FUNC_EXPORT void eap_am_crypto_sha1_c::set_is_valid() +{ + m_is_valid = true; +} + +//------------------------------------------------------------ + +/** + * The get_is_valid() function returns the status of the eap_am_crypto_sha1_c + * object. + * True indicates the object is allocated successfully. + */ +EAP_FUNC_EXPORT bool eap_am_crypto_sha1_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +inline u32_t eap_am_crypto_sha1_c::eap_sha1_rotate( + const u32_t value, + const u32_t shift + ) +{ + return (value << shift) | (value >> (32ul - shift)); +} + +//-------------------------------------------------- + +inline u32_t eap_am_crypto_sha1_c::eap_sha1_b_substitution( + const u32_t Wt_3, + const u32_t Wt_8, + const u32_t Wt_14, + const u32_t Wt_16 + ) +{ + return eap_sha1_rotate(Wt_3 ^ Wt_8 ^ Wt_14 ^ Wt_16, 1ul); +} + +//-------------------------------------------------- + +inline u32_t eap_am_crypto_sha1_c::eap_sha1_ft_0_19( + const u32_t B, + const u32_t C, + const u32_t D + ) +{ + return (((C ^ D) & B) ^ D); +} + +//-------------------------------------------------- + +inline u32_t eap_am_crypto_sha1_c::eap_sha1_ft_20_39( + const u32_t B, + const u32_t C, + const u32_t D + ) +{ + return (B ^ C ^ D); +} + +//-------------------------------------------------- + +inline u32_t eap_am_crypto_sha1_c::eap_sha1_ft_40_59( + const u32_t B, + const u32_t C, + const u32_t D + ) +{ + return ((B & C) | ((B | C) & D)); +} + +//-------------------------------------------------- + +inline u32_t eap_am_crypto_sha1_c::eap_sha1_ft_60_79( + const u32_t B, + const u32_t C, + const u32_t D + ) +{ + return eap_sha1_ft_20_39(B, C, D); +} + +//-------------------------------------------------- + +inline void eap_am_crypto_sha1_c::d_substitution( + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + const u32_t temp + ) +{ + *E = *D; + *D = *C; + *C = eap_sha1_rotate(*B, 30ul); + *B = *A; + *A = temp; +} + +//-------------------------------------------------- + +inline void eap_am_crypto_sha1_c::d_substitution_0_15( + const u32_t t, + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + const u32_t Wt + ) +{ + EAP_UNREFERENCED_PARAMETER(t); + + const u32_t TEMP = eap_sha1_rotate(*A, 5ul) + + eap_sha1_ft_0_19(*B, *C, *D) + + *E + Wt + eap_am_crypto_sha1_c::EAP_SHA1_K__0_19; + + d_substitution(A, B, C, D, E, TEMP); + + EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, + (EAPL("SHA1: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\n"), + t, *A, *B, *C, *D, *E)); +} + +//-------------------------------------------------- + +inline void eap_am_crypto_sha1_c::d_substitution_16_19( + const u32_t t, + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + u32_t * const Wt, + const u32_t Wt_3, + const u32_t Wt_8, + const u32_t Wt_14, + const u32_t Wt_16 + ) +{ + EAP_UNREFERENCED_PARAMETER(t); + + *Wt = eap_sha1_b_substitution(Wt_3, Wt_8, Wt_14, Wt_16); + + const u32_t TEMP = eap_sha1_rotate(*A, 5ul) + + eap_sha1_ft_0_19(*B, *C, *D) + + *E + *Wt + eap_am_crypto_sha1_c::EAP_SHA1_K__0_19; + + d_substitution(A, B, C, D, E, TEMP); + + EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, + (EAPL("SHA1: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\n"), + t, *A, *B, *C, *D, *E)); +} + +//-------------------------------------------------- + +inline void eap_am_crypto_sha1_c::d_substitution_20_39( + const u32_t t, + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + u32_t * const Wt, + const u32_t Wt_3, + const u32_t Wt_8, + const u32_t Wt_14, + const u32_t Wt_16 + ) +{ + EAP_UNREFERENCED_PARAMETER(t); + + *Wt = eap_sha1_b_substitution(Wt_3, Wt_8, Wt_14, Wt_16); + + const u32_t TEMP = eap_sha1_rotate(*A, 5ul) + + eap_sha1_ft_20_39(*B, *C, *D) + + *E + *Wt + eap_am_crypto_sha1_c::EAP_SHA1_K_20_39; + + d_substitution(A, B, C, D, E, TEMP); + + EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, + (EAPL("SHA1: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\n"), + t, *A, *B, *C, *D, *E)); +} + +//-------------------------------------------------- + +inline void eap_am_crypto_sha1_c::d_substitution_40_59( + const u32_t t, + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + u32_t * const Wt, + const u32_t Wt_3, + const u32_t Wt_8, + const u32_t Wt_14, + const u32_t Wt_16 + ) +{ + EAP_UNREFERENCED_PARAMETER(t); + + *Wt = eap_sha1_b_substitution(Wt_3, Wt_8, Wt_14, Wt_16); + + const u32_t TEMP = eap_sha1_rotate(*A, 5ul) + + eap_sha1_ft_40_59(*B, *C, *D) + + *E + *Wt + static_cast(eap_am_crypto_sha1_c::EAP_SHA1_K_40_59); + + d_substitution(A, B, C, D, E, TEMP); + + EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, + (EAPL("SHA1: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\n"), + t, *A, *B, *C, *D, *E)); +} + +//-------------------------------------------------- + +inline void eap_am_crypto_sha1_c::d_substitution_60_79( + const u32_t t, + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + u32_t * const Wt, + const u32_t Wt_3, + const u32_t Wt_8, + const u32_t Wt_14, + const u32_t Wt_16 + ) +{ + EAP_UNREFERENCED_PARAMETER(t); + + *Wt = eap_sha1_b_substitution(Wt_3, Wt_8, Wt_14, Wt_16); + + const u32_t TEMP = eap_sha1_rotate(*A, 5ul) + + eap_sha1_ft_60_79(*B, *C, *D) + + *E + *Wt + static_cast(eap_am_crypto_sha1_c::EAP_SHA1_K_60_79); + + d_substitution(A, B, C, D, E, TEMP); + + EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, + (EAPL("SHA1: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\n"), + t, *A, *B, *C, *D, *E)); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e +eap_am_crypto_sha1_c::eap_sha1_process_data_host_order( + const u32_t * W, + u32_t W_count + ) +{ + u32_t A; + u32_t B; + u32_t C; + u32_t D; + u32_t E; + + if (W == 0 + //|| (reinterpret_cast(W) % sizeof(u32_t)) != 0 + || W_count == 0 + || (W_count % EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT) != 0) + { + EAP_ASSERT_ANYWAY; + EAP_SYSTEM_DEBUG_BREAK(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + #if defined(_DEBUG) + for (u32_t ind = 0ul; ind < W_count; ind++) + { + EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, + (EAPL("SHA1: W[%d]=%08x\n"), + ind, + W[ind])); + } // for() + #endif //#if defined(_DEBUG) + + + do + { + + #if defined(_DEBUG) + EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, + (EAPL("SHA1: H[0]=0x%08x, H[1]=0x%08x, H[2]=0x%08x, H[3]=0x%08x, H[4]=0x%08x\n"), + m_H[0], + m_H[1], + m_H[2], + m_H[3], + m_H[4])); + EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, + (EAPL("SHA1: % 4s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\n"), + "t", "A", "B", "C", "D", "E")); + #endif //#if defined(_DEBUG) + + A = m_H[0]; + B = m_H[1]; + C = m_H[2]; + D = m_H[3]; + E = m_H[4]; + + d_substitution_0_15( 0, &A, &B, &C, &D, &E, W[ 0]); + d_substitution_0_15( 1, &A, &B, &C, &D, &E, W[ 1]); + d_substitution_0_15( 2, &A, &B, &C, &D, &E, W[ 2]); + d_substitution_0_15( 3, &A, &B, &C, &D, &E, W[ 3]); + d_substitution_0_15( 4, &A, &B, &C, &D, &E, W[ 4]); + d_substitution_0_15( 5, &A, &B, &C, &D, &E, W[ 5]); + d_substitution_0_15( 6, &A, &B, &C, &D, &E, W[ 6]); + d_substitution_0_15( 7, &A, &B, &C, &D, &E, W[ 7]); + d_substitution_0_15( 8, &A, &B, &C, &D, &E, W[ 8]); + d_substitution_0_15( 9, &A, &B, &C, &D, &E, W[ 9]); + d_substitution_0_15(10, &A, &B, &C, &D, &E, W[10]); + d_substitution_0_15(11, &A, &B, &C, &D, &E, W[11]); + d_substitution_0_15(12, &A, &B, &C, &D, &E, W[12]); + d_substitution_0_15(13, &A, &B, &C, &D, &E, W[13]); + d_substitution_0_15(14, &A, &B, &C, &D, &E, W[14]); + d_substitution_0_15(15, &A, &B, &C, &D, &E, W[15]); + + d_substitution_16_19(16, &A, &B, &C, &D, &E, &(m_T[ 0]), + W[13], W[ 8], W[ 2], W[ 0]); + d_substitution_16_19(17, &A, &B, &C, &D, &E, &(m_T[ 1]), + W[14], W[ 9], W[ 3], W[ 1]); + d_substitution_16_19(18, &A, &B, &C, &D, &E, &(m_T[ 2]), + W[15], W[10], W[ 4], W[ 2]); + d_substitution_16_19(19, &A, &B, &C, &D, &E, &(m_T[ 3]), + m_T[ 0], W[11], W[ 5], W[ 3]); + + d_substitution_20_39(20, &A, &B, &C, &D, &E, &(m_T[ 4]), + m_T[ 1], W[12], W[ 6], W[ 4]); + d_substitution_20_39(21, &A, &B, &C, &D, &E, &(m_T[ 5]), + m_T[ 2], W[13], W[ 7], W[ 5]); + d_substitution_20_39(22, &A, &B, &C, &D, &E, &(m_T[ 6]), + m_T[ 3], W[14], W[ 8], W[ 6]); + d_substitution_20_39(23, &A, &B, &C, &D, &E, &(m_T[ 7]), + m_T[ 4], W[15], W[ 9], W[ 7]); + d_substitution_20_39(24, &A, &B, &C, &D, &E, &(m_T[ 8]), + m_T[ 5], m_T[ 0], W[10], W[ 8]); + d_substitution_20_39(25, &A, &B, &C, &D, &E, &(m_T[ 9]), + m_T[ 6], m_T[ 1], W[11], W[ 9]); + d_substitution_20_39(26, &A, &B, &C, &D, &E, &(m_T[10]), + m_T[ 7], m_T[ 2], W[12], W[10]); + d_substitution_20_39(27, &A, &B, &C, &D, &E, &(m_T[11]), + m_T[ 8], m_T[ 3], W[13], W[11]); + d_substitution_20_39(28, &A, &B, &C, &D, &E, &(m_T[12]), + m_T[ 9], m_T[ 4], W[14], W[12]); + d_substitution_20_39(29, &A, &B, &C, &D, &E, &(m_T[13]), + m_T[10], m_T[ 5], W[15], W[13]); + d_substitution_20_39(30, &A, &B, &C, &D, &E, &(m_T[14]), + m_T[11], m_T[ 6], m_T[ 0], W[14]); + d_substitution_20_39(31, &A, &B, &C, &D, &E, &(m_T[15]), + m_T[12], m_T[ 7], m_T[ 1], W[15]); + d_substitution_20_39(32, &A, &B, &C, &D, &E, &(m_T[ 0]), + m_T[13], m_T[ 8], m_T[ 2], m_T[ 0]); + d_substitution_20_39(33, &A, &B, &C, &D, &E, &(m_T[ 1]), + m_T[14], m_T[ 9], m_T[ 3], m_T[ 1]); + d_substitution_20_39(34, &A, &B, &C, &D, &E, &(m_T[ 2]), + m_T[15], m_T[10], m_T[ 4], m_T[ 2]); + d_substitution_20_39(35, &A, &B, &C, &D, &E, &(m_T[ 3]), + m_T[ 0], m_T[11], m_T[ 5], m_T[ 3]); + d_substitution_20_39(36, &A, &B, &C, &D, &E, &(m_T[ 4]), + m_T[ 1], m_T[12], m_T[ 6], m_T[ 4]); + d_substitution_20_39(37, &A, &B, &C, &D, &E, &(m_T[ 5]), + m_T[ 2], m_T[13], m_T[ 7], m_T[ 5]); + d_substitution_20_39(38, &A, &B, &C, &D, &E, &(m_T[ 6]), + m_T[ 3], m_T[14], m_T[ 8], m_T[ 6]); + d_substitution_20_39(39, &A, &B, &C, &D, &E, &(m_T[ 7]), + m_T[ 4], m_T[15], m_T[ 9], m_T[ 7]); + + d_substitution_40_59(40, &A, &B, &C, &D, &E, &(m_T[ 8]), + m_T[ 5], m_T[ 0], m_T[10], m_T[ 8]); + d_substitution_40_59(41, &A, &B, &C, &D, &E, &(m_T[ 9]), + m_T[ 6], m_T[ 1], m_T[11], m_T[ 9]); + d_substitution_40_59(42, &A, &B, &C, &D, &E, &(m_T[10]), + m_T[ 7], m_T[ 2], m_T[12], m_T[10]); + d_substitution_40_59(43, &A, &B, &C, &D, &E, &(m_T[11]), + m_T[ 8], m_T[ 3], m_T[13], m_T[11]); + d_substitution_40_59(44, &A, &B, &C, &D, &E, &(m_T[12]), + m_T[ 9], m_T[ 4], m_T[14], m_T[12]); + d_substitution_40_59(45, &A, &B, &C, &D, &E, &(m_T[13]), + m_T[10], m_T[ 5], m_T[15], m_T[13]); + d_substitution_40_59(46, &A, &B, &C, &D, &E, &(m_T[14]), + m_T[11], m_T[ 6], m_T[ 0], m_T[14]); + d_substitution_40_59(47, &A, &B, &C, &D, &E, &(m_T[15]), + m_T[12], m_T[ 7], m_T[ 1], m_T[15]); + d_substitution_40_59(48, &A, &B, &C, &D, &E, &(m_T[ 0]), + m_T[13], m_T[ 8], m_T[ 2], m_T[ 0]); + d_substitution_40_59(49, &A, &B, &C, &D, &E, &(m_T[ 1]), + m_T[14], m_T[ 9], m_T[ 3], m_T[ 1]); + d_substitution_40_59(50, &A, &B, &C, &D, &E, &(m_T[ 2]), + m_T[15], m_T[10], m_T[ 4], m_T[ 2]); + d_substitution_40_59(51, &A, &B, &C, &D, &E, &(m_T[ 3]), + m_T[ 0], m_T[11], m_T[ 5], m_T[ 3]); + d_substitution_40_59(52, &A, &B, &C, &D, &E, &(m_T[ 4]), + m_T[ 1], m_T[12], m_T[ 6], m_T[ 4]); + d_substitution_40_59(53, &A, &B, &C, &D, &E, &(m_T[ 5]), + m_T[ 2], m_T[13], m_T[ 7], m_T[ 5]); + d_substitution_40_59(54, &A, &B, &C, &D, &E, &(m_T[ 6]), + m_T[ 3], m_T[14], m_T[ 8], m_T[ 6]); + d_substitution_40_59(55, &A, &B, &C, &D, &E, &(m_T[ 7]), + m_T[ 4], m_T[15], m_T[ 9], m_T[ 7]); + d_substitution_40_59(56, &A, &B, &C, &D, &E, &(m_T[ 8]), + m_T[ 5], m_T[ 0], m_T[10], m_T[ 8]); + d_substitution_40_59(57, &A, &B, &C, &D, &E, &(m_T[ 9]), + m_T[ 6], m_T[ 1], m_T[11], m_T[ 9]); + d_substitution_40_59(58, &A, &B, &C, &D, &E, &(m_T[10]), + m_T[ 7], m_T[ 2], m_T[12], m_T[10]); + d_substitution_40_59(59, &A, &B, &C, &D, &E, &(m_T[11]), + m_T[ 8], m_T[ 3], m_T[13], m_T[11]); + + d_substitution_60_79(60, &A, &B, &C, &D, &E, &(m_T[12]), + m_T[ 9], m_T[ 4], m_T[14], m_T[12]); + d_substitution_60_79(61, &A, &B, &C, &D, &E, &(m_T[13]), + m_T[10], m_T[ 5], m_T[15], m_T[13]); + d_substitution_60_79(62, &A, &B, &C, &D, &E, &(m_T[14]), + m_T[11], m_T[ 6], m_T[ 0], m_T[14]); + d_substitution_60_79(63, &A, &B, &C, &D, &E, &(m_T[15]), + m_T[12], m_T[ 7], m_T[ 1], m_T[15]); + d_substitution_60_79(64, &A, &B, &C, &D, &E, &(m_T[ 0]), + m_T[13], m_T[ 8], m_T[ 2], m_T[ 0]); + d_substitution_60_79(65, &A, &B, &C, &D, &E, &(m_T[ 1]), + m_T[14], m_T[ 9], m_T[ 3], m_T[ 1]); + d_substitution_60_79(66, &A, &B, &C, &D, &E, &(m_T[ 2]), + m_T[15], m_T[10], m_T[ 4], m_T[ 2]); + d_substitution_60_79(67, &A, &B, &C, &D, &E, &(m_T[ 3]), + m_T[ 0], m_T[11], m_T[ 5], m_T[ 3]); + d_substitution_60_79(68, &A, &B, &C, &D, &E, &(m_T[ 4]), + m_T[ 1], m_T[12], m_T[ 6], m_T[ 4]); + d_substitution_60_79(69, &A, &B, &C, &D, &E, &(m_T[ 5]), + m_T[ 2], m_T[13], m_T[ 7], m_T[ 5]); + d_substitution_60_79(70, &A, &B, &C, &D, &E, &(m_T[ 6]), + m_T[ 3], m_T[14], m_T[ 8], m_T[ 6]); + d_substitution_60_79(71, &A, &B, &C, &D, &E, &(m_T[ 7]), + m_T[ 4], m_T[15], m_T[ 9], m_T[ 7]); + d_substitution_60_79(72, &A, &B, &C, &D, &E, &(m_T[ 8]), + m_T[ 5], m_T[ 0], m_T[10], m_T[ 8]); + d_substitution_60_79(73, &A, &B, &C, &D, &E, &(m_T[ 9]), + m_T[ 6], m_T[ 1], m_T[11], m_T[ 9]); + d_substitution_60_79(74, &A, &B, &C, &D, &E, &(m_T[10]), + m_T[ 7], m_T[ 2], m_T[12], m_T[10]); + d_substitution_60_79(75, &A, &B, &C, &D, &E, &(m_T[11]), + m_T[ 8], m_T[ 3], m_T[13], m_T[11]); + d_substitution_60_79(76, &A, &B, &C, &D, &E, &(m_T[12]), + m_T[ 9], m_T[ 4], m_T[14], m_T[12]); + d_substitution_60_79(77, &A, &B, &C, &D, &E, &(m_T[13]), + m_T[10], m_T[ 5], m_T[15], m_T[13]); + d_substitution_60_79(78, &A, &B, &C, &D, &E, &(m_T[14]), + m_T[11], m_T[ 6], m_T[ 0], m_T[14]); + d_substitution_60_79(79, &A, &B, &C, &D, &E, &(m_T[15]), + m_T[12], m_T[ 7], m_T[ 1], m_T[15]); + + m_H[0] = m_H[0] + A; + m_H[1] = m_H[1] + B; + m_H[2] = m_H[2] + C; + m_H[3] = m_H[3] + D; + m_H[4] = m_H[4] + E; + + W_count -= EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT; + W += EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT; + + } while(W_count > 0ul); + + EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, + (EAPL("SHA1: digest=\t%08x\t%08x\t%08x\t%08x\t%08x\n"), + m_H[0], m_H[1], m_H[2], m_H[3], m_H[4])); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e +eap_am_crypto_sha1_c::eap_sha1_process_data_network_order( + const u32_t * W, + u32_t W_count + ) +{ + if (W == 0 + //|| (reinterpret_cast(W) % sizeof(u32_t)) != 0 + || W_count == 0 + || (W_count % EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT) != 0) + { + EAP_ASSERT_ANYWAY; + EAP_SYSTEM_DEBUG_BREAK(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = eap_status_ok; + + // Array of 16 temporary 32-bit unsigned integers. + u32_t count = W_count / EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT; + + for (u32_t ind = 0ul; ind < count; ind++) + { + for (u32_t ind_W = 0ul; ind_W < EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT + ; ind_W++) + { + // Here we must read data in 8-bit blocks bacause W can be aligned at any position. + const u8_t * const data + = reinterpret_cast( + &W[ind*EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT+ind_W]); + m_W_in_host_order[ind_W] + = (data[0] << 24) + | (data[1] << 16) + | (data[2] << 8) + | (data[3] << 0); + } // for() + + status = eap_sha1_process_data_host_order( + m_W_in_host_order, + EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } // for() + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::copy_message_digest( + void * const output, + u32_t * const max_output_size) +{ + if (output == 0 + || max_output_size == 0 + || *max_output_size < EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + +#if defined(EAP_LITTLE_ENDIAN) + // We must change the data from host order to network order. + u32_t * const tmp_H = static_cast(output); + for (u32_t ind = 0ul; ind < EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_u32_COUNT + ; ind++) + { + tmp_H[ind] = eap_htonl(m_H[ind]); + } // for() + +#elif defined(EAP_BIG_ENDIAN) + + m_am_tools->memmove( + output, + m_H, + EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE); + +#else +#error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ +or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). +#endif + + *max_output_size = EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::eap_sha1_dss_G_function( + const void * const data, + const u32_t data_length, + void * const output, + u32_t * const output_length + ) +{ + if (data == 0 + || data_length == 0 + || data_length > EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE + || output == 0 + || output_length == 0 + || *output_length < EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = hash_init(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_am_tools->memset(m_W_in_host_order, 0, sizeof(m_W_in_host_order)); + m_am_tools->memmove(m_W_in_host_order, data, data_length); + + +#if defined(EAP_LITTLE_ENDIAN) + + { + for (u32_t ind_W = 0ul; ind_W < EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT + ; ind_W++) + { + m_W_in_host_order[ind_W] = eap_ntohl(m_W_in_host_order[ind_W]); + } // for() + + status = eap_sha1_process_data_host_order( + m_W_in_host_order, + EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + +#elif defined(EAP_BIG_ENDIAN) + + { + u32_t count_W = data_length + / EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE; + + status = eap_sha1_process_data_host_order(m_W_in_host_order, count_W); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + +#else +#error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ +or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). +#endif + + status = copy_message_digest( + output, + output_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +/** + * This function returns the size of message digest of HASH-algorithm. + */ +EAP_FUNC_EXPORT u32_t eap_am_crypto_sha1_c::get_digest_length() +{ + return EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE; +} + +//-------------------------------------------------- + +/** + * This function returns the size of block of HASH-algorithm. + */ +EAP_FUNC_EXPORT u32_t eap_am_crypto_sha1_c::get_block_size() +{ + return EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE; +} + +//-------------------------------------------------- + +/** + * This function initializes the context of SHA1-algorithm. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::hash_init() +{ + m_full_hashed_data_length = 0ul; + + m_H[0] = static_cast(EAP_SHA1_INIT_H0); + m_H[1] = static_cast(EAP_SHA1_INIT_H1); + m_H[2] = static_cast(EAP_SHA1_INIT_H2); + m_H[3] = static_cast(EAP_SHA1_INIT_H3); + m_H[4] = static_cast(EAP_SHA1_INIT_H4); + + if (m_saved_data.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = m_saved_data.set_data_length(0ul); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- +/** + * This function updates the context of SHA1-algorithm with data. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::hash_update( + const void * const data, + const u32_t data_length) +{ + eap_status_e status = eap_status_ok; + u32_t prosessed_data_length = 0ul; + + + m_full_hashed_data_length += data_length; + + EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, + (EAPL("SHA1: Processed data length %u\n"), + m_full_hashed_data_length)); + + if (m_saved_data.get_is_valid_data() == true + && m_saved_data.get_data_length() > 0ul) + { + EAP_SHA1_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_MASK_SHA1, + (EAPL("SHA1 saved data"), + m_saved_data.get_data(m_saved_data.get_data_length()), + m_saved_data.get_data_length())); + + // Here we have remaining data to process from previous call + // of hash_update(). + u32_t needed_data_length = EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE + - m_saved_data.get_data_length(); + if (needed_data_length > data_length) + { + // Not enough input data. + needed_data_length = data_length; + } + + prosessed_data_length = needed_data_length; + status = m_saved_data.add_data(data, needed_data_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_saved_data.get_data_length() + == EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE) + { + // Enough data to process. + // Just one block of integers in W array. + + status = eap_sha1_process_data_network_order( + reinterpret_cast( + m_saved_data.get_data( + m_saved_data.get_data_length())), + EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT + ); + + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This is optimization of buffer allocations. + status = m_saved_data.set_data_length(0ul); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_ASSERT(m_saved_data.get_is_valid_data() == false + || m_saved_data.get_data_length() + <= EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE); + + } + + u32_t remaining_data_length = data_length - prosessed_data_length; + u32_t full_block_count = remaining_data_length + / EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE; + + if (full_block_count > 0ul) + { + // Here we have full blocks to process. + status = eap_sha1_process_data_network_order( + reinterpret_cast( + static_cast(data)+prosessed_data_length), + full_block_count * EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT + ); + + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + prosessed_data_length += sizeof(u32_t) * full_block_count + * EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT; + } + if (data_length > prosessed_data_length) + { + // Save the remaining data. + status = m_saved_data.add_data( + static_cast(data)+prosessed_data_length, + data_length-prosessed_data_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +/** + * This function writes the message digest to buffer. + * @param Length is set if md_length_or_null is non-NULL. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::hash_final( + void * const message_digest, + u32_t *md_length_or_null) +{ + eap_status_e status = eap_status_ok; + + if (message_digest == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_saved_data.get_is_valid_data() == true) + { + EAP_SHA1_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_MASK_SHA1, + (EAPL("SHA1 saved data"), + m_saved_data.get_data(m_saved_data.get_data_length()), + m_saved_data.get_data_length())); + } + + // First add the one bit. We use one byte 0x80. + u8_t bit_pad = 0x80; + status = m_saved_data.add_data(&bit_pad, sizeof(bit_pad)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Here we may have remaining data to process from previous call + // of hash_update(). + u32_t min_data_length = m_saved_data.get_data_length() + sizeof(u64_t); + u32_t padding_zero_count = 0ul; + u32_t block_count = min_data_length / EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE; + if ((min_data_length % EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE) != 0) + { + // Last block is not full. + ++block_count; + } + padding_zero_count = (block_count*EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE) + - min_data_length; + + // Now we need to pad the remaining data. + u32_t data_length = m_saved_data.get_data_length(); + status = m_saved_data.set_buffer_length(data_length+padding_zero_count); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_saved_data.set_data_length(data_length+padding_zero_count); + + u8_t * const padding = m_saved_data.get_data_offset(data_length, padding_zero_count); + if (padding == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + m_am_tools->memset( + padding, + 0, + padding_zero_count); + + // And finally the length of the hashed data is added to block. + // Note the length is in bits. + u64_t full_hashed_data_length_in_network_order + = eap_htonll(eap_shift_left_64_bit(m_full_hashed_data_length, 3ul)); + status = m_saved_data.add_data( + &full_hashed_data_length_in_network_order, + sizeof(full_hashed_data_length_in_network_order)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT(m_saved_data.get_data_length() + >= EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE + && (m_saved_data.get_data_length() + % EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE) == 0); + + u32_t full_block_count = m_saved_data.get_data_length() + / EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE; + + status = eap_sha1_process_data_network_order( + reinterpret_cast( + m_saved_data.get_data( + m_saved_data.get_data_length())), + full_block_count * EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT + ); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This is optimization of buffer allocations. + status = m_saved_data.set_data_length(0ul); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u32_t output_length = 0ul; + if (md_length_or_null == 0) + { + // Let's use temporary length variable. + output_length = EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE; + md_length_or_null = &output_length; + } + + status = copy_message_digest( + message_digest, + md_length_or_null); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * This function cleans up the SHA1 context. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::hash_cleanup() +{ + m_saved_data.reset(); + + m_full_hashed_data_length = 0ul; + + m_am_tools->memset(m_H, 0, EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * This function copies the context of SHA1. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::copy_context( + const eap_variable_data_c * const saved_data, + const u64_t full_hashed_data_length, + const u32_t * const H, + const u32_t * const T, + const u32_t * const W_in_host_order) +{ + if (saved_data->get_is_valid_data() == true) + { + eap_status_e status = m_saved_data.set_copy_of_buffer(saved_data); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // No saved data. Just reset. + m_saved_data.reset(); + } + + m_full_hashed_data_length = full_hashed_data_length; + + m_am_tools->memmove(m_H, H, sizeof(m_H)); + + m_am_tools->memmove(m_T, T, sizeof(m_T)); + + m_am_tools->memmove(m_W_in_host_order, W_in_host_order, sizeof(m_W_in_host_order)); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +/** + * This function copies the context of SHA1. + */ +EAP_FUNC_EXPORT eap_am_crypto_sha1_c * eap_am_crypto_sha1_c::copy() +{ + eap_am_crypto_sha1_c * const sha1 = new eap_am_crypto_sha1_c(m_am_tools); + if (sha1 == 0 + || sha1->get_is_valid() == false) + { + delete sha1; + return 0; + } + + eap_status_e status = sha1->copy_context( + &m_saved_data, + m_full_hashed_data_length, + m_H, + m_T, + m_W_in_host_order); + if (status != eap_status_ok) + { + delete sha1; + return 0; + } + + return sha1; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/eap_am_memory.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/eap_am_memory.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,304 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 9 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "abs_eap_am_tools.h" +#include "eap_am_memory.h" + +#if defined(DMALLOC) + //#pragma message("Uses dmalloc.") + #include +#endif // #if defined(DMALLOC) + +#if defined(DMALLOC) || defined(USE_EAP_MEMORY_FUNCTIONS) + +#if (defined(_WIN32) || defined(__GNUC__)) && !defined(__SYMBIAN32__) + + static jph_new_handler g_jph_new_handler = NULL; + + #if defined(USE_EAP_MEMORY_FUNCTIONS_FAILURES) + + #include + bool g_eap_alloc_failures_enabled_flag = false; + u32_t g_eap_alloc_failures_probability = 0ul; + u32_t g_eap_alloc_failures_skip_count = 0ul; + u32_t g_eap_alloc_failures_skip_counter_value = 0ul; + + const u32_t g_eap_alloc_max_probapility = 4294967295ul; + + void g_eap_set_memory_parameters( + const u32_t alloc_failures_probability, + const u32_t alloc_failures_skip_count) + { + srand(time(0)); + + g_eap_alloc_failures_enabled_flag = true; + + g_eap_alloc_failures_probability = alloc_failures_probability; + + g_eap_alloc_failures_skip_count = alloc_failures_skip_count; + + g_eap_alloc_failures_skip_counter_value = 0ul; + } + + void g_eap_alloc_failures_enabled() + { + if (g_eap_alloc_failures_probability != 0) + { + // Parameters must be set before failures can be enabled. + g_eap_alloc_failures_enabled_flag = true; + } + } + + void g_eap_alloc_failures_disabled() + { + g_eap_alloc_failures_enabled_flag = false; + } + + bool g_eap_alloc_failures_active() + { + return (g_eap_alloc_failures_skip_counter_value >= g_eap_alloc_failures_skip_count + && g_eap_alloc_failures_probability == g_eap_alloc_max_probapility); + } + + static bool g_eap_memory_randomize_error() + { + // We cannot use abs_eap_am_tools_c here. + + if (g_eap_alloc_failures_enabled_flag == false) + { + return false; + } + + if (g_eap_alloc_failures_skip_counter_value < g_eap_alloc_failures_skip_count) + { + ++g_eap_alloc_failures_skip_counter_value; + return false; + } + + u32_t random_guard = static_cast(rand()); + if (random_guard < g_eap_alloc_failures_probability) + { + return true; + } + else + { + return false; + } + } + #endif //#if defined(USE_EAP_MEMORY_FUNCTIONS_FAILURES) + +#else + // Note Symbian does not support global writable data in DLL. +#endif //#if defined(_WIN32) || defined(__GNUC__) + + +#if defined(_WIN32) || defined(__GNUC__) +/* + * An overload function the malloc. + */ +EAP_C_FUNC_EXPORT void *jph_malloc(size_t n) +{ + +#if defined(USE_EAP_MEMORY_FUNCTIONS_FAILURES) + if (g_eap_memory_randomize_error() == true) + { + // This is failed allocation. + return 0; + } +#endif //#if defined(USE_EAP_MEMORY_FUNCTIONS_FAILURES) + + #if defined(__SYMBIAN32__) + return User::Alloc(n); + #else + return malloc(n); + #endif +} + +/* + * An overload function the malloc. + */ +EAP_C_FUNC_EXPORT void *jph_malloc_ex(size_t n, const char *file, int line) +{ + return jph_malloc(n); +} +#endif //#if defined(_WIN32) || defined(__GNUC__) + + +#if defined(_WIN32) || defined(__GNUC__) + #if defined(USE_JPH_REALLOC) + /* + * An overload function the realloc. + */ + EAP_C_FUNC_EXPORT void *jph_realloc(void *oldbuf, size_t n) + { + return realloc(oldbuf,n); + } + + /* + * An overload function the realloc. + */ + EAP_C_FUNC_EXPORT void *jph_realloc_ex(void *oldbuf, size_t n, const char *file, int line) + { + return jph_realloc(oldbuf,n); + } + #endif //#if defined(USE_JPH_REALLOC) + + + #if defined(USE_JPH_CALLOC) + /* + * An overload function the jph_calloc. + */ + EAP_C_FUNC_EXPORT void *jph_calloc(size_t count, size_t size) + { + return calloc(count,size); + } + #endif //#if defined(USE_JPH_CALLOC) + + + /* + * An overload function for the free. + */ + EAP_C_FUNC_EXPORT void jph_free(void *cp) + { + #if defined(__SYMBIAN32__) + User::Free(cp); + #else + free( cp ); + #endif + } + + + EAP_C_FUNC_EXPORT void *jph_new(size_t n) + { + void *mem = jph_malloc(n); + + #if (defined(_WIN32) || defined(__GNUC__)) && !defined(__SYMBIAN32__) + if (!mem && g_jph_new_handler) + { + if (g_jph_new_handler(n)) + { + mem = jph_malloc(n); + } + } + #endif //#if (defined(_WIN32) || defined(__GNUC__)) && !defined(__SYMBIAN32__) + + return mem; + } + + EAP_C_FUNC_EXPORT void jph_delete(void *cp) + { + jph_free( cp ); + } + +#endif /* #if defined(_WIN32) */ + + +#if defined(_WIN32) && defined(__GNUC__) + + +/* This will be __builtin_new. */ +EAP_C_FUNC_EXPORT void *operator new(size_t n) +{ + return jph_new(n); +} + +/* This will be __builtin_vec_new. */ +EAP_C_FUNC_EXPORT void *operator new[](size_t n) +{ + return jph_new(n); +} + +/* This will be __builtin_delete. */ +EAP_C_FUNC_EXPORT void operator delete(void *cp) +{ + if (cp) + { + jph_delete(cp); + } +} + +/* This will be __builtin_vec_delete. */ +EAP_C_FUNC_EXPORT void operator delete[](void *cp) +{ + if (cp) + { + jph_delete(cp); + } +} + +#endif /* #if defined(_WIN32) */ + + +#if !defined(_WIN32) && defined(__GNUC__) + +EAP_C_FUNC_EXPORT void *operator new(std::size_t n) throw (std::bad_alloc) +{ + return jph_new(n); +} + +EAP_C_FUNC_EXPORT void *operator new[](std::size_t n) throw (std::bad_alloc) +{ + return jph_new(n); +} + +EAP_C_FUNC_EXPORT void operator delete(void *cp) throw() +{ + if (cp) + { + jph_delete(cp); + } +} + +EAP_C_FUNC_EXPORT void operator delete[](void *cp) throw() +{ + if (cp) + { + jph_delete(cp); + } +} + +#endif + + +#if (defined(_WIN32) || defined(__GNUC__)) && !defined(__SYMBIAN32__) +EAP_C_FUNC_EXPORT jph_new_handler jph_set_new_handler(jph_new_handler handler) +{ + jph_new_handler oldhandler = g_jph_new_handler; + g_jph_new_handler = handler; + return oldhandler; +} +#endif //#if defined(_WIN32) || defined(__GNUC__) + +#endif //#if defined(DMALLOC) || defined(USE_EAP_MEMORY_FUNCTIONS) + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/eap_am_memory_store.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/eap_am_memory_store.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,645 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 10 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_am_memory_store.h" +#include "eap_crypto_api.h" +#include "eap_automatic_variable.h" + +//#if !defined(NO_EAP_AM_MEMORY_STORE) + +const u32_t EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH = 256ul; + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_memory_store_c::~eap_am_memory_store_c() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::~eap_am_memory_store_c(): this = 0x%08x.\n"), + this)); +} + +//------------------------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +EAP_FUNC_EXPORT eap_am_memory_store_c::eap_am_memory_store_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_store_new(tools, this) + , m_timer_id_counter(0ul) + , m_is_valid(false) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::eap_am_memory_store_c(): this = 0x%08x.\n"), + this)); + + set_is_valid(); +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::shutdown() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::shutdown(): begins this = 0x%08x.\n"), + this)); + + return eap_status_ok; + +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_memory_store_c::set_is_valid() +{ + m_is_valid = true; +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_am_memory_store_c::get_is_valid() +{ + return m_is_valid; +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::add_data( + const eap_variable_data_c * const key, + const eap_tlv_message_data_c * const data, + const u32_t timeout) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): data = 0x%08x.\n"), + data)); + + if (key == 0 + || data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_memory_store_tlv_data_c * const tlv_data = new eap_am_memory_store_tlv_data_c(m_am_tools); + if (tlv_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_automatic_variable_c automatic_tlv_data( + m_am_tools, + tlv_data); + + eap_status_e status = tlv_data->copy_message_data( + data, + ++m_timer_id_counter); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c crypted_key(m_am_tools); + status = crypted_key.set_copy_of_buffer(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // This encryption hides the plain text data. + // This is lame hidden operation of credentials. + // @{ The key should be crypted lamely too.} + crypto_rc4_c rc4(m_am_tools); + if (rc4.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = rc4.set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.discard_stream(EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.encrypt_data( + crypted_key.get_data(), + crypted_key.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = rc4.set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.discard_stream(EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.encrypt_data( + tlv_data->get_message_data(), + tlv_data->get_message_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): timeout %d, timer id %d, data = 0x%08x.\n"), + timeout, + tlv_data->get_timer_id(), + data)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): key"), + key->get_data(), + key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): crypted key"), + crypted_key.get_data(), + crypted_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): plain text data"), + data->get_message_data(), + data->get_message_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): hidden data"), + tlv_data->get_message_data(), + tlv_data->get_message_data_length())); + + status = m_store_new.add_handler(&crypted_key, tlv_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + automatic_tlv_data.do_not_free_variable(); + + if (timeout != 0ul) + { + eap_variable_data_c * const copy_key = key->copy(); + if (copy_key == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_tools->am_set_timer( + this, + tlv_data->get_timer_id(), + copy_key, + timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::get_data( + const eap_variable_data_c * const key, + eap_tlv_message_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (key == 0 + || data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_variable_data_c crypted_key(m_am_tools); + eap_status_e status = crypted_key.set_copy_of_buffer(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // This encryption restores lamely hidden key of data. + crypto_rc4_c rc4(m_am_tools); + if (rc4.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = rc4.set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.discard_stream(EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.encrypt_data( + crypted_key.get_data(), + crypted_key.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::get_data(): key"), + key->get_data(), + key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::get_data(): crypted key"), + crypted_key.get_data(), + crypted_key.get_data_length())); + + eap_am_memory_store_tlv_data_c * const tlv_data = m_store_new.get_handler(&crypted_key); + + if (tlv_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); + } + else + { + status = data->copy_message_data( + tlv_data->get_message_data_length(), + tlv_data->get_message_data()); + + { + // This encryption restores lamely hidden plain text data. + crypto_rc4_c rc4(m_am_tools); + if (rc4.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = rc4.set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.discard_stream(EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.decrypt_data( + data->get_message_data(), + data->get_message_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::get_data(): timer id %d, data = 0x%08x.\n"), + tlv_data->get_timer_id(), + data)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::get_data(): hidden data"), + tlv_data->get_message_data(), + tlv_data->get_message_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::get_data(): plain text data"), + data->get_message_data(), + data->get_message_data_length())); + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::remove_data( + const eap_variable_data_c * const key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::remove_data(): key"), + key->get_data(), + key->get_data_length())); + + eap_status_e status(eap_status_ok); + + { + eap_variable_data_c crypted_key(m_am_tools); + eap_status_e status = crypted_key.set_copy_of_buffer(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // This encryption restores lamely hidden key of data. + crypto_rc4_c rc4(m_am_tools); + if (rc4.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = rc4.set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.discard_stream(EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.encrypt_data( + crypted_key.get_data(), + crypted_key.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::remove_data(): crypted key"), + crypted_key.get_data(), + crypted_key.get_data_length())); + + eap_am_memory_store_tlv_data_c * const data = m_store_new.get_handler(&crypted_key); + if (data != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::remove_data(): timer id %d, data = 0x%08x.\n"), + data->get_timer_id(), + data)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::remove_data(): key"), + key->get_data(), + key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::remove_data(): hidden data"), + data->get_message_data(), + data->get_message_data_length())); + + (void) m_am_tools->am_cancel_timer( + this, + data->get_timer_id()); + + status = m_store_new.remove_handler(&crypted_key, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_am_memory_store_c::remove_data(): key not found"), + crypted_key.get_data(), + crypted_key.get_data_length())); + } + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::remove_data(): returns %d\n"), + status)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//------------------------------------------------------------------- + +/** + * Function timer_expired() is called after the timer is elapsed. + * @param id and data are set by caller of abs_eap_am_tools::set_timer() function. + * @param id could be used to separate different timer events. + * @param data could be pointer to any data that is needed in timer processing. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::timer_expired( + const u32_t id, void *data) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::timer_expired(): id %d, data 0x%08x\n"), + id, + data)); + + if (data != 0) + { + eap_variable_data_c * const key = reinterpret_cast(data); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::timer_expired(): key"), + key->get_data(), + key->get_data_length())); + + eap_am_memory_store_tlv_data_c * const tlv_data = m_store_new.get_handler(key); + if (tlv_data != 0) + { + if (id == tlv_data->get_timer_id()) + { + eap_status_e status = remove_data(key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_memory_store_c::timer_expired(): id %d != tlv_data->id %d, tlv_data 0x%08x\n"), + id, + tlv_data->get_timer_id(), + tlv_data)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------------------- + +/** + * This function is called when timer event is deleted. + * Initialiser of the data must delete the data. + * Only the initializer knows the real type of data. + * @param id could be used to separate different timer events. + * @param data could be pointer to any data that is needed in timer processing. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::timer_delete_data( + const u32_t id, void *data) +{ + EAP_UNREFERENCED_PARAMETER(id); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::timer_delete_data(): id %d, data 0x%08x\n"), + id, + data)); + + if (data != 0) + { + eap_variable_data_c * const key = reinterpret_cast(data); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::timer_delete_data(): key"), + key->get_data(), + key->get_data_length())); + + delete key; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------------------- + +//#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/eap_am_memory_store_data.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/eap_am_memory_store_data.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 11 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory_store_data.h" + +//#if !defined(NO_EAP_AM_MEMORY_STORE) + + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT abs_eap_am_memory_store_data_c::~abs_eap_am_memory_store_data_c() +{ +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT abs_eap_am_memory_store_data_c::abs_eap_am_memory_store_data_c() +{ +} + +//------------------------------------------------------------------- +//------------------------------------------------------------------- +//------------------------------------------------------------------- + + +EAP_FUNC_EXPORT eap_am_memory_store_tlv_data_c::~eap_am_memory_store_tlv_data_c() +{ +} + +EAP_FUNC_EXPORT eap_am_memory_store_tlv_data_c::eap_am_memory_store_tlv_data_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_tlv_data(tools) + , m_timer_id(0ul) +{ +} + +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_tlv_data_c::copy_message_data( + const eap_tlv_message_data_c * const tlv_data, + const u32_t timer_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_timer_id = timer_id; + + eap_status_e status = m_tlv_data.copy_message_data( + tlv_data->get_message_data_length(), + tlv_data->get_message_data()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT u32_t eap_am_memory_store_tlv_data_c::get_timer_id() const +{ + return m_timer_id; +} + +EAP_FUNC_EXPORT void * eap_am_memory_store_tlv_data_c::get_message_data() const +{ + return m_tlv_data.get_message_data(); +} + +EAP_FUNC_EXPORT u32_t eap_am_memory_store_tlv_data_c::get_message_data_length() const +{ + return m_tlv_data.get_message_data_length(); +} + +EAP_FUNC_EXPORT void eap_am_memory_store_tlv_data_c::object_increase_reference_count() +{ +} + +EAP_FUNC_EXPORT u32_t eap_am_memory_store_tlv_data_c::object_decrease_reference_count() +{ + return 0ul; +} + + +//#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/eap_am_network_id.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/eap_am_network_id.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,596 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 12 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eapol_key_types.h" +#include "eap_am_network_id.h" + + +//-------------------------------------------------- + +eap_am_network_id_c::eap_am_network_id_impl_str::~eap_am_network_id_impl_str() +{ +} + +//-------------------------------------------------- + +eap_am_network_id_c::eap_am_network_id_impl_str::eap_am_network_id_impl_str( + abs_eap_am_tools_c * const tools) + : m_source(tools) + , m_destination(tools) + , m_type(eapol_ethernet_type_none) + , m_is_valid(false) +{ +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +// +eap_status_e eap_am_network_id_c::initialize_members() +{ + m_data = new eap_am_network_id_impl_str(m_am_tools); + if (m_data == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_network_id_c::initialize_members(): Cannot allocate %d bytes.\n"), + sizeof(eap_am_network_id_impl_str))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_network_id_c::~eap_am_network_id_c() +{ + if (m_data != 0) + { + delete m_data; + m_data = 0; + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_network_id_c::eap_am_network_id_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_data(0) +{ + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return; + } + + set_is_valid(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_network_id_c::eap_am_network_id_c( + abs_eap_am_tools_c * const tools, + const void * const source, + const u32_t source_length, + const void * const destination, + const u32_t destination_length, + const u16_t type, + const bool free_id, + const bool writable_id) + : m_am_tools(tools) + , m_data(0) +{ + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return; + } + + status = m_data->m_source.set_buffer( + source, + source_length, + free_id, + writable_id); + if (status != eap_status_ok + || m_data->m_source.get_is_valid_data() == false) + { + return; + } + + status = m_data->m_destination.set_buffer( + destination, + destination_length, + free_id, + writable_id); + if (status != eap_status_ok + || m_data->m_destination.get_is_valid_data() == false) + { + return; + } + + m_data->m_type = type; + + set_is_valid(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_network_id_c::eap_am_network_id_c( + abs_eap_am_tools_c * const tools, + const eap_variable_data_c * const source, + const eap_variable_data_c * const destination, + const u16_t type) + : m_am_tools(tools) + , m_data(0) +{ + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return; + } + + status = m_data->m_source.set_buffer( + source->get_data(source->get_data_length()), + source->get_data_length(), + false, + false); + if (status != eap_status_ok + || m_data->m_source.get_is_valid_data() == false) + { + return; + } + + status = m_data->m_destination.set_buffer( + destination->get_data(destination->get_data_length()), + destination->get_data_length(), + false, + false); + if (status != eap_status_ok + || m_data->m_destination.get_is_valid_data() == false) + { + return; + } + + m_data->m_type = type; + + set_is_valid(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_network_id_c::eap_am_network_id_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const network_id) + : m_am_tools(tools) + , m_data(0) +{ + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return; + } + + status = m_data->m_source.set_copy_of_buffer( + network_id->get_source_id()); + + if (status != eap_status_ok + || m_data->m_source.get_is_valid_data() == false) + { + return; + } + + status = m_data->m_destination.set_copy_of_buffer( + network_id->get_destination_id()); + + if (status != eap_status_ok + || m_data->m_destination.get_is_valid_data() == false) + { + return; + } + + m_data->m_type = network_id->get_type(); + + set_is_valid(); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_network_id_c::set_is_valid() +{ + if (m_data != 0) + { + m_data->m_is_valid = true; + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_network_id_c::set_copy_of_network_id( + const eap_am_network_id_c * const network_id) +{ + eap_status_e status; + + if (get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_data->m_source.set_copy_of_buffer( + network_id->get_source_id()); + if (m_data->m_source.get_is_valid_data() == false) + { + return status; + } + + status = m_data->m_destination.set_copy_of_buffer( + network_id->get_destination_id()); + if (m_data->m_destination.get_is_valid_data() == false) + { + return status; + } + + m_data->m_type = network_id->get_type(); + + return status; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_network_id_c::set_copy_of_am_network_id( + const void * const source, + const u32_t source_length, + const void * const destination, + const u32_t destination_length, + const u16_t type) +{ + if (get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = m_data->m_source.set_copy_of_buffer( + source, + source_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_data->m_source.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_data->m_destination.set_copy_of_buffer( + destination, + destination_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_data->m_destination.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_data->m_type = type; + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_network_id_c::get_is_valid() const +{ + if (m_data == 0) + { + return false; + } + return m_data->m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_network_id_c::get_is_valid_data() const +{ + return m_data != 0 + && m_data->m_source.get_is_valid() == true + && m_data->m_destination.get_is_valid() == true + && m_data->m_type != eapol_ethernet_type_none; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const eap_variable_data_c * eap_am_network_id_c::get_source_id() const +{ + if (m_data == 0) + { + return 0; + } + return &(m_data->m_source); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const u8_t * eap_am_network_id_c::get_source() const +{ + if (m_data == 0) + { + return 0; + } + return m_data->m_source.get_data(m_data->m_source.get_data_length()); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const eap_variable_data_c * eap_am_network_id_c::get_destination_id() const +{ + if (m_data == 0) + { + return 0; + } + return &(m_data->m_destination); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const u8_t * eap_am_network_id_c::get_destination() const +{ + if (m_data == 0) + { + return 0; + } + return m_data->m_destination.get_data(m_data->m_destination.get_data_length()); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_am_network_id_c::get_source_length() const +{ + if (m_data == 0) + { + return 0; + } + return m_data->m_source.get_data_length(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_am_network_id_c::get_destination_length() const +{ + if (m_data == 0) + { + return 0; + } + return m_data->m_destination.get_data_length(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u16_t eap_am_network_id_c::get_type() const +{ + if (m_data == 0) + { + return 0; + } + return m_data->m_type; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const eap_am_network_id_c * eap_am_network_id_c::get_network_id() const +{ + return this; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_network_id_c * eap_am_network_id_c::copy() const +{ + if (get_is_valid() == false) + { + return 0; + } + + u8_t *source = new u8_t[get_source_length()]; + if (source == 0 + || get_source() == 0) + { + delete [] source; + return 0; + } + m_am_tools->memmove(source, get_source(), get_source_length()); + + u8_t *destination = new u8_t[get_destination_length()]; + if (destination == 0 + || get_destination() == 0) + { + delete [] source; + delete [] destination; + return 0; + } + m_am_tools->memmove(destination, get_destination(), get_destination_length()); + + eap_am_network_id_c * const new_id = new eap_am_network_id_c( + m_am_tools, + source, + get_source_length(), + destination, + get_destination_length(), + get_type(), + true, + true); + + if (new_id == 0) + { + delete [] source; + delete [] destination; + return 0; + } + + if (new_id->get_is_valid() == false) + { + delete new_id; + return 0; + } + + return new_id; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_network_id_c::compare_network_id(const eap_am_network_id_c * const network_id) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("compare_network_id(), NOTE source and destination are compared:\n"))); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("p source"), + network_id->get_source(), + network_id->get_source_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("p destination"), + network_id->get_destination(), + network_id->get_destination_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" source"), + get_source(), + get_source_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" destination"), + get_destination(), + get_destination_length())); + + if (network_id->get_source_length() + != get_source_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_network_id); + return false; + } + + if (network_id->get_destination_length() + != get_destination_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_network_id); + return false; + } + + if (m_am_tools->memcmp( + network_id->get_source(), + get_source(), + network_id->get_source_length()) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_network_id); + return false; + } + + if (m_am_tools->memcmp( + network_id->get_destination(), + get_destination(), + network_id->get_destination_length()) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_network_id); + return false; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_network_id_c::set_type(const u16_t type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (get_is_valid() == false) + { + return; + } + + m_data->m_type = type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_network_id_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (get_is_valid() == false) + { + return; + } + + m_data->m_source.reset(); + m_data->m_destination.reset(); + + m_data->m_type = eapol_ethernet_type_none; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/eap_am_tools.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/eap_am_tools.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2462 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 13 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_am_tools.h" +#include "abs_eap_am_mutex.h" +#include "eap_crypto_api.h" +#include "eap_buffer.h" +#include "eap_configuration_field.h" + +//#if !defined(NO_EAP_AM_MEMORY_STORE) + #include "eap_am_memory_store.h" +//#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) + +/** + * This is the at character used in NAI. + */ +const u8_t EAP_AT_CHARACTER = '@'; + +/** + * This is the length of UUIDs. + */ +static const u32_t EAP_UUID_LENGTH = 16; + +/** + * This is the name space UUID for MAC addresses. + */ +static const u8_t EAP_MAC_ADDRESS_NAMESPACE_UUID_V5[] = + { 0x35, 0x0b, 0x16, 0xfd, + 0x5c, 0xd8, 0x45, 0x50, + 0x9b, 0xb8, 0x49, 0x8f, + 0x95, 0x8a, 0xc9, 0x66 }; + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_tools_c::~eap_am_tools_c() +{ + EAP_ASSERT_ALWAYS_NO_TRACE(m_shutdown_was_called == true); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_tools_c::eap_am_tools_c() +: +#if !defined(NO_EAP_AM_MEMORY_STORE) + m_memory_store(0) +, +#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) + m_trace_mask(eap_am_tools_c::eap_trace_mask_none) +#if defined(USE_EAP_ERROR_TESTS) +, m_packet_index(0u) +#endif //#if defined(USE_EAP_ERROR_TESTS) +, m_use_seconds_timestamp_in_traces(true) +, m_thread_stopped(false) +, m_use_timer_queue(false) +, m_shutdown_was_called(false) +, m_activate_trace_on_error(false) +{ + abs_eap_am_tools_c *m_am_tools = this; + u32_t bytes_8 = 8u; + u32_t bytes_4 = 4u; + u32_t bytes_2 = 2u; + u32_t bytes_1 = 1u; + + EAP_UNREFERENCED_PARAMETER(m_am_tools); + EAP_UNREFERENCED_PARAMETER(bytes_8); + EAP_UNREFERENCED_PARAMETER(bytes_4); + EAP_UNREFERENCED_PARAMETER(bytes_2); + EAP_UNREFERENCED_PARAMETER(bytes_1); + + EAP_ASSERT_ALWAYS(sizeof(u64_t) == bytes_8); + EAP_ASSERT_ALWAYS(sizeof(u32_t) == bytes_4); + EAP_ASSERT_ALWAYS(sizeof(u16_t) == bytes_2); + EAP_ASSERT_ALWAYS(sizeof(u8_t) == bytes_1); + + EAP_ASSERT_ALWAYS(sizeof(i64_t) == bytes_8); + EAP_ASSERT_ALWAYS(sizeof(i32_t) == bytes_4); + EAP_ASSERT_ALWAYS(sizeof(i16_t) == bytes_2); + EAP_ASSERT_ALWAYS(sizeof(i8_t) == bytes_1); + + m_tmp_buffer[0] = 0; + m_tmp_ascii_buffer[0] = 0; + +#if !defined(NO_EAP_AM_MEMORY_STORE) + m_memory_store = new eap_am_memory_store_c(m_am_tools); +#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_tools_c::get_use_seconds_timestamp_in_traces() +{ + return m_use_seconds_timestamp_in_traces; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_tools_c::get_thread_stopped() +{ + return m_thread_stopped; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_c::set_use_timer_queue() +{ + m_use_timer_queue = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_tools_c::get_use_timer_queue() +{ + return m_use_timer_queue; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_am_tools_c::get_trace_mask() const +{ + return m_trace_mask; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_c::set_trace_mask(const u32_t mask) +{ + m_trace_mask = mask; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_c::set_activate_trace_on_error() +{ + m_activate_trace_on_error = true; + + // NOTE the always active traces are only left active. + set_trace_mask(eap_trace_mask_always); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_c::check_activate_trace_on_error() +{ + if (m_activate_trace_on_error == true) + { + set_trace_mask( + eap_trace_mask_debug + | eap_trace_mask_always + | eap_trace_mask_error + | eap_am_tools_c::eap_trace_mask_message_data); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u8_t eap_am_tools_c::octet_to_ascii(i32_t octet) +{ + if (0 <= octet && octet <= 9) + { + return static_cast('0' + octet); + } + else if (10 <= octet && octet <= 16) + { + return static_cast('a' + (octet-10u)); + } + else + { + return 0; + } +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u8_t eap_am_tools_c::ascii_to_octet(i32_t character) +{ + if ('0' <= character && character <= '9') + { + return static_cast(character - '0'); + } + else if ('a' <= character && character <= 'f') + { + return static_cast((character - 'a') + 10u); + } + else if ('A' <= character && character <= 'F') + { + return static_cast((character - 'A') + 10u); + } + else + { + return 0; + } +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_c::trace_data( + eap_const_string prefix, + const void * const p_data, + const u32_t data_length) +{ + u8_t *cursor = m_tmp_buffer; + u8_t *cursor_ascii = m_tmp_ascii_buffer; + const u8_t *data = reinterpret_cast(p_data); + u32_t ind; + bool must_print = false; + u32_t data_start = 0u; + + const u32_t EAP_DATA_TRACE_BYTE_GROUP_SIZE = 1; + u32_t byte_group_size = EAP_DATA_TRACE_BYTE_GROUP_SIZE; + +#if !defined(USE_EAP_DEBUG_TRACE) + // This does not trace the pointer of the data. + formatted_print( + EAPL("%s: data begins: %d (0x%x) bytes\n"), + prefix, + data_length, + data_length); +#else + formatted_print( + EAPL("%s: data begins 0x%08x: %d (0x%x) bytes\n"), + prefix, + p_data, + data_length, + data_length); +#endif + + if (p_data != 0) + { + for (ind = 0u; ind < data_length; ind++) + { + if ((cursor-m_tmp_buffer)+5u >= sizeof(m_tmp_buffer)) + { + must_print = true; + formatted_print( + EAPL("ERROR: eap_am_tools_c::trace_data local buffer (%d bytes) too small.\n"), + sizeof(m_tmp_buffer)); + break; + } + + if (ind > 0u + && (ind % 16) == 0) + { + *cursor++ = 0; + *cursor_ascii++ = 0; + + formatted_print( + EAPL("%s: 0x%04x: %-48s |%-16s|\n"), + prefix, + data_start, + m_tmp_buffer, + m_tmp_ascii_buffer); + + cursor = m_tmp_buffer; + cursor_ascii = m_tmp_ascii_buffer; + must_print = false; + data_start = ind; + } + + *cursor_ascii++ = (*data >= 0x20 && *data < 0x7f) ? *data : '.'; + + *cursor++ = octet_to_ascii(((*data) & 0xf0) >> 4); + *cursor++ = octet_to_ascii(((*data) & 0x0f)); + data++; + + if (ind > 0u + && ((ind+1) % byte_group_size) == 0 + || byte_group_size == 1ul) + { + *cursor++ = ' '; + } + + must_print = true; + } + + if (must_print == true) + { + *cursor++ = 0; + *cursor_ascii = 0; + formatted_print( + EAPL("%s: 0x%04x: %-48s |%-16s|\n"), + prefix, + data_start, + m_tmp_buffer, + m_tmp_ascii_buffer); + } + } + +#if !defined(USE_EAP_DEBUG_TRACE) + // This does not trace the pointer of the data. + formatted_print( + EAPL("%s: data ends: %d (0x%x) bytes\n"), + prefix, + data_length, + data_length); +#else + formatted_print( + EAPL("%s: data ends 0x%08x: %d (0x%x) bytes\n"), + prefix, + p_data, + data_length, + data_length); +#endif + +} + +//-------------------------------------------------- + +#if defined(__SYMBIAN32__) && defined(USE_MULTITHREADING)// Symbian does not have 64 bit divide operator :-(. + +#include "eap_am_tools_symbian.h" +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::timer_thread_function() +{ + EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: Timer thread starts.\n"))); + + u64_t start_time = get_clock_ticks(); + u64_t current_time = start_time; + u64_t real_time = 0u; + u64_t virtual_time = 0u; + u64_t begin_time = 0u; + u64_t end_time = 0u; +#if defined(_DEBUG) + TInt64 *_begin_time = (TInt64 *)&begin_time; + TInt64 *_real_time = (TInt64 *)&real_time; + TInt64 *_end_time = (TInt64 *)&end_time; +#endif + u64_t hw_ticks_of_millisecond = get_clock_ticks_of_second(); + TInt64 *hw_ticks_of_millisecond_tmp = (TInt64 *)&hw_ticks_of_millisecond; + TReal _hw_ticks_of_millisecond = hw_ticks_of_millisecond_tmp->GetTReal(); + _hw_ticks_of_millisecond /= 1000.0; + + // Note 64-bit casted to 32-bit. + EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: get_clock_ticks_of_second() = %lu\n"), + static_cast(get_clock_ticks_of_second())); + + + u32_t sleep_time = get_timer_resolution_ms(); + // The mutex handle must be dublicated in Symbian operating system for each thread. + abs_eap_am_mutex_c *mutex = get_global_mutex()->dublicate_mutex(); + + if (mutex == 0 + || mutex->get_is_valid() == false) + { + EAP_TRACE_ERROR(this, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Mutex dublication failed.\n"))); + m_thread_stopped =true; + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + + u32_t next_sleep_time = sleep_time; + + mutex->mutex_enter(); + while(get_is_timer_thread_active()) + { + mutex->mutex_leave(this); + + virtual_time += sleep_time; + + // Symbian sleep is more like random generator. + // It never sleep right time. + begin_time = get_clock_ticks(); + timer_sleep(sleep_time); + end_time = get_clock_ticks(); + + current_time = get_clock_ticks(); + real_time = current_time - start_time; + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: Timer thread pulse_timer, sleep time = %d ms, ") + EAPL("actually %.3f ms, virtual_time %d ms, real_time %.3f ms.\n"), + sleep_time, + ((_end_time->GetTReal() - _begin_time->GetTReal()))/_hw_ticks_of_millisecond, + (static_cast(virtual_time), + (_real_time->GetTReal())/_hw_ticks_of_millisecond)); + + mutex->mutex_enter(); + if (get_is_timer_thread_active()) + { + next_sleep_time = pulse_timer(next_sleep_time); + } + } + + mutex->mutex_leave(this); + + delete mutex; + EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: Timer thread stops.\n"))); + + m_thread_stopped =true; + + return eap_status_ok; +} + +#elif !defined(__SYMBIAN32__) + +#if defined(USE_EAP_TIMER_QUEUE_TRACE) + #define EAP_TRACE_TIMER EAP_TRACE_DEBUG +#else + #define EAP_TRACE_TIMER(object, flags, parameters) +#endif //#if defined(USE_EAP_TIMER_QUEUE_TRACE) + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::timer_thread_function() +{ + EAP_TRACE_TIMER(this, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: Timer thread starts.\n"))); + + u32_t static_sleep_time = get_timer_resolution_ms(); + u64_t start_time = get_clock_ticks(); + u64_t current_time = start_time; + u64_t virtual_time = 0u; + u64_t real_sleep_time = 0ul; + u32_t current_sleep_time = 0u; + u64_t real_time = 0u; + u64_t hw_ticks_of_millisecond = 0u; + + u64_t begin_time = 0u; + u64_t end_time = 0u; + + // Note 64-bit casted to 32-bit. + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, (EAPL("TIMER: get_clock_ticks_of_second() = %lu\n"), + static_cast(get_clock_ticks_of_second()))); + + hw_ticks_of_millisecond = get_clock_ticks_of_second(); + hw_ticks_of_millisecond /= 1000u; + + // The mutex handle must be dublicated in Symbian operating system for each thread. + abs_eap_am_mutex_c *mutex = get_global_mutex()->dublicate_mutex(); + + if (mutex == 0 + || mutex->get_is_valid() == false) + { + EAP_TRACE_ERROR( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Mutex dublication failed.\n"))); + m_thread_stopped =true; + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + + u32_t next_sleep_time = static_sleep_time; + u64_t delay_time = 0ul; + + + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_enter(): begin\n"))); + + mutex->mutex_enter(); + + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_enter(): end\n"))); + + while(get_is_timer_thread_active()) + { + bool timer_queue_is_empty = get_timer_queue_is_empty(); + + current_sleep_time = next_sleep_time; + + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: timer_sleep(): current_sleep_time=%d\n"), + static_cast(current_sleep_time))); + + // - - - - - - - - - - - - - - - - - - - - - - - - + begin_time = get_clock_ticks(); + + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_leave(): begin\n"))); + + mutex->mutex_leave(this); + + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_leave(): end\n"))); + + // Sleep happens outside of the mutex. + timer_sleep(current_sleep_time); + + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_enter(): begin\n"))); + + mutex->mutex_enter(); + + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_enter(): end\n"))); + + end_time = get_clock_ticks(); + // - - - - - - - - - - - - - - - - - - - - - - - - + + if (timer_queue_is_empty == true) + { + real_sleep_time = 0ul; + delay_time = 0ul; + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: empty timer queue\n"))); + } + else + { + if (end_time < begin_time) + { + end_time = begin_time; + } + real_sleep_time = (end_time - begin_time)/hw_ticks_of_millisecond; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + begin_time = get_clock_ticks(); + if (get_is_timer_thread_active() == true + && get_use_eap_milli_second_timer() == true) + { + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: real_sleep_time=%d, delay_time=%d\n"), + static_cast(real_sleep_time), + static_cast(delay_time))); + + next_sleep_time = pulse_timer(static_cast(real_sleep_time+delay_time)); + } + else + { + (void) pulse_timer(static_sleep_time); + next_sleep_time = static_sleep_time; + } + end_time = get_clock_ticks(); + // - - - - - - - - - - - - - - - - - - - - - - - - + + + if (end_time < begin_time) + { + end_time = begin_time; + } + + delay_time = (end_time - begin_time)/hw_ticks_of_millisecond; + if (delay_time < next_sleep_time) + { + next_sleep_time -= static_cast(delay_time); + } + else + { + next_sleep_time = 0ul; + } + + current_time = get_clock_ticks(); + real_time = current_time - start_time; + real_time /= hw_ticks_of_millisecond; + + real_sleep_time += delay_time; + virtual_time += real_sleep_time; + + + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: Timer thread pulse_timer, sleep time = %4d ms, real_sleep_time %4d ms, ") + EAPL("virtual_time %6d, real_time %6d, next_sleep_time %4d, delay_time %4d.\n"), + current_sleep_time, + static_cast(real_sleep_time), + static_cast(virtual_time), + static_cast(real_time), + next_sleep_time, + delay_time)); + + } // while() + + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_leave(): begin\n"))); + + mutex->mutex_leave(this); + + EAP_TRACE_TIMER( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_leave(): end\n"))); + + delete mutex; + + EAP_TRACE_TIMER(this, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: Timer thread stops.\n"))); + + m_thread_stopped =true; + + return eap_status_ok; +} + +#else + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::timer_thread_function() +{ + return EAP_STATUS_RETURN(this, eap_status_not_supported); +} + +#endif + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_ascii_to_uppercase( + u8_t * const source_bytes, + const u32_t source_bytes_length) +{ + u32_t ind; + for (ind = 0u; ind < source_bytes_length; ind++) + { + if (source_bytes[ind] >= 'a' && source_bytes[ind] <= 'z') + { + source_bytes[ind] -= 32; + } + } + + return eap_status_ok; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_bytes_to_hex_ascii( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length) +{ + u32_t ind; + u32_t length = (source_bytes_length*2u < (*target_length)) ? source_bytes_length : (*target_length)/2u; + for (ind = 0u; ind < length; ind++) + { + target[ind*2u] = octet_to_ascii((source_bytes[ind] >> 4) & 0x0f); + target[(ind*2u)+1] = octet_to_ascii(source_bytes[ind] & 0x0f); + } + *target_length = (ind*2u); + + return eap_status_ok; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_bytes_to_hex_ascii( + const void * const source_bytes, + const u32_t source_bytes_length, + eap_variable_data_c * const target) +{ + if (target == 0 + || target->get_is_valid() == false) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + eap_status_e status = target->set_buffer_length(source_bytes_length/2ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + } + + status = target->set_data_length(target->get_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + } + + u32_t byte_length(target->get_data_length()); + + status = convert_bytes_to_hex_ascii( + reinterpret_cast(source_bytes), + source_bytes_length, + target->get_data(), + &byte_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + } + else if (byte_length != target->get_data_length()) + { + target->reset(); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_data_payload); + } + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_hex_ascii_to_bytes( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length) +{ + if ((source_bytes_length % 2u) != 0) + { + return EAP_STATUS_RETURN(this, eap_status_data_length_not_aligned_to_block_size); + } + + u32_t ind; + u32_t length = (source_bytes_length/2u < (*target_length)) ? source_bytes_length/2u : (*target_length); + for (ind = 0u; ind < length; ind++) + { + target[ind] = static_cast(ascii_to_octet(source_bytes[ind*2u]) << 4u | ascii_to_octet(source_bytes[ind*2u+1u])); + } + *target_length = (ind); + + return eap_status_ok; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_hex_ascii_to_bytes( + const void * const source_bytes, + const u32_t source_bytes_length, + eap_variable_data_c * const target) +{ + if (target == 0 + || target->get_is_valid() == false) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + eap_status_e status = target->set_buffer_length(source_bytes_length/2ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + } + + status = target->set_data_length(source_bytes_length/2ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + } + + u32_t byte_length(target->get_data_length()); + + status = convert_hex_ascii_to_bytes( + reinterpret_cast(source_bytes), + source_bytes_length, + target->get_data(), + &byte_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + } + else if (byte_length != target->get_data_length()) + { + target->reset(); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_data_payload); + } + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u8_t eap_am_tools_c::octet_to_ascii_armor( + const u8_t source_byte) +{ + if (source_byte < 26u) + { + // 'A' ... 'Z' + return static_cast((source_byte) + 'A'); + } + else if (26u <= source_byte && source_byte < 52u) + { + // 'a' ... 'z' + return static_cast((source_byte - 26u) + 'a'); + } + else if (52u <= source_byte && source_byte < 62u) + { + // '0' ... '9' + return static_cast(source_byte - 52u + '0'); + } + else if (source_byte == 62u) + { + return static_cast('+'); + } + else if (source_byte == 63u) + { + return static_cast('/'); + } + else + { + return 0u; + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u8_t eap_am_tools_c::octet_from_ascii_armor( + const u8_t source_byte) +{ + if ('A' <= source_byte && source_byte <= 'Z') + { + // 'A' ... 'Z' + return static_cast((source_byte) - 'A'); + } + else if ('a' <= source_byte && source_byte <= 'z') + { + // 'a' ... 'z' + return static_cast((source_byte + 26u) - 'a'); + } + else if ('0' <= source_byte && source_byte <= '9') + { + // '0' ... '9' + return static_cast((source_byte + 52) - '0'); + } + else if (source_byte == '+') + { + return 62; + } + else if (source_byte == '/') + { + return 63; + } + else + { + return 0u; + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_c::convert_selected_bytes_to_ascii_armor( + const u8_t source_byte, + u32_t * const saved_bit_count, + u8_t * const saved_bits, + u8_t * const target, + u32_t * const output_ind, + const bool last_input_byte) +{ + u8_t value; + + if (*saved_bit_count == 0u) + { + /* |0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+ + // | : : : : : : : | + // +-+-+-+-+-+-+-+-+ + // |0 1 2 3 4 5|0 1 + // | + + // | \ + // | \ + // | + + // | | + // |0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+ + // | : : : : : : : | + // +-+-+-+-+-+-+-+-+ + */ + value = octet_to_ascii_armor(static_cast(source_byte >> 2u)); + *saved_bits = static_cast(source_byte & 0x03); + *saved_bit_count = 2u; + target[*output_ind] = value; + ++(*output_ind); + } + else if (*saved_bit_count == 2u) + { + /* 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+ + // : : | : : : : : : : | + // +-+-+-+-+-+-+-+-+-+-+ + // |0 1 2 3 4 5|0 1 2 3 + // | + + // | \ + // + \ + // \ \ + // \ \ + // + + + // | | + // 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+ + // : : | : : : : : : : | + // +-+-+-+-+-+-+-+-+-+-+ + */ + const u8_t src = static_cast(((*saved_bits) << 4u) | ((source_byte & 0xf0) >> 4u)); + value = octet_to_ascii_armor(src); + *saved_bits = static_cast(source_byte & 0x0f); + *saved_bit_count = 4u; + target[*output_ind] = value; + ++(*output_ind); + } + else if (*saved_bit_count == 4u) + { + /* 4 5 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+-+-+ + // : : : : | : : : : : : : | + // +-+-+-+-+-+-+-+-+-+-+-+-+ + // |0 1 2 3 4 5|0 1 2 3 4 5| + // | | + + // | | \ + // | + \ + // | \ \ + // + \ \ + // \ \ \ + // \ \ \ + // \ \ \ + // \ \ \ + // + + + + // | | | + // 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // : : : : | : : : : : : : | : : : : : : : | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + const u8_t src = static_cast(((*saved_bits) << 2u) | ((source_byte & 0xc0) >> 6u)); + value = octet_to_ascii_armor(src); + target[*output_ind] = value; + ++(*output_ind); + value = octet_to_ascii_armor(static_cast(source_byte & 0x3f)); + target[*output_ind] = value; + ++(*output_ind); + *saved_bits = 0u; + *saved_bit_count = 0u; + } + else + { + eap_am_tools_c *m_am_tools = this; + EAP_UNREFERENCED_PARAMETER(m_am_tools); + EAP_ASSERT(*saved_bit_count == 0u || *saved_bit_count == 2u || *saved_bit_count == 4u); + } + + if (last_input_byte == true + && *saved_bit_count > 0u) + { + value = octet_to_ascii_armor(static_cast((*saved_bits) << (6u - *saved_bit_count))); + target[*output_ind] = value; + ++(*output_ind); + *saved_bits = 0u; + *saved_bit_count = 0u; + } + +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_c::restore_selected_bytes_from_ascii_armor( + const u8_t source_byte, + u32_t * const missing_bit_count, + u8_t * const target, + u32_t * const output_ind, + const bool last_input_byte) +{ + u8_t value; + + EAP_UNREFERENCED_PARAMETER(last_input_byte); + + if (source_byte == '=') + { + return; + } + + if (*missing_bit_count == 0u) + { + /* |0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+ + // | : : : : : : : | + // +-+-+-+-+-+-+-+-+ + // |0 1 2 3 4 5|0 1 + // | + + // | \ + // | \ + // | + + // | | + // |0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+ + // | : : : : : : : | + // +-+-+-+-+-+-+-+-+ + */ + value = static_cast(octet_from_ascii_armor(source_byte) << 2u); + target[*output_ind] = value; + *missing_bit_count = 2u; + } + else if (*missing_bit_count == 2u) + { + /* 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+ + // : : | : : : : : : : | + // +-+-+-+-+-+-+-+-+-+-+ + // |0 1 2 3 4 5|0 1 2 3 + // | + + // | \ + // + \ + // \ \ + // \ \ + // + + + // | | + // 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+ + // : : | : : : : : : : | + // +-+-+-+-+-+-+-+-+-+-+ + */ + value = octet_from_ascii_armor(source_byte); + target[*output_ind] |= (value & 0x30) >> 4u; + ++(*output_ind); + if (last_input_byte == false) + { + target[*output_ind] = static_cast((value & 0x0f) << 4u); + *missing_bit_count = 4u; + } + else + { + *missing_bit_count = 0u; + } + } + else if (*missing_bit_count == 4u) + { + /* 4 5 6 7|0 1 + // +-+-+-+-+-+-+ + // : : : : | : : + // +-+-+-+-+-+-+ + // |0 1 2 3 4 5| + // | + + // | \ + // + \ + // \ \ + // \ \ + // \ \ + // \ \ + // + + + // | | + // 4 5 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+-+-+ + // : : : : | : : : : : : : | + // +-+-+-+-+-+-+-+-+-+-+-+-+ + */ + value = octet_from_ascii_armor(source_byte); + target[*output_ind] |= (value >> 2u) & 0x0f; + ++(*output_ind); + if (last_input_byte == false) + { + target[*output_ind] = static_cast((value & 0x03) << 6u); + *missing_bit_count = 6u; + } + else + { + *missing_bit_count = 0u; + } + } + else if (*missing_bit_count == 6u) + { + /* 2 3 4 5 6 7| + // +-+-+-+-+-+-+ + // : : : : : : | + // +-+-+-+-+-+-+ + // |0 1 2 3 4 5| + // | + + // | \ + // + \ + // \ \ + // \ \ + // \ \ + // \ \ + // \ \ + // \ \ + // + + + // | | + // 2 3 4 5 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // : : : : : : | : : : : : : : | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + value = octet_from_ascii_armor(source_byte); + target[*output_ind] |= value; + ++(*output_ind); + *missing_bit_count = 0u; + } + else + { + eap_am_tools_c *m_am_tools = this; + EAP_UNREFERENCED_PARAMETER(m_am_tools); + EAP_ASSERT(*missing_bit_count == 0u || *missing_bit_count == 2u || *missing_bit_count == 4u || *missing_bit_count == 6u); + } + +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_bytes_to_ascii_armor( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length) +{ + if (source_bytes == 0) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + if (target == 0) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + if (target_length == 0) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + /* 8-bit ascii values are converted to binary 6-bit blocks. Ascii values can easily represent 2^6=64 values. + // If length of source array is not module 3, missing bits are padded with zero bits. + + // |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : |0:0:0:0| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5| + // | | | | | | + + // | | | | | | \ + // | | | | | + \ + // | | | | | \ \ + // | | | | + \ \ + // | | | | \ \ \ + // | | | + \ \ \ + // | | | \ \ \ \ + // | | + \ \ \ \ + // | | \ \ \ \ \ + // | + \ \ \ \ \ + // | \ \ \ \ \ \ + // | \ \ \ \ \ \ + // | + + + + + + + // | | | | | | | + // |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + u32_t output_ind = 0u; + u32_t input_ind = 0u; + u32_t input_count = (source_bytes_length*4u < (*target_length)*3u) ? source_bytes_length : (*target_length)*3u/4u; + u8_t saved_bits = 0u; + u32_t saved_bit_count = 0ul; + + for (input_ind = 0u; input_ind < input_count; input_ind++) + { + convert_selected_bytes_to_ascii_armor(source_bytes[input_ind], &saved_bit_count, &saved_bits, target, &output_ind, (input_ind+1 == input_count)); + } // for() + + u32_t remainder = output_ind % 4ul; + if (remainder != 0ul) + { + u32_t padding_count(4ul - remainder); + + if (padding_count == 2ul) + { + // Add padding '='-characters. + target[output_ind++] = '='; + --padding_count; + } + if (padding_count == 1ul) + { + // Add padding '='-characters. + target[output_ind++] = '='; + } + } + + *target_length = output_ind; + + return eap_status_ok; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::restore_bytes_from_ascii_armor( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length) +{ + if (source_bytes == 0) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + if (target == 0) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + if (target_length == 0) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + /* Binary 6-bit blocks are converted to 8-bit ascii values. Ascii values can easily represent 2^6=64 values. + // If length of target array is not module 3, padding zero bits are ignored. + + // |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5| + // | | | | | | + + // | | | | | | \ + // | | | | | + \ + // | | | | | \ \ + // | | | | + \ \ + // | | | | \ \ \ + // | | | + \ \ \ + // | | | \ \ \ \ + // | | + \ \ \ \ + // | | \ \ \ \ \ + // | + \ \ \ \ \ + // | \ \ \ \ \ \ + // | \ \ \ \ \ \ + // | + + + + + + + // | | | | | | | + // |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + u32_t output_ind = 0u; + u32_t input_ind = 0u; + u32_t input_count = source_bytes_length; + u32_t missing_bit_count = 0ul; + + for (input_ind = 0u; input_ind < input_count; input_ind++) + { + restore_selected_bytes_from_ascii_armor(source_bytes[input_ind], &missing_bit_count, target, &output_ind, (input_ind+1 == input_count)); + } // for() + + *target_length = output_ind; + + return eap_status_ok; +} + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::eap_status_return( + const bool print_error_when_true, + const eap_status_e status, + const eap_char * const file_name, + const i32_t line_number) +{ + if (status == eap_status_not_supported) + { + eap_status_string_c status_string; + + EAP_UNREFERENCED_PARAMETER(file_name); + EAP_UNREFERENCED_PARAMETER(line_number); + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("TODO: %s=%d returned from %s:%d\n"), + status_string.get_status_string(status), + status, + file_name, + line_number)); + } + else if (status == eap_status_success) + { + eap_status_string_c status_string; + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("SUCCESS: %s=%d returned from %s:%d\n"), + status_string.get_status_string(status), + status, + file_name, + line_number)); + } + else if (status == eap_status_not_found + || status == eap_status_illegal_configure_field + || status == eap_status_illegal_configure_type + || status == eap_status_syncronization_failure) + { + eap_status_string_c status_string; + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: %s=%d returned from %s:%d\n"), + status_string.get_status_string(status), + status, + file_name, + line_number)); + } + else if (status == eap_status_pending_request + || status == eap_status_completed_request + || status == eap_status_drop_packet_quietly + || status == eap_status_end_of_file + || status == eap_status_section_ends + || status == eap_status_end_recursion) + { + eap_status_string_c status_string; + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("INFO: %s=%d returned from %s:%d\n"), + status_string.get_status_string(status), + status, + file_name, + line_number)); + } +#if defined(_DEBUG) + else if ((get_trace_mask() & TRACE_FLAGS_OK_RETURNS) + && (status == eap_status_ok + || status == eap_status_success + || status == eap_status_not_supported + || status == eap_status_pending_request + || status == eap_status_completed_request + || status == eap_status_drop_packet_quietly) + ) + { + eap_status_string_c status_string; + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("EXTRA: %s=%d returned from %s:%d\n"), + status_string.get_status_string(status), + status, + file_name, + line_number)); + } +#endif + else if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_not_supported + && status != eap_status_pending_request + && status != eap_status_completed_request + && status != eap_status_drop_packet_quietly + ) + { + check_activate_trace_on_error(); + + eap_status_string_c status_string; + + if (print_error_when_true == true) + { + EAP_TRACE_ALWAYS( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s=%d returned from %s:%d\n"), + status_string.get_status_string(status), + status, + file_name, + line_number)); + } + else + { + EAP_TRACE_ALWAYS( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: %s=%d returned from %s:%d\n"), + status_string.get_status_string(status), + status, + file_name, + line_number)); + } + } + + return status; +} + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::eap_status_return_file_number( + const bool print_error_when_true, + const eap_status_e status, + const u32_t file_date, + const u32_t file_number, + const i32_t line_number) +{ + if (status == eap_status_not_supported) + { + eap_status_string_c status_string; + + EAP_UNREFERENCED_PARAMETER(file_date); + EAP_UNREFERENCED_PARAMETER(file_number); + EAP_UNREFERENCED_PARAMETER(line_number); + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("TODO: %d:%d:%d:%d\n"), + status, + file_date, + file_number, + line_number)); + } + else if (status == eap_status_success) + { + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("SUCCESS: %d:%d:%d:%d\n"), + status, + file_date, + file_number, + line_number)); + } + else if (status == eap_status_not_found + || status == eap_status_illegal_configure_field + || status == eap_status_illegal_configure_type + || status == eap_status_syncronization_failure) + { + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: %d:%d:%d:%d\n"), + status, + file_date, + file_number, + line_number)); + } + else if (status == eap_status_pending_request + || status == eap_status_completed_request + || status == eap_status_drop_packet_quietly + || status == eap_status_end_of_file + || status == eap_status_section_ends) + { + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("INFO: %d:%d:%d:%d\n"), + status, + file_date, + file_number, + line_number)); + } + else if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_not_supported + && status != eap_status_pending_request + && status != eap_status_completed_request + && status != eap_status_drop_packet_quietly + + ) + { + check_activate_trace_on_error(); + + if (print_error_when_true == true) + { + EAP_TRACE_ALWAYS( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %d:%d:%d:%d\n"), + status, + file_date, + file_number, + line_number)); + } + else + { + EAP_TRACE_ALWAYS( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: %d:%d:%d:%d\n"), + status, + file_date, + file_number, + line_number)); + } + } + + return status; +} + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::memory_store_add_data( + const eap_variable_data_c * const key, + eap_tlv_message_data_c * const data, + const u32_t timeout) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + +#if !defined(NO_EAP_AM_MEMORY_STORE) + + if (m_memory_store == 0 + || m_memory_store->get_is_valid() == false) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + + eap_status_e status = m_memory_store->add_data( + key, + data, + timeout); + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + +#else + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_not_supported); + +#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) +} + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::memory_store_get_data( + const eap_variable_data_c * const key, + eap_tlv_message_data_c * const data) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + +#if !defined(NO_EAP_AM_MEMORY_STORE) + + if (m_memory_store == 0 + || m_memory_store->get_is_valid() == false) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + + eap_status_e status = eap_status_process_general_error; + + status = m_memory_store->get_data( + key, + data); + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + +#else + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_not_found); + +#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) + +} + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::memory_store_remove_data( + const eap_variable_data_c * const key) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + +#if !defined(NO_EAP_AM_MEMORY_STORE) + + if (m_memory_store == 0 + || m_memory_store->get_is_valid() == false) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + + eap_status_e status = m_memory_store->remove_data( + key); + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + +#else + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_not_found); + +#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::shutdown_am_tools() +{ + eap_status_e status = eap_status_ok; + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_tools_c::shutdown_am_tools(); this = 0x%08x\n"), + this)); + + if (m_shutdown_was_called == false) + { + m_shutdown_was_called = true; + + #if !defined(NO_EAP_AM_MEMORY_STORE) + if (m_memory_store != 0) + { + status = m_memory_store->shutdown(); + } + delete m_memory_store; + m_memory_store = 0; + #endif //#if !defined(NO_EAP_AM_MEMORY_STORE) + } + + return EAP_STATUS_RETURN(this, status); +} + +//-------------------------------------------------- + +/// Coverts unicode string to UTF8 string. +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::generic_convert_unicode_to_utf8( + eap_variable_data_c & dest, + const eap_variable_data_c & src) +{ + if (src.get_is_valid_data() == true) + { + u32_t len = src.get_data_length(); + u8_t * ascii = new u8_t[len / 2]; + if (!ascii) + { + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + u8_t * src_ptr = src.get_data(len); + u32_t dest_len = len / 2; + u32_t i; + for (i = 0; i < dest_len; i++) + { + ascii[i] = src_ptr[i * 2]; + } + + return EAP_STATUS_RETURN(this, dest.set_buffer(ascii, dest_len, true, true)); + } + + return EAP_STATUS_RETURN(this, eap_status_process_general_error); +} + +//-------------------------------------------------- + +/// Coverts UTF8 string to unicode string. Not yet implemented. +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::generic_convert_utf8_to_unicode( + eap_variable_data_c & dest, + const eap_variable_data_c & src) +{ + if (src.get_is_valid_data() == true) + { + u32_t len = src.get_data_length(); + u8_t * src_ptr = src.get_data(len); + + eap_status_e status = dest.set_buffer_length(2ul*len); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(this, status); + } + + u8_t null_byte(0x00); + u32_t i; + for (i = 0; i < len; i++) + { + status = dest.add_data(&(src_ptr[i]), sizeof(u8_t)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(this, status); + } + + status = dest.add_data(&null_byte, sizeof(u8_t)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(this, status); + } + } + + return EAP_STATUS_RETURN(this, eap_status_ok); + } + + return EAP_STATUS_RETURN(this, eap_status_process_general_error); +} + +//----------------------------------------------------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::parse_nai( + const eap_variable_data_c * const nai, + eap_variable_data_c * const username, + eap_variable_data_c * const realm) +{ + if (nai == 0 + || username == 0 + || realm == 0) + { + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + username->reset(); + realm->reset(); + + if (nai->get_is_valid() == false) + { + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + EAP_TRACE_DATA_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_tools_c::parse_nai(): NAI"), + nai->get_data(), + nai->get_data_length())); + + + eap_status_e status(eap_status_ok); + u32_t username_length = nai->get_data_length(); + + // We read the realm from NAI. + const u8_t *at_character = reinterpret_cast( + memchr( + nai->get_data(nai->get_data_length()), + EAP_AT_CHARACTER, + nai->get_data_length())); + if (at_character != 0 + && nai->get_data_length() + > ((1UL + reinterpret_cast(at_character)) + - reinterpret_cast(nai->get_data( + nai->get_data_length())))) + { + u32_t realm_length = nai->get_data_length() + - ((1UL + reinterpret_cast(at_character)) + - reinterpret_cast(nai->get_data( + nai->get_data_length()))); + + if (realm_length > 0UL) + { + status = realm->set_copy_of_buffer( + at_character+1, + realm_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + } + + username_length -= (realm_length + 1ul); + } + } + else + { + // No realm. + } + + // The begin of the NAI to '@' or the end is username. + status = username->set_copy_of_buffer( + nai->get_data(username_length), + username_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + } + + EAP_TRACE_DATA_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_tools_c::parse_nai(): username"), + username->get_data(), + username->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_tools_c::parse_nai(): realm"), + realm->get_data(), + realm->get_data_length())); + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); +} + +//----------------------------------------------------------------------------------------------- + +#if defined(USE_EAP_ERROR_TESTS) + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::generate_random_error( + eap_buf_chain_wr_c * const sent_packet, + const bool forse_error, + const u32_t packet_index, + const u32_t minimum_index, + const u32_t error_probability, + const u32_t minimum_packet_length) +{ + eap_status_e status(eap_status_ok); + EAP_UNREFERENCED_PARAMETER(packet_index); + + u8_t *data = sent_packet->get_data(sent_packet->get_data_length()); + if (data == 0) + { + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + + crypto_random_c rand(this); + u32_t random_guard = 0; + bool error_generated = false; + + for (u32_t ind = minimum_index; ind < sent_packet->get_data_length(); ind++) + { + status = rand.get_rand_bytes( + reinterpret_cast(&random_guard), + sizeof(random_guard)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(this, status); + } + + // This is simple limiter to the probability of an error. + // probability = m_error_probability / (2^32) + if (random_guard < error_probability) + { + u8_t rnd; + u8_t previous_data; + // Create an error. + status = rand.get_rand_bytes( + &rnd, + sizeof(rnd)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(this, status); + } + + previous_data = data[ind]; + data[ind] ^= rnd; + + if (previous_data != data[ind]) + { + error_generated = true; + sent_packet->set_random_error_type(eap_random_error_type_manipulate_byte); + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): error: manipulate, packet_index 0x%08x:%lu, data[0x%04x] ") + EAPL("changed from 0x%02x to 0x%02x.\n"), + this, packet_index, ind, previous_data, data[ind])); + } + } + } // for() + + + if (error_generated == false + && forse_error == true + && sent_packet->get_data_length() > 0ul) + { + // Generate one error. + + // Random error type. + eap_random_error_type error_type = eap_random_error_type_none_keep_this_last_case; + status = rand.get_rand_bytes( + reinterpret_cast(&error_type), + sizeof(error_type)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(this, status); + } + + error_type = static_cast( + static_cast(error_type) + % static_cast(eap_random_error_type_none_keep_this_last_case)); + + sent_packet->set_random_error_type(error_type); + + switch(error_type) + { + case eap_random_error_type_manipulate_byte: + { + u32_t rnd_index; + u8_t previous_data; + u32_t index; + + do + { + do + { + // Create an error index. + status = rand.get_rand_bytes( + reinterpret_cast(&rnd_index), + sizeof(rnd_index)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(this, status); + } + + index = (rnd_index % (sent_packet->get_data_length() - minimum_index)) + + minimum_index; + } + while(index < minimum_index + || index > sent_packet->get_buffer_length()); + + u8_t rnd; + // Create an error. + status = rand.get_rand_bytes( + &rnd, + sizeof(rnd)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(this, status); + } + + previous_data = data[index]; + data[index] ^= rnd; + } + while(previous_data == data[index]); + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): error: manipulate, packet_index 0x%08x:%lu, ") + EAPL("data[0x%04x] changed from 0x%02x to 0x%02x.\n"), + this, packet_index, index, previous_data, data[index])); + + error_generated = true; + } + break; + case eap_random_error_type_change_packet_length_longer: + { + u8_t delta_length = 0; + i32_t new_length = 0; + + do + { + status = rand.get_rand_bytes( + reinterpret_cast(&delta_length), + sizeof(delta_length)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(this, status); + } + + new_length = static_cast(sent_packet->get_data_length()) + static_cast(delta_length); + } + while (new_length < static_cast(minimum_packet_length) /*eapol_ethernet_header_wr_c::get_header_length()*/ + || new_length > static_cast(sent_packet->get_buffer_length())); + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): error: manipulate, packet_index 0x%08x:%lu, ") + EAPL("packet length changed from %lu to %lu.\n"), + this, + packet_index, + sent_packet->get_data_length(), + new_length)); + + sent_packet->set_data_length(new_length); + + error_generated = true; + } + break; + case eap_random_error_type_change_packet_length_shorter: + { + u8_t delta_length = 0; + i32_t new_length = 0; + + do + { + status = rand.get_rand_bytes( + reinterpret_cast(&delta_length), + sizeof(delta_length)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(this, status); + } + + delta_length %= (static_cast(sent_packet->get_data_length()) + - static_cast(minimum_packet_length) /*eapol_ethernet_header_wr_c::get_header_length()*/ ); + + if (delta_length == 0) + { + continue; + } + + new_length = static_cast(sent_packet->get_data_length()) - static_cast(delta_length); + } + while (new_length < static_cast(minimum_packet_length) /*eapol_ethernet_header_wr_c::get_header_length()*/ + || new_length > static_cast(sent_packet->get_buffer_length())); + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): error: manipulate, packet_index 0x%08x:%lu, ") + EAPL("packet length changed from %lu to %lu.\n"), + this, + packet_index, + sent_packet->get_data_length(), + new_length)); + + sent_packet->set_data_length(new_length); + + error_generated = true; + } + break; + default: + EAP_ASSERT_ANYWAY_TOOLS(this); + break; + } + } // if () + + + if (error_generated == true) + { + sent_packet->set_is_manipulated(); + } + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); +} + +#endif //#if defined(USE_EAP_ERROR_TESTS) + +//----------------------------------------------------------------------------------------------- + +#if defined(USE_EAP_ERROR_TESTS) + +EAP_FUNC_EXPORT u32_t eap_am_tools_c::get_packet_index() +{ + return m_packet_index; +} + +#endif //#if defined(USE_EAP_ERROR_TESTS) + +//----------------------------------------------------------------------------------------------- + +#if defined(USE_EAP_ERROR_TESTS) + +EAP_FUNC_EXPORT void eap_am_tools_c::increase_packet_index() +{ + ++m_packet_index; +} + +#endif //#if defined(USE_EAP_ERROR_TESTS) + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::number_string_to_u32( + const u8_t * const number_string, + const u32_t number_string_length, + u32_t * const integer) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + + if (number_string == 0 + || number_string_length == 0UL + || integer == 0) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + *integer = 0UL; + + u32_t multiplier = 1UL; + + for (i32_t ind = number_string_length-1; ind >= 0; ind--) + { + u8_t character = number_string[ind]; + if (character < '0' || '9' < character) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_data_payload); + } + + u8_t digit = ascii_to_octet(static_cast(number_string[ind])); + + u32_t addition = static_cast(digit) * multiplier; + if (((~0UL) - *integer) < addition) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_illegal_data_payload); + } + + *integer += addition; + + multiplier *= 10UL; + } + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_ok); +} + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_tools_c::trace_configuration( + const eap_status_e configuration_read_status, + const eap_configuration_field_c * const field, + const eap_variable_data_c * const data) +{ + EAP_UNREFERENCED_PARAMETER(data); + + if (configuration_read_status != eap_status_ok) + { + EAP_TRACE_DATA_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: unknown configuration parameter"), + field->get_field(), + field->get_field_length())); + } + else + { + EAP_TRACE_DATA_ALWAYS( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("configuration parameter"), + field->get_field(), + field->get_field_length())); + + if (field->get_is_secret() == true) + { + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("This is secret data. Not shown here.\n"))); + } + else + { + EAP_TRACE_DATA_ALWAYS( + this, + TRACE_FLAGS_DEFAULT, + (EAPL(" configuration value"), + data->get_data(data->get_data_length()), + data->get_data_length())); + } + } +} + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT u64_t eap_am_tools_c::xor_u64( + const u64_t p_a, + const u64_t p_b) +{ + +#if defined(USE_EAP_64_BIT_XOR) + + u64_t ret = p_a ^ p_b; + +#else + + u64_struct a = u64_t_to_u64_struct(p_a); + u64_struct b = u64_t_to_u64_struct(p_b); + + + // Result + u64_struct result; + result.high = a.high ^ b.high; + result.low = a.low ^ b.low; + + u64_t ret = u64_struct_to_u64_t(result); + +#endif //#if defined(USE_EAP_64_BIT_XOR) + + return ret; +} + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT u64_t eap_am_tools_c::multiply_u64( + const u64_t p_a, + const u64_t p_b) +{ + +#if defined(USE_EAP_64_BIT_MULTIPLICATION) + + return p_a * p_b; + +#else + + u32_t a_tmp[4]; + u32_t b_tmp[4]; + u32_t wide_tmp[8]; + u32_t tmp; + u64_struct a = u64_t_to_u64_struct(p_a); + u64_struct b = u64_t_to_u64_struct(p_b); + + // <--- 32 bits ---> <--- 32 bits ---> <--- 32 bits ---> <--- 32 bits ---> + // +--------+--------+--------+--------+--------+--------+--------+--------+ + // | overf. | 0-15 | overf. | 16-31 | overf. | 32-47 | overf. | 48-63 | + // +--------+--------+--------+--------+--------+--------+--------+--------+ + a_tmp[0] = a.low & 0xffff; + a_tmp[1] = (a.low >> 16) & 0xffff; + a_tmp[2] = a.high & 0xffff; + a_tmp[3] = (a.high >> 16) & 0xffff; + + b_tmp[0] = b.low & 0xffff; + b_tmp[1] = (b.low >> 16) & 0xffff; + b_tmp[2] = b.high & 0xffff; + b_tmp[3] = (b.high >> 16) & 0xffff; + + u32_t j_ind; + + for(j_ind = 0ul; j_ind < 4ul; j_ind++) + { + wide_tmp[j_ind]= 0ul; + } + + for(j_ind = 0ul; j_ind < 4ul; j_ind++) + { + if(b_tmp[j_ind] == 0ul) + { + wide_tmp[j_ind+4ul] = 0ul; + } + else + { + u32_t l_ind; + u32_t overflow = 0ul; + + for(l_ind = 0ul; l_ind < 4ul; l_ind++) + { + tmp = a_tmp[l_ind] * b_tmp[j_ind] + wide_tmp[l_ind+j_ind] + overflow; + wide_tmp[l_ind+j_ind] = tmp & 0xffff; + overflow = (tmp >> 16) & 0xffff; + } + + wide_tmp[j_ind+4] = overflow; + } + } + + // Overflow + u64_struct overflow; + overflow.high = ((wide_tmp[7] << 16) & 0xffff0000) + wide_tmp[6]; + overflow.low = ((wide_tmp[5] << 16) & 0xffff0000) + wide_tmp[4]; + EAP_UNREFERENCED_PARAMETER(overflow); + + + // Result + u64_struct result; + result.high = ((wide_tmp[3] << 16) & 0xffff0000) + wide_tmp[2]; + result.low = ((wide_tmp[1] << 16) & 0xffff0000) + wide_tmp[0]; + + u64_t ret = u64_struct_to_u64_t(result); + + return ret; + +#endif //#if defined(USE_EAP_64_BIT_MULTIPLICATION) + +} + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT i32_t eap_am_tools_c::compare_u64(const u64_t p_a, const u64_t p_b) +{ + u64_struct a = u64_t_to_u64_struct(p_a); + u64_struct b = u64_t_to_u64_struct(p_b); + + if (a.high > b.high) + { + return +1; + } + else if (a.high < b.high) + { + return -1; + } + else // if (a.high == b.high) + { + if (a.low > b.low) + { + return +1; + } + else if (a.low < b.low) + { + return -1; + } + else + { + return 0; + } + } +} + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::create_uuid_v5( + const void* const ns_uuid, + const u32_t ns_uuid_length, + const void* const name, + const u32_t name_length, + eap_variable_data_c* const uuid ) +{ + // check input + if( ns_uuid == 0 || + ns_uuid_length != EAP_UUID_LENGTH || + name == 0 || name_length <= 0 || + uuid == 0 || uuid->get_is_valid() == false ) + { + return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); + } + + // make sure that uuid is empty + uuid->reset(); + + crypto_sha1_c sha( this ); + if( sha.get_is_valid() == false ) + { + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + + u32_t hash_len = sha.get_digest_length(); + // hash length must be at least the UUID length + if( hash_len < EAP_UUID_LENGTH ) + { + return EAP_STATUS_RETURN(this, eap_status_illegal_encryption_parameter_size); + } + + eap_status_e status = sha.hash_init(); + if( status != eap_status_ok ) + { + return EAP_STATUS_RETURN(this, status); + } + + status = sha.hash_update( ns_uuid, ns_uuid_length ); + if( status != eap_status_ok ) + { + return EAP_STATUS_RETURN(this, status); + } + + status = sha.hash_update( name, name_length ); + if( status != eap_status_ok ) + { + return EAP_STATUS_RETURN(this, status); + } + + u8_t* hash = new u8_t[hash_len]; + if( hash == 0 ) + { + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + + status = sha.hash_final( hash, 0 ); // 0 - we have space for full digest in hash + if( status != eap_status_ok ) + { + delete[] hash; + hash = 0; + return EAP_STATUS_RETURN(this, status); + } + + // save only the needed bytes + status = uuid->set_copy_of_buffer(hash, EAP_UUID_LENGTH ); + delete[] hash; + if( status != eap_status_ok ) + { + return EAP_STATUS_RETURN(this, status); + } + + // use hash as a temporary pointer + hash = uuid->get_data(); + + // Format according to UUID version 5 (RFC 4122). + // MSByte LSByte + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | time_low | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | time_mid | time_hi_and_version | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |clk_seq_hi_res | clk_seq_low | node (0-1) | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | node (2-5) | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // set the four most significant bits (bits 12 through 15) of the + // time_hi_and_version field to the appropriate 4-bit version number + hash[6] &= 0x0F; + hash[6] |= 0x50; + + // set the two most significant bits (bits 6 and 7) of the + // clock_seq_hi_and_reserved to zero and one, respectively + hash[8] &= 0x3F; + hash[8] |= 0x80; + + return EAP_STATUS_RETURN(this, eap_status_ok); +} + +//----------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::create_uuid_v5_from_mac_address( + const u8_t* const mac_address, + const u32_t mac_address_length, + eap_variable_data_c* const uuid ) +{ + + eap_status_e status = create_uuid_v5( + EAP_MAC_ADDRESS_NAMESPACE_UUID_V5, + sizeof(EAP_MAC_ADDRESS_NAMESPACE_UUID_V5), + mac_address, + mac_address_length, + uuid); + + return EAP_STATUS_RETURN(this, status); +} + +//----------------------------------------------------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/eap_file_config.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/eap_file_config.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2229 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 14 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_file_config.h" +#include "eap_automatic_variable.h" + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + + +#if 0 + const u32_t TRACE_FLAGS_CONFIGURE_DATA = TRACE_FLAGS_DEFAULT; +#else + const u32_t TRACE_FLAGS_CONFIGURE_DATA = eap_am_tools_c::eap_trace_mask_none; +#endif + +//----------------------------------------------------------------- +//----------------------------------------------------------------- +//----------------------------------------------------------------- + +eap_config_value_c::~eap_config_value_c() +{ + delete m_subsection_map; + m_subsection_map = 0; +} + +eap_config_value_c::eap_config_value_c( + abs_eap_am_tools_c* const tools) + : m_am_tools(tools) + , m_subsection_map(0) + , m_data(tools) + , m_type(eap_configure_type_none) + , m_is_valid(false) +{ + if (m_data.get_is_valid() == false) + { + return; + } + + m_is_valid = true; +} + +void eap_config_value_c::set_subsection( + eap_core_map_c * const subsection_map) +{ + m_subsection_map = subsection_map; +} + +eap_core_map_c * eap_config_value_c::get_subsection() +{ + return m_subsection_map; +} + +eap_variable_data_c * eap_config_value_c::get_data() +{ + return &m_data; +} + +void eap_config_value_c::set_type(const eap_configure_type_e type) +{ + m_type = type; +} + +eap_configure_type_e eap_config_value_c::get_type() +{ + return m_type; +} + +void eap_config_value_c::object_increase_reference_count() +{ +} + +bool eap_config_value_c::get_is_valid() +{ + return m_is_valid; +} + +//----------------------------------------------------------------- +//----------------------------------------------------------------- +//----------------------------------------------------------------- + + +EAP_FUNC_EXPORT eap_file_config_c::eap_file_config_c( + abs_eap_am_tools_c* const tools) +: m_am_tools(tools) +, m_config_map(tools, this) +, m_is_valid(false) +{ + EAP_UNREFERENCED_PARAMETER(TRACE_FLAGS_CONFIGURE_DATA); // in release + + set_is_valid(); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_file_config_c::~eap_file_config_c() +{ +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::configure( + abs_eap_am_file_input_c * const file) +{ + eap_status_e status = read_subsections(file, &m_config_map); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::expand_environment_variables( + eap_core_map_c * const config_map, + const eap_variable_data_c * const original_value, + eap_variable_data_c * const expanded_value + ) +{ + eap_status_e status = eap_status_process_general_error; + + if (original_value == 0 + || expanded_value == 0 + ) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u8_t env_char = '$'; + const u8_t char_left_parenthesis = '('; + const u8_t char_right_parenthesis = ')'; + + eap_variable_data_c tmp_value_buffer(m_am_tools); + if (tmp_value_buffer.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tmp_value_buffer.set_buffer_length(MAX_LINE_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + bool expanded_value_when_true = false; + + status = expanded_value->set_copy_of_buffer(original_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + for (;;) + { + u8_t * const start_of_value = expanded_value->get_data(expanded_value->get_data_length()); + + u8_t * const env_start = static_cast(m_am_tools->memchr( + start_of_value, + env_char, + expanded_value->get_data_length())); + + if (env_start == 0) + { + status = eap_status_ok; + break; + } + else + { + if (static_cast((env_start+2)-start_of_value) < expanded_value->get_data_length() + && env_start[1] == char_left_parenthesis) + { + u8_t *tmp_end = start_of_value + expanded_value->get_data_length(); + + u8_t *env_end = static_cast(m_am_tools->memchr( + env_start, + char_right_parenthesis, + tmp_end-env_start)); + if (env_end != 0) + { + *env_end = '\0'; + + u8_t *env_name = env_start+2; + + eap_variable_data_c env_name_buffer(m_am_tools); + if (env_name_buffer.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = env_name_buffer.set_buffer( + env_name, + env_end-env_name, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c env_value_buffer(m_am_tools); + if (env_value_buffer.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e env_status = m_am_tools->getenv( + &env_name_buffer, + &env_value_buffer); + + eap_variable_data_c parsed_value_buffer(m_am_tools); + if (parsed_value_buffer.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = parsed_value_buffer.set_buffer_length(MAX_LINE_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + parsed_value_buffer.set_data_length(MAX_LINE_LENGTH); + + eap_variable_data_c configure_option(m_am_tools); + if (configure_option.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (env_status != eap_status_ok) + { + // Next check whether a one of the defined configuration + // options match to the variable. + eap_configure_type_e configuration_data_type = eap_configure_type_none; + static const u32_t EAP_MAX_CONFIG_BUFFER_LENGTH = 256; + eap_configuration_field_template_c * const tmp_env_name + = new eap_configuration_field_template_c; + + eap_automatic_variable_c > + automatic_tmp_env_name(m_am_tools, tmp_env_name); + + if (tmp_env_name == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = tmp_env_name->set_fields( + m_am_tools, + env_name, + eap_configure_type_none, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = read_configure( + config_map, + tmp_env_name->get_field(), + &configure_option, + &configuration_data_type, + false); + + if (status == eap_status_ok) + { + if (configuration_data_type == eap_configure_type_string) + { + status = configure_option.add_end_null(); + } + else if (configuration_data_type == eap_configure_type_u32_t) + { + u32_t * const p_value = reinterpret_cast( + configure_option.get_data( + configure_option.get_data_length())); + if (p_value != 0) + { + u32_t value = *p_value; + + status = configure_option.set_buffer_length(EAP_MAX_CONFIG_BUFFER_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = configure_option.set_data_length(EAP_MAX_CONFIG_BUFFER_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t length = m_am_tools->snprintf( + reinterpret_cast( + configure_option.get_data( + configure_option.get_data_length())), + EAP_MAX_CONFIG_BUFFER_LENGTH, + EAPL("%u"), + value); + status = configure_option.set_data_length(length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = configure_option.add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (configuration_data_type == eap_configure_type_boolean) + { + u32_t * const p_value = reinterpret_cast( + configure_option.get_data( + configure_option.get_data_length())); + if (p_value != 0) + { + bool value = (*p_value == 0) ? false : true; + + status = configure_option.set_buffer_length(EAP_MAX_CONFIG_BUFFER_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = configure_option.set_data_length(EAP_MAX_CONFIG_BUFFER_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (value == true) + { + u32_t length = m_am_tools->snprintf( + reinterpret_cast( + configure_option.get_data( + configure_option.get_data_length())), + EAP_MAX_CONFIG_BUFFER_LENGTH, + EAPL("true")); + status = configure_option.set_data_length(length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + u32_t length = m_am_tools->snprintf( + reinterpret_cast( + configure_option.get_data( + configure_option.get_data_length())), + EAP_MAX_CONFIG_BUFFER_LENGTH, + EAPL("false")); + configure_option.set_data_length(length); + } + + status = configure_option.add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (configuration_data_type == eap_configure_type_hex_data) + { + u8_t * const p_value = reinterpret_cast( + configure_option.get_data( + configure_option.get_data_length())); + + u8_t buffer[3]; + u8_t comma(','); + + eap_variable_data_c tmp(m_am_tools); + if (tmp.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + for (u32_t ind = 0ul; ind < configure_option.get_data_length(); ind++) + { + u32_t length = m_am_tools->snprintf( + buffer, + sizeof(buffer), + EAPL("%02x"), + p_value[ind]); + + status = tmp.add_data(buffer, length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if ((ind+1) < configure_option.get_data_length()) + { + status = tmp.add_data(&comma, sizeof(comma)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } // for() + + status = configure_option.set_copy_of_buffer(&tmp); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = configure_option.add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + if (configure_option.get_is_valid_data() == false + || configure_option.get_data_length() == 0ul) + { + #if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + printf("WARNING: CONFIG: unknown environment variable %s.\n", + env_name); + #endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: CONFIG: unknown environment variable %s.\n"), + env_name)); + + // This is empty environment value. + } + } + else + { + // OK environment variable found. + eap_configure_type_e type = eap_configure_type_none; + + status = cnf_parse_value( + &env_value_buffer, + &env_name_buffer, + &type, + &configure_option, + true + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + if (configure_option.get_is_valid_data() == true + && configure_option.get_data_length() > 0ul) + { + tmp_value_buffer.reset(); + + u32_t tmp_index = 0ul; + + if (env_start > start_of_value) + { + u32_t length_of_begin = env_start-start_of_value; + if (length_of_begin > 0ul) + { + status = tmp_value_buffer.set_copy_of_buffer( + expanded_value->get_data(length_of_begin), + length_of_begin); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + tmp_index += length_of_begin; + } + } + + if (configure_option.get_data_length() > 0ul) + { + status = tmp_value_buffer.add_data(&configure_option); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + tmp_index += configure_option.get_data_length(); + } + + if (tmp_end > (env_end+1)) + { + u32_t length_of_end = tmp_end-(env_end+1); + if (length_of_end > 0ul) + { + status = tmp_value_buffer.add_data( + (env_end+1), + length_of_end); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + tmp_index += length_of_end; + } + } + + if (tmp_value_buffer.get_is_valid_data() == true + && tmp_value_buffer.get_data_length() > 0ul) + { + status = expanded_value->set_copy_of_buffer(&tmp_value_buffer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = expanded_value->add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + expanded_value_when_true = true; + } + + } + } + else + { + #if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + printf("ERROR: CONFIG: illegal configure value %s.\n", + expanded_value->get_data(expanded_value->get_data_length())); + #endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: CONFIG: illegal configure value %s.\n"), + expanded_value->get_data(expanded_value->get_data_length()))); + status = eap_status_illegal_configure_field; + break; + } + } + else + { + #if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + printf("ERROR: CONFIG: illegal configure value %s.\n", + expanded_value->get_data(expanded_value->get_data_length())); + #endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: CONFIG: illegal configure value %s.\n"), + expanded_value->get_data(expanded_value->get_data_length()))); + status = eap_status_illegal_configure_field; + break; + } + } + } // for() + + if (status == eap_status_ok + && expanded_value_when_true == true) + { + #if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + printf("CONFIG: expanded configuration value [%s] => [%s].\n", + value, + expanded_value); + #endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("CONFIG: expanded configuration value [%s] => [%s].\n"), + original_value->get_data(original_value->get_data_length()), + expanded_value->get_data(expanded_value->get_data_length()))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_file_config_c::read_hex_byte( + u8_t * cursor, + const u8_t * const end, + u8_t * const hex_byte) +{ + u8_t * start = cursor; + bool stop = false; + + while(stop == false && cursor < end) + { + switch(*cursor) + { + case static_cast(','): + case static_cast(' '): + case static_cast('\t'): + stop = true; + break; + default: + ++cursor; + break; + } + + } + + if (cursor <= end) + { + u32_t target_length = sizeof(*hex_byte); + + eap_status_e status = m_am_tools->convert_hex_ascii_to_bytes( + start, + cursor-start, + hex_byte, + &target_length); + if (status != eap_status_ok) + { + return 0; + } + + return ++cursor; + } + + return 0; +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_file_config_c::read_u32_t( + u8_t * cursor, + const u8_t * const end, + u32_t * const integer) +{ + u8_t * start = cursor; + bool stop = false; + + while(stop == false && cursor < end) + { + switch(*cursor) + { + case static_cast(','): + case static_cast(' '): + case static_cast('\t'): + stop = true; + break; + default: + ++cursor; + break; + } + + } + + if (cursor <= end) + { + eap_variable_data_c buffer(m_am_tools); + if (buffer.get_is_valid() == false) + { + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + eap_status_e status = buffer.add_data(start, cursor-start); + if (status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, status); + return 0; + } + + status = m_am_tools->number_string_to_u32( + buffer.get_data(buffer.get_data_length()), + buffer.get_data_length(), + integer); + if (status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, status); + return 0; + } + + return ++cursor; + } + + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + return 0; +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::convert_value( + eap_core_map_c * const config_map, + const eap_variable_data_c * const value_buffer, + const eap_configure_type_e type, + eap_variable_data_c * const value_data) +{ + eap_status_e status = eap_status_process_general_error; + + eap_variable_data_c expanded_value_buffer(m_am_tools); + if (expanded_value_buffer.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = expanded_value_buffer.set_buffer_length(MAX_LINE_LENGTH); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + expanded_value_buffer.set_data_length(MAX_LINE_LENGTH); + + status = expand_environment_variables( + config_map, + value_buffer, + &expanded_value_buffer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (type == eap_configure_type_u32_t) + { + u32_t uint_value = 0UL; + + status = m_am_tools->number_string_to_u32( + expanded_value_buffer.get_data(expanded_value_buffer.get_data_length()), + expanded_value_buffer.get_data_length(), + &uint_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = value_data->set_copy_of_buffer( + &uint_value, + sizeof(uint_value)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (type == eap_configure_type_boolean) + { + u32_t uint_value = static_cast(~0); + + if (!m_am_tools->memcmp( + expanded_value_buffer.get_data(expanded_value_buffer.get_data_length()), + EAP_FILECONFIG_TRUE, + expanded_value_buffer.get_data_length())) + { + // OK, true + uint_value = 1u; + } + else if (!m_am_tools->memcmp( + expanded_value_buffer.get_data(expanded_value_buffer.get_data_length()), + EAP_FILECONFIG_FALSE, + expanded_value_buffer.get_data_length())) + { + // OK, false + uint_value = 0u; + } + else + { +#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + printf("ERROR: CONFIG: illegal boolean value %s\n", + expanded_value_buffer.get_data(expanded_value_buffer.get_data_length())); +#endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: CONFIG: illegal boolean value %s\n"), + expanded_value_buffer.get_data(expanded_value_buffer.get_data_length()))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + + status = value_data->set_copy_of_buffer( + &uint_value, + sizeof(uint_value)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (type == eap_configure_type_string) + { + status = value_data->set_copy_of_buffer( + &expanded_value_buffer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (type == eap_configure_type_hex_data) + { + status = remove_spaces(&expanded_value_buffer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * cursor = expanded_value_buffer.get_data(expanded_value_buffer.get_data_length()); + const u8_t * const cursor_end = cursor + expanded_value_buffer.get_data_length(); + + while(cursor < cursor_end) + { + u8_t hex_byte = 0; + cursor = read_hex_byte( + cursor, + cursor_end, + &hex_byte); + if (cursor == 0) + { + break; + } + + status = value_data->add_data(&hex_byte, sizeof(hex_byte)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (type == eap_configure_type_u32array) + { + status = remove_spaces(&expanded_value_buffer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * cursor = expanded_value_buffer.get_data(expanded_value_buffer.get_data_length()); + const u8_t * const cursor_end = cursor + expanded_value_buffer.get_data_length(); + + while(cursor < cursor_end) + { + u32_t integer = 0; + cursor = read_u32_t( + cursor, + cursor_end, + &integer); + if (cursor == 0) + { + break; + } + + status = value_data->add_data(&integer, sizeof(integer)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::store_configure( + abs_eap_am_file_input_c * const file, + const eap_variable_data_c * const line, + eap_core_map_c * const config_map) +{ + eap_status_e status = eap_status_process_general_error; + + eap_variable_data_c name_buffer(m_am_tools); + if (name_buffer.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c value_buffer(m_am_tools); + if (value_buffer.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c value_data(m_am_tools); + if (value_data.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + status = name_buffer.set_buffer_length(MAX_LINE_LENGTH); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + name_buffer.set_data_length(0ul); + + status = value_buffer.set_buffer_length(MAX_LINE_LENGTH); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + value_buffer.set_data_length(0ul); + + eap_configure_type_e type = eap_configure_type_none; + + if (line->compare( + EAP_FILECONFIG_SECTION_END, + EAP_FILECONFIG_SECTION_END_LENGTH) == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CONFIG: section ends.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_section_ends); + } + + status = cnf_get_string( + line, + &name_buffer, + &value_buffer, + &type); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (name_buffer.compare_length( + EAP_FILECONFIG_SECTION, + EAP_FILECONFIG_SECTION_LENGTH, + EAP_FILECONFIG_SECTION_LENGTH) == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CONFIG: section %s.\n"), + name_buffer.get_data(name_buffer.get_data_length()))); + + status = name_buffer.set_start_offset(EAP_FILECONFIG_SECTION_LENGTH); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_core_map_c * const section_map + = new eap_core_map_c< + eap_config_value_c, + abs_eap_core_map_c, + eap_variable_data_c>(m_am_tools, this); + + eap_automatic_variable_c > + automatic_section_map(m_am_tools, section_map); + + if (section_map == 0 + || section_map->get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = read_section(file, section_map); + if (status == eap_status_section_ends) + { + // Add subsection. + eap_config_value_c * config = new eap_config_value_c(m_am_tools); + + eap_automatic_variable_c + automatic_config(m_am_tools, config); + + if (config == 0 + || config->get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + config->set_type(eap_configure_type_subsection); + + config->set_subsection(section_map); + automatic_section_map.do_not_free_variable(); + + status = convert_value( + &m_config_map, // Note here we use the global name space. + &value_buffer, + type, + &value_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // selector of the section is :. + // section:example=string:match => example:match + status = name_buffer.add_data( + EAP_FILECONFIG_SECTION_SEPARATOR, + EAP_FILECONFIG_SECTION_SEPARATOR_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = name_buffer.add_data(&value_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = name_buffer.add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_variable_data_c selector(m_am_tools); + if (selector.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = selector.set_copy_of_buffer( + name_buffer.get_data(), + name_buffer.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = config_map->add_handler(&selector, config); + if (status == eap_status_ok) + { + automatic_config.do_not_free_variable(); + } + else if (status == eap_status_handler_exists_error) + { + // This is dublicate subsection. + // We will skip this. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: CONFIG: section %s is already defined.\n"), + name_buffer.get_data(name_buffer.get_data_length()))); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CONFIG: subsection name"), + name_buffer.get_data(), + name_buffer.get_data_length())); + + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_CONFIGURE_DATA, + (EAPL("CONFIG: check subsection %s.\n"), + name_buffer.get_data(name_buffer.get_data_length()))); + + eap_configuration_field_template_c * const tmp_name + = new eap_configuration_field_template_c; + + eap_automatic_variable_c > + automatic_tmp_name(m_am_tools, tmp_name); + + if (tmp_name == 0 + || tmp_name->get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tmp_name->set_fields( + m_am_tools, + name_buffer.get_data(name_buffer.get_data_length()), + type, + false); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c check(m_am_tools); + if (check.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = read_configure( + config_map, + tmp_name->get_field(), + &check, + &type, + true); + if (status == eap_status_ok) + { + status = name_buffer.add_end_null(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + // This subsection is already defined. +#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + printf("WARNING: CONFIG: subsection %s is already defined.\n", + name_buffer.get_data(name_buffer.get_data_length())); +#endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: CONFIG: subsection %s is already defined.\n"), + name_buffer.get_data(name_buffer.get_data_length()))); + + // We will skip the dublicate section. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + //------------------------------------------------------------------------------- + + eap_config_value_c * config = new eap_config_value_c(m_am_tools); + + eap_automatic_variable_c + automatic_config(m_am_tools, config); + + if (config == 0 + || config->get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + config->set_type(type); + + status = convert_value( + &m_config_map, // Note here we use the global name space. + &value_buffer, + type, + &value_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = config->get_data()->set_copy_of_buffer( + &value_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c selector(m_am_tools); + if (selector.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = selector.set_copy_of_buffer( + tmp_name->get_field()->get_field(), + tmp_name->get_field()->get_field_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = config_map->add_handler(&selector, config); + if (status == eap_status_ok) + { + automatic_config.do_not_free_variable(); + } + else //if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CONFIG: option added"), + tmp_name->get_field()->get_field(), + tmp_name->get_field()->get_field_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CONFIG: data"), + config->get_data()->get_data(), + config->get_data()->get_data_length())); + + //----------------------------------------------------------------------------- + + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------- + +eap_status_e eap_file_config_c::find_rvalue( + const eap_variable_data_c * const config_param, + bool * const read_env_value, + eap_variable_data_c * const param_name, + eap_variable_data_c * const param_value + ) +{ + const u8_t * rvalue = 0; + const u8_t *env_value = 0; + + if (config_param == 0 + || read_env_value == 0 + || param_name == 0 + || param_value == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u8_t * const param = config_param->get_data(config_param->get_data_length()); + if (param == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u8_t * const param_end + = config_param->get_data(config_param->get_data_length()) + + config_param->get_data_length(); + if (param_end == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + for (rvalue = param; *rvalue; rvalue++) + { + if (*rvalue == '=') + { + break; + } + } + + if (*rvalue == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Check are there defined environment variable to override the file configuration. + { + // backup spaces. + const u8_t *tmp_param_end = rvalue; + + for (tmp_param_end-- + ; m_am_tools->isspace(*tmp_param_end) + || *tmp_param_end == '\r' + || *tmp_param_end == '\n' + || *tmp_param_end == '=' + ; tmp_param_end--) + { + /* empty */ + } + + tmp_param_end++; + u32_t length = tmp_param_end - param; + + + eap_status_e status = param_name->add_data(param, length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = param_name->add_end_null(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c env_value_buffer(m_am_tools); + if (env_value_buffer.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e env_status = m_am_tools->getenv( + param_name, + &env_value_buffer); + if (env_status == eap_status_ok) + { + env_value = env_value_buffer.get_data(env_value_buffer.get_data_length()); + } + else + { + env_value = 0; + } + + if (env_value != 0) + { + rvalue = env_value; + length = m_am_tools->strlen(reinterpret_cast(rvalue)); + *read_env_value = true; + } + else + { + rvalue = tmp_param_end; + + for (; *rvalue; rvalue++) + { + if (*rvalue == '=') + { + break; + } + } + + for (rvalue++; m_am_tools->isspace(*rvalue) || *rvalue == '\r' || *rvalue == '\n'; rvalue++){ + /* empty */ + } + + if (*rvalue == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + length = param_end - rvalue; + } + + // There is overriding environment variable. + status = param_value->set_copy_of_buffer(rvalue, length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = param_value->add_end_null(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::cnf_parse_value( + const eap_variable_data_c * const found_type_value, + const eap_variable_data_c * const found_type_name, + eap_configure_type_e * const parsed_type, + eap_variable_data_c * const parsed_type_value, + const bool is_environment_variable) +{ + if (found_type_value == 0 + || found_type_name == 0 + || parsed_type == 0 + || parsed_type_value == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + *parsed_type = eap_configure_type_none; + + u32_t ind; + for (ind = 0u; ind < sizeof(eap_configure_type_id)/sizeof(eap_configure_type_id[0]); ind++) + { + if (!m_am_tools->memcmp( + eap_configure_type_id[ind].id, + found_type_value->get_data(found_type_value->get_data_length()), + eap_configure_type_id[ind].id_length)) + { + *parsed_type = eap_configure_type_id[ind].type; + break; + } + } + + u32_t value_length = found_type_value->get_data_length(); + + eap_variable_data_c tmp_buffer(m_am_tools); + if (tmp_buffer.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = tmp_buffer.set_buffer_length(MAX_LINE_LENGTH); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + tmp_buffer.set_data_length(MAX_LINE_LENGTH); + + u8_t * const tmp_value_buffer = tmp_buffer.get_buffer(MAX_LINE_LENGTH); + if (tmp_value_buffer == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + const u8_t * used_type_value = found_type_value->get_data(found_type_value->get_data_length()); + if (used_type_value == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (*parsed_type == eap_configure_type_none) + { + // No type defined. + if (is_environment_variable == true) + { + // Environment variable without type is handled as a string type. + *parsed_type = eap_configure_type_string; + ind = *parsed_type; + m_am_tools->memmove( + tmp_value_buffer, + eap_configure_type_id[ind].id, + eap_configure_type_id[ind].id_length); + m_am_tools->memmove( + tmp_value_buffer+eap_configure_type_id[ind].id_length, + found_type_value->get_data(found_type_value->get_data_length()), + value_length); + value_length = eap_configure_type_id[ind].id_length+value_length; + tmp_value_buffer[value_length] = 0; + used_type_value = tmp_value_buffer; + } + else + { + #if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + printf("ERROR: CONFIG: no subsection type: %s=%s\n", + found_type_name->get_data(found_type_name->get_data_length()), + found_type_value->get_data(found_type_value->get_data_length())); + #endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: CONFIG: no subsection type: %s=%s\n"), + found_type_name->get_data(found_type_name->get_data_length()), + found_type_value->get_data(found_type_value->get_data_length()))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + + const u8_t * value_end = used_type_value+value_length; + + // Remove separator and spaces. + for (value_end-- + ; used_type_value < value_end + && (m_am_tools->isspace(*value_end) + || *value_end == '=' + || *value_end == '\r' + || *value_end == '\n') + ; value_end--) + { + /* empty */ + --value_length; + } + ++value_end; + + const u32_t tmp_length = value_end - used_type_value; + + u32_t len = tmp_length - eap_configure_type_id[ind].id_length; + + status = parsed_type_value->add_data( + used_type_value+eap_configure_type_id[ind].id_length, + len); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = parsed_type_value->add_end_null(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (is_environment_variable == true) + { + #if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + printf("CONFIG: %s=%s%s; from environment variable\n", + found_type_name->get_data(found_type_name->get_data_length()), + eap_configure_type_id[ind].id, + parsed_type_value->get_data(parsed_type_value->get_data_length())); + #endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("CONFIG: %s=%s%s; from environment variable\n"), + found_type_name->get_data(found_type_name->get_data_length()), + eap_configure_type_id[ind].id, + parsed_type_value->get_data(parsed_type_value->get_data_length()))); + } + else + { + #if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + printf("CONFIG: %s=%s%s\n", + found_type_name->get_data(found_type_name->get_data_length()), + eap_configure_type_id[ind].id, + parsed_type_value->get_data(parsed_type_value->get_data_length())); + #endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("CONFIG: %s=%s%s\n"), + found_type_name->get_data(found_type_name->get_data_length()), + eap_configure_type_id[ind].id, + parsed_type_value->get_data(parsed_type_value->get_data_length()))); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::cnf_get_string( + const eap_variable_data_c * const param, + eap_variable_data_c * const param_name, + eap_variable_data_c * const param_value, + eap_configure_type_e * const type) +{ + if (param == 0 + || param_name == 0 + || param_value == 0 + || type == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + bool env_value = false; + + *type = eap_configure_type_none; + + // Returned value could be pointer to environment value. + // Do not modify returned value. + eap_status_e status = find_rvalue( + param, + &env_value, + param_name, + param_value + ); + + if (status != eap_status_ok) + { + #if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + printf("ERROR: CONFIG: illegal subsection: %s\n", + param->get_data(param->get_data_length())); + #endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS) + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: CONFIG: illegal subsection: %s\n"), + param->get_data(param->get_data_length()))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + + eap_variable_data_c parsed_value(m_am_tools); + if (parsed_value.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = cnf_parse_value( + param_value, + param_name, + type, + &parsed_value, + env_value); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = param_value->set_copy_of_buffer(&parsed_value); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = param_value->add_end_null(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::read_subsections( + abs_eap_am_file_input_c * const file, + eap_core_map_c * const config_map) +{ + eap_variable_data_c line(m_am_tools); + if (line.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_status_ok; + + // This sets the pre-allocated buffer. + status = line.set_buffer_length(MAX_LINE_LENGTH); + + for (;status == eap_status_ok;) + { + status = get_subsect(file, &line); + if (status == eap_status_end_of_file) + { + // End of file reached. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_configure(file, &line, config_map); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::read_section( + abs_eap_am_file_input_c * const file, + eap_core_map_c * const config_map) +{ + eap_variable_data_c line(m_am_tools); + if (line.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_status_ok; + + // This sets the pre-allocated buffer. + status = line.set_buffer_length(MAX_LINE_LENGTH); + + while (status == eap_status_ok) + { + status = get_subsect(file, &line); + if (status == eap_status_end_of_file) + { + // End of file reached. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (line.compare( + EAP_FILECONFIG_SECTION_START, + EAP_FILECONFIG_SECTION_START_LENGTH) == 0) + { + // Starts new section block. + status = read_subsections( + file, + config_map); + + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: CONFIG: section start '{' is missing.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::remove_spaces(eap_variable_data_c * const buffer) +{ + eap_variable_data_c tmp(m_am_tools); + if (tmp.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status(eap_status_ok); + + for (u32_t ind = 0ul; ind < buffer->get_data_length(); ind++) + { + u8_t * const character = buffer->get_data_offset(ind, sizeof(u8_t)); + if (character == 0) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_am_tools->isspace(*character) == false) + { + status = tmp.add_data(character, sizeof(*character)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } // for() + + status = buffer->set_copy_of_buffer(&tmp); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::remove_leading_spaces( + eap_variable_data_c * const line) +{ + if (line->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + u8_t * const begin = line->get_data(line->get_data_length()); + if(begin == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + for (u32_t ind = 0; ind < line->get_data_length(); ind++) + { + if (begin[ind] != ' ' + && begin[ind] != '\t') + { + eap_status_e status = line->set_start_offset(ind); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::file_read_line( + abs_eap_am_file_input_c * const file, + eap_variable_data_c * const line) +{ + eap_status_e status(eap_status_ok); + bool line_continues(true); + + eap_variable_data_c tmp_line(m_am_tools); + if (tmp_line.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + const u32_t TMP_LINE_BUFFER_INITIAL_LENGTH = 256ul; + + status = tmp_line.set_buffer_length(TMP_LINE_BUFFER_INITIAL_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // This is small optimization that does not free the old buffer. + status = line->reset_start_offset_and_data_length(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + do + { + status = tmp_line.reset_start_offset_and_data_length(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = file->file_read_line(&tmp_line); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_CONFIGURE_DATA, + (EAPL("Configure line"), + tmp_line.get_data(), + tmp_line.get_data_length())); + + status = remove_leading_spaces(&tmp_line); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_CONFIGURE_DATA, + (EAPL("No spaces line"), + tmp_line.get_data(), + tmp_line.get_data_length())); + + if (tmp_line.get_data_length() > 0ul) + { + u8_t * last_char = tmp_line.get_buffer_offset( + tmp_line.get_data_length() - 1ul, + sizeof(u8_t)); + + if (last_char != 0 + && *last_char == '\\') + { + // If the last character in the line is '\' then the line continues to the next line. + tmp_line.set_data_length(tmp_line.get_data_length() - 1ul); + } + else + { + line_continues = false; + } + } + else + { + line_continues = false; + } + + status = line->add_data(&tmp_line); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } while(line_continues == true); + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_CONFIGURE_DATA, + (EAPL("Configure line"), + tmp_line.get_data(), + tmp_line.get_data_length())); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::get_subsect( + abs_eap_am_file_input_c * const file, + eap_variable_data_c * const line) +{ + if( file == 0 + || line == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_ok); + + for(;status == eap_status_ok;) + { + status = file_read_line(file, line); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_CONFIGURE_DATA, + (EAPL("Configure line"), + line->get_data(line->get_data_length()), + line->get_data_length())); + + // error or end of file + if(status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = remove_leading_spaces(line); + if(status != eap_status_ok) + { + // Skip this error. + status = eap_status_ok; + continue; + } + + // too short line, ignore + if(line->get_data_length() < 1ul) + { + continue; + } + + u8_t * const result = line->get_data(line->get_data_length()); + if(result == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // ignore the lines starting with newline, space, tab or '#' + if ((*result == '\r') + || (*result == '\n') + || (*result == ' ') + || (*result == '\t') + || (*result == '#')) + { + continue; + } + else + { + // OK we get a line. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::read_configure( + eap_core_map_c * const config_map, + const eap_configuration_field_c * const field, + eap_variable_data_c* const data, + eap_configure_type_e * const configuration_data_type, + const bool existence_test) +{ + eap_status_e status = eap_status_process_general_error; + + eap_variable_data_c selector(m_am_tools); + if (selector.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = selector.set_buffer( + field->get_field(), + field->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_config_value_c *config = config_map->get_handler(&selector); + + if (config != 0) + { + status = data->set_copy_of_buffer(config->get_data()); + + if (status == eap_status_ok) + { + *configuration_data_type = config->get_type(); + } + else + { + *configuration_data_type = eap_configure_type_none; + } + } + else + { + if (existence_test == false) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: CONFIG: unknown option"), + field->get_field(), + field->get_field_length())); + } + status = eap_status_illegal_configure_field; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; // Here EAP_STATUS_RETURN() macro is too noisy. +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c* const data, + eap_core_map_c * const config_map, + const bool check_subsection_when_true) +{ + eap_status_e status = eap_status_process_general_error; + + eap_variable_data_c selector(m_am_tools); + if (selector.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (check_subsection_when_true == true + && field->get_subsection() != 0) + { + status = selector.set_buffer( + field->get_subsection()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CONFIG: finds subsection name"), + field->get_subsection()->get_data(), + field->get_subsection()->get_data_length())); + + eap_config_value_c *config = config_map->get_handler(&selector); + + if (config != 0) + { + if (check_subsection_when_true == true + && config->get_type() == eap_configure_type_subsection) + { + if (config->get_subsection() != 0) + { + status = read_configure( + field, + data, + config->get_subsection(), + false); + if (status == eap_status_ok) + { + // OK, section configuration found. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: CONFIG: subsection not found"), + field->get_field(), + field->get_field_length())); + } + } + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: CONFIG: subsection not found"), + field->get_field(), + field->get_field_length())); + } + } + + + + { + status = selector.set_buffer( + field->get_field(), + field->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_config_value_c *config = config_map->get_handler(&selector); + + if (config != 0) + { + if (field->get_type() != config->get_type()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: CONFIG: option type failed: required %d != actual %d\n"), + field->get_type(), + config->get_type())); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: CONFIG: rear option type failed: %s\n"), + field->get_field())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_type); + } + + status = data->set_copy_of_buffer(config->get_data()); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CONFIG: value read from eap_file_config_c: %s\n"), + field->get_field())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("value"), + data->get_data(), + data->get_data_length())); + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: CONFIG: option not found"), + field->get_field(), + field->get_field_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_file_config_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c* const data) +{ + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_file_config_c::read_configure()"), + field->get_field(), + field->get_field_length())); + + eap_status_e status = read_configure( + field, + data, + &m_config_map, + true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------- diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/eap_timer_queue.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/eap_timer_queue.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1721 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 15 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_timer_queue.h" + +//-------------------------------------------------- + +#if defined(USE_EAP_TIMER_QUEUE_TRACE) + #define EAP_TRACE_TIMER EAP_TRACE_DEBUG +#else + #define EAP_TRACE_TIMER(object, flags, parameters) +#endif //#if defined(USE_EAP_TIMER_QUEUE_TRACE) + +//-------------------------------------------------- + +// +eap_timer_queue_event_c::~eap_timer_queue_event_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_initializer->timer_delete_data(m_id, m_data); + m_initializer = 0; + m_id = 0; + m_data = 0; + m_hash = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +eap_timer_queue_event_c::eap_timer_queue_event_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) + : m_am_tools(tools) + , m_initializer(initializer) + , m_id(id) + , m_data(data) + , m_time_ms(p_time_ms) + , m_original_time_ms(p_time_ms) + , m_prev(0) + , m_next(0) + , m_hash(0) + , m_prev_same_time(0) + , m_next_same_time(0) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +u32_t eap_timer_queue_event_c::get_time() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_time_ms; +} + +//-------------------------------------------------- + +// +u32_t eap_timer_queue_event_c::get_original_time() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_original_time_ms; +} + +//-------------------------------------------------- + +// +eap_timer_queue_event_c *eap_timer_queue_event_c::get_prev() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_prev; +} + +//-------------------------------------------------- + +// +eap_timer_queue_event_c *eap_timer_queue_event_c::get_next() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_next; +} + +//-------------------------------------------------- + +// +eap_timer_queue_event_c *eap_timer_queue_event_c::get_prev_same_time() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_prev_same_time; +} + +//-------------------------------------------------- + +// +eap_timer_queue_event_c *eap_timer_queue_event_c::get_next_same_time() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_next_same_time; +} + +//-------------------------------------------------- + +// +eap_timer_queue_hash_c * eap_timer_queue_event_c::get_hash() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_hash; +} + +//-------------------------------------------------- + +// +u32_t eap_timer_queue_event_c::pulse_time(const u32_t resolution) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (m_time_ms >= resolution) + { + m_time_ms -= resolution; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0u; + } + else + { + u32_t remainder = resolution - m_time_ms; + m_time_ms = 0u; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return remainder; + } +} + +//-------------------------------------------------- + +// +void eap_timer_queue_event_c::decrease_time_left(const u32_t decrease_time) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_time_ms > decrease_time) + { + m_time_ms -= decrease_time; + } + else + { + m_time_ms = 0u; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +void eap_timer_queue_event_c::increase_time_left(const u32_t increase_time) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_time_ms += increase_time; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +void eap_timer_queue_event_c::set_prev(eap_timer_queue_event_c * const prev) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_prev = prev; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +void eap_timer_queue_event_c::set_next(eap_timer_queue_event_c * const next) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_next = next; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +void eap_timer_queue_event_c::set_prev_same_time(eap_timer_queue_event_c * const prev_same_time) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_prev_same_time = prev_same_time; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +void eap_timer_queue_event_c::set_next_same_time(eap_timer_queue_event_c * const next_same_time) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_next_same_time = next_same_time; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +void eap_timer_queue_event_c::set_hash(eap_timer_queue_hash_c * const hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_hash = hash; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +abs_eap_base_timer_c * eap_timer_queue_event_c::get_initializer() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_initializer; +} + +//-------------------------------------------------- + +// +u32_t eap_timer_queue_event_c::get_id() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_id; +} + +//-------------------------------------------------- + +// +void * eap_timer_queue_event_c::get_data() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_data; +} + +//-------------------------------------------------- + +// +u32_t eap_timer_queue_event_c::get_time_ms() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_time_ms; +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +// +eap_timer_queue_hash_c::~eap_timer_queue_hash_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_atom = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + + //-------------------------------------------------- + +// +eap_timer_queue_hash_c::eap_timer_queue_hash_c( + abs_eap_am_tools_c * const tools, + eap_timer_queue_event_c * const atom, + const u32_t index) + : m_am_tools(tools) + , m_index(index) + , m_atom(atom) + , m_prev(0) + , m_next(0) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +eap_timer_queue_hash_c *eap_timer_queue_hash_c::get_next() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_next; +} + +//-------------------------------------------------- + +// +eap_timer_queue_hash_c *eap_timer_queue_hash_c::get_prev() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_prev; +} + +//-------------------------------------------------- + +// +u32_t eap_timer_queue_hash_c::get_index() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_index; +} + +//-------------------------------------------------- + +// +void eap_timer_queue_hash_c::set_next(eap_timer_queue_hash_c * const next) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_next = next; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +void eap_timer_queue_hash_c::set_prev(eap_timer_queue_hash_c * const prev) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_prev = prev; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +eap_timer_queue_event_c * eap_timer_queue_hash_c::get_atom() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_atom; +} + +//-------------------------------------------------- + +i32_t eap_timer_queue_hash_c::compare( + const abs_eap_base_timer_c * const a_initializer, + const u32_t a_id, + const abs_eap_base_timer_c * const b_initializer, + const u32_t b_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (a_id < b_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return -1; + } + else if (a_id > b_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 1; + } + else if (a_initializer < b_initializer) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return -1; + } + else if (a_initializer > b_initializer) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 1; + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +eap_timer_queue_c::~eap_timer_queue_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + deactivate_timer_queue(); + + // cancel_all_timers() must be called before destructor. + EAP_ASSERT_TOOLS(m_am_tools, m_timer_queue == 0); + EAP_ASSERT_TOOLS(m_am_tools, m_new_event_begin == 0); + EAP_ASSERT_TOOLS(m_am_tools, m_new_event_end == 0); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +eap_timer_queue_c::eap_timer_queue_c( + abs_eap_am_tools_c * const tools, + const u32_t timer_resolution_ms) + : m_am_tools(tools) + , m_timer_queue(0) + , m_new_event_begin(0) + , m_new_event_end(0) + , m_timer_resolution_ms(timer_resolution_ms) + , m_is_active(false) + , m_is_valid(false) + , m_use_eap_millisecond_timer(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + for(u32_t ind = 0; ind < EAP_TIMER_QUEUE_HASH_SIZE; ind++) + { + m_map[ind] = 0; + } + + m_is_active = true; + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +bool eap_timer_queue_c::get_use_eap_milli_second_timer() +{ + return m_use_eap_millisecond_timer; +} + +//-------------------------------------------------- + +void eap_timer_queue_c::set_use_eap_milli_second_timer(const bool use_eap_millisecond_timer) +{ + m_use_eap_millisecond_timer = use_eap_millisecond_timer; +} + +//-------------------------------------------------- + +u32_t eap_timer_queue_c::get_timer_resolution_ms() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_timer_resolution_ms; +} + +//-------------------------------------------------- + +void eap_timer_queue_c::set_timer_resolution_ms(const u32_t timer_resolution_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_timer_resolution_ms = timer_resolution_ms; +} + +//-------------------------------------------------- + +void eap_timer_queue_c::deactivate_timer_queue() +{ + m_is_active = false; +} + +//-------------------------------------------------- + +// This is used in Symbian AM. +eap_status_e eap_timer_queue_c::re_activate_timer_queue() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_active = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +void eap_timer_queue_c::trace_timer_event( + const eap_const_string prefix, + const eap_timer_queue_event_c * const event) +{ + + EAP_UNREFERENCED_PARAMETER(prefix); + EAP_UNREFERENCED_PARAMETER(event); + +#if defined(USE_EAP_TIMER_QUEUE_TRACE) +#if !defined(NO_EAP_TIMER_QUEUE) + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("TIMER: queue: %s, %s[0x%08x], original time %8d, ") + EAPL("time left %8d, initializer 0x%08x, ") + EAPL("id 0x%02x, data 0x%08x, prev 0x%08x, ") + EAPL("next 0x%08x, prev same time 0x%08x, next same time 0x%08x\n"), + prefix, + ((event == m_timer_queue || event->get_time() != 0) ? "-> ": " "), + event, + event->get_original_time(), + event->get_time(), + event->get_initializer(), + event->get_id(), + event->get_data(), + event->get_prev(), + event->get_next(), + event->get_prev_same_time(), + event->get_next_same_time())); + +#endif //#if !defined(NO_EAP_TIMER_QUEUE) +#endif //#if defined(USE_EAP_TIMER_QUEUE_TRACE) +} + +//-------------------------------------------------- + +void eap_timer_queue_c::trace_timer() +{ +#if defined(USE_EAP_TIMER_QUEUE_TRACE) +#if !defined(NO_EAP_TIMER_QUEUE) + + if ( ! (m_am_tools->get_trace_mask() & (TRACE_FLAGS_TIMER_QUEUE))) + { + return; + } + + eap_timer_queue_event_c *cursor = m_timer_queue; + eap_timer_queue_event_c *prev = 0; + EAP_UNREFERENCED_PARAMETER(prev); + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("-------------------------------------------------------------------------\n"))); + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("TIMER: current timer queue:\n"))); + + if (cursor == 0 + && m_new_event_begin == 0) + { + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("TIMER: queue: is empty\n"))); + } + + + { + eap_timer_queue_event_c *pending = m_new_event_begin; + + while(pending != 0) + { + trace_timer_event("new", pending); + + pending = pending->get_next(); + } + } + + + while(cursor != 0) + { + EAP_ASSERT(prev == cursor->get_prev()); + + { + eap_timer_queue_event_c *vertical = cursor; + + while(vertical != 0) + { + trace_timer_event("old", vertical); + + vertical = vertical->get_next_same_time(); + } + } + + prev = cursor; + cursor = cursor->get_next(); + + EAP_ASSERT(prev->get_next() == cursor); + } + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("-------------------------------------------------------------------------\n"))); + +#endif //#if !defined(NO_EAP_TIMER_QUEUE) +#endif //#if defined(USE_EAP_TIMER_QUEUE_TRACE) +} + +//-------------------------------------------------- + +u32_t eap_timer_queue_c::pulse_timer( + const u32_t elapsed_time_in_ms, + const bool can_call_timer_expired_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + u32_t next_sleep_time = get_timer_resolution_ms(); + +#if !defined(NO_EAP_TIMER_QUEUE) + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: pulse_timer(%u), can_call_timer_expired_when_true %d\n"), + elapsed_time_in_ms, + can_call_timer_expired_when_true)); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + trace_timer(); + + if (m_timer_queue != 0) + { + u32_t remainder_time = m_timer_queue->pulse_time(elapsed_time_in_ms); + + if (can_call_timer_expired_when_true == true) + { + while (m_timer_queue != 0 + && m_timer_queue->get_time() == 0) + { + eap_timer_queue_event_c *current = m_timer_queue; + + EAP_ASSERT(m_timer_queue->get_prev() == 0); + EAP_ASSERT(current->get_time() == 0); + + if (current->get_next_same_time() != 0) + { + eap_timer_queue_event_c *next = current->get_next_same_time(); + + EAP_ASSERT(next->get_prev() == 0 && next->get_next() == 0); + + next->set_prev_same_time(0); + next->set_next(m_timer_queue->get_next()); + + if (m_timer_queue->get_next() != 0) + { + m_timer_queue->get_next()->set_prev(next); + } + + m_timer_queue = next; + } + else + { + m_timer_queue = m_timer_queue->get_next(); + if (m_timer_queue != 0) + { + m_timer_queue->set_prev(0); + } + } + + if (current != 0) + { + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: timer_expired(): [0x%08x]->initializer(0x%08x)->timer_expired(") + EAPL("id 0x%02x, data 0x%08x, original time %8d)\n"), + current, + current->get_initializer(), + current->get_id(), + current->get_data(), + current->get_original_time())); + + remove_hash_of_timer_event(current); + + current->set_prev_same_time(0); + current->set_next_same_time(0); + current->set_prev(0); + current->set_next(0); + + current->get_initializer()->timer_expired( + current->get_id(), + current->get_data()); + + delete current; + } + + if (remainder_time != 0u + && m_timer_queue != 0) + { + remainder_time = m_timer_queue->pulse_time(remainder_time); + } + } // while(m_timer_queue != 0 + // && m_timer_queue->get_time() == 0) + } // if (can_call_timer_expired_when_true == true) + } + + + if (m_use_eap_millisecond_timer == true) + { + // New timer events are added here because the current + // pulse might be very long, and the long pulse will + // cause the new event expire immediately. + // By using this function the shortest timer events in the + // timer queue are handled and after that the new timer events + // are added to timer queue. + eap_status_e status = add_pending_timer(); + if (status != eap_status_ok) + { + next_sleep_time = get_timer_resolution_ms(); + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("ERROR: TIMER: add_pending_timer() status=%d, next_sleep_time=%d\n"), + status, + next_sleep_time)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return next_sleep_time; + } + } + + + if (m_timer_queue != 0) + { + next_sleep_time = m_timer_queue->get_time(); + } + else + { + if (m_use_eap_millisecond_timer == true) + { + next_sleep_time = EAP_TIMER_QUEUE_LONG_SLEEP_TIME; + } + } + + trace_timer(); + + if (m_use_eap_millisecond_timer == false) + { + next_sleep_time = get_timer_resolution_ms(); + } + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: next_sleep_time=%d\n"), + next_sleep_time)); + +#endif //#if !defined(NO_EAP_TIMER_QUEUE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return next_sleep_time; +} + + +//-------------------------------------------------- + +bool eap_timer_queue_c::get_timer_queue_is_empty() +{ + +#if !defined(NO_EAP_TIMER_QUEUE) + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: get_timer_queue_is_empty(): m_timer_queue=0x%08x, m_new_event_begin=0x%08x\n"), + m_timer_queue, + m_new_event_begin)); + + return (m_timer_queue == 0 && m_new_event_begin == 0); + +#else + + return true; + +#endif //#if !defined(NO_EAP_TIMER_QUEUE) + +} + +//-------------------------------------------------- + +#if !defined(NO_EAP_TIMER_QUEUE) + +eap_status_e eap_timer_queue_c::add_hash_of_timer_event( + eap_timer_queue_event_c * const event, + const abs_eap_base_timer_c * const initializer, + const u32_t id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const u32_t index = hash(EAP_TIMER_QUEUE_HASH_SIZE, initializer, id); + + if (index >= EAP_TIMER_QUEUE_HASH_SIZE) + { + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TIMER HASH: add_handler(): initializer 0x%08x, ") + EAPL("id 0x%02x, index %d >= EAP_TIMER_QUEUE_HASH_SIZE %d\n"), + initializer, + id, + index, + EAP_TIMER_QUEUE_HASH_SIZE)); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_hashed_index); + } + + eap_timer_queue_hash_c *hash = new eap_timer_queue_hash_c(m_am_tools, event, index); + + if (hash == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + event->set_hash(hash); + + eap_timer_queue_hash_c *cursor = m_map[index]; + eap_timer_queue_hash_c *last_cursor = 0; + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER HASH: add_handler(): initializer 0x%08x, id 0x%02x, index %d\n"), + initializer, + id, + index)); + + while (cursor != 0) + { + if (hash->compare(hash->get_atom()->get_initializer(), + hash->get_atom()->get_id(), + cursor->get_atom()->get_initializer(), + cursor->get_atom()->get_id()) == 0) + { + // match + break; + } + last_cursor = cursor; + cursor = cursor->get_next(); + } + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER HASH: add_hash_of_timer_event(): hash 0x%08x\n"), + hash)); + + EAP_ASSERT(hash->get_index() == index); + + if (last_cursor != 0) + { + if (last_cursor->get_next() != 0) + { + last_cursor->get_next()->set_prev(hash); + } + hash->set_next(last_cursor->get_next()); + last_cursor->set_next(hash); + hash->set_prev(last_cursor); + } + else + { + if (m_map[index] != 0) + { + m_map[index]->set_prev(hash); + } + hash->set_next(m_map[index]); + m_map[index] = hash; + hash->set_prev(0); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif //#if !defined(NO_EAP_TIMER_QUEUE) + +//-------------------------------------------------- + +#if !defined(NO_EAP_TIMER_QUEUE) + +eap_timer_queue_event_c * eap_timer_queue_c::get_hashed_timer_event( + const abs_eap_base_timer_c * const initializer, + const u32_t id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const u32_t index = hash(EAP_TIMER_QUEUE_HASH_SIZE, initializer, id); + + if (index >= EAP_TIMER_QUEUE_HASH_SIZE) + { + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TIMER HASH: get_handler(): initializer 0x%08x, ") + EAPL("id 0x%02x, index %d >= EAP_TIMER_QUEUE_HASH_SIZE %d\n"), + initializer, + id, + index, + EAP_TIMER_QUEUE_HASH_SIZE)); + return 0; + } + + eap_timer_queue_hash_c *cursor = m_map[index]; + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER HASH: get_handler(): initializer 0x%08x, id 0x%02x, index %d\n"), + initializer, + id, + index)); + + while (cursor != 0) + { + eap_timer_queue_event_c * const event = cursor->get_atom(); + + if (cursor->compare(initializer, + id, + event->get_initializer(), + event->get_id()) == 0) + { + // match + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER HASH: match: get_handler(): initializer 0x%08x, ") + EAPL("id 0x%02x, index %d, atom 0x%08x\n"), + initializer, + id, + index, + cursor->get_atom())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return cursor->get_atom(); + } + + cursor = cursor->get_next(); + } + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("WARNING: TIMER HASH: not found: get_handler(): ") + EAPL("initializer 0x%08x, id 0x%02x, index %d\n"), + initializer, + id, + index)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; +} + +#endif //#if !defined(NO_EAP_TIMER_QUEUE) + +//-------------------------------------------------- + +#if !defined(NO_EAP_TIMER_QUEUE) + +eap_status_e eap_timer_queue_c::remove_hash_of_timer_event( + eap_timer_queue_event_c * const event) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (event == 0 + || event->get_hash() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_timer_queue_hash_c *hash = event->get_hash(); + event->set_hash(0); + + if (hash->get_prev() != 0) + { + // Remove from middle. + EAP_ASSERT(m_map[hash->get_index()] != hash); + + if (hash->get_next() != 0) + { + hash->get_next()->set_prev(hash->get_prev()); + } + hash->get_prev()->set_next(hash->get_next()); + } + else + { + // Remove the first item. + EAP_ASSERT(m_map[hash->get_index()] == hash); + EAP_ASSERT(hash->get_prev() == 0); + + if (hash->get_next() != 0) + { + hash->get_next()->set_prev(hash->get_prev()); + } + m_map[hash->get_index()] = hash->get_next(); + EAP_ASSERT(m_map[hash->get_index()] == 0 + || m_map[hash->get_index()]->get_prev() == 0); + } + + delete hash; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif //#if !defined(NO_EAP_TIMER_QUEUE) + +//-------------------------------------------------- + +// +u32_t eap_timer_queue_c::hash( + const u32_t size, + const abs_eap_base_timer_c * const initializer, + const u32_t id) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + u32_t ihash = 0x55555555; + + ihash += static_cast(id); + ihash += reinterpret_cast(initializer); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return ihash % size; +} + +//-------------------------------------------------- + +void eap_timer_queue_c::add_end_of_vertical_list( + eap_timer_queue_event_c * const begin, + eap_timer_queue_event_c * const event) +{ + EAP_ASSERT(begin != 0 && event != 0); + + eap_timer_queue_event_c * previous = 0; + eap_timer_queue_event_c * current = begin; + + while (current != 0) + { + previous = current; + current = current->get_next_same_time(); + } + + // Add to the vertical list of previous time. + event->set_next_same_time(previous->get_next_same_time()); + if (previous->get_next_same_time() != 0) + { + previous->get_next_same_time()->set_prev_same_time(event); + } + previous->set_next_same_time(event); + event->set_prev_same_time(previous); +} + +//-------------------------------------------------- + +eap_status_e eap_timer_queue_c::add_timer( + eap_timer_queue_event_c *event) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#if !defined(NO_EAP_TIMER_QUEUE) + + eap_status_e status = add_hash_of_timer_event( + event, + event->get_initializer(), + event->get_id()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (m_timer_queue == 0) + { + m_timer_queue = event; + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: [0x%08x] add_timer(initializer 0x%08x, ") + EAPL("id 0x%02x, data 0x%08x, time %d)\n"), + m_timer_queue, + event->get_initializer(), + event->get_id(), + event->get_data(), + event->get_time_ms())); + } + else + { + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: [0x%08x]\n"), + event)); + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: initializer 0x%08x\n"), + event->get_initializer())); + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: id 0x%02x\n"), + event->get_id())); + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: data 0x%08x\n"), + event->get_data())); + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: time %d\n"), + event->get_time_ms())); + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: [0x%08x] add_timer(initializer 0x%08x, ") + EAPL("id 0x%02x, data 0x%08x, time %d)\n"), + event, + event->get_initializer(), + event->get_id(), + event->get_data(), + event->get_time_ms())); + + eap_timer_queue_event_c *current = m_timer_queue; + eap_timer_queue_event_c *prev = 0; + u32_t time_ms_sum = 0u; + u32_t tmp_time_ms = 0u; + + + while(current != 0) + { + tmp_time_ms = current->get_time(); + + time_ms_sum += tmp_time_ms; + + if (time_ms_sum >= event->get_time()) + { + // Time segment found. + // tmp_time_ms is decremented from time_ms_sum + // because of we need time sum before current. + // New event is added before current. + if (time_ms_sum > event->get_time()) + { + time_ms_sum -= tmp_time_ms; + } + else + { + // current points to the same time sum. + } + break; + } + + prev = current; + current = current->get_next(); + } // while(current != 0) + + + if (prev == 0 + && time_ms_sum == 0) + { + // Add to first. + + if (m_timer_queue != 0 + && m_timer_queue->get_time() == event->get_time()) + { + // Add to the first vertical list, in the end of the vertical list. + m_timer_queue->decrease_time_left(event->get_time()); // event->get_time() == 0. + add_end_of_vertical_list(m_timer_queue, event); + } + else + { + if (m_timer_queue != 0) + { + m_timer_queue->decrease_time_left(event->get_time()); + } + event->set_next(m_timer_queue); + m_timer_queue->set_prev(event); + m_timer_queue = event; + } + } + else if (current != 0 + && time_ms_sum == event->get_time()) + { + add_end_of_vertical_list(current, event); + event->decrease_time_left(event->get_time()); // event->get_time() == 0. + } + else + { + // Add new vertical list to middle. + EAP_ASSERT(prev != 0); + + event->decrease_time_left(time_ms_sum); + + if (prev != 0) + { + event->set_next(prev->get_next()); + if (prev->get_next() != 0) + { + prev->get_next()->set_prev(event); + prev->get_next()->decrease_time_left(event->get_time()); + } + prev->set_next(event); + event->set_prev(prev); + } + } + } + + trace_timer(); + +#endif //#if !defined(NO_EAP_TIMER_QUEUE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eap_timer_queue_c::add_new_pending_timer( + eap_timer_queue_event_c *event) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: [0x%08x] add_new_pending_timer(initializer 0x%08x, ") + EAPL("id 0x%02x, data 0x%08x, time %d)\n"), + m_timer_queue, + event->get_initializer(), + event->get_id(), + event->get_data(), + event->get_time_ms())); + + // Adds the new event to the end of the list to keep the order of events correct. + EAP_ASSERT(m_new_event_begin == 0 + && m_new_event_end == 0 + || m_new_event_begin != 0 + && m_new_event_end != 0); + + if (m_new_event_begin == 0 + && m_new_event_end == 0) + { + // Adds to the begin. + m_new_event_begin = event; + m_new_event_end = event; + } + else + { + // Adds to the end. + m_new_event_end->set_next(event); + m_new_event_end = event; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eap_timer_queue_c::set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_STACK_TRACE(initializer); + + if (m_is_active == false) + { + initializer->timer_delete_data(id, data); + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: TIMER: not accepted, timer queue is inactive: ") + EAPL("[0x%08x] set_timer(initializer 0x%08x, id 0x%02x, data 0x%08x, time %d)\n"), + m_timer_queue, + initializer, + id, + data, + time_ms)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + +#if !defined(NO_EAP_TIMER_QUEUE) + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + trace_timer(); + + eap_timer_queue_event_c *event = new eap_timer_queue_event_c( + m_am_tools, + initializer, + id, + data, + time_ms); + + if (event == 0) + { + initializer->timer_delete_data(id, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + if (m_use_eap_millisecond_timer == true) + { + // The next pulse_timer() function call will add the event to timer queue. + eap_status_e status = add_new_pending_timer(event); + if (status != eap_status_ok) + { + delete event; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + eap_status_e status = add_timer(event); + if (status != eap_status_ok) + { + delete event; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + +#endif //#if !defined(NO_EAP_TIMER_QUEUE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eap_timer_queue_c::add_pending_timer() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + while (m_new_event_begin != 0) + { + eap_timer_queue_event_c *event = m_new_event_begin; + + m_new_event_begin = m_new_event_begin->get_next(); + + if (m_new_event_begin == 0) + { + m_new_event_end = 0; + } + + event->set_next(0); + + eap_status_e status = add_timer(event); + if (status != eap_status_ok) + { + event->get_initializer()->timer_expired( + event->get_id(), + event->get_data()); + + delete event; + + // Read all pending events. Even the addition failed. + // We might have too less mamory. + } + } // while() + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_timer_queue_c::cancel_pending_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_STACK_TRACE(initializer); + + eap_timer_queue_event_c *previous = 0; + eap_timer_queue_event_c *event = m_new_event_begin; + + while (event != 0) + { + if (initializer == event->get_initializer() + && id == event->get_id()) + { + // Remove this pending event. + eap_timer_queue_event_c *remove = event; + event = event->get_next(); + + if (remove == m_new_event_end) + { + m_new_event_end = previous; + } + + remove->set_next(0); + delete remove; + + if (previous != 0) + { + previous->set_next(event); + } + else + { + m_new_event_begin = event; + } + } + else + { + previous = event; + event = event->get_next(); + } + } // while() + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eap_timer_queue_c::cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_STACK_TRACE(initializer); + +#if !defined(NO_EAP_TIMER_QUEUE) + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + + trace_timer(); + + + eap_status_e status = cancel_pending_timer( + initializer, + id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (m_timer_queue == 0) + { + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: empty queue, [0x%08x] cancel_timer(initializer 0x%08x, id 0x%02x)\n"), + m_timer_queue, + initializer, + id)); + } + else + { + eap_timer_queue_event_c * cursor = get_hashed_timer_event(initializer, id); + + while(cursor != 0) + { + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: [0x%08x] cancel_timer(initializer 0x%08x, ") + EAPL("id 0x%02x, original time %8d)\n"), + cursor, + initializer, + id, + cursor->get_original_time())); + + if (cursor == m_timer_queue) + { + // The first event will be removed. + EAP_ASSERT(cursor->get_prev() == 0); + + if (m_timer_queue->get_next_same_time() != 0) + { + eap_timer_queue_event_c * new_first = m_timer_queue->get_next_same_time(); + EAP_ASSERT(new_first->get_next() == 0 && new_first->get_prev() == 0); + new_first->set_prev_same_time(0); + new_first->set_next(m_timer_queue->get_next()); + if (m_timer_queue->get_next() != 0) + { + m_timer_queue->get_next()->set_prev(new_first); + } + m_timer_queue = new_first; + m_timer_queue->increase_time_left(cursor->get_time()); + } + else + { + if (cursor->get_next() != 0) + { + cursor->get_next()->increase_time_left(cursor->get_time()); + cursor->get_next()->set_prev(0); + } + m_timer_queue = cursor->get_next(); + } + + cursor->set_prev(0); + cursor->set_next(0); + cursor->set_prev_same_time(0); + cursor->set_next_same_time(0); + remove_hash_of_timer_event(cursor); + delete cursor; + } + else if (cursor->get_prev_same_time() != 0) + { + // Event from the vertical time list will be removed. + EAP_ASSERT(cursor->get_next() == 0 && cursor->get_prev() == 0); + cursor->get_prev_same_time()->set_next_same_time(cursor->get_next_same_time()); + if (cursor->get_next_same_time() != 0) + { + cursor->get_next_same_time()->set_prev_same_time(cursor->get_prev_same_time()); + } + cursor->set_prev(0); + cursor->set_next(0); + cursor->set_prev_same_time(0); + cursor->set_next_same_time(0); + remove_hash_of_timer_event(cursor); + delete cursor; + } + else // if (cursor->get_prev_same_time() == 0) + { + EAP_ASSERT(cursor->get_prev() != 0); + + // Event from middle or end of the horizontal queue will be removed. + if (cursor->get_next_same_time() != 0) + { + // Next on the vertical list will replace the removed timer event. + eap_timer_queue_event_c * new_first = cursor->get_next_same_time(); + + new_first->increase_time_left(cursor->get_time()); + + new_first->set_next(cursor->get_next()); + if (cursor->get_next() != 0) + { + cursor->get_next()->set_prev(new_first); + } + new_first->set_prev(cursor->get_prev()); + if (cursor->get_prev() != 0) + { + cursor->get_prev()->set_next(new_first); + } + new_first->set_prev_same_time(0); + } + else + { + // No other timer events are in the vertical list. + cursor->get_prev()->set_next(cursor->get_next()); + if (cursor->get_next() != 0) + { + cursor->get_next()->set_prev(cursor->get_prev()); + cursor->get_next()->increase_time_left(cursor->get_time()); + } + } + cursor->set_prev(0); + cursor->set_next(0); + cursor->set_prev_same_time(0); + cursor->set_next_same_time(0); + remove_hash_of_timer_event(cursor); + delete cursor; + } + cursor = get_hashed_timer_event(initializer, id); + } // while() + } + + trace_timer(); + +#endif //#if !defined(NO_EAP_TIMER_QUEUE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eap_timer_queue_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_STACK_TRACE(0); + + deactivate_timer_queue(); + + while (m_new_event_begin != 0) + { + eap_timer_queue_event_c *event = m_new_event_begin; + + m_new_event_begin = m_new_event_begin->get_next(); + + event->set_next(0); + + delete event; + event = 0; + } // while() + + m_new_event_end = 0; + +#if !defined(NO_EAP_TIMER_QUEUE) + + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: [0x%08x] cancel_all_timers()\n"), + m_timer_queue)); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = add_pending_timer(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + trace_timer(); + + if (m_timer_queue == 0) + { + // Nothing to do. + } + else + { + eap_timer_queue_event_c *cursor = m_timer_queue; + + while (cursor != 0) + { + // The first event will be removed. + m_timer_queue = m_timer_queue->get_next(); + + while (cursor != 0) + { + EAP_TRACE_TIMER( + m_am_tools, + TRACE_FLAGS_TIMER, + (EAPL("TIMER: [0x%08x] cancel_all_timers()\n"), + cursor)); + + eap_timer_queue_event_c *next = cursor->get_next_same_time(); + + cursor->set_prev(0); + cursor->set_next(0); + + remove_hash_of_timer_event(cursor); + + delete cursor; + + cursor = next; + } // while() + + cursor = m_timer_queue; + } // while() + } + + trace_timer(); + +#endif //#if !defined(NO_EAP_TIMER_QUEUE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +bool eap_timer_queue_c::get_is_valid() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/fileconfig_utils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/fileconfig_utils.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,203 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 16 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "fileconfig_utils.h" + +#include + +static char* get_subsect (FILE* file) +{ + + char* result = NULL; + char* line = new char[MAX_LINE_LENGTH]; + + if(!line) { + return NULL; + } + + for(;;) + { + result = fgets(line, MAX_LINE_LENGTH, file); + + // error or end of file + if(!result) + { + delete[] line; + break; + } + + // too short line, ignore + if(strlen(result) < 2) + { + continue; + } + + // In Linux and Symbian we have to remove + // the MS-DOS style carriage return + // (if the conf file happens to include those CRs). + if(result[strlen(result) - 2] == 0x0d) + { + result[strlen(result) - 2] = 0x0a; + result[strlen(result) - 1] = 0x00; + } + + // ignore the lines starting with newline, space, tab or '#' + if ((*result == '\n') || + (*result == ' ') || + (*result == '\t') || + (*result == '#')) + { + continue; + } + else + { + break; + } + } + + return result; +} + +static int is_sect (char* line, char const* sectname) +{ + size_t length; + + if (strlen (line) < (length = strlen (sectname))){ + return 0; + } + + return strncmp (sectname, line, length) == 0; +} + +void cnf_subsects (FILE* file, const SubSection* subsects, void* data) +{ + const SubSection* iter; + char* line; + int found; + + for (line = get_subsect (file); line; line = get_subsect (file)) + { + for (found = 0, iter = subsects; iter->name; iter++) + { + if (is_sect (line, iter->name)) + { + line [strlen (line) - 1] = '\0'; + (*iter->handler) (line, data); + found = 1; + break; + } + } + if (!found) + { + printf("ERROR: unrecognized subsection: %s\n", line); + } + delete[] line; + } +} + + +static char* find_rvalue (char* param) +{ + char* rvalue; + + for (rvalue = param; *rvalue; rvalue++) + { + if (*rvalue == '=') + { + break; + } + } + + if (!*rvalue) + { + return NULL; + } + + // Check are there defined environment variable to override the file confoguration. + { + // backup spaces. + char *param_end = rvalue; + for (param_end--; isspace(*param_end); param_end--){ + /* empty */ + } + param_end++; + char saved_char = *param_end; + *param_end = '\0'; + char * env_value = getenv(param); + if (env_value != 0) + { + printf("%s=%s; from environment variable\n", param, env_value); + } + *param_end = saved_char; + + if (env_value != 0) + { + // There is overriding environment variable. + return env_value; + } + } + + + for (rvalue++; isspace(*rvalue); rvalue++){ + /* empty */ + } + + printf("%s\n", param); + return rvalue; +} + +void cnf_get_string (char* target, char* param, size_t maxlen) +{ + size_t len; + + // Returned value could be pointer to environment value. + // Do not modify returned value. + param = find_rvalue (param); + + if (param == 0 + || target == 0) + { + return; + } + + len = min (maxlen - 1, strlen (param)); + memcpy (target, param, len); + target[len] = '\0'; +} + +i32_t cnf_get_int32 (char* param) +{ + param = find_rvalue (param); + + if (!param) + { + return 0; + } + + return atol (param); +} diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,85 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/common/eap_crypto_api.cpp \ + $(WLAN_COMMON)/am/common/abs_eap_am_mutex.cpp \ + $(WLAN_COMMON)/am/common/abs_eap_am_semaphore.cpp \ + $(WLAN_COMMON)/am/common/eap_am_tools.cpp \ + $(WLAN_COMMON)/am/common/eap_am_memory.cpp \ + $(WLAN_COMMON)/am/common/eap_am_network_id.cpp \ + $(WLAN_COMMON)/am/common/eap_timer_queue.cpp \ + $(WLAN_COMMON)/am/common/eap_am_memory_store.cpp \ + $(WLAN_COMMON)/am/common/eap_am_memory_store_data.cpp \ + $(WLAN_COMMON)/am/common/eap_file_config.cpp \ + $(WLAN_COMMON)/am/common/DSS_random/dss_random.cpp \ + $(WLAN_COMMON)/common/asn1_der_type.cpp \ + $(WLAN_COMMON)/common/eap_base_type.cpp \ + $(WLAN_COMMON)/common/eap_buffer.cpp \ + $(WLAN_COMMON)/common/eap_general_header_base.cpp \ + $(WLAN_COMMON)/common/eap_header.cpp \ + $(WLAN_COMMON)/common/eap_expanded_type.cpp \ + $(WLAN_COMMON)/common/eap_header_string.cpp \ + $(WLAN_COMMON)/common/eap_memory_store_variable_data.cpp \ + $(WLAN_COMMON)/common/eap_rogue_ap_entry.cpp \ + $(WLAN_COMMON)/common/eap_sim_triplets.cpp \ + $(WLAN_COMMON)/common/eap_tlv_header.cpp \ + $(WLAN_COMMON)/common/eap_tlv_message_data.cpp \ + $(WLAN_COMMON)/common/eap_tools.cpp \ + $(WLAN_COMMON)/common/eap_status_string.cpp \ + $(WLAN_COMMON)/common/eap_variable_data.cpp \ + $(WLAN_COMMON)/common/eap_master_session_key.cpp \ + $(WLAN_COMMON)/common/eap_state_notification.cpp \ + $(WLAN_COMMON)/common/eapol_session_key.cpp \ + $(WLAN_COMMON)/common/eap_network_id_selector.cpp \ + $(WLAN_COMMON)/common/eapol_ethernet_header.cpp \ + $(WLAN_COMMON)/common/eapol_header.cpp \ + $(WLAN_COMMON)/am/common/stack/eap_am_stack_trace.cpp \ + $(WLAN_TESTING)/am/common/openssl/eap_am_crypto_openssl.cpp \ + $(WLAN_COMMON)/am/common/crypto/random/eap_am_random_test.cpp \ + $(WLAN_COMMON)/am/common/crypto/sha1/eap_am_crypto_sha1.cpp \ + $(WLAN_COMMON)/am/common/crypto/md4/eap_am_crypto_md4.cpp \ + $(WLAN_COMMON)/am/common/crypto/rc4/eap_am_crypto_rc4.cpp \ + $(WLAN_COMMON)/am/common/crypto/sha1/eap_am_crypto_sha1.cpp \ + $(WLAN_COMMON)/am/common/crypto/sha-256/eap_am_crypto_sha_256.cpp \ + +# $(WLAN_LINUX)/am/common/linux_gnu/eap_am_tools_linux-gnu.cpp \ +# $(WLAN_LINUX)/am/common/linux_gnu/eap_am_mutex_linux-gnu.cpp \ +# $(WLAN_LINUX)/am/common/linux_gnu/eap_am_semaphore_linux-gnu.cpp + +SRC_FILES_CPP := $(SRC_FILES_CPP) \ + $(WLAN_TESTING)/am/common/file_io/stdio/eap_am_file_input_stdio.cpp \ + $(WLAN_TESTING)/am/common/file_trace/eap_am_trace_file_stdio.cpp + +ifeq (linux_gnu,$(EAP_OSTYPE)) + SRC_FILES_CPP := $(SRC_FILES_CPP) \ + $(WLAN_LINUX)/am/eap_test_timer/linux_gnu/eap_test_timer.cpp \ + $(WLAN_LINUX)/am/common/linux_gnu/eap_am_tools_linux-gnu.cpp \ + $(WLAN_LINUX)/am/common/linux_gnu/eap_am_mutex_linux-gnu.cpp \ + $(WLAN_LINUX)/am/common/linux_gnu/eap_am_semaphore_linux-gnu.cpp +endif + +ifeq (cygwin,$(EAP_OSTYPE)) + SRC_FILES_CPP := $(SRC_FILES_CPP) \ + $(WLAN_WINDOWS)/am/eap_test_timer/cygwin/eap_test_timer.cpp \ + $(WLAN_WINDOWS)/am/common/win32_and_cygwin/eap_am_tools_cygwin.cpp +endif + +ifeq (cygwin,$(EAP_OSTYPE)) +LIBS := $(LIBS) $(CYG_OPENSSL_LIBRARY)/libssl.a $(CYG_OPENSSL_LIBRARY)/libcrypto.a +else +LIBS := $(LIBS) $(CYG_OPENSSL_LIBRARY)/libssl.so $(CYG_OPENSSL_LIBRARY)/libcrypto.so +endif + +ifeq (cygwin,$(EAP_OSTYPE)) +ifdef DMALLOC + LIBS := $(LIBS) $(WLAN_WINDOWS)/LIBRARY/windows/dmalloc_dll.lib +endif +endif + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/stack/eap_am_stack_trace.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/stack/eap_am_stack_trace.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,229 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 17 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#if defined(unix) + #include +#endif +#if defined(WIN32) + #include +#endif + +#if !defined(__SYMBIAN32__) + #include + #include + #include + #include +#endif //#if !defined(__SYMBIAN32__) + +#include "eap_am_stack_trace.h" + +#include "abs_eap_am_tools.h" +#include "eap_am_tools.h" + +/********************************************************************/ + +EAP_FUNC_EXPORT stack_trace::~stack_trace() +{ +} + +/********************************************************************/ + +EAP_FUNC_EXPORT stack_trace::stack_trace(abs_eap_am_tools_c * const tools) +: m_am_tools(tools) +{ +} + +/********************************************************************/ + +EAP_FUNC_EXPORT void stack_trace::trace_frames( + unsigned long *bp +) +{ + +#if !defined(__SYMBIAN32__) + + unsigned long *tmp_bp = bp; + + if (bp == 0) + { + return; + } + + while ( tmp_bp != 0x0 && tmp_bp < reinterpret_cast(0xbffff8ec) +#if defined(linux) + && tmp_bp > reinterpret_cast(0xbf800000) +#else + && tmp_bp < reinterpret_cast(0x77000000) +#endif + ) + { + + EAP_TRACE_ALWAYS(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("function: 0x%08x\n"), + reinterpret_cast(*(tmp_bp+1)))); + + tmp_bp = reinterpret_cast(*tmp_bp); + } + +#else + + EAP_UNREFERENCED_PARAMETER(bp); + +#endif //#if !defined(__SYMBIAN32__) + +} + +/********************************************************************/ + + +EAP_FUNC_EXPORT void stack_trace::trace(const void * const memory_address) +{ + +#if defined(__SYMBIAN32__) && (defined(USE_EAP_STACK_TRACE) || defined(USE_EAP_ASSERT_STACK_TRACE)) + + u32_t current_sp = 0; + +#if 0 + // Thumb does not support inline assembler. + __asm + { + MOV current_sp, __current_sp() + } +#else + current_sp = reinterpret_cast(¤t_sp); +#endif + + if (current_sp == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Cannot obtain current stack pointer.\n"))); + } + + TThreadStackInfo aInfo; + + RThread current_thread; + + if (current_thread.StackInfo(aInfo) != KErrNone) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Cannot obtain stack information.\n"))); + } + + if (aInfo.iBase < current_sp) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Stack start %d < current stack pointer %d.\n"), + aInfo.iBase, + current_sp)); + } + + u32_t *start_address = reinterpret_cast(current_sp); + u32_t *address = start_address; + + EAP_TRACE_ALWAYS(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("address 0x%08x, accessed from:.\n"), + memory_address)); + + while (reinterpret_cast(address) >= aInfo.iLimit) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("stack address 0x%08x: 0x%08x\n"), + address, + *address)); + + --address; + } + + EAP_TRACE_ALWAYS(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_ALWAYS(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("address 0x%08x, accessed from:.\n"), + memory_address)); + + address = start_address; + + while (reinterpret_cast(address) < aInfo.iBase) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("stack address 0x%08x: 0x%08x\n"), + address, + *address)); + + ++address; + } + +#elif (defined(unix) || defined(WIN32)) && (defined(USE_EAP_STACK_TRACE) || defined(USE_EAP_ASSERT_STACK_TRACE)) + + jmp_buf tmp_buf; + + +#if defined(linux) + _setjmp( tmp_buf ); +#else + setjmp( tmp_buf ); +#endif + + + EAP_TRACE_ALWAYS(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("address 0x%08x, accessed from:.\n"), + memory_address)); + + + trace_frames( + #if defined(linux) + reinterpret_cast(tmp_buf->__jmpbuf[JB_BP]) + #elif defined(WIN32) + reinterpret_cast(((_JUMP_BUFFER *)tmp_buf)->Ebp) + #elif defined(cygwin) + reinterpret_cast(tmp_buf[0].ebp) + #else + reinterpret_cast(tmp_buf->__ebp) + #endif + ); + +#else + + EAP_UNREFERENCED_PARAMETER(memory_address); + +#endif //#if defined(unix) || defined(WIN32) + +} + + +/********************************************************************/ +/* End. */ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/stack/eap_am_stack_trace.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/stack/eap_am_stack_trace.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_STACK_OUTPUT_H_) +#define _STACK_OUTPUT_H_ + +#include "eap_am_export.h" + +class abs_eap_am_tools_c; + +/** + * This class implemets a stack trace. This code is highly processor dependent. + * Only Intel processor with gcc or MSVC is supported. + */ +class EAP_EXPORT stack_trace +{ +private: + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /** + * This function traces stack frames starting from bp. + * The bp is pointer to base of the starting stack frame. + */ + EAP_FUNC_IMPORT void trace_frames( + unsigned long *bp + ); + +public: + + /** + * Destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~stack_trace(); + + /** + * Constructor does nothing special. + */ + EAP_FUNC_IMPORT stack_trace(abs_eap_am_tools_c * const tools); + + /** + * This function traces stack frames starting from current frame. + * Value of parameter memory_address is traced in the begin. + */ + EAP_FUNC_IMPORT void trace(const void * const memory_address); + +}; + +#endif //#if !defined(_STACK_OUTPUT_H_) + +/* End. */ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/core/eap_am_wimax_authentication.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/core/eap_am_wimax_authentication.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP stack interface for Wimax. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 1000 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include "eap_am_wimax_authentication.h" + +// +eap_am_wimax_authentication_c::~eap_am_wimax_authentication_c() +{ +} + +//-------------------------------------------------- + + + +// End. + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/core/eapol_am_wlan_authentication.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/core/eapol_am_wlan_authentication.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 18 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eapol_am_wlan_authentication.h" + +// +eapol_am_wlan_authentication_c::~eapol_am_wlan_authentication_c() +{ +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_aka_algorithm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_aka_algorithm.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,98 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_AKA_ALGORITHM_H_) +#define _ABS_AKA_ALGORITHM_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "abs_eap_am_tools.h" +#include "eap_am_tools.h" +#include "eap_am_export.h" +#include "eap_type_aka_authentication_vector.h" + +enum aka_algorithm_e +{ + aka_algorithm_none, + aka_algorithm_nokia_test_network_xor, + aka_algorithm_tls_prf_with_shared_secret, + aka_algorithm_milenage, +}; + + +/// This class is implements Nokia test network AKA algorithm. +class EAP_EXPORT abs_eap_am_aka_algorithm_c +{ +private: + //-------------------------------------------------- + + virtual void set_is_valid() = 0; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eap_am_aka_algorithm_c(){}; + + virtual eap_status_e shutdown() = 0; + + + virtual bool get_is_valid() = 0; + + + virtual eap_status_e set_simulator_aka_k( + const eap_variable_data_c * const simulator_aka_ki) = 0; + + virtual eap_status_e set_simulator_aka_op( + const eap_variable_data_c * const simulator_aka_op) = 0; + + virtual eap_status_e set_simulator_aka_amf( + const eap_variable_data_c * const simulator_aka_amf) = 0; + + virtual eap_status_e set_do_ramdom_synchronization_error() = 0; + + + virtual eap_status_e generate_authentication_vector( + eap_type_aka_authentication_vector_c * const authentication_vector) = 0; + + virtual eap_status_e generate_RES( + eap_type_aka_authentication_vector_c * const authentication_vector) = 0; + + virtual eap_status_e re_synchronize( + eap_type_aka_authentication_vector_c * const authentication_vector) = 0; + + //-------------------------------------------------- +}; // class abs_eap_am_aka_algorithm_c + + +/** @file */ + +#endif //#if !defined(_ABS_AKA_ALGORITHM_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_bloom_algorithm_store.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_bloom_algorithm_store.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,112 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_ABS_EAP_AM_BLOOM_ALGORITHM_STORE_H_) +#define _ABS_EAP_AM_BLOOM_ALGORITHM_STORE_H_ + + +#include "eap_tools.h" + +//-------------------------------------------------- + +/// This is interface to bit store of the Bloom filter algorithm. +/** The bit store should be divided to two stores. + * New bits are stored to the current bit store. + * When current bit store becames over populated it should be + * changed previous bit store and a new current bit store should be created. + * Each bit index should be checked from current and previous bit stores. + * Over population can be calculated from count of set bit and size of the bit store. + * When half of the bits are set probability of false filtering will increse + * much faster. Probability of false filtering is saturation raised power to bit index count. + * Saturation is count of set bits divided by size of bit store. + * Bit index count is count of separate indexes extracted from hash digest. + * Each index is n bits long. The size of the bit store is 2^n bits. + */ +class EAP_EXPORT abs_eap_am_bloom_algorithm_store_c +{ + +private: + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + +public: + + /** + * The destructor of the abs_eap_am_bloom_algorithm_store_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~abs_eap_am_bloom_algorithm_store_c() + { + } + + /** + * The constructor of the abs_eap_am_bloom_algorithm_store_c does nothing special. + */ + EAP_FUNC_IMPORT abs_eap_am_bloom_algorithm_store_c() + { + } + + /** + * This function sets the name of the bit store. + * Store name is 8-bit string without terminating NULL. + */ + virtual eap_status_e set_name_of_store(const eap_variable_data_c * const store_name) = 0; + + /** + * This function checks the bit store exists. + * Function should return eap_status_ok when bit store exists and is valid. + */ + virtual eap_status_e bloom_filter_check_does_bit_store_exists() = 0; + + /** + * This is the count of bits in the index of Bloom algorithm. + */ + virtual eap_status_e set_bloom_bit_index_size(const u32_t bloom_bit_index_size) = 0; + + /** + * This function returns the bit value of queried bit from the current and previous bit store. + * @param bit_index indicates the queried bit. + */ + virtual u32_t bloom_filter_get_bit_index(const u32_t bit_index) = 0; + + /** + * This function sets the bit value of queried bit to the bit store. + * @param bit_index indicates the queried bit. + */ + virtual eap_status_e bloom_filter_set_bit_index(const u32_t bit_index) = 0; + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + virtual bool get_is_valid() = 0; + +}; // class eap_am_bloom_algorithm_c + +#endif //#if !defined(_ABS_EAP_AM_BLOOM_ALGORITHM_STORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_crypto.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_crypto.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,671 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _ABS_EAP_AM_CRYPTO_H_ ) +#define _ABS_EAP_AM_CRYPTO_H_ + +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_am_tools.h" +#include "eap_array.h" + +#if 0 +const u32_t TRACE_FLAGS_EAP_AM_CRYPTO = + eap_am_tools_c::eap_trace_mask_crypto + | eap_am_tools_c::eap_trace_mask_debug; +#else +const u32_t TRACE_FLAGS_EAP_AM_CRYPTO = + eap_am_tools_c::eap_trace_mask_crypto; +#endif + +const u32_t EAP_AES_BLOCK_SIZE = 16u; + +const u32_t EAP_3DES_EDE_CBC_BLOCK_SIZE = 8ul; + + +class abs_eap_am_tools_c; +class eap_variable_data_c; + +/// Class eap_am_crypto offers services to authenticate data, encrypt data, +/// decrypt data, generate keys and generate cryptographically strong random data. +class EAP_EXPORT abs_eap_am_crypto_c +{ +private: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /** + * Destructor does nothing special. + */ + virtual ~abs_eap_am_crypto_c() + { + } + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + * Needed configuration depends on the implementation. + */ + virtual eap_status_e configure() = 0; + + /** + * The get_is_valid() function returns the status of the eap_core object. + * True indicates the object is initialized succesfully. + */ + virtual bool get_is_valid() const = 0 ; + + virtual void set_is_valid() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function activates random generator for test use. + * It does generate predictive pseudorandom data. + */ + virtual void use_test_random( + const u8_t * const seed, + const u32_t seed_length, + const bool does_continuous_seeding_when_true) = 0; + + /** + * The get_rand_bytes() function fills count random bytes to buffer. + */ + virtual eap_status_e get_rand_bytes( + u8_t * const buffer, + const u32_t count) = 0; + + /** + * The add_rand_seed() function seeds count bytes from buffer to the random data pool. + * The seed bytes could be any data that increases entropy of the random data pool. + * For example time stamps of send and received messages, likewise addresses, + * cookies and nonces included in messages. + */ + virtual eap_status_e add_rand_seed( + const u8_t * const buffer, + const u32_t count) = 0; + + /** + * The add_rand_seed_hw_ticks() function adds hardware ticks read with + * the abs_eap_am_tools::get_hardware_ticks() function. This could be used to + * seed the random data pool with time stamps. + */ + virtual eap_status_e add_rand_seed_hw_ticks() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The generate_diffie_hellman_keys() function generates private and public + * Diffie-Hellman keys. The key_length parameter is not fully supported. + * It is used only for sanity checks. Only one well-known group is supported. + * @param dh_context Saves context here. Is private key in OpenSSL and CDHKey in Symbian. + */ + virtual eap_status_e generate_diffie_hellman_keys( + eap_variable_data_c * const dh_context, + eap_variable_data_c * const own_public_dh_key, + const u8_t * const prime, + const u32_t prime_length, + const u8_t * const group_generator, + const u32_t group_generator_length) = 0; + + /** + * The generate_g_power_to_xy() function generates shared secret + * Diffie-Hellman key from own_private_dh_key and peer_public_dh_key. + * The key_length parameter is not fully supported. It is used only for sanity checks. + * Only one well-known group is supported. + * @param dh_context Gets context. Is private key in OpenSSL and CDHKey in Symbian. + */ + virtual eap_status_e generate_g_power_to_xy( + const eap_variable_data_c * const dh_context, + const eap_variable_data_c * const peer_public_dh_key, + eap_variable_data_c * const shared_dh_key, + const u8_t * const prime, + const u32_t prime_length, + const u8_t * const group_generator, + const u32_t group_generator_length) = 0; + + /** + * This functions cleans up the diffie-hellman context. + */ + virtual eap_status_e dh_cleanup( + const eap_variable_data_c * const dh_context) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of SHA1-algorithm. + */ + virtual u32_t get_sha_256_digest_length( + eap_variable_data_c * const sha_256_context) = 0; + + /** + * This function returns the block size of SHA1-algorithm. + */ + virtual u32_t get_sha_256_block_size( + eap_variable_data_c * const sha_256_context) = 0; + + /** + * The sha_256_init() function initializes SHA1. + * Internal context of SHA1 is stored to sha_256_context. + */ + virtual eap_status_e sha_256_init( + eap_variable_data_c * const sha_256_context) = 0; + + /** + * The sha_256_update() function updates the context of + * sha_256_context with data_length bytes of data. + */ + virtual eap_status_e sha_256_update( + eap_variable_data_c * const sha_256_context, + const u8_t * const data, + const u32_t data_length) = 0; + + /** + * The sha_256_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non NULL. + */ + virtual eap_status_e sha_256_final( + eap_variable_data_c * const sha_256_context, + u8_t * const message_digest, + u32_t *md_length_or_null) = 0; + + /** + * The hmac_sha_256_cleanup() cleanups the SHA1 context. + */ + virtual eap_status_e sha_256_cleanup( + eap_variable_data_c * const sha_256_context) = 0; + + /** + * The sha_256_copy_context() copies the SHA1 context. + */ + virtual eap_status_e sha_256_copy_context( + eap_variable_data_c * const copied_sha_256_context, + const eap_variable_data_c * const original_sha_256_context) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of SHA1-algorithm. + */ + virtual u32_t get_sha1_digest_length( + eap_variable_data_c * const sha1_context) = 0; + + /** + * This function returns the block size of SHA1-algorithm. + */ + virtual u32_t get_sha1_block_size( + eap_variable_data_c * const sha1_context) = 0; + + /** + * The sha1_init() function initializes SHA1. + * Internal context of SHA1 is stored to sha1_context. + */ + virtual eap_status_e sha1_init( + eap_variable_data_c * const sha1_context) = 0; + + /** + * The sha1_update() function updates the context of + * sha1_context with data_length bytes of data. + */ + virtual eap_status_e sha1_update( + eap_variable_data_c * const sha1_context, + const u8_t * const data, + const u32_t data_length) = 0; + + /** + * The sha1_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non NULL. + */ + virtual eap_status_e sha1_final( + eap_variable_data_c * const sha1_context, + u8_t * const message_digest, + u32_t *md_length_or_null) = 0; + + /** + * The hmac_sha1_cleanup() cleanups the SHA1 context. + */ + virtual eap_status_e sha1_cleanup( + eap_variable_data_c * const sha1_context) = 0; + + /** + * The sha1_copy_context() copies the SHA1 context. + */ + virtual eap_status_e sha1_copy_context( + eap_variable_data_c * const copied_sha1_context, + const eap_variable_data_c * const original_sha1_context) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The aes_key_length() function returns the length of key AES-algorithm. + * This will be constant 16 bytes (128 bits). Still it is better use function + * to help changes if the length of key is changed in future. + */ + virtual u32_t aes_key_length() = 0; + + /** + * The aes_block_size() function returns the block size of AES-algorithm. + * This will be constant 16 bytes (128 bits). Still it is better use function + * to help changes if the size is changed in future. + */ + virtual u32_t aes_block_size() = 0; + + + /** + * The aes_set_encryption_key() function initializes the encryption + * context of AES-algorithm to the aes_context using key_length bytes from buffer key. + */ + virtual eap_status_e aes_set_encryption_key( + eap_variable_data_c * const aes_context, + const u8_t * const key, + const u32_t key_length) = 0; + + /** + * The aes_set_decryption_key() function initializes the decryption context of + * AES-algorithm to the aes_context using key_length bytes from buffer key. + */ + virtual eap_status_e aes_set_decryption_key( + eap_variable_data_c * const aes_context, + const u8_t * const key, + const u32_t key_length) = 0; + + virtual eap_status_e aes_cleanup( + eap_variable_data_c * const aes_context) = 0; + + /** + * The aes_encrypt_block() function encrypts data of data_length bytes + * using encryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of AES-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used taking + * advance from separate buffers. + */ + virtual eap_status_e aes_encrypt_block( + eap_variable_data_c * const aes_context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length) = 0; + + /** + * The aes_decrypt_block() function decrypts data of data_length bytes + * using decryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of AES-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used + * taking advance from separate buffers. + */ + virtual eap_status_e aes_decrypt_block( + eap_variable_data_c * const aes_context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The key_length() function returns the length of key 3DES-EDE-algorithm. + * This will be constant 16 bytes (128 bits). Still it is better use function + * to help changes if the length of key is changed in future. + */ + virtual u32_t key_length_3des_ede() = 0; + + /** + * The block_size() function returns the block size of 3DES-EDE-algorithm. + * This will be constant 16 bytes (128 bits). Still it is better use function + * to help changes if the size is changed in future. + */ + virtual u32_t block_size_3des_ede() = 0; + + + /** + * The cbc_set_encryption_key() function initializes the encryption + * context of 3DES-EDE-algorithm to the context using key_length bytes from buffer key. + */ + virtual eap_status_e set_encryption_key_3des_ede( + eap_variable_data_c * const context, + const u8_t * const key, + const u32_t key_length) = 0; + + /** + * The cbc_set_decryption_key() function initializes the decryption context of + * 3DES-EDE-algorithm to the context using key_length bytes from buffer key. + */ + virtual eap_status_e set_decryption_key_3des_ede( + eap_variable_data_c * const context, + const u8_t * const key, + const u32_t key_length) = 0; + + virtual eap_status_e cleanup_3des_ede( + eap_variable_data_c * const context) = 0; + + /** + * The cbc_encrypt_data() function encrypts data of data_length bytes + * using encryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of 3DES-EDE-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used taking + * advance from separate buffers. + */ + virtual eap_status_e encrypt_block_3des_ede( + eap_variable_data_c * const context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length) = 0; + + /** + * The cbc_decrypt_data() function decrypts data of data_length bytes + * using decryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of 3DES-EDE-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used + * taking advance from separate buffers. + */ + virtual eap_status_e decrypt_block_3des_ede( + eap_variable_data_c * const context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Key derivation is based on the random number generation specified in + * NIST Federal Information Processing Standards (FIPS) Publication + * 186-2 [9]. The random number generator is specified in the change + * notice 1 (2001 October 5) of [9] (Algorithm 1). As specified in the + * change notice (page 74), when Algorithm 1 is used as a general- + * purpose random number generator, the "mod q" term in step 3.3 is + * omitted. The function G used in the algorithm is constructed via + * Secure Hash Standard as specified in Appendix 3.3 of the standard. + + * 160-bit XKEY and XVAL values are used, so b = 160. The initial + * secret seed value XKEY is computed from the n GSM Kc keys and the + * NONCE_MT with the following formula: + * @code + * XKEY = SHA1(n*Kc| NONCE_MT) + * + * Random generator becomes as follows: + * Step 1. Choose a new, secret value for the seed-key, XKEY. + * Step 2. In hexadecimal notation let + * t = 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0. + * This is the initial value for H0 || H1 || H2 || H3 || H4 in the SHS. + * Step 3. For j = 0 to m - 1 do + * c. xj = G(t,XKEY). + * d. XKEY = (1 + XKEY + xj) mod 2^b. + * @endcode + */ + virtual eap_status_e dss_pseudo_random( + u8_t *out, + u32_t out_length, + u8_t *xkey, + u32_t xkey_length) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of MD5-algorithm. + */ + virtual u32_t get_md5_digest_length( + eap_variable_data_c * const md5_context) = 0; + + /** + * This function returns the block size of MD5-algorithm. + */ + virtual u32_t get_md5_block_size( + eap_variable_data_c * const md5_context) = 0; + + /** + * The sha1_init() function initializes MD5. + * Internal context of MD5 is stored to sha1_context. + */ + virtual eap_status_e md5_init( + eap_variable_data_c * const md5_context) = 0; + + /** + * The md5_update() function updates the context of + * md5_context with data_length bytes of data. + */ + virtual eap_status_e md5_update( + eap_variable_data_c * const md5_context, + const u8_t * const data, + const u32_t data_length) = 0; + + /** + * The md5_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non NULL. + */ + virtual eap_status_e md5_final( + eap_variable_data_c * const md5_context, + u8_t * const message_digest, + u32_t *md_length_or_null) = 0; + + /** + * The hmac_md5_cleanup() cleanups the MD5 context. + */ + virtual eap_status_e md5_cleanup( + eap_variable_data_c * const md5_context) = 0; + + /** + * The md5_copy_context() copies the MD5 context. + */ + virtual eap_status_e md5_copy_context( + eap_variable_data_c * const copied_md5_context, + const eap_variable_data_c * const original_md5_context) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of MD4-algorithm. + */ + virtual u32_t get_md4_digest_length( + eap_variable_data_c * const md4_context) = 0; + + /** + * This function returns the block size of MD4-algorithm. + */ + virtual u32_t get_md4_block_size( + eap_variable_data_c * const md4_context) = 0; + + /** + * The sha1_init() function initializes MD4. + * Internal context of MD4 is stored to sha1_context. + */ + virtual eap_status_e md4_init( + eap_variable_data_c * const md4_context) = 0; + + /** + * The md4_update() function updates the context of + * md4_context with data_length bytes of data. + */ + virtual eap_status_e md4_update( + eap_variable_data_c * const md4_context, + const u8_t * const data, + const u32_t data_length) = 0; + + /** + * The md4_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non NULL. + */ + virtual eap_status_e md4_final( + eap_variable_data_c * const md4_context, + u8_t * const message_digest, + u32_t *md_length_or_null) = 0; + + /** + * The hmac_md4_cleanup() cleanups the MD4 context. + */ + virtual eap_status_e md4_cleanup( + eap_variable_data_c * const md4_context) = 0; + + /** + * The md4_copy_context() copies the MD4 context. + */ + virtual eap_status_e md4_copy_context( + eap_variable_data_c * const copied_md4_context, + const eap_variable_data_c * const original_md4_context) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Used to set the RC4 key. + */ + virtual eap_status_e rc4_set_key( + eap_variable_data_c * const rc4_context, + const eap_variable_data_c * const key) = 0; + + /** + * Used to clean up the RC4 context. + */ + virtual eap_status_e rc4_cleanup( + eap_variable_data_c * const rc4_context) = 0; + + /** + * Encrypts RC4 data. + */ + virtual eap_status_e rc4_encrypt( + const eap_variable_data_c * const rc4_context, + void * const data_in_out, + const u32_t data_length) = 0; + + /** + * Encrypts RC4 data. + */ + virtual eap_status_e rc4_encrypt( + const eap_variable_data_c * const rc4_context, + const void * const data_in, + void * const data_out, + const u32_t data_length) = 0; + + /** + * Decrypts RC4 data. + */ + virtual eap_status_e rc4_decrypt( + const eap_variable_data_c * const rc4_context, + void * const data_in_out, + const u32_t data_length) = 0; + + /** + * Decrypts RC4 data. + */ + virtual eap_status_e rc4_decrypt( + const eap_variable_data_c * const rc4_context, + const void * const data_in, + void * const data_out, + const u32_t data_length) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The rsa_init() function initializes context of RSA. + * Internal context of RSA is stored to rsa_context. + */ + virtual eap_status_e rsa_init( + eap_variable_data_c * const rsa_context) = 0; + + virtual eap_status_e rsa_encrypt_with_public_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) = 0; + + virtual eap_status_e rsa_decrypt_with_public_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) = 0; + + virtual eap_status_e rsa_encrypt_with_private_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) = 0; + + virtual eap_status_e rsa_decrypt_with_private_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) = 0; + + virtual eap_status_e rsa_sign( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash) = 0; + + virtual eap_status_e rsa_verify( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash) = 0; + + /** + * The rsa_cleanup() function cleans up context of RSA. + * Internal context of RSA is stored to rsa_context. + */ + virtual eap_status_e rsa_cleanup( + eap_variable_data_c * const rsa_context) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The dsa_init() function initializes context of DSA. + * Internal context of DSA is stored to dsa_context. + */ + virtual eap_status_e dsa_init( + eap_variable_data_c * const dsa_context) = 0; + + virtual eap_status_e dsa_sign( + eap_variable_data_c * const dsa_context, + const eap_variable_data_c * const private_dsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash) = 0; + + virtual eap_status_e dsa_verify( + eap_variable_data_c * const dsa_context, + const eap_variable_data_c * const public_dsa_key, + const eap_variable_data_c * const dsa_param_p, + const eap_variable_data_c * const dsa_param_q, + const eap_variable_data_c * const dsa_param_g, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash) = 0; + + /** + * The dsa_cleanup() function cleans up context of DSA. + * Internal context of DSA is stored to dsa_context. + */ + virtual eap_status_e dsa_cleanup( + eap_variable_data_c * const dsa_context) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + +}; + +#endif //#if !defined( _ABS_EAP_AM_CRYPTO_H ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_file_input.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_file_input.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,218 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_ABS_EAP_AM_FILE_INPUT_H_) +#define _ABS_EAP_AM_FILE_INPUT_H_ + + +#include "eap_tools.h" +#include "eap_array.h" + +//-------------------------------------------------- + +enum eap_file_io_direction_e +{ + eap_file_io_direction_read, + eap_file_io_direction_write, +}; + +//-------------------------------------------------- + +enum eap_file_type_e +{ + eap_file_type_none, + eap_file_type_file, + eap_file_type_directory, +}; + +//-------------------------------------------------- + +class eap_variable_data_c; + + +class abs_eap_file_stat_c +{ +private: + +public: + + virtual ~abs_eap_file_stat_c() + { + } + + abs_eap_file_stat_c() + { + } + + virtual const eap_variable_data_c * const get_file_name() const = 0; + + virtual const eap_file_type_e get_file_type() const = 0; + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + virtual bool get_is_valid() const = 0; +}; + +//-------------------------------------------------- + +/// This is interface to EAP file input. +/** The EAP file input is used in configuration file read operations. + */ +class EAP_EXPORT abs_eap_am_file_input_c +{ + +private: + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + +public: + + /** + * The destructor of the abs_eap_am_file_input_c class does nothing special. + */ + virtual ~abs_eap_am_file_input_c() + { + } + + /** + * The constructor of the abs_eap_am_file_input_c does nothing special. + */ + abs_eap_am_file_input_c() + { + } + + /** + * This function checks the file of name file_name exists. + * It returns eap_status_ok if file exists + * in other cases some error status. + * @param file_nameis the pathname of the tested file. + */ + virtual eap_status_e file_exists(const eap_variable_data_c * const file_name) = 0; + + /** + * This function deletes the file of name if file_name exists. + * It returns eap_status_ok if file did exist and it was deleted + * in other cases some error status. + * @param file_nameis the pathname of the deleted file. + */ + virtual eap_status_e file_delete(const eap_variable_data_c * const file_name) = 0; + + /** + * This function copies the file source_file_name to file target_file_name. + * @param target_file_name is the pathname of the target file. + * @param source_file_name is the pathname of the source file. + */ + virtual eap_status_e file_copy( + const eap_variable_data_c * const target_file_name, + const eap_variable_data_c * const source_file_name) = 0; + + /** + * This function opens file of name file_name. + * @param file_name is the pathname of the opened file. + * @param dir is the I/O direction (eap_file_io_direction_read or eap_file_io_direction_write). + */ + virtual eap_status_e file_open( + const eap_variable_data_c * const file_name, + const eap_file_io_direction_e dir) = 0; + + /** + * This function closes the file. + */ + virtual eap_status_e file_close() = 0; + + /** + * This function returns size of a file. + */ + virtual u32_t file_size() = 0; + + /** + * This function reads data from a file. + * Maximum size read is the buffer size. + * @param buffer must be initialised to reguired size. + */ + virtual eap_status_e file_read(eap_variable_data_c * const buffer) = 0; + + /** + * This function write data to a file. + * Maximum size write is the buffer size. + * @param buffer includes the written data. + */ + virtual eap_status_e file_write(const eap_variable_data_c * const buffer) = 0; + + /** + * This function reads line from file. + * @param The read line will be copied to line parameter. + */ + virtual eap_status_e file_read_line(eap_variable_data_c * const line) = 0; + + /** + * This function reads word from file. + * @param The read word will be copied to word parameter. + */ + virtual eap_status_e file_read_word(eap_variable_data_c * const word) = 0; + + + /** + * This function opens directory of name directory_name. + * @param file_name is the pathname of the opened directory. + */ + virtual eap_status_e directory_open( + const eap_variable_data_c * const directory_name) = 0; + + /** + * This function reads the files and directories from open directory. + * @param directory_list includes the stattus of each file and directory in open directory. + */ + virtual eap_status_e directory_read( + eap_array_c * const directory_list) = 0; + + /** + * This function closes the directory. + */ + virtual eap_status_e directory_close() = 0; + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + virtual bool get_is_valid() = 0; + + /** + * Function creates an object on a platform. + */ + static abs_eap_am_file_input_c * new_abs_eap_am_file_input_c( + abs_eap_am_tools_c * const tools); + +}; // class abs_eap_am_file_input_c + +#endif //#if !defined(_ABS_EAP_AM_FILE_INPUT_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_memory_store_data.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_memory_store_data.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined( _ABS_EAP_AM_TOOLS_MEMORY_STORE_DATA_H_ ) +#define _ABS_EAP_AM_TOOLS_MEMORY_STORE_DATA_H_ + + +#include "eap_am_export.h" + +/// This class is base class for data stored to memory store. +/** + * Here are no real functions. + */ +class EAP_EXPORT abs_eap_am_memory_store_data_c +{ +public: + + /** + * The destructor of the abs_eap_am_memory_store_data_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~abs_eap_am_memory_store_data_c(); + + /** + * The constructor of the abs_eap_am_memory_store_data_c does nothing special. + */ + EAP_FUNC_IMPORT abs_eap_am_memory_store_data_c(); + +}; + +#endif //#if !defined( _ABS_EAP_AM_TOOLS_MEMORY_STORE_DATA_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_mutex.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_mutex.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,184 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _ABS_EAP_AM_MUTEX_H_ ) +#define _ABS_EAP_AM_MUTEX_H_ + +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" + +class eap_am_mutex_reference_c; + +// --------------------------------------------- + +/// This class is interface to mutex. +class EAP_EXPORT abs_eap_am_mutex_c +{ +private: + +public: + + EAP_FUNC_IMPORT virtual ~abs_eap_am_mutex_c(); + + EAP_FUNC_IMPORT abs_eap_am_mutex_c(); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function enters the mutex. Thread will block until the mutex is released + * by other owner of the mutex. + */ + EAP_FUNC_IMPORT virtual eap_status_e mutex_enter() = 0; + + /** + * This function leaves the mutex. Other blocking thread will continue execution. + */ + EAP_FUNC_IMPORT virtual eap_status_e mutex_leave(abs_eap_am_tools_c * const m_am_tools) = 0; + + /** + * The mutex handle must be dublicated in Symbian operating system for each thread. + */ + EAP_FUNC_IMPORT virtual abs_eap_am_mutex_c * dublicate_mutex() = 0; + + /** + * This function returns the flag that indicates whether the mutex is reserved. + * This is used in debug asserts. Those will check the mutex is really reserved when critical code is entered. + */ + EAP_FUNC_IMPORT virtual bool get_is_reserved() const = 0; + + /** + * Returns the validity of the mutex. + */ + EAP_FUNC_IMPORT virtual bool get_is_valid() const = 0; + +#if defined(USE_EAPOL_MUTEX_SEMAPHORE_TRACES) + EAP_FUNC_IMPORT virtual eap_am_mutex_reference_c * get_reference() const = 0; + EAP_FUNC_IMPORT virtual void set_am_tools(abs_eap_am_tools_c * const tools) = 0; +#endif //#if defined(USE_EAPOL_MUTEX_SEMAPHORE_TRACES) + + // - - - - - - - - - - - - - - - - - - - - - - - - + +}; + +// --------------------------------------------- + +/// This class defines a reference counter of a mutex. +class EAP_EXPORT eap_am_mutex_reference_c +{ + +private: + + /// This is the reference count to the mutex. + u32_t m_reference_count; + + /// This flag indicates whether the mutex is reserved. + /// This is used in debug asserts. Those will check the mutex is really reserved when critical code is entered. + bool m_is_reserved; + + // On purpose unimplemented constructors. + eap_am_mutex_reference_c(eap_am_mutex_reference_c &source); + const eap_am_mutex_reference_c & operator=(const eap_am_mutex_reference_c& source); + +public: + + EAP_FUNC_IMPORT virtual ~eap_am_mutex_reference_c(); + + EAP_FUNC_IMPORT eap_am_mutex_reference_c(); + + /** + * This function adds one reference to the mutex. + */ + EAP_FUNC_IMPORT void add_reference(); + + /** + * This function removes one reference to the mutex. + */ + EAP_FUNC_IMPORT void remove_reference(); + + /** + * This function returns the reference count of the mutex. + */ + EAP_FUNC_IMPORT u32_t get_reference_count(); + + /** + * This function sets the flag that indicates whether the mutex is reserved. + */ + EAP_FUNC_IMPORT void set_is_reserved(const bool is_reserved); + + /** + * This function returns the flag that indicates whether the mutex is reserved. + * This is used in debug asserts. Those will check the mutex is really reserved when critical code is entered. + */ + EAP_FUNC_IMPORT bool get_is_reserved(); +}; + +// --------------------------------------------- + +/// This class is base of the mutex. +class EAP_EXPORT eap_am_mutex_base_c +{ +private: + + eap_am_mutex_reference_c * m_reference; + + bool m_is_valid; + + // On purpose unimplemented constructors. + eap_am_mutex_base_c(eap_am_mutex_base_c &source); + const eap_am_mutex_base_c & operator=(const eap_am_mutex_base_c& source); + +public: + + EAP_FUNC_IMPORT virtual ~eap_am_mutex_base_c(); + + EAP_FUNC_IMPORT eap_am_mutex_base_c(); + + EAP_FUNC_IMPORT eap_am_mutex_base_c(const eap_am_mutex_base_c * const owner); + + /** + * This function returns pointer to the reference counter object of the mutex. + */ + EAP_FUNC_IMPORT eap_am_mutex_reference_c * get_reference() const; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the flag that indicates whether the mutex is reserved. + * This is used in debug asserts. Those will check the mutex is really reserved when critical code is entered. + */ + EAP_FUNC_IMPORT bool get_is_reserved() const; + + /** + * Returns the validity of the mutex. + */ + EAP_FUNC_IMPORT bool get_is_valid() const; + + // - - - - - - - - - - - - - - - - - - - - - - - - + +}; + +// --------------------------------------------- + +#endif //#if !defined( _ABS_EAP_AM_MUTEX_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_radius.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_radius.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,119 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_AM_TYPE_RADIUS_H_) +#define _ABS_EAP_AM_TYPE_RADIUS_H_ + +#include "eap_am_export.h" +#include "eap_sim_triplets.h" +#include "eap_radius_types.h" + +/// This class declares the functions adaptation module of RADIUS EAP type +/// requires from the RADIUS EAP type. +class EAP_EXPORT abs_eap_am_radius_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eap_am_radius_c() + { + } + + // + abs_eap_am_radius_c() + { + } + + virtual bool get_is_client() = 0; + + /** Client adaptation module of RADIUS EAP type calls this function. + * AM gives IMSI and optional pseydonym to RADIUS EAP type. + * This function completes asyncronously query_SIM_IMSI_or_pseudonym_or_reauthentication_id() function call. + */ + virtual eap_status_e complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query( + const eap_variable_data_c * const IMSI, + const eap_variable_data_c * const pseudonym, + const eap_variable_data_c * const reauthentication_identity, + const eap_variable_data_c * const automatic_realm, ///< This could be zero pointer if this is not used. + const eap_radius_complete_e required_completion, + const u8_t received_eap_identifier, + const eap_status_e completion_status) = 0; + + +#if defined(USE_EAP_TYPE_SERVER_RADIUS) + /** Server adaptation module of RADIUS EAP type calls this function. + * AM give triplets to RADIUS EAP type. + * This function completes asyncronously query_SIM_triplets() function call. + */ + virtual eap_status_e complete_SIM_triplets( + eap_type_sim_triplet_array_c * const triplets, + const eap_variable_data_c * const IMSI, + const eap_radius_triplet_status_e triplet_status, + const eap_radius_identity_type type, + const eap_status_e completion_status) = 0; +#endif //#if defined(USE_EAP_TYPE_SERVER_RADIUS) + + + /** Client adaptation module of RADIUS EAP type calls this function. + * AM gives n RANDs, n Kcs and n SRESs to RADIUS EAP type. + * This function completes asyncronously query_SIM_kc_sres() function call. + */ + virtual eap_status_e complete_SIM_kc_sres( + const eap_variable_data_c * const n_rand, + const eap_variable_data_c * const n_kc, + const eap_variable_data_c * const n_sres, + const eap_status_e completion_status) = 0; + + +#if defined(USE_EAP_TYPE_SERVER_RADIUS) + /** Server adaptation module of RADIUS EAP type calls this function. + * AM gives IMSI and username to RADIUS EAP type. + * This function completes asyncronously query_imsi_from_username() function call. + */ + virtual eap_status_e complete_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + const eap_variable_data_c * const imsi, + const eap_radius_identity_type type, + const eap_status_e completion_status, + const eap_radius_complete_e completion_action) = 0; +#endif //#if defined(USE_EAP_TYPE_SERVER_RADIUS) + + + //-------------------------------------------------- +}; // class abs_eap_am_radius_c + +#endif //#if !defined(_ABS_EAP_AM_TYPE_RADIUS_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_semaphore.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_semaphore.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,137 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _ABS_EAP_AM_SEMAPHORE_H_ ) +#define _ABS_EAP_AM_SEMAPHORE_H_ + +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" + +class eap_am_semaphore_reference_c; + +// --------------------------------------------- + +/// This class is interface to semaphore. +class EAP_EXPORT abs_eap_am_semaphore_c +{ +private: + +public: + + EAP_FUNC_IMPORT virtual ~abs_eap_am_semaphore_c(); + + EAP_FUNC_IMPORT abs_eap_am_semaphore_c(); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function reserves the semaphore. Thread will block until the semaphore is released + * by other owner of the semaphore. + */ + EAP_FUNC_IMPORT virtual eap_status_e semaphore_reserve() = 0; + + /** + * This function releases the semaphore. Other blocking thread will continue execution. + */ + EAP_FUNC_IMPORT virtual eap_status_e semaphore_release() = 0; + + /** + * The semaphore handle must be dublicated in Symbian operating system for each thread. + */ + EAP_FUNC_IMPORT virtual abs_eap_am_semaphore_c * dublicate_semaphore() = 0; + + EAP_FUNC_IMPORT virtual u32_t get_count() const = 0; + + /** + * Returns the validity of the semaphore. + */ + EAP_FUNC_IMPORT virtual bool get_is_valid() const = 0; + +#if defined(USE_EAPOL_MUTEX_SEMAPHORE_TRACES) + EAP_FUNC_IMPORT virtual eap_am_semaphore_reference_c * get_reference() const = 0; + EAP_FUNC_IMPORT virtual void set_am_tools(abs_eap_am_tools_c * const tools) = 0; +#endif //#if defined(USE_EAPOL_MUTEX_SEMAPHORE_TRACES) + + // - - - - - - - - - - - - - - - - - - - - - - - - + +}; + +// --------------------------------------------- + +/// This class defines a reference counter of a semaphore. +class EAP_EXPORT eap_am_semaphore_reference_c +{ + +private: + + /// This is the reference count to the semaphore. + u32_t m_reference_count; + +public: + + EAP_FUNC_IMPORT virtual ~eap_am_semaphore_reference_c(); + + EAP_FUNC_IMPORT eap_am_semaphore_reference_c(); + + EAP_FUNC_IMPORT void add_reference(); + + EAP_FUNC_IMPORT void remove_reference(); + + EAP_FUNC_IMPORT u32_t get_reference_count(); +}; + +// --------------------------------------------- + +/// This class is base of the semaphore. +class EAP_EXPORT eap_am_semaphore_base_c +{ +private: + + eap_am_semaphore_reference_c * m_reference; + + bool m_is_valid; + +public: + + EAP_FUNC_IMPORT virtual ~eap_am_semaphore_base_c(); + + EAP_FUNC_IMPORT eap_am_semaphore_base_c(); + + EAP_FUNC_IMPORT eap_am_semaphore_base_c(const eap_am_semaphore_base_c * const owner); + + EAP_FUNC_IMPORT eap_am_semaphore_reference_c * get_reference() const; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns the validity of the semaphore. + EAP_FUNC_IMPORT bool get_is_valid() const; + + // - - - - - - - - - - - - - - - - - - - - - - - - + +}; + +// --------------------------------------------- + +#endif //#if !defined( _ABS_EAP_AM_SEMAPHORE_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_sim_algorithm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_sim_algorithm.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_SIM_ALGORITHM_H_) +#define _ABS_SIM_ALGORITHM_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "abs_eap_am_tools.h" +#include "eap_am_tools.h" +#include "eap_am_export.h" +#include "eap_sim_triplets.h" + +enum sim_algorithm_e +{ + sim_algorithm_none, + sim_algorithm_nokia_test_network_xor, + sim_algorithm_tls_prf_with_shared_secret, +}; + + +/// This class is implements Nokia test network SIM algorithm. +class EAP_EXPORT abs_eap_am_sim_algorithm_c +{ +private: + //-------------------------------------------------- + + virtual void set_is_valid() = 0; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eap_am_sim_algorithm_c(){}; + + virtual bool get_is_valid() = 0; + + virtual eap_status_e set_simulator_sim_ki(const eap_variable_data_c * const simulator_sim_ki) = 0; + + virtual eap_status_e generate_kc_sres( + const sim_algorithm_e sim_algorithm, + const u8_t * const rand, + const u32_t rand_length, + u8_t * const kc_sres, + const u32_t kc_sres_length) = 0; + + //-------------------------------------------------- +}; // class abs_eap_am_sim_algorithm_c + + +/** @file */ + +#endif //#if !defined(_ABS_SIM_ALGORITHM_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_tools.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_tools.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,838 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined( _ABS_EAP_AM_TOOLS_H_ ) +#define _ABS_EAP_AM_TOOLS_H_ + +#include "eap_am_types.h" +#include "eap_am_export.h" +#include "eap_status.h" +#include "abs_eap_base_timer.h" +//#include "eap_am_memory_store_data.h" + + +#if defined(EAP_LITTLE_ENDIAN) && defined(EAP_BIG_ENDIAN) +#error Do not define both EAP_LITTLE_ENDIAN and EAP_BIG_ENDIAN +#endif + +#if !defined(EAP_LITTLE_ENDIAN) && !defined(EAP_BIG_ENDIAN) +#error Do define either EAP_LITTLE_ENDIAN or EAP_BIG_ENDIAN +#endif + +class abs_eap_am_crypto_c; +class eap_variable_data_c; +class abs_eap_am_mutex_c; +class eap_buf_chain_wr_c; +class eap_configuration_field_c; +class eap_tlv_message_data_c; + +/// This class offers some services that are dependent of platform Y. +/** + * Current services are timer handling, crypto library, trace functions, + * memory manipulation and hardware tick counter. Use of eap_am_tools is through + * abstract virtual class abs_eap_am_tools. A pointer to the abs_eap_am_tools + * class is given to all other classes as a parameter to each constructor. + * Adaptation module creates the eap_am_tools_Y class before it initializes the stack. + * This prevents the need of global objects. + */ +class EAP_EXPORT abs_eap_am_tools_c +{ + +public: + + /** + * The destructor of the abs_eap_am_tools_c class does nothing special. + */ + virtual ~abs_eap_am_tools_c() + { + } + + /** + * The constructor of the abs_eap_am_tools_c does nothing special. + */ + abs_eap_am_tools_c() + { + } + + /** + * This function allocates platform specific tools object. + * Note this function calls also configure() of the allocated tools object. + * The platform specific module must implement this function. + */ + EAP_FUNC_IMPORT_INTERFACE static abs_eap_am_tools_c * new_abs_eap_am_tools_c(); + + /** + * This function deletes platform specific tools object. + * Note this function calls also shutdown() of the allocated tools object. + * The platform specific module must implement this function. + */ + EAP_FUNC_IMPORT_INTERFACE static void delete_abs_eap_am_tools_c(abs_eap_am_tools_c * const am_tools); + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + * Needed configuration depends on the implementation. + */ + virtual eap_status_e configure() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + /** + * Function converts unicode characters into UTF8 characters. + * @param dest is reference to destination utf8 variable data. + * @param src is refrence to unicode variable data. + * @return eap status code. + */ + virtual eap_status_e convert_unicode_to_utf8( + eap_variable_data_c & dest, + const eap_variable_data_c & src) = 0; + + /** + * Function converts UTF8 characters into unicode characters. + * @param dest is reference to destination unicode variable data. + * @param src is refrence to UTF8 variable data. + * @return eap status code. + */ + virtual eap_status_e convert_utf8_to_unicode( + eap_variable_data_c & dest, + const eap_variable_data_c & src) = 0; + + /** + * Function parses NAI to usename and realm. + * If either is missing the corresponding value will be invalid. + */ + virtual eap_status_e parse_nai( + const eap_variable_data_c * const nai, + eap_variable_data_c * const username, + eap_variable_data_c * const realm) = 0; + + /** + * Function converts one octet to ascii character. + * @param octet is the converted octet. + * @return acsii byte. + */ + virtual u8_t octet_to_ascii(i32_t octet) = 0; + + /** + * Function converts one ascii character to octet. + * @param character is the converted ascii character. + * @return octet. + */ + virtual u8_t ascii_to_octet(i32_t character) = 0; + + /** + * The memmove() function copies count bytes from src to dest. + * The implementation must handle overlapping memory areas correctly. + * Check always the destination is correct memory. + * This function is low level and cannot check the used memory. + * @param dest is pointer to the destination. + * @param src is pointer to the source. + * @param count indicates the count of copied bytes. + */ + virtual void memmove( + void *dest, + const void *src, + const u32_t count) = 0; + + /** + * The memcmp() function compares count bytes from buf1 and buf2. + * @return Returns zero when all count bytes are equal. + * @return Returns negative integer when buf1 contains smaller different byte. + * @return Returns positive integer when buf1 contains bigger different byte. + */ + virtual i32_t memcmp( + const void * const buf1, + const void * const buf2, + const u32_t count) = 0; + + /** + * The memset function sets the first count bytes of dest to the character fill_byte. + * Check always the destination is correct memory. + * This function is low level and cannot check the used memory. + * @param dest is pointer to the destination. + * @param fill_byte is the fill value. + * @param count indicates the count of set bytes. + */ + virtual void memset( + void * const dest, + const i32_t fill_byte, + const u32_t count) = 0; + + /** + * The memchr function searches the first occurence of character starting from buf. + * Maximum count bytes are searched. + */ + virtual void *memchr( + const void *buf, + u8_t character, + u32_t count) = 0; + + /** + * The memchr function searches the last occurence of character starting from the enf of the buf. + * Maximum count bytes are searched. + */ + virtual void *memrchr( + const void *buf, + u8_t character, + u32_t count) = 0; + + /** + * Get the length of a string. + * @return Function returns the number of characters in string, + * excluding the terminal NULL. No return value is reserved to indicate an error. + */ + virtual u32_t strlen( + eap_const_string string) = 0; + + /** + * Get the length of a string. + * @return Function returns the number of characters in string, + * excluding the terminal NULL. No return value is reserved to indicate an error. + */ + virtual u32_t config_strlen( + eap_config_string string) = 0; + + /** + * Function converts lovercase ascii characters to uppercase. + * @param source_bytes is pointer to the source bytes. + * @param source_bytes_length is length of source bytes. + */ + virtual eap_status_e convert_ascii_to_uppercase( + u8_t * const source_bytes, + const u32_t source_bytes_length) = 0; + /** + * Function converts bytes to hex ascii. + * @param source_bytes is pointer to the source bytes. + * @param source_bytes_length is length of source bytes. + * @param target is pointer to the target bytes. + * @param target_length is length of target bytes. + */ + virtual eap_status_e convert_bytes_to_hex_ascii( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length) = 0; + + /** + * Function converts bytes to hex ascii. + * @param source_bytes is pointer to the source bytes. + * @param source_bytes_length is length of source bytes. + * @param target is pointer to the target buffer. + */ + virtual eap_status_e convert_bytes_to_hex_ascii( + const void * const source_bytes, + const u32_t source_bytes_length, + eap_variable_data_c * const target) = 0; + + /** + * Function converts hex ascii to bytes. + * @param source_bytes is pointer to the source bytes. + * @param source_bytes_length is length of source bytes. + * @param target is pointer to the target bytes. + * @param target_length is length of target bytes. + */ + virtual eap_status_e convert_hex_ascii_to_bytes( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length) = 0; + + /** + * Function converts hex ascii to bytes. + * @param source_bytes is pointer to the source bytes. + * @param source_bytes_length is length of source bytes. + * @param target is pointer to the target bytes. + * @param target_length is length of target bytes. + */ + virtual eap_status_e convert_hex_ascii_to_bytes( + const void * const source_bytes, + const u32_t source_bytes_length, + eap_variable_data_c * const target) = 0; + + /** + * Function converts bytes to ascii armored bytes. + * @param source_bytes is pointer to the source bytes. + * @param source_bytes_length is length of source bytes. + * @param target is pointer to the target bytes. + * @param target_length is length of target bytes. + * @code + * Binary 6-bit blocks are converted to 8-bit ascii values. Ascii values can easily represent 2^6=64 values. + * If length of target array is not module 3, padding zero bits are ignored. + * + * |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5| + * | | | | | | + + * | | | | | | \ + * | | | | | + \ + * | | | | | \ \ + * | | | | + \ \ + * | | | | \ \ \ + * | | | + \ \ \ + * | | | \ \ \ \ + * | | + \ \ \ \ + * | | \ \ \ \ \ + * | + \ \ \ \ \ + * | \ \ \ \ \ \ + * | \ \ \ \ \ \ + * | + + + + + + + * | | | | | | | + * |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + virtual eap_status_e convert_bytes_to_ascii_armor( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length) = 0; + + /** + * Function converts ascii armored bytes to bytes. + * @param source_bytes is pointer to the source bytes. + * @param source_bytes_length is length of source bytes. + * @param target is pointer to the target bytes. + * @param target_length is length of target bytes. + * @code + * 8-bit ascii values are converted to binary 6-bit blocks. Ascii values can easily represent 2^6=64 values. + * If length of source array is not module 3, missing bits are padded with zero bits. + * + * |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : |0:0:0:0| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5| + * | | | | | | + + * | | | | | | \ + * | | | | | + \ + * | | | | | \ \ + * | | | | + \ \ + * | | | | \ \ \ + * | | | + \ \ \ + * | | | \ \ \ \ + * | | + \ \ \ \ + * | | \ \ \ \ \ + * | + \ \ \ \ \ + * | \ \ \ \ \ \ + * | \ \ \ \ \ \ + * | + + + + + + + * | | | | | | | + * |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + virtual eap_status_e restore_bytes_from_ascii_armor( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length) = 0; + + /** + * Gets the current trace mask. + */ + virtual u32_t get_trace_mask() const = 0; + + /** + * This function sets the current trace mask. + */ + virtual void set_trace_mask(const u32_t mask) = 0; + + /** + * This function sets the trace output file name. + */ + virtual eap_status_e set_trace_file_name(const eap_variable_data_c * const trace_output_file) = 0; + + /** + * This function sets the maximum size of trace output file in bytes. + * Note this is not absolute value. New file is generated when size of trace log file + * exceeds this limitation. + */ + virtual void set_max_trace_file_size(const u32_t max_trace_file_size) = 0; + + /** + * This functions allows activation of trace when the error occurs. + * Look at the set_activate_trace_on_error() and eap_status_return() + * functions. NOTE the always active traces are only left active. + * That means set_activate_trace_on_error() function calls + * set_trace_mask(eap_trace_mask_always). + */ + virtual void set_activate_trace_on_error() = 0; + + virtual void check_activate_trace_on_error() = 0; + + /** + * This function formats string to buffer. + * Function returns number of written bytes. + */ + virtual u32_t snprintf(u8_t * const buffer, u32_t buffer_size, eap_format_string format, ...) = 0; + + /** + * The formatted_print() function traces format string and formatted parameters to file. + * File is set as a parameter to constructor. This is used in macros + * EAP_TRACE_DEBUG(object_name, _parameter_list_) and + * EAP_TRACE_ERROR(object_name, _parameter_list_). + */ + virtual void formatted_print( + eap_format_string format, + ...) = 0; + + /** + * The trace_data() function traces null terminated prefix string + * and data_length bytes from p_data to file. This is used in macros + * EAP_TRACE_DATA_DEBUG(object_name, _parameter_list_) and + * EAP_TRACE_DATA_ERROR(object_name, _parameter_list_). + */ + virtual void trace_data( + eap_const_string prefix, + const void * const p_data, + const u32_t data_length) = 0; + + /** + * The get_crypto() function returns a pointer to object of type eap_am_crypto. + */ + virtual abs_eap_am_crypto_c * get_crypto() = 0; + + /** + * This function returns the current time and date in standard UNIX 32-bit format (seconds + * since the midnight starting Jan 1, 1970, GMT) according to the + * sender's internal clock. + */ + virtual u32_t get_gmt_unix_time() = 0; + + /** + * The get_hardware_ticks() function returns current value of hardware ticks counter. + */ + virtual u64_t get_hardware_ticks() = 0; + + /** + * Function returns count of hardware ticks in one second. + */ + virtual u64_t get_hardware_ticks_of_second() = 0; + + /** + * Function returns count of clock ticks in one second. + */ + virtual u64_t get_clock_ticks_of_second() = 0; + + /** + * Function returns current value of clock ticks counter. + */ + virtual u64_t get_clock_ticks() = 0; + + /** + * Returns true when timer queue is used. + * Returns false when timer queue is not used. + */ + virtual bool get_use_timer_queue() = 0; + + /** + * Returns true when timer thread is stopped. + * Returns false when timer thread is running. + */ + virtual bool get_thread_stopped() = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * + * Adaptation module of tools includes internal attribute eap_timer_queue_c to + * which this call is directed. + */ + virtual eap_status_e am_set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * + * Adaptation module of tools includes internal attribute eap_timer_queue_c to + * which this call is directed. + */ + virtual eap_status_e am_cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * + * Adaptation module of tools includes internal attribute eap_timer_queue_c to + * which this call is directed. + * + * This function de-activated timer queue. + * You could re-activate timer queue with re_activate_timer_queue function. + */ + virtual eap_status_e am_cancel_all_timers() = 0; + + /** + * This function re-activates timer queue. + * Symbian AM call this function when AM-tools object is re-used. + * This can be called after am_cancel_all_timers() function. + * am_cancel_all_timers() function de-activated timer queue. + */ + virtual eap_status_e re_activate_timer_queue() = 0; + + /** + * This function sets the resolution of the timer. + * The default value is EAP_TIMER_RESOLUTION. + * Each pulse increases time by this value. + * + * Adaptation module of tools includes internal attribute eap_timer_queue_c to + * which this call is directed. + */ + virtual void set_timer_resolution_ms(const u32_t timer_resolution_ms) = 0; + + /** + * This function returns the resolution of the timer. + * Each pulse increases time by this value. + * + * Adaptation module of tools includes internal attribute eap_timer_queue_c to + * which this call is directed. + */ + virtual u32_t get_timer_resolution_ms() = 0; + + /** + * Pulses timer. Time is increased by get_timer_resolution_ms() milli seconds. + * Timer pulse is run parallel to the stack operation. + * This causes the use of global mutex. + * + * Adaptation module of tools includes internal attribute eap_timer_queue_c to + * which this call is directed. + * Function returns the next sleep time in milli seconds. + */ + virtual u32_t pulse_timer(const u32_t elapsed_time_in_ms) = 0; + + /** + * This function checks whether the internal timer queue is empty. + */ + virtual bool get_timer_queue_is_empty() = 0; + + /** + * Starts the thread to pulse timer. + * User of tools should call this after the stack is created. + */ + virtual eap_status_e start_timer_thread() = 0; + + /** + * Stops the timer thread. + * User of tools should call this before the stack is deleted. + */ + virtual eap_status_e stop_timer_thread() = 0; + + /** + * Function runs the timer thread loop. This function calls the pulse_timer() + * function to increase the elapsed time. + */ + virtual eap_status_e timer_thread_function() = 0; + + /** + * Returns the value of timer thread activity. + * Timer thread stops when this functions returns false. + */ + virtual bool get_is_timer_thread_active() = 0; + + /** + * This function enters the global mutex. Mutex is needed to synchronize + * the timer thread and stack call operations. + * Timer pulse is run parallel to the stack operation. + * This causes the use of global mutex. + */ + virtual void enter_global_mutex() = 0; + + /** + * This function leaves the global mutex. + * Timer pulse is run parallel to the stack operation. + * This causes the use of global mutex. + */ + virtual void leave_global_mutex() = 0; + + /** + * Returns the global mutex. This is used in some assertion tests. + */ + virtual abs_eap_am_mutex_c * get_global_mutex() = 0; + + #define ENTER_CRYPTO() + #define LEAVE_CRYPTO() + + /** + * The timer_sleep function suspends the execution of the current timer thread for the specified interval. + * Timer could be set any value. When timer is set to shorter timeout than the smallest current + * timeout is the timer_sleep() will cancel sleep and the new sleep time could be calculated. + * @param milli_seconds is the suspension time in milli seconds. + */ + virtual void timer_sleep(u32_t milli_seconds) = 0; + + /** + * The sleep function suspends the execution of the current thread for the specified interval. + * @param milli_seconds is the suspension time in milli seconds. + */ + virtual void sleep(u32_t milli_seconds) = 0; + + /** + * The get_is_valid() function returns the status of the object. + * True indicates the object is initialized succesfully. + */ + virtual bool get_is_valid() const = 0; + +#if (defined(DMALLOC) || defined(USE_EAP_CRYPTO_MEMORY_LEAK_FUNCTIONS)) && !defined(USE_EAP_LOCAL_TRACE_FILE_OPEN) + virtual const EAP_FILE_POINTER * get_trace_file() = 0; +#endif //#if defined(DMALLOC) && !defined(USE_EAP_LOCAL_TRACE_FILE_OPEN) + + /// This function is global proxy for return values. + virtual eap_status_e eap_status_return( + const bool print_error_when_true, + const eap_status_e status, + const eap_char * const file_name, + const i32_t line_number) = 0; + + /// This function is global proxy for return values with file name and line number. + /// This is used in traces. + virtual eap_status_e eap_status_return_file_number( + const bool print_error_when_true, + const eap_status_e status, + const u32_t file_date, + const u32_t file_number, + const i32_t line_number) = 0; + + /// Memory store is visible only during the eap_am_tools_c object is alive. + /// This function add flat data to memory store. + /// You must format your data to eap_tlv_message_data_c object. + /// Data is identified by key parameter. + /// You can set timeout to data. Data will be automatically removed after timeout. + /// Timeout value zero means no timeout is set. + /// Serious WARNING: do use really good key values. + /// Memory store is globally used by all EAP Core objects. + /// Key must be good that other users do not use others data. + /// Add the real data type as a string to the key and other identifiers + /// that separate data between the other users that store same data type + /// to the memory store. + virtual eap_status_e memory_store_add_data( + const eap_variable_data_c * const key, + eap_tlv_message_data_c * const data, + const u32_t timeout) = 0; + + /// Memory store is visible only during the eap_am_tools_c object is alive. + /// This function gets data from memory store. + /// Data is returned in eap_tlv_message_data_c object. + /// Data is identified by key parameter. + /// Serious WARNING: do use really good key values. + /// Memory store is globally used by all EAP Core objects. + /// Key must be good that other users do not use others data. + /// Add the real data type as a string to the key and other identifiers + /// that separate data between the other users that store same data type + /// to the memory store. + virtual eap_status_e memory_store_get_data( + const eap_variable_data_c * const key, + eap_tlv_message_data_c * const data) = 0; + + + /// Memory store is visible only during the eap_am_tools_c object is alive. + /// This function removes data from memory store. + /// Data is identified by key parameter. + /// Serious WARNING: do use really good key values. + /// Memory store is globally used by all EAP Core objects. + /// Key must be good that other users do not use others data. + /// Add the real data type as a string to the key and other identifiers + /// that separate data between the other users that store same data type + /// to the memory store. + virtual eap_status_e memory_store_remove_data( + const eap_variable_data_c * const key) = 0; + + + +#if defined(USE_EAP_ERROR_TESTS) + /** + * This function generates random error to message. + * This is used in protocol testing. + */ + virtual eap_status_e generate_random_error( + eap_buf_chain_wr_c * const sent_packet, + const bool forse_error, + const u32_t packet_index, + const u32_t minimum_index, + const u32_t error_probability, + const u32_t minimum_packet_length) = 0; + + /** + * This function returns index of message. + * This is used in protocol testing. + */ + virtual u32_t get_packet_index() = 0; + + /** + * This function increases index of message. + * This is used in protocol testing. + */ + virtual void increase_packet_index() = 0; +#endif //#if defined(USE_EAP_ERROR_TESTS) + + + /** + * Function converts AM error value to eap_status_e. + * @param am_error_value is the AM error value. + */ + virtual eap_status_e convert_am_error_to_eapol_error(const i32_t am_error_value) = 0; + + /** + * Function converts eap_status_e to AM error value. + * @param eap_error is the eap_status_e error value. + */ + virtual i32_t convert_eapol_error_to_am_error(eap_status_e eap_error) = 0; + + /** + * This function returns true when milli second timer is used. + */ + virtual bool get_use_eap_milli_second_timer() = 0; + + /** + * This function sets the flag whether to use milli second timer (true) or not (false). + */ + virtual void set_use_eap_milli_second_timer( + const bool use_eap_millisecond_timer) = 0; + + /** + * This function reads value of environment variable. + * Note the all environments does not support this, for example Symbian. + */ + virtual eap_status_e getenv( + const eap_variable_data_c * const environment_variable_name, + eap_variable_data_c * const environment_variable_value) = 0; + + /** + * This function converts string to u32_t value. + */ + virtual eap_status_e number_string_to_u32( + const u8_t * const number_string, + const u32_t number_string_length, + u32_t * const integer) = 0; + + /** + * This function checks whether the character is space. + */ + virtual bool isspace(const u8_t character) = 0; + + /** + * This function traces read configure field and data. + */ + virtual void trace_configuration( + const eap_status_e configuration_read_status, + const eap_configuration_field_c * const field, + const eap_variable_data_c * const data) = 0; + + /** + * This function converts u64_t to u64_struct type. + * This is used in some 64-bit calculations. + */ + virtual u64_struct u64_t_to_u64_struct(const u64_t value) = 0; + + /** + * This function converts u64_struct to u64_t type. + * This is used in some 64-bit calculations. + */ + virtual u64_t u64_struct_to_u64_t(const u64_struct value) = 0; + + /** + * This function xors two 64-bit integers. + */ + virtual u64_t xor_u64(const u64_t a, const u64_t b) = 0; + + /** + * This function multiplys two 64-bit integers. + * Returned value is remainder of 2^64, so overflow is not detected. + */ + virtual u64_t multiply_u64(const u64_t a, const u64_t b) = 0; + + /** + * This function compares two 64-bit integers. + * If a is bigger function returns positive integer. + * If b is bigger function returns negative integer. + * If a == b function returns zero integer. + */ + virtual i32_t compare_u64(const u64_t a, const u64_t b) = 0; + + /** + * The create_uuid_v5() method creates an UUID version 5 (SHA-1) from the + * name space UUID and name (RFC 4122). The name space UUID should be in + * hex format (e.g. 3d813cbb47fb52ba91df831e1593ac29). The name space UUID + * and name must be in network byte order (little endiann). + * + * @param ns_uuid pointer to the UUID of the name space in hex format. + * @param ns_uuid_length lenght of the name space UUID in bytes (should be 16 bytes). + * @param name pointer to the name (e.g. MAC address) in the name space in hex format. + * @param name_length length of the name in bytes. + * @param uuid pointer to an eap_variable_data_c instance to + * which the UUID will be created. + * @return status status code: eap_status_ok when successful, + * otherwise an error code. + */ + virtual eap_status_e create_uuid_v5( + const void* const ns_uuid, + const u32_t ns_uuid_length, + const void* const name, + const u32_t name_length, + eap_variable_data_c* const uuid ) = 0; + + /** + * The create_uuid_v5_from_mac_address() method creates an UUID version 5 + * from a MAC address. Uses an internally defined, fixed name space UUID + * allocated for EAP MAC addresses. The MAC address should be in + * hex format (little endiann). + * + * @param mac_address pointer to the MAC address in hex format. + * @param mac_address_length length of the MAC address (should be 6 bytes). + * @param uuid pointer to an eap_variable_data_c instance to + * which the UUID will be created. + * @return status status code: eap_status_ok when successful, + * otherwise an error code. + */ + virtual eap_status_e create_uuid_v5_from_mac_address( + const u8_t* const mac_address, + const u32_t mac_address_length, + eap_variable_data_c* const uuid ) = 0; + +}; + + +#endif //#if !defined( _ABS_EAP_AM_TOOLS_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_aka.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_aka.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,119 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_AM_TYPE_AKA_H_) +#define _ABS_EAP_AM_TYPE_AKA_H_ + +#include "eap_am_export.h" +#include "eap_type_aka_authentication_vector.h" +#include "eap_type_aka_types.h" + +/// This class declares the functions adaptation module of AKA EAP type +/// requires from the AKA EAP type. +class EAP_EXPORT abs_eap_am_type_aka_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eap_am_type_aka_c() + { + } + + // + abs_eap_am_type_aka_c() + { + } + + virtual bool get_is_client() = 0; + + /** Client adaptation module of AKA EAP type calls this function. + * AM gives IMSI and optional pseydonym to AKA EAP type. + * This function completes asyncronously query_AKA_IMSI_or_pseudonym_or_reauthentication_id() function call. + */ + virtual eap_status_e complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query( + const eap_variable_data_c * const IMSI, + const eap_variable_data_c * const pseudonym, + const eap_variable_data_c * const reauthentication_identity, + const eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + const u32_t length_of_mnc, + const eap_type_aka_complete_e required_completion, + const u8_t received_eap_identifier, + const eap_status_e completion_status) = 0; + + /** Server adaptation module of AKA EAP type calls this function. + * AM give triplets to AKA EAP type. + * This function completes asyncronously query_AKA_authentication_vector() function call. + */ + virtual eap_status_e complete_AKA_authentication_vector_query( + eap_type_aka_authentication_vector_c * const authentication_vector, + const eap_variable_data_c * const IMSI, + const eap_aka_authentication_vector_status_e authentication_vector_status, + const eap_type_aka_identity_type type, + const eap_status_e completion_status, + const u8_t next_eap_identifier) = 0; + + /** Client adaptation module of AKA EAP type calls this function. + * AM gives n RANDs, n Kcs and n SRESs to AKA EAP type. + * This function completes asyncronously query_AKA_RES() function call. + */ + virtual eap_status_e complete_AKA_RES_query( + const eap_type_aka_authentication_vector_c * const authentication_vector, + const eap_status_e completion_status) = 0; + + /** Server adaptation module of AKA EAP type calls this function. + * AM gives IMSI and username to AKA EAP type. + * This function completes asyncronously query_imsi_from_username() function call. + */ + virtual eap_status_e complete_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + const eap_variable_data_c * const imsi, + const eap_type_aka_identity_type type, + const eap_status_e completion_status, + const eap_type_aka_complete_e completion_action) = 0; + + /** Server adaptation module of AKA EAP type calls this function. + * AM gives new authentication vector to AKA EAP type. + * This function completes asyncronously query_re_syncronization() function call. + */ + virtual eap_status_e complete_re_syncronization_query( + const u8_t next_eap_identifier, + const eap_type_aka_authentication_vector_c * const authentication_vector) = 0; + + //-------------------------------------------------- +}; // class abs_eap_am_type_aka_c + +#endif //#if !defined(_ABS_EAP_AM_TYPE_AKA_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_gsmsim.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_gsmsim.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,120 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_AM_TYPE_GSMSIM_H_) +#define _ABS_EAP_AM_TYPE_GSMSIM_H_ + +#include "eap_am_export.h" +#include "eap_sim_triplets.h" +#include "eap_type_gsmsim_types.h" + +/// This class declares the functions adaptation module of GSMSIM EAP type +/// requires from the GSMSIM EAP type. +class EAP_EXPORT abs_eap_am_type_gsmsim_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eap_am_type_gsmsim_c() + { + } + + // + abs_eap_am_type_gsmsim_c() + { + } + + virtual bool get_is_client() = 0; + + /** Client adaptation module of GSMSIM EAP type calls this function. + * AM gives IMSI and optional pseydonym to GSMSIM EAP type. + * This function completes asyncronously query_SIM_IMSI_or_pseudonym_or_reauthentication_id() function call. + */ + virtual eap_status_e complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query( + const eap_variable_data_c * const IMSI, + const eap_variable_data_c * const pseudonym, + const eap_variable_data_c * const reauthentication_identity, + const eap_variable_data_c * const automatic_realm, ///< This could be zero pointer if this is not used. + const u32_t length_of_mnc, + const eap_type_gsmsim_complete_e required_completion, + const u8_t received_eap_identifier, + const eap_status_e completion_status) = 0; + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** Server adaptation module of GSMSIM EAP type calls this function. + * AM give triplets to GSMSIM EAP type. + * This function completes asyncronously query_SIM_triplets() function call. + */ + virtual eap_status_e complete_SIM_triplets( + eap_type_sim_triplet_array_c * const triplets, + const eap_variable_data_c * const IMSI, + const eap_gsmsim_triplet_status_e triplet_status, + const eap_type_gsmsim_identity_type type, + const eap_status_e completion_status) = 0; +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + /** Client adaptation module of GSMSIM EAP type calls this function. + * AM gives n RANDs, n Kcs and n SRESs to GSMSIM EAP type. + * This function completes asyncronously query_SIM_kc_sres() function call. + */ + virtual eap_status_e complete_SIM_kc_sres( + const eap_variable_data_c * const n_rand, + const eap_variable_data_c * const n_kc, + const eap_variable_data_c * const n_sres, + const eap_status_e completion_status) = 0; + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** Server adaptation module of GSMSIM EAP type calls this function. + * AM gives IMSI and username to GSMSIM EAP type. + * This function completes asyncronously query_imsi_from_username() function call. + */ + virtual eap_status_e complete_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + const eap_variable_data_c * const imsi, + const eap_type_gsmsim_identity_type type, + const eap_status_e completion_status, + const eap_type_gsmsim_complete_e completion_action) = 0; +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + //-------------------------------------------------- +}; // class abs_eap_am_type_gsmsim_c + +#endif //#if !defined(_ABS_EAP_AM_TYPE_GSMSIM_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_leap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_leap.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef ABS_EAP_AM_TYPE_LEAP_H +#define ABS_EAP_AM_TYPE_LEAP_H + +// INCLUDES +#include "eap_type_leap_types.h" + +// CLASS DECLARATION + +/// This class declares the functions adaptation module of LEAP type +/// requires from the LEAP EAP type. +class EAP_EXPORT abs_eap_am_type_leap_c +{ +private: + +protected: + +public: + + virtual ~abs_eap_am_type_leap_c() + { + } + + abs_eap_am_type_leap_c() + { + } + + virtual bool get_is_client() = 0; + + virtual eap_status_e complete_eap_identity_query() = 0; + + virtual eap_status_e client_complete_challenge_request() = 0; + + virtual eap_status_e finish_unsuccessful_authentication( + const bool authentication_cancelled) = 0; + +}; // class abs_eap_am_type_leap_c + +#endif // ABS_EAP_AM_TYPE_LEAP_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_mschapv2.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_mschapv2.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_AM_TYPE_MSCHAPV2_H_) +#define _ABS_EAP_AM_TYPE_MSCHAPV2_H_ + +#include "eap_type_mschapv2_types.h" + +/// This class declares the functions adaptation module of GSMSIM MSCHAPv2 type +/// requires from the MSCHAPv2 EAP type. +class EAP_EXPORT abs_eap_am_type_mschapv2_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eap_am_type_mschapv2_c() + { + } + + // + abs_eap_am_type_mschapv2_c() + { + } + + virtual bool get_is_client() = 0; + + virtual eap_status_e complete_eap_identity_query() = 0; + + virtual eap_status_e complete_failure_retry_response() = 0; + + virtual eap_status_e complete_change_password_query() = 0; + + virtual eap_status_e send_success_failure_response(bool is_success_response) = 0; + + virtual eap_status_e finish_unsuccessful_authentication( + const bool authentication_cancelled) = 0; + + //-------------------------------------------------- +}; // class abs_eap_am_type_mschapv2_c + +#endif //#if !defined(_ABS_EAP_AM_TYPE_MSCHAPV2_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_securid.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_securid.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#ifndef ABS_EAP_AM_TYPE_SECURID_H +#define ABS_EAP_AM_TYPE_SECURID_H + +#include "eap_status.h" + +/// This class declares the functions adaptation module of GSMSIM MSCHAPv2 type +/// requires from the MSCHAPv2 EAP type. +class EAP_EXPORT abs_eap_am_type_securid_c +{ +private: + +protected: + +public: + + virtual ~abs_eap_am_type_securid_c() + { + } + + abs_eap_am_type_securid_c() + { + } + + virtual bool get_is_client() = 0; + + virtual eap_status_e complete_eap_identity_query( + const eap_variable_data_c * const identity_utf8) = 0; + + virtual eap_status_e client_securid_complete_passcode_query( + const eap_variable_data_c * const passcode_utf8) = 0; + + virtual eap_status_e client_securid_complete_pincode_query( + const eap_variable_data_c * const pincode, + const eap_variable_data_c * const passcode) = 0; + + virtual eap_status_e client_gtc_complete_user_input_query( + const eap_variable_data_c * const response_utf8) = 0; + + virtual eap_status_e finish_unsuccessful_authentication( + const bool authentication_cancelled) = 0; + +}; // class abs_eap_am_type_securid_c + +#endif // ABS_EAP_AM_TYPE_SECURID_H diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_sim.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_sim.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_AM_TYPE_SIM_H_) +#define _ABS_EAP_AM_TYPE_SIM_H_ + +#include "eap_am_export.h" +#include "eap_sim_triplets.h" + +// +class EAP_EXPORT abs_eap_am_type_sim_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eap_am_type_sim_c() + { + } + + // + abs_eap_am_type_sim_c() + { + } + + virtual eap_status_e complete_SIM_triplets( + eap_type_sim_triplet_array_c * const triplets) = 0; + + virtual eap_status_e complete_SIM_kc_sres( + const eap_variable_data_c * const n_rand, + const eap_variable_data_c * const n_kc, + const eap_variable_data_c * const n_sres) = 0; + + + //-------------------------------------------------- +}; // class abs_eap_am_type_sim_c + +#endif //#if !defined(_ABS_EAP_AM_TYPE_SIM_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_simple_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_simple_config.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_AM_TYPE_SIMPLE_CONFIG_H_) +#define _ABS_EAP_AM_TYPE_SIMPLE_CONFIG_H_ + +#include "eap_am_export.h" + +class eap_am_network_id_c; + + +/// This class declares the functions adaptation module of EAP-SIMPLE_CONFIG type +/// requires from the EAP-SIMPLE_CONFIG type. +class EAP_EXPORT abs_eap_am_type_simple_config_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eap_am_type_simple_config_c() + { + } + + // + abs_eap_am_type_simple_config_c() + { + } + + virtual bool get_is_client() = 0; + + /** Client adaptation module of EAP-SIMPLE_CONFIG type calls this function. + * AM gives identity to EAP-SIMPLE_CONFIG type. + * This function completes asyncronously query_eap_identity() function call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_eap_identity_query( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const eap_status_e completion_status, + const bool use_manual_username, + const eap_variable_data_c * const manual_username, + const bool use_manual_realm, + const eap_variable_data_c * const manual_realm + ) = 0; + + + //-------------------------------------------------- +}; // class abs_eap_am_type_simple_config_c + +#endif //#if !defined(_ABS_EAP_AM_TYPE_SIMPLE_CONFIG_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_tls_peap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_type_tls_peap.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_AM_TYPE_TLS_PEAP_H_) +#define _ABS_EAP_AM_TYPE_TLS_PEAP_H_ + +#include "eap_am_export.h" + +class eap_am_network_id_c; + + +/// This class declares the functions adaptation module of EAP-TLS/PEAP EAP type +/// requires from the EAP-TLS/PEAP EAP type. +class EAP_EXPORT abs_eap_am_type_tls_peap_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eap_am_type_tls_peap_c() + { + } + + // + abs_eap_am_type_tls_peap_c() + { + } + + virtual bool get_is_client() = 0; + + /** Client adaptation module of EAP-TLS/PEAP type calls this function. + * AM gives identity to EAP-TLS/PEAP type. + * This function completes asyncronously query_eap_identity() function call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_eap_identity_query( + const eap_variable_data_c * const user_certificate_identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const eap_status_e completion_status, + const bool use_manual_username, + const eap_variable_data_c * const manual_username, + const bool use_manual_realm, + const eap_variable_data_c * const manual_realm + ) = 0; + + + //-------------------------------------------------- +}; // class abs_eap_am_type_tls_peap_c + +#endif //#if !defined(_ABS_EAP_AM_TYPE_TLS_PEAP_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eap_am_wimax_authentication.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eap_am_wimax_authentication.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP stack interface for Wimax. +* +*/ + + +#if !defined(_ABS_EAP_AM_WIMAX_AUTHENTICATION_H_) +#define _ABS_EAP_AM_WIMAX_AUTHENTICATION_H_ + +#include +#include + + +class EAP_EXPORT abs_eap_am_wimax_authentication_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eap_am_wimax_authentication_c() + { + } + + // + abs_eap_am_wimax_authentication_c() + { + } + + //-------------------------------------------------- +}; // class abs_eap_am_wimax_authentication_c + +#endif //#if !defined(_ABS_EAP_AM_WIMAX_AUTHENTICATION_H_) + +//-------------------------------------------------- + + + +// End. + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_eapol_am_wlan_authentication.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_eapol_am_wlan_authentication.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAPOL_AM_WLAN_AUTHENTICATION_H_) +#define _ABS_EAPOL_AM_WLAN_AUTHENTICATION_H_ + +#include "eap_am_export.h" +#include "eapol_key_types.h" + +/// This class declares the functions adaptation module of GSMSIM EAP type +/// requires from the GSMSIM EAP type. +class EAP_EXPORT abs_eapol_am_wlan_authentication_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eapol_am_wlan_authentication_c() + { + } + + // + abs_eapol_am_wlan_authentication_c() + { + } + + /** + * This function disassociates the connection. + */ + virtual eap_status_e disassociation( + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ) = 0; + + /** + * This function gets the current active eap index. + */ + virtual u32_t get_current_eap_index() = 0; + + /** + * This function sets the current active eap index. + */ + virtual void set_current_eap_index(u32_t eap_index) = 0; + + /** + * This function indicates the state of WLAN authentication. + */ + virtual eap_status_e eapol_indication( + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + const eapol_wlan_authentication_state_e wlan_authentication_state) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. EAP-type MUST send these + * two notifications to lower layer. + * These two notifications are sent using EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + * See also eap_state_notification_c. + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + //-------------------------------------------------- +}; // class abs_eapol_am_wlan_authentication_c + +#endif //#if !defined(_ABS_EAPOL_AM_WLAN_AUTHENTICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_simple_config_am_services.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_simple_config_am_services.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_SIMPLE_CONFIG_AM_SERVICES_H_) +#define _ABS_SIMPLE_CONFIG_AM_SERVICES_H_ + +#include "eap_am_export.h" +#include "eap_array.h" + +class simple_config_payloads_c; + +/// This class declares the functions adaptation module of SIMPLE_CONFIG +/// requires from the SIMPLE_CONFIG. +class EAP_EXPORT abs_simple_config_am_services_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing. + virtual ~abs_simple_config_am_services_c() + { + } + + /// Constructor does nothing. + abs_simple_config_am_services_c() + { + } + + // This is commented in eap_base_type_c::configure(). + virtual eap_status_e configure() = 0; + + + /** + * This function completes the asyncronous + * simple_config_am_services_c::query_network_and_device_parameters() function call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_query_network_and_device_parameters( + const simple_config_state_e state, + simple_config_payloads_c * const network_and_device_parameters, + const eap_status_e completion_status) = 0; + + + //-------------------------------------------------- +}; // class abs_simple_config_am_services_c + +#endif //#if !defined(_ABS_SIMPLE_CONFIG_AM_SERVICES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_tls_am_application_eap_fast.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_tls_am_application_eap_fast.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_TLS_AM_APPLICATION_EAP_FAST_H_) +#define _ABS_TLS_AM_APPLICATION_EAP_FAST_H_ + +#if defined(USE_FAST_EAP_TYPE) + +#include "eap_am_export.h" +#include "eap_array.h" + +#if defined(USE_EAP_TLS_SESSION_TICKET) +class tls_extension_c; +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +/// This class declares the functions adaptation module of TLS +/// requires from the TLS. +class EAP_EXPORT abs_tls_am_application_eap_fast_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing. + virtual ~abs_tls_am_application_eap_fast_c() + { + } + + /// Constructor does nothing. + abs_tls_am_application_eap_fast_c() + { + } + + /** + * This function call completes initialize_PAC_store() function call. + * After all imported PAC files are handled, AM must call this function. + * EAP-FAST authentication will continue within this function call. + */ + virtual eap_status_e complete_initialize_PAC_store( + const eap_fast_completion_operation_e completion_operation, + const eap_fast_initialize_pac_store_completion_e completion) = 0; + + /** + * This function call completes query_pac_of_type() function call. + * This function is used in test server. + */ + virtual eap_status_e complete_query_pac_of_type( + const eap_fast_variable_data_c * const pac_tlv, + const eap_fast_pac_type_e pac_type) = 0; + + /** + * This function call completes verify_pac() function call. + * This function is used in test server. + */ + virtual eap_status_e complete_verify_pac( + const eap_status_e verification_status, + const eap_fast_pac_type_e pac_type) = 0; + + /** + * This function call removes cached PAC store data. + */ + virtual eap_status_e remove_cached_pac_store_data() = 0; + + // This is commented in eap_fast_pac_store_c::add_imported_PAC_file(). + virtual eap_status_e add_imported_PAC_file( + const eap_variable_data_c * const in_IAP_reference, + const eap_fast_pac_store_data_c * const in_opt_group_reference_and_data, + const eap_variable_data_c * const in_imported_PAC_data, + const eap_variable_data_c * const in_imported_PAC_filename) = 0; + + // This is commented in eap_fast_pac_store_c::remove_IAP_reference(). + virtual eap_status_e remove_IAP_reference( + const eap_variable_data_c * const in_IAP_reference, + const eap_fast_pac_store_data_c * const in_opt_group_reference_and_data) = 0; + + + // This is commented in eap_fast_pac_store_c::complete_query_user_permission_for_A_ID(). + virtual eap_status_e complete_query_user_permission_for_A_ID( + const eap_status_e in_completion_status, + const eap_fast_pac_store_pending_operation_e in_pending_operation) = 0; + + // This is commented in eap_fast_pac_store_c::complete_read_PAC_store_data(). + virtual eap_status_e complete_read_PAC_store_data( + const eap_status_e in_completion_status, + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references_and_data_blocks) = 0; + + // This is commented in eap_fast_pac_store_c::complete_write_PAC_store_data(). + virtual eap_status_e complete_write_PAC_store_data( + const eap_status_e in_completion_status, + const eap_fast_pac_store_pending_operation_e in_pending_operation) = 0; + + //-------------------------------------------------- +}; // class abs_tls_am_application_eap_fast_c + +#endif //#if defined(USE_FAST_EAP_TYPE) + +#endif //#if !defined(_ABS_TLS_AM_APPLICATION_EAP_FAST_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/abs_tls_am_services.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/abs_tls_am_services.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,220 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_TLS_AM_SERVICES_H_) +#define _ABS_TLS_AM_SERVICES_H_ + +#include "eap_am_export.h" +#include "eap_array.h" + +#if defined(USE_EAP_TLS_SESSION_TICKET) +class tls_extension_c; +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +/// This class declares the functions adaptation module of TLS +/// requires from the TLS. +class EAP_EXPORT abs_tls_am_services_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing. + virtual ~abs_tls_am_services_c() + { + } + + /// Constructor does nothing. + abs_tls_am_services_c() + { + } + + // This is commented in eap_base_type_c::configure(). + virtual eap_status_e configure() = 0; + + /** + * This function completes the asyncronous + * tls_am_services_c::query_cipher_suites_and_previous_session() function call. + * The list of cipher suites and the list of compression methods are saved. + * All pending actions are checked and completed during this call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_query_cipher_suites_and_previous_session( + const tls_session_type_e session_type, + EAP_TEMPLATE_CONST eap_array_c * const cipher_suites, + EAP_TEMPLATE_CONST eap_array_c * const compression_methods, +#if defined(USE_EAP_TLS_SESSION_TICKET) + EAP_TEMPLATE_CONST eap_array_c * const tls_extensions, +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + const eap_variable_data_c * const resumed_session_id, + const eap_variable_data_c * const resumed_master_secret, + const tls_cipher_suites_e resumed_cipher_suite, + const eap_status_e completion_status) = 0; + + /** + * This function completes the asyncronous + * tls_am_services_c::select_cipher_suite_and_check_session_id() function call. + * The cipher suite, the session id and master secret are saved. + * NOTE the the session id and master secret are optional. + * Adaptation module can make independent + * decision to restore previous session or not. The selected cipher suite must be the same as + * was used in resumed session. The resumed cipher suite must be read from database. + * All pending actions are checked and completed during this call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_select_cipher_suite_and_check_session_id( + const tls_session_type_e session_type, + const u16_t selected_cipher_suite, + const eap_variable_data_c * const resumed_session_id, + const eap_variable_data_c * const resumed_master_secret, +#if defined(USE_EAP_TLS_SESSION_TICKET) + const tls_extension_c * const new_session_ticket_or_null, +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + const eap_status_e completion_status) = 0; + +#if defined(USE_EAP_TLS_SESSION_TICKET) + /** + * This function completes the asyncronous + * tls_am_services_c::query_new_session_ticket() function call. + * The parameter new_session_ticket_or_null is pointer to the + * new session ticket or null if new session ticket is omitted. + */ + virtual eap_status_e complete_query_new_session_ticket( + const tls_extension_c * const new_session_ticket_or_null) = 0; +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + + /** + * This function completes the tls_am_services_c::asyncronous verify_certificate_chain() + * function call. + * The parameter result must be eap_status_ok when certificate chain is valid. + * All pending actions are checked and completed during this call. + */ + virtual eap_status_e complete_verify_certificate_chain( + const eap_status_e result) = 0; + + /** + * This function completes the tls_am_services_c::asyncronous + * query_certificate_chain() function call. + * The parameter certificate_chain is saved. + * All pending actions are checked and completed during this call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_query_certificate_chain( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain, + const eap_status_e completion_status) = 0; + + /** + * This function completes the tls_am_services_c::asyncronous + * query_certificate_authorities_and_types() function call. + * The parameters authorities and types are saved. + * All pending actions are checked and completed during this call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_query_certificate_authorities_and_types( + EAP_TEMPLATE_CONST eap_array_c * const authorities, + EAP_TEMPLATE_CONST eap_array_c * const types, + const eap_status_e completion_status) = 0; + + /** + * This function completes the tls_am_services_c::asyncronous query_dh_parameters() + * function call. + * The parameter dhe_prime and dhe_group_generator are saved. + * All pending actions are checked and completed during this call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_query_dh_parameters( + const eap_variable_data_c * const dh_prime, + const eap_variable_data_c * const dh_group_generator, + const eap_status_e completion_status) = 0; + + /** + * This function completes the asyncronous tls_am_services_c::query_realm() function call. + * The parameter realm is saved. + * All pending actions are checked and completed during this call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_query_realm( + const eap_variable_data_c * const realm, + const eap_status_e completion_status) = 0; + + /** + * This function completes the asyncronous tls_am_services_c::rsa_encrypt_with_public_key() function call. + * The parameter encrypted_premaster_secret is saved. + * All pending actions are checked and completed during this call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_rsa_encrypt_with_public_key( + const eap_variable_data_c * const encrypted_premaster_secret, + const eap_status_e completion_status) = 0; + + /** + * This function completes the asyncronous tls_am_services_c::rsa_decrypt_with_private_key() function call. + * The parameter premaster_secret is saved. + * All pending actions are checked and completed during this call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_rsa_decrypt_with_private_key( + const eap_variable_data_c * const premaster_secret, + const eap_status_e completion_status) = 0; + + /** + * This function completes the asyncronous tls_am_services_c::sign_with_private_key() function call. + * The parameter message_hash is saved. + * All pending actions are checked and completed during this call. + * The parameter completion_status must be eap_status_ok when query is successfull. + */ + virtual eap_status_e complete_sign_with_private_key( + const eap_variable_data_c * const signed_message_hash, + const eap_status_e completion_status) = 0; + + /** + * This function completes the asyncronous tls_am_services_c::verify_with_public_key() function call. + * The parameter verify_status must be eap_status_ok when verification is successfull. + * All pending actions are checked and completed during this call. + */ + virtual eap_status_e complete_verify_with_public_key( + const eap_status_e verify_status) = 0; + + virtual eap_status_e complete_query_ttls_pap_username_and_password( + const eap_variable_data_c * const ttls_pap_username, + const eap_variable_data_c * const ttls_pap_password, + const eap_status_e query_result) = 0; + + virtual eap_status_e complete_verify_ttls_pap_username_and_password( + const eap_status_e authentication_result, + const eap_variable_data_c * const ttls_pap_reply_message) = 0; + + //-------------------------------------------------- +}; // class abs_tls_am_services_c + +#endif //#if !defined(_ABS_TLS_AM_SERVICES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_assert.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_assert.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,211 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_ASSERT_H_) +#define _EAP_ASSERT_H_ + +#include "eap_am_compiler_flags.h" + +#include "eap_tools.h" + + +#if defined(_DEBUG) || defined(DEBUG) || defined(USE_EAP_ASSERTS) + + #if defined(__MARM__) || defined(__THUMB__) \ + || defined(__ARMI__) || defined(__ARM4__) + // Works only in ARM platform. + #define EAP_SYSTEM_DEBUG_BREAK() User::Panic(_L("EAPOL"), KErrGeneral) + #elif defined(__GNUC__) && defined(EAP_INTEL_PROCESSOR) + // Works only in intel platform and gcc. + #define EAP_SYSTEM_DEBUG_BREAK() __asm__( "int $0x03" : : ) + #elif defined(__WINSCW__) + // For RCVT compiler + #define EAP_SYSTEM_DEBUG_BREAK() EAP_NULL_FUNCTION + #elif defined(_WIN32) || defined(__WINS__) + // Works only in intel platform and MSVC++. + #define EAP_SYSTEM_DEBUG_BREAK() { __asm int 0x03 } + #else + #define EAP_SYSTEM_DEBUG_BREAK() EAP_NULL_FUNCTION + #endif + + #define EAP_STATIC_ASSERT(_x) do { typedef int ai[(_x) ? 1 : 0]; } while(0) + +#else + + #define EAP_SYSTEM_DEBUG_BREAK() EAP_NULL_FUNCTION + + #define EAP_STATIC_ASSERT(_x) + +#endif + + + +#if !defined(USE_EAP_ASSERTS) + + #define EAP_ASSERT_TOOLS(am_tools, param) EAP_NULL_FUNCTION + + #define EAP_ASSERT(param) EAP_NULL_FUNCTION + + + #define EAP_ASSERT_ALWAYS_TOOLS(am_tools, param) EAP_NULL_FUNCTION + + #define EAP_ASSERT_ALWAYS(param) EAP_NULL_FUNCTION + + + #define EAP_ASSERT_ALWAYS_NO_TRACE(param) EAP_NULL_FUNCTION + + + #define EAP_ASSERT_ANYWAY_TOOLS(am_tools) EAP_NULL_FUNCTION + + #define EAP_ASSERT_ANYWAY EAP_NULL_FUNCTION + +#else + +#if defined(__SYMBIAN32__) + + #if defined(_DEBUG) || defined(DEBUG) || defined(USE_EAP_ASSERTS) + #define EAP_ASSERT_TOOLS(am_tools, param)\ + if (!(param))\ + {\ + if ((am_tools) != 0) \ + { \ + (*(am_tools)).formatted_print(EAPL("ERROR: assertion failed " #param " %s:%d.\n"), __FILE__, __LINE__); \ + } \ + EAP_ASSERT_STACK_TRACE_TOOLS(am_tools, 0); \ + EAP_SYSTEM_DEBUG_BREAK();\ + }\ + __ASSERT_ALWAYS((param), User::Panic(_L("EAPOL"), 1)) + + #define EAP_ASSERT(param)\ + EAP_ASSERT_TOOLS(m_am_tools, param) + + #else + #define EAP_ASSERT_TOOLS(am_tools, param) EAP_NULL_FUNCTION + #define EAP_ASSERT(param) EAP_NULL_FUNCTION + #endif + + + #define EAP_ASSERT_ALWAYS_TOOLS(am_tools, param)\ + if (!(param))\ + {\ + if ((am_tools) != 0) \ + { \ + (*(am_tools)).formatted_print(EAPL("ERROR: assertion failed " #param " %s:%d.\n"), __FILE__, __LINE__); \ + } \ + EAP_ASSERT_STACK_TRACE_TOOLS(am_tools, 0); \ + EAP_SYSTEM_DEBUG_BREAK();\ + }\ + __ASSERT_ALWAYS((param), User::Panic(_L("EAPOL"), 1)) + + #define EAP_ASSERT_ALWAYS(param)\ + EAP_ASSERT_ALWAYS_TOOLS(m_am_tools, param) + + + #define EAP_ASSERT_ALWAYS_NO_TRACE(param) \ + if (!(param)) \ + { \ + EAP_SYSTEM_DEBUG_BREAK();\ + } \ + __ASSERT_ALWAYS((param), User::Panic(_L("EAPOL"), 1)) + + + #define EAP_ASSERT_ANYWAY_TOOLS(am_tools)\ + if ((am_tools) != 0) \ + { \ + (*(am_tools)).formatted_print(EAPL("ERROR: assertion failed. %s:%d\n"), __FILE__, __LINE__); \ + } \ + EAP_ASSERT_STACK_TRACE_TOOLS(am_tools, 0); \ + EAP_SYSTEM_DEBUG_BREAK();\ + __ASSERT_ALWAYS(0, User::Panic(_L("EAPOL"), 1)) + + #define EAP_ASSERT_ANYWAY\ + EAP_ASSERT_ANYWAY_TOOLS(m_am_tools) + +#elif defined(_WIN32) || defined(__GNUC__) || defined(__arm) + + #include + + #if defined(_DEBUG) || defined(DEBUG) || defined(USE_EAP_ASSERTS) + #define EAP_ASSERT_TOOLS(am_tools, param) \ + if (!(param)) \ + { \ + if ((am_tools) != 0) \ + { \ + (*(am_tools)).formatted_print(EAPL("ERROR: assertion failed " #param " %s:%d.\n"), __FILE__, __LINE__); \ + } \ + EAP_ASSERT_STACK_TRACE_TOOLS(am_tools, 0); \ + EAP_SYSTEM_DEBUG_BREAK();\ + } \ + assert(param) + + #define EAP_ASSERT(param) \ + EAP_ASSERT_TOOLS(m_am_tools, param) + + #else + #define EAP_ASSERT_TOOLS(am_tools, param) EAP_NULL_FUNCTION + #define EAP_ASSERT(param) EAP_NULL_FUNCTION + #endif + + + #define EAP_ASSERT_ALWAYS_TOOLS(am_tools, param) \ + if (!(param)) \ + { \ + if ((am_tools) != 0) \ + { \ + (*(am_tools)).formatted_print(EAPL("ERROR: assertion failed " #param " %s:%d.\n"), __FILE__, __LINE__); \ + } \ + EAP_ASSERT_STACK_TRACE_TOOLS(am_tools, 0); \ + EAP_SYSTEM_DEBUG_BREAK();\ + } \ + assert(param) + + #define EAP_ASSERT_ALWAYS(param) \ + EAP_ASSERT_ALWAYS_TOOLS(m_am_tools, param) + + + #define EAP_ASSERT_ALWAYS_NO_TRACE(param) \ + if (!(param)) \ + { \ + EAP_SYSTEM_DEBUG_BREAK();\ + } \ + assert(param) + + + #define EAP_ASSERT_ANYWAY_TOOLS(am_tools) \ + if ((am_tools) != 0) \ + { \ + (*(am_tools)).formatted_print(EAPL("ERROR: assertion failed. %s:%d\n"), __FILE__, __LINE__); \ + } \ + EAP_ASSERT_STACK_TRACE_TOOLS(am_tools, 0); \ + EAP_SYSTEM_DEBUG_BREAK();\ + assert(0) + + #define EAP_ASSERT_ANYWAY \ + EAP_ASSERT_ANYWAY_TOOLS(m_am_tools) + +#endif //#if defined(_WIN32) || defined(__GNUC__) + +#endif //#if !defined(USE_EAP_ASSERTS) + +#endif //#if !defined(_EAP_ASSERT_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_compiler_flags.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_compiler_flags.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_COMPILER_FLAGS_H_) +#define _EAP_AM_COMPILER_FLAGS_H_ + +#if defined(_DEBUG) || defined(DEBUG) + + #if !defined(USE_EAP_TRACE) + // This macro enables most of the traces. + #define USE_EAP_TRACE + #endif //#if defined(USE_EAP_TRACE) + + #if !defined(USE_EAP_TRACE_ALWAYS) + // This macro enables some traces for release error log. + // EAP_TRACE_ALWAYS() and EAP_TRACE_DATA_ALWAYS() are left + // active if USE_EAP_TRACE_ALWAYS is defined. + #define USE_EAP_TRACE_ALWAYS + #endif //#if !defined(USE_EAP_TRACE_ALWAYS) + + #if !defined(USE_EAP_DEBUG_TRACE) + // This macro enaables debug traces. + // Note the EAP_TRACE_ERROR() and EAP_TRACE_DATA_ERROR macroes + // are left inactive. + #define USE_EAP_DEBUG_TRACE + #endif //#if defined(USE_EAP_DEBUG_TRACE) + + #if !defined(USE_EAP_TRACE_STRINGS) + // This macro enables trace strings. + // Traces does convert enumerations to readable string + // if this is defined. + #define USE_EAP_TRACE_STRINGS + #endif //#if defined(USE_EAP_TRACE_STRINGS) + + #if !defined(USE_EAP_STATUS_RETURN) + // This macro enables status return traces. + // Each return does trace error status and source code file and line + // if this is defined. + #define USE_EAP_STATUS_RETURN + #endif //#if defined(USE_EAP_STATUS_RETURN) + + #if !defined(USE_EAP_ASSERTS) + // This macro enables all EAP assertions. + #define USE_EAP_ASSERTS + #endif //#if defined(USE_EAP_ASSERTS) + + #if !defined(USE_EAP_FILE_TRACE) + // This macro activates file tracing. + #define USE_EAP_FILE_TRACE + #endif //#if !defined(USE_EAP_FILE_TRACE) + + #if !defined(USE_EAP_HARDWARE_TRACE) + // This macro activates hardware traces of each platform if such exists. + #define USE_EAP_HARDWARE_TRACE + #endif //#if !defined(USE_EAP_HARDWARE_TRACE) + + #if !defined(USE_EAP_HARDWARE_TRACE_RAW_PRINT) + // This macro activates hardware traces RAW print of each platform if such exists. + #define USE_EAP_HARDWARE_TRACE_RAW_PRINT + #endif //#if !defined(USE_EAP_HARDWARE_TRACE_RAW_PRINT) + +#else + + // This is release code. + + #if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #if !defined(USE_EAP_TRACE_ALWAYS) + // This macro enables some traces for release error log. + // EAP_TRACE_ALWAYS() and EAP_TRACE_DATA_ALWAYS() are left + // active if USE_EAP_TRACE_ALWAYS is defined. + #define USE_EAP_TRACE_ALWAYS + #endif //#if !defined(USE_EAP_TRACE_ALWAYS) + + #if !defined(USE_EAP_STATUS_RETURN) + // This macro enables status return traces. + // Each return does trace error status and source code file and line + // if this is defined. + #define USE_EAP_STATUS_RETURN + #endif //#if defined(USE_EAP_STATUS_RETURN) + + #if !defined(USE_EAP_FILE_TRACE) + // This macro activates file tracing. + #define USE_EAP_FILE_TRACE + #endif //#if !defined(USE_EAP_FILE_TRACE) + #endif //#if !defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#endif + +#endif //#if !defined(_EAP_AM_COMPILER_FLAGS_H_) + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_crypto_md4.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_crypto_md4.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,267 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined( _EAP_AM_CRYPTO_MD4_H_ ) +#define _EAP_AM_CRYPTO_MD4_H_ + +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_am_tools.h" + + +//-------------------------------------------------- + +/// The eap_am_crypto_md4_c class includes the state of +/// one instance of MD4 algorithm. +class EAP_EXPORT eap_am_crypto_md4_c +{ + +private: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + enum eap_md4_init + { + EAP_MD4_INIT_H0 = 0x67452301ul, + EAP_MD4_INIT_H1 = 0xefcdab89ul, + EAP_MD4_INIT_H2 = 0x98badcfeul, + EAP_MD4_INIT_H3 = 0x10325476ul, + }; + + enum eap_md4_const + { + eap_md4_const_S11 = 3, + eap_md4_const_S12 = 7, + eap_md4_const_S13 = 11, + eap_md4_const_S14 = 19, + eap_md4_const_S21 = 3, + eap_md4_const_S22 = 5, + eap_md4_const_S23 = 9, + eap_md4_const_S24 = 13, + eap_md4_const_S31 = 3, + eap_md4_const_S32 = 9, + eap_md4_const_S33 = 11, + eap_md4_const_S34 = 15, + }; + + enum eap_md4_sizes + { + EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT = 16ul, ///< 16 u32_t integers. + EAP_AM_CRYPTO_MD4_BLOCK_BYTE_SIZE + = EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT * sizeof(u32_t), ///< in bytes. + EAP_AM_CRYPTO_MD4_DIGEST_BUFFER_u32_COUNT = 4ul, ///< 4 u32_t integers. + EAP_AM_CRYPTO_MD4_DIGEST_BUFFER_BYTE_SIZE + = EAP_AM_CRYPTO_MD4_DIGEST_BUFFER_u32_COUNT + * sizeof(u32_t), ///< in bytes. + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This buffer saves remaining data between subsequent calls + /// of hash_update(). + eap_variable_data_c m_saved_data; + + /// This attribute saves the length of hashed data. + u64_t m_full_hashed_data_length; + + u32_t m_W_in_host_order[EAP_AM_CRYPTO_MD4_BLOCK_u32_COUNT]; + + /// This buffer saves the digest value between subsequent calls + /// of hash_update(). + u32_t m_H[EAP_AM_CRYPTO_MD4_DIGEST_BUFFER_u32_COUNT]; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + inline u32_t eap_md4_F( + const u32_t X, + const u32_t Y, + const u32_t Z + ); + + inline u32_t eap_md4_G( + const u32_t X, + const u32_t Y, + const u32_t Z + ); + + inline u32_t eap_md4_H( + const u32_t X, + const u32_t Y, + const u32_t Z + ); + + inline u32_t eap_md4_rotate_left( + const u32_t value, + const u32_t shift + ); + + inline void eap_md4_FF( + const u32_t index, + u32_t * const A, + const u32_t B, + const u32_t C, + const u32_t D, + const u32_t X, + const u32_t S + ); + + inline void eap_md4_GG( + const u32_t index, + u32_t * const A, + const u32_t B, + const u32_t C, + const u32_t D, + const u32_t X, + const u32_t S + ); + + inline void eap_md4_HH( + const u32_t index, + u32_t * const A, + const u32_t B, + const u32_t C, + const u32_t D, + const u32_t X, + const u32_t S + ); + + /// @param W is an array of 16 input 32-bit unsigned integers + /// in host order. + /// @param W_count is count of integers in W array. + EAP_FUNC_IMPORT eap_status_e eap_md4_transform_host_order( + const u32_t * const W, + const u32_t W_count + ); + + /// @param W is an array of 16 input 32-bit unsigned integers + /// in network order. + /// @param W_count is count of integers in W array. + EAP_FUNC_IMPORT eap_status_e eap_md4_process_data( + const u32_t * const W, + const u32_t W_count + ); + + /** + * This function cleans up the MD4 context. + */ + EAP_FUNC_IMPORT eap_status_e hash_cleanup(); + + /** + * This function copies the message digest to output buffer. + */ + EAP_FUNC_IMPORT eap_status_e copy_message_digest( + void * const output, + u32_t * const max_output_size); + + + /** + * The set_is_invalid() function sets the state of the eap_am_crypto_md4_c + * object invalid. + * The eap_am_crypto_md4_c object calls this function after it is + * initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the eap_am_crypto_md4_c + * object valid. + * The eap_am_crypto_md4_c object calls this function after it is + * initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * This function copies the context of MD4. + */ + EAP_FUNC_IMPORT eap_status_e copy_context( + const eap_variable_data_c * const saved_data, + const u64_t full_hashed_data_length, + const u32_t * const H, + const u32_t * const W_in_host_order); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_am_crypto_md4_c(); + + /** + * Constructor initializes the member attributes. + */ + EAP_FUNC_IMPORT eap_am_crypto_md4_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the + * eap_am_crypto_md4_c object. + * True indicates the object is allocated successfully. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function returns the size of message digest of HASH-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_digest_length(); + + /** + * This function returns the size of block of HASH-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_block_size(); + + /** + * This function initializes the context of MD4-algorithm. + */ + EAP_FUNC_IMPORT eap_status_e hash_init(); + + /** + * This function updates the context of MD4-algorithm with data. + */ + EAP_FUNC_IMPORT eap_status_e hash_update( + const void * const data, + const u32_t data_length); + + /** + * This function writes the message digest to buffer. + * @param Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e hash_final( + void * const message_digest, + u32_t *md_length_or_null); + + /** + * This function copies the context of MD4. + */ + EAP_FUNC_IMPORT eap_am_crypto_md4_c * copy(); +}; + +//-------------------------------------------------- + +#endif //#if !defined( _EAP_AM_CRYPTO_OPENSSL_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_crypto_openssl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_crypto_openssl.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,704 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_AM_CRYPTO_OPENSSL_H_ ) +#define _EAP_AM_CRYPTO_OPENSSL_H_ + +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_am_tools.h" +#include "eap_array.h" +#include "abs_eap_am_crypto.h" +#if defined(USE_EAP_RANDOM_TEST) +#include "eap_am_random_test.h" +#endif //#if defined(USE_EAP_RANDOM_TEST) + +#if defined(des_set_key) +// OpenSSL defines this. +#undef des_set_key +#endif //#if defined(des_set_key) + +class abs_eap_am_tools_c; +class eap_variable_data_c; + +const u32_t EAP_HW_TICKS_SEED_BUFFER_SIZE = 8u; + +/// Class eap_am_crypto_openssl_c offers services to authenticate data, +/// encrypt data, decrypt data, generate keys and generate cryptographically +/// strong random data. +class EAP_EXPORT eap_am_crypto_openssl_c +: public abs_eap_am_crypto_c +{ +private: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + +#if defined(USE_EAP_RANDOM_TEST) + /// This is used because of the random generator of OpenSSL does some + /// memory violations that valgrind founds. + eap_am_random_test_c m_test_random; +#endif //#if defined(USE_EAP_RANDOM_TEST) + + bool m_use_test_random; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + u8_t m_hw_ticks_seed_buffer[EAP_HW_TICKS_SEED_BUFFER_SIZE]; + u32_t m_hw_ticks_seed_index; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + static abs_eap_am_tools_c * g_tools; + + /** + * Destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_am_crypto_openssl_c(); + + /** + * Constructor initializes the member attributes. + */ + EAP_FUNC_IMPORT eap_am_crypto_openssl_c(abs_eap_am_tools_c * const tools); + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this + * function. Needed configuration depends on the implementation. + */ + EAP_FUNC_IMPORT eap_status_e configure(); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT bool get_is_valid() const + { + return m_is_valid; + } + EAP_FUNC_IMPORT void set_is_valid() + { + m_is_valid = true; + } + + /** + * This function activates random generator for test use. + * It does generate predictive pseudorandom data. + */ + EAP_FUNC_IMPORT void use_test_random( + const u8_t * const seed, + const u32_t seed_length, + const bool does_continuous_seeding_when_true); + + /** + * The get_rand_bytes() function fills count random bytes to buffer. + */ + EAP_FUNC_IMPORT eap_status_e get_rand_bytes( + u8_t * const buffer, + const u32_t count); + + /** + * The add_rand_seed() function seeds count bytes from buffer to the + * random data pool. The seed bytes could be any data that increases + * entropy of the random data pool. For example time stamps of send + * and received messages, likewise addresses, cookies and nonces + * included in messages. + */ + EAP_FUNC_IMPORT eap_status_e add_rand_seed( + const u8_t * const buffer, + const u32_t count); + + /** + * The add_rand_seed_hw_ticks() function adds hardware ticks read with + * the abs_eap_am_tools::get_hardware_ticks() function. This could be + * used to seed the random data pool with time stamps. + */ + EAP_FUNC_IMPORT eap_status_e add_rand_seed_hw_ticks(); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The generate_diffie_hellman_keys() function generates private and + * public Diffie-Hellman keys. + * @param dh_context Saves context here. It is private key in OpenSSL + * and CDHKey in Symbian. + */ + EAP_FUNC_IMPORT eap_status_e generate_diffie_hellman_keys( + eap_variable_data_c * const dh_context, + eap_variable_data_c * const own_public_dh_key, + const u8_t * const prime, + const u32_t prime_length, + const u8_t * const group_generator, + const u32_t group_generator_length); + + /** + * The generate_g_power_to_xy() function generates shared secret + * Diffie-Hellman key from own_private_dh_key and peer_public_dh_key. + * @param dh_context Gets context. Is private key in OpenSSL and + * CDHKey in Symbian. + */ + EAP_FUNC_IMPORT eap_status_e generate_g_power_to_xy( + const eap_variable_data_c * const dh_context, + const eap_variable_data_c * const peer_public_dh_key, + eap_variable_data_c * const shared_dh_key, + const u8_t * const prime, + const u32_t prime_length, + const u8_t * const group_generator, + const u32_t group_generator_length); + + /** + * This functions cleans up the diffie-hellman context. + */ + + EAP_FUNC_IMPORT eap_status_e dh_cleanup( + const eap_variable_data_c * const dh_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of SHA1-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_sha_256_digest_length( + eap_variable_data_c * const sha_256_context); + + /** + * This function returns the block size of SHA1-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_sha_256_block_size( + eap_variable_data_c * const sha_256_context); + + /** + * The sha_256_init() function initializes SHA1. + * Internal context of SHA1 is stored to sha_256_context. + */ + EAP_FUNC_IMPORT eap_status_e sha_256_init( + eap_variable_data_c * const sha_256_context); + + /** + * The sha_256_update() function updates the context of + * sha_256_context with data_length bytes of data. + */ + EAP_FUNC_IMPORT eap_status_e sha_256_update( + eap_variable_data_c * const sha_256_context, + const u8_t * const data, + const u32_t data_length); + + /** + * The sha_256_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non NULL. + */ + EAP_FUNC_IMPORT eap_status_e sha_256_final( + eap_variable_data_c * const sha_256_context, + u8_t * const message_digest, + u32_t *md_length_or_null); + + /** + * The hmac_sha_256_cleanup() cleanups the SHA1 context. + */ + EAP_FUNC_IMPORT eap_status_e sha_256_cleanup( + eap_variable_data_c * const sha_256_context); + + /** + * The sha_256_copy_context() copies the SHA1 context. + */ + EAP_FUNC_IMPORT eap_status_e sha_256_copy_context( + eap_variable_data_c * const copied_sha_256_context, + const eap_variable_data_c * const original_sha_256_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of SHA1-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_sha1_digest_length( + eap_variable_data_c * const sha1_context); + + /** + * This function returns the block size of SHA1-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_sha1_block_size( + eap_variable_data_c * const sha1_context); + + /** + * The sha1_init() function initializes SHA1. + * Internal context of SHA1 is stored to sha1_context. + */ + EAP_FUNC_IMPORT eap_status_e sha1_init( + eap_variable_data_c * const sha1_context); + + /** + * The sha1_update() function updates the context of + * sha1_context with data_length bytes of data. + */ + EAP_FUNC_IMPORT eap_status_e sha1_update( + eap_variable_data_c * const sha1_context, + const u8_t * const data, + const u32_t data_length); + + /** + * The sha1_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non + * NULL. + */ + EAP_FUNC_IMPORT eap_status_e sha1_final( + eap_variable_data_c * const sha1_context, + u8_t * const message_digest, + u32_t *md_length_or_null); + + /** + * The hmac_sha1_cleanup() cleanups the SHA1 context. + */ + EAP_FUNC_IMPORT eap_status_e sha1_cleanup( + eap_variable_data_c * const sha1_context); + + /** + * The sha1_copy_context() copies the SHA1 context. + */ + EAP_FUNC_IMPORT eap_status_e sha1_copy_context( + eap_variable_data_c * const copied_sha1_context, + const eap_variable_data_c * const original_sha1_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The aes_key_length() function returns the length of key AES-algorithm. + * This will be constant 16 bytes (128 bits). Still it is better use + * function to help changes if the length of key is changed in future. + */ + EAP_FUNC_IMPORT u32_t aes_key_length(); + + /** + * The aes_block_size() function returns the block size of AES-algorithm. + * This will be constant 16 bytes (128 bits). Still it is better use + * function to help changes if the size is changed in future. + */ + EAP_FUNC_IMPORT u32_t aes_block_size(); + + + /** + * The aes_set_encryption_key() function initializes the encryption + * context of AES-algorithm to the aes_context using key_length bytes + * from buffer key. + */ + EAP_FUNC_IMPORT eap_status_e aes_set_encryption_key( + eap_variable_data_c * const aes_context, + const u8_t * const key, + const u32_t key_length); + + /** + * The aes_set_decryption_key() function initializes the decryption + * context of + * AES-algorithm to the aes_context using key_length bytes from buffer key. + */ + EAP_FUNC_IMPORT eap_status_e aes_set_decryption_key( + eap_variable_data_c * const aes_context, + const u8_t * const key, + const u32_t key_length); + + EAP_FUNC_IMPORT eap_status_e aes_cleanup( + eap_variable_data_c * const aes_context); + + /** + * The aes_encrypt_block() function encrypts data of data_length bytes + * using encryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of AES-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used + * taking advance from separate buffers. + */ + EAP_FUNC_IMPORT eap_status_e aes_encrypt_block( + eap_variable_data_c * const aes_context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length); + + /** + * The aes_decrypt_block() function decrypts data of data_length bytes + * using decryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of AES-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used + * taking advance from separate buffers. + */ + EAP_FUNC_IMPORT eap_status_e aes_decrypt_block( + eap_variable_data_c * const aes_context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The key_length() function returns the length of key 3DES-EDE-algorithm. + * This will be constant 16 bytes (128 bits). Still it is better use + * function to help changes if the length of key is changed in future. + */ + EAP_FUNC_IMPORT u32_t key_length_3des_ede(); + + /** + * The block_size() function returns the block size of 3DES-EDE-algorithm. + * This will be constant 16 bytes (128 bits). Still it is better use + * function to help changes if the size is changed in future. + */ + EAP_FUNC_IMPORT u32_t block_size_3des_ede(); + + + /** + * The cbc_set_encryption_key() function initializes the encryption + * context of 3DES-EDE-algorithm to the context using key_length bytes + * from buffer key. + */ + EAP_FUNC_IMPORT eap_status_e set_encryption_key_3des_ede( + eap_variable_data_c * const context, + const u8_t * const key, + const u32_t key_length); + + /** + * The cbc_set_decryption_key() function initializes the decryption + * context of 3DES-EDE-algorithm to the context using key_length bytes + * from buffer key. + */ + EAP_FUNC_IMPORT eap_status_e set_decryption_key_3des_ede( + eap_variable_data_c * const context, + const u8_t * const key, + const u32_t key_length); + + EAP_FUNC_IMPORT eap_status_e cleanup_3des_ede( + eap_variable_data_c * const context); + + /** + * The cbc_encrypt_data() function encrypts data of data_length bytes + * using encryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of 3DES-EDE-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used + * taking advance from separate buffers. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_block_3des_ede( + eap_variable_data_c * const context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length); + + /** + * The cbc_decrypt_data() function decrypts data of data_length bytes + * using decryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of 3DES-EDE-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used + * taking advance from separate buffers. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_block_3des_ede( + eap_variable_data_c * const context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Key derivation is based on the random number generation specified in + * NIST Federal Information Processing Standards (FIPS) Publication + * 186-2 [9]. The random number generator is specified in the change + * notice 1 (2001 October 5) of [9] (Algorithm 1). As specified in the + * change notice (page 74), when Algorithm 1 is used as a general- + * purpose random number generator, the "mod q" term in step 3.3 is + * omitted. The function G used in the algorithm is constructed via + * Secure Hash Standard as specified in Appendix 3.3 of the standard. + + * 160-bit XKEY and XVAL values are used, so b = 160. The initial + * secret seed value XKEY is computed from the n GSM Kc keys and the + * NONCE_MT with the following formula: + * @code + * XKEY = SHA1(n*Kc| NONCE_MT) + * + * Random generator becomes as follows: + * Step 1. Choose a new, secret value for the seed-key, XKEY. + * Step 2. In hexadecimal notation let + * t = 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0. + * This is the initial value for H0 || H1 || H2 || H3 || H4 + * in the SHS. + * Step 3. For j = 0 to m - 1 do + * c. xj = G(t,XKEY). + * d. XKEY = (1 + XKEY + xj) mod 2^b. + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e dss_pseudo_random( + u8_t *out, + u32_t out_length, + u8_t *xkey, + u32_t xkey_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of MD5-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_md5_digest_length( + eap_variable_data_c * const md5_context); + + /** + * This function returns the block size of MD5-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_md5_block_size( + eap_variable_data_c * const md5_context); + + /** + * The sha1_init() function initializes MD5. + * Internal context of MD5 is stored to sha1_context. + */ + EAP_FUNC_IMPORT eap_status_e md5_init( + eap_variable_data_c * const md5_context); + + /** + * The md5_update() function updates the context of + * md5_context with data_length bytes of data. + */ + EAP_FUNC_IMPORT eap_status_e md5_update( + eap_variable_data_c * const md5_context, + const u8_t * const data, + const u32_t data_length); + + /** + * The md5_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non + * NULL. + */ + EAP_FUNC_IMPORT eap_status_e md5_final( + eap_variable_data_c * const md5_context, + u8_t * const message_digest, + u32_t *md_length_or_null); + + /** + * The hmac_md5_cleanup() cleanups the MD5 context. + */ + EAP_FUNC_IMPORT eap_status_e md5_cleanup( + eap_variable_data_c * const md5_context); + + /** + * The md5_copy_context() copies the MD5 context. + */ + EAP_FUNC_IMPORT eap_status_e md5_copy_context( + eap_variable_data_c * const copied_md5_context, + const eap_variable_data_c * const original_md5_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of MD4-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_md4_digest_length( + eap_variable_data_c * const md4_context); + + /** + * This function returns the block size of MD4-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_md4_block_size( + eap_variable_data_c * const md4_context); + + /** + * The sha1_init() function initializes MD4. + * Internal context of MD4 is stored to sha1_context. + */ + EAP_FUNC_IMPORT eap_status_e md4_init( + eap_variable_data_c * const md4_context); + + /** + * The md4_update() function updates the context of + * md5_context with data_length bytes of data. + */ + EAP_FUNC_IMPORT eap_status_e md4_update( + eap_variable_data_c * const md4_context, + const u8_t * const data, + const u32_t data_length); + + /** + * The md4_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non + * NULL. + */ + EAP_FUNC_IMPORT eap_status_e md4_final( + eap_variable_data_c * const md4_context, + u8_t * const message_digest, + u32_t *md_length_or_null); + + /** + * The hmac_md5_cleanup() cleanups the MD4 context. + */ + EAP_FUNC_IMPORT eap_status_e md4_cleanup( + eap_variable_data_c * const md4_context); + + /** + * The md4_copy_context() copies the MD4 context. + */ + EAP_FUNC_IMPORT eap_status_e md4_copy_context( + eap_variable_data_c * const copied_md4_context, + const eap_variable_data_c * const original_md4_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Used to set the RC4 key. + */ + EAP_FUNC_IMPORT eap_status_e rc4_set_key( + eap_variable_data_c * const rc4_context, + const eap_variable_data_c * const key); + + /** + * Used to clean up the RC4 context. + */ + EAP_FUNC_IMPORT eap_status_e rc4_cleanup( + eap_variable_data_c * const rc4_context); + + /** + * Encrypts RC4 data. + */ + EAP_FUNC_IMPORT eap_status_e rc4_encrypt( + const eap_variable_data_c * const rc4_context, + void * const data_in_out, + const u32_t data_length); + + /** + * Encrypts RC4 data. + */ + EAP_FUNC_IMPORT eap_status_e rc4_encrypt( + const eap_variable_data_c * const rc4_context, + const void * const data_in, + void * const data_out, + const u32_t data_length); + + /** + * Decrypts RC4 data. + */ + EAP_FUNC_IMPORT eap_status_e rc4_decrypt( + const eap_variable_data_c * const rc4_context, + void * const data_in_out, + const u32_t data_length); + + /** + * Decrypts RC4 data. + */ + EAP_FUNC_IMPORT eap_status_e rc4_decrypt( + const eap_variable_data_c * const rc4_context, + const void * const data_in, + void * const data_out, + const u32_t data_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The rsa_init() function initializes context of RSA. + * Internal context of RSA is stored to rsa_context. + */ + EAP_FUNC_IMPORT eap_status_e rsa_init( + eap_variable_data_c * const rsa_context); + + EAP_FUNC_IMPORT eap_status_e rsa_encrypt_with_public_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + EAP_FUNC_IMPORT eap_status_e rsa_decrypt_with_public_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + EAP_FUNC_IMPORT eap_status_e rsa_encrypt_with_private_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + EAP_FUNC_IMPORT eap_status_e rsa_decrypt_with_private_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + EAP_FUNC_IMPORT eap_status_e rsa_sign( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash); + + EAP_FUNC_IMPORT eap_status_e rsa_verify( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash); + + /** + * The rsa_cleanup() function cleans up context of RSA. + * Internal context of RSA is stored to rsa_context. + */ + EAP_FUNC_IMPORT eap_status_e rsa_cleanup( + eap_variable_data_c * const rsa_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The dsa_init() function initializes context of DSA. + * Internal context of DSA is stored to dsa_context. + */ + EAP_FUNC_IMPORT eap_status_e dsa_init( + eap_variable_data_c * const dsa_context); + + EAP_FUNC_IMPORT eap_status_e dsa_sign( + eap_variable_data_c * const dsa_context, + const eap_variable_data_c * const private_dsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash); + + EAP_FUNC_IMPORT eap_status_e dsa_verify( + eap_variable_data_c * const dsa_context, + const eap_variable_data_c * const public_dsa_key, + const eap_variable_data_c * const dsa_param_p, + const eap_variable_data_c * const dsa_param_q, + const eap_variable_data_c * const dsa_param_g, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash); + + /** + * The dsa_cleanup() function cleans up context of DSA. + * Internal context of DSA is stored to dsa_context. + */ + EAP_FUNC_IMPORT eap_status_e dsa_cleanup( + eap_variable_data_c * const dsa_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT void open_crypto_memory_leaks(); + EAP_FUNC_IMPORT void close_crypto_memory_leaks(); +}; + +#endif //#if !defined( _EAP_AM_CRYPTO_OPENSSL_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_crypto_rc4.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_crypto_rc4.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,157 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +//------------------------------------------------------------ + +#if !defined(_EAP_AM_CRYPTO_RC4_H_) +#define _EAP_AM_CRYPTO_RC4_H_ + +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_am_tools.h" + +#undef set_key + +//------------------------------------------------------------ + +/// The eap_am_crypto_rc4_c class includes the state of +/// one instance of RC4 algorithm. +class EAP_EXPORT eap_am_crypto_rc4_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + enum eap_am_crypto_rc4_constant + { + eap_am_crypto_rc4_constant_state_size = 256, + }; + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// State is stored to this variable. + u8_t m_state[eap_am_crypto_rc4_constant_state_size]; + + /// This is the index i. + u8_t m_ind_i; + + /// This is the index j. + u8_t m_ind_j; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Function cleanups the state and variables. + */ + EAP_FUNC_IMPORT eap_status_e cleanup(); + + /** + * The set_is_invalid() function sets the state of the eap_am_crypto_rc4_c + * object invalid. + * The eap_am_crypto_rc4_c object calls this function after it is + * initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the eap_am_crypto_rc4_c + * object valid. + * The eap_am_crypto_rc4_c object calls this function after it is + * initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * Function swaps the values. + */ + EAP_FUNC_IMPORT inline void swap( + u8_t * const s_i, + u8_t * const s_j); + + /** + * Function returns the next random byte. + */ + inline u8_t get_random_byte(); + + /** + * Function XORs input data buffer with generated pseudo random data + * and stores result to output data buffer. + */ + inline eap_status_e process_data( + const void * const p_data_in, + void * const p_data_out, + const u32_t data_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~eap_am_crypto_rc4_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT eap_am_crypto_rc4_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the + * eap_am_crypto_rc4_c object. + * True indicates the object is allocated successfully. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function sets the RC4 key. + */ + EAP_FUNC_IMPORT eap_status_e set_key( + const eap_variable_data_c * const key); + + /** + * This function does RC4 encryption. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length); + + /** + * This function does RC4 decryption. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length); +}; + +#endif //#if !defined(_EAP_AM_CRYPTO_RC4_H_) + +//------------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_crypto_sha1.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_crypto_sha1.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,339 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined( _EAP_AM_CRYPTO_SHA1_H_ ) +#define _EAP_AM_CRYPTO_SHA1_H_ + +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_am_tools.h" + + +//-------------------------------------------------- + +/// The eap_am_crypto_sha1_c class includes the state of +/// one instance of SHA1 algorithm. +class EAP_EXPORT eap_am_crypto_sha1_c +{ + +private: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + enum eap_sha1_H_init + { + EAP_SHA1_INIT_H0 = 0x67452301ul, + EAP_SHA1_INIT_H1 = 0xefcdab89ul, + EAP_SHA1_INIT_H2 = 0x98badcfeul, + EAP_SHA1_INIT_H3 = 0x10325476ul, + EAP_SHA1_INIT_H4 = 0xc3d2e1f0ul, + }; + + enum eap_sha1_K + { + EAP_SHA1_K__0_19 = 0x5a827999ul, + EAP_SHA1_K_20_39 = 0x6ed9eba1ul, + EAP_SHA1_K_40_59 = 0x8f1bbcdcul, + EAP_SHA1_K_60_79 = 0xca62c1d6ul, + }; + + enum eap_sha1_sizes + { + EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT = 16ul, ///< 16 u32_t integers. + EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE + = EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT + * sizeof(u32_t), ///< in bytes. + EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_u32_COUNT + = 5ul, ///< 5 u32_t integers. + EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE + = EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_u32_COUNT + * sizeof(u32_t), ///< in bytes. + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This buffer saves remaining data between subsequent calls + /// of hash_update(). + eap_variable_data_c m_saved_data; + + /// This attribute saves the length of hashed data. + u64_t m_full_hashed_data_length; + + /// Array of 16 temporary 32-bit unsigned integers. + u32_t m_T[EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT]; + + + u32_t m_W_in_host_order[EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT]; + + /// This buffer saves the digest value between subsequent call + /// of hash_update(). + u32_t m_H[EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_u32_COUNT]; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + inline u32_t eap_sha1_rotate( + const u32_t value, + const u32_t shift + ); + + inline u32_t eap_sha1_b_substitution( + const u32_t Wt_3, + const u32_t Wt_8, + const u32_t Wt_14, + const u32_t Wt_16 + ); + + inline u32_t eap_sha1_ft_0_19( + const u32_t B, + const u32_t C, + const u32_t D + ); + + inline u32_t eap_sha1_ft_20_39( + const u32_t B, + const u32_t C, + const u32_t D + ); + + inline u32_t eap_sha1_ft_40_59( + const u32_t B, + const u32_t C, + const u32_t D + ); + + inline u32_t eap_sha1_ft_60_79( + const u32_t B, + const u32_t C, + const u32_t D + ); + + inline void d_substitution( + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + const u32_t temp + ); + + inline void d_substitution_0_15( + const u32_t t, + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + const u32_t Wt + ); + + inline void d_substitution_16_19( + const u32_t t, + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + u32_t * const Wt, + const u32_t Wt_3, + const u32_t Wt_8, + const u32_t Wt_14, + const u32_t Wt_16 + ); + + inline void d_substitution_20_39( + const u32_t t, + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + u32_t * const Wt, + const u32_t Wt_3, + const u32_t Wt_8, + const u32_t Wt_14, + const u32_t Wt_16 + ); + + inline void d_substitution_40_59( + const u32_t t, + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + u32_t * const Wt, + const u32_t Wt_3, + const u32_t Wt_8, + const u32_t Wt_14, + const u32_t Wt_16 + ); + + inline void d_substitution_60_79( + const u32_t t, + u32_t * const A, + u32_t * const B, + u32_t * const C, + u32_t * const D, + u32_t * const E, + u32_t * const Wt, + const u32_t Wt_3, + const u32_t Wt_8, + const u32_t Wt_14, + const u32_t Wt_16 + ); + + /// @param W is an array of modulo 16 input 32-bit unsigned integers + /// in host order. + /// @param W_count is count of integers in W array. + EAP_FUNC_IMPORT eap_status_e eap_sha1_process_data_host_order( + const u32_t * W, + u32_t W_count + ); + + /// @param W is an array of modulo 16 input 32-bit unsigned integers + /// in host order. + /// @param W_count is count of integers in W array. + EAP_FUNC_IMPORT eap_status_e eap_sha1_process_data_network_order( + const u32_t * W, + u32_t W_count + ); + + /** + * This function cleans up the SHA1 context. + */ + EAP_FUNC_IMPORT eap_status_e hash_cleanup(); + + /** + * This function copies the message digest to output buffer. + */ + EAP_FUNC_IMPORT eap_status_e copy_message_digest( + void * const output, + u32_t * const max_output_size); + + + /** + * The set_is_invalid() function sets the state of the eap_am_crypto_md4_c + * object invalid. + * The eap_am_crypto_md4_c object calls this function after it is + * initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the eap_am_crypto_md4_c + * object valid. + * The eap_am_crypto_md4_c object calls this function after it is + * initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * This function copies the context of SHA1. + */ + EAP_FUNC_IMPORT eap_status_e copy_context( + const eap_variable_data_c * const saved_data, + const u64_t full_hashed_data_length, + const u32_t * const H, + const u32_t * const T, + const u32_t * const W_in_host_order); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_am_crypto_sha1_c(); + + /** + * Constructor initializes the member attributes. + */ + EAP_FUNC_IMPORT eap_am_crypto_sha1_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the + * eap_am_crypto_md4_c object. + * True indicates the object is allocated successfully. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function returns the size of message digest of HASH-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_digest_length(); + + /** + * This function returns the size of block of HASH-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_block_size(); + + /** + * This function initializes the context of SHA1-algorithm. + */ + EAP_FUNC_IMPORT eap_status_e hash_init(); + + /** + * This function updates the context of SHA1-algorithm with data. + */ + EAP_FUNC_IMPORT eap_status_e hash_update( + const void * const data, + const u32_t data_length); + + /** + * This function writes the message digest to buffer. + * @param Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e hash_final( + void * const message_digest, + u32_t *md_length_or_null); + + /** + * + * eap_sha1_dss_G_function() implements the G() function using + * modified SHA-1 using the routine in Appendix 3.3 Constructing + * The Function G From SHA-1 in the SECURE HASH STANDARD, FIPS PUB 180-1. + */ + EAP_FUNC_IMPORT eap_status_e eap_sha1_dss_G_function( + const void * const data, + const u32_t data_length, + void * const output, + u32_t * const output_length + ); + + /** + * This function copies the context of SHA1. + */ + EAP_FUNC_IMPORT eap_am_crypto_sha1_c * copy(); + +}; + +//-------------------------------------------------- + +#endif //#if !defined( _EAP_AM_CRYPTO_OPENSSL_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_crypto_sha_256.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_crypto_sha_256.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,217 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined( _EAP_AM_CRYPTO_SHA_256_H_ ) +#define _EAP_AM_CRYPTO_SHA_256_H_ + +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_am_tools.h" + + +//-------------------------------------------------- + +/// The eap_am_crypto_sha_256_c class includes the state of +/// one instance of SHA_256 algorithm. +class EAP_EXPORT eap_am_crypto_sha_256_c +{ + +private: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + enum eap_sha_256_H_init + { + EAP_SHA_256_INIT_H0 = 0x6a09e667, + EAP_SHA_256_INIT_H1 = 0xbb67ae85, + EAP_SHA_256_INIT_H2 = 0x3c6ef372, + EAP_SHA_256_INIT_H3 = 0xa54ff53a, + EAP_SHA_256_INIT_H4 = 0x510e527f, + EAP_SHA_256_INIT_H5 = 0x9b05688c, + EAP_SHA_256_INIT_H6 = 0x1f83d9ab, + EAP_SHA_256_INIT_H7 = 0x5be0cd19, + }; + + enum eap_sha_256_sizes + { + EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT = 16ul, ///< 16 u32_t integers. + EAP_AM_CRYPTO_SHA_256_BLOCK_BYTE_SIZE + = EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT + * sizeof(u32_t), ///< in bytes. + EAP_AM_CRYPTO_SHA_256_DIGEST_BUFFER_u32_COUNT + = 8ul, ///< 8 u32_t integers. + EAP_AM_CRYPTO_SHA_256_DIGEST_BUFFER_BYTE_SIZE + = EAP_AM_CRYPTO_SHA_256_DIGEST_BUFFER_u32_COUNT + * sizeof(u32_t), ///< in bytes. + EAP_AM_CRYPTO_SHA_256_SCHEDULE_u32_COUNT = 64ul, ///< 64 u32_t integers. + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This buffer saves remaining data between subsequent calls + /// of hash_update(). + eap_variable_data_c m_saved_data; + + /// This attribute saves the length of hashed data. + u64_t m_full_hashed_data_length; + + /// Array of 16 temporary 32-bit unsigned integers. + u32_t m_T[EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT]; + + static const unsigned long m_K[EAP_AM_CRYPTO_SHA_256_SCHEDULE_u32_COUNT]; + + u32_t m_M_in_host_order[EAP_AM_CRYPTO_SHA_256_BLOCK_u32_COUNT]; + + /// This buffer saves the digest value between subsequent call + /// of hash_update(). + u32_t m_H[EAP_AM_CRYPTO_SHA_256_DIGEST_BUFFER_u32_COUNT]; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + inline u32_t eap_sha_256_rotate( + const u32_t value, + const u32_t shift + ); + + /// @param W is an array of modulo 16 input 32-bit unsigned integers + /// in host order. + /// @param W_count is count of integers in W array. + EAP_FUNC_IMPORT eap_status_e eap_sha_256_process_data_host_order( + const u32_t * W, + u32_t W_count + ); + + /// @param W is an array of modulo 16 input 32-bit unsigned integers + /// in host order. + /// @param W_count is count of integers in W array. + EAP_FUNC_IMPORT eap_status_e eap_sha_256_process_data_network_order( + const u32_t * W, + u32_t W_count + ); + + /** + * This function cleans up the SHA_256 context. + */ + EAP_FUNC_IMPORT eap_status_e hash_cleanup(); + + /** + * This function copies the message digest to output buffer. + */ + EAP_FUNC_IMPORT eap_status_e copy_message_digest( + void * const output, + u32_t * const max_output_size); + + + /** + * The set_is_invalid() function sets the state of the eap_am_crypto_md4_c + * object invalid. + * The eap_am_crypto_md4_c object calls this function after it is + * initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the eap_am_crypto_md4_c + * object valid. + * The eap_am_crypto_md4_c object calls this function after it is + * initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * This function copies the context of SHA_256. + */ + EAP_FUNC_IMPORT eap_status_e copy_context( + const eap_variable_data_c * const saved_data, + const u64_t full_hashed_data_length, + const u32_t * const H, + const u32_t * const T, + const u32_t * const W_in_host_order); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_am_crypto_sha_256_c(); + + /** + * Constructor initializes the member attributes. + */ + EAP_FUNC_IMPORT eap_am_crypto_sha_256_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the + * eap_am_crypto_md4_c object. + * True indicates the object is allocated successfully. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function returns the size of message digest of HASH-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_digest_length(); + + /** + * This function returns the size of block of HASH-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_block_size(); + + /** + * This function initializes the context of SHA_256-algorithm. + */ + EAP_FUNC_IMPORT eap_status_e hash_init(); + + /** + * This function updates the context of SHA_256-algorithm with data. + */ + EAP_FUNC_IMPORT eap_status_e hash_update( + const void * const data, + const u32_t data_length); + + /** + * This function writes the message digest to buffer. + * @param Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e hash_final( + void * const message_digest, + u32_t *md_length_or_null); + + /** + * This function copies the context of SHA_256. + */ + EAP_FUNC_IMPORT eap_am_crypto_sha_256_c * copy(); + +}; + +//-------------------------------------------------- + +#endif //#if !defined( _EAP_AM_CRYPTO_SHA_256_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_dh_primes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_dh_primes.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_DH_PRIMES_H_) +#define _EAP_AM_DH_PRIMES_H_ + +//-------------------------------------------------- + +const u32_t OAKLEY_DEFAULT_GROUP_1_PRIME_LENGTH = 96; /* bytes */ + +const u8_t OAKLEY_DEFAULT_GROUP_1_PRIME[OAKLEY_DEFAULT_GROUP_1_PRIME_LENGTH] = +{ + 0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF + ,0xC9,0x0F,0xDA,0xA2 ,0x21,0x68,0xC2,0x34 + ,0xC4,0xC6,0x62,0x8B ,0x80,0xDC,0x1C,0xD1 + ,0x29,0x02,0x4E,0x08 ,0x8A,0x67,0xCC,0x74 + ,0x02,0x0B,0xBE,0xA6 ,0x3B,0x13,0x9B,0x22 + ,0x51,0x4A,0x08,0x79 ,0x8E,0x34,0x04,0xDD + ,0xEF,0x95,0x19,0xB3 ,0xCD,0x3A,0x43,0x1B + ,0x30,0x2B,0x0A,0x6D ,0xF2,0x5F,0x14,0x37 + ,0x4F,0xE1,0x35,0x6D ,0x6D,0x51,0xC2,0x45 + ,0xE4,0x85,0xB5,0x76 ,0x62,0x5E,0x7E,0xC6 + ,0xF4,0x4C,0x42,0xE9 ,0xA6,0x3A,0x36,0x20 + ,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF +}; + +const u32_t OAKLEY_DEFAULT_GROUP_GENERATOR_LENGTH = 1; /* bytes */ + +const u8_t OAKLEY_DEFAULT_GROUP_GENERATOR[OAKLEY_DEFAULT_GROUP_GENERATOR_LENGTH] = +{ + 0x02 +}; + + +const u32_t OAKLEY_DEFAULT_GROUP_2_PRIME_LENGTH = 128; /* bytes */ + +const u8_t OAKLEY_DEFAULT_GROUP_2_PRIME[OAKLEY_DEFAULT_GROUP_2_PRIME_LENGTH] = +{ + 0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF + ,0xC9,0x0F,0xDA,0xA2 ,0x21,0x68,0xC2,0x34 + ,0xC4,0xC6,0x62,0x8B ,0x80,0xDC,0x1C,0xD1 + ,0x29,0x02,0x4E,0x08 ,0x8A,0x67,0xCC,0x74 + ,0x02,0x0B,0xBE,0xA6 ,0x3B,0x13,0x9B,0x22 + ,0x51,0x4A,0x08,0x79 ,0x8E,0x34,0x04,0xDD + ,0xEF,0x95,0x19,0xB3 ,0xCD,0x3A,0x43,0x1B + ,0x30,0x2B,0x0A,0x6D ,0xF2,0x5F,0x14,0x37 + ,0x4F,0xE1,0x35,0x6D ,0x6D,0x51,0xC2,0x45 + ,0xE4,0x85,0xB5,0x76 ,0x62,0x5E,0x7E,0xC6 + ,0xF4,0x4C,0x42,0xE9 ,0xA6,0x37,0xED,0x6B + ,0x0B,0xFF,0x5C,0xB6 ,0xF4,0x06,0xB7,0xED + ,0xEE,0x38,0x6B,0xFB ,0x5A,0x89,0x9F,0xA5 + ,0xAE,0x9F,0x24,0x11 ,0x7C,0x4B,0x1F,0xE6 + ,0x49,0x28,0x66,0x51 ,0xEC,0xE6,0x53,0x81 + ,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF +}; + + +const u32_t OAKLEY_DEFAULT_GROUP_5_PRIME_LENGTH = 192; /* bytes */ + +const u8_t OAKLEY_DEFAULT_GROUP_5_PRIME[OAKLEY_DEFAULT_GROUP_5_PRIME_LENGTH] = +{ + 0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF + ,0xC9,0x0F,0xDA,0xA2 ,0x21,0x68,0xC2,0x34 + ,0xC4,0xC6,0x62,0x8B ,0x80,0xDC,0x1C,0xD1 + ,0x29,0x02,0x4E,0x08 ,0x8A,0x67,0xCC,0x74 + ,0x02,0x0B,0xBE,0xA6 ,0x3B,0x13,0x9B,0x22 + ,0x51,0x4A,0x08,0x79 ,0x8E,0x34,0x04,0xDD + ,0xEF,0x95,0x19,0xB3 ,0xCD,0x3A,0x43,0x1B + ,0x30,0x2B,0x0A,0x6D ,0xF2,0x5F,0x14,0x37 + ,0x4F,0xE1,0x35,0x6D ,0x6D,0x51,0xC2,0x45 + ,0xE4,0x85,0xB5,0x76 ,0x62,0x5E,0x7E,0xC6 + ,0xF4,0x4C,0x42,0xE9 ,0xA6,0x37,0xED,0x6B + ,0x0B,0xFF,0x5C,0xB6 ,0xF4,0x06,0xB7,0xED + ,0xEE,0x38,0x6B,0xFB ,0x5A,0x89,0x9F,0xA5 + ,0xAE,0x9F,0x24,0x11 ,0x7C,0x4B,0x1F,0xE6 + ,0x49,0x28,0x66,0x51 ,0xEC,0xE4,0x5B,0x3D + ,0xC2,0x00,0x7C,0xB8 ,0xA1,0x63,0xBF,0x05 + ,0x98,0xDA,0x48,0x36 ,0x1C,0x55,0xD3,0x9A + ,0x69,0x16,0x3F,0xA8 ,0xFD,0x24,0xCF,0x5F + ,0x83,0x65,0x5D,0x23 ,0xDC,0xA3,0xAD,0x96 + ,0x1C,0x62,0xF3,0x56 ,0x20,0x85,0x52,0xBB + ,0x9E,0xD5,0x29,0x07 ,0x70,0x96,0x96,0x6D + ,0x67,0x0C,0x35,0x4E ,0x4A,0xBC,0x98,0x04 + ,0xF1,0x74,0x6C,0x08 ,0xCA,0x23,0x73,0x27 + ,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF +}; + +const u32_t OAKLEY_DEFAULT_DH_EXPONENT_SIZE = 20; /* bytes (= 160 bits) */ + +const u32_t OAKLEY_DEFAULT_NONCE_SIZE = (128 / 8); /* 128 bits */ + +//-------------------------------------------------- + +#if 0 + #define SAE_GROUP_PRIME OAKLEY_DEFAULT_GROUP_5_PRIME + #define SAE_GROUP_PRIME_LENGTH OAKLEY_DEFAULT_GROUP_5_PRIME_LENGTH + #define SAE_GROUP_GENERATOR OAKLEY_DEFAULT_GROUP_GENERATOR + #define SAE_GROUP_GENERATOR_LENGTH OAKLEY_DEFAULT_GROUP_GENERATOR_LENGTH +#else + #define SAE_GROUP_PRIME OAKLEY_DEFAULT_GROUP_2_PRIME + #define SAE_GROUP_PRIME_LENGTH OAKLEY_DEFAULT_GROUP_2_PRIME_LENGTH + #define SAE_GROUP_GENERATOR OAKLEY_DEFAULT_GROUP_GENERATOR + #define SAE_GROUP_GENERATOR_LENGTH OAKLEY_DEFAULT_GROUP_GENERATOR_LENGTH +#endif + +//-------------------------------------------------- + +#endif //#if !defined(_EAP_AM_DH_PRIMES_H_) + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_export.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_export.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_EXPORT_H_ ) +#define _EAP_EXPORT_H_ + +#if defined(EAP_NO_EXPORTS) + // No exports are needed. + #define EAP_FUNC_IMPORT + #define EAP_FUNC_EXPORT + #define EAP_C_FUNC_IMPORT + #define EAP_C_FUNC_EXPORT + #define EAP_FUNC_IMPORT_EMPTY + #define EAP_FUNC_EXPORT_EMPTY + #define EAP_EXPORT + #define EAP_NONSHARABLE_CLASS + #if defined(__WINS__) + #pragma warning( disable : 4355 ) + #endif /* defined(__WINS__) */ +#elif defined(__SYMBIAN32__) + // This is Symbian compilation. + #define EAP_FUNC_IMPORT IMPORT_C + #define EAP_FUNC_EXPORT EXPORT_C + #define EAP_C_FUNC_IMPORT IMPORT_C + #define EAP_C_FUNC_EXPORT EXPORT_C + #define EAP_FUNC_IMPORT_EMPTY + #define EAP_FUNC_EXPORT_EMPTY + #define EAP_EXPORT + #if defined(__WINS__) + #define EAP_NONSHARABLE_CLASS + #else + #define EAP_NONSHARABLE_CLASS __declspec(notshared) + #endif + #if defined(__WINS__) + #pragma warning( disable : 4355 ) + #endif /* defined(__WINS__) */ +#elif defined(linux) + // This is linux compilation. + #define EAP_FUNC_IMPORT + #define EAP_FUNC_EXPORT + #define EAP_C_FUNC_IMPORT + #define EAP_C_FUNC_EXPORT + #define EAP_FUNC_IMPORT_EMPTY + #define EAP_FUNC_EXPORT_EMPTY + #define EAP_EXPORT + #define EAP_NONSHARABLE_CLASS +#elif defined(__GNUC__) + // This is cygwin compilation. + #define EAP_FUNC_IMPORT __declspec(dllexport) + #define EAP_FUNC_EXPORT + #define EAP_C_FUNC_IMPORT __declspec(dllexport) + #define EAP_C_FUNC_EXPORT + #define EAP_FUNC_IMPORT_EMPTY + #define EAP_FUNC_EXPORT_EMPTY + #define EAP_EXPORT __declspec(dllexport) + #define EAP_NONSHARABLE_CLASS +#elif defined(_WIN32) && !defined(__GNUC__) + // This is windows compilation. + #define EAP_FUNC_IMPORT + #define EAP_FUNC_EXPORT + #define EAP_C_FUNC_IMPORT __declspec(dllexport) + #define EAP_C_FUNC_EXPORT + #define EAP_FUNC_IMPORT_EMPTY + #define EAP_FUNC_EXPORT_EMPTY + #define EAP_EXPORT __declspec(dllexport) + #define EAP_NONSHARABLE_CLASS + #if defined(__WINS__) + #pragma warning( disable : 4355 ) + #endif /* defined(__WINS__) */ +#endif + +// This is for separate exports of interface functions. +#if defined(USE_EAP_INTERFACE_EXPORTS) + #if defined(__SYMBIAN32__) + #define EAP_FUNC_IMPORT_INTERFACE IMPORT_C + #define EAP_FUNC_EXPORT_INTERFACE EXPORT_C + #define EAP_EXPORT_INTERFACE + #elif defined(linux) + #define EAP_FUNC_IMPORT_INTERFACE + #define EAP_FUNC_EXPORT_INTERFACE + #define EAP_EXPORT_INTERFACE + #elif defined(__GNUC__) + #define EAP_FUNC_IMPORT_INTERFACE __declspec(dllexport) + #define EAP_FUNC_EXPORT_INTERFACE + #define EAP_EXPORT_INTERFACE __declspec(dllexport) + #elif defined(_WIN32) && !defined(__GNUC__) + #define EAP_FUNC_IMPORT_INTERFACE + #define EAP_FUNC_EXPORT_INTERFACE + #define EAP_EXPORT_INTERFACE __declspec(dllexport) + #endif +#else + #define EAP_FUNC_IMPORT_INTERFACE EAP_FUNC_IMPORT + #define EAP_FUNC_EXPORT_INTERFACE EAP_FUNC_EXPORT + #define EAP_EXPORT_INTERFACE EAP_EXPORT +#endif //#if defined(USE_EAP_INTERFACE_EXPORTS) + +#endif //#if !defined( _EAP_EXPORT_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_fast_pac_store_services.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_fast_pac_store_services.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,169 @@ +/* +* Copyright (c) 2001-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_FAST_PAC_STORE_SERVICES_H_) +#define _EAP_AM_FAST_PAC_STORE_SERVICES_H_ + +#if defined(USE_FAST_EAP_TYPE) + +#include "eap_am_export.h" +#include "eap_tools.h" +#include "eap_fast_pac_store_types.h" +#include "eap_fast_tlv_header.h" + +class eap_variable_data_c; +class eap_fast_variable_data_c; +class abs_eap_state_notification_c; + +/** @file */ + +//---------------------------------------------------------------------------- + +/// This class defines PAC TLV. +/** + * PAC TLV is constructed with Attribute-Value Pairs. + */ +class EAP_EXPORT eap_am_fast_pac_store_services_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + virtual ~eap_am_fast_pac_store_services_c() {} + + /** + * Function queries user the permission for A-ID. + * This function is completed by complete_query_user_permission_for_A_ID() function call. + */ + virtual eap_status_e query_user_permission_for_A_ID( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + const eap_fast_variable_data_c * const in_pac_attribute_A_ID_info, + const eap_fast_variable_data_c * const in_pac_attribute_A_ID) = 0; + + /** + * Function reads the PAC store data referenced by parameter in_references. + * This function is completed by complete_read_PAC_store_data() function call. + */ + virtual eap_status_e read_PAC_store_data( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references) = 0; + + /** + * Function writes the PAC store data referenced by parameter in_references_and_data_blocks. + * This function is completed by complete_write_PAC_store_data() function call. + */ + virtual eap_status_e write_PAC_store_data( + const bool when_true_must_be_synchronous_operation, + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references_and_data_blocks) = 0; + + /** + * Function completes the add_PAC_TLV() function call. + */ + virtual eap_status_e complete_add_PAC_TLV( + const eap_status_e in_completion_status, + const eap_fast_completion_operation_e in_completion_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_saved_pac_types) = 0; + + /** + * This function call removes cached PAC store data. + */ + virtual eap_status_e remove_cached_pac_store_data() = 0; + + /** + * Function completes the add_imported_PAC_file() function call. + */ + virtual eap_status_e complete_add_imported_PAC_file( + const eap_status_e in_completion_status, + const eap_variable_data_c * const in_imported_PAC_filename, + const eap_variable_data_c * const out_used_group_reference) = 0; + + /** + * Function completes the query_PACs() function call. + */ + virtual eap_status_e complete_query_PACs( + const eap_status_e in_completion_status, + EAP_TEMPLATE_CONST eap_array_c * const out_matched_PACs, + const eap_variable_data_c * const out_used_group_reference) = 0; + + /** + * Function completes the remove_PAC() function call. + */ + virtual eap_status_e complete_remove_PAC( + const eap_status_e in_completion_status, + const eap_variable_data_c * const out_used_group_reference) = 0; + + /** + * Function completes the remove_IAP_reference() function call. + */ + virtual eap_status_e complete_remove_IAP_reference( + const eap_status_e in_completion_status) = 0; + + /** + * Function cancels all PAC store operations. + */ + virtual eap_status_e cancel_PAC_store_operations() = 0; + + /** + * The set_session_timeout() function changes the session timeout timer to be elapsed after session_timeout_ms milliseconds. + */ + virtual eap_status_e set_session_timeout( + const u32_t session_timeout_ms) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. EAP-type MUST send these + * two notifications to lower layer. + * These two notifications are sent using EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + * See also eap_state_notification_c. + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + * + * EAP-type should store it's parameters to an own database. The own database should be accessed + * through adaptation module of EAP-type. See eap_am_type_tls_peap_simulator_c::type_configure_read. + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + //-------------------------------------------------- +}; // class eap_am_fast_pac_store_services_c + + +#endif //#if defined(USE_FAST_EAP_TYPE) + +#endif //#if !defined(_EAP_AM_FAST_PAC_STORE_SERVICES_H_) + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_memory.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_memory.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,201 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_MEMORY_H_) +#define _EAP_MEMORY_H_ + + +#if !defined(USE_EAP_MEMORY_FUNCTIONS_FAILURES) + + #define g_eap_set_memory_parameters( \ + alloc_failures_probability, \ + alloc_failures_skip_count) + + #define g_eap_alloc_failures_enabled() + + #define g_eap_alloc_failures_disabled() + +#endif // #if defined(USE_EAP_MEMORY_FUNCTIONS_FAILURES) + + +#if defined(DMALLOC) || defined(USE_EAP_MEMORY_FUNCTIONS) + + #include "eap_tools.h" + #include "eap_variable_data.h" + #include "eap_am_export.h" + + + #if defined(USE_EAP_MEMORY_FUNCTIONS_FAILURES) + + void g_eap_set_memory_parameters( + const u32_t alloc_failures_probability, + const u32_t alloc_failures_skip_count); + + void g_eap_alloc_failures_enabled(); + + void g_eap_alloc_failures_disabled(); + + bool g_eap_alloc_failures_active(); + + #endif // #if defined(USE_EAP_MEMORY_FUNCTIONS_FAILURES) + + + #define USE_JPH_REALLOC + + #if defined(__GNUC__) + #include + #elif defined(__SYMBIAN32__) + #include + #endif + + #if defined(_WIN32) && !defined(__GNUC__) && defined(USE_MEMORY_LEAK_DETECTION) + #pragma message("Uses memory leak detection of WIN32.") + #define _CRTDBG_MAP_ALLOC + #include + #endif + + #if defined(_WIN32) || defined(__GNUC__) + #include + #endif + + #if defined(__cplusplus) || defined(__cc) + extern "C" { + #endif + + #if defined(_WIN32) || defined(__GNUC__) + /* + * An overload function the malloc. + */ + EAP_C_FUNC_IMPORT void *jph_malloc(size_t n); + + /* + * An overload function the malloc. + */ + EAP_C_FUNC_IMPORT void *jph_malloc_ex(size_t n, const char *file, int line); + + #if defined(USE_JPH_REALLOC) + /* + * An overload function the realloc. + */ + EAP_C_FUNC_IMPORT void *jph_realloc(void *oldbuf, size_t n); + + /* + * An overload function the realloc. + */ + EAP_C_FUNC_IMPORT void *jph_realloc_ex(void *oldbuf, size_t n, const char *file, int line); + #endif //#if defined(USE_JPH_REALLOC) + + #if defined(USE_JPH_CALLOC) + /* + * An overload function the calloc. + */ + EAP_C_FUNC_IMPORT void *jph_calloc(size_t count, size_t size); + #endif //#if defined(USE_JPH_CALLOC) + + /* + * An overload function for the free. + */ + EAP_C_FUNC_IMPORT void jph_free(void *cp); + + + EAP_C_FUNC_IMPORT void *jph_new(size_t n); + + EAP_C_FUNC_IMPORT void jph_delete(void *cp); + + #endif /* #if defined(_WIN32) */ + + #if defined(__cplusplus) || defined(__cc) + } + #endif + + + #if defined(__cplusplus) || defined(__cc) + + // NOTE, gcc does not need these prototypes. These are defined internally. + + #if defined(_WIN32) && !defined(__GNUC__) && !defined(__SYMBIAN32__) && !defined(USE_MEMORY_LEAK_DETECTION) + + inline void *operator new(size_t n) + { + return jph_new(n); + } + + inline void *operator new[](size_t n) + { + return jph_new(n); + } + + inline void operator delete(void *cp) + { + if (cp) + { + jph_delete(cp); + } + } + + inline void operator delete[](void *cp) + { + if (cp) + { + jph_delete(cp); + } + } + + #elif defined(__GNUC__) + + #include + + void *operator new(std::size_t n) throw (std::bad_alloc); + + void *operator new[](std::size_t n) throw (std::bad_alloc); + + void operator delete(void *cp) throw(); + + void operator delete[](void *cp) throw(); + + #endif //#if defined(WIN32) + + + #if defined(unix) + typedef int (*jph_new_handler) (size_t); + EAP_C_FUNC_IMPORT jph_new_handler jph_set_new_handler(jph_new_handler); + #elif defined(_WIN32) && !defined(__GNUC__) + typedef int (__cdecl * jph_new_handler) (size_t); + EAP_C_FUNC_IMPORT jph_new_handler __cdecl jph_set_new_handler(jph_new_handler); + #else + // Not supported in Symbian. + #endif + + + #endif // #if defined(__cplusplus) || defined(__cc) + +#elif defined(USE_EAP_GLOBAL_NEW_AND_DELETE_H) + + #include "GlobalNewAndDelete.h" + +#endif //#if defined(DMALLOC) || defined(USE_EAP_MEMORY_FUNCTIONS) + +#endif //#if !defined(_EAP_MEMORY_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_memory_store.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_memory_store.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,143 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined( _EAP_AM_MEMORY_STORE_H_ ) +#define _EAP_AM_MEMORY_STORE_H_ + +//#if !defined(NO_EAP_AM_MEMORY_STORE) + +#include "abs_eap_base_type.h" +#include "eap_am_memory_store_data.h" +#include "eap_core_map.h" +#include "eap_tlv_message_data.h" + + +/// This class is base class for data stored to memory store. +/** + * This class allows EAP objects store data to memory + * between authentication sessions. + */ +class eap_am_memory_store_c +: public abs_eap_am_memory_store_data_c +, public abs_eap_base_timer_c +{ +private: + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + eap_core_map_c< + eap_am_memory_store_tlv_data_c, + abs_eap_am_memory_store_data_c, + eap_variable_data_c> m_store_new; + + // This is counter to get unique timer IDs for each data stored. + u32_t m_timer_id_counter; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + // This is documented in abs_eap_stack_interface_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + +public: + + EAP_FUNC_IMPORT virtual ~eap_am_memory_store_c(); + + EAP_FUNC_IMPORT eap_am_memory_store_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT eap_status_e shutdown(); + + // This is documented in abs_eap_stack_interface_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + /// Memory store is visible only during the eap_am_tools_c object is alive. + /// This function add flat data to memory store. + /// You must format your data to eap_tlv_message_data_c object. + /// Data is identified by key parameter. + /// You can set timeout to data. Data will be automatically removed after timeout. + /// Timeout value zero means no timeout is set. + /// Serious WARNING: do use really good key values. + /// Memory store is globally used by all EAP Core objects. + /// Key must be good that other users do not use others data. + /// Add the real data type as a string to the key and other identifiers + /// that separate data between the other users that store same data type + /// to the memory store. + EAP_FUNC_IMPORT virtual eap_status_e add_data( + const eap_variable_data_c * const key, + const eap_tlv_message_data_c * const data, + const u32_t timeout); + + /// Memory store is visible only during the eap_am_tools_c object is alive. + /// This function gets data from memory store. + /// Data is returned in eap_tlv_message_data_c object. + /// Data is identified by key parameter. + /// Serious WARNING: do use really good key values. + /// Memory store is globally used by all EAP Core objects. + /// Key must be good that other users do not use others data. + /// Add the real data type as a string to the key and other identifiers + /// that separate data between the other users that store same data type + /// to the memory store. + EAP_FUNC_IMPORT virtual eap_status_e get_data( + const eap_variable_data_c * const key, + eap_tlv_message_data_c * const data); + + /// Memory store is visible only during the eap_am_tools_c object is alive. + /// This function removes data from memory store. + /// Data is identified by key parameter. + /// Serious WARNING: do use really good key values. + /// Memory store is globally used by all EAP Core objects. + /// Key must be good that other users do not use others data. + /// Add the real data type as a string to the key and other identifiers + /// that separate data between the other users that store same data type + /// to the memory store. + EAP_FUNC_IMPORT eap_status_e remove_data( + const eap_variable_data_c * const key); + + + /** + * Function timer_expired() is called after the timer is elapsed. + * @param id and data are set by caller of abs_eap_am_tools::set_timer() function. + * @param id could be used to separate different timer events. + * @param data could be pointer to any data that is needed in timer processing. + */ + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data); + + /** + * This function is called when timer event is deleted. + * Initialiser of the data must delete the data. + * Only the initializer knows the real type of data. + * @param id could be used to separate different timer events. + * @param data could be pointer to any data that is needed in timer processing. + */ + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data); +}; + +//#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) + +#endif //#if !defined( _EAP_AM_MEMORY_STORE_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_memory_store_data.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_memory_store_data.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined( _EAP_AM_TOOLS_MEMORY_STORE_DATA_H_ ) +#define _EAP_AM_TOOLS_MEMORY_STORE_DATA_H_ + + +#include "eap_am_export.h" +#include "eap_tlv_message_data.h" + +class eap_variable_data_c; +class abs_eap_am_tools_c; + + +/// This class is base class for data stored to memory store. +/** + * Here the functions eap_core_map_c template requires. + */ +class EAP_EXPORT eap_am_memory_store_tlv_data_c +{ +private: + + abs_eap_am_tools_c * const m_am_tools; + + eap_tlv_message_data_c m_tlv_data; + + u32_t m_timer_id; + +public: + + /** + * The destructor of the eap_am_memory_store_tlv_data_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_am_memory_store_tlv_data_c(); + + /** + * The constructor of the eap_am_memory_store_tlv_data_c does nothing special. + */ + EAP_FUNC_IMPORT eap_am_memory_store_tlv_data_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT eap_status_e copy_message_data( + const eap_tlv_message_data_c * const tlv_data, + const u32_t timer_id); + + EAP_FUNC_IMPORT u32_t get_timer_id() const; + + /** + * This function returns the pointer to the data. + * Empty message return NULL pointer. + */ + EAP_FUNC_IMPORT void * get_message_data() const; + + /** + * This function returns the length of the data. + * Empty message return zero. + */ + EAP_FUNC_IMPORT u32_t get_message_data_length() const; + + /** + * This function should increase reference count. + */ + EAP_FUNC_IMPORT void object_increase_reference_count(); + + /** + * This function should first decrease reference count + * and second return the remaining reference count. + * Reference count must not be decreased when it is zero. + */ + EAP_FUNC_IMPORT u32_t object_decrease_reference_count(); +}; + +#endif //#if !defined( _EAP_AM_TOOLS_MEMORY_STORE_DATA_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_network_id.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_network_id.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,247 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_NETWORK_ID_H_) +#define _EAP_NETWORK_ID_H_ + +#include "eap_tools.h" +#include "abs_eap_am_tools.h" +#include "eap_am_tools.h" +#include "eap_am_export.h" + +/// This class stores the protocol layer network identity. +/** + * A eap_am_network_id_c class. + * Network addresses are handled through eap_am_network_id_c class. + * It includes source and destination addresses and the type of packet. + * Addresses are mostly Ethernet addresses. Packet type is the type of Ethernet packet. + * The eap_am_network_id class stores the addresses using the eap_variable_data objects. + */ +class EAP_EXPORT eap_am_network_id_c +{ + +private: + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This struct decreases the memory print of eap_am_network_id_c. + class eap_am_network_id_impl_str + { + public: + ~eap_am_network_id_impl_str(); + + eap_am_network_id_impl_str( + abs_eap_am_tools_c * const tools); + + /// This is source address. + eap_variable_data_c m_source; + + /// This is destination address. + eap_variable_data_c m_destination; + + /// This is type of the packet. Mostly this is Ethernet type. + u16_t m_type; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + }; + + /// This is pointer to data of eap_am_network_id_c. + /// This decreases memory print of eap_am_network_id_c. + /// This decreases stack usage of EAP_Core. + eap_am_network_id_impl_str * m_data; + + eap_status_e initialize_members(); + + /** + * The set_is_valid() function sets the state of the eap_core object valid. + * The eap_core object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + +public: + + /** + * The destructor does nothing extra. The buffers of each address are + * freed in the destructor of the eap_variable_data class. + */ + EAP_FUNC_IMPORT virtual ~eap_am_network_id_c(); + + /** + * This version initializes the object. + * @param tools parameter is pointer to the tools class. + */ + EAP_FUNC_IMPORT eap_am_network_id_c( + abs_eap_am_tools_c * const tools); + + /** + * This version takes addresses as pointers to any data. + * This could be used to initialize addresses from the received packet. + * @param tools parameter is pointer to the tools class. + * @param source parameter is pointer to the source address. + * @param source_length parameter is length of the source address. + * @param destination parameter is pointer to the destination address. + * @param destination_length parameter is length of the destination address. + * @param type parameter is type of the packet. Mostly this is Ethernet type. + * @param free_id parameter indicates whether the source and destination buffers must be freed in destructors. + * @param writable_id parameter indicates whether the source and destination buffers are writable. + * + * NOTE the data buffers are NOT copied. + */ + EAP_FUNC_IMPORT eap_am_network_id_c( + abs_eap_am_tools_c * const tools, + const void * const source, + const u32_t source_length, + const void * const destination, + const u32_t destination_length, + const u16_t type, + const bool free_id, + const bool writable_id); + + /** + * This version takes addresses as pointers to eap_variable_data_c. + * @param tools parameter is pointer to the tools class. + * @param source parameter is pointer to the source address. + * @param destination parameter is pointer to the destination address. + * @param type parameter is type of the packet. Mostly this is Ethernet type. + * + * NOTE the data buffers are NOT copied. This is used to swap addresses of existing + * eap_am_network_id_c object and create a new object using existing addresses. + */ + EAP_FUNC_IMPORT eap_am_network_id_c( + abs_eap_am_tools_c * const tools, + const eap_variable_data_c * const source, + const eap_variable_data_c * const destination, + const u16_t type); + + /** + * This version uses the data from existing object. + * @param tools parameter is pointer to the tools class. + * @param network_id parameter is pointer to the existing object. + * + * NOTE this copies the addresses. + */ + EAP_FUNC_IMPORT eap_am_network_id_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const network_id); + + /** + * This function uses the data from existing object. + * @param network_id parameter is pointer to the existing object. + * + * NOTE this copies the addresses. + */ + EAP_FUNC_IMPORT eap_status_e set_copy_of_network_id( + const eap_am_network_id_c * const network_id); + + EAP_FUNC_IMPORT eap_status_e set_copy_of_am_network_id( + const void * const source, + const u32_t source_length, + const void * const destination, + const u32_t destination_length, + const u16_t type); + + /** + * The get_is_valid() function returns the status of the eap_core object. + * True indicates the object is initialized succesfully. + */ + EAP_FUNC_IMPORT bool get_is_valid() const; + + /** + * The get_is_valid_data() function returns the status of the eap_core object. + * True indicates the object does include valid addresses. + */ + EAP_FUNC_IMPORT bool get_is_valid_data() const; + + /** + * The get_source_id() function returns pointer to the source address. + */ + EAP_FUNC_IMPORT const eap_variable_data_c * get_source_id() const; + + /** + * The get_destination_id() function returns pointer to the destination address. + */ + EAP_FUNC_IMPORT const eap_variable_data_c * get_destination_id() const; + + + /** + * The get_source() function returns pointer to the source data. + */ + EAP_FUNC_IMPORT const u8_t * get_source() const; + + /** + * The get_destination() function returns pointer to the destination data. + */ + EAP_FUNC_IMPORT const u8_t * get_destination() const; + + + /** + * The get_source_length() function returns length of the source address. + */ + EAP_FUNC_IMPORT u32_t get_source_length() const; + + /** + * The get_destination_length() function returns length of the destination address. + */ + EAP_FUNC_IMPORT u32_t get_destination_length() const; + + /** + * The get_type() function returns type of the packet. + */ + EAP_FUNC_IMPORT u16_t get_type() const; + + /** + * The get_network_id() function returns pointer to this. + */ + EAP_FUNC_IMPORT const eap_am_network_id_c * get_network_id() const; + + /** + * The copy() function copies the eap_am_network_id object. + * The data of addresses are copied to new buffers. + */ + EAP_FUNC_IMPORT eap_am_network_id_c * copy() const; + + /** + * Compare the objects are identical. + * @return false if data of objects differs. + * @return true if data of objects are the same. + */ + EAP_FUNC_IMPORT bool compare_network_id(const eap_am_network_id_c * const network_id) const; + + /** + * The get_type() function sets type of the packet. + */ + EAP_FUNC_IMPORT void set_type(const u16_t type); + + /** + * Resets the object. + */ + EAP_FUNC_IMPORT void reset(); +}; + + +#endif //#if !defined(_EAP_NETWORK_ID_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_radius.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_radius.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,345 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_TYPE_RADIUS_H_) +#define _EAP_AM_TYPE_RADIUS_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "abs_eap_am_radius.h" +#include "eap_sim_triplets.h" +#include "eap_am_network_id.h" +#include "eap_radius_types.h" + + +/// This class is interface to adaptation module of RADIUS. +class EAP_EXPORT eap_am_radius_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_radius_c *m_am_partner; + abs_eap_am_tools_c *m_am_tools; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_am_radius_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + // + eap_am_radius_c(abs_eap_am_tools_c * const tools /*, abs_eap_am_radius_c * const partner */) + : m_am_partner(0) + , m_am_tools(tools) + , m_is_valid(false) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + set_is_valid(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + /** Function returns partner object of adaptation module of RADIUS. + * Partner object is the RADIUS object. + */ + abs_eap_am_radius_c * const get_am_partner() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_partner; + } + + /** Function sets partner object of adaptation module of RADIUS. + * Partner object is the RADIUS object. + */ + void set_am_partner(abs_eap_am_radius_c * const partner) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_am_partner = partner; + } + + void set_is_valid() + { + m_is_valid = true; + } + + bool get_is_valid() + { + return m_is_valid; + } + + virtual eap_status_e configure() = 0; + + virtual eap_status_e reset() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + /** RADIUS client calls this function. + * RADIUS AM could store copy of pseudonym identity to favourite place for future use. + * If parameter pseudonym is NULL pointer, AM should reset the existing pseudonym. + */ + virtual eap_status_e store_pseudonym_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const pseudonym) = 0; + + /** RADIUS client calls this function. + * RADIUS AM could store copy of reauthentication identity to favourite place for future use. + * If parameter reauthentication_identity is NULL pointer, AM should reset the existing reauthentication identity. + */ + virtual eap_status_e store_reauthentication_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const reauthentication_identity) = 0; + + /** RADIUS server and client calls this function. + * In order to use re-authentication, the client and the server need to + * store the following values: original XKEY, K_aut, K_encr, latest + * counter value and the next re-authentication identity. + * This function stores original XKEY, K_aut and K_encr. + */ + virtual eap_status_e store_reauth_parameters( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter) = 0; + + /** RADIUS client calls this function. + * RADIUS AM could do finishing operations to databases etc. based on authentication status and type. + */ + virtual eap_status_e authentication_finished( + const bool true_when_successfull, + const eap_radius_authentication_type_e authentication_type, + const eap_radius_identity_type identity_type) = 0; + + /** RADIUS server and client calls this function. + * In order to use re-authentication, the client and the server need to + * store the following values: original XKEY, K_aut, K_encr, latest + * counter value and the next re-authentication identity. + */ + virtual eap_status_e query_reauth_parameters( + eap_variable_data_c * const XKEY, + eap_variable_data_c * const K_aut, + eap_variable_data_c * const K_encr, + u32_t * const reauth_counter) = 0; + + /** RADIUS server and client calls this function. + * This function increases re-authentication counter after a successfull re-authentication. + */ + virtual eap_status_e increase_reauth_counter() = 0; + + /** RADIUS client calls this function. + * This call cancels asyncronous query_SIM_IMSI_or_pseudonym_or_reauthentication_id() function call. + * AM must not complete query_SIM_IMSI_or_pseudonym_or_reauthentication_id() + * with abs_eap_am_radius_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() after + * cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + */ + virtual eap_status_e cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() = 0; + + + /** RADIUS client calls this function. + * Input parameter n_rands includes n RANDs as input to SIM algorithm. + * AM could copy n_kc or n_sres to output parameters. + * This function could be completed asyncronously with abs_eap_am_radius_c::complete_SIM_kc_sres() function call. + */ + virtual eap_status_e query_SIM_kc_sres( + const bool must_be_synchronous, + const eap_variable_data_c * const n_rands, + eap_variable_data_c * const n_kc, + eap_variable_data_c * const n_sres) = 0; + + /** RADIUS client calls this function. + * This call cancels asyncronous query_SIM_kc_sres() function call. + * AM must not complete query_SIM_kc_sres() + * with abs_eap_am_radius_c::complete_SIM_kc_sres() after + * cancel_SIM_kc_sres_query() call. + */ + virtual eap_status_e cancel_SIM_kc_sres_query() = 0; + + + /** RADIUS client calls this function. + * Received AT_NOTIFICATION is handled in AM of RADIUS. + * AM could show localized message to user. + */ + virtual eap_status_e handle_radius_notification(eap_radius_notification_codes_e radius_notification_code) = 0; + + +#if defined(USE_EAP_TYPE_SERVER_RADIUS) + /** RADIUS server calls this function. + * AM could copy triplets to output parameters. + * This function could be completed asyncronously with abs_eap_am_radius_c::complete_SIM_triplets() function call. + */ + virtual eap_status_e query_SIM_triplets( + const bool must_be_synchronous, + const eap_variable_data_c * const username, ///< // This is payload AT_IDENTITY. If this is uninitialized then imsi must be initialized. + eap_variable_data_c * const imsi, ///< This is the real IMSI. If this is uninitialized then username must be initialized and imsi will be initialized after this call. + eap_type_sim_triplet_array_c * const triplets, + eap_radius_identity_type * const type) = 0; +#endif //#if defined(USE_EAP_TYPE_SERVER_RADIUS) + + +#if defined(USE_EAP_TYPE_SERVER_RADIUS) + /** RADIUS server calls this function. + * This call cancels asyncronous query_SIM_triplets() function call. + * AM must not complete query_SIM_triplets() with abs_eap_am_radius_c::complete_SIM_triplets() after + * cancel_SIM_triplets_query() call. + */ + virtual eap_status_e cancel_SIM_triplets_query() = 0; +#endif //#if defined(USE_EAP_TYPE_SERVER_RADIUS) + + /** RADIUS server calls this function. + * This function call generates with a good source of + * randomness the initialization vector (AT_IV payload). + */ + virtual eap_status_e generate_encryption_IV( + eap_variable_data_c * const encryption_IV, + const u32_t IV_length) = 0; + + /** RADIUS server calls this function. + * New pseudonym identity is generated for IMSI. + * Algorithm is freely selected. Look at query_imsi_from_username(). + * Pseudonym identity is copied to pseudonym_identity parameter. + * Maximum length of pseudonym is maximum_pseudonym_length bytes. + */ + virtual eap_status_e generate_pseudonym_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const pseudonym_identity, + const u32_t maximum_pseudonym_length) = 0; + + /** RADIUS server calls this function. + * New reauthentication identity is generated for IMSI. + * Algorithm is freely selected. Look at query_imsi_from_username(). + * Reauthentication identity is copied to pseudonym parameter. + * Maximum length of pseudonym is maximum_reauthentication_identity_length bytes. + */ + virtual eap_status_e generate_reauthentication_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const reauthentication_identity, + const u32_t maximum_reauthentication_identity_length) = 0; + + +#if defined(USE_EAP_TYPE_SERVER_RADIUS) + /** RADIUS server calls this function. + * Server queries IMSI with username. + * Username could be IMSI, pseudonym or re-authentication identity. + * Adaptation module must verify which username is. + * Adaptation module could map IMSI and username as it wish. + * It can select any algorithm. Look at generate_pseudonym_id() and generate_reauthentication_id(). + * Function must return IMSI and set the identity type of received username. + */ + virtual eap_status_e query_imsi_from_username( + const bool must_be_synchronous, + const u8_t next_eap_identifier, + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_radius_identity_type * const type, + const eap_radius_complete_e completion_action) = 0; +#endif //#if defined(USE_EAP_TYPE_SERVER_RADIUS) + + + /** RADIUS server calls this function. + * This call cancels asyncronous query_imsi_from_username() function call. + * AM must not complete query_imsi_from_username() + * with abs_eap_am_radius_c::complete_imsi_from_username() after + * cancel_imsi_from_username_query() call. + */ + virtual eap_status_e cancel_imsi_from_username_query() = 0; + + /** RADIUS client calls this function. + * This call could check whether the RANDs are already used. + * For example Bloom algorithm couls be used. + * Function must return eap_status_ok when RAND is not used before. + */ + virtual eap_status_e check_is_rand_unused(const eap_variable_data_c * const n_rands) = 0; + + /** RADIUS client calls this function. + * This call could set the RANDs used. + * For example Bloom algorithm couls be used. + * Function must return eap_status_ok when operation is successfull. + */ + virtual eap_status_e set_rand_is_used(const eap_variable_data_c * const n_rands) = 0; + + /** + * The type_configure_read() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + virtual eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The type_configure_write() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + virtual eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + //-------------------------------------------------- +}; // class eap_am_radius_c + + +/** @file */ + +/** + * This function creates a new instance of adaptation module of RADIUS EAP-type. + * @param tools is pointer to the abs_eap_am_tools class created by the adaptation module. + * RADIUS EAP-type will callback caller using the partner pointer. + */ +EAP_C_FUNC_IMPORT eap_am_radius_c *new_eap_am_radius( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const bool is_client_when_true); + + +#endif //#if !defined(_EAP_AM_TYPE_RADIUS_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_tools.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_tools.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,394 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_AM_TOOLS_H_ ) +#define _EAP_AM_TOOLS_H_ + +#include "abs_eap_am_tools.h" +#include "eap_variable_data.h" +#include "eap_tools.h" +#include "eap_status.h" +#include "eap_am_export.h" +#include "eap_status_string.h" +#include "abs_eap_am_memory_store_data.h" + + +//#if !defined(NO_EAP_AM_MEMORY_STORE) +class eap_tlv_message_data_c; +class eap_am_memory_store_c; +//#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) + + +/// This class defines the common functions of tools. +/// These are the platform independent functions used in tools. +class EAP_EXPORT eap_am_tools_c +: public abs_eap_am_tools_c +//#if !defined(NO_EAP_AM_MEMORY_STORE) +, public abs_eap_am_memory_store_data_c +//#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) +{ +private: + +#if !defined(NO_EAP_AM_MEMORY_STORE) + eap_am_memory_store_c * m_memory_store; +#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) + + /// This is trace mask. This could be changed dynamically with set_trace_mask() function. + u32_t m_trace_mask; + +#if defined(USE_EAP_ERROR_TESTS) + u32_t m_packet_index; +#endif //#if defined(USE_EAP_ERROR_TESTS) + + bool m_use_seconds_timestamp_in_traces; + + bool m_thread_stopped; + + bool m_use_timer_queue; + + /// Function shutdown_am_tools() is called already. + bool m_shutdown_was_called; + + /// This flag allows activation of trace when the error occurs. + /// Look at the set_activate_trace_on_error() and eap_status_return() + /// functions. + bool m_activate_trace_on_error; + + u8_t m_tmp_buffer[256]; + + u8_t m_tmp_ascii_buffer[256]; + + + EAP_FUNC_IMPORT u8_t octet_to_ascii_armor( + const u8_t source_byte); + + EAP_FUNC_IMPORT u8_t octet_from_ascii_armor( + const u8_t source_byte); + + EAP_FUNC_IMPORT void convert_selected_bytes_to_ascii_armor( + const u8_t source_byte, + u32_t * const saved_bit_count, + u8_t * const saved_bits, + u8_t * const target, + u32_t * const output_ind, + const bool last_input_byte); + + EAP_FUNC_IMPORT void restore_selected_bytes_from_ascii_armor( + const u8_t source_byte, + u32_t * const missing_bit_count, + u8_t * const target, + u32_t * const output_ind, + const bool last_input_byte); + +public: + + /// These are valid values used with set_trace_mask() function. + enum + { + eap_trace_mask_none = (0u), ///< This value disables all traces. + eap_trace_mask_always = (1u << 0u), ///< This values traces all permanent traces (EAP_TRACE_ALWAYS() macro). + eap_trace_mask_error = (1u << 1u), ///< This values traces all errors. + eap_trace_mask_debug = (1u << 2u), ///< This value traces debug information. Not used in released code. + eap_trace_mask_functions = (1u << 3u), ///< This value traces function enters and returns. + eap_trace_mask_crypto = (1u << 4u), ///< This value traces crypto data. Do not use on released code. All keys and intermediate values are traced. + eap_trace_mask_timer = (1u << 5u), ///< This value traces the timer functions. + eap_trace_mask_eap_messages = (1u << 6u), ///< This value traces only the EAP messages. + eap_trace_mask_test_vectors = (1u << 7u), ///< This value traces only the test vectors of each EAP-type. + eap_trace_mask_crypto_sha1 = (1u << 8u), ///< This value traces only internal state of SHA1. + eap_trace_mask_crypto_md4 = (1u << 9u), ///< This value traces only internal state of MD4. + eap_trace_mask_crypto_rc4 = (1u << 10u), ///< This value traces only internal state of RC4. + eap_trace_mask_crypto_test_random = (1u << 11u), ///< This value traces only internal state of test random generator. + eap_trace_mask_message_data = (1u << 12u), ///< This value traces only data of the messages, this will increase trace bloat. + eap_trace_mask_hash_map = (1u << 13u), ///< This value traces only data of hash table. It does map data and selector. + eap_trace_mask_timer_queue = (1u << 14u), ///< This value traces the timer queue. + eap_trace_mask_ok_returns = (1u << 15u), ///< This value traces the OK return values, alot of them. + }; + + EAP_FUNC_IMPORT u8_t octet_to_ascii(i32_t octet); + + EAP_FUNC_IMPORT u8_t ascii_to_octet(i32_t character); + + EAP_FUNC_IMPORT virtual ~eap_am_tools_c(); + + EAP_FUNC_IMPORT eap_am_tools_c(); + + EAP_FUNC_IMPORT bool get_use_seconds_timestamp_in_traces(); + + EAP_FUNC_IMPORT bool get_thread_stopped(); + + EAP_FUNC_IMPORT void set_use_timer_queue(); + + EAP_FUNC_IMPORT bool get_use_timer_queue(); + + EAP_FUNC_IMPORT u32_t get_trace_mask() const; + + EAP_FUNC_IMPORT void set_trace_mask(const u32_t mask); + + EAP_FUNC_IMPORT void set_activate_trace_on_error(); + + EAP_FUNC_IMPORT void check_activate_trace_on_error(); + + EAP_FUNC_IMPORT void trace_data(eap_const_string prefix, const void * const data, const u32_t data_length); + + EAP_FUNC_IMPORT eap_status_e timer_thread_function(); + + EAP_FUNC_IMPORT eap_status_e convert_ascii_to_uppercase( + u8_t * const source_bytes, + const u32_t source_bytes_length); + + EAP_FUNC_IMPORT eap_status_e convert_bytes_to_hex_ascii( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length); + + EAP_FUNC_IMPORT eap_status_e convert_bytes_to_hex_ascii( + const void * const source_bytes, + const u32_t source_bytes_length, + eap_variable_data_c * const target); + + EAP_FUNC_IMPORT eap_status_e convert_hex_ascii_to_bytes( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length); + + EAP_FUNC_IMPORT eap_status_e convert_hex_ascii_to_bytes( + const void * const source_bytes, + const u32_t source_bytes_length, + eap_variable_data_c * const target); + + + EAP_FUNC_IMPORT eap_status_e convert_bytes_to_ascii_armor( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length); + + EAP_FUNC_IMPORT eap_status_e restore_bytes_from_ascii_armor( + const u8_t * const source_bytes, + const u32_t source_bytes_length, + u8_t * const target, + u32_t *target_length); + + EAP_FUNC_IMPORT eap_status_e eap_status_return( + const bool print_error_when_true, + const eap_status_e status, + const eap_char * const file_name, + const i32_t line_number); + + EAP_FUNC_IMPORT eap_status_e eap_status_return_file_number( + const bool print_error_when_true, + const eap_status_e status, + const u32_t file_date, + const u32_t file_number, + const i32_t line_number); + + + // This is documented in abs_eap_am_tools_c::memory_store_add_data(). + EAP_FUNC_IMPORT eap_status_e memory_store_add_data( + const eap_variable_data_c * const key, + eap_tlv_message_data_c * const data, + const u32_t timeout); + + // This is documented in abs_eap_am_tools_c::memory_store_get_data(). + EAP_FUNC_IMPORT eap_status_e memory_store_get_data( + const eap_variable_data_c * const key, + eap_tlv_message_data_c * const data); + + // This is documented in abs_eap_am_tools_c::memory_store_remove_data(). + EAP_FUNC_IMPORT eap_status_e memory_store_remove_data( + const eap_variable_data_c * const key); + + + /// This function shuts down eap_am_tools_c object. + EAP_FUNC_IMPORT eap_status_e shutdown_am_tools(); + + /// The implementing function must call eap_am_tools_c::shutdown_am_tools(). + EAP_FUNC_IMPORT virtual eap_status_e shutdown() = 0; + + /** + * Function converts unicode characters into UTF8 characters. + * @param dest is reference to destination utf8 variable data. + * @param src is refrence to unicode variable data. + * @return eap status code. + */ + EAP_FUNC_IMPORT eap_status_e generic_convert_unicode_to_utf8( + eap_variable_data_c & dest, + const eap_variable_data_c & src); + + /** + * Function converts UTF8 characters into unicode characters. + * @param dest is reference to destination unicode variable data. + * @param src is refrence to UTF8 variable data. + * @return eap status code. + */ + EAP_FUNC_IMPORT eap_status_e generic_convert_utf8_to_unicode( + eap_variable_data_c & dest, + const eap_variable_data_c & src); + + /** + * Function parses NAI to usename and realm. + * If either is missing the corresponding value will be invalid. + */ + EAP_FUNC_IMPORT eap_status_e parse_nai( + const eap_variable_data_c * const nai, + eap_variable_data_c * const username, + eap_variable_data_c * const realm); + + +#if defined(USE_EAP_ERROR_TESTS) + EAP_FUNC_IMPORT eap_status_e generate_random_error( + eap_buf_chain_wr_c * const sent_packet, + const bool forse_error, + const u32_t packet_index, + const u32_t minimum_index, + const u32_t error_probability, + const u32_t minimum_packet_length); + + EAP_FUNC_IMPORT u32_t get_packet_index(); + + EAP_FUNC_IMPORT void increase_packet_index(); +#endif //#if defined(USE_EAP_ERROR_TESTS) + + + EAP_FUNC_IMPORT eap_status_e number_string_to_u32( + const u8_t * const number_string, + const u32_t number_string_length, + u32_t * const integer); + + EAP_FUNC_IMPORT void trace_configuration( + const eap_status_e configuration_read_status, + const eap_configuration_field_c * const field, + const eap_variable_data_c * const data); + + EAP_FUNC_IMPORT u64_t xor_u64(const u64_t a, const u64_t b); + + EAP_FUNC_IMPORT u64_t multiply_u64(const u64_t a, const u64_t b); + + EAP_FUNC_IMPORT i32_t compare_u64(const u64_t a, const u64_t b); + + EAP_FUNC_IMPORT eap_status_e create_uuid_v5( + const void* const ns_uuid, + const u32_t ns_uuid_length, + const void* const name, + const u32_t name_length, + eap_variable_data_c* const uuid ); + + EAP_FUNC_IMPORT eap_status_e create_uuid_v5_from_mac_address( + const u8_t* const mac_address, + const u32_t mac_address_length, + eap_variable_data_c* const uuid ); + +}; + +/** @file */ + +//----------------------------------------------------------------------------------------------- + +/// This is the default trace mask. +const u32_t TRACE_FLAGS_DEFAULT = eap_am_tools_c::eap_trace_mask_debug; +const u32_t TRACE_FLAGS_ERROR = eap_am_tools_c::eap_trace_mask_error; +const u32_t TRACE_FLAGS_ALWAYS = eap_am_tools_c::eap_trace_mask_always; + +const u32_t TRACE_TEST_VECTORS = eap_am_tools_c::eap_trace_mask_test_vectors; + +const u32_t EAP_TRACE_FLAGS_MESSAGE_DATA = eap_am_tools_c::eap_trace_mask_message_data; + +const u32_t EAP_TRACE_MASK_HASH_MAP = eap_am_tools_c::eap_trace_mask_hash_map; + +/// This mask activates an additional timer trace. +const u32_t TRACE_FLAGS_TIMER = eap_am_tools_c::eap_trace_mask_timer; +const u32_t TRACE_FLAGS_TIMER_QUEUE = eap_am_tools_c::eap_trace_mask_timer_queue; + +const u32_t TRACE_FLAGS_OK_RETURNS = eap_am_tools_c::eap_trace_mask_ok_returns; + +//----------------------------------------------------------------------------------------------- + +#if !defined(USE_EAP_STATUS_RETURN) + + #define EAP_STATUS_RETURN(tools, status) (status) + + #define EAP_STATUS_RETURN_WARNING(tools, status) (status) + +#else + + #if defined(USE_EAP_MINIMUM_RELEASE_TRACES) && !defined(_DEBUG) && !defined(DEBUG) + // This is used only in release version. + + #if !defined(EAP_FILE_NUMBER_ENUM) + #define EAP_FILE_NUMBER_ENUM 0ul + #endif //#if defined(EAP_FILE_NUMBER_ENUM) + + #if !defined(EAP_FILE_NUMBER_DATE) + #define EAP_FILE_NUMBER_DATE 0ul + #endif //#if defined(EAP_FILE_NUMBER_DATE) + + #define EAP_STATUS_RETURN(tools, status) \ + ((tools != 0 && (*(tools)).get_trace_mask()) \ + ? (*(tools)).eap_status_return_file_number( \ + true, \ + (status), \ + EAP_FILE_NUMBER_DATE, \ + EAP_FILE_NUMBER_ENUM, \ + __LINE__) \ + : status) + + #define EAP_STATUS_RETURN_WARNING(tools, status) \ + ((tools != 0 && (*(tools)).get_trace_mask()) \ + ? (*(tools)).eap_status_return_file_number( \ + false, \ + (status), \ + EAP_FILE_NUMBER_DATE, \ + EAP_FILE_NUMBER_ENUM, \ + __LINE__) \ + : status) + + #else + + #define EAP_STATUS_RETURN(tools, status) \ + ((tools != 0 && (*(tools)).get_trace_mask()) \ + ? (*(tools)).eap_status_return( \ + true, \ + (status), \ + __FILE__, \ + __LINE__) \ + : status) + + #define EAP_STATUS_RETURN_WARNING(tools, status) \ + ((tools != 0 && (*(tools)).get_trace_mask()) \ + ? (*(tools)).eap_status_return( \ + false, \ + (status), \ + __FILE__, \ + __LINE__) \ + : status) + + #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#endif //#if !defined(USE_EAP_STATUS_RETURN) + +//----------------------------------------------------------------------------------------------- + +#endif //#if !defined( _EAP_AM_TOOLS_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_trace.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_trace.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#error Not used any more. + +#if !defined(_EAP_AM_TRACE_H_) && 0 +#define _EAP_AM_TRACE_H_ + + +#include "eap_am_export.h" +#include "eap_variable_data.h" + + +class EAP_EXPORT abs_eap_am_trace_c +{ +public: + + /** + * Destructor does nothing special. + */ + virtual ~abs_eap_am_trace_c() + { + } + + virtual void formatted_print(eap_format_string format, ...) = 0; +}; + + +class EAP_EXPORT eap_am_trace_c +{ +public: + + /** + * Destructor does nothing special. + */ + virtual ~eap_am_trace_c() + { + } + + eap_am_trace_c(const char *pfilename); + + void formatted_print(eap_format_string format, ...); + +private: + + const eap_char *m_filename; + bool m_directory_exists; +}; + + +#endif //#if !defined(_EAP_AM_TRACE_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_type_aka.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_type_aka.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,343 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_TYPE_AKA_H_) +#define _EAP_AM_TYPE_AKA_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "abs_eap_am_type_aka.h" +#include "eap_sim_triplets.h" +#include "eap_am_network_id.h" + +/// This class is interface to adaptation module of AKA. +class EAP_EXPORT eap_am_type_aka_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_type_aka_c *m_am_partner; + abs_eap_am_tools_c *m_am_tools; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_am_type_aka_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + // + eap_am_type_aka_c(abs_eap_am_tools_c * const tools /*, abs_eap_am_type_aka_c * const partner */) + : m_am_partner(0) + , m_am_tools(tools) + , m_is_valid(false) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + set_is_valid(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + /** Function returns partner object of adaptation module of AKA. + * Partner object is the AKA object. + */ + abs_eap_am_type_aka_c * const get_am_partner() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_partner; + } + + /** Function sets partner object of adaptation module of AKA. + * Partner object is the AKA object. + */ + void set_am_partner(abs_eap_am_type_aka_c * const partner) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_am_partner = partner; + } + + void set_is_valid() + { + m_is_valid = true; + } + + bool get_is_valid() + { + return m_is_valid; + } + + virtual eap_status_e configure() = 0; + + virtual eap_status_e reset() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + /** AKA client calls this function. + * AKA AM could store copy of pseudonym identity to favourite place for future use. + * If parameter pseudonym is NULL pointer, AM should reset the existing pseudonym. + */ + virtual eap_status_e store_pseudonym_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const pseudonym) = 0; + + /** AKA client calls this function. + * AKA AM could store copy of reauthentication identity to favourite place for future use. + * If parameter reauthentication_identity is NULL pointer, AM should reset the existing reauthentication identity. + */ + virtual eap_status_e store_reauthentication_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const reauthentication_identity) = 0; + + /** AKA server and client calls this function. + * In order to use re-authentication, the client and the server need to + * store the following values: original XKEY, K_aut, K_encr, latest + * counter value and the next re-authentication identity. + * This function stores original XKEY, K_aut, K_encr and latest + * counter value. + */ + virtual eap_status_e store_reauth_parameters( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter) = 0; + + /** AKA client calls this function. + * AKA AM could do finishing operations to databases etc. based on authentication status and type. + */ + virtual eap_status_e authentication_finished( + const bool true_when_successfull, + const eap_aka_authentication_type_e authentication_type, + const eap_type_aka_identity_type identity_type) = 0; + + /** AKA server and client calls this function. + * In order to use re-authentication, the client and the server need to + * store the following values: original XKEY, K_aut, K_encr, latest + * counter value and the next re-authentication identity. + */ + virtual eap_status_e query_reauth_parameters( + eap_variable_data_c * const XKEY, + eap_variable_data_c * const K_aut, + eap_variable_data_c * const K_encr, + u32_t * const reauth_counter) = 0; + + /** AKA server and client calls this function. + * This function increases re-authentication counter after a successfull re-authentication. + */ + virtual eap_status_e increase_reauth_counter() = 0; + + /** AKA client calls this function. + * AM could copy IMSI or pseudonym to output parameters. + * AM must copy IMSI or pseudonym to output parameters. + * This function could be completed asyncronously with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + */ + virtual eap_status_e query_AKA_IMSI_or_pseudonym_or_reauthentication_id( + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const length_of_mnc, + const aka_payload_AT_type_e required_identity, ///< This parameter indicated the type of identity required. + const eap_type_aka_complete_e required_completion, ///< This parameter tells the required completion after this call is completed, if this is asyncronous. Use this value with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + const u8_t received_eap_identifier ///< This is the EAP-identifier of the received EAP-request message. Use this value with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + ) = 0; + + /** AKA client calls this function. + * This call cancels asyncronous query_AKA_IMSI_or_pseudonym_or_reauthentication_id() function call. + * AM must not complete query_AKA_IMSI_or_pseudonym_or_reauthentication_id() + * with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() after + * cancel_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + */ + virtual eap_status_e cancel_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() = 0; + + + /** AKA client calls this function. + * Input parameter RAND and AUTN as input to AKA algorithm. + * AM could copy CK, IK and RES to output parameters. + * This function could be completed asyncronously with abs_eap_am_type_aka_c::complete_AKA_RES_query() function call. + */ + virtual eap_status_e query_AKA_RES( + eap_type_aka_authentication_vector_c * const authentication_vector) = 0; + + /** AKA client calls this function. + * This call cancels asyncronous query_AKA_RES() function call. + * AM must not complete query_AKA_RES() + * with abs_eap_am_type_aka_c::complete_AKA_RES_query() after + * cancel_AKA_RES_query() call. + */ + virtual eap_status_e cancel_AKA_RES_query() = 0; + + + /** AKA client calls this function. + * Received AT_NOTIFICATION is handled in AM of AKA. + * AM could show localized message to user. + */ + virtual eap_status_e handle_aka_notification(eap_aka_notification_codes_e aka_notification_code) = 0; + + /** AKA server calls this function. + * AM could copy triplets to output parameters. + * This function could be completed asyncronously with abs_eap_am_type_aka_c::complete_AKA_authentication_vector_query() function call. + */ + virtual eap_status_e query_AKA_authentication_vector( + const eap_variable_data_c * const username, ///< // This is payload AT_IDENTITY. If this is uninitialized then imsi must be initialized. + const u8_t next_eap_identifier, + eap_variable_data_c * const imsi, ///< This is the real IMSI. If this is uninitialized then username must be initialized and imsi will be initialized after this call. + eap_type_aka_authentication_vector_c * const authentication_vector, + eap_type_aka_identity_type * const type) = 0; + + /** AKA server calls this function. + * This call cancels asyncronous query_AKA_authentication_vector() function call. + * AM must not complete query_AKA_authentication_vector() with abs_eap_am_type_aka_c::complete_AKA_authentication_vector_query() after + * cancel_AKA_authentication_vector_query() call. + */ + virtual eap_status_e cancel_AKA_authentication_vector_query() = 0; + + /** AKA server calls this function. + * This function call generates with a good source of + * randomness the initialization vector (AT_IV payload). + */ + virtual eap_status_e generate_encryption_IV( + eap_variable_data_c * const encryption_IV, + const u32_t IV_length) = 0; + + /** AKA server calls this function. + * New pseudonym identity is generated for IMSI. + * Algorithm is freely selected. Look at query_imsi_from_username(). + * Pseudonym identity is copied to pseudonym_identity parameter. + * Maximum length of pseudonym is maximum_pseudonym_length bytes. + */ + virtual eap_status_e generate_pseudonym_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const pseudonym_identity, + const u32_t maximum_pseudonym_length) = 0; + + /** AKA server calls this function. + * New reauthentication identity is generated for IMSI. + * Algorithm is freely selected. Look at query_imsi_from_username(). + * Reauthentication identity is copied to pseudonym parameter. + * Maximum length of pseudonym is maximum_reauthentication_identity_length bytes. + */ + virtual eap_status_e generate_reauthentication_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const reauthentication_identity, + const u32_t maximum_reauthentication_identity_length) = 0; + + + /** AKA server calls this function. + * Server queries IMSI with username. + * Username could be IMSI, pseudonym or re-authentication identity. + * Adaptation module must verify which username is. + * Adaptation module could map IMSI and username as it wish. + * It can select any algorithm. Look at generate_pseudonym_id() and generate_reauthentication_id(). + * Function must return IMSI and set the identity type of received username. + */ + virtual eap_status_e query_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_type_aka_identity_type * const type, + const eap_type_aka_complete_e completion_action) = 0; + + /** AKA server calls this function. + * Server queries re-syncronization. + * This function call is completed by complete_re_syncronization_query() function. + */ + virtual eap_status_e query_re_syncronization( + const u8_t next_eap_identifier, + eap_type_aka_authentication_vector_c * const authentication_vector + ) = 0; + + /** AKA server calls this function. + * This call cancels asyncronous query_imsi_from_username() function call. + * AM must not complete query_imsi_from_username() + * with abs_eap_am_type_aka_c::complete_imsi_from_username() after + * cancel_imsi_from_username_query() call. + */ + virtual eap_status_e cancel_imsi_from_username_query() = 0; + + /** + * The type_configure_read() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + virtual eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The type_configure_write() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + virtual eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + //-------------------------------------------------- +}; // class eap_am_type_aka_c + + +/** @file */ + +/** + * This function creates a new instance of adaptation module of AKA EAP-type. + * @param tools is pointer to the abs_eap_am_tools class created by the adaptation module. + * AKA EAP-type will callback caller using the partner pointer. + */ +EAP_C_FUNC_IMPORT eap_am_type_aka_c *new_eap_am_type_aka( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + +#endif //#if !defined(_EAP_AM_TYPE_AKA_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_type_gsmsim.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_type_gsmsim.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,363 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_TYPE_GSMSIM_H_) +#define _EAP_AM_TYPE_GSMSIM_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "abs_eap_am_type_gsmsim.h" +#include "eap_sim_triplets.h" +#include "eap_am_network_id.h" +#include "eap_type_gsmsim_types.h" + + +/// This class is interface to adaptation module of GSMSIM. +class EAP_EXPORT eap_am_type_gsmsim_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_type_gsmsim_c *m_am_partner; + abs_eap_am_tools_c *m_am_tools; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_am_type_gsmsim_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + // + eap_am_type_gsmsim_c(abs_eap_am_tools_c * const tools /*, abs_eap_am_type_gsmsim_c * const partner */) + : m_am_partner(0) + , m_am_tools(tools) + , m_is_valid(false) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + set_is_valid(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + /** Function returns partner object of adaptation module of GSMSIM. + * Partner object is the GSMSIM object. + */ + abs_eap_am_type_gsmsim_c * const get_am_partner() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_partner; + } + + /** Function sets partner object of adaptation module of GSMSIM. + * Partner object is the GSMSIM object. + */ + void set_am_partner(abs_eap_am_type_gsmsim_c * const partner) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_am_partner = partner; + } + + void set_is_valid() + { + m_is_valid = true; + } + + bool get_is_valid() + { + return m_is_valid; + } + + virtual eap_status_e configure() = 0; + + virtual eap_status_e reset() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + /** GSMSIM client calls this function. + * GSMSIM AM could store copy of pseudonym identity to favourite place for future use. + * If parameter pseudonym is NULL pointer, AM should reset the existing pseudonym. + */ + virtual eap_status_e store_pseudonym_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const pseudonym) = 0; + + /** GSMSIM client calls this function. + * GSMSIM AM could store copy of reauthentication identity to favourite place for future use. + * If parameter reauthentication_identity is NULL pointer, AM should reset the existing reauthentication identity. + */ + virtual eap_status_e store_reauthentication_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const reauthentication_identity) = 0; + + /** GSMSIM server and client calls this function. + * In order to use re-authentication, the client and the server need to + * store the following values: original XKEY, K_aut, K_encr, latest + * counter value and the next re-authentication identity. + * This function stores original XKEY, K_aut and K_encr. + */ + virtual eap_status_e store_reauth_parameters( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter) = 0; + + /** GSMSIM client calls this function. + * GSMSIM AM could do finishing operations to databases etc. based on authentication status and type. + */ + virtual eap_status_e authentication_finished( + const bool true_when_successfull, + const eap_gsmsim_authentication_type_e authentication_type, + const eap_type_gsmsim_identity_type identity_type) = 0; + + /** GSMSIM server and client calls this function. + * In order to use re-authentication, the client and the server need to + * store the following values: original XKEY, K_aut, K_encr, latest + * counter value and the next re-authentication identity. + */ + virtual eap_status_e query_reauth_parameters( + eap_variable_data_c * const XKEY, + eap_variable_data_c * const K_aut, + eap_variable_data_c * const K_encr, + u32_t * const reauth_counter) = 0; + + /** GSMSIM server and client calls this function. + * This function increases re-authentication counter after a successfull re-authentication. + */ + virtual eap_status_e increase_reauth_counter() = 0; + + /** GSMSIM client calls this function. + * AM could copy IMSI or pseudonym to output parameters if must_be_synchronous parameter is false. + * AM must copy IMSI or pseudonym to output parameters if must_be_synchronous parameter is true. + * This function could be completed asyncronously with abs_eap_am_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + */ + virtual eap_status_e query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + const bool must_be_synchronous, + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const length_of_mnc, + const gsmsim_payload_AT_type_e required_identity, ///< This parameter indicated the type of identity required. + const eap_type_gsmsim_complete_e required_completion, ///< This parameter tells the required completion after this call is completed, if this is asyncronous. Use this value with abs_eap_am_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + const u8_t received_eap_identifier ///< This is the EAP-identifier of the received EAP-request message. Use this value with abs_eap_am_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + ) = 0; + + /** GSMSIM client calls this function. + * This call cancels asyncronous query_SIM_IMSI_or_pseudonym_or_reauthentication_id() function call. + * AM must not complete query_SIM_IMSI_or_pseudonym_or_reauthentication_id() + * with abs_eap_am_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() after + * cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + */ + virtual eap_status_e cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() = 0; + + + /** GSMSIM client calls this function. + * Input parameter n_rands includes n RANDs as input to SIM algorithm. + * AM could copy n_kc or n_sres to output parameters. + * This function could be completed asyncronously with abs_eap_am_type_gsmsim_c::complete_SIM_kc_sres() function call. + */ + virtual eap_status_e query_SIM_kc_sres( + const bool must_be_synchronous, + const eap_variable_data_c * const n_rands, + eap_variable_data_c * const n_kc, + eap_variable_data_c * const n_sres) = 0; + + /** GSMSIM client calls this function. + * This call cancels asyncronous query_SIM_kc_sres() function call. + * AM must not complete query_SIM_kc_sres() + * with abs_eap_am_type_gsmsim_c::complete_SIM_kc_sres() after + * cancel_SIM_kc_sres_query() call. + */ + virtual eap_status_e cancel_SIM_kc_sres_query() = 0; + + + /** GSMSIM client calls this function. + * Received AT_NOTIFICATION is handled in AM of GSMSIM. + * AM could show localized message to user. + */ + virtual eap_status_e handle_gsmsim_notification(eap_gsmsim_notification_codes_e gsmsim_notification_code) = 0; + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** GSMSIM server calls this function. + * AM could copy triplets to output parameters. + * This function could be completed asyncronously with abs_eap_am_type_gsmsim_c::complete_SIM_triplets() function call. + */ + virtual eap_status_e query_SIM_triplets( + const bool must_be_synchronous, + const eap_variable_data_c * const username, ///< // This is payload AT_IDENTITY. If this is uninitialized then imsi must be initialized. + eap_variable_data_c * const imsi, ///< This is the real IMSI. If this is uninitialized then username must be initialized and imsi will be initialized after this call. + eap_type_sim_triplet_array_c * const triplets, + eap_type_gsmsim_identity_type * const type) = 0; +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** GSMSIM server calls this function. + * This call cancels asyncronous query_SIM_triplets() function call. + * AM must not complete query_SIM_triplets() with abs_eap_am_type_gsmsim_c::complete_SIM_triplets() after + * cancel_SIM_triplets_query() call. + */ + virtual eap_status_e cancel_SIM_triplets_query() = 0; +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + /** GSMSIM server calls this function. + * This function call generates with a good source of + * randomness the initialization vector (AT_IV payload). + */ + virtual eap_status_e generate_encryption_IV( + eap_variable_data_c * const encryption_IV, + const u32_t IV_length) = 0; + + /** GSMSIM server calls this function. + * New pseudonym identity is generated for IMSI. + * Algorithm is freely selected. Look at query_imsi_from_username(). + * Pseudonym identity is copied to pseudonym_identity parameter. + * Maximum length of pseudonym is maximum_pseudonym_length bytes. + */ + virtual eap_status_e generate_pseudonym_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const pseudonym_identity, + const u32_t maximum_pseudonym_length) = 0; + + /** GSMSIM server calls this function. + * New reauthentication identity is generated for IMSI. + * Algorithm is freely selected. Look at query_imsi_from_username(). + * Reauthentication identity is copied to pseudonym parameter. + * Maximum length of pseudonym is maximum_reauthentication_identity_length bytes. + */ + virtual eap_status_e generate_reauthentication_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const reauthentication_identity, + const u32_t maximum_reauthentication_identity_length) = 0; + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** GSMSIM server calls this function. + * Server queries IMSI with username. + * Username could be IMSI, pseudonym or re-authentication identity. + * Adaptation module must verify which username is. + * Adaptation module could map IMSI and username as it wish. + * It can select any algorithm. Look at generate_pseudonym_id() and generate_reauthentication_id(). + * Function must return IMSI and set the identity type of received username. + */ + virtual eap_status_e query_imsi_from_username( + const bool must_be_synchronous, + const u8_t next_eap_identifier, + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_type_gsmsim_identity_type * const type, + const eap_type_gsmsim_complete_e completion_action) = 0; +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + /** GSMSIM server calls this function. + * This call cancels asyncronous query_imsi_from_username() function call. + * AM must not complete query_imsi_from_username() + * with abs_eap_am_type_gsmsim_c::complete_imsi_from_username() after + * cancel_imsi_from_username_query() call. + */ + virtual eap_status_e cancel_imsi_from_username_query() = 0; + + /** GSMSIM client calls this function. + * This call could check whether the RANDs are already used. + * For example Bloom algorithm couls be used. + * Function must return eap_status_ok when RAND is not used before. + */ + virtual eap_status_e check_is_rand_unused(const eap_variable_data_c * const n_rands) = 0; + + /** GSMSIM client calls this function. + * This call could set the RANDs used. + * For example Bloom algorithm couls be used. + * Function must return eap_status_ok when operation is successfull. + */ + virtual eap_status_e set_rand_is_used(const eap_variable_data_c * const n_rands) = 0; + + /** + * The type_configure_read() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + virtual eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The type_configure_write() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + virtual eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + //-------------------------------------------------- +}; // class eap_am_type_gsmsim_c + + +/** @file */ + +/** + * This function creates a new instance of adaptation module of GSMSIM EAP-type. + * @param tools is pointer to the abs_eap_am_tools class created by the adaptation module. + * GSMSIM EAP-type will callback caller using the partner pointer. + */ +EAP_C_FUNC_IMPORT eap_am_type_gsmsim_c *new_eap_am_type_gsmsim( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + +#endif //#if !defined(_EAP_AM_TYPE_GSMSIM_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_type_leap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_type_leap.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,134 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAP_AM_TYPE_LEAP_H +#define EAP_AM_TYPE_LEAP_H + +// INCLUDES +#include "abs_eap_am_type_leap.h" + +// CLASS DECLARATION + +/// This class is interface to adaptation module of LEAP. +class EAP_EXPORT eap_am_type_leap_c +{ + public: // Methods + + // Constructors and destructor + + eap_am_type_leap_c(abs_eap_am_tools_c * const tools) + : m_am_partner(0) + , m_am_tools(tools) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + virtual ~eap_am_type_leap_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + virtual eap_status_e shutdown() = 0; + + /** Function returns partner object of adaptation module of LEAP. + * Partner object is the LEAP object. + */ + abs_eap_am_type_leap_c * const get_am_partner() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_partner; + } + + /** Function sets partner object of adaptation module of LEAP. + * Partner object is the LEAP object. + */ + void set_am_partner(abs_eap_am_type_leap_c * const partner) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_am_partner = partner; + } + + virtual void set_is_valid() = 0; + + virtual bool get_is_valid() = 0; + + virtual eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + virtual eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + virtual eap_status_e configure() = 0; + + virtual eap_status_e reset() = 0; + + virtual eap_status_e show_username_password_dialog( + eap_variable_data_c &username_utf8, + eap_variable_data_c &password_utf8, + bool &password_prompt_enabled, + bool is_identity_query) = 0; + + virtual eap_status_e read_auth_failure_string(eap_variable_data_c &string) = 0; + + /// This function queries unique key for memory store object of this access. + virtual eap_status_e get_memory_store_key(eap_variable_data_c * const memory_store_key) = 0; + + /** + * Returns true if the full authenticated session is valid. + * It finds the difference between current time and the + * last full authentication time. If the difference is less than the + * Maximum Session Validity Time, then session is valid, returns true. + * Otherwise returns false. + * Full authentication (using pw query) should be done if the session is not valid. + */ + virtual bool is_session_valid() = 0; + + /** + * Stores current universal time as the the full authentication time + * in the database. + * Returns appropriate error if storing fails. eap_status_ok for successful storing. + */ + virtual eap_status_e store_authentication_time() = 0; + + private: // Data + + abs_eap_am_type_leap_c * m_am_partner; + + abs_eap_am_tools_c * m_am_tools; + +protected: + +}; + + +EAP_C_FUNC_IMPORT eap_am_type_leap_c *new_eap_am_type_leap( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + +#endif // EAP_AM_TYPE_LEAP_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_type_mschapv2.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_type_mschapv2.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,156 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAP_AM_TYPE_MSCHAPV2_H_ +#define _EAP_AM_TYPE_MSCHAPV2_H_ + +#include "abs_eap_am_type_mschapv2.h" + +enum eap_mschapv2_error_e { + EAP_MSCHAPV2_ERROR_RESTRICTED_LOGON_HOURS = 646, + EAP_MSCHAPV2_ERROR_ACCT_DISABLED = 647, + EAP_MSCHAPV2_ERROR_PASSWD_EXPIRED = 648, + EAP_MSCHAPV2_ERROR_NO_DIALIN_PERMISSION = 649, + EAP_MSCHAPV2_ERROR_AUTHENTICATION_FAILURE = 691, + EAP_MSCHAPV2_ERROR_CHANGING_PASSWORD = 709 +}; + +/// This class is interface to adaptation module of Ms-Chap-v2. +class EAP_EXPORT eap_am_type_mschapv2_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_type_mschapv2_c *m_am_partner; + abs_eap_am_tools_c *m_am_tools; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_am_type_mschapv2_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + eap_am_type_mschapv2_c(abs_eap_am_tools_c * const tools /*, abs_eap_am_type_mschapv2_c * const partner */) + : m_am_partner(0) + , m_am_tools(tools) + , m_is_valid(false) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + set_is_valid(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + virtual eap_status_e shutdown() = 0; + + /** Function returns partner object of adaptation module of MSCHAPV2. + * Partner object is the MSCHAPV2 object. + */ + abs_eap_am_type_mschapv2_c * const get_am_partner() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_partner; + } + + /** Function sets partner object of adaptation module of MSCHAPV2. + * Partner object is the MSCHAPV2 object. + */ + void set_am_partner(abs_eap_am_type_mschapv2_c * const partner) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_am_partner = partner; + } + + void set_is_valid() + { + m_is_valid = true; + } + + bool get_is_valid() + { + return m_is_valid; + } + + virtual eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + virtual eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + virtual eap_status_e configure() = 0; + + virtual eap_status_e reset() = 0; + + virtual eap_status_e show_username_password_dialog( + eap_variable_data_c & username, + eap_variable_data_c & password, + bool & password_prompt_enabled, + bool is_identity_query) = 0; + + virtual eap_status_e show_change_password_dialog( + eap_variable_data_c & username, + eap_variable_data_c & old_password, + eap_variable_data_c & password, + bool & password_prompt_enabled) = 0; + + virtual eap_status_e update_username_password() = 0; + + virtual eap_status_e read_auth_failure_string(eap_mschapv2_error_e error_code, eap_variable_data_c &string) = 0; + + /// This function queries unique key for memory store object of this access. + virtual eap_status_e get_memory_store_key(eap_variable_data_c * const memory_store_key) = 0; + + /** + * Returns true if the full authenticated session is valid. + * It finds the difference between current time and the + * last full authentication time. If the difference is less than the + * Maximum Session Validity Time, then session is valid, returns true. + * Otherwise returns false. + * Full authentication (using pw query) should be done if the session is not valid. + */ + virtual bool is_session_valid() = 0; + + /** + * Stores current universal time as the the full authentication time + * in the database. + * Returns appropriate error if storing fails. eap_status_ok for successful storing. + */ + virtual eap_status_e store_authentication_time() = 0; + +}; + +EAP_C_FUNC_IMPORT eap_am_type_mschapv2_c *new_eap_am_type_mschapv2( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const eap_am_network_id_c * const receive_network_id); + +#endif diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_type_securid.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_type_securid.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,124 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef EAP_AM_TYPE_SECURID_H +#define EAP_AM_TYPE_SECURID_H + +#include "abs_eap_am_type_securid.h" + +/// This class is interface to adaptation module of EAP SecurID +class EAP_EXPORT eap_am_type_securid_c +{ +private: + + abs_eap_am_type_securid_c *m_am_partner; + abs_eap_am_tools_c *m_am_tools; + + bool m_is_valid; + +protected: + +public: + + virtual ~eap_am_type_securid_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + eap_am_type_securid_c(abs_eap_am_tools_c * const tools /*, abs_eap_am_type_securid_c * const partner */) + : m_am_partner(0) + , m_am_tools(tools) + , m_is_valid(false) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + set_is_valid(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + virtual eap_status_e shutdown() = 0; + + /** Function returns partner object of adaptation module of EAP SecurID. + * Partner object is the EAP SecurID object. + */ + abs_eap_am_type_securid_c * const get_am_partner() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_partner; + } + + /** Function sets partner object of adaptation module of SECURID. + * Partner object is the SECURID object. + */ + void set_am_partner(abs_eap_am_type_securid_c * const partner) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_am_partner = partner; + } + + void set_is_valid() + { + m_is_valid = true; + } + + bool get_is_valid() + { + return m_is_valid; + } + + virtual eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + virtual eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + virtual eap_status_e configure() = 0; + + virtual eap_status_e reset() = 0; + + virtual eap_status_e show_identity_query_dialog(eap_type_value_e eap_type, eap_variable_data_c * const identity) = 0; + + virtual eap_status_e show_passcode_query_dialog(eap_variable_data_c * const passcode, + bool is_first_query) = 0; + + virtual eap_status_e show_pincode_query_dialog(eap_variable_data_c * const passcode, + eap_variable_data_c * const pincode, + bool is_first_query) = 0; + + virtual eap_status_e show_gtc_query_dialog(eap_variable_data_c * const passcode, + const u8_t * const message, + u32_t message_length, + bool is_first_query) = 0; + + virtual eap_status_e read_auth_failure_string(eap_variable_data_c * const string) = 0; + + /// This function queries unique key for memory store object of this access. + virtual eap_status_e get_memory_store_key(eap_variable_data_c * const memory_store_key) = 0; +}; + +EAP_C_FUNC_IMPORT eap_am_type_securid_c *new_eap_am_type_securid( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const eap_type_value_e eap_type, + const eap_am_network_id_c * const receive_network_id); + +#endif // EAP_AM_TYPE_SECURID_H diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_type_sim.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_type_sim.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_TYPE_SIM_H_) +#define _EAP_AM_TYPE_SIM_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "abs_eap_am_type_sim.h" +#include "eap_sim_triplets.h" + +// +class EAP_EXPORT eap_am_type_sim_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_type_sim_c *m_am_partner; + abs_eap_am_tools_c *m_am_tools; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_am_type_sim_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + // + eap_am_type_sim_c(abs_eap_am_tools_c * const tools, abs_eap_am_type_sim_c * const partner) + : m_am_partner(partner) + , m_am_tools(tools) + , m_is_valid(false) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + set_is_valid(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + // + abs_eap_am_type_sim_c * const get_am_partner() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_partner; + } + + void set_is_valid() + { + m_is_valid = true; + } + + bool get_is_valid() + { + return m_is_valid; + } + + // + virtual eap_status_e query_SIM_imsi( + u8_t * const imsi, const u32_t max_length, u32_t * const imsi_length) = 0; + + // + virtual eap_status_e query_SIM_kc_and_sres( + const u8_t * const imsi, const u32_t imsi_length, + const u8_t * const rand, const u32_t rand_length, + u8_t * const kc, u32_t * const kc_length, + u8_t * const sres, u32_t * const sres_length) = 0; + + // + virtual eap_status_e query_SIM_triplets( + const eap_variable_data_c * const imsi, + eap_type_sim_triplet_array_c * const triplets) = 0; + + // + virtual eap_status_e query_SIM_kc_sres( + const eap_variable_data_c * const n_rands, + eap_variable_data_c * const n_kc, + eap_variable_data_c * const n_sres) = 0; + + //-------------------------------------------------- +}; // class eap_am_type_sim_c + +#endif //#if !defined(_EAP_AM_TYPE_SIM_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_type_simple_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_type_simple_config.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,206 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_TYPE_SIMPLE_CONFIG_H_) +#define _EAP_AM_TYPE_SIMPLE_CONFIG_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_header.h" +#include "eap_am_export.h" +#include "abs_eap_am_type_simple_config.h" +#include "eap_am_network_id.h" +#include "simple_config_am_services.h" + +class abs_eap_base_type_c; +class eap_base_type_c; +class abs_eap_am_type_simple_config_c; +class abs_eap_configuration_if_c; + +/// This class is interface to adaptation module of EAP/SIMPLE_CONFIG. +class EAP_EXPORT eap_am_type_simple_config_c +: public simple_config_am_services_c +{ +private: + //-------------------------------------------------- + + /** Function returns partner object of adaptation module of EAP-SIMPLE_CONFIG. + * Partner object is the EAP-SIMPLE_CONFIG object. + */ + virtual abs_eap_am_type_simple_config_c * get_am_partner() = 0; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + virtual ~eap_am_type_simple_config_c() + { + } + + /** Function sets partner object of adaptation module of EAP-SIMPLE_CONFIG. + * Partner object is the EAP-SIMPLE_CONFIG object. + */ + virtual void set_am_partner(abs_eap_am_type_simple_config_c * const partner) = 0; + + virtual eap_status_e configure() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + virtual bool get_is_valid() = 0; + + /** Client calls this function. + * EAP-SIMPLE_CONFIG AM could do finishing operations to databases etc. based on authentication status and type. + */ + virtual eap_status_e reset() = 0; + + /** Client calls this function. + * EAP-SIMPLE_CONFIG AM could make some fast operations here, heavy operations should be done in the reset() function. + */ + virtual eap_status_e authentication_finished( + const bool true_when_successfull, + const bool true_when_session_resumed) = 0; + + /** Client calls this function. + * AM must copy identity to output parameters if call is syncronous. + * This function could be completed asyncronously with abs_eap_am_type_simple_config_c::complete_query_eap_identity_query() function call. + */ + virtual eap_status_e query_eap_identity( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + bool * const use_manual_username, + eap_variable_data_c * const manual_username, + bool *const use_manual_realm, + eap_variable_data_c * const manual_realm + ) = 0; + + /** Client calls this function. + * This call cancels asyncronous query_SIM_IMSI_or_pseudonym_or_reauthentication_id() function call. + * AM must not complete query_SIM_IMSI_or_pseudonym_or_reauthentication_id() + * with abs_eap_am_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() after + * cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + */ + virtual eap_status_e cancel_identity_query() = 0; + + /** + * The type_configure_read() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + virtual eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The type_configure_write() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + virtual eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is needed by PEAP type. + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + /** + * This is needed by PEAP type. + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + /** + * This is needed by PEAP type. + * The unload_module() function unloads the module of a EAP-type. + * @param type is the requested EAP-type. + */ + virtual eap_status_e unload_module(const eap_type_value_e type) = 0; + + + //-------------------------------------------------- +}; // class eap_am_type_simple_config_c + + +/** @file */ + +/** + * This function creates a new instance of adaptation module of EAP-SIMPLE_CONFIG-type. + * @param tools is pointer to the abs_eap_am_tools class created by the adaptation module. + * EAP-SIMPLE_CONFIG-type will callback caller using the partner pointer. + */ +EAP_C_FUNC_IMPORT eap_am_type_simple_config_c *new_eap_am_type_simple_config( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const eap_type_value_e eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if); + + +#endif //#if !defined(_EAP_AM_TYPE_SIMPLE_CONFIG_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_type_tls_peap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_type_tls_peap.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,211 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_TYPE_TLS_PEAP_H_) +#define _EAP_AM_TYPE_TLS_PEAP_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_header.h" +#include "eap_am_export.h" +#include "abs_eap_am_type_tls_peap.h" +#include "eap_am_network_id.h" +#include "tls_am_services.h" + +#if defined(USE_FAST_EAP_TYPE) +#include "tls_am_application_eap_fast.h" +#endif //#if defined(USE_FAST_EAP_TYPE) + +class abs_eap_base_type_c; +class eap_base_type_c; + +/// This class is interface to adaptation module of EAP/TLS and PEAP. +class EAP_EXPORT eap_am_type_tls_peap_c +: public tls_am_services_c +#if defined(USE_FAST_EAP_TYPE) +, public tls_am_application_eap_fast_c +#endif //#if defined(USE_FAST_EAP_TYPE) +{ +private: + //-------------------------------------------------- + + /** Function returns partner object of adaptation module of EAP-TLS/PEAP. + * Partner object is the EAP-TLS/PEAP object. + */ + virtual abs_eap_am_type_tls_peap_c * get_am_partner() = 0; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + virtual ~eap_am_type_tls_peap_c() + { + } + + /** Function sets partner object of adaptation module of EAP-TLS/PEAP. + * Partner object is the EAP-TLS/PEAP object. + */ + virtual void set_am_partner(abs_eap_am_type_tls_peap_c * const partner) = 0; + + virtual eap_status_e configure() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + virtual bool get_is_valid() = 0; + + /** Client calls this function. + * EAP-TLS/PEAP AM could do finishing operations to databases etc. based on authentication status and type. + */ + virtual eap_status_e reset() = 0; + + /** Client calls this function. + * EAP-TLS/PEAP AM could make some fast operations here, heavy operations should be done in the reset() function. + */ + virtual eap_status_e authentication_finished( + const bool true_when_successfull, + const tls_session_type_e tls_session_type) = 0; + + /** Client calls this function. + * AM must copy identity to output parameters if call is syncronous. + * This function could be completed asyncronously with abs_eap_am_type_tls_peap_c::complete_query_eap_identity_query() function call. + */ + virtual eap_status_e query_eap_identity( + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + bool * const use_manual_username, + eap_variable_data_c * const manual_username, + bool *const use_manual_realm, + eap_variable_data_c * const manual_realm + ) = 0; + + /** Client calls this function. + * This call cancels asyncronous query_SIM_IMSI_or_pseudonym_or_reauthentication_id() function call. + * AM must not complete query_SIM_IMSI_or_pseudonym_or_reauthentication_id() + * with abs_eap_am_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() after + * cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + */ + virtual eap_status_e cancel_identity_query() = 0; + + /** + * The type_configure_read() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + virtual eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The type_configure_write() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + virtual eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is needed by PEAP type. + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + /** + * This is needed by PEAP type. + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + /** + * This is needed by PEAP type. + * The unload_module() function unloads the module of a EAP-type. + * @param type is the requested EAP-type. + */ + virtual eap_status_e unload_module(const eap_type_value_e type) = 0; + + + //-------------------------------------------------- +}; // class eap_am_type_tls_peap_c + + +/** @file */ + +/** + * This function creates a new instance of adaptation module of EAP-TLS/PEAP EAP-type. + * @param tools is pointer to the abs_eap_am_tools class created by the adaptation module. + * EAP-TLS/PEAP EAP-type will callback caller using the partner pointer. + */ +EAP_C_FUNC_IMPORT eap_am_type_tls_peap_c *new_eap_am_type_tls_peap( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const eap_type_value_e eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + +#endif //#if !defined(_EAP_AM_TYPE_TLS_PEAP_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,225 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +/** @file */ + +#if !defined(_EAP_AM_TYPES_H_) +#define _EAP_AM_TYPES_H_ + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if !defined(EAP_NO_STDINT_H_HEADER) +#if defined(__GNUC__) + #include +#endif //#if defined(__GNUC__) +#endif //#if !defined(EAP_NO_STDINT_H_HEADER) + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(__SYMBIAN32__) + /// This is unsigned 64-bit integer. + /// Actual implementation may be signed 64-bit integer. + /// This depends on Symbian version. + typedef unsigned long long u64_t; +#elif defined(__WINSCW__) + /// This is unsigned 64-bit integer. + typedef unsigned long long u64_t; +#elif defined(__GNUC__) + /// This is unsigned 64-bit integer. +#if defined(EAP_NO_STDINT_H_HEADER) + typedef unsigned long long u64_t; +#else + typedef uint64_t u64_t; +#endif //#if defined(EAP_NO_STDINT_H_HEADER) +#else + /// This is unsigned 64-bit integer. Actually there is not unsigned version. + typedef __int64 u64_t; +#endif + +/// This is unsigned 32-bit integer. +typedef unsigned long int u32_t; +/// This is unsigned 16-bit integer. +typedef unsigned short int u16_t; +/// This is unsigned 8-bit integer. +typedef unsigned char u8_t; + +#if defined(__WINSCW__) + /// This is signed 64-bit integer. + typedef long long i64_t; +#elif defined(__GNUC__) + /// This is signed 64-bit integer. +#if defined(EAP_NO_STDINT_H_HEADER) + typedef long long i64_t; +#else + typedef int64_t i64_t; +#endif //#if defined(EAP_NO_STDINT_H_HEADER) +#else + /// This is signed 64-bit integer. + typedef __int64 i64_t; +#endif + +/// This is signed 32-bit integer. +typedef long int i32_t; + +#if defined(__WINSCW__) + /// This is signed 16-bit integer. + typedef short i16_t; +#else + /// This is signed 16-bit integer. + typedef short int i16_t; +#endif + + /// This is signed 32-bit integer. +typedef char i8_t; + + +typedef struct + { +#if defined(EAP_BIG_ENDIAN) + u32_t high; + u32_t low; +#elif defined(EAP_LITTLE_ENDIAN) + u32_t low; + u32_t high; +#endif + } u64_struct; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(__SYMBIAN32__) + + /** + * This defines const reserved word for template types. + * This is because the stupid Windows compiler cannot compile "const template_type * const". + */ + #define EAP_TEMPLATE_CONST const + +#elif defined(__GNUC__) || defined(__arm) + + /** + * This defines const reserved word for template types. + * This is because the stupid Windows compiler cannot compile "const template_type * const". + */ + #define EAP_TEMPLATE_CONST const + +#elif defined(_WIN32) + + /** + * This defines const reserved word for template types. + * This is because the stupid Windows compiler cannot compile "const template_type * const". + */ + #define EAP_TEMPLATE_CONST + +#endif + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(__SYMBIAN32__) + + /** + * This attribute defines parameter unused. This is not supported in Symbian. + */ + #define EAP_ATTRIBUTE_UNUSED + +#elif defined(__GNUC__) + + /** + * This attribute defines parameter unused. This is not supported in Symbian. + */ + #define EAP_ATTRIBUTE_UNUSED __attribute__((unused)) + +#elif defined(_WIN32) + + /** + * This attribute defines parameter unused. This is not supported in windows. + */ + #define EAP_ATTRIBUTE_UNUSED + +#else + + /** + * This attribute defines parameter unused. This is not supported in windows. + */ + #define EAP_ATTRIBUTE_UNUSED + +#endif + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(__SYMBIAN32__) + #include + + /// This is character type. + typedef i8_t eap_char; + /// This is constant string type. + typedef const eap_char * eap_const_string; + /// This is format string type. + typedef eap_const_string eap_format_string; + /// Literal string definition. This is not used currently. + #define EAPLIT(symbol,param) param + /// Literal string definition. + #define EAPL(param) param + + /// This defines literal for database use. + #define EAP_AM_CONFIGURATION_FIELD_LITERAL(name, field) \ + _LIT( name##_literal, field ) + +#elif defined(_WIN32) || defined(__GNUC__) || defined(__arm) + /// This is character type. + typedef i8_t eap_char; + /// This is constant string type. + typedef const eap_char * eap_const_string; + /// This is format string type. + typedef eap_const_string eap_format_string; + /// Literal string definition. This is not used currently. + #define EAPLIT(symbol,param) param + /// Literal string definition. + #define EAPL(param) param + + /// This is not needed here. + #define EAP_AM_CONFIGURATION_FIELD_LITERAL(name, field) +#else + #error platform not supported, do something. +#endif + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/// This is configure string type. +typedef const i8_t * eap_config_string; + +#if !defined(__SYMBIAN32__) + #if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS) + #include + typedef FILE EAP_FILE_POINTER; + #endif // #if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS) +#endif // !defined(__SYMBIAN32__) + +#if defined(USE_EAP_INLINE_FUNCTIONS) + #define EAP_INLINE inline +#else + #define EAP_INLINE +#endif //#if defined(USE_EAP_INLINE_FUNCTIONS) + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#endif //#if !defined(_EAP_AM_TYPES_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_am_wimax_authentication.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_am_wimax_authentication.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,166 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP stack interface for Wimax. +* +*/ + + +#if !defined(_EAP_AM_WIMAX_AUTHENTICATION_H_) +#define _EAP_AM_WIMAX_AUTHENTICATION_H_ + +#include +#include +#include +#include + +class abs_eap_am_wimax_authentication_c; +class abs_eap_am_tools_c; +class abs_eap_base_type_c; +class eap_base_type_c; +class eap_am_network_id_c; +class eap_type_selection_c; +class abs_eapol_wlan_database_reference_if_c; +class abs_eap_state_notification_c; + +/// This is interface to adaptation module of class eap_wimax_authentication_c. +class EAP_EXPORT eap_am_wimax_authentication_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_am_wimax_authentication_c(); + + EAP_FUNC_IMPORT static eap_am_wimax_authentication_c* new_eap_am_wimax_authentication( + abs_eap_am_tools_c * const tools, + const bool is_client_when_true, + const abs_eapol_wlan_database_reference_if_c * const wimax_database_reference + ); + + /// This is documented in abs_eap_stack_interface_c::get_is_valid(). + virtual bool get_is_valid() = 0; + + /// This is documented in abs_eap_stack_interface_c::configure(). + virtual eap_status_e configure() = 0; + + /// This is documented in abs_eap_stack_interface_c::shutdown(). + virtual eap_status_e shutdown() = 0; + + /// Function sets the parther object of this object. + virtual eap_status_e set_am_partner( + abs_eap_am_wimax_authentication_c * am_partner + ) = 0; + + /// Function resets current EAP-configuration. + virtual eap_status_e reset_eap_configuration() = 0; + + /// This is documented in eap_wimax_authentication.h. + virtual eap_status_e set_wimax_parameters( + eap_variable_data_c* const routing_info, + eap_variable_data_c* const nai_decoration) = 0; + + /** + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param tunneling_type is the EAP-type that tunnels the type. When plain EAP-type is used this parameter is eap_type_none. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + * @param receive_network_id includes the addresses (network identity) and packet type. + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ) = 0; + + /** + * The unload_module() function unloads the module of a EAP-type. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e unload_module( + const eap_type_value_e type) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + //-------------------------------------------------- +}; // class eap_am_wimax_authentication_c + +#endif //#if !defined(_EAP_AM_WIMAX_AUTHENTICATION_H_) + +//-------------------------------------------------- + + + +// End. + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_file_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_file_config.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,247 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _FILECONFIG_H +#define _FILECONFIG_H + +#include "eap_core_map.h" +#include "eap_configuration_field.h" +#include "abs_eap_am_file_input.h" + + +template +Type minimum( Type a, Type b ) +{ + return a < b ? a : b; +} + + +class eap_config_value_c +{ +private: + + abs_eap_am_tools_c* const m_am_tools; + + eap_core_map_c * m_subsection_map; + + eap_variable_data_c m_data; + + eap_configure_type_e m_type; + + bool m_is_valid; + +public: + + virtual ~eap_config_value_c(); + + eap_config_value_c( + abs_eap_am_tools_c* const tools); + + void set_subsection( + eap_core_map_c * const subsection_map); + + eap_core_map_c * get_subsection(); + + eap_variable_data_c * get_data(); + + void set_type(const eap_configure_type_e type); + + eap_configure_type_e get_type(); + + void object_increase_reference_count(); + + bool get_is_valid(); + +}; + +const u32_t MAX_LINE_LENGTH = 1024; +const u32_t MAX_CONFIG_TYPE_LENGTH = 32; + + +struct eap_configure_type +{ + char id[MAX_CONFIG_TYPE_LENGTH]; + u32_t id_length; + eap_configure_type_e type; +}; + + +const char * const EAP_FILECONFIG_TRUE = "true"; +const char * const EAP_FILECONFIG_FALSE = "false"; + + +const char EAP_FILECONFIG_SECTION[] = "section:"; +const u32_t EAP_FILECONFIG_SECTION_LENGTH = (sizeof(EAP_FILECONFIG_SECTION)-1ul); + +const char EAP_FILECONFIG_SECTION_START[] = "{"; +const u32_t EAP_FILECONFIG_SECTION_START_LENGTH = (sizeof(EAP_FILECONFIG_SECTION_START)-1ul); + +const char EAP_FILECONFIG_SECTION_END[] = "}"; +const u32_t EAP_FILECONFIG_SECTION_END_LENGTH = (sizeof(EAP_FILECONFIG_SECTION_END)-1ul); + + +/// Keep this on the same order as eap_configure_type_e. +const eap_configure_type eap_configure_type_id[] = +{ + { + "none:", + 5u, + eap_configure_type_none + }, + { + "u32_t:", + 6u, + eap_configure_type_u32_t + }, + { + "bool:", + 5u, + eap_configure_type_boolean + }, + { + "string:", + 7u, + eap_configure_type_string + }, + { + "hex:", + 4u, + eap_configure_type_hex_data + }, + { + "u32array:", + 9u, + eap_configure_type_u32array + }, +}; + + +class EAP_EXPORT eap_file_config_c +: public abs_eap_core_map_c +{ + + private: + abs_eap_am_tools_c* const m_am_tools; + + /// This stores eap_config_value_c objects using eap_variable_data selector. + eap_core_map_c m_config_map; + + bool m_is_valid; + + EAP_FUNC_IMPORT eap_status_e expand_environment_variables( + eap_core_map_c * const config_map, + const eap_variable_data_c * const value, + eap_variable_data_c * const expanded_value + ); + + EAP_FUNC_IMPORT eap_status_e remove_spaces(eap_variable_data_c * const buffer); + + EAP_FUNC_IMPORT eap_status_e remove_leading_spaces(eap_variable_data_c * const line); + + EAP_FUNC_IMPORT eap_status_e read_section( + abs_eap_am_file_input_c * const file, + eap_core_map_c * const config_map); + + EAP_FUNC_IMPORT eap_status_e read_subsections( + abs_eap_am_file_input_c * const file, + eap_core_map_c * const config_map); + + EAP_FUNC_IMPORT eap_status_e get_subsect( + abs_eap_am_file_input_c * const file, + eap_variable_data_c * const line); + + EAP_FUNC_IMPORT eap_status_e convert_value( + eap_core_map_c * const config_map, + const eap_variable_data_c * const value_buffer, + const eap_configure_type_e type, + eap_variable_data_c * const value_data); + + EAP_FUNC_IMPORT eap_status_e store_configure( + abs_eap_am_file_input_c * const file, + const eap_variable_data_c * const line, + eap_core_map_c * const config_map); + + EAP_FUNC_IMPORT eap_status_e cnf_parse_value( + const eap_variable_data_c * const found_type_value, + const eap_variable_data_c * const found_type_name, + eap_configure_type_e * const parsed_type, + eap_variable_data_c * const parsed_type_value, + const bool is_environment_variable); + + EAP_FUNC_IMPORT eap_status_e cnf_get_string( + const eap_variable_data_c * const param, + eap_variable_data_c * const param_name, + eap_variable_data_c * const param_value, + eap_configure_type_e * const type); + + EAP_FUNC_IMPORT eap_status_e find_rvalue( + const eap_variable_data_c * const config_param, + bool * const read_env_value, + eap_variable_data_c * const param_name, + eap_variable_data_c * const param_value + ); + + EAP_FUNC_IMPORT u8_t * read_hex_byte(u8_t * cursor, const u8_t * const end, u8_t * const hex_byte); + + EAP_FUNC_IMPORT u8_t * read_u32_t(u8_t * cursor, const u8_t * const end, u32_t * const hex_byte); + + EAP_FUNC_IMPORT eap_status_e read_configure( + eap_core_map_c * const config_map, + const eap_configuration_field_c * const field, + eap_variable_data_c* const data, + eap_configure_type_e * const configuration_data_type, + const bool existence_test); + + EAP_FUNC_IMPORT eap_status_e file_read_line( + abs_eap_am_file_input_c * const file, + eap_variable_data_c * const line); + + EAP_FUNC_IMPORT eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c* const data, + eap_core_map_c * const config_map, + const bool check_subsection_when_true); + + public: + + EAP_FUNC_IMPORT eap_file_config_c( + abs_eap_am_tools_c* const tools); + + EAP_FUNC_IMPORT virtual ~eap_file_config_c(); + + EAP_FUNC_IMPORT eap_status_e configure( + abs_eap_am_file_input_c * const file); + + EAP_FUNC_IMPORT eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c* const data); + + bool get_is_valid() const + { + return m_is_valid; + } + + void set_is_valid() + { + m_is_valid = true; + } +}; + +#endif /* #ifndef _FILECONFIG_H */ + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eap_sim_triplets.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eap_sim_triplets.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,120 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_SIM_TRIPLETS_H_) +#define _EAP_SIM_TRIPLETS_H_ + +//#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_variable_data.h" + + +//----------------------------------------------- + +const u32_t SIM_RAND_LENGTH = 16u; +const u32_t SIM_KC_LENGTH = 8u; +const u32_t SIM_SRES_LENGTH = 4u; + + +class EAP_EXPORT eap_type_saesim_triplet_c +{ +private: + + eap_variable_data_c *m_kc; + eap_variable_data_c *m_rand; + eap_variable_data_c *m_sres; + bool m_is_valid; + +public: + + EAP_FUNC_IMPORT virtual ~eap_type_saesim_triplet_c(); + + EAP_FUNC_IMPORT eap_type_saesim_triplet_c( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT void reset(); + + EAP_FUNC_IMPORT eap_status_e set_triplet( + eap_variable_data_c * const kc, + eap_variable_data_c * const rand, + eap_variable_data_c * const sres + ); + + EAP_FUNC_IMPORT eap_type_saesim_triplet_c * copy( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT eap_variable_data_c *get_kc(); + + EAP_FUNC_IMPORT eap_variable_data_c *get_rand(); + + EAP_FUNC_IMPORT eap_variable_data_c *get_sres(); +}; + +//----------------------------------------------- + +class EAP_EXPORT eap_type_sim_triplet_array_c +{ +private: + + u32_t m_triplet_count; + eap_type_saesim_triplet_c **m_array; + abs_eap_am_tools_c * m_am_tools; + +public: + + EAP_FUNC_IMPORT virtual ~eap_type_sim_triplet_array_c(); + + EAP_FUNC_IMPORT eap_type_sim_triplet_array_c( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT eap_status_e set_triplet_count( + const u32_t triplet_count + ); + + EAP_FUNC_IMPORT eap_type_saesim_triplet_c * add_triplet(); + + EAP_FUNC_IMPORT eap_type_saesim_triplet_c * get_triplet(abs_eap_am_tools_c * const m_am_tools, u32_t index); + + EAP_FUNC_IMPORT eap_status_e set_triplet(u32_t index, eap_type_saesim_triplet_c * const triplet); + + EAP_FUNC_IMPORT u32_t get_triplet_count(); + + EAP_FUNC_IMPORT eap_type_sim_triplet_array_c * copy(); + + EAP_FUNC_IMPORT void reset(); + +}; + + +#endif //#if !defined(_EAP_SIM_TRIPLETS_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/eapol_am_wlan_authentication.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/eapol_am_wlan_authentication.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,252 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_AM_WLAN_AUTHENTICATION_H_) +#define _EAPOL_AM_WLAN_AUTHENTICATION_H_ + +#include "eap_am_export.h" +#include "eap_status.h" +#include "eap_header.h" +#include "eap_array.h" +#include "eapol_key_types.h" + +class abs_eapol_am_wlan_authentication_c; +class abs_eap_am_tools_c; +class abs_eap_base_type_c; +class eap_base_type_c; +class eap_am_network_id_c; +class eap_type_selection_c; +class abs_eapol_wlan_database_reference_if_c; +class abs_eap_state_notification_c; + +#if defined(USE_EAP_SIMPLE_CONFIG) +class abs_eap_configuration_if_c; +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + +/// This is interface to adaptation module of class eapol_wlan_authentication_c. +class EAP_EXPORT eapol_am_wlan_authentication_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eapol_am_wlan_authentication_c(); + + /// @param tools: Constructor takes parameter tools that is pointer to adaptation of the platform. + /// @param is_client_when_true: Second parameter is true when object is client and false when object is server. + /// @param wlan_database_reference: third parameter is pointer to interface to read the current database reference. + EAP_FUNC_IMPORT static eapol_am_wlan_authentication_c * new_eapol_am_wlan_authentication( + abs_eap_am_tools_c * const tools, + const bool is_client_when_true, + const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference + ); + + /// This is documented in abs_eap_stack_interface_c::get_is_valid(). + virtual bool get_is_valid() = 0; + + /// This is documented in abs_eap_stack_interface_c::configure(). + virtual eap_status_e configure() = 0; + + /// This is documented in abs_eap_stack_interface_c::shutdown(). + virtual eap_status_e shutdown() = 0; + + /// Function sets the parther object of this object. + virtual eap_status_e set_am_partner( + abs_eapol_am_wlan_authentication_c * am_partner +#if defined(USE_EAP_SIMPLE_CONFIG) + , abs_eap_configuration_if_c * const configuration_if +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + ) = 0; + + /// Function resets current EAP-configuration. + virtual eap_status_e reset_eap_configuration() = 0; + + /// Function sets the new WLAN parameters. + virtual eap_status_e set_wlan_parameters( + const eap_variable_data_c * const SSID, + const bool WPA_override_enabled, + const eap_variable_data_c * const wpa_preshared_key, + const eapol_key_authentication_type_e selected_eapol_key_authentication_type) = 0; + + /// New association is completed. + virtual eap_status_e association( + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ) = 0; + + /// Previous connection was disassiciated. + virtual eap_status_e disassociation( + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ) = 0; + + /** + * This function queries the selected and active EAP-types that can be used + * in current connection. + */ + virtual eap_status_e get_selected_eap_types( + eap_array_c * const selected_eap_types) = 0; + + /// Function gets the current WLAN configuration, now only the HASH of the WPA(2)-PSK. + virtual eap_status_e get_wlan_configuration( + eap_variable_data_c * const wpa_preshared_key_hash) = 0; + + /** + * This function indicates finish of the authentication to adatation module. + * @param when_true_successfull tells whether authentication was successfull (true) or not (false). + * @param eap_type tells the used EAP-type. + * @param authentication_type tells the used WLAN authentication type. + */ + virtual eap_status_e authentication_finished( + const bool when_true_successfull, + const eap_type_value_e eap_type, + const eapol_key_authentication_type_e authentication_type) = 0; + + /** + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param tunneling_type is the EAP-type that tunnels the type. When plain EAP-type is used this parameter is eap_type_none. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + * @param receive_network_id includes the addresses (network identity) and packet type. + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ) = 0; + + /** + * The unload_module() function unloads the module of a EAP-type. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e unload_module( + const eap_type_value_e type) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * @param p_time_ms is time of timer to elapse in milli seconds. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * @param initializer is the object that initialised the timer. + * @param id is the identity of the timer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + /** + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + //-------------------------------------------------- +}; // class eapol_am_wlan_authentication_c + +#endif //#if !defined(_EAPOL_AM_WLAN_AUTHENTICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/ms_mppe_keys.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/ms_mppe_keys.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,145 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_MS_MPPE_KEYS_H_) +#define _MS_MPPE_KEYS_H_ + + +//---------------------------------------------------------------------------- + +// Here is copy from draft-ietf-radius-mschap-attr-01.txt: +// +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Vendor-ID | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Vendor-Type | Vendor-Length | Keys | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Keys (cont) total 24 bytes | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Keys (cont) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Keys (cont) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Keys (cont) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Keys (cont) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Keys (cont) | Padding | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Padding | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Padding | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +const u32_t MPPE_LM_KEY_LENGTH = 8u; +const u32_t MPPE_NT_KEY_LENGTH = 16u; +const u32_t MPPE_PADDING_LENGTH = 8u; + +#pragma pack(1) + +// +class mppe_keys_c +{ +private: + //-------------------------------------------------- + + u32_t m_vendor_id; + u8_t m_vendor_type; + u8_t m_vendor_length; + u8_t m_LM_Key[MPPE_LM_KEY_LENGTH]; + u8_t m_NT_Key[MPPE_NT_KEY_LENGTH]; + u8_t m_padding[MPPE_PADDING_LENGTH]; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + ~mppe_keys_c() + { + } + + // + mppe_keys_c(abs_eap_am_tools_c * const m_am_tools) + { + reset_header(m_am_tools); + } + + void reset_header(abs_eap_am_tools_c * const m_am_tools) + { + m_vendor_id = eap_htonl(311); // microsoft + m_vendor_type = 12u; // MS-CHAP-MPPE-Keys + m_vendor_length = 34u; + m_am_tools->memset(m_LM_Key, 0, sizeof(m_LM_Key)); + m_am_tools->memset(m_NT_Key, 0, sizeof(m_NT_Key)); + m_am_tools->memset(m_padding, 0, sizeof(m_padding)); + } + + eap_status_e set_LM_Key( + abs_eap_am_tools_c * const m_am_tools, + const u8_t * const key, + const u32_t key_length) + { + if (key_length >= sizeof(m_LM_Key)) + { + m_am_tools->memmove(m_LM_Key, key, sizeof(m_LM_Key)); + return eap_status_ok; + } + else + { + return eap_status_key_error; + } + } + + eap_status_e set_NT_Key( + abs_eap_am_tools_c * const m_am_tools, + const u8_t * const key, + const u32_t key_length) + { + if (key_length >= sizeof(m_NT_Key)) + { + m_am_tools->memmove(m_NT_Key, key, sizeof(m_NT_Key)); + return eap_status_ok; + } + else + { + return eap_status_key_error; + } + } + + // + //-------------------------------------------------- +}; // class mppe_keys_c + +#pragma pack() + +#endif //#if !defined(_MS_MPPE_KEYS_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/ms_mppe_send_recv_key.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/ms_mppe_send_recv_key.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,156 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_MS_MPPE_SEND_RECV_KEY_H_) +#define _MS_MPPE_SEND_RECV_KEY_H_ + +//---------------------------------------------------------------------------- + +// +// Bytes needed: +// 4: Vendor-Id +// 1: Vendor-Type +// 1: Vendor-Length +// 2: Salt +// 1: Key-Length +// 32: Key +// 15: Padding +// ----------------- +// 56: Total +// +// Copy MS-MPPE-Send-Key +// +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Vendor-ID | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Vendor-Type | Vendor-Length | Salt | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Key Length | Key total 32 bytes | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Key (cont) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Key (cont) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Key (cont) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Key (cont) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Key (cont) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Key (cont) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Key (cont) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | Padding total 15 bytes | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Padding | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Padding | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Padding | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +const u32_t MS_MPPE_KEY_LENGTH = 32u; +const u32_t MS_MPPE_PADDING_LENGTH = 15u; + +const u8_t MS_MPPE_Send_Key = 16u; +const u8_t MS_MPPE_Recv_Key = 17u; + +#pragma pack(1) + +// +class ms_mppe_send_recv_key_c +{ +private: + //-------------------------------------------------- + + + u32_t m_vendor_id; + u8_t m_vendor_type; + u8_t m_vendor_length; + u16_t m_salt; + u8_t m_key_length; + u8_t m_key[MS_MPPE_KEY_LENGTH]; + u8_t m_padding[MS_MPPE_PADDING_LENGTH]; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + ~ms_mppe_send_recv_key_c() + { + } + + // + ms_mppe_send_recv_key_c(abs_eap_am_tools_c * const m_am_tools) + { + reset_header(m_am_tools); + } + + void reset_header(abs_eap_am_tools_c * const m_am_tools) + { + m_vendor_id = eap_htonl(311); // microsoft + m_vendor_type = 0u; + m_vendor_length = sizeof(*this) - sizeof(m_vendor_id); + m_salt = 0u; + m_key_length = 0u; + m_am_tools->memset(m_key, 0, sizeof(m_key)); + m_am_tools->memset(m_padding, 0, sizeof(m_padding)); + } + + eap_status_e set_key( + abs_eap_am_tools_c * const m_am_tools, + const u8_t * const key, + const u32_t key_length, + const u8_t key_type) + { + if (key_length >= sizeof(m_key)) + { + m_vendor_type = key_type; // MS-MPPE-Send-Key or MS-MPPE-Recv-Key + m_key_length = sizeof(m_key); + m_am_tools->memmove(m_key, key, sizeof(m_key)); + return eap_status_ok; + } + else + { + return eap_status_key_error; + } + } + + // + //-------------------------------------------------- +}; // class ms_mppe_send_recv_key_c + +#pragma pack() + +#endif //#if !defined(_MS_MPPE_SEND_RECV_KEY_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/simple_config_am_services.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/simple_config_am_services.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,137 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_SIMPLE_CONFIG_AM_SERVICES_H_) +#define _SIMPLE_CONFIG_AM_SERVICES_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "abs_eap_am_type_simple_config.h" +#include "eap_am_network_id.h" +#include "eap_array.h" +#include "simple_config_types.h" + +class abs_simple_config_am_services_c; +class simple_config_payloads_c; +class simple_config_credential_c; + + +/// This class is interface to adaptation module of SIMPLE_CONFIG. +class EAP_EXPORT simple_config_am_services_c +{ +private: + //-------------------------------------------------- + + /// This function returns pointer to adaptation module of SIMPLE_CONFIG. See abs_simple_config_am_services_c. + virtual abs_simple_config_am_services_c * get_simple_config_am_partner() = 0; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + virtual ~simple_config_am_services_c() + { + } + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + virtual bool get_is_valid() = 0; + + /// This function sets pointer to adaptation module of SIMPLE_CONFIG. See abs_simple_config_am_services_c. + virtual void set_simple_config_am_partner(abs_simple_config_am_services_c * const tls_am_partner) = 0; + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + */ + virtual eap_status_e configure() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + /** + * This function queries all network and device parameters. + * abs_simple_config_am_services_c::complete_query_network_and_device_parameters() completes this query. + */ + virtual eap_status_e query_network_and_device_parameters( + const simple_config_state_e state) = 0; + + /** + * This function tells AM to save SIMPLE_CONFIG configuration parameters. + * This is always syncronous call. + */ + virtual eap_status_e save_simple_config_session( + const simple_config_state_e state, + EAP_TEMPLATE_CONST eap_array_c * const credential_array, + const eap_variable_data_c * const new_password, + const simple_config_Device_Password_ID_e Device_Password_ID, + const simple_config_payloads_c * const other_configuration + ) = 0; + + /** + * This function forwards all payloads received in M2D messages. + * Adaptation layer could show this information to user. + * This is always syncronous call. + */ + virtual eap_status_e received_registrar_information( + EAP_TEMPLATE_CONST eap_array_c * const M2D_payloads) = 0; + + /** + * This function cancels query_network_and_device_parameters() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_query_network_and_device_parameters() = 0; + + //-------------------------------------------------- +}; // class simple_config_am_services_c + + +/** @file */ + +/** + * This function creates a new instance of adaptation module of SIMPLE_CONFIG. + * @param tools is pointer to the abs_eap_am_tools class created by the adaptation module. + * Adaptation module of SIMPLE_CONFIG will callback caller using the partner pointer. + */ +EAP_C_FUNC_IMPORT simple_config_am_services_c *new_simple_config_am_services( + abs_eap_am_tools_c * const tools); + + +#endif //#if !defined(_SIMPLE_CONFIG_AM_SERVICES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/tls_am_application_eap_fast.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/tls_am_application_eap_fast.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,158 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_AM_APPLICATION_EAP_FAST_H_) +#define _TLS_AM_APPLICATION_EAP_FAST_H_ + +#if defined(USE_FAST_EAP_TYPE) + +#include "eap_am_export.h" +#include "eap_array.h" +#include "eap_fast_pac_store_types.h" + +#include "eap_fast_tlv_header.h" + +#if defined(USE_EAP_TLS_SESSION_TICKET) +class tls_extension_c; +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +class abs_tls_am_application_eap_fast_c; +class eap_fast_variable_data_c; + + +/// This class declares the functions adaptation module of TLS +/// requires from the TLS. +class EAP_EXPORT tls_am_application_eap_fast_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing. + virtual ~tls_am_application_eap_fast_c() + { + } + + /// Constructor does nothing. + tls_am_application_eap_fast_c() + { + } + + /// This function sets pointer to application of TLS. See abs_tls_am_application_eap_fast_c. + virtual void set_tls_application(abs_tls_am_application_eap_fast_c * const tls_application) = 0; + + // This is commented in eap_base_type_c::configure(). + virtual eap_status_e configure() = 0; + + /** + * This function initializes PAC store. + * Imported PACs and other configuration can be done within this function call. + * If asyncronous operations are needed the operations must be completed + * by complete_initialize_PAC_store() function call. + */ + virtual eap_status_e initialize_PAC_store( + const eap_fast_completion_operation_e completion_operation, + const eap_fast_initialize_pac_store_completion_e completion) = 0; + + /** + * This function reads the authority identity (A-ID) of server. + * This is used in EAP-FAST. + * Parameter includes the TLV of A-ID. + */ + virtual eap_status_e read_authority_identity(eap_variable_data_c * const authority_identity_payload) = 0; + + /** + * This function call is always asyncronous. + * It will be completed always with complete_query_pac_of_type() function call. + * Function creates a new PAC. + */ + virtual eap_status_e query_pac_of_type(const eap_fast_pac_type_e pac_type) = 0; + +#if defined(USE_EAP_CORE_SERVER) + /** + * This function call is always asyncronous. + * It will be completed always with complete_verify_pac() function call. + * Function verifies the received PAC is valid. + */ + virtual eap_status_e verify_pac(const eap_fast_variable_data_c * const tlv_pac) = 0; +#endif //#if defined(USE_EAP_CORE_SERVER) + + + virtual eap_status_e indicates_eap_fast_provisioning_starts( + const eap_fast_completion_operation_e provisioning_mode, + const eap_fast_pac_type_e pac_type) = 0; + + virtual eap_status_e indicates_eap_fast_provisioning_ends( + const bool provisioning_successfull, + const eap_fast_completion_operation_e provisioning_mode, + const eap_fast_pac_type_e pac_type) = 0; + + // This is commented in eap_am_fast_pac_store_services_c::query_user_permission_for_A_ID(). + virtual eap_status_e query_user_permission_for_A_ID( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + const eap_fast_variable_data_c * const in_pac_attribute_A_ID_info, + const eap_fast_variable_data_c * const in_pac_attribute_A_ID) = 0; + + // This is commented in eap_am_fast_pac_store_services_c::read_PAC_store_data(). + virtual eap_status_e read_PAC_store_data( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references) = 0; + + // This is commented in eap_am_fast_pac_store_services_c::write_PAC_store_data(). + virtual eap_status_e write_PAC_store_data( + const bool when_true_must_be_synchronous_operation, + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references_and_data_blocks) = 0; + + // This is commented in eap_am_fast_pac_store_services_c::complete_add_imported_PAC_file(). + virtual eap_status_e complete_add_imported_PAC_file( + const eap_status_e in_completion_status, + const eap_variable_data_c * const in_imported_PAC_filename, + const eap_variable_data_c * const out_used_group_reference) = 0; + + // This is commented in eap_am_fast_pac_store_services_c::complete_remove_PAC(). + virtual eap_status_e complete_remove_PAC( + const eap_status_e in_completion_status, + const eap_variable_data_c * const out_used_group_reference) = 0; + + // This is commented in eap_am_fast_pac_store_services_c::complete_remove_IAP_reference(). + virtual eap_status_e complete_remove_IAP_reference( + const eap_status_e in_completion_status) = 0; + + // This is commented in eap_am_fast_pac_store_services_c::cancel_PAC_store_operations(). + virtual eap_status_e cancel_PAC_store_operations() = 0; + + //-------------------------------------------------- +}; // class tls_am_application_eap_fast_c + +#endif //#if defined(USE_FAST_EAP_TYPE) + +#endif //#if !defined(_TLS_AM_APPLICATION_EAP_FAST_H_) + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/include/tls_am_services.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/include/tls_am_services.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,306 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_AM_SERVICES_H_) +#define _TLS_AM_SERVICES_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "abs_eap_am_type_tls_peap.h" +#include "eap_am_network_id.h" +#include "eap_array.h" +#include "tls_peap_types.h" + +class abs_tls_am_services_c; + +#if defined(USE_EAP_TLS_SESSION_TICKET) +class tls_extension_c; +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + + +/// This class is interface to adaptation module of TLS. +class EAP_EXPORT tls_am_services_c +{ +private: + //-------------------------------------------------- + + /// This function returns pointer to adaptation module of TLS. See abs_tls_am_services_c. + virtual abs_tls_am_services_c * get_tls_am_partner() = 0; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + virtual ~tls_am_services_c() + { + } + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + virtual bool get_is_valid() = 0; + + /// This function sets pointer to adaptation module of TLS. See abs_tls_am_services_c. + virtual void set_tls_am_partner(abs_tls_am_services_c * const tls_am_partner) = 0; + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + */ + virtual eap_status_e configure() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + /** + * This function is called when TLS-Alert message is received. + * Adaptation module could record this event. + */ + virtual eap_status_e alert_received( + const tls_alert_level_e alert_level, + const tls_alert_description_e alert_description) = 0; + + /** + * This function queries from AM cipher suites and previous session. + * abs_tls_am_services_c::complete_query_cipher_suites_and_previous_session() completes this query. + */ + virtual eap_status_e query_cipher_suites_and_previous_session() = 0; + +#if defined(USE_EAP_TLS_SESSION_TICKET) + /** + * This function queries from AM a new session ticket, see RFC 4507. + * abs_tls_am_services_c::complete_query_new_session_ticket() completes this query. + */ + virtual eap_status_e query_new_session_ticket() = 0; +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + + /** + * This function queries AM to select cipher suite and check session id. + * abs_tls_am_services_c::complete_select_cipher_suite_and_check_session_id() completes this query. + */ + virtual eap_status_e select_cipher_suite_and_check_session_id( + EAP_TEMPLATE_CONST eap_array_c * const cipher_suite_proposal, + const eap_variable_data_c * const session_id +#if defined(USE_EAP_TLS_SESSION_TICKET) + , const tls_extension_c * const session_ticket +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + ) = 0; + + + /** + * This function queries AM to verify certificate chain. + * abs_tls_am_services_c::complete_verify_certificate_chain() completes this query. + */ + virtual eap_status_e verify_certificate_chain( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain, + const tls_cipher_suites_e required_cipher_suite) = 0; + + /** + * This function queries AM certificate chain. + * abs_tls_am_services_c::complete_query_certificate_chain() completes this query. + */ + virtual eap_status_e query_certificate_chain( + EAP_TEMPLATE_CONST eap_array_c * const certificate_authorities, + EAP_TEMPLATE_CONST eap_array_c * const certificate_types, + const tls_cipher_suites_e required_cipher_suite) = 0; + + /** + * This function queries AM certificate authorities and certifica types. + * abs_tls_am_services_c::complete_query_certificate_authorities_and_types() completes this query. + */ + virtual eap_status_e query_certificate_authorities_and_types() = 0; + + /** + * This function queries AM ephemeral Diffie-Hellman parameters. + * abs_tls_am_services_c::complete_query_dh_parameters() completes this query. + */ + virtual eap_status_e query_dh_parameters( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain, + const tls_cipher_suites_e required_cipher_suite) = 0; + + /** + * This function queries AM NAI realm. + * abs_tls_am_services_c::complete_query_realm() completes this query. + */ + virtual eap_status_e query_realm( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain) = 0; + + /** + * This function tells AM to save TLS-session ID and master secret. + * If AM does not support TLS-session resumption AM could dischard these paramteters. + * This is always syncronous call. + */ + virtual eap_status_e save_tls_session( + const eap_variable_data_c * const session_id, + const eap_variable_data_c * const master_secret, + const tls_cipher_suites_e used_cipher_suite +#if defined(USE_EAP_TLS_SESSION_TICKET) + , const tls_extension_c * const new_session_ticket +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + ) = 0; + + /** + * This function encrypts data with own RSA private key. + * abs_tls_am_services_c::complete_rsa_encrypt_with_public_key() completes this query. + */ + virtual eap_status_e rsa_encrypt_with_public_key( + const eap_variable_data_c * const premaster_secret) = 0; + + /** + * This function decrypts data with own RSA private key. + * abs_tls_am_services_c::complete_rsa_decrypt_with_private_key() completes this query. + */ + virtual eap_status_e rsa_decrypt_with_private_key( + const eap_variable_data_c * const encrypted_premaster_secret) = 0; + + /** + * Function signs data with own PKI private key. + * abs_tls_am_services_c::complete_sign_with_private_key() completes this query. + */ + virtual eap_status_e sign_with_private_key( + const eap_variable_data_c * const message_hash) = 0; + + /** + * This function verifies signed data with peer PKI public key. + * abs_tls_am_services_c::complete_verify_with_public_key() completes this query. + */ + virtual eap_status_e verify_with_public_key( + const eap_variable_data_c * const message_hash, + const eap_variable_data_c * const signed_message_hash) = 0; + + + /** + * This function cancels query_cipher_suites_and_previous_session() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_query_cipher_suites_and_previous_session() = 0; + + /** + * This function cancels select_cipher_suite_and_check_session_id() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_select_cipher_suite_and_check_session_id() = 0; + + /** + * This function cancels verify_certificate_chain() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_verify_certificate_chain() = 0; + + /** + * This function cancels query_certificate_chain() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_query_certificate_chain() = 0; + + /** + * This function cancels query_certificate_authorities_and_types() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_query_certificate_authorities_and_types() = 0; + + /** + * This function cancels query_dh_parameters() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_query_dh_parameters() = 0; + + /** + * This function cancels query_realm() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_query_realm() = 0; + + /** + * This function cancels rsa_encrypt_with_public_key() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_rsa_encrypt_with_public_key() = 0; + + /** + * This function cancels rsa_decrypt_with_private_key() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_rsa_decrypt_with_private_key() = 0; + + /** + * This function cancels sign_with_private_key() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_sign_with_private_key() = 0; + + /** + * This function cancels verify_with_public_key() query. + * After this call AM must not complete related query. + */ + virtual eap_status_e cancel_verify_with_public_key() = 0; + + /** + * This function sets the tunnel type. + */ + virtual void set_peap_version( + const peap_version_e peap_version, + const bool use_tppd_tls_peap, + const bool use_tppd_peapv1_acknowledge_hack) = 0; + + virtual bool is_ttls_pap_session_valid() = 0; + + virtual eap_status_e query_ttls_pap_username_and_password( + const eap_variable_data_c * const reply_message) = 0; + + virtual eap_status_e verify_ttls_pap_username_and_password( + const eap_variable_data_c * const user_name, + const eap_variable_data_c * const user_password) = 0; + + //-------------------------------------------------- +}; // class tls_am_services_c + + +/** @file */ + +/** + * This function creates a new instance of adaptation module of TLS. + * @param tools is pointer to the abs_eap_am_tools class created by the adaptation module. + * Adaptation module of TLS will callback caller using the partner pointer. + */ +EAP_C_FUNC_IMPORT tls_am_services_c *new_tls_am_services( + abs_eap_am_tools_c * const tools); + + +#endif //#if !defined(_TLS_AM_SERVICES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/type/tls_peap/tls_am_services.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/type/tls_peap/tls_am_services.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,92 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 19 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#error no used anymore. + + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "tls_am_services.h" + +// +EAP_FUNC_EXPORT tls_am_services_c::~tls_am_services_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +// +EAP_FUNC_EXPORT tls_am_services_c::tls_am_services_c(abs_eap_am_tools_c * const tools) +: m_am_partner(0) +, m_am_tools(tools) +, m_is_valid(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + set_is_valid(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +/** Function returns partner object of adaptation module of TLS. + * Partner object is the TLS object. + */ +EAP_FUNC_EXPORT abs_tls_am_services_c * tls_am_services_c::get_am_partner() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_partner; +} + +/** Function sets partner object of adaptation module of TLS. + * Partner object is the TLS object. + */ +EAP_FUNC_EXPORT void tls_am_services_c::set_am_partner(abs_tls_am_services_c * const partner) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_am_partner = partner; +} + +EAP_FUNC_EXPORT void tls_am_services_c::set_is_valid() +{ + m_is_valid = true; +} + +EAP_FUNC_EXPORT bool tls_am_services_c::get_is_valid() +{ + return m_is_valid; +} + +/** @file */ + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/asn1_der_type.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/asn1_der_type.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1706 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#include "asn1_der_type.h" +#include "eap_automatic_variable.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT asn1_der_type_c::~asn1_der_type_c() +{ + delete m_sub_types; + m_sub_types = 0; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT asn1_der_type_c::asn1_der_type_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_is_valid(false) + , m_index(0u) + , m_count_of_sub_types(0u) + , m_recursion(0ul) + , m_input_data_length(0ul) + , m_input_data(0) + , m_used_octets(0ul) + , m_offset_of_length_field(0ul) + , m_offset_of_contents_field(0ul) + , m_parent_type(0) + , m_sub_types(0) +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool asn1_der_type_c::get_is_valid() const +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t asn1_der_type_c::get_index() const +{ + return m_index; +} + +//-------------------------------------------------- + +u32_t asn1_der_type_c::get_input_data_length() const +{ + return m_input_data_length; +} + +//-------------------------------------------------- + +const u8_t * asn1_der_type_c::get_input_data() const +{ + return m_input_data; +} + +//-------------------------------------------------- + +u16_t asn1_der_type_c::get_recursion() const +{ + return m_recursion; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string asn1_der_type_c::get_class_string() const +{ + +#if defined(USE_EAP_DEBUG_TRACE) + + asn1_class_e asn1_class = get_class(); + + if (asn1_class == asn1_class_universal) + { + return("U"); + } + else if (asn1_class == asn1_class_application) + { + return("A"); + } + else if (asn1_class == asn1_class_context_specific) + { + return("C"); + } + else if (asn1_class == asn1_class_private) + { + return("P"); + } + else +#endif //#if defined(USE_EAP_DEBUG_TRACE) + { + return(""); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string asn1_der_type_c::get_pc_string() const +{ + +#if defined(USE_EAP_DEBUG_TRACE) + + asn1_pc_e pc = get_pc(); + + if (pc == asn1_pc_primitive) + { + return("P"); + } + else if (pc == asn1_pc_constructed) + { + return("C"); + } + else +#endif //#if defined(USE_EAP_DEBUG_TRACE) + { + return(""); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string asn1_der_type_c::get_tag_string() const +{ + +#if defined(USE_EAP_DEBUG_TRACE) + + asn1_class_e asn1_class = get_class(); + asn1_tag_e tag = get_tag(); + + if (asn1_class == asn1_class_context_specific) + { + static const eap_char context[][4] = { "[0]", "[1]", "[2]", "[3]", "[4]", "[5]", "[6]", "[7]", "[8]", "[9]", }; + if (tag < (sizeof(context)/sizeof(context[0]))) + { + return context[tag]; + } + else + { + return(""); + } + } + else + { + EAP_IF_RETURN_STRING(tag, asn1_tag_end_of_content) + else EAP_IF_RETURN_STRING(tag, asn1_tag_boolean) + else EAP_IF_RETURN_STRING(tag, asn1_tag_integer) + else EAP_IF_RETURN_STRING(tag, asn1_tag_bit_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_octet_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_null) + else EAP_IF_RETURN_STRING(tag, asn1_tag_object_identifier) + else EAP_IF_RETURN_STRING(tag, asn1_tag_object_descriptor) + else EAP_IF_RETURN_STRING(tag, asn1_tag_external) + else EAP_IF_RETURN_STRING(tag, asn1_tag_real) + else EAP_IF_RETURN_STRING(tag, asn1_tag_enumerated) + else EAP_IF_RETURN_STRING(tag, asn1_tag_empedded_pdv) + else EAP_IF_RETURN_STRING(tag, asn1_tag_utf8_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_relative_oid) + else EAP_IF_RETURN_STRING(tag, asn1_tag_unknown_14) + else EAP_IF_RETURN_STRING(tag, asn1_tag_unknown_15) + else EAP_IF_RETURN_STRING(tag, asn1_tag_sequence) + else EAP_IF_RETURN_STRING(tag, asn1_tag_set) + else EAP_IF_RETURN_STRING(tag, asn1_tag_numeric_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_printable_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_t61_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_videotex_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_ia5_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_utc_time) + else EAP_IF_RETURN_STRING(tag, asn1_tag_unknown_24) + else EAP_IF_RETURN_STRING(tag, asn1_tag_graphic_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_visible_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_general_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_universal_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_character_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_bmp_string) + else EAP_IF_RETURN_STRING(tag, asn1_tag_extented) + else EAP_IF_RETURN_STRING(tag, asn1_tag_none) + else + { + return(""); + } + } + +#else + + return(""); + +#endif //#if defined(USE_EAP_DEBUG_TRACE) + +} + +//-------------------------------------------------- + +#if defined(USE_EAP_DEBUG_TRACE) + +eap_status_e asn1_der_type_c::debug_create_prefix(const u32_t recursion, u8_t * const prefix, const u32_t max_prefix, u32_t * const prefix_length) +{ + if (prefix == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t offset(0ul); + + for (u32_t ind = 0ul; ind < recursion; ++ind) + { + offset += m_am_tools->snprintf( + &prefix[offset], + max_prefix - offset, + " |\0"); + + if (max_prefix <= offset) + { + break; + } + } + + if (max_prefix > offset) + { + prefix[offset] = 0; + } + + *prefix_length = offset; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif //#if defined(USE_EAP_DEBUG_TRACE) + +//-------------------------------------------------- + +#if defined(USE_EAP_DEBUG_TRACE) + +eap_status_e asn1_der_type_c::debug_header(eap_variable_data_c * const debug_buffer) +{ + if (debug_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t max_data_length(m_recursion * SIZE_OF_ONE_OCTET_STRING + m_offset_of_contents_field * SIZE_OF_ONE_OCTET_STRING); + + if (max_data_length > debug_buffer->get_buffer_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = debug_buffer->set_data_length(max_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t ind(0ul); + u32_t offset(0ul); + + u8_t * const prefix = reinterpret_cast(debug_buffer->get_data(max_data_length)); + + if (prefix == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = debug_create_prefix(m_recursion, prefix, max_data_length, &offset); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (ind = 0ul; ind < m_offset_of_length_field && ind < m_input_data_length; ++ind) + { + offset += m_am_tools->snprintf( + debug_buffer->get_data_offset(offset, debug_buffer->get_data_length() - offset), + debug_buffer->get_data_length() - offset, + "%02x \0", + m_input_data[ind]); + } + + for (ind = m_offset_of_length_field; ind < m_offset_of_contents_field && ind < m_input_data_length; ++ind) + { + offset += m_am_tools->snprintf( + debug_buffer->get_data_offset(offset, debug_buffer->get_data_length() - offset), + debug_buffer->get_data_length() - offset, + "%02x \0", + m_input_data[ind]); + } + + status = debug_buffer->add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_const_string tag_string = 0; + eap_char buffer[MAX_STACK_BUFFER]; + + if (get_class() == asn1_class_application) + { + m_am_tools->snprintf( + reinterpret_cast(buffer), + MAX_STACK_BUFFER, + "Application[%d]\0", + get_tag()); + + tag_string = buffer; + } + else if (get_class() == asn1_class_context_specific) + { + m_am_tools->snprintf( + reinterpret_cast(buffer), + MAX_STACK_BUFFER, + "[%d]\0", + get_tag()); + + tag_string = buffer; + } + else + { + tag_string = get_tag_string(); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s # %s, %s, %s, length=0x%x=%d, this=0x%08x, index=%d\n"), + debug_buffer->get_data(max_data_length), + get_class_string(), + get_pc_string(), + tag_string, + get_content_length(), + get_content_length(), + this, + m_index)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_DEBUG_TRACE) + +//-------------------------------------------------- + +#if defined(USE_EAP_DEBUG_TRACE) + +eap_status_e asn1_der_type_c::debug_content(eap_variable_data_c * const debug_buffer) +{ + if (debug_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_process_general_error); + + if (get_tag() == asn1_tag_object_identifier) + { + status = debug_object_identifier(debug_buffer); + } + else + { + status = debug_data(debug_buffer); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_DEBUG_TRACE) + +//-------------------------------------------------- + +#if defined(USE_EAP_DEBUG_TRACE) + +eap_status_e asn1_der_type_c::debug_data(eap_variable_data_c * const debug_buffer) +{ + if (debug_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t max_prefix_length((m_recursion + 1ul) * SIZE_OF_ONE_OCTET_STRING + COUNT_OF_OCTETS * SIZE_OF_ONE_OCTET_STRING + 1ul); + const u32_t ascii_length(COUNT_OF_OCTETS + 5ul); + + if ((max_prefix_length + ascii_length) > debug_buffer->get_buffer_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = debug_buffer->set_data_length(max_prefix_length + ascii_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const prefix = reinterpret_cast(debug_buffer->get_data(max_prefix_length)); + u8_t * const ascii = reinterpret_cast(debug_buffer->get_data_offset(max_prefix_length, ascii_length)); + + if (prefix == 0 || ascii == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t ind(0ul); + u32_t offset(0ul); + + status = debug_create_prefix(m_recursion + 1u, prefix, max_prefix_length, &offset); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t init_indentation_offset = offset; + u32_t type_data_size = get_header_length() + get_content_length(); + u32_t data_ind(0ul); + u32_t ascii_ind(0ul); + u8_t octet(0); + + for (ind = m_offset_of_contents_field; ind < type_data_size && ind < m_input_data_length; ++ind) + { + offset += m_am_tools->snprintf( + &prefix[offset], + max_prefix_length - offset, + "%02x \0", + m_input_data[ind]); + + octet = m_input_data[ind]; + + if (octet < 0x20 || 0x7e < octet) + { + octet = '.'; + } + + m_am_tools->snprintf( + &ascii[ascii_ind], + ascii_length - ascii_ind, + "%c\0", + octet); + + ++data_ind; + ++ascii_ind; + + if ((ascii_ind % COUNT_OF_OCTETS) == 0) + { + prefix[offset] = 0; + ascii[ascii_ind] = 0; + + offset = init_indentation_offset; + ascii_ind = 0ul; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s |%s|\n"), + prefix, + ascii)); + } + } // for() + + u32_t remainder(ascii_ind % COUNT_OF_OCTETS); + + if (remainder > 0ul) + { + for (; ascii_ind < COUNT_OF_OCTETS; ++ascii_ind) + { + offset += m_am_tools->snprintf( + &prefix[offset], + max_prefix_length - offset, + " \0"); + + m_am_tools->snprintf( + &ascii[ascii_ind], + ascii_length - ascii_ind, + " \0"); + } // for() + + prefix[offset] = 0; + ascii[ascii_ind] = 0; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s |%s|\n"), + prefix, + ascii)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_DEBUG_TRACE) + +//-------------------------------------------------- + +#if defined(USE_EAP_DEBUG_TRACE) + +eap_status_e asn1_der_type_c::debug_object_identifier(eap_variable_data_c * const debug_buffer) +{ + if (debug_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = debug_buffer->set_data_length(debug_buffer->get_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t recursion(m_recursion + 1u); + const u32_t max_prefix_length(recursion * SIZE_OF_ONE_OCTET_STRING + 1ul); + + if (debug_buffer->get_buffer_length() < (max_prefix_length + 2ul)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + const u32_t max_data_output_length((debug_buffer->get_buffer_length() - (max_prefix_length + 2ul))/2ul); + const u32_t max_plain_output_length(max_data_output_length); + + u32_t prefix_length(0ul); + + u8_t * const prefix = debug_buffer->get_data(); + if (prefix == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = debug_create_prefix(recursion, prefix, max_prefix_length, &prefix_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const data_output = debug_buffer->get_data_offset(max_prefix_length, max_data_output_length); + if (data_output == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + data_output[max_data_output_length-1ul] = 0; + + u8_t * const plain_output = debug_buffer->get_data_offset(max_prefix_length + max_data_output_length, max_plain_output_length); + if (plain_output == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + plain_output[max_plain_output_length - 1ul] = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + const u32_t length = get_content_length(); + + if (length == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("# ERROR: invalid %s, length=%d\n"), + get_tag_string(), + length)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + const u8_t * const oid_data = get_content(); + + if (oid_data == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("# ERROR: invalid %s, length=%d\n"), + get_tag_string(), + length)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + u32_t offset(0ul); + u8_t oid_octet = oid_data[offset]; + u32_t oid1 = oid_octet / 40; + u32_t oid2 = (oid_octet - oid1*40); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s%02x # = %d = 40 * %d + %d => %d.%d\n"), + prefix, + oid_octet, + oid_octet, + oid1, + oid2, + oid1, + oid2)); + + ++offset; + + while(offset < length) + { + u32_t oid_length(0ul); + u32_t data_output_offset(0ul); + u32_t plain_output_offset(0ul); + u32_t ind(0ul); + + for (ind = offset; ind < length; ++ind) + { + u8_t oid_octet = oid_data[ind]; + ++oid_length; + if ((oid_octet & OID_HIGH_BIT) == 0) + { + break; + } + } // for() + + u32_t power = oid_length - 1ul; + u32_t oid_value(0ul); + + for (ind = offset; ind < (offset+oid_length); ++ind) + { + u8_t oid_octet = oid_data[ind]; + + data_output_offset += m_am_tools->snprintf( + &data_output[data_output_offset], + max_data_output_length - data_output_offset, + "%02x \0", + oid_octet); + + u8_t oid = oid_octet & (~OID_HIGH_BIT); + + if (ind > offset) + { + plain_output_offset += m_am_tools->snprintf( + &plain_output[plain_output_offset], + max_data_output_length - plain_output_offset, + " + \0"); + } + + if (power > 1ul) + { + plain_output_offset += m_am_tools->snprintf( + &plain_output[plain_output_offset], + max_data_output_length - plain_output_offset, + "0x%02x * 128 ^ %d\0", + oid, + power); + } + else if (power > 0ul) + { + plain_output_offset += m_am_tools->snprintf( + &plain_output[plain_output_offset], + max_data_output_length - plain_output_offset, + "0x%02x * 128\0", + oid); + } + else + { + plain_output_offset += m_am_tools->snprintf( + &plain_output[plain_output_offset], + max_data_output_length - plain_output_offset, + "0x%02x\0", + oid); + } + + oid_value = (oid_value << 7) + oid; + + --power; + } // for() + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s%s # %s = %d\n"), + prefix, + data_output, + plain_output, + oid_value)); + + offset += oid_length; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_DEBUG_TRACE) + +//-------------------------------------------------- + +eap_status_e asn1_der_type_c::initialize( + const u32_t length, + const u8_t * const data, + const u16_t recursion, + const u32_t index, + eap_variable_data_c * const debug_buffer) +{ + if (index > 0xffff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + m_index = static_cast(index); + + m_recursion = recursion; + + m_input_data_length = length; + + if (m_input_data_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + m_input_data = data; + + if (m_input_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + m_offset_of_length_field = get_offset_of_length_field(); + + if (m_offset_of_length_field > m_input_data_length + || m_offset_of_length_field == 0) + { + ASN1_DEBUG_HEADER(this, debug_buffer); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + m_offset_of_contents_field = get_offset_of_contents_field(); + + if (m_offset_of_contents_field > m_input_data_length + || m_offset_of_contents_field == 0) + { + ASN1_DEBUG_HEADER(this, debug_buffer); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + if ((m_offset_of_contents_field + get_content_length()) > m_input_data_length) + { + ASN1_DEBUG_HEADER(this, debug_buffer); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + u32_t data_length = get_header_length() + get_content_length(); + + if (m_input_data_length >= data_length) + { + m_input_data_length = data_length; + } + else + { + ASN1_DEBUG_HEADER(this, debug_buffer); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + add_used_octets(get_header_length()); + + ASN1_DEBUG_HEADER(this, debug_buffer); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT asn1_der_type_c::asn1_class_e asn1_der_type_c::get_class() const +{ + if (m_input_data == 0) + { + return asn1_der_type_c::asn1_class_none; + } + + return static_cast(m_input_data[0] & asn1_identifier_mask_class); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT asn1_der_type_c::asn1_pc_e asn1_der_type_c::get_pc() const +{ + if (m_input_data == 0) + { + return asn1_der_type_c::asn1_pc_none; + } + + return static_cast(m_input_data[0] & asn1_identifier_mask_pc); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT asn1_der_type_c::asn1_tag_e asn1_der_type_c::get_tag() const +{ + if (m_input_data == 0) + { + return asn1_der_type_c::asn1_tag_none; + } + + asn1_der_type_c::asn1_tag_e tag = static_cast(m_input_data[0] & asn1_identifier_mask_tag); + + if (m_offset_of_length_field == asn1_identifier_const_simple_tag_size + && static_cast(tag) != asn1_identifier_mask_tag) + { + // Simple Tag. + return tag; + } + else if (m_offset_of_length_field > asn1_identifier_const_simple_tag_size) + { + return asn1_der_type_c::asn1_tag_extented; + } + else + { + return asn1_der_type_c::asn1_tag_none; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e asn1_der_type_c::get_extented_tag(const u8_t ** const extented_tag, u32_t * const extented_tag_size) const +{ + if (extented_tag == 0 + || extented_tag_size == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (get_tag() == asn1_der_type_c::asn1_tag_extented) + { + *extented_tag = m_input_data + asn1_identifier_const_simple_tag_size; + *extented_tag_size = m_offset_of_length_field - asn1_identifier_const_simple_tag_size; + } + else + { + *extented_tag = m_input_data; + *extented_tag_size = m_offset_of_length_field; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +u16_t asn1_der_type_c::get_offset_of_length_field() +{ + if (m_input_data == 0) + { + return 0ul; + } + + asn1_der_type_c::asn1_tag_e tag = static_cast(m_input_data[0] & asn1_identifier_mask_tag); + + if (static_cast(tag) != asn1_identifier_mask_tag) + { + // Simple Tag. + return asn1_identifier_const_simple_tag_size; + } + else if (m_input_data_length > asn1_identifier_const_simple_tag_size) + { + const u8_t * extented_tag = &(m_input_data[1]); + if (extented_tag == 0) + { + return 0ul; + } + + const u8_t * const end_byte = &(m_input_data[m_input_data_length]); + if (end_byte == 0) + { + return 0ul; + } + + while (extented_tag < end_byte) + { + if ((extented_tag[0] & static_cast(asn1_high_bit_mask_tag)) == 0) + { + return (extented_tag - m_input_data); + } + + ++extented_tag; + } + } + + // Illegal data. + return 0ul; +} + +//-------------------------------------------------- + +u16_t asn1_der_type_c::get_offset_of_contents_field() +{ + if (m_input_data == 0) + { + return 0ul; + } + + if (m_offset_of_length_field < asn1_identifier_const_simple_tag_size + || m_offset_of_length_field > m_input_data_length) + { + return 0ul; + } + + const u8_t length_octet1 = m_input_data[m_offset_of_length_field]; + + if ((length_octet1 & static_cast(asn1_high_bit_mask_tag)) == 0) + { + // Short Length field. + return m_offset_of_length_field + asn1_identifier_const_short_length_size; + } + else if (m_input_data_length > static_cast(m_offset_of_length_field + asn1_identifier_const_short_length_size)) + { + const u8_t * extented_length = &(m_input_data[m_offset_of_length_field]); + if (extented_length == 0) + { + return 0ul; + } + + u16_t count_of_length_octets = static_cast((*extented_length) & static_cast(~asn1_high_bit_mask_tag)); + + u16_t offset(static_cast(m_offset_of_length_field + asn1_identifier_const_short_length_size + count_of_length_octets)); + + if (offset > m_input_data_length) + { + // Illegal data. + return 0ul; + } + + return offset; + } + + // Illegal data. + return 0ul; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t asn1_der_type_c::get_header_length() const +{ + return m_offset_of_contents_field; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t asn1_der_type_c::get_content_length() const +{ + if (m_input_data == 0 + || m_offset_of_length_field == 0ul + || m_offset_of_contents_field == 0ul) + { + return 0ul; + } + + const u8_t * extented_length = &(m_input_data[m_offset_of_length_field]); + if (extented_length == 0) + { + return 0ul; + } + + if (((*extented_length) & static_cast(asn1_high_bit_mask_tag)) == 0) + { + // Short Length field. + return static_cast(*extented_length); + } + + u32_t count_of_length_octets = static_cast((*extented_length) & static_cast(~asn1_high_bit_mask_tag)); + + if ((m_offset_of_length_field + asn1_identifier_const_short_length_size + count_of_length_octets) > m_input_data_length) + { + // Illegal data. + return 0ul; + } + + const u8_t * end_byte = &(m_input_data[m_offset_of_contents_field]); + if (end_byte == 0) + { + return 0ul; + } + + ++extented_length; + + if (static_cast(end_byte - extented_length) > sizeof(u32_t)) + { + // Overflow of length. + return 0ul; + } + + u32_t length(0ul); + + + while (extented_length < end_byte) + { + length = (length << 8) + static_cast(*extented_length); + ++extented_length; + } + + return length; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const u8_t * asn1_der_type_c::get_content() const +{ + if (m_input_data == 0) + { + return 0; + } + + if (m_offset_of_contents_field > m_input_data_length + || m_offset_of_contents_field == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + return (&m_input_data[m_offset_of_contents_field]); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t asn1_der_type_c::get_full_data_length() const +{ + return m_input_data_length; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const u8_t * asn1_der_type_c::get_full_data() const +{ + return m_input_data; +} + +//-------------------------------------------------- + +void asn1_der_type_c::set_parent_type(asn1_der_type_c * const parent_type) +{ + m_parent_type = parent_type; +} + +//-------------------------------------------------- + +asn1_der_type_c * asn1_der_type_c::get_parent_type() const +{ + return m_parent_type; +} + +//-------------------------------------------------- + +eap_status_e asn1_der_type_c::add_sub_type(asn1_der_type_c * const sub_type) +{ + if (m_sub_types == 0) + { + m_sub_types = new eap_array_c(m_am_tools); + if (m_sub_types == 0) + { + delete sub_type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + sub_type->set_parent_type(this); + + eap_status_e status = m_sub_types->add_object(sub_type, true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_array_c * asn1_der_type_c::get_sub_types() const +{ + return m_sub_types; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const asn1_der_type_c * asn1_der_type_c::get_sub_type( + const asn1_type_const_c * const asn1_type) const +{ + const asn1_type_object_c * type = asn1_type[0].get_type(); + + if (type == 0 + || type->get_is_valid() == false) + { + return 0; + } + + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("# asn1_type = 0x%08x, class=%d, tag=%d, index=%d\n"), + type, + type->get_asn1_class(), + type->get_asn1_tag(), + type->get_index())); + + const asn1_der_type_c * current_type = this; + + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("### current_type = 0x%08x, class=%d, tag=%d, index=%d\n"), + current_type, + current_type->get_class(), + current_type->get_tag(), + 0)); + + if (current_type->get_class() != type->get_asn1_class() + || current_type->get_tag() != type->get_asn1_tag()) + { + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: ### current_type does not match.\n"))); + return 0; + } + + ++type; + + while (current_type != 0 && type->get_is_valid() == true) + { + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("# asn1_type = 0x%08x, class=%d, tag=%d, index=%d\n"), + type, + type->get_asn1_class(), + type->get_asn1_tag(), + type->get_index())); + + const eap_array_c * sub_type_array = current_type->get_sub_types(); + if (sub_type_array == 0) + { + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: ### No sub-type array.\n"))); + return 0; + } + + current_type = 0; + + for (u32_t sub_ind = type->get_index(); sub_ind < sub_type_array->get_object_count(); ++sub_ind) + { + const asn1_der_type_c * const sub_type = sub_type_array->get_object(sub_ind); + if (sub_type == 0 + || sub_type->get_is_valid() == false) + { + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: ### No sub-type.\n"))); + return 0; + } + + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("### sub_type = 0x%08x, class=%d, tag=%d, index=%d\n"), + sub_type, + sub_type->get_class(), + sub_type->get_tag(), + sub_ind)); + + if (sub_type->get_class() == type->get_asn1_class() + && sub_type->get_tag() == type->get_asn1_tag()) + { + current_type = sub_type; + break; + } + } + + ++type; + } + + if (current_type == 0) + { + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: ### No match found.\n"))); + } + else + { + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("### Match found.\n"))); + + ASN1_TYPE_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ASN.1 type data"), + current_type->get_full_data(), + current_type->get_full_data_length())); + } + + return current_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const asn1_der_type_c * asn1_der_type_c::get_previous_type() const +{ + const asn1_der_type_c * parent = get_parent_type(); + + if (parent == 0) + { + return 0; + } + + if (parent->get_sub_types() == 0) + { + return 0; + } + + const u32_t object_count = parent->get_sub_types()->get_object_count(); + + if (object_count <= 1ul) + { + return 0; + } + + const u32_t previous_index = get_index() - 1ul; + + if (object_count <= previous_index) + { + return 0; + } + + return parent->get_sub_types()->get_object(previous_index); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const asn1_der_type_c * asn1_der_type_c::get_next_type() const +{ + const asn1_der_type_c * parent = get_parent_type(); + + if (parent == 0) + { + return 0; + } + + const u32_t next_index = get_index() + 1ul; + + if (parent->get_sub_types() == 0 + || parent->get_sub_types()->get_object_count() <= next_index) + { + return 0; + } + + return parent->get_sub_types()->get_object(next_index); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u16_t asn1_der_type_c::get_count_of_sub_types() const +{ + return m_count_of_sub_types; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void asn1_der_type_c::increase_count_of_sub_types() +{ + ++m_count_of_sub_types; +} + +//-------------------------------------------------- + +void asn1_der_type_c::add_used_octets(const u32_t used_octets) +{ + m_used_octets += used_octets; +} + +//-------------------------------------------------- + +u32_t asn1_der_type_c::get_used_octets() const +{ + return m_used_octets; +} + +//-------------------------------------------------- + +u32_t asn1_der_type_c::get_unused_data_length() const +{ + return get_input_data_length() - get_used_octets(); +} + +//-------------------------------------------------- + +const u8_t * asn1_der_type_c::get_unused_data() const +{ + return get_input_data() + get_used_octets(); +} + +//-------------------------------------------------- + +eap_status_e asn1_der_type_c::encode_oid_from_string(eap_const_string oid, const u32_t oid_length, eap_variable_data_c * const buffer) const +{ + if (oid == 0 + || buffer == 0 + || buffer->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_process_general_error); + + const eap_char * oid_char = oid; + const eap_char * end_char = &oid[oid_length]; + u32_t remaining_length(oid_length); + u32_t first_component(0ul); + u32_t component_index(0ul); + + status = buffer->set_data_length(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + while(oid_char < end_char) + { + // Search next dot (.). + const eap_char * dot = reinterpret_cast(m_am_tools->memchr(oid_char, '.', remaining_length)); + if (dot == 0) + { + // The last component. + dot = reinterpret_cast(oid_char + remaining_length); + if (dot == 0 + || dot != end_char) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + } + + u32_t integer(0ul); + + status = m_am_tools->number_string_to_u32( + reinterpret_cast(oid_char), + dot - oid_char, + &integer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (component_index == 0ul) + { + // The first component is encoded with the second component. + first_component = integer; + } + else if (component_index == 1ul) + { + if (first_component < 2ul + && integer > 39ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + else if (first_component > 2ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t oid_value = first_component * 40ul + integer; + if (oid_value > 0xff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u8_t oid_octet(static_cast(oid_value)); + + status = buffer->add_data(&oid_octet, sizeof(oid_octet)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + eap_variable_data_c encoded_data(m_am_tools); + if (encoded_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + const u32_t ENCODE_BASE = 128ul; + + while(integer > 0ul) + { + const u8_t oid_octet = static_cast(integer % ENCODE_BASE); + + // Encodes the octets to reverse order. + status = encoded_data.add_data(&oid_octet, sizeof(oid_octet)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + integer = integer / ENCODE_BASE; + } // while() + + for (u32_t ind = encoded_data.get_data_length(); ind > 0ul; --ind) + { + // reads the octets on reverse order. + u8_t * oid_octet = encoded_data.get_data_offset(ind-1ul, sizeof(u8_t)); + if (oid_octet == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (ind > 1ul) + { + // All but the last octet have high bit set. + *oid_octet |= static_cast(asn1_high_bit_mask_tag); + } + + status = buffer->add_data(oid_octet, sizeof(*oid_octet)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + } + + remaining_length -= (dot - oid_char) + 1ul; + + oid_char = dot+1ul; + + ++component_index; + + } // while() + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e asn1_der_type_c::compare_object_identifier(const u8_t * const der_encoded_oid, const u32_t oid_length) const +{ + if (get_tag() != asn1_tag_object_identifier + || der_encoded_oid == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t content_length(get_content_length()); + + if (content_length != oid_length + || m_am_tools->memcmp( + der_encoded_oid, + get_content(), + content_length) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_no_match; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e asn1_der_type_c::compare_object_identifier(eap_const_string oid, const u32_t oid_length) const +{ + if (get_tag() != asn1_tag_object_identifier + || oid == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_variable_data_c oid_buffer(m_am_tools); + + if (oid_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = encode_oid_from_string(oid, oid_length, &oid_buffer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return compare_object_identifier(oid_buffer.get_data(), oid_buffer.get_data_length()); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e asn1_der_type_c::decode(const eap_variable_data_c * const asn1_der_data) +{ + if (asn1_der_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_variable_data_c * debug_buffer = 0; + +#if defined(USE_EAP_DEBUG_TRACE) + // Buffer is used for debug traces. + eap_variable_data_c tmp_debug_buffer(m_am_tools); + + { + eap_status_e status = tmp_debug_buffer.set_buffer_length(MAX_DEBUG_BUFFER); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + debug_buffer = &tmp_debug_buffer; + } +#endif // #if defined(USE_EAP_DEBUG_TRACE) + + + eap_status_e status = initialize( + asn1_der_data->get_data_length(), + asn1_der_data->get_data(), + 0ul, + 0ul, + debug_buffer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + asn1_der_type_c * current_type = this; + + if (current_type->get_pc() == asn1_pc_constructed) + { + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("# this = 0x%08x, input_data_length=%d, used_octets=%d\n"), + current_type, + current_type->get_input_data_length(), + current_type->get_used_octets())); + + while (current_type->get_used_octets() != current_type->get_input_data_length()) + { + asn1_der_type_c * sub_type = new asn1_der_type_c(m_am_tools); + + eap_automatic_variable_c automatic_sub_type(m_am_tools, sub_type); + + if (sub_type == 0 + || sub_type->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("# this = 0x%08x, unused_data_length=%d, recursion=%d\n"), + current_type, + current_type->get_unused_data_length(), + current_type->get_recursion())); + + status = sub_type->initialize( + current_type->get_unused_data_length(), + current_type->get_unused_data(), + current_type->get_recursion() + 1u, + current_type->get_count_of_sub_types(), + debug_buffer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + current_type->increase_count_of_sub_types(); + + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("# this = 0x%08x, used_octets=%d\n"), + sub_type, + sub_type->get_used_octets())); + + automatic_sub_type.do_not_free_variable(); + + status = current_type->add_sub_type(sub_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (sub_type->get_pc() == asn1_pc_primitive) + { + ASN1_DEBUG_DATA(sub_type, debug_buffer); + + sub_type->add_used_octets(sub_type->get_content_length()); + + current_type = sub_type; + + do + { + sub_type = current_type; + current_type = current_type->get_parent_type(); + current_type->add_used_octets(sub_type->get_used_octets()); + + ASN1_TYPE_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("# this = 0x%08x, input_data_length=%d, used_octets=%d\n"), + current_type, + current_type->get_input_data_length(), + current_type->get_used_octets())); + } + while (current_type->get_used_octets() == current_type->get_input_data_length() && current_type->get_parent_type() != 0); + } + else + { + current_type = sub_type; + } + + } // while() + } + else + { + ASN1_DEBUG_DATA(this, debug_buffer); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_base_type.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_base_type.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 20 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_base_type.h" + + +EAP_FUNC_EXPORT eap_base_type_c::~eap_base_type_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +EAP_FUNC_EXPORT eap_base_type_c::eap_base_type_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner) +: m_type_partner(partner) +, m_am_tools(tools) +, m_reference_count(0u) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +EAP_FUNC_EXPORT void eap_base_type_c::object_increase_reference_count() +{ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("REF: eap_base_type_c::object_increase_reference_count(): this 0x%08x, counter %d.\n"), + this, m_reference_count+1)); + ++m_reference_count; +} + +EAP_FUNC_EXPORT u32_t eap_base_type_c::object_decrease_reference_count() +{ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("REF: eap_base_type_c::object_decrease_reference_count(): this 0x%08x, counter %d.\n"), + this, m_reference_count)); + if (m_reference_count > 0u) + { + --m_reference_count; + } + else if (m_reference_count == 0u) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: eap_base_type_c::object_decrease_reference_count(): reference count already zero (0).\n"))); + } + return m_reference_count; +} + +EAP_FUNC_EXPORT abs_eap_base_type_c * eap_base_type_c::get_type_partner() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_type_partner; +} + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_buffer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_buffer.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1069 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 21 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_buffer.h" +#include "eap_am_assert.h" +#include "eap_am_tools.h" +#include "eapol_ethernet_header.h" + +static const bool EAP_BUFFER_DO_PACKET_RETRANSMISSION_INIT_VALUE = true; + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_buf_chain_base_c::check_guard_bytes(const u8_t * const guard) const +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return false; + } + + u32_t ind = 0; + for (ind = 0; ind < m_data->m_mem_guard_length; ind++) + { + if (guard[ind] != EAP_MEM_GUARD_BYTE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: check_guard_bytes(): buffer overflow in byte %d."), + ind)); + EAP_ASSERT_ANYWAY_TOOLS(m_am_tools); + return false; + } + } + return true; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT abs_eap_am_tools_c * eap_buf_chain_base_c::get_am_tools() +{ + return m_am_tools; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_buf_chain_base_c::check_guards() const +{ + +#if defined(_DEBUG) + if (m_data == 0 + || m_data->m_buffer == 0) + { + return false; + } + + if (m_data->m_buffer->get_is_writable() == true) + { + const u8_t * const buffer = m_data->m_buffer->get_data( + m_data->m_buffer->get_data_length()); + + if (buffer == 0) + { + return true; + } + + if (check_guard_bytes(buffer) == false + || check_guard_bytes( + buffer+(m_data->m_buffer->get_buffer_length() + - m_data->m_mem_guard_length)) == false + /* || check_guard_bytes(buffer+(m_data->m_real_data_length + - m_data->m_mem_guard_length)) == false */) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: check_guard_bytes(): buffer overflow, buffer 0x%08x."), + buffer - m_data->m_mem_guard_length)); + EAP_ASSERT_ANYWAY_TOOLS(m_am_tools); + return false; + } + } +#endif //#if defined(_DEBUG) + + return true; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_base_c::~eap_buf_chain_base_c() +{ + if (m_data != 0) + { + check_guards(); + + delete m_data->m_buffer; + m_data->m_buffer = 0; + } + + delete m_data; + m_data = 0; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_base_c::eap_buf_chain_base_c( + const eap_write_buffer_e, + abs_eap_am_tools_c * const tools, + u8_t * const data, + const u32_t data_length, + const bool reset_data, + const bool free_buffer, + const u32_t mem_guard_length) + : m_am_tools(tools) + , m_data(0) +{ + eap_status_e status = initialize(mem_guard_length); + if (status != eap_status_ok) + { + if (free_buffer == true) + { + delete [] data; + } + return; + } + + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0 + || m_data->m_buffer == 0) + { + if (free_buffer == true) + { + delete [] data; + } + return; + } + + status = m_data->m_buffer->set_buffer( + data, + data_length, + free_buffer, + true); + if (status != eap_status_ok) + { + if (free_buffer == true) + { + delete [] data; + } + m_data->m_is_valid = false; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + EAP_ASSERT_TOOLS(m_am_tools, data_length >= m_data->m_mem_guard_length); + m_data->m_buffer->set_data_length(data_length - m_data->m_mem_guard_length); + + set_mem_guard_bytes(); + + if (reset_data == true) + { + reset_data_buffer(); + } +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_base_c::eap_buf_chain_base_c( + const eap_read_buffer_e, + abs_eap_am_tools_c * const tools, + const u8_t * const data, + const u32_t data_length, + const bool free_buffer) + : m_am_tools(tools) + , m_data(0) +{ + eap_status_e status = initialize(0ul); + if (status != eap_status_ok) + { + return; + } + + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0 + || m_data->m_buffer == 0) + { + return; + } + + status = m_data->m_buffer->set_buffer( + data, + data_length, + free_buffer, + false); + if (status != eap_status_ok) + { + m_data->m_is_valid = false; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_base_c::eap_buf_chain_base_c( + const eap_write_buffer_e, + abs_eap_am_tools_c * const tools, + const u32_t data_length) + : m_am_tools(tools) + , m_data(0) +{ + eap_status_e status = initialize(EAP_MEM_GUARD_LENGTH); + if (status != eap_status_ok) + { + return; + } + + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0 + || m_data->m_buffer == 0) + { + return; + } + + status = m_data->m_buffer->init(data_length+2*m_data->m_mem_guard_length); + if (status == eap_status_ok) + { + m_data->m_buffer->set_is_valid(); + m_data->m_buffer->set_data_length(m_data->m_mem_guard_length); + set_mem_guard_bytes(); + } + else + { + m_data->m_is_valid = false; + } +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_base_c::eap_buf_chain_base_c( + const eap_read_buffer_e, + abs_eap_am_tools_c * const tools, + const u32_t data_length) + : m_am_tools(tools) + , m_data(0) +{ + eap_status_e status = initialize(EAP_MEM_GUARD_LENGTH); + if (status != eap_status_ok) + { + return; + } + + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0 + || m_data->m_buffer == 0) + { + return; + } + + if (data_length > 0ul) + { + status = m_data->m_buffer->init(data_length+2*m_data->m_mem_guard_length); + if (status == eap_status_ok) + { + m_data->m_buffer->set_is_valid(); + m_data->m_buffer->set_data_length(m_data->m_mem_guard_length); + set_mem_guard_bytes(); + } + else + { + m_data->m_is_valid = false; + } + } +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_buf_chain_base_c::initialize( + const u32_t mem_guard_length) +{ + m_data = new eap_buf_chain_base_impl_str; + if (m_data == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_data->m_mem_guard_length = mem_guard_length; + m_data->m_buffer = 0; + m_data->m_next_buffer = 0; + m_data->m_random_error_type = eap_random_error_type_none_keep_this_last_case; + m_data->m_send_packet_index = 0ul; + m_data->m_stack_address = 0; + m_data->m_is_valid = false; + m_data->m_is_manipulated = false; + m_data->m_do_packet_retransmission = EAP_BUFFER_DO_PACKET_RETRANSMISSION_INIT_VALUE; + m_data->m_is_client = true; + m_data->m_do_length_checks = false; + m_data->m_encrypt = false; + + m_data->m_buffer = new eap_variable_data_c(m_am_tools); + if (m_data->m_buffer == 0 + || m_data->m_buffer->get_is_valid() == false) + { + delete m_data; + m_data = 0; + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_data->m_is_valid = true; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_base_c::reset_data_buffer() +{ + if (m_data == 0 + || m_data->m_buffer == 0) + { + return; + } + + m_am_tools->memset( + get_data(get_data_length()), + 0, + get_data_length()); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_base_c::set_mem_guard_bytes() +{ + EAP_ASSERT_TOOLS( + m_am_tools, + m_data != 0); + EAP_ASSERT_TOOLS( + m_am_tools, + m_data->m_buffer->get_buffer_length() + >= m_data->m_mem_guard_length); + EAP_ASSERT_TOOLS( + m_am_tools, + m_data->m_buffer->get_data_length() + >= m_data->m_mem_guard_length); + + if (m_data == 0 + || m_data->m_buffer == 0) + { + return; + } + + u8_t * const buffer = m_data->m_buffer->get_data(m_data->m_buffer->get_data_length()); + + m_am_tools->memset( + buffer, + EAP_MEM_GUARD_BYTE, + m_data->m_mem_guard_length); + + m_am_tools->memset( + buffer+(m_data->m_buffer->get_buffer_length() - m_data->m_mem_guard_length), + EAP_MEM_GUARD_BYTE, + m_data->m_mem_guard_length); + + m_am_tools->memset( + buffer+(m_data->m_buffer->get_data_length()), + EAP_MEM_GUARD_BYTE, + m_data->m_mem_guard_length); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_buf_chain_base_c::get_mem_guard_length() +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return 0; + } + + return m_data->m_mem_guard_length; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_buf_chain_base_c::get_buffer_length() const +{ + EAP_ASSERT_TOOLS( + m_am_tools, + m_data != 0); + EAP_ASSERT_TOOLS( + m_am_tools, + m_data->m_buffer->get_buffer_length() + >= 2ul*m_data->m_mem_guard_length); + + if (m_data == 0 + || m_data->m_buffer == 0) + { + return 0; + } + + return m_data->m_buffer->get_buffer_length() - 2ul*m_data->m_mem_guard_length; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_buf_chain_base_c::get_data_length() const +{ + EAP_ASSERT_TOOLS( + m_am_tools, + m_data != 0); + EAP_ASSERT_TOOLS( + m_am_tools, + m_data->m_buffer->get_data_length() + >= m_data->m_mem_guard_length); + + if (m_data == 0 + || m_data->m_buffer == 0) + { + return 0; + } + + return m_data->m_buffer->get_data_length() - m_data->m_mem_guard_length; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_buf_chain_base_c::get_data_offset( + const u32_t p_offset, + const u32_t p_continuous_bytes) const +{ + EAP_ASSERT_TOOLS( + m_am_tools, + m_data != 0); + EAP_ASSERT_TOOLS( + m_am_tools, + m_data->m_buffer->get_data_length() >= m_data->m_mem_guard_length); + + if (m_data == 0 + || m_data->m_buffer == 0) + { + return 0; + } + + if (p_offset+p_continuous_bytes <= get_buffer_length()) + { + return m_data->m_buffer->get_buffer_offset( + p_offset + m_data->m_mem_guard_length, + p_continuous_bytes); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Fragments are not supported yet.\n"))); + EAP_ASSERT_ALWAYS_TOOLS( + m_am_tools, + p_offset+p_continuous_bytes <= get_data_length()); + return 0; + } +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_buf_chain_base_c::get_data( + const u32_t p_continuous_bytes) const +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0 + || m_data->m_buffer == 0) + { + return 0; + } + + return get_data_offset(0u, p_continuous_bytes); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_buf_chain_base_c::set_buffer_length( + const u32_t buffer_length) +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + EAP_ASSERT_TOOLS(m_am_tools, m_data->m_buffer != 0); + + if (m_data == 0 + || m_am_tools == 0 + || m_am_tools->get_is_valid() == false) + { + return eap_status_allocation_error; + } + + if (m_data->m_buffer == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_data->m_buffer->reset(); + + eap_status_e status = m_data->m_buffer->init(buffer_length+2*m_data->m_mem_guard_length); + if (status == eap_status_ok) + { + m_data->m_buffer->set_is_valid(); + m_data->m_buffer->set_data_length(m_data->m_mem_guard_length); + set_mem_guard_bytes(); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_buf_chain_base_c::set_data_length( + const u32_t length) +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + EAP_ASSERT_TOOLS(m_am_tools, m_data->m_buffer != 0); + EAP_ASSERT_TOOLS(m_am_tools, m_data->m_buffer->get_is_writable() == true); + + if (m_data == 0 + || m_am_tools == 0 + || m_am_tools->get_is_valid() == false) + { + return eap_status_allocation_error; + } + + if (m_data->m_buffer == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + check_guards(); + + if (get_buffer_length() > length) + { + // Here we must reset the memory guard bytes because not all of the buffer is used. + EAP_ASSERT_TOOLS( + m_am_tools, + m_data->m_buffer->get_data_length() + >= m_data->m_mem_guard_length); + + u8_t * const buffer = m_data->m_buffer->get_data_offset( + m_data->m_mem_guard_length, + m_data->m_buffer->get_data_length() - m_data->m_mem_guard_length); + if (buffer == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + m_am_tools->memset( + buffer+length, + EAP_MEM_GUARD_BYTE, + m_data->m_mem_guard_length); + } + + m_data->m_buffer->set_data_length(length + m_data->m_mem_guard_length); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_buf_chain_base_c::get_is_valid() const +{ + if (m_data == 0) + { + return false; + } + + return m_data->m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_buf_chain_base_c::get_is_valid_data() const +{ + if (m_data == 0) + { + return false; + } + + if (m_data->m_is_valid == false) + { + return false; + } + + // Note the buffer could be empty. + if (m_data->m_buffer == 0) + { + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_base_c::set_is_manipulated() +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return; + } + + m_data->m_is_manipulated = true; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_buf_chain_base_c::get_is_manipulated() +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return false; + } + + return m_data->m_is_manipulated; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_base_c::set_send_packet_index(const u32_t send_packet_index) +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return; + } + + m_data->m_send_packet_index = send_packet_index; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_buf_chain_base_c::get_send_packet_index() +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return 0; + } + + return m_data->m_send_packet_index; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_base_c::set_random_error_type( + eap_random_error_type error_type) +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return; + } + + m_data->m_random_error_type = error_type; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_random_error_type eap_buf_chain_base_c::get_random_error_type() +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return eap_random_error_type_manipulate_byte; + } + + return m_data->m_random_error_type; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_base_c::set_do_packet_retransmission( + const bool do_packet_retransmission_when_true) +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return; + } + + m_data->m_do_packet_retransmission = do_packet_retransmission_when_true; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_buf_chain_base_c::get_do_packet_retransmission() +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return false; + } + + return m_data->m_do_packet_retransmission; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_base_c::set_is_client(const bool is_client_when_true) +{ + m_data->m_is_client = is_client_when_true; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_buf_chain_base_c::get_is_client() const +{ + return m_data->m_is_client; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_base_c::set_do_length_checks(const bool do_length_checks) +{ + m_data->m_do_length_checks = do_length_checks; +} + +EAP_FUNC_EXPORT bool eap_buf_chain_base_c::get_do_length_checks() const +{ + return m_data->m_do_length_checks; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_base_c::set_encrypt(const bool encrypt_when_true) +{ + m_data->m_encrypt = encrypt_when_true; +} + +EAP_FUNC_EXPORT bool eap_buf_chain_base_c::get_encrypt() const +{ + return m_data->m_encrypt; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_base_c::set_stack_address(const void * const stack_address) +{ + m_data->m_stack_address = stack_address; +} + +EAP_FUNC_EXPORT const void * eap_buf_chain_base_c::get_stack_address() const +{ + return m_data->m_stack_address; +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_buf_chain_base_c::add_data( + const void * const buffer, + const u32_t buffer_length) +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0 + || m_am_tools == 0 + || m_am_tools->get_is_valid() == false) + { + return eap_status_allocation_error; + } + + eap_status_e status = add_data_to_offset( + get_data_length(), + buffer, + buffer_length); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_buf_chain_base_c::add_data( + const eap_variable_data_c * const buffer) +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0 + || m_am_tools == 0 + || m_am_tools->get_is_valid() == false) + { + return eap_status_allocation_error; + } + + return EAP_STATUS_RETURN(m_am_tools, add_data( + buffer->get_data(buffer->get_data_length()), + buffer->get_data_length())); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_buf_chain_base_c::add_data_to_offset( + const u32_t offset, + const void * const buffer, + const u32_t buffer_length) +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0 + || m_am_tools == 0 + || m_am_tools->get_is_valid() == false) + { + return eap_status_allocation_error; + } + + eap_status_e status = m_data->m_buffer->add_data_to_offset( + m_data->m_mem_guard_length+offset, + buffer, + buffer_length); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_buf_chain_base_c::add_data_to_offset( + const u32_t offset, + const eap_variable_data_c * const buffer) +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0 + || m_am_tools == 0 + || m_am_tools->get_is_valid() == false) + { + return eap_status_allocation_error; + } + + eap_status_e status = m_data->m_buffer->add_data_to_offset( + m_data->m_mem_guard_length+offset, + buffer->get_data(buffer->get_data_length()), + buffer->get_data_length()); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_wr_c::~eap_buf_chain_wr_c() +{ +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_wr_c::eap_buf_chain_wr_c( + const eap_write_buffer_e, + abs_eap_am_tools_c * const tools, + u8_t * const data, + const u32_t data_length, + const bool reset_data, + const bool free_buffer, + const u32_t mem_guard_length) + : eap_buf_chain_base_c( + eap_write_buffer, + tools, + data, + data_length, + reset_data, + free_buffer, + mem_guard_length) +{ +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_wr_c::eap_buf_chain_wr_c( + const eap_write_buffer_e, + abs_eap_am_tools_c * const tools, + const u32_t data_length) + : eap_buf_chain_base_c(eap_write_buffer, tools, data_length) +{ +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_wr_c::eap_buf_chain_wr_c( + const eap_write_buffer_e, + abs_eap_am_tools_c * const tools) + : eap_buf_chain_base_c(eap_write_buffer, tools, 0ul) +{ +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_wr_c::force_inheritance() +{ +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_buf_chain_wr_c::get_ethernet_header() +{ + return static_cast( + get_data( + eapol_ethernet_header_wr_c::get_header_length())); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_wr_c * eap_buf_chain_wr_c::copy() +{ + if (get_is_valid() == false) + { + return 0; + } + + u8_t *new_data = new u8_t[get_buffer_length()+(2u*get_mem_guard_length())]; + + if (new_data == 0) + { + return 0; + } + + get_am_tools()->memmove( + new_data+get_mem_guard_length(), + get_data(get_buffer_length()), + get_buffer_length()); + + eap_buf_chain_wr_c * const new_buffer + = new eap_buf_chain_wr_c( + eap_write_buffer, + get_am_tools(), + new_data, + get_buffer_length()+(2u*get_mem_guard_length()), + false, // Do not init data + true, // Free buffer on destructor + get_mem_guard_length()); + + if (new_buffer == 0 + || new_buffer->get_is_valid_data() == false) + { + delete new_buffer; + return 0; + } + + new_buffer->set_data_length(get_data_length()); + + new_buffer->set_send_packet_index(get_send_packet_index()); + new_buffer->set_random_error_type(get_random_error_type()); + new_buffer->set_stack_address(get_stack_address()); + new_buffer->set_is_client(get_is_client()); + + return new_buffer; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_rd_c::~eap_buf_chain_rd_c() +{ + check_guards(); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_rd_c::eap_buf_chain_rd_c( + const eap_read_buffer_e, + abs_eap_am_tools_c * const tools, + const u8_t * const data, + const u32_t data_length, + const bool free_buffer) + : eap_buf_chain_base_c( + eap_read_buffer, + tools, + data, + data_length, + free_buffer) +{ +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_rd_c::eap_buf_chain_rd_c( + const eap_read_buffer_e, + abs_eap_am_tools_c * const tools, + const u32_t data_length) + : eap_buf_chain_base_c(eap_read_buffer, tools, data_length) +{ +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_buf_chain_rd_c::force_inheritance() +{ +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT const u8_t * eap_buf_chain_rd_c::get_data( + const u32_t p_continuous_bytes) const +{ + return static_cast( + eap_buf_chain_base_c::get_data(p_continuous_bytes)); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT const u8_t * eap_buf_chain_rd_c::get_data_offset( + const u32_t p_offset, + const u32_t p_continuous_bytes) const +{ + return static_cast( + eap_buf_chain_base_c::get_data_offset( + p_offset, + p_continuous_bytes)); +} + +//----------------------------------------------------------------------------- + +EAP_FUNC_EXPORT const u8_t * eap_buf_chain_rd_c::get_ethernet_header() const +{ + return static_cast( + get_data( + eapol_ethernet_header_rd_c::get_header_length())); +} + +//----------------------------------------------------------------------------- + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_crypto_api.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_crypto_api.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,6097 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 22 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_crypto_api.h" + +//-------------------------------------------------- + +// This is simple optimization. +const u32_t EAP_CRYPTO_API_SHA1_DIGEST_BUFFER_BYTE_SIZE = 20ul; +const u32_t EAP_CRYPTO_API_SHA1_BLOCK_BYTE_SIZE = 64ul; + +const u32_t EAP_CRYPTO_API_SHA_256_DIGEST_BUFFER_BYTE_SIZE = 32ul; +const u32_t EAP_CRYPTO_API_SHA_256_BLOCK_BYTE_SIZE = 64ul; + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT abs_crypto_cbc_block_algorithm_c::~abs_crypto_cbc_block_algorithm_c() +{ +} + + +EAP_FUNC_EXPORT abs_crypto_block_algorithm_c::~abs_crypto_block_algorithm_c() +{ +} + +EAP_FUNC_EXPORT abs_crypto_stream_algorithm_c::~abs_crypto_stream_algorithm_c() +{ +} + +EAP_FUNC_EXPORT abs_crypto_hash_algorithm_c::~abs_crypto_hash_algorithm_c() +{ +} + +EAP_FUNC_EXPORT abs_crypto_hmac_algorithm_c::~abs_crypto_hmac_algorithm_c() +{ +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + + +EAP_FUNC_EXPORT crypto_hmac_c::~crypto_hmac_c() +{ + hmac_cleanup(); + + delete m_key; + m_key = 0; + + delete m_ipad; + m_ipad = 0; + + delete m_opad; + m_opad = 0; +} + +EAP_FUNC_EXPORT crypto_hmac_c::crypto_hmac_c( + abs_eap_am_tools_c * const tools, + abs_crypto_hash_algorithm_c * const crypto_hash_algorithm, + const bool free_crypto_hash_algorithm) + : m_am_tools(tools) + , m_crypto_hash_algorithm(crypto_hash_algorithm) + , m_key(0) + , m_ipad(0) + , m_opad(0) + , m_is_valid(false) + , m_free_crypto_hash_algorithm(free_crypto_hash_algorithm) +{ + m_key = new eap_variable_data_c(m_am_tools); + if (m_key == 0) + { + return; + } + + m_ipad = new eap_variable_data_c(m_am_tools); + if (m_ipad == 0) + { + return; + } + + m_opad = new eap_variable_data_c(m_am_tools); + if (m_opad == 0) + { + return; + } + + set_is_valid(); +} + +EAP_FUNC_EXPORT void crypto_hmac_c::set_is_valid() +{ + m_is_valid = true; +} + +EAP_FUNC_EXPORT bool crypto_hmac_c::get_is_valid() +{ + return m_is_valid; +} + +EAP_FUNC_EXPORT u32_t crypto_hmac_c::get_digest_length() +{ + return m_crypto_hash_algorithm->get_digest_length(); +} + +EAP_FUNC_EXPORT eap_status_e crypto_hmac_c::initialize_pad( + eap_variable_data_c * const p_pad, + const u8_t pad_value) +{ + if (get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = p_pad->set_buffer_length( + m_crypto_hash_algorithm->get_block_size()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + p_pad->set_data_length(m_crypto_hash_algorithm->get_block_size()); + + u32_t ind = 0ul; + u8_t * key = m_key->get_data(m_key->get_data_length()); + u8_t * ipad = p_pad->get_data(p_pad->get_data_length()); + + for (ind = 0ul; ind < m_key->get_data_length(); ind++) + { + ipad[ind] = static_cast(key[ind] ^ pad_value); + } + + for (ind = m_key->get_data_length() + ; ind < m_crypto_hash_algorithm->get_block_size(); ind++) + { + ipad[ind] = pad_value; + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e crypto_hmac_c::hmac_set_key( + const eap_variable_data_c * const hmac_key) +{ + if (hmac_key == 0 + || hmac_key->get_is_valid_data() == false + || get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = eap_status_process_general_error; + + status = m_crypto_hash_algorithm->hash_init(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (hmac_key->get_data_length() + > m_crypto_hash_algorithm->get_block_size()) + { + status = m_crypto_hash_algorithm->hash_update( + hmac_key->get_data(hmac_key->get_data_length()), + hmac_key->get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_key->set_buffer_length( + m_crypto_hash_algorithm->get_digest_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_key->set_data_length(m_crypto_hash_algorithm->get_digest_length()); + + u32_t md_length = m_key->get_data_length(); + + status = m_crypto_hash_algorithm->hash_final( + m_key->get_data(m_key->get_data_length()), + &md_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT(md_length == m_key->get_data_length()); + } + else + { + status = m_key->set_copy_of_buffer(hmac_key); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - + // Initialize inner pad. + + { + static const u8_t EAP_HMAC_IPAD = 0x36; + + status = initialize_pad( + m_ipad, + EAP_HMAC_IPAD); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - + // Initialize outer pad. + + { + static const u8_t EAP_HMAC_OPAD = 0x5C; + + status = initialize_pad( + m_opad, + EAP_HMAC_OPAD); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - + + status = m_crypto_hash_algorithm->hash_init(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_crypto_hash_algorithm->hash_update( + m_ipad->get_data(m_ipad->get_data_length()), + m_ipad->get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e crypto_hmac_c::hmac_update( + const void * const data, + const u32_t data_length) +{ + if (get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = m_crypto_hash_algorithm->hash_update( + data, + data_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e crypto_hmac_c::hmac_final( + void * const message_digest, + u32_t *md_length_or_null) +{ + if (get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_variable_data_c idigest(m_am_tools); + + eap_status_e status = idigest.set_buffer_length( + m_crypto_hash_algorithm->get_digest_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + idigest.set_data_length(m_crypto_hash_algorithm->get_digest_length()); + + u32_t md_length = idigest.get_data_length(); + + status = m_crypto_hash_algorithm->hash_final( + idigest.get_data(idigest.get_data_length()), + &md_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT(md_length == m_crypto_hash_algorithm->get_digest_length()); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_crypto_hash_algorithm->hash_init(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_crypto_hash_algorithm->hash_update( + m_opad->get_data(m_opad->get_data_length()), + m_opad->get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_crypto_hash_algorithm->hash_update( + idigest.get_data(idigest.get_data_length()), + idigest.get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_crypto_hash_algorithm->hash_final( + message_digest, + md_length_or_null); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (md_length_or_null != 0) + { + EAP_ASSERT(*md_length_or_null + == m_crypto_hash_algorithm->get_digest_length()); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +EAP_FUNC_EXPORT eap_status_e crypto_hmac_c::hmac_128_final( + void * const message_digest, + u32_t *md_length_or_null) +{ + if (message_digest == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t tmp_length = get_digest_length(); + eap_variable_data_c tmp_digest(m_am_tools); + if (tmp_digest.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + eap_status_e status = tmp_digest.set_buffer_length(tmp_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_final( + tmp_digest.get_buffer(tmp_digest.get_buffer_length()), + &tmp_length); + if (status != eap_status_ok + || tmp_length != tmp_digest.get_buffer_length()) + { + if (md_length_or_null != 0) + { + *md_length_or_null = 0; + } + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + status = tmp_digest.set_data_length(tmp_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (md_length_or_null != 0) + { + *md_length_or_null = HMAC_SHA1_128_SIZE; + } + + m_am_tools->memmove( + message_digest, + tmp_digest.get_data(HMAC_SHA1_128_SIZE), + HMAC_SHA1_128_SIZE); + + return EAP_STATUS_RETURN(m_am_tools, status); + } +} + +EAP_FUNC_EXPORT eap_status_e crypto_hmac_c::hmac_cleanup() +{ + if (m_key != 0) + { + m_key->reset(); + } + + if (m_ipad != 0) + { + m_ipad->reset(); + } + + if (m_opad != 0) + { + m_opad->reset(); + } + + if (m_free_crypto_hash_algorithm == true) + { + delete m_crypto_hash_algorithm; + } + m_crypto_hash_algorithm = 0; + + m_is_valid = false; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_cbc_c::~crypto_cbc_c() +{ + reset(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_cbc_c::crypto_cbc_c( + abs_eap_am_tools_c * const tools, + abs_crypto_block_algorithm_c * const crypto_block_algorithm, + const bool free_crypto_block_algorithm) + : m_am_tools(tools) + , m_crypto_block_algorithm(crypto_block_algorithm) + , m_is_valid(false) + , m_tmp_IV(0) + , m_encr_offset(0ul) + , m_encr_dispatch(0) + , m_encr_hold(0) + , m_saved_in_buffer(0) + , m_saved_out_buffer(0) + , m_iv_buffer_1(0) + , m_iv_buffer_2(0) + , m_free_crypto_block_algorithm(free_crypto_block_algorithm) +{ + m_tmp_IV = new eap_variable_data_c(m_am_tools); + m_encr_dispatch = new u8_t *[m_crypto_block_algorithm->get_block_size()]; + m_encr_hold = new u8_t [m_crypto_block_algorithm->get_block_size()]; + m_saved_in_buffer = new u8_t [m_crypto_block_algorithm->get_block_size()]; + m_saved_out_buffer = new u8_t [m_crypto_block_algorithm->get_block_size()]; + m_iv_buffer_1 = new u8_t [m_crypto_block_algorithm->get_block_size()]; + m_iv_buffer_2 = new u8_t [m_crypto_block_algorithm->get_block_size()]; + + if (m_tmp_IV == 0 + || m_encr_dispatch == 0 + || m_encr_hold == 0 + || m_saved_in_buffer == 0 + || m_saved_out_buffer == 0 + || m_iv_buffer_1 == 0 + || m_iv_buffer_2 == 0) + { + reset(); + } + else + { + set_is_valid(); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_cbc_c::reset() +{ + m_is_valid = false; + + if (m_tmp_IV != 0) + { + m_tmp_IV->reset(); + delete m_tmp_IV; + m_tmp_IV = 0; + } + + if (m_crypto_block_algorithm != 0) + { + if (m_encr_dispatch != 0) + { + m_am_tools->memset( + m_encr_dispatch, + 0, + m_crypto_block_algorithm->get_block_size()); + } + + if (m_encr_hold != 0) + { + m_am_tools->memset( + m_encr_hold, + 0, + m_crypto_block_algorithm->get_block_size()); + } + } + + delete [] m_encr_dispatch; + m_encr_dispatch = 0; + + delete [] m_encr_hold; + m_encr_hold = 0; + + delete [] m_saved_in_buffer; + m_saved_in_buffer = 0; + + delete [] m_saved_out_buffer; + m_saved_out_buffer = 0; + + delete [] m_iv_buffer_1; + m_iv_buffer_1 = 0; + + delete [] m_iv_buffer_2; + m_iv_buffer_2 = 0; + + if (m_free_crypto_block_algorithm == true) + { + delete m_crypto_block_algorithm; + } + m_crypto_block_algorithm = 0; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_cbc_c::cbc_xor_block( + const void * const cipher_IV, + void * const data_block, + const u32_t block_size, + const u32_t key_length) +{ + EAP_UNREFERENCED_PARAMETER(block_size); + EAP_UNREFERENCED_PARAMETER(key_length); + EAP_ASSERT((block_size % m_crypto_block_algorithm->get_block_size()) == 0); + EAP_ASSERT((key_length % m_crypto_block_algorithm->get_key_length()) == 0); + +#if defined(USE_EAP_64_BIT_MULTIPLICATION) + if ((reinterpret_cast(cipher_IV) % sizeof(u64_t)) == 0 + && (reinterpret_cast(data_block) % sizeof(u64_t)) == 0) + { + const u64_t * const pIV = static_cast(cipher_IV); + u64_t * const pdata = static_cast(data_block); + + for (u32_t ind = 0u; ind < block_size/sizeof(u64_t); ind++) + { + pdata[ind] ^= pIV[ind]; + } + } + else +#endif //#if defined(USE_EAP_64_BIT_MULTIPLICATION) + if ((reinterpret_cast(cipher_IV) % sizeof(u32_t)) == 0 + && (reinterpret_cast(data_block) % sizeof(u32_t)) == 0) + { + const u32_t * const pIV = static_cast(cipher_IV); + u32_t * const pdata = static_cast(data_block); + + for (u32_t ind = 0u; ind < block_size/sizeof(u32_t); ind++) + { + pdata[ind] ^= pIV[ind]; + } + } + else if ((reinterpret_cast(cipher_IV) % sizeof(u16_t)) == 0 + && (reinterpret_cast(data_block) % sizeof(u16_t)) == 0) + { + const u16_t * const pIV = static_cast(cipher_IV); + u16_t * const pdata = static_cast(data_block); + + for (u32_t ind = 0u; ind < block_size/sizeof(u16_t); ind++) + { + pdata[ind] ^= pIV[ind]; + } + } + else + { + const u8_t * const pIV = static_cast(cipher_IV); + u8_t * const pdata = static_cast(data_block); + + for (u32_t ind = 0u; ind < block_size/sizeof(u8_t); ind++) + { + pdata[ind] ^= pIV[ind]; + } + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_cbc_c::cbc_copy_block( + void * const target, + const void * const source, + const u32_t block_size, + const u32_t key_length) +{ + EAP_UNREFERENCED_PARAMETER(key_length); + EAP_ASSERT((block_size % m_crypto_block_algorithm->get_block_size()) == 0); + EAP_ASSERT((key_length % m_crypto_block_algorithm->get_key_length()) == 0); + +#if defined(USE_EAP_64_BIT_MULTIPLICATION) + if ((reinterpret_cast(source) % sizeof(u64_t)) == 0 + && (reinterpret_cast(target) % sizeof(u64_t)) == 0) + { + const u64_t * const p_source + = static_cast(source); + u64_t * const p_target = static_cast(target); + + for (u32_t ind = 0u; ind < block_size/sizeof(u64_t); ind++) + { + p_target[ind] = p_source[ind]; + } + } + else +#endif //#if defined(USE_EAP_64_BIT_MULTIPLICATION) + if ((reinterpret_cast(source) % sizeof(u32_t)) == 0 + && (reinterpret_cast(target) % sizeof(u32_t)) == 0) + { + const u32_t * const p_source + = static_cast(source); + u32_t * const p_target = static_cast(target); + + for (u32_t ind = 0u; ind < block_size/sizeof(u32_t); ind++) + { + p_target[ind] = p_source[ind]; + } + } + else if ((reinterpret_cast(source) % sizeof(u16_t)) == 0 + && (reinterpret_cast(target) % sizeof(u16_t)) == 0) + { + const u16_t * const p_source + = static_cast(source); + u16_t * const p_target = static_cast(target); + + for (u32_t ind = 0u; ind < block_size/sizeof(u16_t); ind++) + { + p_target[ind] = p_source[ind]; + } + } + else + { + const u8_t * const p_source = static_cast(source); + u8_t * const p_target = static_cast(target); + + for (u32_t ind = 0u; ind < block_size/sizeof(u8_t); ind++) + { + p_target[ind] = p_source[ind]; + } + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_cbc_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_cbc_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_variable_data_c * crypto_cbc_c::get_tmp_IV() +{ + return m_tmp_IV; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_cbc_c::get_encrypts() +{ + return m_crypto_block_algorithm->get_encrypts(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_cbc_c::get_key_length() +{ + return m_crypto_block_algorithm->get_key_length(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_cbc_c::get_block_size() +{ + return m_crypto_block_algorithm->get_block_size(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_cbc_c::aligned_data_length( + u32_t data_length) +{ + const u32_t fill_bytes = data_length + % (m_crypto_block_algorithm->get_block_size()); + + // NOTE, this will always add padding bytes (1...BLOCK_SIZE). + data_length += ((m_crypto_block_algorithm->get_block_size())-fill_bytes); + + return data_length; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::add_padding_bytes( + void * const buffer, + const u32_t buffer_length, + const u8_t padding_byte) +{ + u8_t * const p_buffer = static_cast(buffer); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CBC: encrypt_function: crypto_cbc_c::add_padding_bytes(): buffer=0x%08x, buffer_length=%d, padding_byte=0x%02x\n"), + buffer, + buffer_length, + padding_byte)); + + for(u32_t ind = 0; ind < buffer_length; ind++) + { + p_buffer[ind] = padding_byte; + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("crypto_cbc_c::add_padding_bytes()"), + p_buffer, + buffer_length)); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::check_padding_bytes( + const void * const buffer, + const u32_t buffer_length, + const u8_t padding_byte) +{ + const u8_t * const p_buffer = static_cast(buffer); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CBC: encrypt_function: crypto_cbc_c::check_padding_bytes(): buffer=0x%08x, buffer_length=%d, padding_byte=0x%02x\n"), + buffer, + buffer_length, + padding_byte)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("crypto_cbc_c::check_padding_bytes()"), + p_buffer, + buffer_length)); + + for(u32_t ind = 0; ind < buffer_length; ind++) + { + if (p_buffer[ind] != padding_byte) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::set_encryption_key( + const void * const encryption_IV, + const u32_t encryption_IV_length, + const void * const key, + const u32_t key_length) +{ + eap_status_e status = m_tmp_IV->set_copy_of_buffer( + encryption_IV, encryption_IV_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return m_crypto_block_algorithm->set_encryption_key( + key, + key_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::set_decryption_key( + const void * const encryption_IV, + const u32_t encryption_IV_length, + const void * const key, + const u32_t key_length) +{ + eap_status_e status = m_tmp_IV->set_copy_of_buffer( + encryption_IV, encryption_IV_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return m_crypto_block_algorithm->set_decryption_key( + key, + key_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::internal_encrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + if ((data_length % m_crypto_block_algorithm->get_block_size()) != 0) + { + return EAP_STATUS_RETURN( + m_am_tools, + eap_status_data_length_not_aligned_to_block_size); + } + + const u8_t * const p_data_in = static_cast(data_in); + u8_t * const p_data_out = static_cast(data_out); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("encrypt data_in"), + data_in, data_length)); + + cbc_copy_block( + m_saved_in_buffer, + data_in, + m_crypto_block_algorithm->get_block_size(), + m_crypto_block_algorithm->get_key_length()); + + cbc_xor_block( + m_tmp_IV->get_data(m_tmp_IV->get_data_length()), + m_saved_in_buffer, + m_crypto_block_algorithm->get_block_size(), + m_crypto_block_algorithm->get_key_length()); + + u32_t ind; + eap_status_e status = eap_status_ok; + + for (ind = 0u; ind < data_length + ; ind += m_crypto_block_algorithm->get_block_size()) + { + if (ind > 0u) + { + cbc_copy_block( + m_saved_in_buffer, + p_data_in+ind, + m_crypto_block_algorithm->get_block_size(), + m_crypto_block_algorithm->get_key_length()); + + cbc_xor_block( + p_data_out+(ind-m_crypto_block_algorithm->get_block_size()), + m_saved_in_buffer, + m_crypto_block_algorithm->get_block_size(), + m_crypto_block_algorithm->get_key_length()); + } + + status = m_crypto_block_algorithm->encrypt_block( + m_saved_in_buffer, + m_saved_out_buffer, + m_crypto_block_algorithm->get_block_size()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + cbc_copy_block( + p_data_out+ind, + m_saved_out_buffer, + m_crypto_block_algorithm->get_block_size(), + m_crypto_block_algorithm->get_key_length()); + + } + + // Save the last block. + status = m_tmp_IV->set_copy_of_buffer( + p_data_out+(ind-m_crypto_block_algorithm->get_block_size()), + m_crypto_block_algorithm->get_block_size()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("encrypt data_out"), + data_out, + data_length)); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::encrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + EAP_ASSERT(data_in != data_out); + + eap_status_e status = internal_encrypt_data( + data_in, + data_out, + data_length); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::encrypt_data( + void * const data_in_out, + const u32_t data_length) +{ + + eap_status_e status = internal_encrypt_data( + data_in_out, + data_in_out, + data_length); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::internal_decrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + u8_t *saved_iv_buffer = m_iv_buffer_1; + u8_t *encrypted_buffer = m_iv_buffer_2; + + if ((data_length % m_crypto_block_algorithm->get_block_size()) != 0u) + { + return EAP_STATUS_RETURN( + m_am_tools, + eap_status_data_length_not_aligned_to_block_size); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("decrypt data_in"), + data_in, + data_length)); + + const u8_t * const p_data_in = static_cast(data_in); + u8_t * const p_data_out = static_cast(data_out); + + cbc_copy_block( + saved_iv_buffer, + m_tmp_IV->get_data(m_tmp_IV->get_data_length()), + m_crypto_block_algorithm->get_block_size(), + m_crypto_block_algorithm->get_key_length()); + + u32_t ind; + eap_status_e status = eap_status_ok; + + for (ind = 0u; ind < data_length + ; ind += m_crypto_block_algorithm->get_block_size()) + { + cbc_copy_block( + encrypted_buffer, + p_data_in+ind, + m_crypto_block_algorithm->get_block_size(), + m_crypto_block_algorithm->get_key_length()); + + cbc_copy_block( + m_saved_in_buffer, + p_data_in+ind, + m_crypto_block_algorithm->get_block_size(), + m_crypto_block_algorithm->get_key_length()); + + status = m_crypto_block_algorithm->decrypt_block( + m_saved_in_buffer, + m_saved_out_buffer, + m_crypto_block_algorithm->get_block_size()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + cbc_xor_block( + saved_iv_buffer, + m_saved_out_buffer, + m_crypto_block_algorithm->get_block_size(), + m_crypto_block_algorithm->get_key_length()); + + cbc_copy_block( + p_data_out+ind, + m_saved_out_buffer, + m_crypto_block_algorithm->get_block_size(), + m_crypto_block_algorithm->get_key_length()); + + u8_t *tmp = encrypted_buffer; + encrypted_buffer = saved_iv_buffer; + saved_iv_buffer = tmp; + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("decrypt data_out"), + data_out, + data_length)); + + // Save the last block. + status = m_tmp_IV->set_copy_of_buffer( + saved_iv_buffer, + m_crypto_block_algorithm->get_block_size()); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::decrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + EAP_ASSERT(data_in != data_out); + + eap_status_e status = internal_decrypt_data( + data_in, + data_out, + data_length); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::decrypt_data( + void * const data_in_out, + const u32_t data_length) +{ + + eap_status_e status = internal_decrypt_data( + data_in_out, + data_in_out, + data_length); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::update_non_aligned( + const void * const msg_in, + void * const msg_out, + const u32_t msg_size) +{ + EAP_ASSERT_ALWAYS(msg_in != msg_out); + + const u8_t *inp = reinterpret_cast(msg_in); + u8_t *oup = static_cast(msg_out); + i32_t len = static_cast(msg_size); + i32_t tail; + eap_status_e status = eap_status_process_general_error; + + if (m_encr_offset) + { + // + // Non aligned handling + // + while (len > 0 + && m_encr_offset + < static_cast(m_crypto_block_algorithm->get_block_size())) + { + m_encr_dispatch[m_encr_offset] = oup++; + m_encr_hold[m_encr_offset++] = *inp++; + len--; + } + + if (m_encr_offset == static_cast(m_crypto_block_algorithm->get_block_size())) + { + // Got full block, flush out + if (m_crypto_block_algorithm->get_encrypts() == true) + { + status = encrypt_data( + m_encr_hold, + m_crypto_block_algorithm->get_block_size()); + } + else + { + status = decrypt_data( + m_encr_hold, + m_crypto_block_algorithm->get_block_size()); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (m_encr_offset = 0 + ; m_encr_offset + < static_cast(m_crypto_block_algorithm->get_block_size()) + ; ++m_encr_offset) + { + *(m_encr_dispatch[m_encr_offset]) = m_encr_hold[m_encr_offset]; + } + m_encr_offset = 0; + } + // Either len == 0 or (encrypt->encr_offset) == 0, or both!!! + } + + tail = len % m_crypto_block_algorithm->get_block_size(); + len -= tail; + if (len > 0) + { + if (m_crypto_block_algorithm->get_encrypts() == true) + { + status = encrypt_data( + inp, + oup, + len); + } + else + { + status = decrypt_data( + inp, + oup, + len); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (tail > 0) + { + oup += len; + inp += len; + while (m_encr_offset < tail) + { + m_encr_dispatch[m_encr_offset] = oup++; + m_encr_hold[m_encr_offset++] = *inp++; + } + status = eap_status_ok; + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::update_non_aligned( + void * const msg_in_out, + const u32_t msg_size) +{ + u8_t *msg = static_cast(msg_in_out); + i32_t len = static_cast(msg_size); + i32_t tail; + eap_status_e status = eap_status_process_general_error; + + if (m_encr_offset) + { + // + // Non aligned handling + // + while (len > 0 + && m_encr_offset + < static_cast(m_crypto_block_algorithm->get_block_size())) + { + m_encr_dispatch[m_encr_offset] = msg; + m_encr_hold[m_encr_offset++] = *msg++; + len--; + } + + if (m_encr_offset == static_cast(m_crypto_block_algorithm->get_block_size())) + { + // Got full block, flush out + if (m_crypto_block_algorithm->get_encrypts() == true) + { + status = encrypt_data( + m_encr_hold, + m_crypto_block_algorithm->get_block_size()); + } + else + { + status = decrypt_data( + m_encr_hold, + m_crypto_block_algorithm->get_block_size()); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (m_encr_offset = 0 + ; m_encr_offset + < static_cast(m_crypto_block_algorithm->get_block_size()) + ; ++m_encr_offset) + { + *(m_encr_dispatch[m_encr_offset]) = m_encr_hold[m_encr_offset]; + } + m_encr_offset = 0; + } + // Either len == 0 or (encrypt->encr_offset) == 0, or both!!! + } + + tail = len % m_crypto_block_algorithm->get_block_size(); + len -= tail; + if (len > 0) + { + if (m_crypto_block_algorithm->get_encrypts() == true) + { + status = encrypt_data( + msg, + len); + } + else + { + status = decrypt_data( + msg, + len); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (tail > 0) + { + msg += len; + while (m_encr_offset < tail) + { + m_encr_dispatch[m_encr_offset] = msg; + m_encr_hold[m_encr_offset++] = *msg++; + } + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_cbc_c::finalize_non_aligned() +{ + eap_status_e status = eap_status_ok; + + if (m_encr_offset > 0) + { + if ((m_encr_offset + % m_crypto_block_algorithm->get_block_size()) != 0u) + { + EAP_ASSERT_ALWAYS( + (m_encr_offset + % m_crypto_block_algorithm->get_block_size()) == 0u); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_data_length_not_aligned_to_block_size); + } + + i32_t ind; + + /* Unfinished business... flush it out! */ + if (m_crypto_block_algorithm->get_encrypts() == true) + { + status = encrypt_data( + m_encr_hold, + m_crypto_block_algorithm->get_block_size()); + } + else + { + status = decrypt_data( + m_encr_hold, + m_crypto_block_algorithm->get_block_size()); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (ind = 0u; ind < m_encr_offset; ++ind) + { + *(m_encr_dispatch[ind]) = m_encr_hold[ind]; + } + m_encr_offset = 0; /* (should not be needed, but... ) */ + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_aes_c::~crypto_aes_c() +{ + if (m_aes_context.get_is_valid_data() == true) + { + m_am_tools->get_crypto()->aes_cleanup(&m_aes_context); + } + m_aes_context.reset(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_aes_c::crypto_aes_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_is_valid(false) + , m_aes_context(tools) + , m_block_size(0u) + , m_encrypt(false) +{ + m_block_size = m_am_tools->get_crypto()->aes_block_size(); + + m_aes_context.reset(); + + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_aes_c::get_encrypts() +{ + return m_encrypt; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_aes_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_aes_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_aes_c::get_key_length() +{ + return m_am_tools->get_crypto()->aes_key_length(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_aes_c::get_block_size() +{ + return m_block_size; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_aes_c::set_encryption_key( + const void * const key, + const u32_t key_length) +{ + m_encrypt = true; + + return m_am_tools->get_crypto()->aes_set_encryption_key( + &m_aes_context, static_cast(key), key_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_aes_c::set_decryption_key( + const void * const key, + const u32_t key_length) +{ + m_encrypt = false; + + return m_am_tools->get_crypto()->aes_set_decryption_key( + &m_aes_context, static_cast(key), key_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_aes_c::encrypt_block( + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + EAP_ASSERT_TOOLS(m_am_tools, ((reinterpret_cast(data_in) % 4) == 0)); + EAP_ASSERT_TOOLS(m_am_tools, ((reinterpret_cast(data_out) % 4) == 0)); + + return m_am_tools->get_crypto()->aes_encrypt_block( + &m_aes_context, + static_cast(data_in), + static_cast(data_out), + data_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_aes_c::decrypt_block( + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + EAP_ASSERT_TOOLS(m_am_tools, ((reinterpret_cast(data_in) % 4) == 0)); + EAP_ASSERT_TOOLS(m_am_tools, ((reinterpret_cast(data_out) % 4) == 0)); + + return m_am_tools->get_crypto()->aes_decrypt_block( + &m_aes_context, + static_cast(data_in), + static_cast(data_out), data_length); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_3des_ede_c::~crypto_3des_ede_c() +{ + if (m_context.get_is_valid_data() == true) + { + m_am_tools->get_crypto()->cleanup_3des_ede(&m_context); + } + m_context.reset(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_3des_ede_c::crypto_3des_ede_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_is_valid(false) + , m_context(tools) + , m_block_size(0u) + , m_encrypt(false) +{ + m_block_size = m_am_tools->get_crypto()->block_size_3des_ede(); + + m_context.reset(); + + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_3des_ede_c::get_encrypts() +{ + return m_encrypt; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_3des_ede_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_3des_ede_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_3des_ede_c::get_key_length() +{ + return m_am_tools->get_crypto()->key_length_3des_ede(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_3des_ede_c::get_block_size() +{ + return m_block_size; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_3des_ede_c::set_encryption_key( + const void * const key, + const u32_t key_length) +{ + m_encrypt = true; + + return m_am_tools->get_crypto()->set_encryption_key_3des_ede( + &m_context, static_cast(key), key_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_3des_ede_c::set_decryption_key( + const void * const key, + const u32_t key_length) +{ + m_encrypt = false; + + return m_am_tools->get_crypto()->set_decryption_key_3des_ede( + &m_context, static_cast(key), key_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_3des_ede_c::encrypt_block( + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + EAP_ASSERT_TOOLS(m_am_tools, ((reinterpret_cast(data_in) % 4) == 0)); + EAP_ASSERT_TOOLS(m_am_tools, ((reinterpret_cast(data_out) % 4) == 0)); + + return m_am_tools->get_crypto()->encrypt_block_3des_ede( + &m_context, + static_cast(data_in), + static_cast(data_out), + data_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_3des_ede_c::decrypt_block( + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + EAP_ASSERT_TOOLS(m_am_tools, ((reinterpret_cast(data_in) % 4) == 0)); + EAP_ASSERT_TOOLS(m_am_tools, ((reinterpret_cast(data_out) % 4) == 0)); + + return m_am_tools->get_crypto()->decrypt_block_3des_ede( + &m_context, + static_cast(data_in), + static_cast(data_out), + data_length); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_aes_wrap_c::~crypto_aes_wrap_c() +{ +} + +EAP_FUNC_EXPORT crypto_aes_wrap_c::crypto_aes_wrap_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_aes(tools) + , m_key(tools) + , m_encrypt(false) + , m_is_valid(false) +{ + if (m_aes.get_is_valid() == false) + { + return; + } + + if (m_key.get_is_valid() == false) + { + return; + } + + set_is_valid(); +} + +EAP_FUNC_EXPORT void crypto_aes_wrap_c::set_is_valid() +{ + m_is_valid = true; +} + +EAP_FUNC_EXPORT bool crypto_aes_wrap_c::get_is_valid() +{ + return m_is_valid; +} + +EAP_FUNC_EXPORT bool crypto_aes_wrap_c::get_encrypts() +{ + return m_encrypt; +} + +EAP_FUNC_EXPORT u32_t crypto_aes_wrap_c::get_key_length() +{ + return m_aes.get_key_length(); +} + +EAP_FUNC_EXPORT u32_t crypto_aes_wrap_c::get_block_size() +{ + return EAP_CRYPTO_AES_WRAP_BLOCK_SIZE; +} + +EAP_FUNC_EXPORT eap_status_e crypto_aes_wrap_c::set_encryption_key( + const void * const key, + const u32_t key_length) +{ + eap_status_e status = m_key.set_copy_of_buffer(key, key_length); + + m_encrypt = true; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("AES-Wrap enc key"), + m_key.get_data(), + m_key.get_data_length())); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e crypto_aes_wrap_c::set_decryption_key( + const void * const key, + const u32_t key_length) +{ + eap_status_e status = m_key.set_copy_of_buffer(key, key_length); + + m_encrypt = false; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("AES-Wrap dec key"), + m_key.get_data(), + m_key.get_data_length())); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e crypto_aes_wrap_c::add_padding_bytes( + void * const buffer, + const u32_t buffer_length) +{ + if (buffer == 0 + || buffer_length == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u8_t * data = static_cast(buffer); + + data[0] = 0xdd; + + for (u32_t ind = 1ul; ind < buffer_length; ind++) + { + data[ind] = 0x00; + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +EAP_FUNC_EXPORT eap_status_e crypto_aes_wrap_c::encrypt_block( + const void * const data_in, + const u32_t data_in_length, + void * const data_out, + const u32_t data_out_length) +{ +#if !defined(DISABLE_CRYPTO_AES_WRAP) + /* + Inputs: Plaintext, n 64-bit values {P1, P2, ..., Pn}, and + Key, K (the KEK). + Outputs: Ciphertext, (n+1) 64-bit values {C0, C1, ..., Cn}. + */ + if (data_in == 0 + || data_out == 0 + || (data_in_length % get_block_size()) != 0 + || data_out_length < data_in_length+get_block_size()) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("plain data"), + data_in, + data_in_length)); + + /* + 1) Initialize variables. + + Set A = IV, an initial value (see 2.2.3) + For i = 1 to n + R[i] = P[i] + */ + + u64_t A_integrity_reg; + EAP_ASSERT_TOOLS(m_am_tools, sizeof(A_integrity_reg) == sizeof(EAP_CRYPTO_AES_WRAP_DEFAULT_INITIAL_IV)); + m_am_tools->memmove(&A_integrity_reg, EAP_CRYPTO_AES_WRAP_DEFAULT_INITIAL_IV, sizeof(A_integrity_reg)); + + eap_variable_data_c Register(m_am_tools); + + eap_status_e status = Register.set_copy_of_buffer(data_in, data_in_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + /* + 2) Calculate intermediate values. + + For j = 0 to 5 + For i=1 to n + B = AES(K, A | R[i]) + A = MSB(64, B) ^ t where t = (n*j)+i + R[i] = LSB(64, B) + */ + + u64_t n_block_count = Register.get_data_length() / 8ul; + u64_t B_tmp_buffer[2]; + eap_variable_data_c data(m_am_tools); + + status = data.set_buffer_length(sizeof(A_integrity_reg) + EAP_CRYPTO_AES_WRAP_BLOCK_SIZE); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (u64_t j_ind = 0ul; j_ind <= 5ul; j_ind++) + { + for (u64_t i_ind = 1ul; i_ind <= n_block_count; i_ind++) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("crypto_aes_wrap_c::encrypt_block(): j_ind %d, i_ind %d\n"), + j_ind, + i_ind)); + + eap_status_e status = m_aes.set_encryption_key( + m_key.get_data(), + m_key.get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("In A_integrity_reg"), + &A_integrity_reg, + sizeof(A_integrity_reg))); + + status = data.set_copy_of_buffer(&A_integrity_reg, sizeof(A_integrity_reg)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const Ri_reg = Register.get_data_offset( + static_cast((i_ind-1ul))*static_cast(EAP_CRYPTO_AES_WRAP_BLOCK_SIZE), + static_cast(EAP_CRYPTO_AES_WRAP_BLOCK_SIZE)); + if (Ri_reg == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL(" In Ri_reg"), + Ri_reg, + static_cast(EAP_CRYPTO_AES_WRAP_BLOCK_SIZE))); + + status = data.add_data(Ri_reg, EAP_CRYPTO_AES_WRAP_BLOCK_SIZE); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT_TOOLS(m_am_tools, sizeof(B_tmp_buffer) == data.get_data_length()); + + status = m_aes.encrypt_block( + data.get_data(), + B_tmp_buffer, + data.get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL(" Enc B_tmp_buffer"), + B_tmp_buffer, + sizeof(B_tmp_buffer))); + + u64_t counter = m_am_tools->multiply_u64(n_block_count, j_ind) + i_ind; + + A_integrity_reg = eap_htonll( + m_am_tools->xor_u64( + eap_ntohll(*B_tmp_buffer), + counter)); + + m_am_tools->memmove(Ri_reg, B_tmp_buffer+1, sizeof(u64_t)); + } + } + + /* + 3) Output the results. + + Set C[0] = A + For i = 1 to n + C[i] = R[i] + */ + + u8_t * const C = static_cast(data_out); + + m_am_tools->memmove(C, &A_integrity_reg, EAP_CRYPTO_AES_WRAP_BLOCK_SIZE); + + for (u32_t i_ind = 1ul; i_ind <= n_block_count; i_ind++) + { + u32_t offset = static_cast(i_ind)*static_cast(EAP_CRYPTO_AES_WRAP_BLOCK_SIZE); + + u8_t * const Ri_reg = Register.get_data_offset( + static_cast((i_ind-1ul))*static_cast(EAP_CRYPTO_AES_WRAP_BLOCK_SIZE), + static_cast(EAP_CRYPTO_AES_WRAP_BLOCK_SIZE)); + if (Ri_reg == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove((C + offset), Ri_reg, EAP_CRYPTO_AES_WRAP_BLOCK_SIZE); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("encrypted data"), + data_out, + data_out_length)); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + +#else // !defined(DISABLE_CRYPTO_AES_WRAP) + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +#endif + +} + +EAP_FUNC_EXPORT eap_status_e crypto_aes_wrap_c::decrypt_block( + const void * const data_in, + const u32_t data_in_length, + void * const data_out, + const u32_t data_out_length) +{ +#if !defined(DISABLE_CRYPTO_AES_WRAP) + /* + Inputs: Ciphertext, (n+1) 64-bit values {C0, C1, ..., Cn}, and + Key, K (the KEK). + Outputs: Plaintext, n 64-bit values {P0, P1, K, Pn}. + */ + if (data_in == 0 + || data_out == 0 + || (data_in_length % get_block_size()) != 0 + || data_out_length < data_in_length-get_block_size()) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("encrypted data"), + data_in, + data_in_length)); + + /* + 1) Initialize variables. + + Set A = C[0] + For i = 1 to n + R[i] = C[i] + */ + u64_t A_integrity_reg(0ul); + const u8_t * const cipher_text = static_cast(data_in); + + m_am_tools->memmove(&A_integrity_reg, cipher_text, EAP_CRYPTO_AES_WRAP_BLOCK_SIZE); + + eap_variable_data_c Register(m_am_tools); + + eap_status_e status = Register.set_copy_of_buffer( + (cipher_text + static_cast(EAP_CRYPTO_AES_WRAP_BLOCK_SIZE)), + data_in_length - static_cast(EAP_CRYPTO_AES_WRAP_BLOCK_SIZE)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + /* + 2) Compute intermediate values. + + For j = 5 to 0 + For i = n to 1 + B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i + A = MSB(64, B) + R[i] = LSB(64, B) + */ + + u64_t n_block_count = Register.get_data_length() / 8ul; + u64_t B_tmp_buffer[2]; + eap_variable_data_c data(m_am_tools); + + status = data.set_buffer_length(sizeof(A_integrity_reg) + EAP_CRYPTO_AES_WRAP_BLOCK_SIZE); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u64_t j_ind(5ul); + + for(;;) + { + for (u64_t i_ind = n_block_count; i_ind >= 1; i_ind--) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("crypto_aes_wrap_c::decrypt_block(): j_ind %d, i_ind %d\n"), + j_ind, + i_ind)); + + eap_status_e status = m_aes.set_decryption_key( + m_key.get_data(), + m_key.get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u64_t counter = m_am_tools->multiply_u64(n_block_count, j_ind) + i_ind; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("In A_integrity_reg"), + &A_integrity_reg, + sizeof(A_integrity_reg))); + + A_integrity_reg = eap_htonll( + m_am_tools->xor_u64( + eap_ntohll(A_integrity_reg), + counter)); + + status = data.set_copy_of_buffer(&A_integrity_reg, sizeof(A_integrity_reg)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const Ri_reg = Register.get_data_offset( + static_cast((i_ind-1ul))*static_cast(EAP_CRYPTO_AES_WRAP_BLOCK_SIZE), + static_cast(EAP_CRYPTO_AES_WRAP_BLOCK_SIZE)); + if (Ri_reg == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL(" In Ri_reg"), + Ri_reg, + EAP_CRYPTO_AES_WRAP_BLOCK_SIZE)); + + status = data.add_data(Ri_reg, EAP_CRYPTO_AES_WRAP_BLOCK_SIZE); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT_TOOLS(m_am_tools, sizeof(B_tmp_buffer) == data.get_data_length()); + + status = m_aes.decrypt_block( + data.get_data(), + B_tmp_buffer, + data.get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL(" Dec B_tmp_buffer"), + B_tmp_buffer, + sizeof(B_tmp_buffer))); + + A_integrity_reg = *B_tmp_buffer; + + m_am_tools->memmove(Ri_reg, B_tmp_buffer+1, sizeof(u64_t)); + } + + if (j_ind == 0) + { + // Terminates the loop. + break; + } + + // Decrementation must be after the termination test, + // because we need to run the loop also with j_ind value 0. + --j_ind; + } + + /* + 3) Output results. + + If A is an appropriate initial value (see 2.2.3), + Then + For i = 1 to n + P[i] = R[i] + Else + Return an error + */ + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("plain data"), + Register.get_data(), + Register.get_data_length())); + + if (m_am_tools->memcmp(&A_integrity_reg, EAP_CRYPTO_AES_WRAP_DEFAULT_INITIAL_IV, sizeof(A_integrity_reg)) == 0) + { + // OK + m_am_tools->memmove(data_out, Register.get_data(), Register.get_data_length()); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + +#else // !defined(DISABLE_CRYPTO_AES_WRAP) + + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + +#endif + +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_random_c::~crypto_random_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_random_c::crypto_random_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_is_valid(false) +{ + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_random_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_random_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_random_c::get_rand_bytes( + void * const buffer, + const u32_t count) +{ + return m_am_tools->get_crypto()->get_rand_bytes( + static_cast(buffer), count); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_random_c::get_rand_bytes( + eap_variable_data_c * const buffer, + const u32_t count) +{ + if (buffer == 0 + || buffer->get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = buffer->init(count); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = buffer->set_data_length(count); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_rand_bytes( + buffer->get_data(), + buffer->get_data_length()); + if (status != eap_status_ok) + { + buffer->reset(); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_random_c::get_rand_integer( + const u32_t minimum, + const u32_t maximum) +{ + const u32_t MAX_U32 = ~(static_cast(0ul)); + + u32_t random = 0ul; + + if ((maximum - minimum) == MAX_U32 ) + { + eap_status_e status = get_rand_bytes(&random, sizeof(random)); + if (status != eap_status_ok) + { + return 0; + } + } + else + { + u32_t frame = ((maximum+1)-minimum); + u32_t randomized = 0; + u32_t max_value = MAX_U32 - (MAX_U32 % frame); + + do + { + eap_status_e status = get_rand_bytes(&randomized, sizeof(randomized)); + if (status != eap_status_ok) + { + return 0; + } + } + while(randomized >= max_value); + + random = ((randomized % frame) + minimum); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("RANDOM u32_t %lu\n"), + random)); + + return random; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_random_c::add_rand_seed( + const void * const buffer, + const u32_t count) +{ + return m_am_tools->get_crypto()->add_rand_seed( + static_cast(buffer), count); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_random_c::add_rand_seed_hw_ticks() +{ + return m_am_tools->get_crypto()->add_rand_seed_hw_ticks(); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_sha_256_c::~crypto_sha_256_c() +{ + hash_cleanup(); + m_sha_256_context.reset(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_sha_256_c::crypto_sha_256_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_sha_256_context(tools) + , m_is_valid(false) +{ + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_sha_256_c::copy_context( + const eap_variable_data_c * const sha_256_context) +{ + if (sha_256_context == 0 + || sha_256_context->get_is_valid_data() == false) + { + set_is_invalid(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = m_am_tools->get_crypto()->sha_256_copy_context( + &m_sha_256_context, + sha_256_context); + if (status != eap_status_ok) + { + set_is_invalid(); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_sha_256_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_sha_256_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_sha_256_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_sha_256_c::get_digest_length() +{ + // This is simple optimization. + return EAP_CRYPTO_API_SHA_256_DIGEST_BUFFER_BYTE_SIZE; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_sha_256_c::get_block_size() +{ + // This is simple optimization. + return EAP_CRYPTO_API_SHA_256_BLOCK_BYTE_SIZE; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_sha_256_c::hash_init() +{ + eap_status_e status = m_am_tools->get_crypto()->sha_256_init(&m_sha_256_context); + if (m_sha_256_context.get_is_valid_data() == false) + { + set_is_invalid(); + if (status == eap_status_ok) + { + status = eap_status_allocation_error; + } + } + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_sha_256_c::hash_update( + const void * const data, + const u32_t data_length) +{ + eap_status_e status = m_am_tools->get_crypto()->sha_256_update( + &m_sha_256_context, + static_cast(data), + data_length); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_sha_256_c::hash_final( + void * const message_digest, + u32_t *md_length_or_null) +{ + eap_status_e status = m_am_tools->get_crypto()->sha_256_final( + &m_sha_256_context, + static_cast(message_digest), + md_length_or_null); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_sha_256_c::hash_cleanup() +{ + if (m_sha_256_context.get_is_valid_data() == true) + { + m_am_tools->get_crypto()->sha_256_cleanup(&m_sha_256_context); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT abs_crypto_hash_algorithm_c * crypto_sha_256_c::copy() +{ + crypto_sha_256_c * const new_context = new crypto_sha_256_c(m_am_tools); + if (new_context == 0) + { + return 0; + } + + eap_status_e status = new_context->copy_context(&m_sha_256_context); + if (status != eap_status_ok) + { + delete new_context; + return 0; + } + + return new_context; +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_sha1_c::~crypto_sha1_c() +{ + hash_cleanup(); + m_sha1_context.reset(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_sha1_c::crypto_sha1_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_sha1_context(tools) + , m_is_valid(false) +{ + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_sha1_c::copy_context( + const eap_variable_data_c * const sha1_context) +{ + if (sha1_context == 0 + || sha1_context->get_is_valid_data() == false) + { + set_is_invalid(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = m_am_tools->get_crypto()->sha1_copy_context( + &m_sha1_context, + sha1_context); + if (status != eap_status_ok) + { + set_is_invalid(); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_sha1_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_sha1_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_sha1_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_sha1_c::get_digest_length() +{ + // This is simple optimization. + return EAP_CRYPTO_API_SHA1_DIGEST_BUFFER_BYTE_SIZE; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_sha1_c::get_block_size() +{ + // This is simple optimization. + return EAP_CRYPTO_API_SHA1_BLOCK_BYTE_SIZE; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_sha1_c::hash_init() +{ + eap_status_e status = m_am_tools->get_crypto()->sha1_init(&m_sha1_context); + if (m_sha1_context.get_is_valid_data() == false) + { + set_is_invalid(); + if (status == eap_status_ok) + { + status = eap_status_allocation_error; + } + } + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_sha1_c::hash_update( + const void * const data, + const u32_t data_length) +{ + eap_status_e status = m_am_tools->get_crypto()->sha1_update( + &m_sha1_context, + static_cast(data), + data_length); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_sha1_c::hash_final( + void * const message_digest, + u32_t *md_length_or_null) +{ + eap_status_e status = m_am_tools->get_crypto()->sha1_final( + &m_sha1_context, + static_cast(message_digest), + md_length_or_null); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_sha1_c::hash_cleanup() +{ + if (m_sha1_context.get_is_valid_data() == true) + { + m_am_tools->get_crypto()->sha1_cleanup(&m_sha1_context); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT abs_crypto_hash_algorithm_c * crypto_sha1_c::copy() +{ + crypto_sha1_c * const new_context = new crypto_sha1_c(m_am_tools); + if (new_context == 0) + { + return 0; + } + + eap_status_e status = new_context->copy_context(&m_sha1_context); + if (status != eap_status_ok) + { + delete new_context; + return 0; + } + + return new_context; +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT +crypto_ephemeral_diffie_hellman_c::~crypto_ephemeral_diffie_hellman_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT +crypto_ephemeral_diffie_hellman_c::crypto_ephemeral_diffie_hellman_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_is_valid(false) +{ + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_ephemeral_diffie_hellman_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_ephemeral_diffie_hellman_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e +crypto_ephemeral_diffie_hellman_c::generate_diffie_hellman_keys( + eap_variable_data_c * const own_private_dh_key, + eap_variable_data_c * const own_public_dh_key, + const void * const prime, + const u32_t prime_length, + const void * const group_generator, + const u32_t group_generator_length) +{ + return m_am_tools->get_crypto()->generate_diffie_hellman_keys( + own_private_dh_key, + own_public_dh_key, + static_cast(prime), + prime_length, + static_cast(group_generator), + group_generator_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e +crypto_ephemeral_diffie_hellman_c::generate_g_power_to_xy( + const eap_variable_data_c * const own_private_dh_key, + const eap_variable_data_c * const peer_public_dh_key, + eap_variable_data_c * const shared_dh_key, + const void * const prime, + const u32_t prime_length, + const void * const group_generator, + const u32_t group_generator_length) +{ + return m_am_tools->get_crypto()->generate_g_power_to_xy( + own_private_dh_key, + peer_public_dh_key, + shared_dh_key, + static_cast(prime), + prime_length, + static_cast(group_generator), + group_generator_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e +crypto_ephemeral_diffie_hellman_c::dh_cleanup( + const eap_variable_data_c * const dh_context) +{ + return m_am_tools->get_crypto()->dh_cleanup( + dh_context); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_md5_c::~crypto_md5_c() +{ + hash_cleanup(); + m_md5_context.reset(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_md5_c::crypto_md5_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_md5_context(tools) + , m_is_valid(false) +{ + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_md5_c::copy_context( + const eap_variable_data_c * const md5_context) +{ + if (md5_context == 0 + || md5_context->get_is_valid_data() == false) + { + set_is_invalid(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = m_am_tools->get_crypto()->md5_copy_context( + &m_md5_context, + md5_context); + if (status != eap_status_ok) + { + set_is_invalid(); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_md5_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_md5_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_md5_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_md5_c::get_digest_length() +{ + return m_am_tools->get_crypto()->get_md5_digest_length(&m_md5_context); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_md5_c::get_block_size() +{ + return m_am_tools->get_crypto()->get_md5_block_size(&m_md5_context); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_md5_c::hash_init() +{ + eap_status_e status = m_am_tools->get_crypto()->md5_init(&m_md5_context); + + if (m_md5_context.get_is_valid_data() == false) + { + set_is_invalid(); + if (status == eap_status_ok) + { + status = eap_status_allocation_error; + } + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_md5_c::hash_update( + const void * const data, + const u32_t data_length) +{ + eap_status_e status = m_am_tools->get_crypto()->md5_update( + &m_md5_context, + static_cast(data), + data_length); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_md5_c::hash_final( + void * const message_digest, + u32_t *md_length_or_null) +{ + eap_status_e status = m_am_tools->get_crypto()->md5_final( + &m_md5_context, + static_cast(message_digest), + md_length_or_null); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_md5_c::hash_cleanup() +{ + if (m_md5_context.get_is_valid_data() == true) + { + m_am_tools->get_crypto()->md5_cleanup(&m_md5_context); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT abs_crypto_hash_algorithm_c * crypto_md5_c::copy() +{ + crypto_md5_c * const new_context = new crypto_md5_c(m_am_tools); + if (new_context == 0) + { + return 0; + } + + eap_status_e status = new_context->copy_context(&m_md5_context); + if (status != eap_status_ok) + { + delete new_context; + return 0; + } + + return new_context; +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_md4_c::~crypto_md4_c() +{ + hash_cleanup(); + m_md4_context.reset(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_md4_c::crypto_md4_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_md4_context(tools) + , m_is_valid(false) +{ + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_md4_c::copy_context( + const eap_variable_data_c * const md4_context) +{ + if (md4_context == 0 + || md4_context->get_is_valid_data() == false) + { + set_is_invalid(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = m_am_tools->get_crypto()->md4_copy_context( + &m_md4_context, + md4_context); + if (status != eap_status_ok) + { + set_is_invalid(); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_md4_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_md4_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_md4_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_md4_c::get_digest_length() +{ + return m_am_tools->get_crypto()->get_md4_digest_length(&m_md4_context); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t crypto_md4_c::get_block_size() +{ + return m_am_tools->get_crypto()->get_md4_block_size(&m_md4_context); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_md4_c::hash_init() +{ + // Cleanup the previous context. + hash_cleanup(); + + eap_status_e status = m_am_tools->get_crypto()->md4_init(&m_md4_context); + + if (m_md4_context.get_is_valid_data() == false) + { + set_is_invalid(); + if (status == eap_status_ok) + { + status = eap_status_allocation_error; + } + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_md4_c::hash_update( + const void * const data, + const u32_t data_length) +{ + eap_status_e status = m_am_tools->get_crypto()->md4_update( + &m_md4_context, + static_cast(data), + data_length); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_md4_c::hash_final( + void * const message_digest, + u32_t *md_length_or_null) +{ + eap_status_e status = m_am_tools->get_crypto()->md4_final( + &m_md4_context, + static_cast(message_digest), + md_length_or_null); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_md4_c::hash_cleanup() +{ + if (m_md4_context.get_is_valid_data() == true) + { + m_am_tools->get_crypto()->md4_cleanup(&m_md4_context); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT abs_crypto_hash_algorithm_c * crypto_md4_c::copy() +{ + crypto_md4_c * const new_context = new crypto_md4_c(m_am_tools); + if (new_context == 0) + { + return 0; + } + + eap_status_e status = new_context->copy_context(&m_md4_context); + if (status != eap_status_ok) + { + delete new_context; + return 0; + } + + return new_context; +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_rc4_c::~crypto_rc4_c() +{ + if (m_rc4_context.get_is_valid_data() == true) + { + m_am_tools->get_crypto()->rc4_cleanup(&m_rc4_context); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_rc4_c::crypto_rc4_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_rc4_context(tools) + , m_is_valid(false) +{ + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_rc4_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_rc4_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_rc4_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rc4_c::set_key( + const eap_variable_data_c * const key) +{ + return m_am_tools->get_crypto()->rc4_set_key(&m_rc4_context, key); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rc4_c::discard_stream( + const u32_t count_of_discarded_octets) +{ + eap_status_e status = eap_status_ok; + + for (u32_t ind = 0ul; ind < count_of_discarded_octets; ind++) + { + u8_t octet = 0; + status = encrypt_data( + &octet, + sizeof(octet)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rc4_c::encrypt_data( + void * const data_in_out, + const u32_t data_length) +{ + return m_am_tools->get_crypto()->rc4_encrypt( + &m_rc4_context, + data_in_out, + data_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rc4_c::encrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + return m_am_tools->get_crypto()->rc4_encrypt( + &m_rc4_context, + data_in, + data_out, + data_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rc4_c::decrypt_data( + void * const data_in_out, + const u32_t data_length) +{ + return m_am_tools->get_crypto()->rc4_decrypt( + &m_rc4_context, + data_in_out, + data_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rc4_c::decrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + return m_am_tools->get_crypto()->rc4_decrypt( + &m_rc4_context, + data_in, + data_out, + data_length); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_tls_base_prf_c::~crypto_tls_base_prf_c() +{ + tls_prf_cleanup(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_tls_base_prf_c::crypto_tls_base_prf_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_is_valid(false) +{ + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_tls_base_prf_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_tls_base_prf_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_tls_base_prf_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_base_prf_c::tls_prf_A_value( + abs_crypto_hmac_algorithm_c * const hash, + eap_variable_data_c * const key, + eap_variable_data_c * const seed, + eap_variable_data_c * const A_output) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (hash == 0 + || key == 0 + || seed == 0 + || A_output == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // First we initialize A value. + + eap_status_e status = hash->hmac_set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hash->hmac_update( + seed->get_data(seed->get_data_length()), + seed->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t hmac_md_length = hash->get_digest_length(); + + status = hash->hmac_final( + A_output->get_data(hmac_md_length), + &hmac_md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_base_prf_c::tls_prf_one_round( + abs_crypto_hmac_algorithm_c * const hash, + const eap_variable_data_c * const key, + eap_variable_data_c * const A_input, + eap_variable_data_c * const seed, + void * const out_buffer, + const u32_t out_buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (hash == 0 + || key == 0 + || A_input == 0 + || seed == 0 + || out_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = hash->hmac_set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hash->hmac_update( + A_input->get_data(A_input->get_data_length()), + A_input->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hash->hmac_update( + seed->get_data(seed->get_data_length()), + seed->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t hmac_md_length = hash->get_digest_length(); + + if (hmac_md_length > out_buffer_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + status = hash->hmac_final( + out_buffer, + &hmac_md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_base_prf_c::tls_prf_cleanup() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_tls_sha1_prf_c::~crypto_tls_sha1_prf_c() +{ + tls_prf_cleanup(); + + delete m_sha1_context; + m_sha1_context = 0; + + delete m_A_sha1_context; + m_A_sha1_context = 0; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_tls_sha1_prf_c::crypto_tls_sha1_prf_c( + abs_eap_am_tools_c * const tools) + : crypto_tls_base_prf_c(tools) + , m_am_tools(tools) + , m_sha1_context(0) + , m_A_sha1_context(0) + , m_sha1_key(tools) + , m_seed(tools) + , m_is_valid(false) +{ + { + crypto_sha1_c * sha1 = new crypto_sha1_c(m_am_tools); + if (sha1 == 0 + || sha1->get_is_valid() == false) + { + delete sha1; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + m_sha1_context = new crypto_hmac_c(m_am_tools, sha1, true); + if (m_sha1_context == 0 + || m_sha1_context->get_is_valid() == false) + { + delete m_sha1_context; + m_sha1_context = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + + { + crypto_sha1_c * sha1 = new crypto_sha1_c(m_am_tools); + if (sha1 == 0 + || sha1->get_is_valid() == false) + { + delete sha1; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + m_A_sha1_context = new crypto_hmac_c(m_am_tools, sha1, true); + if (m_A_sha1_context == 0 + || m_A_sha1_context->get_is_valid() == false) + { + delete m_A_sha1_context; + m_A_sha1_context = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_tls_sha1_prf_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_tls_sha1_prf_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_tls_sha1_prf_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_sha1_prf_c::tls_prf_init( + const eap_variable_data_c * const secret, + const eap_variable_data_c * const label, + const eap_variable_data_c * const seed) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (secret->get_is_valid_data() == false + || secret->get_data_length() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (label->get_is_valid_data() == false + || label->get_data_length() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // NOTE seed could be empty buffer. + if (seed->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c input(m_am_tools); + + eap_status_e status = input.add_data(label); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = input.add_data(seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_seed.set_copy_of_buffer(&input); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("tls_prf_init(): m_seed"), + m_seed.get_data(m_seed.get_data_length()), + m_seed.get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_sha1_key.set_copy_of_buffer( + secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("tls_prf_init(): m_sha1_key"), + m_sha1_key.get_data(m_sha1_key.get_data_length()), + m_sha1_key.get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_sha1_prf_c::tls_prf_output( + void * const pseudo_random_data, + const u32_t pseudo_random_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (pseudo_random_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = eap_status_not_supported; + + EAP_ASSERT_ALWAYS(get_is_valid() == true); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_A_sha1_context->hmac_set_key(&m_sha1_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_sha1_context->hmac_set_key(&m_sha1_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c A_sha1_output(m_am_tools); + + status = A_sha1_output.init(m_A_sha1_context->get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + A_sha1_output.set_is_valid(); + A_sha1_output.set_data_length(A_sha1_output.get_buffer_length()); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c sha1_output(m_am_tools); + + status = sha1_output.init( + pseudo_random_data_length+m_sha1_context->get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sha1_output.set_is_valid(); + sha1_output.set_data_length(sha1_output.get_buffer_length()); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + u32_t hmac_sha1_md_length = m_sha1_context->get_digest_length(); + u32_t sha1_count = sha1_output.get_data_length() + / m_sha1_context->get_digest_length(); + + // First we initialize A value: + // A(0) = seed + status = tls_prf_A_value( + m_A_sha1_context, + &m_sha1_key, + &m_seed, + &A_sha1_output); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // out(1) = HMAC_hash(secret, A(1) + seed) + status = tls_prf_one_round( + m_sha1_context, + &m_sha1_key, + &A_sha1_output, + &m_seed, + sha1_output.get_data_offset(0ul, hmac_sha1_md_length), + hmac_sha1_md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (u32_t ind = 1ul; ind < sha1_count; ind++) + { + // Next A value is: + // A(i) = HMAC_hash(secret, A(i-1)). + status = tls_prf_A_value( + m_A_sha1_context, + &m_sha1_key, + &A_sha1_output, + &A_sha1_output); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // out(i) = HMAC_hash(secret, A(i) + seed) + status = tls_prf_one_round( + m_sha1_context, + &m_sha1_key, + &A_sha1_output, + &m_seed, + sha1_output.get_data_offset( + ind*hmac_sha1_md_length, + hmac_sha1_md_length), + hmac_sha1_md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Final operation is copy sha1_output to output buffer. + + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("crypto_tls_sha1_prf_c::tls_prf_output(): sha1_output"), + sha1_output.get_data(pseudo_random_data_length), + pseudo_random_data_length)); + + EAP_ASSERT(pseudo_random_data_length <= sha1_output.get_data_length()); + + const u8_t * const sha1_buffer = sha1_output.get_data( + pseudo_random_data_length); + if (sha1_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u8_t * const p_pseudo_random_data + = static_cast(pseudo_random_data); + + m_am_tools->memmove( + p_pseudo_random_data, + sha1_buffer, + pseudo_random_data_length); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("crypto_tls_sha1_prf_c::tls_prf_output(): ") + EAPL("p_pseudo_random_data"), + p_pseudo_random_data, + pseudo_random_data_length)); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_sha1_prf_c::tls_prf_cleanup() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_sha1_context != 0) + { + m_sha1_context->hmac_cleanup(); + } + + if (m_A_sha1_context != 0) + { + m_A_sha1_context->hmac_cleanup(); + } + + m_sha1_key.reset(); + m_seed.reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_tls_md5_prf_c::~crypto_tls_md5_prf_c() +{ + tls_prf_cleanup(); + + delete m_md5_context; + m_md5_context = 0; + + delete m_A_md5_context; + m_A_md5_context = 0; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_tls_md5_prf_c::crypto_tls_md5_prf_c( + abs_eap_am_tools_c * const tools) + : crypto_tls_base_prf_c(tools) + , m_am_tools(tools) + , m_md5_context(0) + , m_A_md5_context(0) + , m_md5_key(tools) + , m_seed(tools) + , m_is_valid(false) +{ + { + crypto_md5_c * md5 = new crypto_md5_c(m_am_tools); + if (md5 == 0 + || md5->get_is_valid() == false) + { + delete md5; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + m_md5_context = new crypto_hmac_c(m_am_tools, md5, true); + if (m_md5_context == 0 + || m_md5_context->get_is_valid() == false) + { + delete m_md5_context; + m_md5_context = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + + { + crypto_md5_c * md5 = new crypto_md5_c(m_am_tools); + if (md5 == 0 + || md5->get_is_valid() == false) + { + delete md5; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + m_A_md5_context = new crypto_hmac_c(m_am_tools, md5, true); + if (m_A_md5_context == 0 + || m_A_md5_context->get_is_valid() == false) + { + delete m_A_md5_context; + m_A_md5_context = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_tls_md5_prf_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_tls_md5_prf_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_tls_md5_prf_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_md5_prf_c::tls_prf_init( + const eap_variable_data_c * const secret, + const eap_variable_data_c * const label, + const eap_variable_data_c * const seed) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (secret->get_is_valid_data() == false + || secret->get_data_length() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (label->get_is_valid_data() == false + || label->get_data_length() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (seed->get_is_valid_data() == false + || seed->get_data_length() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c input(m_am_tools); + + eap_status_e status = input.add_data(label); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = input.add_data(seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_seed.set_copy_of_buffer(&input); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("tls_prf_init(): m_seed"), + m_seed.get_data(m_seed.get_data_length()), + m_seed.get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_md5_key.set_copy_of_buffer( + secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("tls_prf_init(): m_md5_key"), + m_md5_key.get_data(m_md5_key.get_data_length()), + m_md5_key.get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_md5_prf_c::tls_prf_output( + void * const pseudo_random_data, + const u32_t pseudo_random_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (pseudo_random_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = eap_status_not_supported; + + EAP_ASSERT_ALWAYS(get_is_valid() == true); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_A_md5_context->hmac_set_key(&m_md5_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_md5_context->hmac_set_key(&m_md5_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c A_md5_output(m_am_tools); + + status = A_md5_output.init(m_A_md5_context->get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + A_md5_output.set_is_valid(); + A_md5_output.set_data_length(A_md5_output.get_buffer_length()); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c md5_output(m_am_tools); + + status = md5_output.init( + pseudo_random_data_length+m_md5_context->get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + md5_output.set_is_valid(); + md5_output.set_data_length(md5_output.get_buffer_length()); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + u32_t hmac_md5_md_length = m_md5_context->get_digest_length(); + u32_t md5_count = md5_output.get_data_length() + / m_md5_context->get_digest_length(); + + // First we initialize A value: + // A(0) = seed + status = tls_prf_A_value( + m_A_md5_context, + &m_md5_key, + &m_seed, + &A_md5_output); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // out(1) = HMAC_hash(secret, A(1) + seed) + status = tls_prf_one_round( + m_md5_context, + &m_md5_key, + &A_md5_output, + &m_seed, + md5_output.get_data_offset(0ul, hmac_md5_md_length), + hmac_md5_md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (u32_t ind = 1ul; ind < md5_count; ind++) + { + // Next A value is: + // A(i) = HMAC_hash(secret, A(i-1)). + status = tls_prf_A_value( + m_A_md5_context, + &m_md5_key, + &A_md5_output, + &A_md5_output); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // out(i) = HMAC_hash(secret, A(i) + seed) + status = tls_prf_one_round( + m_md5_context, + &m_md5_key, + &A_md5_output, + &m_seed, + md5_output.get_data_offset( + ind*hmac_md5_md_length, + hmac_md5_md_length), + hmac_md5_md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Final operation is copy md5_output to output buffer. + + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("crypto_tls_md5_prf_c::tls_prf_output(): md5_output"), + md5_output.get_data(pseudo_random_data_length), + pseudo_random_data_length)); + + EAP_ASSERT(pseudo_random_data_length <= md5_output.get_data_length()); + + const u8_t * const md5_buffer + = md5_output.get_data(pseudo_random_data_length); + if (md5_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u8_t * const p_pseudo_random_data + = static_cast(pseudo_random_data); + + m_am_tools->memmove( + p_pseudo_random_data, + md5_buffer, + pseudo_random_data_length); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("crypto_tls_md5_prf_c::tls_prf_output(): ") + EAPL("p_pseudo_random_data"), + p_pseudo_random_data, + pseudo_random_data_length)); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_md5_prf_c::tls_prf_cleanup() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_md5_context != 0) + { + m_md5_context->hmac_cleanup(); + } + + if (m_A_md5_context != 0) + { + m_A_md5_context->hmac_cleanup(); + } + + m_md5_key.reset(); + m_seed.reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_tls_prf_c::~crypto_tls_prf_c() +{ + tls_prf_cleanup(); + + delete m_tls_md5_prf; + m_tls_md5_prf = 0; + + delete m_tls_sha1_prf; + m_tls_sha1_prf = 0; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_tls_prf_c::crypto_tls_prf_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_tls_md5_prf(0) + , m_tls_sha1_prf(0) + , m_is_valid(false) +{ + m_tls_md5_prf = new crypto_tls_md5_prf_c(tools); + if (m_tls_md5_prf == 0) + { + return; + } + + m_tls_sha1_prf = new crypto_tls_sha1_prf_c(tools); + if (m_tls_sha1_prf == 0) + { + return; + } + + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_tls_prf_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_tls_prf_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_tls_prf_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_prf_c::tls_prf_init( + const eap_variable_data_c * const secret, + const eap_variable_data_c * const label, + const eap_variable_data_c * const seed) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_tls_md5_prf == 0 + || m_tls_sha1_prf == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (secret->get_is_valid_data() == false + || secret->get_data_length() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (label->get_is_valid_data() == false + || label->get_data_length() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (seed->get_is_valid_data() == false + || seed->get_data_length() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + bool is_odd_key = false; + if ((secret->get_data_length() % 2) != 0) + { + // Odd length, one byte will be shared with both keys. + is_odd_key = true; + } + + u32_t key_length = secret->get_data_length() / 2ul; + u32_t sha1_key_offset = key_length; + + if (is_odd_key == true) + { + ++key_length; + } + + eap_variable_data_c md5_secret(m_am_tools); + eap_variable_data_c sha1_secret(m_am_tools); + + eap_status_e status = md5_secret.set_buffer( + secret->get_data_offset(0ul, key_length), + key_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1_secret.set_buffer( + secret->get_data_offset(sha1_key_offset, key_length), + key_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = m_tls_md5_prf->tls_prf_init(&md5_secret, label, seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_tls_sha1_prf->tls_prf_init(&sha1_secret, label, seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_prf_c::tls_prf_output( + void * const pseudo_random_data, + const u32_t pseudo_random_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_not_supported; + + EAP_ASSERT_ALWAYS(get_is_valid() == true); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c tls_md5_prf_output(m_am_tools); + eap_variable_data_c tls_sha1_prf_output(m_am_tools); + + + status = tls_md5_prf_output.init(pseudo_random_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + tls_md5_prf_output.set_is_valid(); + tls_md5_prf_output.set_data_length(tls_md5_prf_output.get_buffer_length()); + + status = tls_sha1_prf_output.init(pseudo_random_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + tls_sha1_prf_output.set_is_valid(); + tls_sha1_prf_output.set_data_length( + tls_sha1_prf_output.get_buffer_length()); + + + status = m_tls_md5_prf->tls_prf_output( + tls_md5_prf_output.get_data(tls_md5_prf_output.get_data_length()), + tls_md5_prf_output.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_tls_sha1_prf->tls_prf_output( + tls_sha1_prf_output.get_data(tls_sha1_prf_output.get_data_length()), + tls_sha1_prf_output.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Final operation is XOR the md5_output and sha1_output. + + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("tls_prf_init(): tls_md5_prf_output"), + tls_md5_prf_output.get_data(tls_md5_prf_output.get_data_length()), + tls_md5_prf_output.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("tls_prf_init(): tls_sha1_prf_output"), + tls_sha1_prf_output.get_data( + tls_sha1_prf_output.get_data_length()), + tls_sha1_prf_output.get_data_length())); + + EAP_ASSERT( + pseudo_random_data_length + <= tls_md5_prf_output.get_data_length()); + EAP_ASSERT( + pseudo_random_data_length + <= tls_sha1_prf_output.get_data_length()); + + const u8_t * const md5_buffer + = tls_md5_prf_output.get_data(pseudo_random_data_length); + const u8_t * const sha1_buffer + = tls_sha1_prf_output.get_data(pseudo_random_data_length); + u8_t * const p_pseudo_random_data + = static_cast(pseudo_random_data); + + for (u32_t ind = 0u; ind < pseudo_random_data_length; ind++) + { + p_pseudo_random_data[ind] + = static_cast((md5_buffer[ind] ^ sha1_buffer[ind])); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("tls_prf_init(): p_pseudo_random_data"), + p_pseudo_random_data, + pseudo_random_data_length)); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_tls_prf_c::tls_prf_cleanup() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_tls_md5_prf != 0) + { + m_tls_md5_prf->tls_prf_cleanup(); + } + + if (m_tls_sha1_prf != 0) + { + m_tls_sha1_prf->tls_prf_cleanup(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + + +EAP_FUNC_EXPORT crypto_eap_fast_hmac_sha1_prf_c::~crypto_eap_fast_hmac_sha1_prf_c() +{ + t_prf_cleanup(); + + delete m_context; + m_context = 0; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_eap_fast_hmac_sha1_prf_c::crypto_eap_fast_hmac_sha1_prf_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_context(0) + , m_key(tools) + , m_S_value(tools) + , m_is_valid(false) +{ + { + crypto_sha1_c * sha1 = new crypto_sha1_c(m_am_tools); + if (sha1 == 0 + || sha1->get_is_valid() == false) + { + delete sha1; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + m_context = new crypto_hmac_c(m_am_tools, sha1, true); + if (m_context == 0 + || m_context->get_is_valid() == false) + { + delete m_context; + m_context = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_eap_fast_hmac_sha1_prf_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_eap_fast_hmac_sha1_prf_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_eap_fast_hmac_sha1_prf_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_eap_fast_hmac_sha1_prf_c::t_prf_init( + const eap_variable_data_c * const key, + const eap_variable_data_c * const label, + const eap_variable_data_c * const seed) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (key->get_is_valid_data() == false + || key->get_data_length() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (label->get_is_valid_data() == false + || label->get_data_length() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // NOTE seed could be empty buffer. + if (seed != 0 + && seed->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + m_S_value.reset(); + + eap_status_e status = m_S_value.set_copy_of_buffer(label); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t byte_counter(0ul); + + status = m_S_value.add_data(&byte_counter, sizeof(byte_counter)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (seed != 0) + { + status = m_S_value.add_data(seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("tls_prf_init(): m_S_value"), + m_S_value.get_data(), + m_S_value.get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_key.set_copy_of_buffer(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("tls_prf_init(): m_key"), + m_key.get_data(), + m_key.get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_eap_fast_hmac_sha1_prf_c::t_prf_output( + void * const pseudo_random_data, + const u16_t pseudo_random_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (pseudo_random_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = eap_status_not_supported; + + EAP_ASSERT_ALWAYS(get_is_valid() == true); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_context->hmac_set_key(&m_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c sha1_output(m_am_tools); + + u32_t required_data = pseudo_random_data_length+m_context->get_digest_length(); + + status = sha1_output.init( + required_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sha1_output.set_is_valid(); + sha1_output.set_data_length(0ul); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + u32_t hmac_sha1_md_length = m_context->get_digest_length(); + u32_t sha1_count = required_data + / m_context->get_digest_length(); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c T_value(m_am_tools); + if (T_value.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = T_value.set_buffer_length(hmac_sha1_md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = T_value.set_data_length(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u16_t network_order_pseudo_random_data_length(eap_htons(pseudo_random_data_length)); + u8_t byte_counter(0ul); + + for (u32_t ind = 0ul; ind < sha1_count; ind++) + { + ++byte_counter; + + // Next A value is: + // T(i) = HMAC_hash(key, T(i-1) + S + outputlength + 0x(i)). + + status = m_context->hmac_set_key(&m_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_context->hmac_update(T_value.get_data(), T_value.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_context->hmac_update(m_S_value.get_data(), m_S_value.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_context->hmac_update(&network_order_pseudo_random_data_length, sizeof(network_order_pseudo_random_data_length)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_context->hmac_update(&byte_counter, sizeof(byte_counter)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t digest_length(m_context->get_digest_length()); + + status = T_value.set_data_length(digest_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_context->hmac_final( + T_value.get_data(), + &digest_length); + + if (m_context->get_digest_length() != digest_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1_output.add_data(&T_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } // for() + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Final operation is copy sha1_output to output buffer. + + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("crypto_eap_fast_hmac_sha1_prf_c::tls_prf_output(): sha1_output"), + sha1_output.get_data(pseudo_random_data_length), + pseudo_random_data_length)); + + EAP_ASSERT(pseudo_random_data_length <= sha1_output.get_data_length()); + + const u8_t * const sha1_buffer = sha1_output.get_data( + pseudo_random_data_length); + if (sha1_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u8_t * const p_pseudo_random_data + = static_cast(pseudo_random_data); + + m_am_tools->memmove( + p_pseudo_random_data, + sha1_buffer, + pseudo_random_data_length); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("crypto_eap_fast_hmac_sha1_prf_c::tls_prf_output(): ") + EAPL("p_pseudo_random_data"), + p_pseudo_random_data, + pseudo_random_data_length)); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_eap_fast_hmac_sha1_prf_c::t_prf_cleanup() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_context != 0) + { + m_context->hmac_cleanup(); + } + + m_key.reset(); + m_S_value.reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_rsa_c::~crypto_rsa_c() +{ + cleanup(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_rsa_c::crypto_rsa_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_context(tools) + , m_is_valid(false) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_rsa_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_rsa_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_rsa_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rsa_c::init() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto()->rsa_init(&m_context); + + if (m_context.get_is_valid_data() == false) + { + set_is_invalid(); + if (status == eap_status_ok) + { + status = eap_status_allocation_error; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rsa_c::encrypt_with_public_key( + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto() + ->rsa_encrypt_with_public_key( + &m_context, + public_rsa_key, + input_data, + output_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rsa_c::decrypt_with_public_key( + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto() + ->rsa_decrypt_with_public_key( + &m_context, + public_rsa_key, + input_data, + output_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rsa_c::encrypt_with_private_key( + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto() + ->rsa_encrypt_with_private_key( + &m_context, + private_rsa_key, + input_data, + output_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rsa_c::decrypt_with_private_key( + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto() + ->rsa_decrypt_with_private_key( + &m_context, + private_rsa_key, + input_data, + output_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rsa_c::sign( + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto()->rsa_sign( + &m_context, + private_rsa_key, + hash, + signed_hash); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rsa_c::verify( + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto()->rsa_verify( + &m_context, + public_rsa_key, + hash, + signed_hash); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_rsa_c::cleanup() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto()->rsa_cleanup(&m_context); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_dsa_c::~crypto_dsa_c() +{ + cleanup(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_dsa_c::crypto_dsa_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_context(tools) + , m_is_valid(false) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_dsa_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void crypto_dsa_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_dsa_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_dsa_c::init() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto()->dsa_init(&m_context); + + if (m_context.get_is_valid_data() == false) + { + set_is_invalid(); + if (status == eap_status_ok) + { + status = eap_status_allocation_error; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_dsa_c::sign( + const eap_variable_data_c * const private_dsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto()->dsa_sign( + &m_context, + private_dsa_key, + hash, + signed_hash); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_dsa_c::verify( + const eap_variable_data_c * const public_dsa_key, + const eap_variable_data_c * const dsa_param_p, + const eap_variable_data_c * const dsa_param_q, + const eap_variable_data_c * const dsa_param_g, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto()->dsa_verify( + &m_context, + public_dsa_key, + dsa_param_p, + dsa_param_q, + dsa_param_g, + hash, + signed_hash); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_dsa_c::cleanup() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_am_tools->get_crypto()->dsa_cleanup(&m_context); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_wpa_psk_password_hash_c::~crypto_wpa_psk_password_hash_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_wpa_psk_password_hash_c::crypto_wpa_psk_password_hash_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_is_valid(false) +{ + set_is_valid(); +} + +//-------------------------------------------------- + +void crypto_wpa_psk_password_hash_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +void crypto_wpa_psk_password_hash_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_wpa_psk_password_hash_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// These are the functions for calculating PSK from ascii string +// taken from 802.11i D3.0 + +/* +* password - ascii string up to 63 characters in length +* ssid - octet string up to 32 octets +* ssidlength - length of ssid in octets +* output must be 40 octets in length and outputs 256 bits of key +*/ +EAP_FUNC_EXPORT eap_status_e crypto_wpa_psk_password_hash_c::password_hash( + const eap_variable_data_c * const password, + const eap_variable_data_c * const ssid, + eap_variable_data_c * const output, + void * object, + eap_status_e (*progress_callback)(void*, u32_t)) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Hashing WPA PSK ASCII password.\n"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("password"), + password->get_data(), + password->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ssid"), + ssid->get_data(), + ssid->get_data_length())); + + // Buffer must be reset before new HASH is added to it. + // This causes the new HASH addition to the begin of the buffer. + // This is small optimization that does not free the old buffer. + eap_status_e status = output->reset_start_offset_and_data_length(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if ((password->get_data_length() > 63) || (ssid->get_data_length() > 32)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = password_hash_F(password, ssid, 4096, 1, output, object, progress_callback); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = password_hash_F(password, ssid, 4096, 2, output, object, progress_callback); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // truncate the buffer to 32 bytes + output->set_data_length(WPA_PSK_LENGTH); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WPA PSK"), + output->get_data(), + output->get_data_length())); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +eap_status_e crypto_wpa_psk_password_hash_c::password_hash_F( + const eap_variable_data_c * const password, + const eap_variable_data_c * const ssid, + u32_t iterations, + u32_t count, + eap_variable_data_c * const output, + void * object, + eap_status_e (*progress_callback)(void*, u32_t)) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_process_general_error); + + crypto_sha1_c sha1(m_am_tools); + + status = sha1.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t digest_length = sha1.get_digest_length(); + + crypto_hmac_c hmac(m_am_tools, &sha1, false); + + u32_t i_ind, j_ind; + + // Check for illegal characters + for (i_ind = 0; i_ind < password->get_data_length(); i_ind++) + { + u8_t * const character = password->get_data_offset(i_ind, 1); + if (character == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if(!((*character >= 32) && (*character <= 126))) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + } + + eap_variable_data_c digest(m_am_tools); + eap_variable_data_c digest1(m_am_tools); + + status = digest.set_copy_of_buffer(ssid); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t tmp[] = { + static_cast((count>>24) & 0xff), + static_cast((count>>16) & 0xff), + static_cast((count>>8) & 0xff), + static_cast(count & 0xff) + }; + + status = digest.add_data(tmp, sizeof(tmp)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac.hmac_set_key(password); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac.hmac_update( + digest.get_data(), + digest.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = digest1.set_buffer_length(digest_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac.hmac_final( + digest1.get_buffer(digest_length), + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + digest1.set_data_length(digest_length); + + status = digest.set_buffer_length(digest_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + digest.set_data_length(digest_length); + + /* output = U1 */ + status = output->add_data(&digest1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * p_output = output->get_data_offset((count - 1) * digest_length, digest_length); + if (p_output == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t callback_trigger = 0ul; + + for (i_ind = 1; i_ind < iterations; i_ind++) + { + callback_trigger++; + + if (callback_trigger > 400 + && progress_callback != 0 + && object != 0) + { + callback_trigger = 0; + status = progress_callback(object, 400); + if (status != eap_status_ok) + { + // This means that the operation was cancelled. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WPA PSK password hashing cancelled.\n"))); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = hmac.hmac_set_key(password); + if (status != eap_status_ok) + { + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("illegal password:"), + password->get_data(), + password->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac.hmac_update( + digest1.get_data(), + digest1.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac.hmac_final( + digest.get_data(sha1.get_digest_length()), + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + digest.set_data_length(digest_length); + + status = digest1.set_copy_of_buffer(&digest); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + /* output = output xor Un */ + u8_t * p_digest = digest.get_data(digest_length); + if (p_digest == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + for (j_ind = 0; j_ind < digest_length; j_ind++) + { + p_output[j_ind] ^= p_digest[j_ind]; + } + } // for() + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + + +EAP_FUNC_EXPORT crypto_nt_hash_c::~crypto_nt_hash_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_nt_hash_c::crypto_nt_hash_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_is_valid(false) +{ + set_is_valid(); +} + +//-------------------------------------------------- + +void crypto_nt_hash_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +void crypto_nt_hash_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_nt_hash_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_nt_hash_c::nt_password_hash( + const eap_variable_data_c * const password_utf8, + eap_variable_data_c * const password_hash, + const u32_t /* digest_size */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (password_utf8 == 0 + || password_hash == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_variable_data_c tmp_password_unicode(m_am_tools); + eap_status_e status = m_am_tools->convert_utf8_to_unicode(tmp_password_unicode, *password_utf8); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Ms-Chap-V2 wants the byte order of password is little endian +#if defined(EAP_BIG_ENDIAN) + { + u32_t password_size = tmp_password_unicode.get_data_length(); + u8_t * password = tmp_password_unicode.get_data(password_size); + u8_t tmp; + + for (i = 0; i < password_size; i += 2) + { + // Swap bytes + tmp = password[i]; + password[i] = password[i + 1]; + password[i + 1] = tmp; + } + } +#endif // EAP_BIG_ENDIAN + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: nt_password_hash(), password_unicode"), + tmp_password_unicode.get_data(), + tmp_password_unicode.get_data_length())); + + crypto_md4_c md4(m_am_tools); + + status = md4.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md4.hash_update( + tmp_password_unicode.get_data(), + tmp_password_unicode.get_data_length()); // unicode-chars + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + password_hash->reset(); + + status = password_hash->set_buffer_length(md4.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = password_hash->set_data_length(md4.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md4.hash_final(password_hash->get_data(md4.get_digest_length()), 0); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_nt_hash_c::hash_nt_password_hash( + const eap_variable_data_c * const password_hash, + eap_variable_data_c * const password_hash_hash, + const u32_t digest_size) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (!password_hash + || !password_hash_hash) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + crypto_md4_c md4(m_am_tools); + + eap_status_e status = md4.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md4.hash_update(password_hash->get_data(digest_size), digest_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + password_hash_hash->reset(); + + status = password_hash_hash->set_buffer_length(md4.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = password_hash_hash->set_data_length(md4.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md4.hash_final(password_hash_hash->get_data(md4.get_digest_length()), 0); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: hash_nt_password_hash(), password_hash_hash"), + password_hash_hash->get_data(), + password_hash_hash->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +/* RFC 3079 */ + +static const u8_t eap_type_mschapv2_magic1[] = { + 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 }; + +EAP_FUNC_EXPORT eap_status_e crypto_nt_hash_c::get_master_key( + const eap_variable_data_c * const in_password_hash_hash, + const eap_variable_data_c * const in_nt_response, + eap_variable_data_c * const out_master_key, + const u32_t in_master_key_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::get_master_key(): this = 0x%08x\n"), + this)); + + if (in_password_hash_hash == 0 + || in_password_hash_hash->get_is_valid_data() == false + || in_nt_response == 0 + || in_nt_response->get_is_valid_data() == false + || out_master_key == 0 + || out_master_key->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + crypto_sha1_c sha1(m_am_tools); + + eap_status_e status = sha1.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + in_password_hash_hash->get_data(), + in_password_hash_hash->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + in_nt_response->get_data(), + in_nt_response->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update(eap_type_mschapv2_magic1, sizeof(eap_type_mschapv2_magic1)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c digest(m_am_tools); + if (digest.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = digest.set_buffer_length(sha1.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = digest.set_data_length(sha1.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_final( + digest.get_data(), 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = out_master_key->set_copy_of_buffer( + digest.get_data(in_master_key_length), + in_master_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +static const u8_t eap_type_mschapv2_magic2[] = { + 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, + 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, + 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, + 0x6b, 0x65, 0x79, 0x2e }; + +static const u8_t eap_type_mschapv2_magic3[] = { + 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, + 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, + 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, + 0x6b, 0x65, 0x79, 0x2e }; + + +EAP_FUNC_EXPORT eap_status_e crypto_nt_hash_c::get_asymmetric_start_key( + const eap_variable_data_c * const in_master_key, + eap_variable_data_c * const out_session_key, + const u32_t in_session_key_length, + const bool in_is_send, + const bool in_is_server) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::get_asymmetric_start_key(): this = 0x%08x\n"), + this)); + + if (in_master_key == 0 + || in_master_key->get_is_valid_data() == false + || out_session_key == 0 + || out_session_key->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + crypto_sha1_c sha1(m_am_tools); + + eap_status_e status = sha1.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = sha1.hash_update( + in_master_key->get_data(), + in_master_key->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t padding_size = 40; + + eap_variable_data_c padding(m_am_tools); + if (padding.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = padding.set_buffer_length(padding_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = padding.set_data_length(padding_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t padding1_value = 0x00; + + m_am_tools->memset(padding.get_data(), padding1_value, padding.get_data_length()); // padding1 + + status = sha1.hash_update( + padding.get_data(), + padding.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + const u8_t * magic = eap_type_mschapv2_magic2; + + if (in_is_send == in_is_server) + { + magic = eap_type_mschapv2_magic3; + } + + status = sha1.hash_update(magic, sizeof(eap_type_mschapv2_magic2)); // magic2 and magic3 are both 84 bytes + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + const u32_t padding2_value = 0xf2; + + m_am_tools->memset(padding.get_data(), padding2_value, padding.get_data_length()); // padding2 + + status = sha1.hash_update( + padding.get_data(), + padding.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c digest(m_am_tools); + if (digest.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = digest.set_buffer_length(sha1.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = digest.set_data_length(sha1.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_final(digest.get_data(), 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = out_session_key->set_copy_of_buffer(digest.get_data(in_session_key_length), in_session_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_nt_hash_c::get_new_key_from_sha( + const eap_variable_data_c * const in_start_key, + const eap_variable_data_c * const in_session_key, + eap_variable_data_c * const out_interim_key, + const u32_t in_interim_key_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::get_new_key_from_sha(): this = 0x%08x\n"), + this)); + + if (in_start_key == 0 + || in_start_key->get_is_valid_data() == false + || in_session_key == 0 + || in_session_key->get_is_valid_data() == false + || out_interim_key == 0 + || out_interim_key->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + crypto_sha1_c sha1(m_am_tools); + + eap_status_e status = sha1.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = sha1.hash_update( + in_start_key->get_data(), + in_start_key->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t padding_size = 40; + + eap_variable_data_c padding(m_am_tools); + if (padding.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = padding.set_buffer_length(padding_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = padding.set_data_length(padding_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + const u32_t padding1_value = 0x00; + + m_am_tools->memset(padding.get_data(), padding1_value, padding.get_data_length()); // padding1 + + status = sha1.hash_update( + padding.get_data(), + padding.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + in_session_key->get_data(), + in_session_key->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t padding2_value = 0xf2; + + m_am_tools->memset(padding.get_data(), padding2_value, padding.get_data_length()); // padding2 + + status = sha1.hash_update( + padding.get_data(), + padding.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c digest(m_am_tools); + if (digest.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = digest.set_buffer_length(sha1.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = digest.set_data_length(sha1.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_final(digest.get_data(), 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = out_interim_key->set_copy_of_buffer(digest.get_data(in_interim_key_length), in_interim_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +void crypto_kd_hmac_sha256_c::set_is_invalid() +{ + m_is_valid = false; +} + +//-------------------------------------------------- + +void crypto_kd_hmac_sha256_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_kd_hmac_sha256_c::~crypto_kd_hmac_sha256_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT crypto_kd_hmac_sha256_c::crypto_kd_hmac_sha256_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_is_valid(false) +{ + set_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool crypto_kd_hmac_sha256_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e crypto_kd_hmac_sha256_c::expand_key( + eap_variable_data_c * const output, + const u32_t required_output_size, + const eap_variable_data_c * const key, + const eap_variable_data_c * const label + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("crypto_kd_hmac_sha256_c::expand_key()\n"))); + + output->reset(); + + crypto_sha_256_c sha_256(m_am_tools); + if (sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + crypto_hmac_c hmac_sha_256( + m_am_tools, + &sha_256, + false); + if (hmac_sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("crypto_kd_hmac_sha256_c::expand_key(): key"), + key->get_data(), + key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("crypto_kd_hmac_sha256_c::expand_key(): label"), + label->get_data(), + label->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("crypto_kd_hmac_sha256_c::expand_key(): required_output_size %d\n"), + required_output_size)); + + const u32_t prf_digest_size(hmac_sha_256.get_digest_length()); + const u32_t iterations((required_output_size + prf_digest_size - 1) / prf_digest_size); + + eap_status_e status = output->set_buffer_length(iterations * prf_digest_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = output->set_data_length(iterations * prf_digest_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c input(m_am_tools); + if (input.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = input.set_buffer(label); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + for (u32_t ind = 0ul; ind != iterations; ++ind) + { + status = hmac_sha_256.hmac_set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_sha_256.hmac_update( + input.get_data(), + input.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t md_length(prf_digest_size); + + status = hmac_sha_256.hmac_final( + output->get_data_offset(ind*prf_digest_size, prf_digest_size), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = input.set_buffer( + output->get_data_offset(ind*prf_digest_size, prf_digest_size), + md_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + + status = output->set_data_length(required_output_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("crypto_kd_hmac_sha256_c::expand_key(): output"), + output->get_data(), + output->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_expanded_type.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_expanded_type.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,733 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 23 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_expanded_type.h" +#include "eap_header.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_expanded_type_c::~eap_expanded_type_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_expanded_type_c::eap_expanded_type_c() +{ + m_vendor_id = eap_type_vendor_id_ietf; + m_vendor_type = static_cast(eap_type_none); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_expanded_type_c::eap_expanded_type_c( + const eap_type_vendor_id_e vendor_id, + const u32_t vendor_type) +{ + m_vendor_id = vendor_id; + m_vendor_type = vendor_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_expanded_type_c::eap_expanded_type_c( + const eap_type_ietf_values_e type) +{ + m_vendor_id = eap_type_vendor_id_ietf; + m_vendor_type = static_cast(type); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_expanded_type_c::is_expanded_type(const eap_type_ietf_values_e eap_type) +{ + return (eap_type == eap_type_expanded_type); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_EXPANDED_TYPES) +EAP_FUNC_EXPORT bool eap_expanded_type_c::is_ietf_type(const eap_expanded_type_c eap_type) +{ + return (eap_type.get_vendor_id() == eap_type_vendor_id_ietf + && eap_type.get_vendor_type() < eap_type_expanded_type); +} + +#else +EAP_FUNC_EXPORT bool eap_expanded_type_c::is_ietf_type(const eap_type_ietf_values_e eap_type) +{ + return (eap_type < eap_type_expanded_type); +} + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_expanded_type_c::get_type_data( + abs_eap_am_tools_c * const am_tools, + eap_type_ietf_values_e * const type) +{ + if (type == 0) + { + EAP_UNREFERENCED_PARAMETER(am_tools); + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + + if (m_vendor_type < eap_type_expanded_type + && m_vendor_id == eap_type_vendor_id_ietf) + { + *type = static_cast(m_vendor_type); + } + else + { + // This is EAP type of other vendor than IETF. + // This cannot be denoted in eap_type_ietf_values_e. + *type = static_cast(m_vendor_type); + } + + return EAP_STATUS_RETURN(am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_expanded_type_c::get_type_data( + abs_eap_am_tools_c * const am_tools, + eap_expanded_type_c * const type) +{ + if (type == 0) + { + EAP_UNREFERENCED_PARAMETER(am_tools); + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + + *type = *this; + + return EAP_STATUS_RETURN(am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_expanded_type_c::get_expanded_type_data( + abs_eap_am_tools_c * const am_tools, + eap_variable_data_c * const data) +{ + if (data == 0) + { + EAP_UNREFERENCED_PARAMETER(am_tools); + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = data->reset(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(am_tools, status); + } + + status = data->set_buffer_length(get_eap_expanded_type_size()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(am_tools, status); + } + + status = data->set_data_length(get_eap_expanded_type_size()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(am_tools, status); + } + + u32_t offset = 0ul; + + { + u8_t * const ietf_type = static_cast(data->get_data_offset(offset, m_ietf_type_size)); + if (ietf_type == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + offset += m_ietf_type_size; + + *ietf_type = static_cast(eap_type_expanded_type); + } + + { + u8_t * const vendor_id = data->get_data_offset(offset, m_vendor_id_size); + if (vendor_id == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + offset += m_vendor_id_size; + + status = eap_write_u24_t_network_order( + vendor_id, + m_vendor_id_size, + m_vendor_id); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(am_tools, status); + } + } + + { + u8_t * const vendor_type = data->get_data_offset(offset, m_vendor_type_size); + if (vendor_type == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + offset += m_vendor_type_size; + + status = eap_write_u32_t_network_order( + vendor_type, + m_vendor_type_size, + m_vendor_type); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(am_tools, status); + } + } + + return EAP_STATUS_RETURN(am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_expanded_type_c::set_expanded_type_data( + abs_eap_am_tools_c * const am_tools, + const eap_variable_data_c * const data) +{ + if (data->get_data_length() != get_eap_expanded_type_size() + || data->get_data(data->get_data_length()) == 0) + { + EAP_UNREFERENCED_PARAMETER(am_tools); + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + + u32_t offset = 0ul; + + { + u8_t * const ietf_type = static_cast(data->get_data_offset(offset, m_ietf_type_size)); + if (ietf_type == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + offset += m_ietf_type_size; + + if (static_cast(*ietf_type) != eap_type_expanded_type) + { + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + } + + { + u8_t * const vendor_id = data->get_data_offset(offset, m_vendor_id_size); + if (vendor_id == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + offset += m_vendor_id_size; + + m_vendor_id = static_cast(eap_read_u24_t_network_order(vendor_id, m_vendor_id_size)); + } + + { + u8_t * const vendor_type = data->get_data_offset(offset, m_vendor_type_size); + if (vendor_type == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + offset += m_vendor_type_size; + + m_vendor_type = eap_read_u32_t_network_order(vendor_type, m_vendor_type_size); + } + + return EAP_STATUS_RETURN(am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_expanded_type_c::set_eap_type_values( + const eap_type_vendor_id_e vendor_id, + const u32_t vendor_type) +{ + m_vendor_id = vendor_id; + m_vendor_type = vendor_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_vendor_id_e eap_expanded_type_c::get_vendor_id() const +{ + return m_vendor_id; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_expanded_type_c::get_vendor_type() const +{ + return m_vendor_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_expanded_type_c::get_eap_expanded_type_size() +{ + return m_eap_expanded_type_size; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_expanded_type_c::operator == (const eap_type_ietf_values_e right_type_value) const +{ + if (m_vendor_id != eap_type_vendor_id_ietf) + { + return false; + } + else if (m_vendor_type != static_cast(right_type_value)) + { + return false; + } + else + { + return true; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_expanded_type_c::operator != (const eap_type_ietf_values_e right_type_value) const +{ + return !(*this == right_type_value); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_expanded_type_c::operator == (const eap_expanded_type_c &right_type_value) const +{ + if (m_vendor_id != right_type_value.get_vendor_id()) + { + return false; + } + else if (m_vendor_type != right_type_value.get_vendor_type()) + { + return false; + } + else + { + return true; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_expanded_type_c::operator != (const eap_expanded_type_c &right_type_value) const +{ + return !(*this == right_type_value); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_expanded_type_c &eap_expanded_type_c::operator = (const eap_type_ietf_values_e right_type_value) +{ + m_vendor_id = eap_type_vendor_id_ietf; ///< Here we use only 24 least significant bits. + m_vendor_type = static_cast(right_type_value); + + return *this; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_expanded_type_c &eap_expanded_type_c::operator = (const eap_expanded_type_c &right_type_value) +{ + m_vendor_id = right_type_value.get_vendor_id(); ///< Here we use only 24 least significant bits. + m_vendor_type = right_type_value.get_vendor_type(); + + return *this; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_expanded_type_c *eap_expanded_type_c::operator & () +{ + return this; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_expanded_type_c *eap_expanded_type_c::operator & () const +{ + return this; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_expanded_type_c::read_type( + abs_eap_am_tools_c * const am_tools, + const u32_t index, + const void * const p_buffer, + const u32_t buffer_length, +#if defined(USE_EAP_EXPANDED_TYPES) + eap_expanded_type_c * const type +#else + eap_type_ietf_values_e * const type +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + ) +{ + if (p_buffer == 0) + { + EAP_UNREFERENCED_PARAMETER(am_tools); + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + + const u8_t * const buffer = static_cast(p_buffer); + + if (buffer_length >= eap_expanded_type_c::m_ietf_type_size) + { + const u8_t * const type_data = buffer; + if (type_data != 0) + { + eap_type_ietf_values_e ietf_eap_type = static_cast(*type_data); + + if (ietf_eap_type < eap_type_expanded_type + && buffer_length >= eap_expanded_type_c::m_ietf_type_size*(index+1)) + { + if (index > 0ul) + { + const u8_t * const offset_type_data = + &(buffer[eap_expanded_type_c::m_ietf_type_size*index]); + if (offset_type_data != 0) + { + *type = static_cast(*offset_type_data); + return EAP_STATUS_RETURN(am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + } + else + { + *type = ietf_eap_type; + return EAP_STATUS_RETURN(am_tools, eap_status_ok); + } + } + else if (ietf_eap_type == eap_type_expanded_type + && buffer_length >= eap_header_base_c::get_expanded_type_field_length()*(index+1ul)) + { + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Type | Vendor-Id | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Vendor-Type | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Vendor data... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + eap_type_ietf_values_e ietf_eap_type(eap_type_none); + + { + const u8_t * const offset_type_data = + &(buffer[eap_header_base_c::get_expanded_ietf_type_offset() + +eap_header_base_c::get_expanded_type_field_length()*index]); + if (offset_type_data != 0) + { + ietf_eap_type = static_cast(*offset_type_data); + } + else + { + EAP_UNREFERENCED_PARAMETER(ietf_eap_type); + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + } + + eap_type_vendor_id_e vendor_id_value = eap_type_vendor_id_ietf; + + { + const u8_t * const vendor_id = + &(buffer[eap_header_base_c::get_expanded_vendor_id_offset() + +eap_header_base_c::get_expanded_type_field_length()*index]); + if (vendor_id == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + + vendor_id_value = static_cast( + eap_read_u24_t_network_order( + vendor_id, + 3ul*sizeof(u8_t))); + } + + u32_t vendor_type_value = 0ul; + + { + const u8_t * const vendor_type = + &(buffer[eap_header_base_c::get_expanded_vendor_type_offset() + +eap_header_base_c::get_expanded_type_field_length()*index]); + if (vendor_type == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + + vendor_type_value = eap_read_u32_t_network_order( + vendor_type, + sizeof(u32_t)); + } + +#if defined(USE_EAP_EXPANDED_TYPES) + type->set_eap_type_values( + vendor_id_value, + vendor_type_value); + + EAP_ASSERT_TOOLS(am_tools, (ietf_eap_type == eap_type_expanded_type)); +#else + if (vendor_id_value == eap_type_vendor_id_ietf) + { + *type = static_cast(vendor_type_value); // Type field follows eap_header_c. + } + else + { + *type = ietf_eap_type; // Type field follows eap_header_c. + } +#endif + + return EAP_STATUS_RETURN(am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + } + else + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + } + else + { + // NOTE, Every EAP-packet does not include EAP-type field. + return EAP_STATUS_RETURN(am_tools, eap_status_ok); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_expanded_type_c::write_type( + abs_eap_am_tools_c * const am_tools, + const u32_t index, + void * const p_buffer, + const u32_t buffer_length, + const bool write_extented_type_when_true, +#if defined(USE_EAP_EXPANDED_TYPES) + const eap_expanded_type_c p_type ///< The EAP type to be written. +#else + const eap_type_ietf_values_e p_type ///< The EAP type to be written. +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + ) +{ + if (p_buffer == 0) + { + EAP_UNREFERENCED_PARAMETER(am_tools); + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + + u8_t * const buffer = static_cast(p_buffer); + +#if defined(USE_EAP_EXPANDED_TYPES) + + if (write_extented_type_when_true == false + && is_ietf_type(p_type) == true + && buffer_length >= eap_expanded_type_c::m_ietf_type_size*(index+1ul)) + { + u8_t * const type_data = + &(buffer[eap_expanded_type_c::m_ietf_type_size*index]); + if (type_data == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + + *type_data = static_cast(p_type.get_vendor_type()); + } + else if ((write_extented_type_when_true == true + || is_ietf_type(p_type) == false) + && buffer_length >= eap_header_base_c::get_expanded_type_field_length()*(index+1ul)) + { + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Type | Vendor-Id | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Vendor-Type | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Vendor data or other Type ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + { + u8_t * const type_data = + &(buffer[eap_header_base_c::get_expanded_ietf_type_offset() + +eap_header_base_c::get_expanded_type_field_length()*index]); + if (type_data == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + *type_data = static_cast(eap_type_expanded_type); + } + + { + u8_t * const vendor_id = + &(buffer[eap_header_base_c::get_expanded_vendor_id_offset() + +eap_header_base_c::get_expanded_type_field_length()*index]); + if (vendor_id == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + eap_status_e status = eap_write_u24_t_network_order( + vendor_id, + 3ul*sizeof(u8_t), + static_cast(p_type.get_vendor_id())); + EAP_ASSERT_ALWAYS_TOOLS(am_tools, status == eap_status_ok); + } + + { + u8_t * const vendor_type = + &(buffer[eap_header_base_c::get_expanded_vendor_type_offset() + +eap_header_base_c::get_expanded_type_field_length()*index]); + if (vendor_type == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + eap_status_e status = eap_write_u32_t_network_order( + vendor_type, + sizeof(u32_t), + p_type.get_vendor_type()); + EAP_ASSERT_ALWAYS_TOOLS(am_tools, status == eap_status_ok); + } + } + else + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + +#else + + EAP_UNREFERENCED_PARAMETER(write_extented_type_when_true); // Only Expanded Type version uses this. + + if (buffer_length >= eap_expanded_type_c::m_ietf_type_size*(index+1ul)) + { + u8_t * const type_data = + &(buffer[eap_expanded_type_c::m_ietf_type_size*index]); + if (type_data == 0) + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + *type_data = static_cast(p_type); + } + else + { + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + return EAP_STATUS_RETURN(am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_EXPANDED_TYPES) + +EAP_FUNC_EXPORT i32_t eap_expanded_type_c::compare(const eap_expanded_type_c * const data) const +{ + if (*this == *data) + { + return 0; + } + else + { + if (get_vendor_id() < data->get_vendor_id() + || (get_vendor_id() == data->get_vendor_id() + && get_vendor_type() < data->get_vendor_type())) + { + // (*this < *data) + return -1; + } + else + { + // (*this > *data) + return +1; + } + } +} + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_expanded_type_c &eap_static_expanded_type_c::get_type() const +{ + return *reinterpret_cast(this); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +#if defined(USE_EAP_EXPANDED_TYPES) + +EAP_C_FUNC_EXPORT u32_t convert_eap_type_to_u32_t(eap_type_value_e type) +{ + // NOTE, this returns only 8 least significant bits of vendor type. + return static_cast(type.get_vendor_id() << sizeof(u8_t)*8ul + | (0xff & type.get_vendor_type())); +} + +EAP_C_FUNC_EXPORT u64_t convert_eap_type_to_u64_t(eap_type_value_e type) +{ + return static_cast(type.get_vendor_id()) << sizeof(u32_t)*8ul + | static_cast(type.get_vendor_type()); +} + +#else + +EAP_C_FUNC_EXPORT u32_t convert_eap_type_to_u32_t(eap_type_value_e type) +{ + return static_cast(type); +} + +EAP_C_FUNC_EXPORT u64_t convert_eap_type_to_u64_t(eap_type_value_e type) +{ + return static_cast(type); +} + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_general_header_base.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_general_header_base.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 24 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_general_header_base.h" + + +// +EAP_FUNC_EXPORT eap_general_header_base_c::~eap_general_header_base_c() +{ + // NOTE do not delete these attributes. These are references to objects owned by other objects. + m_header_buffer = 0; + m_header_buffer_length = 0ul; +} + +// +EAP_FUNC_EXPORT eap_general_header_base_c::eap_general_header_base_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length) + : m_am_tools(tools) + , m_header_buffer(static_cast(header_buffer)) + , m_header_buffer_length(header_buffer_length) +#if defined(USE_EAP_ERROR_TESTS) + , m_error_detected(true) +#endif //#if defined(USE_EAP_ERROR_TESTS) +{ + EAP_ASSERT((m_header_buffer != 0 && m_header_buffer_length > 0ul) || (m_header_buffer == 0 && m_header_buffer_length == 0ul)); +} + +EAP_FUNC_EXPORT void eap_general_header_base_c::set_header_buffer(u8_t * const header_buffer, const u32_t header_buffer_length) +{ + m_header_buffer = header_buffer; + m_header_buffer_length = header_buffer_length; +} + +EAP_FUNC_EXPORT u8_t * eap_general_header_base_c::get_header_buffer(const u32_t data_length) const +{ + EAP_ASSERT(m_header_buffer != 0 && m_header_buffer_length > 0ul && m_header_buffer_length >= data_length); + + if (m_header_buffer_length >= data_length) + { + return m_header_buffer; + } + return 0; +} + +EAP_FUNC_EXPORT u32_t eap_general_header_base_c::get_header_buffer_length() const +{ + return m_header_buffer_length; +} + +EAP_FUNC_EXPORT u8_t * eap_general_header_base_c::get_header_offset( + const u32_t offset, + const u32_t data_length) const +{ + if (get_header_buffer_length() >= offset+data_length) + { + return get_header_buffer(offset+data_length)+offset; + } + else + { + //NOTE: Cannot assert here because illagal message will always fail. EAP_ASSERT(get_header_buffer_length() >= offset+data_length); + return 0; + } +} + +EAP_FUNC_EXPORT bool eap_general_header_base_c::get_is_valid() const +{ + if (get_header_buffer_length() == 0 + || get_header_buffer(get_header_buffer_length()) == 0) + { + return false; + } + return true; +} + +EAP_FUNC_EXPORT abs_eap_am_tools_c * eap_general_header_base_c::get_am_tools() const +{ + return m_am_tools; +} + + +#if defined(USE_EAP_ERROR_TESTS) + +EAP_FUNC_EXPORT void eap_general_header_base_c::set_error_detected(const bool error_detected) +{ + m_error_detected = error_detected; +} + +EAP_FUNC_EXPORT bool eap_general_header_base_c::get_error_detected() +{ + return m_error_detected; +} + +#endif //#if defined(USE_EAP_ERROR_TESTS) + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_handle.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_handle.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 25 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#error Do not use this anymore + +#include "eap_handle.h" + + +EAP_FUNC_EXPORT eap_handle_c::~eap_handle_c() +{ +} + +EAP_FUNC_EXPORT eap_handle_c::eap_handle_c( + abs_eap_am_tools_c * const tools) + : eap_variable_data_c(tools) + , m_send_network_id(tools) + , m_eap_type(eap_type_none) +{ +} + +EAP_FUNC_EXPORT eap_handle_c::eap_handle_c( + abs_eap_am_tools_c * const tools, + eap_variable_data_c * const selector, + const eap_am_network_id_c * const network_id, + const eap_type_value_e p_eap_type) + : eap_variable_data_c(tools) + , m_send_network_id(tools, network_id) + , m_eap_type(p_eap_type) +{ + eap_status_e status = set_copy_of_buffer(selector); + if (status != eap_status_ok) + { + return; + } + + set_is_valid(); +} + +EAP_FUNC_EXPORT eap_status_e eap_handle_c::set_handle( + eap_variable_data_c * const selector, + const eap_am_network_id_c * const network_id, + const eap_type_value_e p_eap_type) +{ + eap_status_e status = eap_status_process_general_error; + + if (selector != 0) + { + status = set_copy_of_buffer(selector); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (network_id != 0) + { + status = m_send_network_id.set_copy_of_network_id(network_id); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + m_eap_type = (p_eap_type); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_am_network_id_c * eap_handle_c::get_send_network_id() const +{ + return &m_send_network_id; +} + +EAP_FUNC_EXPORT eap_type_value_e eap_handle_c::get_eap_type() const +{ + return m_eap_type; +} + +EAP_FUNC_EXPORT void eap_handle_c::reset() +{ + eap_variable_data_c::reset(); + m_send_network_id.reset(); + m_eap_type = eap_type_none; +} + + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,487 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 26 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_header.h" +#include "eap_header_string.h" + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_header_base_c::~eap_header_base_c() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_header_base_c::eap_header_base_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) +{ + EAP_ASSERT(sizeof(eap_expanded_type_c) == sizeof(eap_static_expanded_type_c)); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_header_base_c::get_header_length() +{ + return m_type_offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_header_base_c::get_ietf_type_field_length() +{ + return eap_expanded_type_c::m_ietf_type_size; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_header_base_c::get_expanded_type_field_length() +{ + return eap_expanded_type_c::m_eap_expanded_type_size; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_header_base_c::get_expanded_ietf_type_offset() +{ + return m_exp_ietf_type_offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_header_base_c::get_expanded_vendor_id_offset() +{ + return m_exp_vendor_id_offset; +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_header_base_c::get_expanded_vendor_type_offset() +{ + return m_exp_vendor_type_offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_header_base_c::get_type_data_start_offset( + const bool expanded_type_when_true) +{ + u32_t type_field_length(get_ietf_type_field_length()); + + if (expanded_type_when_true == true) + { + type_field_length = get_expanded_type_field_length(); + } + + return get_header_length() + type_field_length; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_code_value_e eap_header_base_c::get_code() const +{ + const u8_t * const code_data = get_header_offset(m_code_offset, sizeof(u8_t)); + if (code_data != 0) + { + return static_cast(*code_data); + } + else + { + return eap_code_none; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t eap_header_base_c::get_identifier() const +{ + const u8_t * const identifier_data = get_header_offset(m_identifier_offset, sizeof(u8_t)); + if (identifier_data != 0) + { + return *identifier_data; + } + else + { + return 0xff; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u16_t eap_header_base_c::get_length() const +{ + const u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u16_t)); + if (length_data != 0) + { + return static_cast(static_cast(length_data[0]) << 8 + | static_cast(length_data[1])); + } + else + { + return 0ul; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_ietf_values_e eap_header_base_c::get_ietf_type() const +{ + const u8_t * const ietf_type_field = get_data(eap_expanded_type_c::m_ietf_type_size); + if (ietf_type_field == 0) + { + return eap_type_none; + } + else + { + return static_cast(*ietf_type_field); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_value_e eap_header_base_c::get_type() const +{ + eap_type_value_e type(eap_type_none); + + if (get_length() > static_cast(get_header_length())) + { + eap_status_e status = eap_expanded_type_c::read_type( + m_am_tools, + 0ul, + get_data(get_data_length()), + get_data_length(), + &type); + + EAP_UNREFERENCED_PARAMETER(status); + (void)EAP_STATUS_RETURN(m_am_tools, status); + } + + return type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u16_t eap_header_base_c::get_data_length() const +{ + if (get_length() > static_cast(get_header_length())) + { + return static_cast(get_length()-get_header_length()); + } + return 0u; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_header_base_c::get_type_field_length() const +{ + eap_type_ietf_values_e p_type = get_ietf_type(); + + if (eap_expanded_type_c::is_expanded_type(p_type) == true) + { + return eap_expanded_type_c::m_eap_expanded_type_size; + } + else + { + return eap_expanded_type_c::m_ietf_type_size; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u16_t eap_header_base_c::get_type_data_length() const +{ + u32_t type_field_length(get_type_field_length()); + + if (get_length() > static_cast(get_header_length()+type_field_length)) + { + return static_cast(get_length()-(get_header_length()+type_field_length)); + } + return 0u; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_header_base_c::get_data_offset( + const u32_t p_offset, const u32_t p_continuous_bytes) const +{ + if (get_length() >= static_cast(get_header_length()+p_offset+p_continuous_bytes)) + { + u8_t * const data_begin = get_header_offset(m_type_offset, sizeof(u8_t)); + if (data_begin == 0) + { + return 0; + } + return &(data_begin[p_offset]); + } + else + { + return 0; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_header_base_c::get_type_data_offset( + const u32_t p_offset, const u32_t p_continuous_bytes) const +{ + u32_t type_field_length(get_type_field_length()); + + u32_t type_data_offset = get_header_length()+type_field_length; + + if (get_length() >= static_cast(type_data_offset+p_offset+p_continuous_bytes)) + { + u8_t * const data_begin = get_header_offset(type_data_offset, sizeof(u8_t)); + if (data_begin == 0) + { + return 0; + } + return &(data_begin[p_offset]); + } + else + { + return 0; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_header_base_c::get_type_data( + const u32_t p_continuous_bytes) const +{ + return get_type_data_offset(0u, p_continuous_bytes); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_header_base_c::get_data( + const u32_t p_continuous_bytes) const +{ + return get_data_offset(0u, p_continuous_bytes); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_header_base_c::set_code(const eap_code_value_e p_code) +{ + u8_t * const code_data = get_header_offset(m_code_offset, sizeof(u8_t)); + EAP_ASSERT(code_data != 0); + *code_data = static_cast(p_code); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_header_base_c::set_identifier(const u8_t p_identifier) +{ + u8_t * const identifier_data = get_header_offset(m_identifier_offset, sizeof(u8_t)); + EAP_ASSERT(identifier_data != 0); + *identifier_data = p_identifier; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_header_base_c::set_length( + const u16_t p_length, + const bool /* expanded_type_when_true */) +{ + u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u16_t)); + EAP_ASSERT(length_data != 0); + length_data[0] = static_cast((p_length & 0xff00) >> 8); + length_data[1] = static_cast(p_length & 0x00ff); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_header_base_c::set_type_data_length( + const u16_t p_length, + const bool expanded_type_when_true) +{ + u32_t type_field_length(eap_expanded_type_c::m_ietf_type_size); + + if (expanded_type_when_true == true) + { + type_field_length = eap_expanded_type_c::m_eap_expanded_type_size; + } + + set_length( + static_cast(p_length+get_header_length()+type_field_length), + expanded_type_when_true); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_header_base_c::set_type( + const eap_type_value_e p_type, + const bool expanded_type_when_true) +{ + return eap_expanded_type_c::write_type( + m_am_tools, + 0ul, + get_data(get_data_length()), + get_data_length(), + expanded_type_when_true, + p_type); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_header_base_c::get_code_string() const +{ + return eap_header_string_c::get_eap_code_string(get_code()); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_header_base_c::get_type_string() const +{ + if (get_length() <= get_header_length()) + { + return EAPL("No EAP-type"); + } + + return eap_header_string_c::get_eap_type_string(get_type()); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_header_base_c::check_header() const +{ + eap_status_e status = eap_status_process_general_error; + + if (get_code() < eap_code_request + || eap_code_failure < get_code()) + { + status = eap_status_illegal_eap_code; + + EAP_TRACE_DEBUG( + get_am_tools(), + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_header_c::check_header(), illegal code field 0x%02x, eap_status_e %d\n"), + get_code(), + status)); + } + else if ((get_code() == eap_code_request + || get_code() == eap_code_response) + && get_length() < get_header_length() + sizeof(u8_t)) + { + // Packet is too short. + status = eap_status_too_short_message; + + EAP_TRACE_DEBUG( + get_am_tools(), + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_header_c::check_header(), code 0x%02x, illegal length field 0x%02x, eap_status_e %d\n"), + get_code(), + get_length(), + status)); + } + else + { + status = eap_status_ok; + } + + return EAP_STATUS_RETURN_WARNING(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_header_rd_c::~eap_header_rd_c() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_header_rd_c::eap_header_rd_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length) + : eap_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_header_wr_c::~eap_header_wr_c() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_header_wr_c::eap_header_wr_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length) + : eap_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_header_wr_c::get_type_data(const u32_t p_continuous_bytes) const +{ + return const_cast(eap_header_base_c::get_type_data(p_continuous_bytes)); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_header_wr_c::get_type_data_offset( + const u32_t p_offset, + const u32_t p_continuous_bytes) const +{ + return const_cast(eap_header_base_c::get_type_data_offset( + p_offset, p_continuous_bytes)); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_header_wr_c::reset_header( + const u16_t buffer_length, + const bool expanded_type_when_true) +{ + set_code(eap_code_none); + set_identifier(0u); + set_length(buffer_length, expanded_type_when_true); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_header_string.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_header_string.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,98 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 27 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +/** @file */ + +#include "eap_tools.h" +#include "eap_header_string.h" + +//------------------------------------------------------------------------------ + +EAP_FUNC_EXPORT eap_header_string_c::~eap_header_string_c() +{ +} + +EAP_FUNC_EXPORT eap_header_string_c::eap_header_string_c() +{ +} + +EAP_FUNC_EXPORT eap_const_string eap_header_string_c::get_eap_code_string(const eap_code_value_e code) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(code, eap_code_none) + else EAP_IF_RETURN_STRING(code, eap_code_request) + else EAP_IF_RETURN_STRING(code, eap_code_response) + else EAP_IF_RETURN_STRING(code, eap_code_success) + else EAP_IF_RETURN_STRING(code, eap_code_failure) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(code); + return EAPL("Unknown EAP-code"); + } +} + +EAP_FUNC_EXPORT eap_const_string eap_header_string_c::get_eap_type_string(const eap_type_value_e type) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(type, eap_type_none) + else EAP_IF_RETURN_STRING(type, eap_type_identity) + else EAP_IF_RETURN_STRING(type, eap_type_notification) + else EAP_IF_RETURN_STRING(type, eap_type_nak) + else EAP_IF_RETURN_STRING(type, eap_type_md5_challenge) + else EAP_IF_RETURN_STRING(type, eap_type_one_time_password) + else EAP_IF_RETURN_STRING(type, eap_type_generic_token_card) + else EAP_IF_RETURN_STRING(type, eap_type_tls) + else EAP_IF_RETURN_STRING(type, eap_type_leap) + else EAP_IF_RETURN_STRING(type, eap_type_gsmsim) + else EAP_IF_RETURN_STRING(type, eap_type_ttls) + else EAP_IF_RETURN_STRING(type, eap_type_aka) + else EAP_IF_RETURN_STRING(type, eap_type_peap) + else EAP_IF_RETURN_STRING(type, eap_type_mschapv2) + else EAP_IF_RETURN_STRING(type, eap_type_securid) + else EAP_IF_RETURN_STRING(type, eap_type_tlv_extensions) +#if defined(USE_FAST_EAP_TYPE) + else EAP_IF_RETURN_STRING(type, eap_type_fast) +#endif //#if defined(USE_FAST_EAP_TYPE) + else EAP_IF_RETURN_STRING(type, eap_type_saesim) +#if defined(USE_EAP_EXPANDED_TYPES) + else EAP_IF_RETURN_STRING(type, eap_expanded_type_simple_config.get_type()) +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(type); + return EAPL("Unknown EAP-type"); + } +} + +//------------------------------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_master_session_key.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_master_session_key.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,93 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 28 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_master_session_key.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_master_session_key_c::~eap_master_session_key_c() +{ +} + +EAP_FUNC_EXPORT eap_master_session_key_c::eap_master_session_key_c( + abs_eap_am_tools_c * const tools, + const eap_type_value_e eap_type) + : eap_variable_data_c(tools) + , m_am_tools(tools) + , m_leap_password(tools) + , m_eap_type(eap_type) +{ +} + +EAP_FUNC_EXPORT eap_type_value_e eap_master_session_key_c::get_eap_type() const +{ + return m_eap_type; +} + +EAP_FUNC_EXPORT void eap_master_session_key_c::set_eap_type(eap_type_value_e type) +{ + m_eap_type = type; +} + +EAP_FUNC_EXPORT eap_status_e eap_master_session_key_c::copy_leap_password(const eap_variable_data_c * const key) +{ + return m_leap_password.set_copy_of_buffer(key); +} + +EAP_FUNC_EXPORT const eap_variable_data_c * eap_master_session_key_c::get_leap_password() const +{ + return &m_leap_password; +} + +EAP_FUNC_EXPORT eap_status_e eap_master_session_key_c::set_copy(const eap_master_session_key_c * const msk) +{ + eap_status_e status = eap_variable_data_c::set_copy_of_buffer(msk); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (msk->get_leap_password()->get_is_valid_data() == true) + { + status = m_leap_password.set_copy_of_buffer(msk->get_leap_password()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + m_eap_type = msk->get_eap_type(); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_memory_store_variable_data.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_memory_store_variable_data.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 29 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "eap_memory_store_variable_data.h" + + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_network_id_selector.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_network_id_selector.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,135 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 30 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_variable_data.h" +#include "eap_network_id_selector.h" + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_network_id_selector_c::~eap_network_id_selector_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_network_id_selector_c::eap_network_id_selector_c( + abs_eap_am_tools_c * const tools) + : eap_variable_data_c(tools) + , m_am_tools(tools) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_network_id_selector_c::eap_network_id_selector_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const network_id) + : eap_variable_data_c(tools) + , m_am_tools(tools) +{ + if (eap_variable_data_c::get_is_valid() == false) + { + return; + } + + eap_status_e status = set_selector(network_id); + if (status != eap_status_ok) + { + return; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_network_id_selector_c::set_selector( + const eap_am_network_id_c * const network_id) +{ + eap_status_e status = eap_status_process_general_error; + + if (network_id == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Pre-allocates buffer for ID. + status = set_buffer_length(network_id->get_source_id()->get_data_length() + network_id->get_destination_id()->get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_copy_of_buffer(network_id->get_source_id()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_data(network_id->get_destination_id()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_network_id_selector_c::eap_network_id_selector_c( + abs_eap_am_tools_c * const tools, + const eap_network_id_selector_c * const selector) + : eap_variable_data_c(tools) + , m_am_tools(tools) +{ + eap_status_e status = set_copy_of_buffer( + selector->get_data(selector->get_data_length()), + selector->get_data_length()); + if (status != eap_status_ok) + { + return; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_network_id_selector_c * eap_network_id_selector_c::copy() const +{ + eap_network_id_selector_c * const new_selector + = new eap_network_id_selector_c(m_am_tools, this); + + return new_selector; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_rogue_ap_entry.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_rogue_ap_entry.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,104 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 35 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "eap_am_memory.h" +#include "eap_rogue_ap_entry.h" + +EAP_FUNC_EXPORT eap_rogue_ap_entry_c::~eap_rogue_ap_entry_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_rogue_ap_entry_c::eap_rogue_ap_entry_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_rogue_ap_reason(rogue_ap_none) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_rogue_ap_entry_c * eap_rogue_ap_entry_c::copy() const +{ + eap_rogue_ap_entry_c * const new_object = new eap_rogue_ap_entry_c(m_am_tools); + + if (new_object != 0) + { + new_object->set_mac_address(get_mac_address()); + new_object->set_rogue_reason(get_rogue_reason()); + } + + return new_object; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_rogue_ap_entry_c::get_mac_address() const +{ + return const_cast(m_rogue_ap_mac_address); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_rogue_ap_entry_c::get_mac_address(u8_t * const mac_address) const +{ + if (mac_address) + { + m_am_tools->memmove(mac_address, m_rogue_ap_mac_address, EAPOL_ETHERNET_ADDRESS_LENGTH); + } + return const_cast(m_rogue_ap_mac_address); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_rogue_ap_entry_c::set_mac_address(const u8_t * const mac_address) +{ + if (mac_address) + { + m_am_tools->memmove(m_rogue_ap_mac_address, mac_address, EAPOL_ETHERNET_ADDRESS_LENGTH); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_rogue_ap_entry_c::set_rogue_reason(const eap_rogue_ap_reason_e reason) +{ + m_rogue_ap_reason = reason; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_rogue_ap_reason_e eap_rogue_ap_entry_c::get_rogue_reason() const +{ + return m_rogue_ap_reason; +} + + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_sim_triplets.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_sim_triplets.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,348 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 36 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_sim_triplets.h" +#include "abs_eap_am_tools.h" + + +EAP_FUNC_EXPORT eap_type_saesim_triplet_c::~eap_type_saesim_triplet_c() +{ + reset(); +} + +EAP_FUNC_EXPORT eap_type_saesim_triplet_c::eap_type_saesim_triplet_c( + abs_eap_am_tools_c * const tools + ) + : m_kc(0) + , m_rand(0) + , m_sres(0) + , m_is_valid(false) +{ + m_kc = new eap_variable_data_c(tools); + m_rand = new eap_variable_data_c(tools); + m_sres = new eap_variable_data_c(tools); + + if (m_kc == 0 + || m_rand == 0 + || m_sres == 0) + { + reset(); + } + else + { + eap_status_e status = m_kc->init(SIM_KC_LENGTH); + if (status != eap_status_ok) + { + return; + } + m_kc->set_is_valid(); + + status = m_rand->init(SIM_RAND_LENGTH); + if (status != eap_status_ok) + { + return; + } + m_rand->set_is_valid(); + + status = m_sres->init(SIM_SRES_LENGTH); + if (status != eap_status_ok) + { + return; + } + m_sres->set_is_valid(); + + set_is_valid(); + } +} + +EAP_FUNC_EXPORT void eap_type_saesim_triplet_c::reset() +{ + if (m_kc) + { + delete m_kc; + m_kc = 0; + } + if (m_rand) + { + delete m_rand; + m_rand = 0; + } + if (m_sres) + { + delete m_sres; + m_sres = 0; + } +} + +EAP_FUNC_EXPORT eap_status_e eap_type_saesim_triplet_c::set_triplet( + eap_variable_data_c * const kc, + eap_variable_data_c * const rand, + eap_variable_data_c * const sres + ) +{ + reset(); + + m_kc = kc; + m_rand = rand; + m_sres = sres; + + if (m_kc == 0 + || m_rand == 0 + || m_sres == 0) + { + return eap_status_allocation_error; + } + return eap_status_ok; +} + +EAP_FUNC_EXPORT eap_type_saesim_triplet_c * eap_type_saesim_triplet_c::copy( + abs_eap_am_tools_c * const tools + ) +{ + eap_type_saesim_triplet_c * const triplet = new eap_type_saesim_triplet_c(tools); + + if (triplet != 0 + && triplet->get_is_valid() == true) + { + eap_status_e status = triplet->set_triplet( + get_kc()->copy(), + get_rand()->copy(), + get_sres()->copy()); + if (status != eap_status_ok) + { + delete triplet; + return 0; + } + } + else + { + delete triplet; + return 0; + } + + return triplet; +} + +EAP_FUNC_EXPORT void eap_type_saesim_triplet_c::set_is_valid() +{ + m_is_valid = true; +} + +EAP_FUNC_EXPORT bool eap_type_saesim_triplet_c::get_is_valid() +{ + return m_is_valid; +} + +EAP_FUNC_EXPORT eap_variable_data_c *eap_type_saesim_triplet_c::get_kc() +{ + return m_kc; +} + +EAP_FUNC_EXPORT eap_variable_data_c *eap_type_saesim_triplet_c::get_rand() +{ + return m_rand; +} + +EAP_FUNC_EXPORT eap_variable_data_c *eap_type_saesim_triplet_c::get_sres() +{ + return m_sres; +} + + + +EAP_FUNC_EXPORT eap_type_sim_triplet_array_c::~eap_type_sim_triplet_array_c() +{ + reset(); +} + +EAP_FUNC_EXPORT eap_type_sim_triplet_array_c::eap_type_sim_triplet_array_c( + abs_eap_am_tools_c * const tools + ) + : m_triplet_count(0) + , m_array(0) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT eap_status_e eap_type_sim_triplet_array_c::set_triplet_count( + const u32_t triplet_count + ) +{ + m_triplet_count = triplet_count; + + m_array = new eap_type_saesim_triplet_c *[m_triplet_count]; + + if (m_array != 0) + { + u32_t ind = 0; + + for (ind = 0; ind < m_triplet_count; ind++) + { + m_array[ind] = 0; + } + + for (ind = 0; ind < m_triplet_count; ind++) + { + m_array[ind] = new eap_type_saesim_triplet_c(m_am_tools); + if (m_array[ind] == 0) + { + return eap_status_allocation_error; + } + } + return eap_status_ok; + } + else + { + return eap_status_allocation_error; + } +} + +EAP_FUNC_EXPORT eap_type_saesim_triplet_c * eap_type_sim_triplet_array_c::add_triplet() +{ + eap_type_saesim_triplet_c **old_array = m_array; + + m_array = new eap_type_saesim_triplet_c *[m_triplet_count+1u]; + + if (m_array != 0) + { + u32_t ind; + + for (ind = 0; ind < m_triplet_count; ind++) + { + m_array[ind] = old_array[ind]; + } + + delete [] old_array; + ++m_triplet_count; + + m_array[ind] = new eap_type_saesim_triplet_c(m_am_tools); + if (m_array[ind] == 0) + { + return 0; + } + + return m_array[ind]; + } + else + { + m_array = old_array; + return 0; + } +} + +EAP_FUNC_EXPORT eap_type_saesim_triplet_c * eap_type_sim_triplet_array_c::get_triplet( + abs_eap_am_tools_c * const /* m_am_tools */, u32_t index) +{ + if (index < m_triplet_count) + { + return m_array[index]; + } + else + { + EAP_ASSERT_ALWAYS(index < m_triplet_count); + return 0; + } +} + +EAP_FUNC_EXPORT eap_status_e eap_type_sim_triplet_array_c::set_triplet(u32_t index, eap_type_saesim_triplet_c * const triplet) +{ + if (index < m_triplet_count) + { + if (m_array[index] != 0) + { + delete m_array[index]; + } + m_array[index] = triplet; + return eap_status_ok; + } + else + { + return eap_status_illegal_index; + } +} + +EAP_FUNC_EXPORT u32_t eap_type_sim_triplet_array_c::get_triplet_count() +{ + return m_triplet_count; +} + +EAP_FUNC_EXPORT eap_type_sim_triplet_array_c * eap_type_sim_triplet_array_c::copy() +{ + eap_type_sim_triplet_array_c * const new_triplets + = new eap_type_sim_triplet_array_c(m_am_tools); + if (new_triplets == 0) + { + return 0; + } + + eap_status_e status = new_triplets->set_triplet_count(get_triplet_count()); + if (status != eap_status_ok) + { + delete new_triplets; + return 0; + } + + for (u32_t ind = 0; ind < get_triplet_count(); ind++) + { + eap_status_e status = new_triplets->set_triplet( + ind, + get_triplet(m_am_tools, ind)->copy(m_am_tools)); + if (status != eap_status_ok) + { + delete new_triplets; + return 0; + } + } + + return new_triplets; +} + +EAP_FUNC_EXPORT void eap_type_sim_triplet_array_c::reset() +{ + if (m_array != 0) + { + for (u32_t ind = 0; ind < m_triplet_count; ind++) + { + delete m_array[ind]; + m_array[ind] = 0; + } + delete [] m_array; + m_array = 0; + } + + m_triplet_count = 0u; + m_am_tools = 0; +} + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_state_notification.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_state_notification.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,475 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 37 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_state_notification.h" +#include "eap_am_tools.h" +#include "eap_tools.h" +#include "eapol_key_types.h" + + +EAP_FUNC_EXPORT eap_state_notification_c::~eap_state_notification_c() +{ +} + +EAP_FUNC_EXPORT eap_state_notification_c::eap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : m_am_tools(tools) + , m_layer(layer) + , m_notification_string(tools) + , m_needs_confirmation_from_user(false) + , m_protocol(protocol) + , m_eap_type(eap_type_none) + , m_previous_state(previous_state) + , m_current_state(current_state) + , m_send_network_id(send_network_id) + , m_is_client(is_client) + , m_eap_identifier(eap_identifier) + , m_allow_send_eap_success(allow_send_eap_success) + , m_authentication_error(eap_status_ok) +{ +} + +#if defined(USE_EAP_EXPANDED_TYPES) + +EAP_FUNC_EXPORT eap_state_notification_c::eap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : m_am_tools(tools) + , m_layer(layer) + , m_notification_string(tools) + , m_needs_confirmation_from_user(false) + , m_protocol(0ul) + , m_eap_type(eap_type) + , m_previous_state(previous_state) + , m_current_state(current_state) + , m_send_network_id(send_network_id) + , m_is_client(is_client) + , m_eap_identifier(eap_identifier) + , m_allow_send_eap_success(allow_send_eap_success) + , m_authentication_error(eap_status_ok) +{ +} + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + +EAP_FUNC_EXPORT eap_state_notification_c::eap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : m_am_tools(tools) + , m_layer(layer) + , m_notification_string(tools) + , m_needs_confirmation_from_user(false) + , m_protocol(0ul) + , m_eap_type(eap_type) + , m_previous_state(previous_state) + , m_current_state(current_state) + , m_send_network_id(send_network_id) + , m_is_client(is_client) + , m_eap_identifier(eap_identifier) + , m_allow_send_eap_success(allow_send_eap_success) + , m_authentication_error(eap_status_ok) +{ +} + +EAP_FUNC_EXPORT const eap_am_network_id_c * eap_state_notification_c::get_send_network_id() const +{ + return m_send_network_id; +} + +EAP_FUNC_EXPORT eap_protocol_layer_e eap_state_notification_c::get_protocol_layer() const +{ + return m_layer; +} + +EAP_FUNC_EXPORT u32_t eap_state_notification_c::get_protocol() const +{ + return m_protocol; +} + +EAP_FUNC_EXPORT eap_type_value_e eap_state_notification_c::get_eap_type() const +{ + return m_eap_type; +} + +EAP_FUNC_EXPORT u32_t eap_state_notification_c::get_previous_state() const +{ + return m_previous_state; +} + +EAP_FUNC_EXPORT u32_t eap_state_notification_c::get_current_state() const +{ + return m_current_state; +} + +EAP_FUNC_EXPORT eap_const_string eap_state_notification_c::get_state_string(const u32_t protocol_layer, const u32_t state) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + + if (protocol_layer == eap_protocol_layer_general) + { + EAP_IF_RETURN_STRING(state, eap_general_state_none) + else EAP_IF_RETURN_STRING(state, eap_general_state_show_notification_string) + else EAP_IF_RETURN_STRING(state, eap_general_state_configuration_error) + else EAP_IF_RETURN_STRING(state, eap_general_state_authentication_cancelled) + else EAP_IF_RETURN_STRING(state, eap_general_state_authentication_error) + else EAP_IF_RETURN_STRING(state, eap_general_state_immediate_reconnect) + else EAP_IF_RETURN_STRING(state, eap_general_state_last_mark) + else + { + return EAPL("Unknown general state"); + } + } + else if (protocol_layer == eap_protocol_layer_internal_type + || protocol_layer == eap_protocol_layer_am_eap_type + || protocol_layer == eap_protocol_layer_eap_type + || protocol_layer == eap_protocol_layer_eap) + { + EAP_IF_RETURN_STRING(state, eap_state_none) + else EAP_IF_RETURN_STRING(state, eap_state_identity_request_sent) + else EAP_IF_RETURN_STRING(state, eap_state_identity_request_received) + else EAP_IF_RETURN_STRING(state, eap_state_identity_response_received) + else EAP_IF_RETURN_STRING(state, eap_state_eap_response_sent) + else EAP_IF_RETURN_STRING(state, eap_state_tppd_peapv1_authentication_finished_successfully_with_tunneled_eap_success) + else EAP_IF_RETURN_STRING(state, eap_state_authentication_finished_successfully) + else EAP_IF_RETURN_STRING(state, eap_state_authentication_terminated_unsuccessfully) + else EAP_IF_RETURN_STRING(state, eap_state_authentication_wait_tppd_peapv1_empty_acknowledge) + else EAP_IF_RETURN_STRING(state, eap_state_use_eap_failure_in_termination) + else EAP_IF_RETURN_STRING(state, eap_state_inner_eap_method_skipped) + else EAP_IF_RETURN_STRING(state, eap_state_authentication_wait_eap_fast_empty_acknowledge) + else EAP_IF_RETURN_STRING(state, eap_state_wait_plain_eap_success) + else + { + return EAPL("Unknown EAP state"); + } + } + else if (protocol_layer == eap_protocol_layer_eapol) + { + EAP_IF_RETURN_STRING(state, eapol_state_none) + else EAP_IF_RETURN_STRING(state, eapol_state_start_sent) + else EAP_IF_RETURN_STRING(state, eapol_state_no_start_response) + else + { + return EAPL("Unknown EAPOL state"); + } + } + else if (protocol_layer == eap_protocol_layer_eapol_key) + { + EAP_IF_RETURN_STRING(state, eapol_key_state_none) + else EAP_IF_RETURN_STRING(state, eapol_key_state_preauthenticated) + else EAP_IF_RETURN_STRING(state, eapol_key_state_eap_authentication_running) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_4_way_handshake_start) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_4_way_handshake_message_1) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_4_way_handshake_message_2) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_4_way_handshake_message_3) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_4_way_handshake_message_4) + else EAP_IF_RETURN_STRING(state, eapol_key_state_4_way_handshake_running) + else EAP_IF_RETURN_STRING(state, eapol_key_state_4_way_handshake_failed) + else EAP_IF_RETURN_STRING(state, eapol_key_state_4_way_handshake_successfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_group_key_handshake_message_1) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_group_key_handshake_message_2) + else EAP_IF_RETURN_STRING(state, eapol_key_state_group_key_handshake_failed) + else EAP_IF_RETURN_STRING(state, eapol_key_state_group_key_handshake_successfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_rc4_key_message) + else EAP_IF_RETURN_STRING(state, eapol_key_state_802_11i_authentication_terminated_unsuccessfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_802_11i_authentication_finished_successfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_reassociation_failed) +#if defined(EAP_USE_WPXM) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wpxm_reassociation_finished_successfull) +#endif //#if defined(EAP_USE_WPXM) + else + { + return EAPL("Unknown EAPOL state"); + } + } +#if defined(USE_WAPI_CORE) + else if (protocol_layer == eap_protocol_layer_wapi) + { + EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_none) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_this_ap_failed) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_authentication_successfull) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_wapi_authentication_running) + else + { + return EAPL("Unknown WAPI state"); + } + } + else if (protocol_layer == eap_protocol_layer_wai) + { + EAP_IF_RETURN_STRING(state, eapol_key_state_none) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wapi_authentication_terminated_unsuccessfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wapi_authentication_finished_successfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wapi_authentication_running) + else + { + return EAPL("Unknown WAI state"); + } + } +#endif //#if defined(USE_WAPI_CORE) + else if (protocol_layer == eap_protocol_layer_ethernet) + { + return EAPL("Unknown ethernet state"); + } + else if (protocol_layer == eap_protocol_layer_wlan_authentication) + { + EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_none) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_association_ok) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_this_ap_failed) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_failed_completely) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_802_11_auth_algorithm_not_supported) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_authenticating) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_eap_authentication_running) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_no_response) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_4_way_handshake_running) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_authentication_successfull) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_authentication_cancelled) + else EAP_IF_RETURN_STRING(state, eapol_wlan_authentication_state_immediate_reconnect) + else + { + return EAPL("Unknown wauth state"); + } + } +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(protocol_layer); + EAP_UNREFERENCED_PARAMETER(state); + + return EAPL("Unknown state"); + } +} + +EAP_FUNC_EXPORT eap_const_string eap_state_notification_c::get_current_state_string() const +{ + return get_state_string(m_layer, m_current_state); +} + +EAP_FUNC_EXPORT eap_const_string eap_state_notification_c::get_previous_state_string() const +{ + return get_state_string(m_layer, m_previous_state); +} + +EAP_FUNC_EXPORT eap_const_string eap_state_notification_c::get_protocol_layer_string(const u32_t protocol_layer) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + + EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_none) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_general) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_internal_type) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_am_eap_type) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_radius) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_eap_type) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_eap) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_eapol) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_eapol_key) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_ethernet) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_wlan_authentication) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_authentication_server) +#if defined(USE_WAPI_CORE) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_wapi) + else EAP_IF_RETURN_STRING(protocol_layer, eap_protocol_layer_wai) +#endif //#if defined(USE_WAPI_CORE) + +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(protocol_layer); + + return EAPL("Unknown protocol layer"); + } +} + +EAP_FUNC_EXPORT eap_const_string eap_state_notification_c::get_protocol_layer_string() const +{ + return get_protocol_layer_string(m_layer); +} + +EAP_FUNC_EXPORT eap_const_string eap_state_notification_c::get_protocol_string(const u32_t protocol_layer, const u32_t protocol) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + + if (protocol_layer == eap_protocol_layer_general) + { + return EAPL("No general protocol"); + } + else if (protocol_layer == eap_protocol_layer_internal_type + || protocol_layer == eap_protocol_layer_am_eap_type + || protocol_layer == eap_protocol_layer_eap_type + || protocol_layer == eap_protocol_layer_eap) + { + return EAPL("No EAP protocol"); + } + else if (protocol_layer == eap_protocol_layer_eapol) + { + return EAPL("No EAPOL protocol"); + } + else if (protocol_layer == eap_protocol_layer_eapol_key) + { + EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_none) + else EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_4_way_handshake) + else EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_group_key_handshake) + else EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_STAKey_handshake) + else EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_802_11i_handshake) + else EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_dynamic_WEP) +#if defined(EAP_USE_WPXM) + else EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_WPXM_reassociation) +#endif //#if defined(EAP_USE_WPXM) +#if defined(USE_WAPI_CORE) + else EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_wai_handshake) +#endif //#if defined(USE_WAPI_CORE) + else + { + return EAPL("Unknown EAPOL protocol"); + } + } + else if (protocol_layer == eap_protocol_layer_ethernet) + { + return EAPL("No ethernet protocol"); + } + else if (protocol_layer == eap_protocol_layer_wlan_authentication) + { + { + return EAPL("No wauth protocol"); + } + } +#if defined(USE_WAPI_CORE) + else if (protocol_layer == eap_protocol_layer_wapi) + { + EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_none) + else EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_wai_handshake) + else + { + return EAPL("Unknown WAPI protocol"); + } + } + else if (protocol_layer == eap_protocol_layer_wai) + { + EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_none) + else EAP_IF_RETURN_STRING(protocol, eapol_key_handshake_type_wai_handshake) + else + { + return EAPL("Unknown WAI protocol"); + } + } +#endif //#if defined(USE_WAPI_CORE) +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(protocol_layer); + EAP_UNREFERENCED_PARAMETER(protocol); + + return EAPL("Unknown protocol"); + } +} + +EAP_FUNC_EXPORT eap_const_string eap_state_notification_c::get_protocol_string() const +{ + return get_protocol_string(m_layer, m_protocol); +} + +EAP_FUNC_EXPORT bool eap_state_notification_c::get_is_client() const +{ + return m_is_client; +} + +EAP_FUNC_EXPORT u8_t eap_state_notification_c::get_eap_identifier() const +{ + return m_eap_identifier; +} + +EAP_FUNC_EXPORT bool eap_state_notification_c::get_allow_send_eap_success() const +{ + return m_allow_send_eap_success; +} + +EAP_FUNC_EXPORT eap_status_e eap_state_notification_c::set_notification_string( + const eap_variable_data_c * const notification_string, + const bool needs_confirmation_from_user) +{ + eap_status_e status = m_notification_string.set_copy_of_buffer(notification_string); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_needs_confirmation_from_user = needs_confirmation_from_user; + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT const eap_variable_data_c * eap_state_notification_c::get_notification_string() const +{ + return &m_notification_string; +} + +EAP_FUNC_EXPORT bool eap_state_notification_c::get_needs_confirmation_from_user() const +{ + return m_needs_confirmation_from_user; +} + + +EAP_FUNC_EXPORT void eap_state_notification_c::set_authentication_error(const eap_status_e error) +{ + m_authentication_error = error; +} + +EAP_FUNC_EXPORT eap_status_e eap_state_notification_c::get_authentication_error() const +{ + return m_authentication_error; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_status_string.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_status_string.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,186 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 38 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +/** @file */ + +#include "eap_tools.h" +#include "eap_status_string.h" + +//------------------------------------------------------------------------------ + +EAP_FUNC_EXPORT eap_status_string_c::~eap_status_string_c() +{ +} + +EAP_FUNC_EXPORT eap_status_string_c::eap_status_string_c() +{ +} + +EAP_FUNC_EXPORT eap_const_string eap_status_string_c::get_status_string(const eap_status_e status) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(status, eap_status_ok) + else EAP_IF_RETURN_STRING(status, eap_status_success) + else EAP_IF_RETURN_STRING(status, eap_status_pending_request) + else EAP_IF_RETURN_STRING(status, eap_status_completed_request) + else EAP_IF_RETURN_STRING(status, eap_status_drop_packet_quietly) + else EAP_IF_RETURN_STRING(status, eap_status_not_supported) + else EAP_IF_RETURN_STRING(status, eap_status_process_general_error) + else EAP_IF_RETURN_STRING(status, eap_status_type_does_not_exists_error) + else EAP_IF_RETURN_STRING(status, eap_status_allocation_error) + else EAP_IF_RETURN_STRING(status, eap_status_process_illegal_packet_error) + else EAP_IF_RETURN_STRING(status, eap_status_ethernet_type_not_supported) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_eap_code) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_eap_type) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_eap_identity) + else EAP_IF_RETURN_STRING(status, eap_status_authentication_failure) + else EAP_IF_RETURN_STRING(status, eap_status_encryption_failure) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_padding) + else EAP_IF_RETURN_STRING(status, eap_status_randomize_failure) + else EAP_IF_RETURN_STRING(status, eap_status_handler_exists_error) + else EAP_IF_RETURN_STRING(status, eap_status_handler_does_not_exists_error) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_sae_state) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_eapol_version) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_eapol_type) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_eapol_oui) + else EAP_IF_RETURN_STRING(status, eap_status_header_corrupted) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_sae_sequence_number) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_isakmp_header_version) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_isakmp_exchange_type) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_isakmp_flags) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_isakmp_message_id) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_isakmp_cookie) + else EAP_IF_RETURN_STRING(status, eap_status_unsupported_isakmp_payload) + else EAP_IF_RETURN_STRING(status, eap_status_key_error) + else EAP_IF_RETURN_STRING(status, eap_status_too_many_offers) + else EAP_IF_RETURN_STRING(status, eap_status_send_failed) + else EAP_IF_RETURN_STRING(status, eap_status_data_length_not_aligned_to_block_size) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_network_id) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_handle) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_configure_field) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_configure_type) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_sae_header_version) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_sae_exchange_type) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_sae_flags) + else EAP_IF_RETURN_STRING(status, eap_status_unsupported_sae_payload) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_sae_cookie) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_encryption_parameter_size) + else EAP_IF_RETURN_STRING(status, eap_status_state_reference_count_not_zero) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_nai) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_nai_payload) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_data_payload) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_payload) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_hashed_index) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_gsmsim_state) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_eap_type_state) + else EAP_IF_RETURN_STRING(status, eap_status_unsupported_gsmsim_payload) + else EAP_IF_RETURN_STRING(status, eap_status_gsmsim_triplet_query_failed) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_index) + else EAP_IF_RETURN_STRING(status, eap_status_timed_out) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_eap_subtype) + else EAP_IF_RETURN_STRING(status, eap_status_exit_test) + else EAP_IF_RETURN_STRING(status, eap_status_no_matching_protocol_version) + else EAP_IF_RETURN_STRING(status, eap_status_too_short_message) + else EAP_IF_RETURN_STRING(status, eap_status_too_long_message) + else EAP_IF_RETURN_STRING(status, eap_status_hardware_not_ready) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_protocol) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_type) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_parameter) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_certificate) + else EAP_IF_RETURN_STRING(status, eap_status_illegal_cipher_suite) + else EAP_IF_RETURN_STRING(status, eap_status_bad_certificate) + else EAP_IF_RETURN_STRING(status, eap_status_unsupported_certificate) + else EAP_IF_RETURN_STRING(status, eap_status_certificate_revoked) + else EAP_IF_RETURN_STRING(status, eap_status_certificate_expired) + + // This is splitted to decrease if nesting. Some compilers fails to compile. + EAP_IF_RETURN_STRING(status, eap_status_user_certificate_unknown) + else EAP_IF_RETURN_STRING(status, eap_status_ca_certificate_unknown) + else EAP_IF_RETURN_STRING(status, eap_status_unknown_ca) + else EAP_IF_RETURN_STRING(status, eap_status_access_denied) + else EAP_IF_RETURN_STRING(status, eap_status_unexpected_message) + else EAP_IF_RETURN_STRING(status, eap_status_buffer_too_short) + else EAP_IF_RETURN_STRING(status, eap_status_not_found) + else EAP_IF_RETURN_STRING(status, eap_status_not_enough_challenges) + else EAP_IF_RETURN_STRING(status, eap_status_not_fresh_challenges) + else EAP_IF_RETURN_STRING(status, eap_status_already_exists) + else EAP_IF_RETURN_STRING(status, eap_status_insufficient_security) + else EAP_IF_RETURN_STRING(status, eap_status_syncronization_failure) + else EAP_IF_RETURN_STRING(status, eap_status_file_does_not_exist) + else EAP_IF_RETURN_STRING(status, eap_status_end_of_file) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_authentication_type) + else EAP_IF_RETURN_STRING(status, eap_status_section_ends) + else EAP_IF_RETURN_STRING(status, eap_status_missing_payload) + else EAP_IF_RETURN_STRING(status, eap_status_realm_check_failed) + else EAP_IF_RETURN_STRING(status, eap_status_identity_query_failed) + else EAP_IF_RETURN_STRING(status, eap_status_credential_query_failed) + else EAP_IF_RETURN_STRING(status, eap_status_user_has_not_subscribed_to_the_requested_service) + else EAP_IF_RETURN_STRING(status, eap_status_users_calls_are_barred) + else EAP_IF_RETURN_STRING(status, eap_status_restricted_logon_hours) + else EAP_IF_RETURN_STRING(status, eap_status_account_disabled) + else EAP_IF_RETURN_STRING(status, eap_status_no_dialin_permission) + else EAP_IF_RETURN_STRING(status, eap_status_password_expired) + else EAP_IF_RETURN_STRING(status, eap_status_wrong_password) + else EAP_IF_RETURN_STRING(status, eap_status_oob_interface_read_error) + else EAP_IF_RETURN_STRING(status, eap_status_decryption_crc_failure) + else EAP_IF_RETURN_STRING(status, eap_status_rf_band_2_4_ghz_not_supported) + else EAP_IF_RETURN_STRING(status, eap_status_rf_band_5_0_ghz_not_supported) + else EAP_IF_RETURN_STRING(status, eap_status_signal_too_weak) + else EAP_IF_RETURN_STRING(status, eap_status_network_authentication_failure) + else EAP_IF_RETURN_STRING(status, eap_status_network_association_failure) + else EAP_IF_RETURN_STRING(status, eap_status_no_dhcp_response) + else EAP_IF_RETURN_STRING(status, eap_status_failed_dhcp_configure) + else EAP_IF_RETURN_STRING(status, eap_status_ip_address_conflict) + else EAP_IF_RETURN_STRING(status, eap_status_could_not_connect_to_registrar) + else EAP_IF_RETURN_STRING(status, eap_status_multiple_pbc_sessions_detected) + else EAP_IF_RETURN_STRING(status, eap_status_rogue_activity_suspected) + else EAP_IF_RETURN_STRING(status, eap_status_device_busy) + else EAP_IF_RETURN_STRING(status, eap_status_setup_locked) + else EAP_IF_RETURN_STRING(status, eap_status_message_timeout) + else EAP_IF_RETURN_STRING(status, eap_status_registration_session_timeout) + else EAP_IF_RETURN_STRING(status, eap_status_device_password_authentication_failure) + else EAP_IF_RETURN_STRING(status, eap_status_pin_code_authentication_not_supported) + else EAP_IF_RETURN_STRING(status, eap_status_push_button_authentication_not_supported) + else EAP_IF_RETURN_STRING(status, eap_status_end_recursion) + else EAP_IF_RETURN_STRING(status, eap_status_tunnel_compromise_error) + else EAP_IF_RETURN_STRING(status, eap_status_unexpected_tlv_exhanged) + else EAP_IF_RETURN_STRING(status, eap_status_no_pac_nor_certs_to_authenticate_with_provision_disabled) + else EAP_IF_RETURN_STRING(status, eap_status_no_matching_pac_for_aid) + else EAP_IF_RETURN_STRING(status, eap_status_pac_store_corrupted) + else EAP_IF_RETURN_STRING(status, eap_status_user_cancel_authentication) + else EAP_IF_RETURN_STRING(status, eap_status_no_match) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(status); + return EAPL("Unknown EAP-status"); + } +} + +//------------------------------------------------------------------------------ +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_tlv_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_tlv_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,208 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 39 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tlv_header.h" + +/** @file */ + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_tlv_header_c::~eap_tlv_header_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_tlv_header_c::eap_tlv_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_tlv_type_t eap_tlv_header_c::get_type() const +{ + const u8_t * const tlv_type_data = get_header_offset(m_type_offset, sizeof(u32_t)); + if (tlv_type_data != 0) + { + return static_cast(eap_read_u32_t_network_order(tlv_type_data, sizeof(u32_t))); + } + else + { + return eap_tlv_type_none; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_tlv_header_c::get_value_length() const +{ + const u8_t * const tlv_length_data = get_header_offset(m_length_offset, sizeof(u32_t)); + if (tlv_length_data != 0) + { + return eap_read_u32_t_network_order(tlv_length_data, sizeof(u32_t)); + } + else + { + return 0ul; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_tlv_header_c::get_header_length() +{ + return m_data_offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_tlv_header_c::get_value_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + u32_t data_length = get_value_length(); + + if (data_length >= offset+contignuous_bytes) + { + u8_t * const data = get_header_offset(m_data_offset, offset+contignuous_bytes); + if (data != 0) + { + return &data[offset]; + } + else + { + return 0; + } + } + else + { + EAP_ASSERT_ALWAYS(data_length >= offset+contignuous_bytes); + } + return 0; +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_tlv_header_c::get_value(const u32_t contignuous_bytes) const +{ + return get_value_offset(0u, contignuous_bytes); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_header_c::check_header() const +{ + if ((get_header_length() + get_value_length()) > get_header_buffer_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_header_c::set_type(const eap_tlv_type_t type) +{ + if (type == eap_tlv_type_none) + { + EAP_ASSERT(type != eap_tlv_type_none); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_type); + } + + u8_t * const type_data = get_header_offset(m_type_offset, sizeof(u32_t)); + + if (type_data == 0) + { + EAP_ASSERT(type_data != 0); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_write_u32_t_network_order(type_data, sizeof(u32_t), type); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_header_c::set_value_length(const u32_t value_length) +{ + if (get_header_length() + value_length > get_header_buffer_length()) + { + EAP_ASSERT(get_header_length() + value_length <= get_header_buffer_length()); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u32_t)); + + if (length_data == 0) + { + EAP_ASSERT(length_data != 0); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_write_u32_t_network_order(length_data, sizeof(u32_t), value_length); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_header_c::reset_header( + const eap_tlv_type_t type, + const u32_t value_length) +{ + eap_status_e status = set_type(type); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_value_length(value_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_tlv_message_data.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_tlv_message_data.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,545 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 579 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_automatic_variable.h" +#include "eap_tlv_message_data.h" + +/** @file */ + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_tlv_message_data_c::~eap_tlv_message_data_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_tlv_message_data_c::eap_tlv_message_data_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_message_data(tools) +{ +} + +//------------------------------------------------------------------- + +/** + * This function should increase reference count. + */ +EAP_FUNC_EXPORT void eap_tlv_message_data_c::object_increase_reference_count() +{ +} + +//------------------------------------------------------------------- + +/** + * This function should first decrease reference count + * and second return the remaining reference count. + * Reference count must not be decreased when it is zero. + */ +EAP_FUNC_EXPORT u32_t eap_tlv_message_data_c::object_decrease_reference_count() +{ + return 0; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void * eap_tlv_message_data_c::get_message_data() const +{ + return m_message_data.get_data(m_message_data.get_data_length()); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_tlv_message_data_c::get_message_data_length() const +{ + return m_message_data.get_data_length(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_message_data_c::allocate_message_data_buffer( + const u32_t approximate_buffer_requirement) +{ + if (m_message_data.get_is_valid() == true) + { + return m_message_data.set_buffer_length(m_message_data.get_buffer_length()+approximate_buffer_requirement); + } + else + { + return m_message_data.set_buffer_length(approximate_buffer_requirement); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_message_data_c::copy_message_data( + const u32_t length, + const void * const value) +{ + eap_status_e status(eap_status_process_general_error); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("copy_message_data()"), + value, + length)); + + status = m_message_data.set_copy_of_buffer( + value, + length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_message_data_c::set_message_data( + const u32_t length, + const void * const value) +{ + eap_status_e status(eap_status_process_general_error); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("set_message_data()"), + value, + length)); + + status = m_message_data.set_buffer( + value, + length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_message_data_c::add_message_data( + const eap_tlv_type_t type, + const u32_t length, + const void * const value) +{ + eap_status_e status(eap_status_process_general_error); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eap_tlv_message_data_c::add_message_data(): type %2d=0x%08x, length %3d=0x%08x\n"), + type, + type, + length, + length)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("add_message_data()"), + value, + length)); + + u32_t tlv_header_offset(0ul); + + if (m_message_data.get_is_valid() == true) + { + tlv_header_offset = m_message_data.get_data_length(); + } + else + { + tlv_header_offset = 0ul; + } + + // This will allocate space for eap_tlv_header_c too. + status = m_message_data.add_data_to_offset( + tlv_header_offset+eap_tlv_header_c::get_header_length(), + value, + length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Add eap_tlv_header_c to message. + eap_tlv_header_c header( + m_am_tools, + m_message_data.get_data_offset(tlv_header_offset, eap_tlv_header_c::get_header_length()+length), + eap_tlv_header_c::get_header_length()+length); + + if (header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = header.reset_header(type, length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_message_data_c::add_message_data_array( + const eap_tlv_type_t type, + const u32_t length_of_each_data_block, + eap_array_c * const data_array) +{ + eap_status_e status(eap_status_process_general_error); + + u32_t tlv_header_offset(0ul); + + if (m_message_data.get_is_valid() == true) + { + tlv_header_offset = m_message_data.get_data_length(); + } + else + { + tlv_header_offset = 0ul; + } + + if (data_array->get_object_count() != 0ul) + { + for (u32_t ind = 0ul; ind < data_array->get_object_count(); ind++) + { + eap_variable_data_c * const data = data_array->get_object(ind); + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (data->get_data_length() != length_of_each_data_block) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // This will allocate space for eap_tlv_header_c too. + status = m_message_data.add_data_to_offset( + tlv_header_offset+eap_tlv_header_c::get_header_length()+(ind*length_of_each_data_block), + data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + } + else + { + // This will allocate space for eap_tlv_header_c only. + status = m_message_data.add_data_to_offset( + tlv_header_offset+eap_tlv_header_c::get_header_length(), + 0, + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + u32_t length = data_array->get_object_count() * length_of_each_data_block; + + // Add eap_tlv_header_c to message. + eap_tlv_header_c header( + m_am_tools, + m_message_data.get_data_offset(tlv_header_offset, eap_tlv_header_c::get_header_length()+length), + eap_tlv_header_c::get_header_length()+length); + + if (header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = header.reset_header(type, length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_message_data_c::parse_message_data( + eap_array_c * const tlv_blocks) +{ + eap_status_e status(eap_status_ok); + + tlv_blocks->reset(); + + u8_t *next_header_begins = m_message_data.get_data(); + u32_t remaining_message_data_length = m_message_data.get_data_length(); + + if (next_header_begins == 0 + || remaining_message_data_length == 0) + { + // TLV is empty. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + // This is reference to the first eap_tlv_header_c in the message_data. + eap_tlv_header_c header( + m_am_tools, + next_header_begins, + remaining_message_data_length); + + while (header.get_is_valid() == true) + { + const u32_t payload_length(header.get_header_length()+header.get_value_length()); + + status = header.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("ERROR: illegal payload"), + header.get_header_buffer(header.get_header_buffer_length()), + header.get_header_buffer_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("payload"), + header.get_header_buffer(payload_length), + payload_length)); + } + + + if (remaining_message_data_length < payload_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + { + eap_tlv_header_c * const tlv = new eap_tlv_header_c( + m_am_tools, + header.get_header_buffer(payload_length), + payload_length); + + eap_automatic_variable_c automatic_tlv(m_am_tools, tlv); + + if (tlv == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (tlv->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + automatic_tlv.do_not_free_variable(); + + status = tlv_blocks->add_object(tlv, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u32_t tlv_length = tlv->get_header_length()+tlv->get_value_length(); + next_header_begins += tlv_length; + remaining_message_data_length -= tlv_length; + + if (next_header_begins >= (m_message_data.get_data()+m_message_data.get_data_length()) + || remaining_message_data_length == 0) + { + // No next header. + break; + } + } + + header.set_header_buffer( + next_header_begins, + remaining_message_data_length); + if (header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // while() + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_message_data_c::add_message_header( + const eap_tlv_type_t type, + const u32_t length) +{ + // This will allocate space for eap_tlv_header_c without any value. + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eap_tlv_message_data_c::add_message_header(): type %2d=0x%08x, length %3d=0x%08x\n"), + type, + type, + length, + length)); + + u32_t network_order_type(eap_htonl(type)); + + eap_status_e status = m_message_data.add_data( + &network_order_type, + sizeof(network_order_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t network_order_length(eap_htonl(length)); + + status = m_message_data.add_data( + &network_order_length, + sizeof(network_order_length)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_tlv_message_data_c::allocate_message_buffer( + const eap_tlv_type_t type, + const u32_t length, + void * * const buffer) +{ + eap_status_e status(eap_status_process_general_error); + + *buffer = 0; + + u32_t tlv_header_offset(0ul); + + if (m_message_data.get_is_valid() == true) + { + tlv_header_offset = m_message_data.get_data_length(); + } + else + { + tlv_header_offset = 0ul; + } + + // This will allocate space for eap_tlv_header_c only. + status = m_message_data.add_data_to_offset( + tlv_header_offset+eap_tlv_header_c::get_header_length()+length, + 0, + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Add eap_tlv_header_c to message. + eap_tlv_header_c header( + m_am_tools, + m_message_data.get_data_offset(tlv_header_offset, eap_tlv_header_c::get_header_length()+length), + eap_tlv_header_c::get_header_length()+length); + + if (header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = header.reset_header(type, length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *buffer = header.get_value(length); + + if ((*buffer) == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_tlv_message_data_c::get_is_valid() +{ + return m_message_data.get_is_valid(); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_tools.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_tools.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,564 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 41 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +/** @file */ + +#include "eap_tools.h" + +//------------------------------------------------------------------- + +EAP_C_FUNC_EXPORT u16_t eap_htons(const u16_t value) +{ + #if defined(EAP_LITTLE_ENDIAN) /// byte 0 is least significant (i386) + return(static_cast((value >> (sizeof(u8_t)*8u)) + | (value << (sizeof(u8_t)*8u)))); + #elif defined(EAP_BIG_ENDIAN) /// byte 0 is most significant (mc68k) + return value; + #else + #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ + or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). + #endif +} + +EAP_C_FUNC_EXPORT u32_t eap_htonl(const u32_t value) +{ + #if defined(EAP_LITTLE_ENDIAN) /// byte 0 is least significant (i386) + return(static_cast((value & 0xFF) << 24) + | ((value & 0xFF00) << 8) + | ((value & 0xFF0000) >> 8) + | ((value & 0xFF000000) >> 24)); + #elif defined(EAP_BIG_ENDIAN) /// byte 0 is most significant (mc68k) + return value; + #else + #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ + or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). + #endif +} + +EAP_C_FUNC_EXPORT u64_t eap_htonll(const u64_t value) +{ + + #if defined(EAP_LITTLE_ENDIAN) /// byte 0 is least significant (i386) + #if defined(__SYMBIAN32__) + u32_t *val = reinterpret_cast(const_cast(&value)); + u64_t out_buf; + u32_t *out = reinterpret_cast(&out_buf); + + out[0] = eap_htonl(val[1]); + out[1] = eap_htonl(val[0]); + + return out_buf; + #else + return(static_cast((value & 0xFF) << 56) + | ((value & 0xFF00) << 40) + | ((value & 0xFF0000) << 24) + | ((value & 0xFF000000) << 8) + | (((value >> 32) & 0xFF) << 24) + | (((value >> 32) & 0xFF00) << 8) + | (((value >> 32) & 0xFF0000) >> 8) + | (((value >> 32) & 0xFF000000) >> 24)); + #endif + #elif defined(EAP_BIG_ENDIAN) /// byte 0 is most significant (mc68k) + return value; + #else + #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ + or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). + #endif +} + +EAP_C_FUNC_EXPORT u16_t eap_host_to_little_endian_short(const u16_t value) +{ + #if defined(EAP_LITTLE_ENDIAN) /// byte 0 is least significant (i386) + return value; + #elif defined(EAP_BIG_ENDIAN) /// byte 0 is most significant (mc68k) + return(static_cast((value & 0xFF) << 8) + | ((value & 0xFF00) >> 8)); + #else + #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ + or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). + #endif +} + +EAP_C_FUNC_EXPORT u32_t eap_host_to_little_endian_long(const u32_t value) +{ + #if defined(EAP_LITTLE_ENDIAN) /// byte 0 is least significant (i386) + return value; + #elif defined(EAP_BIG_ENDIAN) /// byte 0 is most significant (mc68k) + return(static_cast((value & 0xFF) << 24) + | ((value & 0xFF00) << 8) + | ((value & 0xFF0000) >> 8) + | ((value & 0xFF000000) >> 24)); + #else + #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ + or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). + #endif +} + +EAP_C_FUNC_EXPORT u64_t eap_host_to_little_endian_long_long(const u64_t value) +{ + #if defined(EAP_LITTLE_ENDIAN) /// byte 0 is least significant (i386) + return value; + #elif defined(EAP_BIG_ENDIAN) /// byte 0 is most significant (mc68k) + #if defined(__SYMBIAN32__) + u32_t *val = reinterpret_cast(const_cast(&value)); + u64_t out_buf; + u32_t *out = reinterpret_cast(&out_buf); + + out[0] = eap_host_to_little_endian_long(val[1]); + out[1] = eap_host_to_little_endian_long(val[0]); + + return out_buf; + #else + return(static_cast((value & 0xFF) << 56) + | ((value & 0xFF00) << 40) + | ((value & 0xFF0000) << 24) + | ((value & 0xFF000000) << 8) + | (((value >> 32) & 0xFF) << 24) + | (((value >> 32) & 0xFF00) << 8) + | (((value >> 32) & 0xFF0000) >> 8) + | (((value >> 32) & 0xFF000000) >> 24)); + #endif + #else + #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ + or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). + #endif +} + +//------------------------------------------------------------------- + +EAP_C_FUNC_EXPORT eap_status_e eap_write_u16_t_little_endian_order( + void * const p_data, + const u32_t data_length, + const u16_t value) +{ + if (data_length < sizeof(u16_t) + || p_data == 0) + { + return eap_status_allocation_error; + } + + u8_t * const data = static_cast(p_data); + + data[0] = static_cast((value) & 0xff); + data[1] = static_cast((value >> 8) & 0xff); + + return eap_status_ok; +} + +EAP_C_FUNC_EXPORT eap_status_e eap_write_u32_t_little_endian_order( + void * const p_data, + const u32_t data_length, + const u32_t value) +{ + if (data_length < sizeof(u32_t) + || p_data == 0) + { + return eap_status_allocation_error; + } + + u8_t * const data = static_cast(p_data); + + data[0] = static_cast((value) & 0xff); + data[1] = static_cast((value >> 8) & 0xff); + data[2] = static_cast((value >> 16) & 0xff); + data[3] = static_cast((value >> 24) & 0xff); + + return eap_status_ok; +} + + +EAP_C_FUNC_EXPORT eap_status_e eap_write_u64_t_little_endian_order( + void * const p_data, + const u32_t data_length, + const u64_t value) +{ + if (data_length < sizeof(u64_t) + || p_data == 0) + { + return eap_status_allocation_error; + } + + // This is used because Symbian does not have 64 bit shift operation. + u8_t * const data = static_cast(p_data); + + const u32_t * const outvalue = reinterpret_cast(&value); + + #if defined(EAP_LITTLE_ENDIAN) /// byte 0 is least significant (i386) + const u32_t least_significant_u32_t_index = 0; + const u32_t most_significant_u32_t_index = 1; + #elif defined(EAP_BIG_ENDIAN) /// byte 0 is most significant (mc68k) + const u32_t most_significant_u32_t_index = 0; + const u32_t least_significant_u32_t_index = 1; + #else + #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ + or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). + #endif + + eap_status_e status = eap_write_u32_t_little_endian_order( + data, + sizeof(u32_t), + outvalue[least_significant_u32_t_index]); + if (status != eap_status_ok) + { + return status; + } + + status = eap_write_u32_t_little_endian_order( + data+sizeof(u32_t), + sizeof(u32_t), + outvalue[most_significant_u32_t_index]); + if (status != eap_status_ok) + { + return status; + } + + return eap_status_ok; +} + + +EAP_C_FUNC_EXPORT u16_t eap_read_u16_t_little_endian_order( + const void * const p_data, + const u32_t data_length) +{ + if (data_length < sizeof(u16_t) + || p_data == 0) + { + return 0ul; + } + + const u8_t * const data = static_cast(p_data); + + return(static_cast( + (static_cast(data[0]) + | static_cast(data[1]) << 8))); +} + +EAP_C_FUNC_EXPORT u32_t eap_read_u32_t_little_endian_order( + const void * const p_data, + const u32_t data_length) +{ + if (data_length < sizeof(u32_t) + || p_data == 0) + { + return 0ul; + } + + const u8_t * const data = static_cast(p_data); + + return(static_cast( + static_cast(data[0]) + | (static_cast(data[1]) << 8) + | (static_cast(data[2]) << 16) + | (static_cast(data[3]) << 24))); +} + +EAP_C_FUNC_EXPORT u64_t eap_read_u64_t_little_endian_order( + const void * const p_data, + const u32_t data_length) +{ + if (data_length < sizeof(u64_t) + || p_data == 0) + { + return 0ul; + } + + union + { + u64_t q; + u64_struct w; + } v; + + const u8_t *data = static_cast(p_data); + + v.w.low = eap_read_u32_t_little_endian_order(data,sizeof(u32_t)); + data += sizeof(u32_t); + v.w.high = eap_read_u32_t_little_endian_order(data,sizeof(u32_t)); + + return v.q; +} + + +EAP_C_FUNC_EXPORT u16_t eap_read_u16_t_network_order( + const void * const p_data, + const u32_t data_length) +{ + if (data_length < sizeof(u16_t) + || p_data == 0) + { + return 0ul; + } + + const u8_t * const data = static_cast(p_data); + + return(static_cast( + (static_cast(data[0]) << 8) + | static_cast(data[1]))); +} + +EAP_C_FUNC_EXPORT u32_t eap_read_u24_t_network_order( + const void * const p_data, + const u32_t data_length) +{ + if (data_length < sizeof(u8_t)*3ul + || p_data == 0) + { + return 0ul; + } + + const u8_t * const data = static_cast(p_data); + + return(static_cast( + (static_cast(data[0]) << 16) + | (static_cast(data[1]) << 8) + | static_cast(data[2]))); +} + +EAP_C_FUNC_EXPORT u32_t eap_read_u32_t_network_order( + const void * const p_data, + const u32_t data_length) +{ + if (data_length < sizeof(u32_t) + || p_data == 0) + { + return 0ul; + } + + const u8_t * const data = static_cast(p_data); + + return(static_cast( + (static_cast(data[0]) << 24) + | (static_cast(data[1]) << 16) + | (static_cast(data[2]) << 8) + | static_cast(data[3]))); +} + + +/* The following function is problematic for ARM Linux. + There is now linux_gnu code which _should_ work also + with other architectures. It does not use 64 bit shift. +*/ +EAP_C_FUNC_EXPORT u64_t eap_read_u64_t_network_order( + const void * const p_data, + const u32_t data_length) +{ + if (data_length < sizeof(u64_t) + || p_data == 0) + { + return 0ul; + } + + union + { + u64_t q; + u64_struct w; + } v; + + const u8_t *data = static_cast(p_data); + + v.w.high = eap_read_u32_t_network_order(data,sizeof(u32_t)); + data += sizeof(u32_t); + v.w.low = eap_read_u32_t_network_order(data,sizeof(u32_t)); + + return v.q; +} + +//------------------------------------------------------------------- + +EAP_C_FUNC_EXPORT eap_status_e eap_write_u16_t_network_order( + void * const p_data, + const u32_t data_length, + const u16_t value) +{ + if (data_length < sizeof(u16_t) + || p_data == 0) + { + return eap_status_allocation_error; + } + + u8_t * const data = static_cast(p_data); + + data[0] = static_cast((value >> 8) & 0xff); + data[1] = static_cast((value) & 0xff); + + return eap_status_ok; +} + +EAP_C_FUNC_EXPORT eap_status_e eap_write_u24_t_network_order( + void * const p_data, + const u32_t data_length, + const u32_t value) +{ + if (data_length < 3ul*sizeof(u8_t) + || p_data == 0) + { + return eap_status_allocation_error; + } + + u8_t * const data = static_cast(p_data); + + data[0] = static_cast((value >> 16) & 0xff); + data[1] = static_cast((value >> 8) & 0xff); + data[2] = static_cast((value) & 0xff); + + return eap_status_ok; +} + +EAP_C_FUNC_EXPORT eap_status_e eap_write_u32_t_network_order( + void * const p_data, + const u32_t data_length, + const u32_t value) +{ + if (data_length < sizeof(u32_t) + || p_data == 0) + { + return eap_status_allocation_error; + } + + u8_t * const data = static_cast(p_data); + + data[0] = static_cast((value >> 24) & 0xff); + data[1] = static_cast((value >> 16) & 0xff); + data[2] = static_cast((value >> 8) & 0xff); + data[3] = static_cast((value) & 0xff); + + return eap_status_ok; +} + +EAP_C_FUNC_EXPORT eap_status_e eap_write_u64_t_network_order( + void * const p_data, + const u32_t data_length, + const u64_t value) +{ + if (data_length < sizeof(u64_t) + || p_data == 0) + { + return eap_status_allocation_error; + } + + // This is used because Symbian does not have 64 bit shift operation. + u8_t * const data = static_cast(p_data); + + const u32_t * const outvalue = reinterpret_cast(&value); + + #if defined(EAP_LITTLE_ENDIAN) /// byte 0 is least significant (i386) + const u32_t least_significant_u32_t_index = 0; + const u32_t most_significant_u32_t_index = 1; + #elif defined(EAP_BIG_ENDIAN) /// byte 0 is most significant (mc68k) + const u32_t most_significant_u32_t_index = 0; + const u32_t least_significant_u32_t_index = 1; + #else + #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ + or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). + #endif + + eap_status_e status = eap_write_u32_t_network_order( + data, + sizeof(u32_t), + outvalue[most_significant_u32_t_index]); + if (status != eap_status_ok) + { + return status; + } + + status = eap_write_u32_t_network_order( + data+sizeof(u32_t), + sizeof(u32_t), + outvalue[least_significant_u32_t_index]); + if (status != eap_status_ok) + { + return status; + } + + return eap_status_ok; +} + +//------------------------------------------------------------------- + +EAP_C_FUNC_EXPORT u64_t eap_shift_left_64_bit(u64_t value, u32_t shift) +{ + if (shift > 63u) + { + return 0ul; + } + else if (shift == 0) + { + return value; + } + + u32_t *val = reinterpret_cast(&value); + u64_t out_buf; + u32_t *out = reinterpret_cast(&out_buf); + + if (shift < 32ul) + { + out[0] = val[0] << shift; + out[1] = (val[1] << shift) | val[0] >> (32ul - shift); + } + else + { + out[0] = 0ul; + out[1] = val[0] << (shift - 32ul); + } + + return out_buf; +} + +EAP_C_FUNC_EXPORT u64_t eap_shift_right_64_bit(u64_t value, u32_t shift) +{ + if (shift > 63u) + { + return 0ul; + } + else if (shift == 0) + { + return value; + } + + u32_t *val = reinterpret_cast(&value); + u64_t out_buf; + u32_t *out = reinterpret_cast(&out_buf); + + if (shift < 32ul) + { + out[0] = (val[0] >> shift) | val[1] << (32ul - shift); + out[1] = val[1] >> shift; + } + else + { + out[0] = val[1] >> (shift - 32ul); + out[1] = 0ul; + } + + return out_buf; +} + +//------------------------------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eap_variable_data.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eap_variable_data.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1044 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 42 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_variable_data.h" +#include "abs_eap_am_tools.h" +#include "eap_am_tools.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::initialize_members() +{ + m_data = new eap_variable_data_impl_str; + if (m_data == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_variable_data_c::initialize_members(): Cannot allocate %d bytes.\n"), + sizeof(eap_variable_data_impl_str))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_data->m_buffer = 0; + m_data->m_buffer_length = 0ul; + m_data->m_real_data_start_index = 0ul; + m_data->m_real_data_length = 0ul; + m_data->m_free_buffer = false; + m_data->m_is_writable = false; + + m_data->m_is_valid = true; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c::~eap_variable_data_c() +{ + if (m_data != 0) + { + if (m_data->m_free_buffer == true) + { + // Buffer was allocated. + +#if !defined(NO_EAP_VARIABLE_DATA_MEMORY_ZERO) + if (m_am_tools != 0) + { + m_am_tools->memset(m_data->m_buffer, 0, m_data->m_buffer_length); + } +#endif //#if !defined(NO_EAP_VARIABLE_DATA_MEMORY_ZERO) + + delete [] m_data->m_buffer; + } + m_data->m_buffer = 0; + m_data->m_buffer_length = 0ul; + m_data->m_real_data_start_index = 0ul; + m_data->m_real_data_length = 0ul; + m_data->m_free_buffer = false; + + m_data->m_is_valid = false; + + delete m_data; + m_data = 0; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c::eap_variable_data_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_data(0) +{ + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c::eap_variable_data_c( + abs_eap_am_tools_c * const tools, + const void * const buffer, + const u32_t buffer_length, + bool free_buffer, + bool is_writable) + : m_am_tools(tools) + , m_data(0) +{ + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return; + } + + status = set_buffer( + buffer, + buffer_length, + free_buffer, + is_writable); + if (status != eap_status_ok) + { + // ERROR. + set_is_invalid(); + return; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_variable_data_c::get_is_valid() const +{ + if (m_data == 0) + { + return false; + } + + return m_data->m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_variable_data_c::get_is_valid_data() const +{ + if (m_data == 0) + { + return false; + } + + if (m_data->m_is_valid == false) + { + return false; + } + + // Note the data length could be zero. + if (m_data->m_buffer == 0) + { + return false; + } + + return true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_variable_data_c::set_is_valid() +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return; + } + + m_data->m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_variable_data_c::set_is_invalid() +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return; + } + + m_data->m_is_valid = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_variable_data_c::get_is_writable() const +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return false; + } + + return m_data->m_is_writable; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_variable_data_c::get_buffer_offset( + const u32_t offset, + const u32_t buffer_length) const +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data != 0 + && m_data->m_is_valid == true + && m_data->m_buffer_length >= (m_data->m_real_data_start_index+offset+buffer_length)) + { + return m_data->m_buffer + (m_data->m_real_data_start_index + offset); + } + else + { + EAP_ASSERT_TOOLS( + m_am_tools, + m_data != 0 + && m_data->m_is_valid == true + && m_data->m_buffer_length + >= (m_data->m_real_data_start_index+offset+buffer_length)); + return 0; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_variable_data_c::get_buffer(const u32_t buffer_length) const +{ + return get_buffer_offset(0u, buffer_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_variable_data_c::get_data_offset( + const u32_t offset, + const u32_t data_length) const +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data != 0 + && m_data->m_is_valid == true + && m_data->m_real_data_length >= (offset+data_length)) + { + return get_buffer_offset(offset, data_length); + } + else + { + EAP_ASSERT_TOOLS( + m_am_tools, + m_data != 0 + && m_data->m_is_valid == true + && m_data->m_real_data_length >= (offset+data_length)); + return 0; + } +} + +//-------------------------------------------------- + +#if !defined(USE_EAP_INLINE_FUNCTIONS) + +EAP_FUNC_EXPORT u8_t * eap_variable_data_c::get_data() const +{ + return get_data(get_data_length()); +} + +#endif //#if !defined(USE_EAP_INLINE_FUNCTIONS) + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_variable_data_c::get_data(const u32_t data_length) const +{ + return get_data_offset(0u, data_length); +} + +//-------------------------------------------------- + +#if !defined(USE_EAP_INLINE_FUNCTIONS) + +EAP_FUNC_EXPORT u32_t eap_variable_data_c::get_data_length() const +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data != 0 + && m_data->m_is_valid == true) + { + return m_data->m_real_data_length; + } + else + { + return 0u; + } +} + +#endif //#if !defined(USE_EAP_INLINE_FUNCTIONS) + +//-------------------------------------------------- + +#if !defined(USE_EAP_INLINE_FUNCTIONS) + +EAP_FUNC_EXPORT u32_t eap_variable_data_c::get_buffer_length() const +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data != 0 + && m_data->m_is_valid == true) + { + return m_data->m_buffer_length; + } + else + { + return 0u; + } +} + +#endif //#if !defined(USE_EAP_INLINE_FUNCTIONS) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::reset_start_offset_and_data_length() +{ + if (m_data != 0 + && m_data->m_is_valid == true) + { + m_data->m_real_data_start_index = 0ul; + m_data->m_real_data_length = 0ul; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + EAP_ASSERT_TOOLS( + m_am_tools, + m_data != 0 + && m_data->m_is_valid == true); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::set_start_offset(const u32_t index) +{ + if (m_data != 0 + && m_data->m_is_valid == true + && m_data->m_real_data_length >= index) + { + m_data->m_real_data_start_index += index; + m_data->m_real_data_length -= index; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + EAP_ASSERT_TOOLS( + m_am_tools, + m_data != 0 + && m_data->m_is_valid == true + && m_data->m_real_data_length >= index); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::set_data_length( + const u32_t length) +{ + if (m_data != 0 + && m_data->m_is_valid == true + && m_data->m_buffer_length >= (m_data->m_real_data_start_index + length)) + { + m_data->m_real_data_length = length; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + EAP_ASSERT_TOOLS( + m_am_tools, + m_data != 0 + && m_data->m_is_valid == true + && m_data->m_buffer_length >= (m_data->m_real_data_start_index + length)); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::reset() +{ + if (m_data == 0) + { + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + else + { + if (m_data->m_free_buffer == true) + { + +#if !defined(NO_EAP_VARIABLE_DATA_MEMORY_ZERO) + m_am_tools->memset(m_data->m_buffer, 0, m_data->m_buffer_length); +#endif //#if !defined(NO_EAP_VARIABLE_DATA_MEMORY_ZERO) + + delete [] m_data->m_buffer; + m_data->m_free_buffer = false; + } + m_data->m_buffer = 0; + m_data->m_buffer_length = 0u; + m_data->m_real_data_start_index = 0ul; + m_data->m_real_data_length = 0u; + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::set_buffer( + const void * const p_buffer, + const u32_t buffer_length, + bool free_buffer, + bool is_writable) +{ + return set_buffer( + const_cast(p_buffer), + buffer_length, + free_buffer, + is_writable); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::set_buffer( + void * const p_buffer, + const u32_t buffer_length, + bool free_buffer, + bool is_writable) +{ + if (m_data == 0) + { + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + if (p_buffer == 0 + && buffer_length != 0UL) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + reset(); + + m_data->m_free_buffer = free_buffer; + m_data->m_is_writable = is_writable; + m_data->m_buffer = static_cast(p_buffer); + m_data->m_buffer_length = buffer_length; + m_data->m_real_data_start_index = 0ul; + m_data->m_real_data_length = buffer_length; + + // This cannot fail. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::set_buffer( + const eap_variable_data_c * const buffer) +{ + if (m_data == 0) + { + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (buffer == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (buffer == this) + { + // Here we are setting buffer from from itself. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + return EAP_STATUS_RETURN(m_am_tools, set_buffer( + buffer->get_data(), + buffer->get_data_length(), + false, + true)); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::set_copy_of_buffer( + const void * const buffer, + const u32_t buffer_length) +{ + if (m_data == 0) + { + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (buffer == m_data->m_buffer) + { + // Here we are copying from itself. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + if (buffer == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = init(buffer_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + set_is_valid(); + + if (buffer_length > 0u) + { + m_am_tools->memmove(m_data->m_buffer, buffer, buffer_length); + } + + set_data_length(buffer_length); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::set_copy_of_buffer( + const eap_variable_data_c * const buffer) +{ + if (m_data == 0) + { + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (buffer == 0 + || buffer->get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (buffer == this) + { + // Here we are copying from itself. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + return EAP_STATUS_RETURN(m_am_tools, set_copy_of_buffer( + buffer->get_data(), + buffer->get_data_length())); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::allocate_buffer( + const u32_t required_buffer_length) +{ + u8_t *tmp_buffer = new u8_t[required_buffer_length]; + if (tmp_buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_variable_data_c::allocate_buffer(): Cannot allocate %d bytes.\n"), + required_buffer_length)); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // This is for testing. It is better leave buffer uninitialized. + // Memory checking programs could track use of uninitialized data. + + if (m_data->m_real_data_length > 0u) + { + // Note the data is copied from start index of original buffer + // to the begin of the new buffer. + m_am_tools->memmove( + tmp_buffer, + m_data->m_buffer + m_data->m_real_data_start_index, + m_data->m_real_data_length); + } + + if (m_data->m_free_buffer == true) + { + +#if !defined(NO_EAP_VARIABLE_DATA_MEMORY_ZERO) + m_am_tools->memset(m_data->m_buffer, 0, m_data->m_buffer_length); +#endif //#if !defined(NO_EAP_VARIABLE_DATA_MEMORY_ZERO) + + delete [] m_data->m_buffer; + } + + m_data->m_buffer = tmp_buffer; + m_data->m_buffer_length = required_buffer_length; + m_data->m_real_data_start_index = 0ul; // Data is now in the begin of the new buffer. + m_data->m_free_buffer = true; + m_data->m_is_writable = true; + set_is_valid(); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::set_buffer_length( + const u32_t p_buffer_length) +{ + if (m_data == 0) + { + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + u32_t required_buffer_length = p_buffer_length; + if (required_buffer_length < 1ul) + { + required_buffer_length = 1ul; + } + + if (m_data->m_buffer_length < required_buffer_length) + { + eap_status_e status = allocate_buffer(required_buffer_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::add_data_to_offset( + const u32_t offset, + const void * const buffer, + const u32_t buffer_length) +{ + if (m_data == 0) + { + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + EAP_ASSERT_TOOLS(m_am_tools, m_data->m_is_valid == true); + + const u32_t offset_and_buffer_length = offset + buffer_length; + + u32_t required_buffer_length + = m_data->m_real_data_start_index; + + if (m_data->m_real_data_length > offset_and_buffer_length) + { + required_buffer_length + += m_data->m_real_data_length; + } + else + { + required_buffer_length + += offset_and_buffer_length; + + if (required_buffer_length == 0ul) + { + ++required_buffer_length; + } + } + + if (m_data->m_buffer_length < required_buffer_length) + { + eap_status_e status = allocate_buffer(required_buffer_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (buffer_length != 0u + && buffer != 0) + { + m_am_tools->memmove( + m_data->m_buffer + + (m_data->m_real_data_start_index + + offset), + buffer, + buffer_length); + } + + if (offset_and_buffer_length > m_data->m_real_data_length) + { + m_data->m_real_data_length = offset_and_buffer_length; + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::add_data_to_offset( + const u32_t offset, + const eap_variable_data_c * const buffer) +{ + if (get_is_valid() == false) + { + // ERROR. + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + return EAP_STATUS_RETURN(m_am_tools, add_data_to_offset( + offset, + buffer->get_data(), + buffer->get_data_length())); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::add_data( + const void * const buffer, + const u32_t buffer_length) +{ + if (get_is_valid() == false) + { + // ERROR. + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + return EAP_STATUS_RETURN( + m_am_tools, + add_data_to_offset( + get_data_length(), + buffer, + buffer_length)); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::add_data( + const eap_variable_data_c * const buffer) +{ + if (buffer == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + return EAP_STATUS_RETURN(m_am_tools, add_data( + buffer->get_data(), + buffer->get_data_length())); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::add_end_null() +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + u16_t zero(0ul); + eap_status_e status = add_data(&zero, sizeof(zero)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This removes the null from data length. + set_data_length(get_data_length() - sizeof(zero)); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_variable_data_c::init( + const u32_t length) +{ + if (m_data == 0) + { + eap_status_e status = initialize_members(); + if (status != eap_status_ok) + { + // ERROR. + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + u32_t required_buffer_length = length; + if (length == 0u) + { + required_buffer_length = 1ul; + } + + if (required_buffer_length > m_data->m_buffer_length // Too small buffer. + || m_data->m_is_writable == false) // Old buffer is read only. + { + // Must allocate a new m_buffer. + + reset(); + + m_data->m_buffer = new u8_t[required_buffer_length]; + if (m_data->m_buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_variable_data_c::init(): Cannot allocate %d bytes.\n"), + required_buffer_length)); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // This is for testing. It is better leave buffer uninitialized. + // Memory checking programs could track use of uninitialized data. + + m_data->m_free_buffer = true; + m_data->m_is_writable = true; + m_data->m_buffer_length = required_buffer_length; + } + + m_data->m_real_data_start_index = 0ul; + m_data->m_real_data_length = 0u; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * eap_variable_data_c::copy() const +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + // ERROR. + return 0; + } + + eap_variable_data_c *new_data = new eap_variable_data_c(m_am_tools); + + if (new_data == 0 + || new_data->get_is_valid() == false) + { + delete new_data; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_variable_data_c::copy(): Cannot allocate %d bytes.\n"), + sizeof(eap_variable_data_c))); + return 0; + } + + eap_status_e status = new_data->set_copy_of_buffer(this); + if (status != eap_status_ok) + { + delete new_data; + return 0; + } + + return new_data; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT i32_t eap_variable_data_c::compare_length( + const void * const data, + const u32_t data_length, + const u32_t compare_length_of_data) const +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return -1; + } + + if (get_data_length() < compare_length_of_data) + { + // Different length, cannot match. + return -1; + } + else if (data_length < compare_length_of_data) + { + // Different length, cannot match. + return 1; + } + + return m_am_tools->memcmp( + get_data(), + data, + compare_length_of_data); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT i32_t eap_variable_data_c::compare_length( + const eap_variable_data_c * const data, + const u32_t compare_length_of_data) const +{ + return compare_length( + data->get_data(), + data->get_data_length(), + compare_length_of_data); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT i32_t eap_variable_data_c::compare( + const void * const data, + const u32_t data_length) const +{ + EAP_ASSERT_TOOLS(m_am_tools, m_data != 0); + + if (m_data == 0) + { + return -1; + } + + if (get_data_length() < data_length) + { + // Different length, cannot match. + return -1; + } + else if (get_data_length() > data_length) + { + // Different length, cannot match. + return 1; + } + + return m_am_tools->memcmp( + get_data(), + data, + data_length); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT i32_t eap_variable_data_c::compare( + const eap_variable_data_c * const data) const +{ + return compare( + data->get_data(), + data->get_data_length()); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_variable_data_c::hash( + const u32_t size) const +{ + if (m_data == 0) + { + return 0ul; + } + + u32_t ihash = 0x55555555; + const u32_t length = get_data_length(); + const u8_t * const id = get_data(length); + + if (id == 0) + { + return 0ul; + } + + for(u32_t ind = 0u; ind < length; ind++) + { + ihash += static_cast(id[ind]) + static_cast((~ind) << 15); + } + + return ihash % size; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eapol_ethernet_address.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eapol_ethernet_address.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 31 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eapol_ethernet_address.h" + +eap_eth_address_c::eap_eth_address_c() +{ +} + +eap_eth_address_c::~eap_eth_address_c() +{ +} + +u8_t * eap_eth_address_c::get_address() const +{ + return const_cast(m_address); +} + +u32_t eap_eth_address_c::get_address_length() const +{ + return sizeof(m_address); +} + +void eap_eth_address_c::set_address(abs_eap_am_tools_c * const m_am_tools, u8_t * const p_address, const u32_t length) +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + EAP_ASSERT_ALWAYS(length == EAPOL_ETHERNET_ADDRESS_LENGTH); + + for (u32_t ind = 0u; ind < length; ind++) + { + m_address[ind] = p_address[ind]; + } +} + +void eap_eth_address_c::reset_address() +{ + for (u32_t ind = 0u; ind < EAPOL_ETHERNET_ADDRESS_LENGTH; ind++) + { + m_address[ind] = 0; + } +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eapol_ethernet_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eapol_ethernet_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,188 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 32 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eapol_ethernet_header.h" + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_ethernet_header_base_c::~eapol_ethernet_header_base_c() +{ +} + +// +EAP_FUNC_EXPORT eapol_ethernet_header_base_c::eapol_ethernet_header_base_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT u8_t * eapol_ethernet_header_base_c::get_destination() const +{ + return (get_header_offset(m_destination_offset, EAPOL_ETHERNET_ADDRESS_LENGTH)); +} + +EAP_FUNC_EXPORT u8_t * eapol_ethernet_header_base_c::get_source() const +{ + return (get_header_offset(m_source_offset, EAPOL_ETHERNET_ADDRESS_LENGTH)); +} + +EAP_FUNC_EXPORT u32_t eapol_ethernet_header_base_c::get_destination_length() const +{ + return EAPOL_ETHERNET_ADDRESS_LENGTH; +} + +EAP_FUNC_EXPORT u32_t eapol_ethernet_header_base_c::get_source_length() const +{ + return EAPOL_ETHERNET_ADDRESS_LENGTH; +} + +EAP_FUNC_EXPORT u16_t eapol_ethernet_header_base_c::get_type() const +{ + const u8_t * const type_data = get_header_offset(m_type_offset, sizeof(u16_t)); + if (type_data != 0) + { + return eap_read_u16_t_network_order(type_data, sizeof(u16_t)); + } + else + { + return 0; + } +} + +EAP_FUNC_EXPORT u8_t * eapol_ethernet_header_base_c::get_data(const u32_t data_length) const +{ + return get_header_offset(m_data_offset, data_length); +} + +EAP_FUNC_EXPORT u32_t eapol_ethernet_header_base_c::get_data_length() const +{ + return get_header_buffer_length()-get_header_length(); +} + +EAP_FUNC_EXPORT u16_t eapol_ethernet_header_base_c::get_header_length() +{ + return m_data_offset; +} + +EAP_FUNC_EXPORT void eapol_ethernet_header_base_c::set_type(const eapol_ethernet_type_e type) +{ + u8_t * const type_data = get_header_offset(m_type_offset, sizeof(u16_t)); + EAP_ASSERT(type_data != 0); + type_data[0] = static_cast((type & 0xff00) >> 8); + type_data[1] = static_cast(type & 0x00ff); +} + +EAP_FUNC_EXPORT eap_status_e eapol_ethernet_header_base_c::check_header() const +{ + if (get_type() != eapol_ethernet_type_pae + && get_type() != eapol_ethernet_type_preauthentication) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_ethernet_header_rd_c::~eapol_ethernet_header_rd_c() +{ +} + +// +EAP_FUNC_EXPORT eapol_ethernet_header_rd_c::eapol_ethernet_header_rd_c( + abs_eap_am_tools_c * const tools, + const u8_t * const header_buffer, + const u32_t header_buffer_length) + : eapol_ethernet_header_base_c(tools, const_cast(header_buffer), header_buffer_length) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT u8_t * eapol_ethernet_header_rd_c::get_eapol_header() const +{ + return eapol_ethernet_header_base_c::get_data(eapol_header_base_c::get_header_length()); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_ethernet_header_wr_c::~eapol_ethernet_header_wr_c() +{ +} + +// +EAP_FUNC_EXPORT eapol_ethernet_header_wr_c::eapol_ethernet_header_wr_c( + abs_eap_am_tools_c * const tools, + const u8_t * const header_buffer, + const u32_t header_buffer_length) + : eapol_ethernet_header_base_c(tools, const_cast(header_buffer), header_buffer_length) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT u8_t * eapol_ethernet_header_wr_c::get_eapol_header() const +{ + return eapol_ethernet_header_base_c::get_data(eapol_header_base_c::get_header_length()); +} + +EAP_FUNC_EXPORT u8_t * eapol_ethernet_header_wr_c::get_destination() +{ + return eapol_ethernet_header_base_c::get_destination(); +} + +EAP_FUNC_EXPORT u8_t * eapol_ethernet_header_wr_c::get_source() +{ + return eapol_ethernet_header_base_c::get_source(); +} + +EAP_FUNC_EXPORT void eapol_ethernet_header_wr_c::reset_header(const eapol_ethernet_type_e type, const u16_t buffer_length) +{ + EAP_UNREFERENCED_PARAMETER(buffer_length); // <-- in release version + m_am_tools->memset(get_destination(), 0, EAPOL_ETHERNET_ADDRESS_LENGTH); + m_am_tools->memset(get_source(), 0, EAPOL_ETHERNET_ADDRESS_LENGTH); + + set_type(type); + + EAP_ASSERT(buffer_length >= get_header_length()+eapol_header_wr_c::get_header_length()); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eapol_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eapol_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,244 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 33 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eapol_header.h" + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_header_base_c::~eapol_header_base_c() +{ +} + +// +EAP_FUNC_EXPORT eapol_header_base_c::eapol_header_base_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT eapol_protocol_version_e eapol_header_base_c::get_version() const +{ + const u8_t * const version_data = get_header_offset(m_version_offset, sizeof(u8_t)); + if (version_data != 0) + { + return static_cast(*version_data); + } + else + { + return eapol_protocol_version_none; + } +} + +EAP_FUNC_EXPORT eapol_packet_type_e eapol_header_base_c::get_packet_type() const +{ + const u8_t * const type_data = get_header_offset(m_packet_type_offset, sizeof(u8_t)); + if (type_data != 0) + { + return static_cast(*type_data); + } + else + { + return eapol_packet_type_no_type; + } +} + +EAP_FUNC_EXPORT u16_t eapol_header_base_c::get_data_length() const +{ + const u8_t * const length_data = get_header_offset(m_data_length_offset, sizeof(u16_t)); + if (length_data != 0) + { + return eap_read_u16_t_network_order(length_data, sizeof(u16_t)); + } + else + { + return 0ul; + } +} + +EAP_FUNC_EXPORT u32_t eapol_header_base_c::get_header_length() +{ + return m_data_offset; +} + +EAP_FUNC_EXPORT u8_t * eapol_header_base_c::get_data(const u32_t data_length) const +{ + return get_header_offset(m_data_offset, data_length); // Data begins after the header. +} + +EAP_FUNC_EXPORT void eapol_header_base_c::set_version(const eapol_protocol_version_e p_version) +{ + u8_t * const version_data = get_header_offset(m_version_offset, sizeof(u8_t)); + EAP_ASSERT(version_data != 0); + *version_data = static_cast(p_version); +} + +EAP_FUNC_EXPORT void eapol_header_base_c::set_packet_type(const eapol_packet_type_e p_packet_type) +{ + u8_t * const type_data = get_header_offset(m_packet_type_offset, sizeof(u8_t)); + EAP_ASSERT(type_data != 0); + *type_data = static_cast(p_packet_type); +} + +EAP_FUNC_EXPORT void eapol_header_base_c::set_data_length(const u16_t p_data_length) +{ + u8_t * const data_length = get_header_offset(m_data_length_offset, sizeof(u16_t)); + EAP_ASSERT(data_length != 0); + data_length[0] = static_cast((p_data_length & 0xff00) >> 8); + data_length[1] = static_cast(p_data_length & 0x00ff); +} + +EAP_FUNC_EXPORT eap_const_string eapol_header_base_c::get_type_string() const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + eapol_packet_type_e type = get_packet_type(); + + EAP_IF_RETURN_STRING(type, eapol_packet_type_eap) + else EAP_IF_RETURN_STRING(type, eapol_packet_type_start) + else EAP_IF_RETURN_STRING(type, eapol_packet_type_logoff) + else EAP_IF_RETURN_STRING(type, eapol_packet_type_key) + else EAP_IF_RETURN_STRING(type, eapol_packet_type_enc_asf_alert) + else EAP_IF_RETURN_STRING(type, eapol_packet_type_SAE_KE) + else EAP_IF_RETURN_STRING(type, eapol_packet_type_SAE_EAP) + else EAP_IF_RETURN_STRING(type, eapol_packet_type_SAE_START) + else EAP_IF_RETURN_STRING(type, eapol_packet_type_SAE_LOGOFF) + else EAP_IF_RETURN_STRING(type, eapol_packet_type_no_type) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown EAPOL-type"); + } +} + +EAP_FUNC_EXPORT eap_status_e eapol_header_base_c::check_header() const +{ + eap_status_e status = eap_status_process_general_error; + + if (get_version() == eapol_protocol_version_none) + { + status = eap_status_wrong_eapol_version; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_header_base_c::check_header(), illegal version field 0x%02x, at least 0x%02x was expected, eap_status_e %d\n"), + get_version(), + eapol_protocol_version_none+1, + status)); + } + else if (/* get_packet_type() < eapol_packet_type_eap // This is always false. + || */ + eapol_packet_type_SAE_LOGOFF < get_packet_type()) + { + status = eap_status_wrong_eapol_type; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_header_base_c::check_header(), illegal type field 0x%02x, eap_status_e %d\n"), + get_packet_type(), status)); + } + else + { + status = eap_status_ok; + } + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_header_rd_c::~eapol_header_rd_c() +{ +} + +// +EAP_FUNC_EXPORT eapol_header_rd_c::eapol_header_rd_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length) + : eapol_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT u8_t * eapol_header_rd_c::get_eap_header() const +{ + return get_data(eap_header_base_c::get_header_length()); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_header_wr_c::~eapol_header_wr_c() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_header_wr_c::eapol_header_wr_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length) + : eapol_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eapol_header_wr_c::get_eap_header() +{ + return get_data(eap_header_base_c::get_header_length()); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eapol_header_wr_c::reset_header(u16_t buffer_length) +{ + set_version(eapol_protocol_version_none); + set_packet_type(eapol_packet_type_eap); + EAP_ASSERT(buffer_length >= get_header_length()); + set_data_length(static_cast(buffer_length-get_header_length())); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/eapol_session_key.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/eapol_session_key.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,198 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 34 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eapol_session_key.h" +#include "eap_tools.h" + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_session_key_c::~eapol_session_key_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_session_key_c::eapol_session_key_c( + abs_eap_am_tools_c * const tools, + eap_variable_data_c * const key, ///< Here is the key. + const eapol_key_type_e key_type, ///< This the type of the key. + const u32_t key_index, ///< This is the index of the key. + const bool key_tx_bit, ///< This is the TX bit of the key. + const u8_t * const key_RSC, ///< This is the RSC counter + const u32_t key_RSC_size ///< This is the size of RSC counter + ) + : m_am_tools(tools) + , m_key(tools) + , m_sequence_number(tools) + , m_key_type(key_type) + , m_key_index(key_index) + , m_key_tx_bit(key_tx_bit) + , m_is_valid(false) +{ + eap_status_e status = m_key.set_copy_of_buffer(key); + if (status != eap_status_ok) + { + return; + } + + if (key_RSC != 0 + && key_RSC_size > 0ul) + { + status = m_sequence_number.set_copy_of_buffer( + key_RSC, + key_RSC_size); + if (status != eap_status_ok) + { + return; + } + } + + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_session_key_c::eapol_session_key_c( + abs_eap_am_tools_c * const tools + ) + : m_am_tools(tools) + , m_key(tools) + , m_sequence_number(tools) + , m_key_type(eapol_key_type_last_type) + , m_key_index(0ul) + , m_key_tx_bit(false) + , m_is_valid(true) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_variable_data_c * eapol_session_key_c::get_key() const +{ + return &m_key; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_variable_data_c * eapol_session_key_c::get_sequence_number() const +{ + return &m_sequence_number; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_key_type_e eapol_session_key_c::get_key_type() const +{ + return m_key_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eapol_session_key_c::get_key_index() const +{ + return m_key_index; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eapol_session_key_c::get_key_tx_bit() const +{ + return m_key_tx_bit; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eapol_session_key_c::get_is_valid() const +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_session_key_c::set_key(const eap_variable_data_c * const key) +{ + return m_key.set_copy_of_buffer(key); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_session_key_c::set_sequence_number(eap_variable_data_c * const sequence_number) +{ + return m_sequence_number.set_copy_of_buffer(sequence_number); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eapol_session_key_c::set_key_type(const eapol_key_type_e key_type) +{ + m_key_type = key_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eapol_session_key_c::set_key_index(const u32_t key_index) +{ + m_key_index = key_index; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eapol_session_key_c::set_key_tx_bit(const bool key_tx_bit) +{ + m_key_tx_bit = key_tx_bit; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eapol_session_key_c::get_eapol_key_type_string( + const eapol_key_type_e key_type) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(key_type, eapol_key_type_broadcast) + else EAP_IF_RETURN_STRING(key_type, eapol_key_type_unicast) +#if defined(EAP_USE_WPXM) + else EAP_IF_RETURN_STRING(key_type, eapol_key_type_wpxm_wpxk1) + else EAP_IF_RETURN_STRING(key_type, eapol_key_type_wpxm_wpxk2) +#endif //#if defined(EAP_USE_WPXM) + else EAP_IF_RETURN_STRING(key_type, eapol_key_type_pmkid) + else EAP_IF_RETURN_STRING(key_type, eapol_key_type_last_type) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(key_type); + + return EAPL("Unknown EAPOL-Key type"); + } +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/common/wlan_eap_if_send_status.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/common/wlan_eap_if_send_status.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#include "eap_am_export.h" +#include "eap_am_types.h" +#include "eap_status.h" +#include "wlan_eap_if_send_status.h" + +/** @file */ + +EAP_FUNC_EXPORT_INTERFACE wlan_eap_if_send_status_e wlan_eap_if_send_status_conversion_c::convert(const eap_status_e status) +{ + switch(status) + { + case eap_status_ok: + return wlan_eap_if_send_status_ok; + case eap_status_pending_request: + return wlan_eap_if_send_status_pending_request; + case eap_status_allocation_error: + return wlan_eap_if_send_status_allocation_error; + case eap_status_illegal_parameter: + return wlan_eap_if_send_status_illegal_parameter; + case eap_status_not_found: + return wlan_eap_if_send_status_not_found; + case eap_status_success: + return wlan_eap_if_send_status_success; + case eap_status_drop_packet_quietly: + return wlan_eap_if_send_status_drop_packet_quietly; + default: + return wlan_eap_if_send_status_process_general_error; + } +} + +EAP_FUNC_EXPORT_INTERFACE eap_status_e wlan_eap_if_send_status_conversion_c::convert(const wlan_eap_if_send_status_e status) +{ + switch(status) + { + case wlan_eap_if_send_status_ok: + return eap_status_ok; + case wlan_eap_if_send_status_pending_request: + return eap_status_pending_request; + case wlan_eap_if_send_status_allocation_error: + return eap_status_allocation_error; + case wlan_eap_if_send_status_illegal_parameter: + return eap_status_illegal_parameter; + case wlan_eap_if_send_status_not_found: + return eap_status_not_found; + case wlan_eap_if_send_status_success: + return eap_status_success; + case wlan_eap_if_send_status_drop_packet_quietly: + return eap_status_drop_packet_quietly; + default: + return eap_status_process_general_error; + } +} + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eap_config.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eap_config.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 43 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_am_assert.h" +#include "eap_variable_data.h" +#include "eap_tools.h" +#include "eap_config.h" + + + + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eap_core.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eap_core.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,5542 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 44 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_core.h" +#include "eap_core_nak_info.h" +#include "eap_state_notification.h" +#include "eap_network_id_selector.h" +#include "eap_buffer.h" +#include "eap_header_string.h" +#include "eap_automatic_variable.h" + + +/** + * This is the character that separates routing realms. + */ +const u8_t EAP_NAI_ROUTING_REALM_SEPARATOR[] = "!"; + +/** + * This is the at character of NAI. + */ +const u8_t EAP_NAI_AT_CHARACTER[] = "@"; + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_core_c::~eap_core_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::~eap_core_c(): %s, %s, this = 0x%08x => 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + this, + dynamic_cast(this))); + + EAP_ASSERT(m_shutdown_was_called == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +// +EAP_FUNC_EXPORT eap_core_c::eap_core_c( + abs_eap_am_tools_c * const tools, + abs_eap_core_c * const partner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + const bool is_tunneled_eap) + : m_partner(partner) + , m_am_tools(tools) + , m_type_map(tools, this) + , m_current_eap_type(eap_type_none) + , m_default_eap_type(eap_type_none) + , m_eap_identity(tools) + , m_eap_header_offset(0u) + , m_MTU(0u) + , m_trailer_length(0u) + , m_receive_network_id(tools) + , m_retransmission(0) + , m_retransmission_time(EAP_CORE_RETRANSMISSION_TIME) + , m_retransmission_counter(EAP_CORE_RETRANSMISSION_COUNTER) + , m_session_timeout(EAP_CORE_SESSION_TIMEOUT) + , m_eap_core_failure_received_timeout(EAP_CORE_FAILURE_RECEIVED_TIMEOUT) + , m_remove_session_timeout(EAP_CORE_REMOVE_SESSION_TIMEOUT) +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + , m_wait_eap_request_type_timeout(EAP_CORE_WAIT_EAP_REQUEST_TYPE_TIMEOUT) + , m_wait_eap_request_type_timeout_set(false) +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + , m_eap_identity_request_identifier_client(0) + , m_is_client(is_client_when_true) + , m_is_client_role(is_client_when_true) + , m_is_valid(false) + , m_client_restart_authentication_initiated(false) + , m_marked_removed(false) + , m_eap_identity_response_accepted(false) + , m_shutdown_was_called(false) + , m_eap_type_response_sent(false) + , m_is_tunneled_eap(is_tunneled_eap) +#if defined(USE_EAP_CORE_SERVER) + , m_process_eap_nak_immediately(EAP_CORE_PROCESS_EAP_NAK_IMMEDIATELY) + , m_nak_process_timer_active(false) + , m_eap_identity_request_send(false) + , m_eap_identity_response_received(false) + , m_eap_failure_sent(false) + , m_send_eap_success_after_notification(false) +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + , m_skip_eap_request_identity(false) +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) +#endif //#if defined(USE_EAP_CORE_SERVER) + , m_use_eap_expanded_type(false) + , m_ignore_eap_failure(false) + , m_ignore_notifications(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::eap_core_c(): %s, %s, this = 0x%08x => 0x%08x, compiled %s %s.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + this, + dynamic_cast(this), + __DATE__, + __TIME__)); + + eap_status_e status = m_receive_network_id.set_copy_of_network_id(receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT abs_eap_core_c * eap_core_c::get_partner() +{ + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + return m_partner; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_core_c::set_partner(abs_eap_core_c * const partner) +{ + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + m_partner = partner; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_core_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_core_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_core_c::object_increase_reference_count() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_core_c::object_decrease_reference_count() +{ + return 0u; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_core_c::get_marked_removed() +{ + return m_marked_removed; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_core_c::set_marked_removed() +{ + m_marked_removed = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_core_c::unset_marked_removed() +{ + m_marked_removed = false; +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_core_c::ignore_notifications() +{ + m_ignore_notifications = true; +} + +//-------------------------------------------------- + +// +eap_status_e eap_core_c::initialize_asynchronous_init_remove_eap_session( + const u32_t remove_session_timeout) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::initialize_asynchronous_init_remove_eap_session(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = eap_status_process_general_error; + + + if (m_is_client_role == false) + { + // Server stops re-transmissions. + // Client can re-transmit until session is removed. + cancel_retransmission(); + } + + cancel_eap_failure_timeout(); + + cancel_session_timeout(); + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + if (m_is_tunneled_eap == false + && m_is_client_role == true) + { + cancel_wait_eap_request_type_timeout(); + } +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + set_marked_removed(); + + + if (remove_session_timeout == 0ul) + { + status = asynchronous_init_remove_eap_session(); + } + else + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + cancel_asynchronous_init_remove_eap_session(); + + status = m_partner->set_timer( + this, + EAP_CORE_REMOVE_SESSION_TIMEOUT_ID, + 0, + remove_session_timeout); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_REMOVE_SESSION_TIMEOUT_ID set %d ms, this = 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + remove_session_timeout, + this)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_core_c::cancel_asynchronous_init_remove_eap_session() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_partner != 0) + { + eap_status_e status = m_partner->cancel_timer( + this, + EAP_CORE_REMOVE_SESSION_TIMEOUT_ID); + + EAP_UNREFERENCED_PARAMETER(status); // in release + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_REMOVE_SESSION_TIMEOUT_ID cancelled status %d, this = 0x%08x.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + status, + this)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +eap_status_e eap_core_c::asynchronous_init_remove_eap_session() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::asynchronous_init_remove_eap_session(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_am_network_id_c send_network_id( + m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + eap_status_e status = m_partner->asynchronous_init_remove_eap_session( + &send_network_id); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eap_core_c::init_end_of_session( + const abs_eap_state_notification_c * const state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::init_end_of_session(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status(eap_status_process_general_error); + + // Normally we will remove session after authentication ends. + // Remove session only if the stack is not already being deleted + if (m_shutdown_was_called == false) + { + #if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAP_CORE_RESTART_AUTHENTICATION) + #error ERROR: USE_EAPOL_KEY_STATE and USE_EAP_CORE_RESTART_AUTHENTICATION cannot be used same time. + #endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAP_CORE_RESTART_AUTHENTICATION) + + #if defined(USE_EAP_CORE_SIMULATOR_VERSION) && defined(USE_EAP_CORE_RESTART_AUTHENTICATION) + + // Simulator reuses current session. + status = restart_authentication( + state->get_send_network_id(), + m_is_client); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + #elif defined(USE_EAP_CORE_SIMULATOR_VERSION) && defined(USE_EAPOL_KEY_STATE) + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::state_notification(): %s, %s, Ignored notification: ") + EAPL("Protocol layer %d, EAP type 0x%02x, State transition from ") + EAPL("%d=%s to %d=%s, client %d.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + state->get_protocol_layer(), + state->get_protocol(), + state->get_previous_state(), + state->get_previous_state_string(), + state->get_current_state(), + state->get_current_state_string(), + state->get_is_client())); + + #endif //#if defined(USE_EAP_CORE_SIMULATOR_VERSION) + + status = initialize_asynchronous_init_remove_eap_session(m_remove_session_timeout); + if (status != eap_status_ok) + { + EAP_UNREFERENCED_PARAMETER(state); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::state_notification(): %s, %s, Ignored notification: ") + EAPL("Protocol layer %d, EAP type 0x%02x, State transition from ") + EAPL("%d=%s to %d=%s, client %d when shutdown was called.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + state->get_protocol_layer(), + state->get_protocol(), + state->get_previous_state(), + state->get_previous_state_string(), + state->get_current_state(), + state->get_current_state_string(), + state->get_is_client())); + + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_core_c::state_notification( + const abs_eap_state_notification_c * const state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_string_c status_string; + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(status_string); // in release + EAP_UNREFERENCED_PARAMETER(eap_string); // in release + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::state_notification(), %s, %s, protocol_layer %d=%s, protocol %d=%s, EAP-type 0x%08x=%s.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + state->get_protocol_layer(), + state->get_protocol_layer_string(), + state->get_protocol(), + state->get_protocol_string(), + convert_eap_type_to_u32_t(state->get_eap_type()), + eap_string.get_eap_type_string(state->get_eap_type()))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::state_notification(), %s, %s, current_state %d=%s, error %d=%s.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + state->get_current_state(), + state->get_current_state_string(), + state->get_authentication_error(), + status_string.get_status_string(state->get_authentication_error()))); + + if (m_ignore_notifications == true + || m_partner == 0) + { + return; + } + + // Check if the notification is from the current active type + if (state->get_protocol_layer() == eap_protocol_layer_general) + { + // These notications are allowed always. + } + else if (state->get_protocol_layer() == eap_protocol_layer_eap + && state->get_eap_type() != m_current_eap_type) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::state_notification(): %s, %s, Ignored notification: ") + EAPL("Protocol layer %d, non-active EAP type 0x%02x, current EAP type 0x%08x, State transition from ") + EAPL("%d=%s to %d=%s, client %d\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + state->get_protocol_layer(), + state->get_protocol(), + convert_eap_type_to_u32_t(m_current_eap_type), + state->get_previous_state(), + state->get_previous_state_string(), + state->get_current_state(), + state->get_current_state_string(), + state->get_is_client())); + return; + } + + if (state->get_protocol_layer() == eap_protocol_layer_eap) + { + if (state->get_current_state() == eap_state_identity_response_received) + { + m_eap_identity_response_accepted = true; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-Response/Identity received: %s, %s\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + } + else if (state->get_current_state() == eap_state_identity_request_received) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-Request/Identity received: %s, %s\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + } + else if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eap_core_c::state_notification(): %s, %s: EAP-authentication terminated unsuccessfully.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + +#if defined(USE_EAP_CORE_SERVER) + if (m_is_client == false + && (m_eap_type_response_sent == true + || m_eap_identity_response_received == true) + && m_send_eap_success_after_notification == false) + { + /** + * 2003-10-01 draft-ietf-eap-rfc2284bis-06.txt chapter 2. + * Extensible Authentication Protocol (EAP): + * The authenticator MUST NOT send a Success or Failure packet when retransmitting + * or when it fails to get a response from the peer. + * In the case eap_state_authentication_terminated_unsuccessfully we will need a flag + * that indicates whether there was a response from client or not. + * If there was a response server must send EAP-Failure. + * If there was NO response from client server + * does NOT send EAP-Failure. + */ + send_eap_failure( + state->get_send_network_id(), + state->get_eap_identifier()); + } +#endif //#if defined(USE_EAP_CORE_SERVER) + + (void) init_end_of_session(state); + } + else if (state->get_current_state() == eap_state_authentication_finished_successfully) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::state_notification(): %s, %s: EAP-authentication finished successfully.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + +#if defined(USE_EAP_CORE_SERVER) + if (m_is_client == false + && m_eap_type_response_sent == true + && m_send_eap_success_after_notification == false) + { + // Here we test whether the EAP-type allow send EAP-Success. + // For example PEAP v1 does not allow send EAP-Success. + if (state->get_allow_send_eap_success() == true) + { + send_eap_success( + state->get_send_network_id(), + state->get_eap_identifier()); + } + + // Now we can send a new EAP-Request/Identity. + m_eap_identity_request_send = false; + } +#endif //#if defined(USE_EAP_CORE_SERVER) + + (void) init_end_of_session(state); + } + else if (m_is_client == true + && state->get_current_state() == eap_state_use_eap_failure_in_termination) + { + // Client should accept EAP-Failure quietly. + m_ignore_eap_failure = true; + + (void) init_end_of_session(state); + } +#if defined(USE_EAP_CORE_SERVER) + else if (m_is_client == false + && state->get_current_state() == eap_state_use_eap_failure_in_termination) + { + send_eap_failure( + state->get_send_network_id(), + state->get_eap_identifier()); + + (void) init_end_of_session(state); + } + else if (m_current_eap_type == eap_type_peap + && state->get_current_state() == eap_state_authentication_wait_tppd_peapv1_empty_acknowledge) + { + send_eap_success( + state->get_send_network_id(), + state->get_eap_identifier()); + + return; + } +#endif //#if defined(USE_EAP_CORE_SERVER) + } + + + m_partner->state_notification(state); + + +#if defined(USE_EAP_CORE_SERVER) + // EAP-Success is send after the success notification is forwarded to lower layer. + // This allows to combine success notification and sent EAP-success packet. + if (state->get_current_state() == eap_state_authentication_finished_successfully) + { + if (m_is_client == false + && m_eap_type_response_sent == true + && m_send_eap_success_after_notification == true) + { + // Here we test whether the EAP-type allow send EAP-Success. + // For example PEAP v1 does not allow send EAP-Success. + if (state->get_allow_send_eap_success() == true) + { + send_eap_success( + state->get_send_network_id(), + state->get_eap_identifier()); + } + + // Now we can send a new EAP-Request/Identity. + m_eap_identity_request_send = false; + } + } + else if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully) + { + if (m_is_client == false + && (m_eap_type_response_sent == true + || m_eap_identity_response_received == true) + && m_send_eap_success_after_notification == true) + { + /** + * 2003-10-01 draft-ietf-eap-rfc2284bis-06.txt chapter 2. + * Extensible Authentication Protocol (EAP): + * The authenticator MUST NOT send a Success or Failure packet when retransmitting + * or when it fails to get a response from the peer. + * In the case eap_state_authentication_terminated_unsuccessfully we will need a flag + * that indicates whether there was a response from client or not. + * If there was a response server must send EAP-Failure. + * If there was NO response from client server + * does NOT send EAP-Failure. + */ + send_eap_failure( + state->get_send_network_id(), + state->get_eap_identifier()); + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_base_type_c * eap_core_c::load_type( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_base_type_c *handler = 0; + + eap_status_e status = m_partner->load_module( + type, + tunneling_type, + this, + &handler, + m_is_client, + receive_network_id); + if (status != eap_status_ok) + { + if (handler != 0) + { + handler->shutdown(); + delete handler; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return handler; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::check_is_valid_eap_type(const eap_type_value_e eap_type) +{ + eap_status_e status = m_partner->check_is_valid_eap_type(eap_type); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + eap_status_e status = m_partner->get_eap_type_list(eap_type_list); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::initialize_session_timeout(const u32_t session_timeout_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + cancel_session_timeout(); + + eap_status_e status = m_partner->set_timer( + this, + EAP_CORE_SESSION_TIMEOUT_ID, + 0, + session_timeout_ms); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_SESSION_TIMEOUT_ID set %d ms, this = 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + session_timeout_ms, + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::cancel_session_timeout() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_partner->cancel_timer( + this, + EAP_CORE_SESSION_TIMEOUT_ID); + + EAP_UNREFERENCED_PARAMETER(status); // in release + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_SESSION_TIMEOUT_ID cancelled status %d, this = 0x%08x.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + status, + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_core_c::trace_eap_packet( + eap_const_string prefix, + const eap_header_wr_c * const eap_header) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Get rid of warnings in release version + EAP_UNREFERENCED_PARAMETER(eap_header); + EAP_UNREFERENCED_PARAMETER(prefix); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s EAP_Core: %s, %s, code=0x%02x=%s, identifier=0x%02x, length=0x%04x, type=0x%08x=%s, packet length 0x%04x\n"), + prefix, + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + eap_header->get_code(), + eap_header->get_code_string(), + eap_header->get_identifier(), + eap_header->get_length(), + convert_eap_type_to_u32_t(eap_header->get_type()), + eap_header->get_type_string(), + eap_header->get_length())); +} + + +//-------------------------------------------------- + +#if defined(USE_EAP_CORE_SERVER) + +EAP_FUNC_EXPORT eap_status_e eap_core_c::restart_with_new_type( + const eap_type_value_e used_eap_type, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::restart_with_new_type(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::restart_with_new_type()"); + + // Here we need to re-create the received EAP-Response/Identity message. + + if (m_eap_identity.get_is_valid_data() == false) + { + // No saved EAP-Identity. Cannot continue. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + eap_status_e status = eap_status_process_general_error; + + eap_buf_chain_wr_c response_packet( + eap_write_buffer, + m_am_tools, + EAP_CORE_PACKET_BUFFER_LENGTH); + + if (response_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted: %s, %s\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = create_eap_identity_response( + &response_packet, + &m_eap_identity, + eap_identifier); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_header_wr_c eap( + m_am_tools, + response_packet.get_data_offset(m_eap_header_offset, response_packet.get_data_length()), + response_packet.get_data_length()); + if (eap.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Bacause we start with a new EAP-type EAP-Response/Identity is prosessed again. + m_eap_identity_response_accepted = false; + + m_ignore_eap_failure = false; + + status = packet_process_type( + used_eap_type, + receive_network_id, + &eap, + eap.get_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_CORE_SERVER) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::client_proposes_eap_types( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier) +{ + eap_array_c eap_type_list(m_am_tools); + + /** + * @{ 2005-04-19 complete Expanded Nak Type to client_proposes_eap_types(). } + */ + eap_status_e status = get_eap_type_list(&eap_type_list); + if (status != eap_status_ok) + { + eap_type_list.reset(); + + eap_type_value_e * default_eap_type = new eap_type_value_e(m_default_eap_type); + if (default_eap_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_type_list.add_object(default_eap_type, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = send_eap_nak_response( + receive_network_id, + eap_identifier, + &eap_type_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::packet_process_type( + const eap_type_value_e used_eap_type, + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::packet_process_type(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::packet_process_type()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (packet_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (packet_length < eap_header_base_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_header_wr_c eap( + m_am_tools, + packet_data->get_header_buffer(packet_data->get_header_buffer_length()), + packet_data->get_header_buffer_length()); + + if (eap.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (packet_length < eap.get_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if (eap.get_code() == eap_code_none) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_TEST_VECTORS, + (EAPL("--------------------------------------------------------\n"))); + + eap_status_e status = eap.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + + status = eap_status_process_general_error; + + if (m_eap_type_response_sent == false + && m_current_eap_type != used_eap_type) + { + status = check_is_valid_eap_type(used_eap_type); + if (status != eap_status_ok) + { + if (m_is_client_role == true) + { + // Client does not accept proposed EAP type. + // We must send EAP-Response/Nak message with list of our own preferred EAP-Types. + status = client_proposes_eap_types( + receive_network_id, + eap.get_identifier()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not acceptable EAP-type in the server. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // Now the current EAP-type is used_eap_type. + + // First remove current EAP-type. + eap_variable_data_c selector(m_am_tools); + status = selector.set_copy_of_buffer(&m_current_eap_type, sizeof(m_current_eap_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + eap_base_type_c *handler = m_type_map.get_handler(&selector); + + // Change the current EAP-type here because shutdown could cause state notifications from old EAP-type. + m_current_eap_type = used_eap_type; + + if (handler != 0) + { + status = handler->shutdown(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_type_map.remove_handler(&selector, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + // Here we query the desired EAP-type. + eap_variable_data_c selector(m_am_tools); + u64_t selector_eap_type = convert_eap_type_to_u64_t(used_eap_type); + status = selector.set_buffer(&selector_eap_type, sizeof(selector_eap_type), false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + eap_base_type_c *handler = m_type_map.get_handler(&selector); + + // Check if we already have this type loaded. + if (handler == 0) + { + // No. Load it. + if (m_eap_type_response_sent == false + && eap.get_type() != eap_type_identity + && (eap.get_code() == eap_code_request + || eap.get_code() == eap_code_response)) + { + // Here we need a check that proposed EAP type is valid for us. + status = check_is_valid_eap_type(used_eap_type); + if (status != eap_status_ok) + { + if (m_is_client_role == true) + { + // Client does not accept proposed EAP type. + // We must send EAP-Response/Nak message with list of our own preferred EAP-Types. + status = client_proposes_eap_types( + receive_network_id, + eap.get_identifier()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not acceptable EAP-type in the server. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + // Change the current eap type. + m_current_eap_type = used_eap_type; + } + else if (eap.get_code() == eap_code_success + || eap.get_code() == eap_code_failure) + { + // EAP-Success or EAP-Failure is not allowed at this state. + // This packet is dropped quietly. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_core_c::packet_process_type(): %s, %s, drops %s quietly.\n"), + (m_is_client_role == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + eap.get_code_string() + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (m_eap_type_response_sent == false + && eap.get_type() == eap_type_identity + && (eap.get_code() == eap_code_request + || eap.get_code() == eap_code_response)) + { + // EAP-Request/Identity is allowed at this state. + EAP_ASSERT(used_eap_type != eap_type_none); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); + } + + // A new EAP-type is needed. The load_type() allocates new object. + handler = load_type( + used_eap_type, + eap_type_none, + receive_network_id); + if (handler != 0 + && handler->get_is_valid() == true) + { + status = handler->configure(); + if (status != eap_status_ok) + { + handler->shutdown(); + delete handler; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_type_map.add_handler(&selector, handler); + if (status != eap_status_ok) + { + handler->shutdown(); + delete handler; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + if (handler != 0) + { + // Handler not constructed successfully. + handler->shutdown(); + delete handler; + status = eap_status_allocation_error; + } + else + { + status = eap_status_type_does_not_exists_error; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + +#if defined(USE_EAP_CORE_SERVER) + // We now have handler. Process packet + if (m_nak_process_timer_active == true) + { + m_partner->cancel_timer( + this, + EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID cancelled, this = 0x%08x.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + this)); + + m_nak_process_timer_active = false; + } +#endif //#if defined(USE_EAP_CORE_SERVER) + + + if (m_is_client_role == true + && eap.get_code() == eap_code_request + && (eap.get_type() == eap_type_identity + || eap.get_type() == eap_type_notification)) + { + // Client handles this packet, which is EAP-Request/Identity or EAP-Request/Notification. + + if (eap.get_type() == eap_type_identity) + { + status = handle_eap_identity_request( + used_eap_type, + eap.get_identifier(), + receive_network_id); + } + else if (eap.get_type() == eap_type_notification) + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + /** + * @{ 2003-10-02 draft-ietf-eap-rfc2284bis-06.txt chapter 5.2 Notification: + * The peer SHOULD display this message to the user or log it if it + * cannot be displayed. The Notification Type is intended to provide + * an acknowledged notification of some imperative nature, but it is + * not an error indication, and therefore does not change the state + * of the peer. Examples include a password with an expiration time + * that is about to expire, an OTP sequence integer which is nearing + * 0, an authentication failure warning, etc. In most circumstances, + * Notification should not be required. + * } + */ + status = send_eap_notification_response( + &send_network_id, + eap.get_identifier()); + } + } +#if defined(USE_EAP_CORE_SERVER) + else if (m_is_client_role == false + && eap.get_code() == eap_code_response + && eap.get_type() == eap_type_identity) + { + // Server handles this EAP-Response/Identity packet. + + if (m_eap_identity_response_accepted == false) + { + m_eap_identity_response_received = true; + + status = handle_eap_identity_response( + handler, + used_eap_type, + receive_network_id, + &eap, + packet_length); + + EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eap); + } + else + { + // Do not accept multiple EAP-Response/Identity messages. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAP_Core: %s,%s, packet dropped quietly. m_eap_type_response_sent %d, ") + EAPL("EAP-Type 0x%08x, m_current_eap_type 0x%08x\n"), + (m_is_client_role == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + m_eap_type_response_sent, + convert_eap_type_to_u32_t(eap.get_type()), + convert_eap_type_to_u32_t(m_current_eap_type))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + else if ((eap.get_code() == eap_code_request + || eap.get_code() == eap_code_response) + && eap.get_type() == used_eap_type + || eap.get_code() == eap_code_success + || eap.get_code() == eap_code_failure) + { + // Client and server handles this packet. + // Packet is EAP-Request, EAP-Response, EAP-Success or EAP-Failure. + // EAP-Request and EAP-Response must be of the used EAP-type. + + if (m_is_client_role == false) + { + // Server received EAP-Response from client. + // Now server could send EAP-Failure or EAP-success to client. + // See draft-ietf-eap-rfc2284bis-06.txt chapter 2. Extensible Authentication Protocol (EAP). + if (m_eap_type_response_sent == false) + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + // Send state change notification + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_eap_response_sent, + eap.get_identifier(), + false); + state_notification(¬ification); + } + m_eap_type_response_sent = true; + } +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + else + { + if (eap.get_code() == eap_code_request + && m_is_tunneled_eap == false + && m_is_client_role == true) + { + // We got the response. Now we let the session timer handle rest of timeout cases. + cancel_wait_eap_request_type_timeout(); + } + } +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + if (m_ignore_eap_failure == false + && eap.get_code() == eap_code_failure) + { + // Set timer to delay EAP-Failure handling. + // If no other packet is received session will be + // terminated after timeout. + set_eap_failure_timeout(); + } + else + { + cancel_eap_failure_timeout(); + } + + status = handler->packet_process( + receive_network_id, + &eap, + packet_length); + + EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eap); + + if (status == eap_status_success) + { + // NOTE state_notification() will send EAP-Success message. + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s, %s, Illegal EAP-Code %d=0x%02x=%s, EAP-Type 0x%08x=%s\n"), + (m_is_client_role == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + eap.get_code(), + eap.get_code(), + eap.get_code_string(), + convert_eap_type_to_u32_t(eap.get_type()), + eap.get_type_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +/** + * @{ 2003-10-01 draft-ietf-eap-rfc2284bis-06.txt chapter 2.1 Support for sequences: + * An EAP conversation MAY utilize a sequence of methods. A common + * example of this is an Identity request followed by a single EAP + * authentication method such as an MD5-Challenge. However the peer and + * authenticator MUST utilize only one authentication method (Type 4 or + * greater) within an EAP conversation, after which the authenticator + * MUST send a Success or Failure packet. + * Once a peer has sent a Response of the same Type as the initial + * Request, an authenticator MUST NOT send a Request of a different Type + * prior to completion of the final round of a given method (with the + * exception of a Notification-Request) and MUST NOT send a Request for + * an additional method of any Type after completion of the initial + * authentication method; a peer receiving such Requests MUST treat them + * as invalid, and silently discard them. As a result, Identity Requery + * is not supported. + * A peer MUST NOT send a Nak (legacy or expanded) in reply to a + * Request, after an initial non-Nak Response has been sent. Since + * spoofed EAP Request packets may be sent by an attacker, an + * authenticator receiving an unexpected Nak SHOULD discard it and log + * the event. + * Multiple authentication methods within an EAP conversation are not + * supported due to their vulnerability to man-in-the-middle attacks + * (see Section 7.4) and incompatibility with existing implementations. + * } + */ +EAP_FUNC_EXPORT eap_status_e eap_core_c::packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::packet_process(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::packet_process()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (packet_data == 0 + || packet_data->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (packet_length < eap_header_base_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_header_wr_c eap( + m_am_tools, + packet_data->get_header_buffer(packet_data->get_header_buffer_length()), + packet_data->get_header_buffer_length()); + + if (eap.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (packet_length < eap.get_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if (eap.get_code() == eap_code_none) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_TEST_VECTORS, + (EAPL("--------------------------------------------------------\n"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA|TRACE_TEST_VECTORS, + (EAPL("EAP-packet"), + eap.get_header_buffer(packet_length), + packet_length)); + + trace_eap_packet("->", &eap); + + eap_status_e status = eap.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + +#if defined (_DEBUG) + if (m_retransmission != 0) + { + eap_header_string_c eap_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_Core: eap_core_c::packet_process(): %s, retransmission counter %d, retrans EAP-type %s, retrans EAP-Id %d, current EAP-type %s, current EAP-Id %d, session 0x%08x.\n"), + (m_is_client_role == true) ? "client": "server", + m_retransmission->get_retransmission_counter(), + eap_string.get_eap_type_string(m_retransmission->get_eap_type()), + m_retransmission->get_eap_identifier(), + eap_string.get_eap_type_string(eap.get_type()), + eap.get_identifier(), + this)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_Core: eap_core_c::packet_process(): %s, retransmission NULL, session 0x%08x.\n"), + (m_is_client_role == true) ? "client": "server", + this)); + } +#endif //#if defined (_DEBUG) + + + if (m_is_client_role == true + && m_retransmission != 0 + && m_retransmission->get_eap_type() == eap.get_type() + && m_retransmission->get_eap_identifier() == eap.get_identifier()) + { + if (m_retransmission->get_retransmission_counter() > 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_Core: eap_core_c::packet_process(): %s, retransmits previous packet, counter %d, session 0x%08x.\n"), + (m_is_client_role == true) ? "client": "server", + m_retransmission->get_retransmission_counter(), + this)); + + // We have the previous send EAP-packet stored. + // It does match to the current query. + // We could send the previous EAP-packet again. + status = resend_packet( + m_retransmission->get_send_network_id(), + m_retransmission->get_sent_packet(), + m_retransmission->get_header_offset(), + m_retransmission->get_data_length(), + m_retransmission->get_buffer_size(), + m_retransmission->get_retransmission_counter() + ); + + m_retransmission->get_next_retransmission_counter(); // This decrements the counter. + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_Core: eap_core_c::packet_process(): %s, Does not retransmit previous packet, counter %d, session 0x%08x.\n"), + (m_is_client_role == true) ? "client": "server", + m_retransmission->get_retransmission_counter(), + this)); + + status = eap_status_unexpected_message; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#if defined(USE_EAP_CORE_SERVER) + else if (m_is_client_role == false + && m_retransmission != 0 + && m_retransmission->get_eap_type() == eap.get_type() + && m_retransmission->get_eap_identifier() > eap.get_identifier()) + { + // Here we assume the EAP-Identifier increases. This is for testing purposes. + // This packet is old response, drop it. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_Core: eap_core_c::packet_process(): %s, Does not process old packet, EAP-Identifier of last received response %d, EAP-Identifier of the packet %d, session 0x%08x.\n"), + (m_is_client_role == true) ? "client": "server", + m_retransmission->get_eap_identifier(), + eap.get_identifier(), + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } +#endif //#if defined(USE_EAP_CORE_SERVER) + else if (get_marked_removed() == true + && eap.get_code() != eap_code_success + && eap.get_code() != eap_code_failure) + { + // NOTE, this delayed reset of session is used bacause in some cases cannot be responsed + // 4-Way Handshake message fast enough. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::packet_process(): %s, resets session, session 0x%08x.\n"), + (m_is_client_role == true) ? "client": "server", + this)); + + unset_marked_removed(); + + reset(); + } + + + eap_type_value_e used_eap_type = eap_type_none; + + if (eap.get_code() == eap_code_request + && m_is_client_role == true) + { + // Send ID using default EAP type, this is our best quess of other peer's EAP type. + // Other peer will sent the real EAP type later and we can NAK it then + // and send our own EAP type. + if (m_current_eap_type == eap_type_none) + { + // In Symbian implementation the default type is the highest priority EAP type. + // At the moment it is always used to reply to the identity request. + m_current_eap_type = m_default_eap_type; + used_eap_type = m_current_eap_type; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (eap.get_length() > eap_header_base_c::get_header_length()) + { + if (m_eap_type_response_sent == true + && eap.get_type() != m_current_eap_type) + { + if (eap.get_type() == eap_type_tlv_extensions) + { + // Send EAP-Response/Nak to show this is not supported. + + eap_array_c eap_type_list(m_am_tools); + + status = send_eap_nak_response( + receive_network_id, + eap.get_identifier(), + &eap_type_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + /* + * 2003-10-01 draft-ietf-eap-rfc2284bis-06.txt chapter 2.1 Support for sequences: + * An EAP conversation MAY utilize a sequence of methods. A common + * example of this is an Identity request followed by a single EAP + * authentication method such as an MD5-Challenge. However the peer and + * authenticator MUST utilize only one authentication method (Type 4 or + * greater) within an EAP conversation, after which the authenticator + * MUST send a Success or Failure packet. + * Once a peer has sent a Response of the same Type as the initial + * Request, an authenticator MUST NOT send a Request of a different Type + * prior to completion of the final round of a given method (with the + * exception of a Notification-Request) and MUST NOT send a Request for + * an additional method of any Type after completion of the initial + * authentication method; a peer receiving such Requests MUST treat them + * as invalid, and silently discard them. As a result, Identity Requery + * is not supported. + */ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAP_Core: %s, %s, packet dropped quietly. m_eap_type_response_sent %d, ") + EAPL("EAP-Type 0x%08x, m_current_eap_type 0x%08x\n"), + (m_is_client_role == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + m_eap_type_response_sent, + convert_eap_type_to_u32_t(eap.get_type()), + convert_eap_type_to_u32_t(m_current_eap_type))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + } + else if (eap.get_type() == eap_type_identity) + { + // Should we respond here with another type? + /** + * @{ Check if this is a re-transmission or a new request. + * If this is re-transmission respond using the same type as previously. + * Otherwise assume that peer did not like our previous identity and + * try another configured type. + * At the moment just try the last type that was used. + * } + */ + used_eap_type = m_current_eap_type; + } + else if (eap.get_type() == eap_type_notification) + { + // Here we are again on thin ice. + // Best ques is the las used EAP type. + used_eap_type = m_current_eap_type; + } + else + { + // Here we know what the server really wants + // use this EAP-Type. + used_eap_type = eap.get_type(); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); + } + } +#if defined(USE_EAP_CORE_SERVER) + else if (eap.get_code() == eap_code_response + && m_is_client_role == false) + { + // Received ID using some EAP type, this may be other than our current type. + + if (m_current_eap_type == eap_type_none) + { + m_current_eap_type = m_default_eap_type; + used_eap_type = m_default_eap_type; + } + else if (eap.get_length() > eap_header_base_c::get_header_length()) + { + if (eap.get_type() == eap_type_identity) + { + used_eap_type = m_default_eap_type; + } + else + { + used_eap_type = eap.get_type(); + + if (used_eap_type == eap_type_nak + || eap_expanded_type_nak.get_type() == used_eap_type + ) + { + // Server received EAP-Response from client. + // Now server could send EAP-Failure or EAP-success to client. + // See draft-ietf-eap-rfc2284bis-06.txt chapter 2. Extensible Authentication Protocol (EAP). + + /** + * @{ 2003-10-02 draft-ietf-eap-rfc2284bis-06.txt chapter 5.3.1 Legacy Nak: + * The legacy Nak Type is valid only in Response messages. It is + * sent in reply to a Request where the desired authentication Type + * is unacceptable. Authentication Types are numbered 4 and above. + * The Response contains one or more authentication Types desired by + * the Peer. Type zero (0) is used to indicate that the sender has + * no viable alternatives, and therefore the authenticator SHOULD NOT + * send another Request after receiving a Nak Response containing a + * zero value. + * Since the legacy Nak Type is valid only in Responses and has very + * limited functionality, it MUST NOT be used as a general purpose + * error indication, such as for communication of error messages, or + * negotiation of parameters specific to a particular EAP method. + * } + */ + + /** + * @{ 2003-10-02 draft-ietf-eap-rfc2284bis-06.txt chapter 5.3.2 Expanded Nak: + * The Expanded Nak Type is valid only in Response messages. It MUST + * be sent only in reply to a Request of Type 254 (Expanded Type) + * where the authentication Type is unacceptable. The Expanded Nak + * Type uses the Expanded Type format itself, and the Response + * contains one or more authentication Types desired by the peer, all + * in Expanded Type format. Type zero (0) is used to indicate that + * the sender has no viable alternatives. The general format of the + * Expanded Type is described in Section 5.7. + * Since the Expanded Nak Type is valid only in Responses and has + * very limited functionality, it MUST NOT be used as a general + * purpose error indication, such as for communication of error + * messages, or negotiation of parameters specific to a particular + * EAP method. + * } + */ + + // Only server should receive this packet. + if (eap.get_type_data_length() >= sizeof(u8_t)) + { + // EAP-Response/Nak includes list of new proposal for EAP type. + // Now we need to know does the proposed EAP type need separate identity. + // In that case we must restart the authentication. + // If the same identity is valid, we could continue. + + u32_t proposal_length = eap.get_type_data_length(); + for (u32_t ind = 0ul; ind < proposal_length; ind++) + { + /** + * @{ 2005-04-19 complete Expanded Nak Type to packet_process(). } + */ + status = eap_expanded_type_c::read_type( + m_am_tools, + ind, + eap.get_type_data(eap.get_type_data_length()), + eap.get_type_data_length(), + &used_eap_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Here we need a check that proposed EAP type is valid for us. + status = check_is_valid_eap_type(used_eap_type); + if (status == eap_status_ok) + { + // Let's use this EAP-type. + break; + } + else + { + used_eap_type = eap_type_none; + } + } // for() + + if (used_eap_type == eap_type_none) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP-Reponse/Nak did not include any valid EAp-type.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (m_process_eap_nak_immediately == true) + { + if (used_eap_type == eap_type_none) + { + // No acceptable EAP-type. + // Send a EAP-Failure. + status = send_eap_failure( + &send_network_id, + static_cast(eap.get_identifier()+1ul)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type); + } + else + { + // First remove current EAP-type. + eap_variable_data_c selector(m_am_tools); + status = selector.set_copy_of_buffer( + &m_current_eap_type, + sizeof(m_current_eap_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + eap_base_type_c *handler = m_type_map.get_handler(&selector); + + // Change the current EAP-type here because shutdown could + // cause state notifications from old EAP-type. + m_current_eap_type = used_eap_type; + + if (handler != 0) + { + status = handler->shutdown(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_type_map.remove_handler(&selector, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // Now restart authentication with proposed EAP type. + status = restart_with_new_type( + used_eap_type, + receive_network_id, + eap.get_identifier()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else //if (m_process_eap_nak_immediately == false) + { + status = eap_status_illegal_eap_type; + + if (m_nak_process_timer_active == false) + { + eap_core_nak_info_c * const nak_info + = new eap_core_nak_info_c( + m_am_tools, + receive_network_id, + used_eap_type, + eap.get_identifier()); + + status = m_partner->set_timer( + this, + EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID, + nak_info, + EAP_CORE_DELAYED_EAP_NAK_PROCESS_TIMEOUT); + if (status == eap_status_ok) + { + m_nak_process_timer_active = true; + } + else + { + // ERROR. + // NOTE: timer queue did call timer_delete_data() function to free nak_info. + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID set %d ms.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + EAP_CORE_DELAYED_EAP_NAK_PROCESS_TIMEOUT + )); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + + } // if (eap.get_type_data_length() >= sizeof(u8_t)) + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type); + } + } + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + else if (eap.get_code() == eap_code_success + || eap.get_code() == eap_code_failure) + { + if (m_current_eap_type != eap_type_none) + { + // Here we are again on thin ice. + // Use saved EAP type, this is our best quess of other peer's EAP type. + // Other peer just informs status of authentication. + used_eap_type = m_current_eap_type; + } + else + { + // No EAP-type loaded, drop message quietly. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAP_Core: %s,%s, %s packet dropped quietly. m_eap_type_response_sent %d, ") + EAPL("m_current_eap_type 0x%08x\n"), + (m_is_client_role == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + eap.get_code_string(), + m_eap_type_response_sent, + convert_eap_type_to_u32_t(m_current_eap_type))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); + } + + + status = packet_process_type( + used_eap_type, + receive_network_id, + packet_data, + packet_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_header_wr_c eap( + m_am_tools, + sent_packet->get_data_offset( + header_offset, data_length), + data_length); + + if (eap.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: %s, %s, packet buffer corrupted.\n"), + (m_is_client_role == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_ASSERT(header_offset < sent_packet->get_data_length()); + EAP_ASSERT(data_length <= sent_packet->get_data_length()); + EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA|TRACE_TEST_VECTORS, + (EAPL("EAP-packet"), + eap.get_header_buffer(data_length), + data_length)); + + trace_eap_packet("<-", &eap); + + if (m_shutdown_was_called == true + && m_is_client_role == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAP_Core: %s,%s, eap_core_c::packet_send(): %s packet dropped quietly because shutdown was already called. m_eap_type_response_sent %d, ") + EAPL("m_current_eap_type 0x%08x\n"), + (m_is_client_role == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + eap.get_code_string(), + m_eap_type_response_sent, + convert_eap_type_to_u32_t(m_current_eap_type))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_TEST_VECTORS, + (EAPL("--------------------------------------------------------\n"))); + + + cancel_retransmission(); + + if (sent_packet->get_do_packet_retransmission() == true) + { + // Both EAP-client and EAP-server initializes re-transmission. + // EAP-client will respond to re-transmitted EAP-request with the matching packet. + // EAP-server will re-transmit the packet when timer elapses and no response is received. + // Note the EAP-type could do re-transmission itself too. When EAP-type do re-transmission + // itself EAP-type should set flag of re-transmission in the packet to true with the + // set_do_packet_retransmission(true) function. + init_retransmission( + send_network_id, + sent_packet, + header_offset, + data_length, + eap.get_code(), + eap.get_identifier(), + eap.get_type()); + } + + + eap_status_e status = m_partner->packet_send( + send_network_id, sent_packet, header_offset, data_length, buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_is_client_role == true + && eap.get_type() == m_current_eap_type + && m_current_eap_type != eap_type_none) + { + /* + * Once a peer has sent a Response of the same Type as the initial + * Request, an authenticator MUST NOT send a Request of a different Type + * prior to completion of the final round of a given method (with the + * exception of a Notification-Request) and MUST NOT send a Request for + * an additional method of any Type after completion of the initial + * authentication method; a peer receiving such Requests MUST treat them + * as invalid, and silently discard them. As a result, Identity Requery + * is not supported. + */ + if (m_eap_type_response_sent == false) + { + // Send state change notification + eap_state_notification_c notification( + m_am_tools, + send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_eap_response_sent, + eap.get_identifier(), + false); + state_notification(¬ification); + } + m_eap_type_response_sent = true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::resend_packet( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length, + const u32_t retransmission_counter) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(retransmission_counter); // Only trace uses this. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("<- EAP_Core: %s: %s, eap_core_c::resend_packet(), counter %d.\n"), + (m_is_client_role == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + retransmission_counter + )); + + // We make a copy because random error test may corrupt the data. + eap_buf_chain_wr_c * const copy_packet = sent_packet->copy(); + + if (copy_packet == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT(m_eap_header_offset < sent_packet->get_data_length()); + EAP_ASSERT(data_length <= sent_packet->get_data_length()); + EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); + + // NOTE: send packet directly to partner object. + // This will skip initialization of re-transmission tfor re-transmitted packet. + eap_status_e status = m_partner->packet_send( + send_network_id, + copy_packet, + header_offset, + data_length, + buffer_length + ); + + delete copy_packet; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::cancel_retransmission() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + //if (m_retransmission != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID cancelled.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + if (m_is_client_role == false) + { + // Only EAP-server uses timer to re-transmits EAP-packets. + m_partner->cancel_timer(this, EAP_CORE_TIMER_RETRANSMISSION_ID); + } + + if (m_retransmission != 0) + { + delete m_retransmission; + m_retransmission = 0; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::init_retransmission( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const eap_code_value_e eap_code, + const u8_t eap_identifier, + const eap_type_value_e eap_type + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (m_is_client_role == false) + { + if (m_retransmission_time == 0u + || m_retransmission_counter == 0u) + { + // No retransmission. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + + EAP_ASSERT(send_network_id->get_source() != 0); + EAP_ASSERT(send_network_id->get_destination() != 0); + + if (m_retransmission != 0) + { + delete m_retransmission; + m_retransmission = 0; + } + + m_retransmission = new eap_core_retransmission_c( + m_am_tools, + send_network_id, + sent_packet, + header_offset, + data_length, + m_retransmission_time, + m_retransmission_counter, + eap_code, + eap_identifier, + eap_type + ); + + if (m_is_client_role == false) + { + // Only EAP-server uses timer to re-transmits EAP-packets. + m_partner->cancel_timer(this, EAP_CORE_TIMER_RETRANSMISSION_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID cancelled.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + } + + if (m_retransmission == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_retransmission->get_is_valid() == true) + { + // Because this object do re-transmission other layers must not do re-transmission of this packet. + sent_packet->set_do_packet_retransmission(false); + + if (m_is_client_role == false) + { + // Only EAP-server uses timer to re-transmits EAP-packets. + u32_t next_retransmission_time = m_retransmission->get_next_retransmission_time(); + + eap_status_e status = m_partner->set_timer(this, EAP_CORE_TIMER_RETRANSMISSION_ID, 0, + next_retransmission_time); + if (status != eap_status_ok) + { + delete m_retransmission; + m_retransmission = 0; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID set %d ms.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + next_retransmission_time)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + else + { + delete m_retransmission; + m_retransmission = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::set_eap_failure_timeout() +{ + eap_status_e status = m_partner->set_timer( + this, + EAP_CORE_FAILURE_RECEIVED_ID, + 0, + m_eap_core_failure_received_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TIMER: %s: %s, EAP_CORE_FAILURE_RECEIVED_ID failed.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_FAILURE_RECEIVED_ID set %d ms.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + m_eap_core_failure_received_timeout + )); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::cancel_eap_failure_timeout() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_FAILURE_RECEIVED_ID cancelled.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + return m_partner->cancel_timer( + this, + EAP_CORE_FAILURE_RECEIVED_ID); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + +// +eap_status_e eap_core_c::set_wait_eap_request_type_timeout() +{ + EAP_ASSERT_TOOLS(m_am_tools, (m_wait_eap_request_type_timeout_set == false)); + + eap_status_e status = m_partner->set_timer( + this, + EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID, + 0, + m_wait_eap_request_type_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TIMER: %s: %s, EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID failed.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID set %d ms.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + m_wait_eap_request_type_timeout + )); + + m_wait_eap_request_type_timeout_set = true; + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + +//-------------------------------------------------- + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + +// +eap_status_e eap_core_c::cancel_wait_eap_request_type_timeout() +{ + if (m_wait_eap_request_type_timeout_set == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID cancelled.\n"), + (m_is_client_role == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + m_wait_eap_request_type_timeout_set = false; + + return m_partner->cancel_timer( + this, + EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } +} + +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_core_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const u32_t offset = m_partner->get_header_offset(MTU, trailer_length); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::get_header_offset(): offset=%d, MTU=%d, trailer_length=%d\n"), + offset, + *MTU, + *trailer_length)); + + return offset; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const handler, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->load_module( + type, + tunneling_type, + partner, + handler, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#if !defined(USE_EAP_DEBUG_TRACE) + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::configure(): %s: %s.\n"), + ((m_is_client == true) ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most")); +#else + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::configure(): %s: %s, this = 0x%08x => 0x%08x.\n"), + ((m_is_client == true) ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + this, + dynamic_cast(this))); +#endif + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::configure()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + eap_variable_data_c data(m_am_tools); + + status = m_partner->read_configure( + cf_str_EAP_default_type_hex_data.get_field(), + &data); + if (status == eap_status_illegal_configure_type) + { + status = m_partner->read_configure( + cf_str_EAP_default_type_u32_t.get_field(), + &data); + } + +#if defined(USE_EAP_CORE_SERVER) + if (m_is_client == false) + { + // This option is only applicable in server. + + eap_variable_data_c server_data(m_am_tools); + + eap_status_e server_status = m_partner->read_configure( + cf_str_EAP_server_default_type_hex_data.get_field(), + &server_data); + if (server_status == eap_status_illegal_configure_type) + { + server_status = m_partner->read_configure( + cf_str_EAP_server_default_type_u32_t.get_field(), + &server_data); + } + + if (server_status == eap_status_ok + && server_data.get_is_valid_data() == true) + { + status = data.set_copy_of_buffer(&server_data); + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + m_default_eap_type + = *(reinterpret_cast( + data.get_data(data.get_data_length()))); + } + else if (data.get_data_length() == eap_expanded_type_c::get_eap_expanded_type_size() + && data.get_data(data.get_data_length()) != 0) + { + eap_expanded_type_c eap_type(eap_type_none); + + status = eap_type.set_expanded_type_data( + m_am_tools, + &data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_type.get_type_data( + m_am_tools, + &m_default_eap_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s: %s, No EAP-type configured, %s.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + cf_str_EAP_default_type_hex_data.get_field()->get_field())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_TEST_VECTORS) + + { + eap_variable_data_c data(m_am_tools); + + status = m_partner->read_configure( + cf_str_EAP_TRACE_only_trace_messages.get_field(), + &data); + if (status == eap_status_ok + && data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + if (*(reinterpret_cast(data.get_data(data.get_data_length()))) != 0u) + { + // Activate only EAP message traces. + m_am_tools->set_trace_mask( + eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_eap_messages); + } + else + { + // Disable only EAP message traces. + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() & (~eap_am_tools_c::eap_trace_mask_eap_messages)); + } + } + else + { + // Disable only EAP message traces. + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() & (~eap_am_tools_c::eap_trace_mask_eap_messages)); + } + } + + + { + eap_variable_data_c data(m_am_tools); + + status = m_partner->read_configure( + cf_str_EAP_TRACE_only_test_vectors.get_field(), + &data); + if (status == eap_status_ok + && data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + if (*(reinterpret_cast(data.get_data(data.get_data_length()))) != 0u) + { + // Activates only EAP test vector traces. + m_am_tools->set_trace_mask(eap_am_tools_c::eap_trace_mask_test_vectors); + } + } + } + + + { + eap_variable_data_c data(m_am_tools); + + status = m_partner->read_configure( + cf_str_EAP_TRACE_crypto_test_vectors_sha1.get_field(), + &data); + if (status == eap_status_ok + && data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + if (*(reinterpret_cast(data.get_data(data.get_data_length()))) != 0u) + { + // Activates SHA1 EAP test vector traces. + m_am_tools->set_trace_mask(m_am_tools->get_trace_mask() + | eap_am_tools_c::eap_trace_mask_crypto_sha1); + } + } + } + + + { + eap_variable_data_c data(m_am_tools); + + status = m_partner->read_configure( + cf_str_EAP_TRACE_crypto_test_vectors_rc4.get_field(), + &data); + if (status == eap_status_ok + && data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + if (*(reinterpret_cast(data.get_data(data.get_data_length()))) != 0u) + { + // Activates RC4 EAP test vector traces. + m_am_tools->set_trace_mask(m_am_tools->get_trace_mask() + | eap_am_tools_c::eap_trace_mask_crypto_rc4); + } + } + } + + + { + eap_variable_data_c data(m_am_tools); + + status = m_partner->read_configure( + cf_str_EAP_TRACE_crypto_test_vectors_md4.get_field(), + &data); + if (status == eap_status_ok + && data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + if (*(reinterpret_cast(data.get_data(data.get_data_length()))) != 0u) + { + // Activates MD4 EAP test vector traces. + m_am_tools->set_trace_mask(m_am_tools->get_trace_mask() + | eap_am_tools_c::eap_trace_mask_crypto_md4); + } + } + } + + + { + eap_variable_data_c data(m_am_tools); + + status = m_partner->read_configure( + cf_str_EAP_TRACE_crypto_test_vectors_test_random.get_field(), + &data); + if (status == eap_status_ok + && data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + if (*(reinterpret_cast(data.get_data(data.get_data_length()))) != 0u) + { + // Activates test random generator EAP test vector traces. + m_am_tools->set_trace_mask(m_am_tools->get_trace_mask() + | eap_am_tools_c::eap_trace_mask_crypto_test_random + | eap_am_tools_c::eap_trace_mask_crypto_sha1); + } + } + } + +#endif //#if defined(USE_EAP_TEST_VECTORS) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_CORE_SERVER) + if (m_is_client == false) + { + eap_variable_data_c data(m_am_tools); + + status = m_partner->read_configure( + cf_str_EAP_CORE_process_EAP_Nak_immediately.get_field(), + &data); + if (status == eap_status_ok + && data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + u32_t *flag = reinterpret_cast(data.get_data(data.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_process_eap_nak_immediately = true; + } + else + { + m_process_eap_nak_immediately = false; + } + } + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_CORE_SERVER) + if (m_is_client == false) + { + eap_variable_data_c retransmission_time(m_am_tools); + + status = read_configure( + cf_str_EAP_CORE_retransmission_time.get_field(), + &retransmission_time); + if (status == eap_status_ok + && retransmission_time.get_is_valid_data() == true) + { + u32_t *retransmission_time_value = reinterpret_cast( + retransmission_time.get_data(sizeof(u32_t))); + if (retransmission_time_value != 0) + { + m_retransmission_time = *retransmission_time_value; + } + else + { + m_retransmission_time = EAP_CORE_RETRANSMISSION_TIME; + } + } + else + { + m_retransmission_time = EAP_CORE_RETRANSMISSION_TIME; + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + + //if (m_is_client == false) + { + eap_variable_data_c retransmission_counter(m_am_tools); + + status = read_configure( + cf_str_EAP_CORE_retransmission_counter.get_field(), + &retransmission_counter); + if (status == eap_status_ok + && retransmission_counter.get_is_valid_data() == true) + { + u32_t *retransmission_counter_value = reinterpret_cast( + retransmission_counter.get_data(sizeof(u32_t))); + if (retransmission_counter_value != 0) + { + m_retransmission_counter = *retransmission_counter_value; + } + else + { + m_retransmission_counter = EAP_CORE_RETRANSMISSION_COUNTER; + } + } + else + { + m_retransmission_counter = EAP_CORE_RETRANSMISSION_COUNTER; + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c session_timeout(m_am_tools); + + status = read_configure( + cf_str_EAP_CORE_session_timeout.get_field(), + &session_timeout); + if (status == eap_status_ok + && session_timeout.get_is_valid_data() == true) + { + u32_t *handler_timeout = reinterpret_cast( + session_timeout.get_data(sizeof(u32_t))); + if (handler_timeout != 0) + { + m_session_timeout = *handler_timeout; + } + else + { + m_session_timeout = EAP_CORE_SESSION_TIMEOUT; + } + } + else + { + m_session_timeout = EAP_CORE_SESSION_TIMEOUT; + } + } + + +#if defined(USE_EAP_CORE_SERVER) + + if (m_is_client == false) + { + eap_variable_data_c session_timeout(m_am_tools); + + status = read_configure( + cf_str_EAP_CORE_server_session_timeout.get_field(), + &session_timeout); + if (status == eap_status_ok + && session_timeout.get_is_valid_data() == true) + { + u32_t *handler_timeout = reinterpret_cast( + session_timeout.get_data(sizeof(u32_t))); + if (handler_timeout != 0) + { + // This is optional. + m_session_timeout = *handler_timeout; + } + } + } + + if (m_is_client == false) + { + eap_variable_data_c data(m_am_tools); + + status = m_partner->read_configure( + cf_str_EAP_CORE_send_eap_success_after_notification.get_field(), + &data); + if (status == eap_status_ok + && data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + u32_t *flag = reinterpret_cast(data.get_data(data.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_send_eap_success_after_notification = true; + } + else + { + m_send_eap_success_after_notification = false; + } + } + } + } + +#endif //#if defined(USE_EAP_CORE_SERVER) + + //---------------------------------------------------------- + + { + eap_variable_data_c failure_received_timeout(m_am_tools); + + status = read_configure( + cf_str_EAP_CORE_failure_received_timeout.get_field(), + &failure_received_timeout); + if (status == eap_status_ok + && failure_received_timeout.get_is_valid_data() == true) + { + u32_t *timeout = reinterpret_cast( + failure_received_timeout.get_data(sizeof(u32_t))); + if (timeout != 0) + { + m_eap_core_failure_received_timeout = *timeout; + } + } + } + + //---------------------------------------------------------- + + if (m_is_tunneled_eap == false) + { + eap_variable_data_c remove_session_timeout(m_am_tools); + + status = read_configure( + cf_str_EAP_CORE_remove_session_timeout.get_field(), + &remove_session_timeout); + if (status == eap_status_ok + && remove_session_timeout.get_is_valid_data() == true) + { + u32_t *remove_session_timeout_value = reinterpret_cast( + remove_session_timeout.get_data(sizeof(u32_t))); + if (remove_session_timeout_value != 0) + { + m_remove_session_timeout = *remove_session_timeout_value; + } + } + } + else + { + // Inside the tunnel we do not need any timeout. + m_remove_session_timeout = 0ul; + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_EXPANDED_TYPES) + { + eap_variable_data_c use_eap_expanded_type(m_am_tools); + + status = m_partner->read_configure( + cf_str_EAP_CORE_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + if (status == eap_status_ok + && use_eap_expanded_type.get_data_length() == sizeof(u32_t) + && use_eap_expanded_type.get_data() != 0) + { + u32_t *flag = reinterpret_cast(use_eap_expanded_type.get_data(use_eap_expanded_type.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_use_eap_expanded_type = true; + } + else + { + m_use_eap_expanded_type = false; + } + } + } + } +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + //---------------------------------------------------------- + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + { + eap_variable_data_c wait_eap_request_type_timeout(m_am_tools); + + status = read_configure( + cf_str_EAP_CORE_wait_eap_request_type_timeout.get_field(), + &wait_eap_request_type_timeout); + if (status == eap_status_ok + && wait_eap_request_type_timeout.get_is_valid_data() == true) + { + u32_t *timeout = reinterpret_cast( + wait_eap_request_type_timeout.get_data(sizeof(u32_t))); + if (timeout != 0) + { + m_wait_eap_request_type_timeout = *timeout; + } + } + } + +#if defined(USE_EAP_CORE_SERVER) + if (m_is_tunneled_eap == false) + { + + eap_variable_data_c skip_eap_request_identity(m_am_tools); + + status = m_partner->read_configure( + cf_str_EAP_CORE_skip_eap_request_identity.get_field(), + &skip_eap_request_identity); + if (status == eap_status_ok + && skip_eap_request_identity.get_data_length() == sizeof(u32_t) + && skip_eap_request_identity.get_data() != 0) + { + u32_t *flag = reinterpret_cast(skip_eap_request_identity.get_data(skip_eap_request_identity.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_skip_eap_request_identity = true; + } + else + { + m_skip_eap_request_identity = false; + } + } + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + //---------------------------------------------------------- + + m_eap_header_offset = m_partner->get_header_offset(&m_MTU, &m_trailer_length); + + + // Add session timeout. + status = initialize_session_timeout(m_session_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + if (m_is_tunneled_eap == false + && m_is_client_role == true) + { + status = cancel_wait_eap_request_type_timeout(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_wait_eap_request_type_timeout(); + } + +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::shutdown_operation( + eap_base_type_c * const handler, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::shutdown_operation(): handler=0x%08x.\n"), + handler)); + + eap_status_e status = handler->shutdown(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + +#if !defined(USE_EAP_DEBUG_TRACE) + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::shutdown(): %s: %s, m_shutdown_was_called=%d.\n"), + ((m_is_client == true) ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + m_shutdown_was_called)); +#else + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::shutdown(): %s: %s, this = 0x%08x => 0x%08x, ") + EAPL("m_shutdown_was_called=%d.\n"), + ((m_is_client == true) ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + this, + dynamic_cast(this), + m_shutdown_was_called)); +#endif + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::shutdown()"); + + if (m_shutdown_was_called == true) + { + // Shutdown was already called once. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + if (m_partner == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::shutdown(): m_is_tunneled_eap=%d, m_eap_type_response_sent=%d\n"), + m_is_tunneled_eap, + m_eap_type_response_sent)); + + if (m_is_client == true + && m_is_tunneled_eap == false + && m_eap_type_response_sent == false) + { + // EAP-authentication failed before any EAP-messages. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::shutdown(): EAP-authentication failed before any EAP-messages.\n"))); + + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + m_eap_identity_request_identifier_client, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + state_notification(¬ification); + } + + eap_status_e status = m_type_map.for_each(shutdown_operation, true); + + + cancel_retransmission(); + + cancel_session_timeout(); + + cancel_eap_failure_timeout(); + + cancel_asynchronous_init_remove_eap_session(); + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + if (m_is_tunneled_eap == false + && m_is_client_role == true) + { + cancel_wait_eap_request_type_timeout(); + } +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + + if (m_partner != 0) + { + +#if defined(USE_EAP_CORE_SERVER) + m_partner->cancel_timer(this, EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID ") + EAPL("cancelled, this = 0x%08x.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + this)); +#endif //#if defined(USE_EAP_CORE_SERVER) + + m_partner->cancel_timer(this, EAP_CORE_SESSION_TIMEOUT_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_SESSION_TIMEOUT_ID cancelled, this = 0x%08x.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + this)); + } + +#if !defined(USE_EAP_DEBUG_TRACE) + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::shutdown(): %s: %s, m_shutdown_was_called=%d, status=%d returns.\n"), + ((m_is_client == true) ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + m_shutdown_was_called, + status)); +#else + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::shutdown(): %s: %s, this = 0x%08x => 0x%08x, ") + EAPL("m_shutdown_was_called=%d, status=%d returns.\n"), + ((m_is_client == true) ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + this, + dynamic_cast(this), + m_shutdown_was_called, + status)); +#endif + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->unload_module(type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::eap_acknowledge( + const eap_am_network_id_c * const receive_network_id) +{ + // Any Network Protocol packet is accepted as a success indication. + // This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status(eap_status_process_general_error); + + /** + * @{ 2003-10-01 draft-ietf-eap-rfc2284bis-06.txt chapter 3.4 Lower layer indications: + * To improve reliability, if a peer receives a lower layer success + * indication as defined in Section 7.2, it MAY conclude that a Success + * packet has been lost, and behave as if it had actually received a + * Success packet. This includes choosing to ignore the Success in some + * circumstances as described in Section 4.2. + * Add call to current EAP-type. Maybe the EAP-Success packet could + * be created here and send to EAP-type. + * } + */ + + if (m_current_eap_type != eap_type_none) + { + // Here we query the current EAP-type. + eap_variable_data_c selector(m_am_tools); + u64_t selector_eap_type = convert_eap_type_to_u64_t(m_current_eap_type); + status = selector.set_buffer(&selector_eap_type, sizeof(selector_eap_type), false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + eap_base_type_c *handler = m_type_map.get_handler(&selector); + + // Check if we already have this type loaded. + if (handler != 0) + { + status = handler->eap_acknowledge(receive_network_id); + + if (status == eap_status_not_supported) + { + // This is too noisy. + /** + * @{ 2004-09-02 Fix all eap_acknowledge() functions. } + */ + status = eap_status_ok; + } + } + else + { + // Here we do not care of missing handler. + // Acknowledge is meaningfull only for existing handler. + status = eap_status_ok; + } + } + else + { + // Here we do not care of missing handler. + // Acknowledge is meaningfull only for existing handler. + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::restart_authentication( + const eap_am_network_id_c * const send_network_id, + const bool is_client_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + send_network_id->get_destination_id(), + send_network_id->get_source_id(), + send_network_id->get_type()); + + eap_status_e status = eap_status_process_general_error; + + initialize_session_timeout(m_session_timeout); + + if (is_client_when_true == false) + { + // This is much faster. + status = m_partner->restart_authentication( + &receive_network_id, + is_client_when_true, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_client_restart_authentication_initiated = true; + } + else + { + if (m_client_restart_authentication_initiated == true) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + // This is much faster. + status = m_partner->restart_authentication( + &receive_network_id, + is_client_when_true, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_client_restart_authentication_initiated = true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_CORE_SERVER) + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_identity_request( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_ASSERT(m_is_client == false); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_identity_request(): %s, %s\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::send_eap_identity_request()"); + + if (receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_identity_request(): %s, %s, m_skip_eap_request_identity=%d, m_eap_identity_request_send=%d, m_eap_identity_response_accepted=%d\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + m_skip_eap_request_identity, + m_eap_identity_request_send, + m_eap_identity_response_accepted + )); + + if (m_skip_eap_request_identity == true) + { + if (m_eap_identity_request_send == true) + { + // Do nothing, this have been done already. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + if (m_eap_identity.get_is_valid_data() == false) + { + // No saved EAP-Identity. Set an empty EAP-Identity. + status = m_eap_identity.init(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // We will skip EAP-Request/Identity and EAP-Response/Identity for testing purposes. + // Now restart authentication with proposed EAP type. + status = restart_with_new_type( + m_default_eap_type, + receive_network_id, + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_eap_identity_request_send = true; + m_eap_identity_response_accepted = true; + } + else +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + { + // Creates a identity request message. + eap_buf_chain_wr_c request_packet( + eap_write_buffer, + m_am_tools, + EAP_CORE_PACKET_BUFFER_LENGTH); + + if (request_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_eap_identity_request(): %s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t buffer_size = EAP_CORE_PACKET_BUFFER_LENGTH; + EAP_ASSERT_ALWAYS(m_MTU > m_trailer_length); + if (m_MTU-m_trailer_length < buffer_size) + { + buffer_size = m_MTU-m_trailer_length; + } + + EAP_ASSERT_ALWAYS(buffer_size >= m_eap_header_offset); + eap_header_wr_c eap_request( + m_am_tools, + request_packet.get_data_offset( + m_eap_header_offset, + (buffer_size-m_eap_header_offset)), + (buffer_size-m_eap_header_offset)); + + if (eap_request.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_eap_identity_request(): %s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_request.set_length( + static_cast((EAP_CORE_PACKET_BUFFER_LENGTH-m_eap_header_offset)), + m_use_eap_expanded_type); + eap_request.set_code(eap_code_request); + eap_request.set_identifier(0); + eap_request.set_type_data_length(0ul, m_use_eap_expanded_type); + eap_request.set_type(eap_type_identity, m_use_eap_expanded_type); + + request_packet.set_data_length(m_eap_header_offset+eap_request.get_length()); + request_packet.set_do_packet_retransmission(true); + + EAP_ASSERT(m_eap_header_offset < request_packet.get_data_length()); + EAP_ASSERT(eap_request.get_length() <= request_packet.get_data_length()); + EAP_ASSERT(request_packet.get_data_length() <= EAP_CORE_PACKET_BUFFER_LENGTH); + + status = packet_send( + &send_network_id, &request_packet, m_eap_header_offset, + eap_request.get_length(), + EAP_CORE_PACKET_BUFFER_LENGTH); + + if (status == eap_status_ok) + { + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_identity_request_sent, + eap_request.get_identifier(), + false); + state_notification(¬ification); + } + + m_eap_identity_request_send = true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_CORE_SERVER) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_nak_response( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_nak_response(): %s, %s\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + // Creates a identity request message. + eap_buf_chain_wr_c nak_packet( + eap_write_buffer, + m_am_tools, + EAP_CORE_PACKET_BUFFER_LENGTH); + + if (nak_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_nak_response(): %s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t buffer_size = EAP_CORE_PACKET_BUFFER_LENGTH; + EAP_ASSERT_ALWAYS(m_MTU > m_trailer_length); + if (m_MTU-m_trailer_length < buffer_size) + { + buffer_size = m_MTU-m_trailer_length; + } + + EAP_ASSERT_ALWAYS(buffer_size >= m_eap_header_offset); + eap_header_wr_c eap_nak_hdr( + m_am_tools, + nak_packet.get_data_offset( + m_eap_header_offset, + (buffer_size-m_eap_header_offset)), + (buffer_size-m_eap_header_offset) + ); + + if (eap_nak_hdr.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_nak_response(): %s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + bool write_expanded_type(false); + u32_t ind = 0ul; + u32_t count_of_eap_types = eap_type_list->get_object_count(); + + for (ind = 0ul; ind < count_of_eap_types; ind++) + { + const eap_type_value_e * const type = eap_type_list->get_object(ind); + if (type != 0 + && eap_expanded_type_c::is_ietf_type(*type) == false) + { + write_expanded_type = true; + break; + } + } + + eap_nak_hdr.set_length( + static_cast((EAP_CORE_PACKET_BUFFER_LENGTH-m_eap_header_offset)), + write_expanded_type); + eap_nak_hdr.set_code(eap_code_response); + eap_nak_hdr.set_identifier(eap_identifier); + eap_nak_hdr.set_type_data_length(eap_nak_hdr.get_length(), write_expanded_type); + eap_nak_hdr.set_type(eap_type_nak, write_expanded_type); + + u32_t required_data_length = count_of_eap_types + *eap_expanded_type_c::get_eap_expanded_type_size(); + + if (eap_nak_hdr.get_length() < required_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t type_length = eap_expanded_type_c::m_ietf_type_size; + if (write_expanded_type == true) + { + type_length = eap_expanded_type_c::m_eap_expanded_type_size; + } + + u8_t * const type_data = eap_nak_hdr.get_data_offset(type_length, required_data_length); + + if (type_data == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_nak_response(): %s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + u8_t * const data = type_data; + + for (ind = 0ul; ind < count_of_eap_types; ind++) + { + const eap_type_value_e * const type = eap_type_list->get_object(ind); + + if (type != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_core_c::send_eap_nak_response(): allowed EAP-type %d.\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(*type))); + + status = eap_expanded_type_c::write_type( + m_am_tools, + ind, + data, + eap_nak_hdr.get_type_data_length() + -eap_expanded_type_c::get_eap_expanded_type_size()*ind, + write_expanded_type, + *type); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_nak_response(): %s, %s, ") + EAPL("No EAP-type supported.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most")); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + } // for() + + eap_nak_hdr.set_type_data_length( + static_cast(count_of_eap_types*type_length), + write_expanded_type); + nak_packet.set_data_length(m_eap_header_offset+eap_nak_hdr.get_length()); + + EAP_ASSERT(m_eap_header_offset < nak_packet.get_data_length()); + EAP_ASSERT(eap_nak_hdr.get_length() <= nak_packet.get_data_length()); + EAP_ASSERT(nak_packet.get_data_length() <= EAP_CORE_PACKET_BUFFER_LENGTH); + + status = packet_send( + &send_network_id, &nak_packet, m_eap_header_offset, + eap_nak_hdr.get_length(), + EAP_CORE_PACKET_BUFFER_LENGTH); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->packet_data_crypto_keys( + send_network_id, + master_session_key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->read_configure(field, data); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->write_configure(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::timer_expired( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(data); // Only trace uses this. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_core_c::timer_expired(id 0x%02x, data 0x%08x), %s, %s.\n"), + this, + id, + data, + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most")); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (id == EAP_CORE_FAILURE_RECEIVED_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_FAILURE_RECEIVED_ID elapsed.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + { + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + m_eap_identity_request_identifier_client, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + state_notification(¬ification); + } + + status = eap_status_ok; + } + else if (id == EAP_CORE_TIMER_RETRANSMISSION_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID elapsed.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + if (m_retransmission != 0 + && m_retransmission->get_is_valid() == true + && m_retransmission->get_retransmission_counter() > 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s, %s, new retransmission, m_retransmission->get_is_valid()=%d, ") + EAPL("m_retransmission->get_retransmission_counter()=%d.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + m_retransmission->get_is_valid(), + m_retransmission->get_retransmission_counter())); + + // This packet send is initialized by timer event. + + status = resend_packet( + m_retransmission->get_send_network_id(), + m_retransmission->get_sent_packet(), + m_retransmission->get_header_offset(), + m_retransmission->get_data_length(), + m_retransmission->get_buffer_size(), + m_retransmission->get_retransmission_counter() + ); + + if (status == eap_status_ok) + { + if (m_retransmission->get_retransmission_counter() > 0u) + { + // OK, initialize the next time to retransmit. + u32_t next_retransmission_time + = m_retransmission->get_next_retransmission_time(); + + status = m_partner->set_timer( + this, + EAP_CORE_TIMER_RETRANSMISSION_ID, + 0, + next_retransmission_time); + if (status != eap_status_ok) + { + delete m_retransmission; + m_retransmission = 0; + } + else + { + m_retransmission->get_next_retransmission_counter(); // This decrements the counter. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID ") + EAPL("set %d ms, retransmission_counter %d.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + next_retransmission_time, + m_retransmission->get_retransmission_counter())); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + delete m_retransmission; + m_retransmission = 0; + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s, %s, no retransmission, m_retransmission=0x%08x.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + m_retransmission)); + if (m_retransmission != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s, %s, no retransmission, m_retransmission->get_is_valid()=%d, ") + EAPL("m_retransmission->get_retransmission_counter()=%d.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + m_retransmission->get_is_valid(), + m_retransmission->get_retransmission_counter())); + } + + // No good EAP-Response received to EAP-Requests. + // Terminate the session. + + { + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + m_eap_identity_request_identifier_client, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + state_notification(¬ification); + } + + status = eap_status_ok; + } + } +#if defined(USE_EAP_CORE_SERVER) + else if (id == EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID) + { + // Now restart authentication with proposed EAP type. + const eap_core_nak_info_c * const nak_info + = reinterpret_cast(data); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID elapsed.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + eap_type_value_e used_eap_type = nak_info->get_proposed_eap_type(); + + m_nak_process_timer_active = false; + + { + // First remove current EAP-type. + eap_variable_data_c selector(m_am_tools); + status = selector.set_copy_of_buffer( + &m_current_eap_type, + sizeof(m_current_eap_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + eap_base_type_c *handler = m_type_map.get_handler(&selector); + + // Change the current EAP-type here because shutdown could + // cause state notifications from old EAP-type. + m_current_eap_type = used_eap_type; + + if (handler != 0) + { + status = handler->shutdown(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_type_map.remove_handler(&selector, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // Now restart authentication with proposed EAP type. + status = restart_with_new_type( + used_eap_type, + nak_info->get_network_id(), + nak_info->get_eap_identifier()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + else if (id == EAP_CORE_SESSION_TIMEOUT_ID +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + || id == EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + ) + { +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + if (id == EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID elapsed.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + } + else +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_SESSION_TIMEOUT_ID elapsed.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + } + + // we will remove this session immediately. + status = initialize_asynchronous_init_remove_eap_session(0ul); + + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + m_eap_identity_request_identifier_client, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + state_notification(¬ification); + + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (id == EAP_CORE_REMOVE_SESSION_TIMEOUT_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_REMOVE_SESSION_TIMEOUT_ID elapsed.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + status = asynchronous_init_remove_eap_session(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::timer_delete_data( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(data); // Only trace uses this. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_core_c::timer_delete_data(id 0x%02x, data 0x%08x): %s, %s.\n"), + this, + id, + data, + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (id == EAP_CORE_TIMER_RETRANSMISSION_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID delete data.\n"), + (m_is_client == true ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + if (m_retransmission != 0 + && m_retransmission->get_is_valid() == true + && m_retransmission->get_retransmission_counter() > 0) + { + // Do not delete yet. + // cancel_retransmission() will delete m_retransmission. + } + else if (m_retransmission != 0) + { + delete m_retransmission; + m_retransmission = 0; + } + } +#if defined(USE_EAP_CORE_SERVER) + else if (id == EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID) + { + const eap_core_nak_info_c * const nak_info + = reinterpret_cast(data); + delete nak_info; + } +#endif //#if defined(USE_EAP_CORE_SERVER) + else if (id == EAP_CORE_REMOVE_SESSION_TIMEOUT_ID) + { + // Nothing to do. + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::reset_operation( + eap_base_type_c * const handler, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::reset_operation(): handler=0x%08x.\n"), + handler)); + + eap_status_e status = handler->reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#if !defined(USE_EAP_DEBUG_TRACE) + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::reset(): %s: %s.\n"), + ((m_is_client == true) ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most")); +#else + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::reset(): %s: %s, this = 0x%08x => 0x%08x.\n"), + ((m_is_client == true) ? "client": "server"), + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + this, + dynamic_cast(this))); +#endif + + eap_status_e status = eap_status_ok; + + eap_variable_data_c selector(m_am_tools); + u64_t tmp_eap_type = convert_eap_type_to_u64_t(m_current_eap_type); + status = selector.set_buffer(&tmp_eap_type, sizeof(tmp_eap_type), false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + cancel_retransmission(); + + cancel_session_timeout(); + + cancel_eap_failure_timeout(); + + cancel_asynchronous_init_remove_eap_session(); + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + if (m_is_tunneled_eap == false + && m_is_client_role == true) + { + status = cancel_wait_eap_request_type_timeout(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_wait_eap_request_type_timeout(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + m_eap_identity_response_accepted = false; + m_eap_type_response_sent = false; + +#if defined(USE_EAP_CORE_SERVER) + m_eap_identity_request_send = false; + m_eap_identity_response_received = false; + m_eap_failure_sent = false; +#endif //#if defined(USE_EAP_CORE_SERVER) + + m_ignore_eap_failure = false; + + status = m_type_map.for_each(reset_operation, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_current_eap_type = eap_type_none; + m_eap_identity.reset(); + + // Add session timeout. + initialize_session_timeout(m_session_timeout); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::handle_eap_identity_request( + const eap_type_value_e used_eap_type, + const u8_t eap_identifier, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + if (m_is_tunneled_eap == false + && m_is_client_role == true) + { + status = cancel_wait_eap_request_type_timeout(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + // Here we query the desired EAP-type. + eap_variable_data_c selector(m_am_tools); + u64_t tmp_used_eap_type = convert_eap_type_to_u64_t(used_eap_type); + status = selector.set_buffer(&tmp_used_eap_type, sizeof(tmp_used_eap_type), false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_base_type_c *handler = m_type_map.get_handler(&selector); + + if (handler == 0 + || handler->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_type_does_not_exists_error); + } + + m_client_restart_authentication_initiated = false; + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + + // Send state change notification + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_identity_request_received, + eap_identifier, + false); + state_notification(¬ification); + + // Save EAP-identifier + m_eap_identity_request_identifier_client = eap_identifier; + + status = handler->query_eap_identity( + false, + &m_eap_identity, + receive_network_id, + eap_identifier); + if (status == eap_status_drop_packet_quietly) + { + // This packet was dropped. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_eap_identity_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_eap_identity_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status != eap_status_ok) + { + // Send failure notification + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + eap_identifier, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + state_notification(¬ification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // status == eap_status_ok + { + // The query_eap_identity() function call is synchronous. + // We must call send_eap_identity_response(). + + status = send_eap_identity_response( + &send_network_id, + &m_eap_identity, + m_eap_identity_request_identifier_client); // Uses the EAP-Identifier from the latest EAP-Request/Identity. + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_CORE_SERVER) + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::handle_eap_identity_response( + eap_base_type_c * const handler, + const eap_type_value_e used_eap_type, + const eap_am_network_id_c * const receive_network_id, + eap_header_wr_c * const eap, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(used_eap_type); + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_ASSERT(m_is_client == false); + + if (handler == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_type_does_not_exists_error); + } + + status = handler->packet_process( + receive_network_id, + eap, + packet_length); + + if (status == eap_status_ok) + { + // We need to copy EAP-Identity for later use. + + const u8_t * identity = eap->get_type_data(eap->get_type_data_length()); + const u32_t identity_length = eap->get_type_data_length(); + const u8_t empty_identity[] = ""; + + if (identity == 0 + || identity_length == 0ul) + { + identity = empty_identity; + } + + status = m_eap_identity.set_copy_of_buffer( + identity, + identity_length); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_CORE_SERVER) + +//-------------------------------------------------- + +#if defined(USE_EAP_CORE_SERVER) + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_success( + const eap_am_network_id_c * const send_network_id, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_buf_chain_wr_c eap_success_packet( + eap_write_buffer, + m_am_tools, + EAP_CORE_PACKET_BUFFER_LENGTH); + + if (eap_success_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_success(): packet buffer corrupted: %s, %s\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT_ALWAYS(EAP_CORE_PACKET_BUFFER_LENGTH >= (m_eap_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_CORE_PACKET_BUFFER_LENGTH-m_trailer_length; + + if (m_eap_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_eap_header_offset+m_MTU; + } + + eap_header_wr_c eap_response( + m_am_tools, + eap_success_packet.get_data_offset( + m_eap_header_offset, + (packet_buffer_free-m_eap_header_offset)), + (packet_buffer_free-m_eap_header_offset)); + + if (eap_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_success(): %s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_response.reset_header( + static_cast((packet_buffer_free-m_eap_header_offset)), + m_use_eap_expanded_type); + eap_response.set_length( + static_cast((eap_header_wr_c::get_header_length())), + m_use_eap_expanded_type); + eap_response.set_code(eap_code_success); + eap_response.set_identifier(eap_identifier); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_success_packet.set_data_length(m_eap_header_offset+eap_response.get_header_length()); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" send: EAP-success packet"), + eap_response.get_header_buffer(eap_response.get_length()), + eap_response.get_length())); + + status = packet_send( + send_network_id, + &eap_success_packet, + m_eap_header_offset, + eap_response.get_length(), + EAP_CORE_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + // After EAP-Success is sent no re-transmissions must occur. + cancel_retransmission(); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_CORE_SERVER) + +//-------------------------------------------------- + +#if defined(USE_EAP_CORE_SERVER) + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_failure( + const eap_am_network_id_c * const send_network_id, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_eap_failure_sent == true) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_failure(): %s, %s, EAP-Failure already sent.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + eap_buf_chain_wr_c eap_failure_packet( + eap_write_buffer, + m_am_tools, + EAP_CORE_PACKET_BUFFER_LENGTH); + + if (eap_failure_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_failure(): %s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT_ALWAYS(EAP_CORE_PACKET_BUFFER_LENGTH >= (m_eap_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_CORE_PACKET_BUFFER_LENGTH-m_trailer_length; + + if (m_eap_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_eap_header_offset+m_MTU; + } + + eap_header_wr_c eap_response( + m_am_tools, + eap_failure_packet.get_data_offset( + m_eap_header_offset, + (packet_buffer_free-m_eap_header_offset)), + (packet_buffer_free-m_eap_header_offset)); + + if (eap_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_failure(): %s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_response.reset_header( + static_cast((packet_buffer_free-m_eap_header_offset)), + m_use_eap_expanded_type); + eap_response.set_length( + static_cast((eap_header_wr_c::get_header_length())), + m_use_eap_expanded_type); + eap_response.set_code(eap_code_failure); + eap_response.set_identifier(eap_identifier); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_failure_packet.set_data_length(m_eap_header_offset+eap_response.get_header_length()); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" send: EAP-failure packet"), + eap_response.get_header_buffer(eap_response.get_length()), + eap_response.get_length())); + + status = packet_send( + send_network_id, + &eap_failure_packet, + m_eap_header_offset, + eap_response.get_length(), + EAP_CORE_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + m_eap_failure_sent = true; + + // After EAP-Failure is sent no re-transmissions must occur. + cancel_retransmission(); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_CORE_SERVER) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_notification_response( + const eap_am_network_id_c * const send_network_id, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_buf_chain_wr_c eap_notification_packet( + eap_write_buffer, + m_am_tools, + EAP_CORE_PACKET_BUFFER_LENGTH); + + if (eap_notification_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_notification_response(): ") + EAPL("%s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT_ALWAYS(EAP_CORE_PACKET_BUFFER_LENGTH >= (m_eap_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_CORE_PACKET_BUFFER_LENGTH-m_trailer_length; + + if (m_eap_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_eap_header_offset+m_MTU; + } + + eap_header_wr_c eap_response( + m_am_tools, + eap_notification_packet.get_data_offset( + m_eap_header_offset, + (packet_buffer_free-m_eap_header_offset)), + (packet_buffer_free-m_eap_header_offset)); + + if (eap_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_core_c::send_eap_notification_response(): ") + EAPL("%s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_response.reset_header( + static_cast((packet_buffer_free-m_eap_header_offset)), + m_use_eap_expanded_type); + eap_response.set_length( + static_cast((eap_header_base_c::get_header_length()+1u)), + m_use_eap_expanded_type); + eap_response.set_code(eap_code_response); + eap_response.set_identifier(eap_identifier); + eap_response.set_type(eap_type_notification, m_use_eap_expanded_type); + + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_notification_packet.set_data_length( + m_eap_header_offset+eap_response.get_header_length()+1u); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: EAP-Response/Notification packet"), + eap_response.get_header_buffer(eap_response.get_length()), + eap_response.get_length())); + + status = packet_send( + send_network_id, + &eap_notification_packet, + m_eap_header_offset, + eap_response.get_length(), + EAP_CORE_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + // After EAP-Notification is sent no re-transmissions must occur. + cancel_retransmission(); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::create_eap_identity_response( + eap_buf_chain_wr_c * const response_packet, + const eap_variable_data_c * const identity, + const u8_t eap_identifier + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (identity == 0 + || identity->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + if (response_packet == 0 + || response_packet->get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted: %s, %s\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT_ALWAYS(EAP_CORE_PACKET_BUFFER_LENGTH >= (m_eap_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_CORE_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_eap_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_eap_header_offset+m_MTU; + } + + eap_header_wr_c eap_response( + m_am_tools, + response_packet->get_data_offset( + m_eap_header_offset, + (EAP_CORE_PACKET_BUFFER_LENGTH-(m_eap_header_offset+m_trailer_length))), + EAP_CORE_PACKET_BUFFER_LENGTH-(m_eap_header_offset+m_trailer_length)); + + if (eap_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_eap_identity_response: %s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_response.reset_header( + static_cast((packet_buffer_free-m_eap_header_offset)), + m_use_eap_expanded_type); + + eap_response.set_length( + static_cast((packet_buffer_free-m_eap_header_offset)), + m_use_eap_expanded_type); + eap_response.set_code(eap_code_response); + eap_response.set_identifier(eap_identifier); + eap_response.set_type(eap_type_identity, m_use_eap_expanded_type); + + packet_buffer_offset += eap_response.get_header_length(); + + u8_t * const target_nai = eap_response.get_type_data( + identity->get_data_length()); + if (target_nai == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_eap_identity_response: %s, %s, too long EAP-Identity.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Identity"), + identity->get_data(identity->get_data_length()), + identity->get_data_length())); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + target_nai, + identity->get_data(identity->get_data_length()), + identity->get_data_length()); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_response.set_type_data_length( + static_cast(identity->get_data_length()), + m_use_eap_expanded_type); + + response_packet->set_data_length(m_eap_header_offset+eap_response.get_length()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send EAP-identity NAI"), + eap_response.get_type_data(eap_response.get_type_data_length()), + eap_response.get_type_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_identity_response( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const identity, + const u8_t eap_identifier + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (send_network_id == 0 + || identity == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_buf_chain_wr_c response_packet( + eap_write_buffer, + m_am_tools, + EAP_CORE_PACKET_BUFFER_LENGTH); + + if (response_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted: %s, %s.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + // Get add possible NAI decoration and + // extra routing info to identity + + eap_variable_data_c local_identity(m_am_tools); + status = local_identity.set_copy_of_buffer(identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_eap_identity_routing_info_and_nai_decoration(&local_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = create_eap_identity_response( + &response_packet, + &local_identity, + eap_identifier); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_header_wr_c eap_response( + m_am_tools, + response_packet.get_data_offset( + m_eap_header_offset, + (response_packet.get_buffer_length()-(m_eap_header_offset+m_trailer_length))), + response_packet.get_buffer_length()-(m_eap_header_offset+m_trailer_length)); + if (eap_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_eap_identity_response: %s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most" + )); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = packet_send( + send_network_id, + &response_packet, + m_eap_header_offset, + eap_response.get_length(), + response_packet.get_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + if (m_is_tunneled_eap == false + && m_is_client_role == true) + { + status = cancel_wait_eap_request_type_timeout(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_wait_eap_request_type_timeout(); + } + +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eap_core_c::set_eap_identity_routing_info_and_nai_decoration( + eap_variable_data_c * const identity) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (identity == 0 + || identity->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + bool routing_info_available(true); + bool nai_decoration_available(true); + + eap_status_e status(eap_status_process_general_error); + + // read routing info from AM + eap_variable_data_c routing_info(m_am_tools); + status = read_configure( + cf_str_EAP_outer_identity_routing.get_field(), + &routing_info); + if (status != eap_status_ok + || routing_info.get_is_valid_data() == false + || routing_info.get_data_length() == 0) + { + routing_info_available = false; + } + + // read NAI decoration from AM + eap_variable_data_c nai_decoration(m_am_tools); + status = read_configure( + cf_str_EAP_outer_identity_decoration.get_field(), + &nai_decoration); + if (status != eap_status_ok + || nai_decoration.get_is_valid_data() == false + || nai_decoration.get_data_length() == 0) + { + nai_decoration_available = false; + } + + // nothing to be added (which is ok) + if(routing_info_available == false + && nai_decoration_available == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + eap_variable_data_c username(m_am_tools); + eap_variable_data_c home_realm(m_am_tools); + + // get username and home realm from the current NAI + status = m_am_tools->parse_nai( + identity, + &username, + &home_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // username must be present + if (username.get_is_valid_data() == false + /* || home_realm.get_is_valid_data() == false */) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // original NAI can be cleared, + // the new one is constructed to the same place + identity->reset(); + + // routing_info contains a string in format + // "RoutingRealm1!RoutingRealm2!RoutingRealm3" + // in which RoutingRealm3 is replaced with the home + // realm and RoutingRealm1 is appended after @-sign in NAI + if(routing_info_available == true) + { + // this points to the last byte of routing_info + const u8_t* const p_last = + routing_info.get_data() + + (routing_info.get_data_length() - 1); + + // first and last characters cannot be !-signs + if(*p_last == EAP_NAI_ROUTING_REALM_SEPARATOR[0] + || *(routing_info.get_data()) == EAP_NAI_ROUTING_REALM_SEPARATOR[0]) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // find first !-sign + const u8_t *separator = reinterpret_cast( + m_am_tools->memchr( + routing_info.get_data(), + EAP_NAI_ROUTING_REALM_SEPARATOR[0], + routing_info.get_data_length()) + ); + + // !-sign found, more than one realm present + // (the sign is not first or last character) + if (separator != 0) + { + // others except the first realm are put in front + status = identity->add_data( + separator + 1, + p_last - separator); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // add !-sign + status = identity->add_data(EAP_NAI_ROUTING_REALM_SEPARATOR, 1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + + // add home realm if it existed + if(home_realm.get_is_valid_data() == true) + { + status = identity->add_data( + home_realm.get_data(), + home_realm.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // add !-sign + status = identity->add_data(EAP_NAI_ROUTING_REALM_SEPARATOR, 1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // store the first realm of routing info here + home_realm.reset(); + + // more than one realm in routing info + if (separator != 0) + { + status = home_realm.add_data( + routing_info.get_data(), + separator - routing_info.get_data() + ); + } + // only one realm in routing info + else + { + status = home_realm.add_data( + routing_info.get_data(), + routing_info.get_data_length()); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // nai_decoration contains a string which is placed + // in front of the username in NAI + if(nai_decoration_available == true) + { + status = identity->add_data(nai_decoration.get_data(), nai_decoration.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = identity->add_data(username.get_data(), username.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // add realm if it exists + if (home_realm.get_is_valid_data() == true) { + // add @-sign + status = identity->add_data(EAP_NAI_AT_CHARACTER, 1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = identity->add_data(home_realm.get_data(), home_realm.get_data_length()); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::complete_eap_identity_query( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const identity, + const u8_t /*eap_identifier*/) // Remove eap_identifier parameter. +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_illegal_eap_identity); + + if (identity != 0) + { + status = m_eap_identity.set_copy_of_buffer(identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_eap_identity_response( + send_network_id, + identity, + m_eap_identity_request_identifier_client); // Uses the EAP-Identifier from the latest EAP-Request/Identity. + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::get_saved_eap_identity( + eap_variable_data_c * const identity) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_illegal_eap_identity; + + if (m_eap_identity.get_is_valid_data() == true) + { + status = identity->set_copy_of_buffer(&m_eap_identity); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: %s, %s, EAP-identity is unknown: current EAP-type 0x%08x\n"), + (m_is_client == true) ? "client": "server", + (m_is_tunneled_eap == true) ? "tunneled": "outer most", + convert_eap_type_to_u32_t(m_current_eap_type))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_WARNING(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::set_session_timeout( + const u32_t session_timeout_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = initialize_session_timeout(session_timeout_ms); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_is_tunneled_eap == true) + { + status = m_partner->set_session_timeout(session_timeout_ms); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_core_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::set_authentication_role(const bool when_true_set_client) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + cancel_retransmission(); + + cancel_eap_failure_timeout(); + + m_is_client_role = when_true_set_client; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_core_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_partner->add_rogue_ap(rogue_ap_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_core_c::get_is_tunneled_eap() const +{ + return m_is_tunneled_eap; +} + +//-------------------------------------------------- +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eap_core_map.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eap_core_map.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 45 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +Not used anymore, JPH + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eap_core_nak_info.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eap_core_nak_info.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 46 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_core_nak_info.h" + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_core_nak_info_c::~eap_core_nak_info_c() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_core_nak_info_c::eap_core_nak_info_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const receive_network_id, + const eap_type_value_e proposed_eap_type, + const u8_t eap_identifier) + : eap_am_network_id_c(tools, receive_network_id) + , m_proposed_eap_type(proposed_eap_type) + , m_eap_identifier(eap_identifier) +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_type_value_e eap_core_nak_info_c::get_proposed_eap_type() const +{ + return m_proposed_eap_type; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u8_t eap_core_nak_info_c::get_eap_identifier() const +{ + return m_eap_identifier; +} + + +//-------------------------------------------------- +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eap_core_retransmission.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eap_core_retransmission.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,232 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 47 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_core.h" +#include "eap_core.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "abs_eap_base_timer.h" +#include "eap_core_retransmission.h" +#include "eap_buffer.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_core_retransmission_c::~eap_core_retransmission_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (m_send_network_id != 0) + { + delete m_send_network_id; + m_send_network_id = 0; + } + if (m_sent_packet != 0) + { + delete m_sent_packet; + m_sent_packet = 0; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_core_retransmission_c::eap_core_retransmission_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t retransmission_time, + const u32_t retransmission_counter, + const eap_code_value_e eap_code, + const u8_t eap_identifier, + const eap_type_value_e eap_type) + : m_am_tools(tools) + , m_send_network_id(send_network_id->copy()) + , m_sent_packet(sent_packet->copy()) + , m_header_offset(header_offset) + , m_data_length(data_length) + , m_is_valid(false) + , m_retransmission_time(retransmission_time) + , m_retransmission_counter(retransmission_counter) + , m_eap_code(eap_code) + , m_eap_identifier(eap_identifier) + , m_eap_type(eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_send_network_id != 0 + && m_sent_packet != 0 + && m_send_network_id->get_is_valid_data() == true) + { + m_is_valid = true; + } + else + { + if (m_send_network_id != 0) + { + delete m_send_network_id; + m_send_network_id = 0; + } + if (m_send_network_id != 0) + { + delete m_sent_packet; + m_sent_packet = 0; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_core_retransmission_c::get_is_valid() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_core_retransmission_c::get_next_retransmission_counter() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return --m_retransmission_counter; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_core_retransmission_c::get_retransmission_counter() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_retransmission_counter; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_core_retransmission_c::get_next_retransmission_time() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + u32_t time = m_retransmission_time; + + u32_t jitter_data = 0ul; + i32_t jitter = 0; + eap_status_e status = m_am_tools->get_crypto()->get_rand_bytes( + reinterpret_cast(&jitter_data), + sizeof(jitter_data)); + if (status != eap_status_ok) + { + jitter = 0; + } + else + { + // Jitter should be -m_retransmission_time/2 ... m_retransmission_time/2. + jitter_data = (jitter_data % (m_retransmission_time)); + jitter = jitter_data - m_retransmission_time/2; + } + m_retransmission_time += (m_retransmission_time + jitter); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return time; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_network_id_c *eap_core_retransmission_c::get_send_network_id() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_send_network_id; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_buf_chain_wr_c * eap_core_retransmission_c::get_sent_packet() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_sent_packet; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_core_retransmission_c::get_header_offset() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_header_offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_core_retransmission_c::get_data_length() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_data_length; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_core_retransmission_c::get_buffer_size() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_sent_packet->get_buffer_length(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_code_value_e eap_core_retransmission_c::get_eap_code() const +{ + return m_eap_code; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t eap_core_retransmission_c::get_eap_identifier() const +{ + return m_eap_identifier; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_value_e eap_core_retransmission_c::get_eap_type() const +{ + return m_eap_type; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eap_session_core.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eap_session_core.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1462 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 60 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_session_core.h" +#include "eap_state_notification.h" +#include "eap_network_id_selector.h" +#include "abs_eap_am_mutex.h" +#include "eap_config.h" +#include "eap_core.h" +#include "eap_buffer.h" +#include "eap_base_type.h" +#include "eap_automatic_variable.h" + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_session_core_c::~eap_session_core_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::~eap_session_core_c(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + EAP_ASSERT(m_shutdown_was_called == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +// +EAP_FUNC_EXPORT eap_session_core_c::eap_session_core_c( + abs_eap_am_tools_c * const tools, + abs_eap_core_c * const partner, + const bool is_client_when_true) +: m_partner(partner) +, m_am_tools(tools) +, m_session_map(tools, this) +, m_remove_session_timeout(EAP_SESSION_CORE_REMOVE_SESSION_TIMEOUT) +, m_is_client(is_client_when_true) +, m_is_valid(false) +, m_use_eap_session_core_reset_session(true) +, m_shutdown_was_called(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::eap_session_core_c(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT abs_eap_core_c * eap_session_core_c::get_partner() +{ + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + return m_partner; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_session_core_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_session_core_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::reset(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + eap_status_e status = m_session_map.for_each(shutdown_operation, true); + (void)EAP_STATUS_RETURN(m_am_tools, status); + + status = m_session_map.reset(); + (void)EAP_STATUS_RETURN(m_am_tools, status); + + m_partner->cancel_timer(this, EAP_SESSION_CORE_REMOVE_SESSION_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAP_SESSION_CORE_REMOVE_SESSION_ID cancelled, %s.\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = m_partner->load_module( + type, + tunneling_type, + partner, + eap_type, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_core_c * eap_session_core_c::create_new_session( + const eap_am_network_id_c * const receive_network_id) +{ + eap_status_e status = eap_status_process_general_error; + + // Create a new session. + eap_core_c *session = new eap_core_c( + m_am_tools, + this, + m_is_client, + receive_network_id, + false); + + if (session == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + if (session->get_is_valid() == false) + { + session->shutdown(); + delete session; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + status = session->configure(); + if (status != eap_status_ok) + { + session->shutdown(); + delete session; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return 0; + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + session->shutdown(); + delete session; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + session->shutdown(); + delete session; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("create_new_session() EAP-session"), + selector.get_data(selector.get_data_length()), + selector.get_data_length())); + + status = m_session_map.add_handler(&selector, session); + if (status != eap_status_ok) + { + session->shutdown(); + delete session; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return 0; + } + + return session; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::reset_or_remove_session( + eap_core_c ** const session, + const eap_network_id_selector_c * const selector, + const bool reset_immediately) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + if (session == 0 + || *session == 0 + || selector == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + if (m_use_eap_session_core_reset_session == true) + { + // This will reuse session. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::reset_or_remove_session(): resets session, session 0x%08x.\n"), + (*session))); + + // NOTE, this delayed reset of session is used bacause the device is so slow it cannot respond to + // 4-Way Handshake message fast enough. + + if (reset_immediately == true) + { + (*session)->unset_marked_removed(); + + status = (*session)->reset(); + } + else + { + // This will delay reset to eap_core_c::packet_process(). + status = eap_status_ok; + } + } + else + { + // This will cause shutdown of the session. + status = eap_status_process_general_error; + } + + if (status != eap_status_ok) + { + // We cannot reuse the session. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::reset_or_remove_session(): shutdown session, session 0x%08x.\n"), + (*session))); + + (*session)->shutdown(); + (*session) = 0; + + status = m_session_map.remove_handler(selector, true); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eap_session_core_c::reset_or_remove_session(): m_session_map.remove_type(), eap_status_e %d\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::reset_or_remove_session(): session NOT reused.\n"))); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::reset_or_remove_session(): session reused, session 0x%08x.\n"), + (*session))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + // Each EAP authentication session includes own eap_core_c object. + // EAP authentication sessions are separated by eap_am_network_id_c object. + + if (packet_data == 0 + || packet_length < eap_header_base_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_header_wr_c eap( + m_am_tools, + packet_data->get_header_buffer(packet_data->get_header_buffer_length()), + packet_data->get_header_buffer_length()); + + if (eap.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (packet_length < eap.get_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (eap.get_code() == eap_code_none) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("-> EAP_session: %s, code=0x%02x=%s, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x=%s, packet length 0x%04x\n"), + (m_is_client == true) ? "client": "server", + eap.get_code(), + eap.get_code_string(), + eap.get_identifier(), + eap.get_length(), + convert_eap_type_to_u32_t(eap.get_type()), + eap.get_type_string(), + packet_length)); + + status = eap.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_process() EAP-session"), + selector.get_data(selector.get_data_length()), + selector.get_data_length())); + + eap_core_c *session = m_session_map.get_handler(&selector); + + if (session == 0) + { + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + +#else + // Create a new session. + session = create_new_session(receive_network_id); + +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + } + + if (session != 0) + { + status = session->packet_process( + receive_network_id, + &eap, + packet_length); + + EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eap); + } + else + { + status = eap_status_illegal_eap_type; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_header_wr_c eap( + m_am_tools, + sent_packet->get_data_offset(header_offset, data_length), + data_length); + + if (eap.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_ASSERT(header_offset < sent_packet->get_data_length()); + EAP_ASSERT(data_length <= sent_packet->get_data_length()); + EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("<- EAP_session: %s, code=0x%02x=%s, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x=%s, packet length 0x%04x\n"), + (m_is_client == true) ? "client": "server", + eap.get_code(), + eap.get_code_string(), + eap.get_identifier(), + eap.get_length(), + convert_eap_type_to_u32_t(eap.get_type()), + eap.get_type_string(), + data_length)); + + eap_status_e status = m_partner->packet_send( + send_network_id, sent_packet, header_offset, data_length, buffer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_session_core_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const u32_t offset = m_partner->get_header_offset(MTU, trailer_length); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return offset; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + + { + // This is optional. + eap_variable_data_c data(m_am_tools); + + eap_status_e status = m_partner->read_configure( + cf_str_EAP_SESSION_use_reset_session.get_field(), + &data); + if (status == eap_status_ok + && data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + u32_t *flag = reinterpret_cast(data.get_data(data.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_use_eap_session_core_reset_session = true; + } + else + { + m_use_eap_session_core_reset_session = false; + } + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::shutdown_operation( + eap_core_c * const core, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + eap_status_e status = core->shutdown(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::shutdown(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + eap_status_e status = reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->unload_module(type); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::eap_acknowledge( + const eap_am_network_id_c * const receive_network_id) +{ + // Any Network Protocol packet is accepted as a success indication. + // This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (receive_network_id == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_acknowledge() EAP-session"), + selector.get_data(selector.get_data_length()), + selector.get_data_length())); + + eap_core_c *session = m_session_map.get_handler(&selector); + + if (session != 0) + { + status = session->eap_acknowledge( + receive_network_id); + } + else + { + // Here we do not care of missing session. + // Acknowledge is meaningfull only for existing session. + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::restart_authentication( + const eap_am_network_id_c * const send_network_id, + const bool is_client_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + eap_network_id_selector_c selector( + m_am_tools, + send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("restart_authentication() EAP-session"), + selector.get_data(selector.get_data_length()), + selector.get_data_length())); + + eap_core_c *session = m_session_map.get_handler(&selector); + + if (session != 0) + { + status = session->restart_authentication(send_network_id, is_client_when_true); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool /* is_client_when_true */, + const bool force_clean_restart, + const bool /* from_timer */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("restart_authentication() EAP-session"), + selector.get_data(selector.get_data_length()), + selector.get_data_length())); + + eap_core_c *session = m_session_map.get_handler(&selector); + + if (session == 0) + { + // Create a new session. + session = create_new_session(receive_network_id); + } + + if (session != 0) + { + status = m_partner->restart_authentication( + receive_network_id, + m_is_client, + force_clean_restart); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_CORE_SERVER) + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::send_eap_identity_request( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::send_eap_identity_request()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_session_core_c::send_eap_identity_request()"); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_eap_identity_request() EAP-session"), + selector.get_data(selector.get_data_length()), + selector.get_data_length())); + + eap_core_c *session = m_session_map.get_handler(&selector); + + if (session == 0) + { + // Create a new session. + session = create_new_session(receive_network_id); + } + + if (session != 0) + { + status = session->send_eap_identity_request(receive_network_id); + (void)EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_CORE_SERVER) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->packet_data_crypto_keys( + send_network_id, + master_session_key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->read_configure(field, data); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->write_configure(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::timer_expired( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_session_core_c::") + EAPL("timer_expired(id 0x%02x, data 0x%08x), %s.\n"), + this, + id, + data, + (m_is_client == true) ? "client": "server")); + + if (id == EAP_SESSION_CORE_REMOVE_SESSION_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAP_SESSION_CORE_REMOVE_SESSION_ID elapsed, %s.\n"), + (m_is_client == true) ? "client": "server")); + + const eap_network_id_selector_c * const selector + = reinterpret_cast(data); + if (selector == 0 + || selector->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("timer_expired() EAP-session"), + selector->get_data(selector->get_data_length()), + selector->get_data_length())); + + eap_core_c *session = m_session_map.get_handler(selector); + + if (session != 0 + && session->get_marked_removed() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: unused session found, it is deleted, session 0x%08x.\n"), + session)); + + // Session must be deleted here. + session->shutdown(); + session = 0; + + // This will delete session. + eap_status_e status = m_session_map.remove_handler(selector, true); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: m_session_map.remove_type(), eap_status_e %d\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (session != 0 + && session->get_marked_removed() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: session found, it is in use, session 0x%08x.\n"), + session)); + } + else + { + // Not found, no need to remove. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: session not found.\n"))); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::timer_delete_data( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_session_core_c::") + EAPL("timer_delete_data(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + + if (id == EAP_SESSION_CORE_REMOVE_SESSION_ID) + + { + const eap_network_id_selector_c * const selector + = reinterpret_cast(data); + delete selector; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::synchronous_cancel_all_eap_sessions() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::synchronous_cancel_all_eap_sessions(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + eap_status_e status = reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::synchronous_create_eap_session( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::synchronous_create_eap_session(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + eap_status_e status = eap_status_process_general_error; + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("synchronous_create_eap_session() EAP-session"), + selector.get_data(selector.get_data_length()), + selector.get_data_length())); + + eap_core_c *session = m_session_map.get_handler(&selector); + + if (session == 0) + { + session = create_new_session(receive_network_id); + + if (session == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + else + { + status = eap_status_ok; + } + } + else + { + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::synchronous_remove_eap_session( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::synchronous_remove_eap_session(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + eap_status_e status = eap_status_process_general_error; + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("synchronous_remove_eap_session() EAP-session"), + selector.get_data(selector.get_data_length()), + selector.get_data_length())); + + eap_core_c *session = m_session_map.get_handler(&selector); + + if (session != 0) + { + // This reset is immediaete. + status = reset_or_remove_session( + &session, + &selector, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Not found, no need to remove. + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eap_session_core_c::asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::asynchronous_init_remove_eap_session(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_network_id_selector_c state_selector( + m_am_tools, + send_network_id); + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("asynchronous_init_remove_eap_session() EAP-session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eap_status_e status = asynchronous_init_remove_eap_session( + &state_selector); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eap_session_core_c::asynchronous_init_remove_eap_session( + const eap_network_id_selector_c * const state_selector) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::asynchronous_init_remove_eap_session(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + // NOTE: we cannot call directly synchronous_remove_eap_session(), because we will + // return from here to removed object. + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("asynchronous_init_remove_eap_session() EAP-session"), + state_selector->get_data(state_selector->get_data_length()), + state_selector->get_data_length())); + + eap_core_c *session = m_session_map.get_handler(state_selector); + + if (session != 0) + { + session->set_marked_removed(); + + // So we initiate a timer to remove session identified by state_selector. + eap_network_id_selector_c * const copy_selector = state_selector->copy(); + if (copy_selector == 0 + || copy_selector->get_is_valid() == false) + { + delete copy_selector; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_partner->set_timer( + this, + EAP_SESSION_CORE_REMOVE_SESSION_ID, + copy_selector, + m_remove_session_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::asynchronous_init_remove_eap_session()") + EAPL(": %s: EAP_SESSION_CORE_REMOVE_SESSION_ID timer set %d ms.\n"), + (m_is_client == true) ? "client": "server", + m_remove_session_timeout)); + } + else + { + // Not found, cannot remove. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eap_session_core_c::asynchronous_init_remove_eap_session()") + EAPL(": %s: failed session not found.\n"), + (m_is_client == true) ? "client": "server")); + + status = eap_status_ok; + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_session_core_c::state_notification( + const abs_eap_state_notification_c * const state) +{ + m_partner->state_notification(state); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::check_is_valid_eap_type( + const eap_type_value_e eap_type) +{ + eap_status_e status = m_partner->check_is_valid_eap_type(eap_type); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + eap_status_e status = m_partner->get_eap_type_list(eap_type_list); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_partner->add_rogue_ap(rogue_ap_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_session_core_c::set_session_timeout( + const u32_t /* session_timeout_ms */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eap_type_selection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eap_type_selection.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 61 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_type_selection.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_selection_c::~eap_type_selection_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_selection_c::eap_type_selection_c( + abs_eap_am_tools_c * const tools, + const eap_type_value_e type, + const bool is_enabled) + : m_am_tools(tools) + , m_type(type) + , m_is_enabled(is_enabled) + , m_is_valid(true) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_value_e eap_type_selection_c::get_type() const +{ + return m_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_selection_c::get_is_enabled() const +{ + return m_is_enabled; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_selection_c * eap_type_selection_c::copy() const +{ + eap_type_selection_c * const copy_object = new eap_type_selection_c( + m_am_tools, + m_type, + m_is_enabled); + + return copy_object; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_selection_c::get_is_valid() const +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_selection_c::get_is_valid_data() const +{ + return (m_type != eap_type_none); +} + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eap_wimax_authentication.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eap_wimax_authentication.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1304 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP stack interface for Wimax. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 1001 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include + +#include +#include +#include +#include "eap_type_all.h" + +#include "eap_wimax_authentication.h" +#include "eap_session_core.h" +#include +#include +#include +#include +#include +#include +#include "eap_automatic_variable.h" +#include + +#include +#include + + +#if defined(USE_EAP_WIMAX_AUTHENTICATION_MUTEX) + + #if defined(USE_TEST_WIMAX_AUTHENTICATION_MUTEX) + #error "You cannot define both USE_EAP_WIMAX_AUTHENTICATION_MUTEX and USE_TEST_WIMAX_AUTHENTICATION_MUTEX." + #endif + + #define WAUTH_ENTER_MUTEX(tools) { tools->enter_global_mutex(); } + + #define WAUTH_LEAVE_MUTEX(tools) { tools->leave_global_mutex(); } + +#else + + #define WAUTH_ENTER_MUTEX(tools) + + #define WAUTH_LEAVE_MUTEX(tools) + +#endif //#if defined(USE_EAP_WIMAX_AUTHENTICATION_MUTEX) + + + +// ================= MEMBER FUNCTIONS ======================= + +EAP_FUNC_EXPORT eap_wimax_authentication_c::~eap_wimax_authentication_c() +{ + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eap_wimax_authentication_c::~eap_wimax_authentication_c(): this = 0x%08x\n"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eap_wimax_authentication_c::~eap_wimax_authentication_c()\n"); + + EAP_ASSERT(m_shutdown_was_called == true); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_wimax_authentication_c::eap_wimax_authentication_c +(abs_eap_am_tools_c* const tools, + abs_eap_wimax_authentication_c* const partner, + // eap_wimax_authentication_c must always delete the am_wauth object + eap_am_wimax_authentication_c* const am_wauth, + const bool is_client_when_true) + : m_am_tools(tools), + m_partner(partner), + m_am_wauth(am_wauth), + m_eap_core(0), // created in configure + m_is_valid(false), + m_is_client(is_client_when_true), + m_shutdown_was_called(false), + m_block_state_notifications(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("starts: eap_wimax_authentication_c::eap_wimax_authentication_c(): %s, this = 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_wimax_authentication_c::eap_wimax_authentication_c()\n"); + + if (m_am_wauth == 0 + || m_am_wauth->get_is_valid() == false) + { + // ERROR. + if (m_am_wauth != 0) + { + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::eap_wimax_authentication_c(): m_am_wauth->shutdown(): %s.\n"), + (is_client_when_true == true) ? "client": "server")); + + m_am_wauth->shutdown(); + delete am_wauth; + } + return; + } + + if (m_am_tools == 0 + || m_am_tools->get_is_valid() == false) + { + // ERROR. + if (m_am_wauth != 0) + { + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::eap_wimax_authentication_c(): m_am_wauth->shutdown(): %s.\n"), + (is_client_when_true == true) ? "client": "server")); + + m_am_wauth->shutdown(); + delete am_wauth; + } + return; + } + + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_wimax_authentication_c* eap_wimax_authentication_c::new_eap_wimax_authentication_c +(abs_eap_am_tools_c* const tools, + abs_eap_wimax_authentication_c* const partner, + const bool is_client_when_true, + const abs_eapol_wlan_database_reference_if_c* const wimax_database_reference) +{ + EAP_TRACE_DEBUG + (tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eap_wimax_authentication_c::new_eap_wimax_authentication_c()\n"))); + + EAP_TRACE_RETURN_STRING(tools, "returns to partner: eap_wimax_authentication_c::new_eap_wimax_authentication_c()\n"); + + eap_am_wimax_authentication_c* m_am_wauth = eap_am_wimax_authentication_c::new_eap_am_wimax_authentication + (tools, + is_client_when_true, + wimax_database_reference); + + if (m_am_wauth == 0 + || m_am_wauth->get_is_valid() == false) + { + // ERROR. + if (m_am_wauth != 0) + { + EAP_TRACE_DEBUG + (tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::new_eap_wimax_authentication_c(): m_am_wauth->shutdown(): %s.\n"), + (is_client_when_true == true) ? "client": "server")); + + m_am_wauth->shutdown(); + delete m_am_wauth; + m_am_wauth = 0; + } + return 0; + } + + eap_wimax_authentication_c* wauth = new eap_wimax_authentication_c(tools, partner, m_am_wauth, is_client_when_true); + if (wauth == 0 + || wauth->get_is_valid() == false) + { + // ERROR. + if (wauth != 0) + { + wauth->shutdown(); + delete wauth; + } + return 0; + } + + EAP_TRACE_DEBUG + (tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::new_eap_wimax_authentication_c(): m_am_wauth->set_am_partner(): %s.\n"), + (is_client_when_true == true) ? "client": "server")); + + m_am_wauth->set_am_partner(wauth); + + return wauth; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eap_wimax_authentication_c::shutdown(); %s, m_shutdown_was_called=%d\n"), + (m_is_client == true) ? "client": "server", + m_shutdown_was_called)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eap_wimax_authentication_c::shutdown()\n"); + + if (m_shutdown_was_called == true) + { + // Shutdown was already called once. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + m_shutdown_was_called = true; + + // Cancel timers + cancel_all_timers(); + + // Delete upper stack if it still exists + if (m_eap_core != 0) + { + WAUTH_ENTER_MUTEX(m_am_tools); + + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eap: eap_wimax_authentication_c::shutdown(): m_eap_core->shutdown(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_eap_core->shutdown(); + + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eap: eap_wimax_authentication_c::shutdown(): m_eap_core->shutdown(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + EAP_UNREFERENCED_PARAMETER(status); // in release + + WAUTH_LEAVE_MUTEX(m_am_tools); + + delete m_eap_core; + m_eap_core = 0; + } + + if (m_am_wauth != 0) + { + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::shutdown(): m_am_wauth->shutdown(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + m_am_wauth->shutdown(); + delete m_am_wauth; + m_am_wauth = 0; + } + + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WAUTH EXITING.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::cancel_all_authentication_sessions() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_wimax_authentication_c::cancel_all_authentication_sessions(): this = 0x%08x.\n"), + this)); + + eap_status_e status(eap_status_ok); + + bool previous_block = m_block_state_notifications; + m_block_state_notifications = true; + + if (m_eap_core != 0) + { + + WAUTH_ENTER_MUTEX(m_am_tools); + + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eap: eap_wimax_authentication_c:cancel_all_authentication_sessions(): m_eap_core->synchronous_cancel_all_eap_sessions(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_eap_core->synchronous_cancel_all_eap_sessions(); + + EAP_TRACE_DEBUG + (m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eap: eap_wimax_authentication_c:cancel_all_authentication_sessions(): m_eap_core->synchronous_cancel_all_eap_sessions(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + WAUTH_LEAVE_MUTEX(m_am_tools); + } + + m_block_state_notifications = previous_block; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_wimax_authentication_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_wimax_authentication_c::get_is_client() +{ + return m_is_client; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_wimax_authentication_c::packet_data_crypto_keys()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (master_session_key->get_is_valid() == true) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("master session key"), + master_session_key->get_data(master_session_key->get_data_length()), + master_session_key->get_data_length())); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eap_wimax_authentication_c::packet_data_crypto_keys(): %s: m_partner->packet_data_crypto_keys()\n"), + (m_is_client == true) ? "client": "server")); + + // Forward the keys to lower layers (defined in abs_eap_wimax_authentication_c) + status = m_partner->packet_data_crypto_keys(send_network_id, master_session_key); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eap_wimax_authentication_c::packet_data_crypto_keys(): %s: m_partner->packet_data_crypto_keys(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eap_wimax_authentication_c::packet_send(data_length=%d): %s.\n"), + data_length, + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::packet_send()\n"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status(eap_status_ok); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eap_wimax_authentication_c::packet_send(): %s: m_partner->packet_send()\n"), + (m_is_client == true) ? "client": "server")); + + // Here we send the original packet. + status = m_partner->packet_send( + network_id, + sent_packet, + header_offset, + data_length, + buffer_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eap_wimax_authentication_c::packet_send(): %s: m_partner->packet_send(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_wimax_authentication_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eap_wimax_authentication_c::get_header_offset()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::get_header_offset()\n"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eap_wimax_authentication_c::get_header_offset(): %s: m_partner->get_header_offset()\n"), + (m_is_client == true) ? "client": "server")); + + // we ask these from the partner in case it wants to leave some + // room for adding something (e.g. Ethernet header) + const u32_t offset = m_partner->get_header_offset(MTU, trailer_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eap_wimax_authentication_c::get_header_offset(): %s: m_partner->get_header_offset(): offset = %d\n"), + (m_is_client == true) ? "client": "server", + offset)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return offset; + +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eap_wimax_authentication_c::load_module(type 0x%08x=%s, tunneling_type 0x%08x=%s)\n"), + convert_eap_type_to_u32_t(type), + eap_header_string_c::get_eap_type_string(type), + convert_eap_type_to_u32_t(tunneling_type), + eap_header_string_c::get_eap_type_string(tunneling_type))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::load_module()\n"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::load_module(): m_am_wauth->load_module(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->load_module( + type, + tunneling_type, + partner, + eap_type, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::unload_module(const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap calls: eap_wimax_authentication_c::unload_module(type 0x%08x=%s): \n"), + convert_eap_type_to_u32_t(eap_type), + eap_header_string_c::get_eap_type_string(eap_type) + )); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::unload_module()\n"); + + eap_status_e status(eap_status_type_does_not_exists_error); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::unload_module(): m_am_wauth->unload_module(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_am_wauth->unload_module(eap_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_not_supported); + +#if defined(USE_EAP_CORE_SERVER) + if(is_client_when_true == false) + { + // only the server can start authentication + status = m_eap_core->send_eap_identity_request(receive_network_id); + } +#endif + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eap_wimax_authentication_c::read_configure(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::read_configure()\n"); + + EAP_ASSERT_ALWAYS(data != 0); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::read_configure(): m_am_wauth->read_configure(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->read_configure(field, data); + + m_am_tools->trace_configuration( + status, + field, + data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eap_wimax_authentication_c::write_configure(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::write_configure()\n"); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::write_configure(): m_am_wauth->write_configure(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->write_configure(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_wimax_authentication_c::state_notification( + const abs_eap_state_notification_c * const state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap calls: eap_wimax_authentication_c::state_notification()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::state_notification()\n"); + + // Calls lower layer. + m_partner->state_notification(state); + + // AM could have to show some notification to user. + m_am_wauth->state_notification(state); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + // not supported + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap calls: eap_wimax_authentication_c::set_timer(): id = %d, data = 0x%08x, time = %d\n"), + id, + data, + time_ms)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::set_timer()\n"); + + const eap_status_e status = m_am_tools->am_set_timer( + initializer, + id, + data, + time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap calls: eap_wimax_authentication_c::cancel_timer(): initializer = 0x%08x, id = %d\n"), + initializer, + id)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::cancel_timer()\n"); + + const eap_status_e status = m_am_tools->am_cancel_timer( + initializer, + id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap calls: eap_wimax_authentication_c::cancel_all_timers()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::cancel_all_timers()\n"); + + eap_status_e status = eap_status_ok; + + if (m_am_tools != 0) + { + WAUTH_ENTER_MUTEX(m_am_tools); + status = m_am_tools->am_cancel_all_timers(); + WAUTH_LEAVE_MUTEX(m_am_tools); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::check_is_valid_eap_type( + const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap calls: eap_wimax_authentication_c::check_is_valid_eap_type()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::check_is_valid_eap_type()\n"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::check_is_valid_eap_type(): m_am_wauth->check_is_valid_eap_type(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->check_is_valid_eap_type(eap_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap calls: eap_wimax_authentication_c::get_eap_type_list()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::get_eap_type_list()\n"); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::get_eap_type_list(): m_am_wauth->get_eap_type_list(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->get_eap_type_list(eap_type_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + // not used in Wimax + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::set_session_timeout( + const u32_t /* session_timeout_ms */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + // not supported + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eap_wimax_authentication_c::packet_process(): %s\n"), + (m_is_client == true) ? "client": "server")); + + if (packet_data == 0 + || packet_length < eap_header_base_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_header_wr_c eap( + m_am_tools, + packet_data->get_header_buffer(packet_data->get_header_buffer_length()), + packet_data->get_header_buffer_length()); + + if (eap.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (packet_length < eap.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (m_eap_core == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Forward the packet to the EAP layer of the EAP stack. + // Ignore return value. Failure is signalled using state_notification. + WAUTH_ENTER_MUTEX(m_am_tools); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eap_wimax_authentication_c::packet_process(): m_eap_core->packet_process(): %s. %d %d\n"), + (m_is_client == true) ? "client": "server", eap.get_data_length(), packet_length)); + + eap_status_e status = m_eap_core->packet_process( + receive_network_id, + &eap, + packet_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eap_wimax_authentication_c::packet_process(): m_eap_core->packet_process(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + EAP_UNREFERENCED_PARAMETER(status); // in release + + WAUTH_LEAVE_MUTEX(m_am_tools); + + EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eap); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::eap_acknowledge( + const eap_am_network_id_c * const receive_network_id) +{ + // Any Network Protocol packet is accepted as a success indication. + // This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (m_eap_core == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + WAUTH_ENTER_MUTEX(m_am_tools); + eap_status_e status = m_eap_core->eap_acknowledge(receive_network_id); + WAUTH_LEAVE_MUTEX(m_am_tools); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::configure() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eap_wimax_authentication_c::configure(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eap_wimax_authentication_c::configure()\n"); + + //---------------------------------------------------------- + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::configure(): m_am_wauth->configure(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_disable_traces(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_disable_traces.get_field(), + &EAP_TRACE_disable_traces); + if (status == eap_status_ok + && EAP_TRACE_disable_traces.get_is_valid_data() == true) + { + u32_t *disable_traces = reinterpret_cast( + EAP_TRACE_disable_traces.get_data(sizeof(u32_t))); + if (disable_traces != 0 + && *disable_traces != 0) + { + m_am_tools->set_trace_mask(eap_am_tools_c::eap_trace_mask_none); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_activate_only_trace_masks_always_and_error(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_activate_only_trace_masks_always_and_error.get_field(), + &EAP_TRACE_activate_only_trace_masks_always_and_error); + if (status == eap_status_ok + && EAP_TRACE_activate_only_trace_masks_always_and_error.get_is_valid_data() == true) + { + u32_t *activate_trace_mask_always = reinterpret_cast( + EAP_TRACE_activate_only_trace_masks_always_and_error.get_data(sizeof(u32_t))); + if (activate_trace_mask_always != 0 + && *activate_trace_mask_always != 0) + { + m_am_tools->set_trace_mask( + eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_error + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_activate_trace_on_error(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_activate_trace_on_error.get_field(), + &EAP_TRACE_activate_trace_on_error); + if (status == eap_status_ok + && EAP_TRACE_activate_trace_on_error.get_is_valid_data() == true) + { + u32_t *activate_trace_on_error = reinterpret_cast( + EAP_TRACE_activate_trace_on_error.get_data(sizeof(u32_t))); + if (activate_trace_on_error != 0 + && *activate_trace_on_error != 0) + { + m_am_tools->set_activate_trace_on_error(); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_enable_timer_traces(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_enable_timer_traces.get_field(), + &EAP_TRACE_enable_timer_traces); + if (status == eap_status_ok + && EAP_TRACE_enable_timer_traces.get_is_valid_data() == true) + { + u32_t *enable_timer_traces = reinterpret_cast( + EAP_TRACE_enable_timer_traces.get_data(sizeof(u32_t))); + if (enable_timer_traces != 0 + && *enable_timer_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | TRACE_FLAGS_TIMER + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_enable_timer_queue_traces(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_enable_timer_queue_traces.get_field(), + &EAP_TRACE_enable_timer_queue_traces); + if (status == eap_status_ok + && EAP_TRACE_enable_timer_queue_traces.get_is_valid_data() == true) + { + u32_t *enable_timer_queue_traces = reinterpret_cast( + EAP_TRACE_enable_timer_queue_traces.get_data(sizeof(u32_t))); + if (enable_timer_queue_traces != 0 + && *enable_timer_queue_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | TRACE_FLAGS_TIMER_QUEUE + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_enable_ok_return_traces(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_enable_ok_return_traces.get_field(), + &EAP_TRACE_enable_ok_return_traces); + if (status == eap_status_ok + && EAP_TRACE_enable_ok_return_traces.get_is_valid_data() == true) + { + u32_t *enable_ok_return_traces = reinterpret_cast( + EAP_TRACE_enable_ok_return_traces.get_data(sizeof(u32_t))); + if (enable_ok_return_traces != 0 + && *enable_ok_return_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | TRACE_FLAGS_OK_RETURNS + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_enable_message_data_traces(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_enable_message_data_traces.get_field(), + &EAP_TRACE_enable_message_data_traces); + if (status == eap_status_ok + && EAP_TRACE_enable_message_data_traces.get_is_valid_data() == true) + { + u32_t *enable_message_data_traces = reinterpret_cast( + EAP_TRACE_enable_message_data_traces.get_data(sizeof(u32_t))); + if (enable_message_data_traces != 0 + && *enable_message_data_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | EAP_TRACE_FLAGS_MESSAGE_DATA + ); + } + } + } + + //---------------------------------------------------------- + + // Create stack if it does not already exist. + status = create_upper_stack(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // All of the configuration options are optional. + // So we return OK. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::set_wimax_parameters( + eap_variable_data_c* const routing_info, + eap_variable_data_c* const nai_decoration) +{ + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eap_wimax_authentication_c::set_wimax_parameters(): m_am_wauth->reset_eap_configuration(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->reset_eap_configuration(); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_am_wauth->set_wimax_parameters(routing_info, nai_decoration); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_wimax_authentication_c::create_upper_stack() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap calls: eap_wimax_authentication_c::create_upper_stack()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eap: eap_wimax_authentication_c::create_upper_stack()\n"); + + eap_status_e status(eap_status_ok); + + if (m_eap_core == 0) + { + // we use session always + m_eap_core = new eap_session_core_c(m_am_tools, this, m_is_client); + if (m_eap_core == 0 + || m_eap_core->get_is_valid() != true) + { + if (m_eap_core != 0) + { + WAUTH_ENTER_MUTEX(m_am_tools); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eap: eap_wimax_authentication_c::create_upper_stack(): m_eap_core->shutdown(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_eap_core->shutdown(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eap: eap_wimax_authentication_c::create_upper_stack(): m_eap_core->shutdown(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + WAUTH_LEAVE_MUTEX(m_am_tools); + + delete m_eap_core; + m_eap_core = 0; + } + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Stack creation failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Initialise upper stack + WAUTH_ENTER_MUTEX(m_am_tools); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eap_wimax_authentication_c::create_upper_stack(): m_eap_core->configure(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_eap_core->configure(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eap_wimax_authentication_c::create_upper_stack(): m_eap_core->configure(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + WAUTH_LEAVE_MUTEX(m_am_tools); + + if (status != eap_status_ok) + { + WAUTH_ENTER_MUTEX(m_am_tools); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eap: eap_wimax_authentication_c::create_upper_stack(): m_eap_core->shutdown(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_eap_core->shutdown(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eap: eapol_wlan_authentication_c::create_upper_stack(): m_eap_core->shutdown(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + WAUTH_LEAVE_MUTEX(m_am_tools); + + delete m_eap_core; + m_eap_core = 0; + + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Stack creation failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + else + { + status = eap_status_already_exists; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_core.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_core.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,4183 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 48 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eapol_core.h" +#include "eap_crypto_api.h" +#include "eapol_key_header.h" +#include "eapol_rc4_key_header.h" +#include "eap_state_notification.h" +#include "eap_automatic_variable.h" +#include "eap_network_id_selector.h" +#include "eap_config.h" +#include "eap_buffer.h" +#include "eapol_session_key.h" +#include "eap_master_session_key.h" + +#define MPPE_KEY_LENGTH 32 + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_core_c::~eapol_core_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::~eapol_core_c(): this = 0x%08x\n"), + this)); + + EAP_ASSERT(m_shutdown_was_called == true); + + delete m_eap_core; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +// +EAP_FUNC_EXPORT eapol_core_c::eapol_core_c( + abs_eap_am_tools_c * const tools, + abs_eapol_core_c * const partner, + const bool is_client_when_true) + : m_partner(partner) +#if !defined(NO_EAP_SESSION_CORE) + , m_eap_core(new eap_session_core_c(tools, this, is_client_when_true)) +#else + , m_eap_core(new eap_core_c(tools, this, is_client_when_true, 0, false)) +#endif +#if defined(USE_EAPOL_KEY_STATE) + , m_eapol_key_state_map(tools, this) +#endif //#if defined(USE_EAPOL_KEY_STATE) + , m_am_tools(tools) + , m_master_session_key(m_am_tools) + , m_authentication_type(eapol_key_authentication_type_none) + , m_eapol_header_offset(0u) + , m_MTU(0u) + , m_trailer_length(0u) + , m_max_eapol_starts(0u) + , m_eapol_start_interval(0u) + , m_eapol_starts_sent(0u) + , m_is_client(is_client_when_true) + , m_is_valid(false) + , m_shutdown_was_called(false) + , m_block_state_notifications(false) +#if defined(USE_EAPOL_KEY_STATE) + , m_skip_start_4_way_handshake(false) +#endif //#if defined(USE_EAPOL_KEY_STATE) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::eapol_core_c(): %s, this = 0x%08x => 0x%08x, compiled %s %s.\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this), + __DATE__, + __TIME__)); + + if (m_eap_core != 0 + && m_eap_core->get_is_valid() == true) + { + set_is_valid(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (packet_data == 0 + || packet_length < eap_header_base_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + eapol_header_wr_c eapol( + m_am_tools, + packet_data->get_header_buffer(packet_data->get_header_buffer_length()), + packet_data->get_header_buffer_length()); + + if (eapol.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (packet_length < eapol.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (m_eap_core == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (packet_length < eapol_header_rd_c::get_header_length() // First we need atleast header to check the data length. + || packet_length < eapol_header_rd_c::get_header_length()+eapol.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("-> EAPOL: %s, version=0x%02x, packet_type=0x%02x=%s, data_length=0x%04x, packet_length 0x%04x\n"), + (m_is_client == true) ? "client": "server", + eapol.get_version(), + eapol.get_packet_type(), + eapol.get_type_string(), + eapol.get_data_length(), + packet_length)); + + status = eapol.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (receive_network_id->get_type() == eapol_ethernet_type_preauthentication + && eapol.get_packet_type() != eapol_packet_type_eap + && eapol.get_packet_type() != eapol_packet_type_start) + { + // Only EAP-Packet and EAPOL-Start are valid for preauthentication. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); + } + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eapol_key_state_c *eapol_key_state = 0; + + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c state_selector( + m_am_tools, + &send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_process(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + + // Check do we have handler for this packet. This applies to EAP-packets too. + eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + + if (eapol_key_state == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::packet_process() failed, no eapol_key_state_c object for this packet. Drop packet.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + if (eapol.get_packet_type() == eapol_packet_type_eap + && eapol.get_data_length() >= eap_header_base_c::get_header_length()) + { + if (m_authentication_type != eapol_key_authentication_type_RSNA_EAP + && m_authentication_type != eapol_key_authentication_type_WPA_EAP + && m_authentication_type != eapol_key_authentication_type_802_1X +#if defined(EAP_USE_WPXM) + && m_authentication_type != eapol_key_authentication_type_WPXM +#endif //#if defined(EAP_USE_WPXM) + && m_authentication_type != eapol_key_authentication_type_WFA_SC + ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::packet_process(): Illegal authentication type 0x%08x\n"), + m_authentication_type)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); + } + + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + // Test first we are connected. + if (eapol_key_state->get_is_associated() == true) + { + status = m_eap_core->synchronous_create_eap_session(receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + +#endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + + eap_header_wr_c eap( + m_am_tools, + eapol.get_eap_header(), + eapol.get_data_length()); + + status = m_eap_core->packet_process( + receive_network_id, + &eap, + eapol.get_data_length()); + + EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eap); + } + else if (m_is_client == false + && eapol.get_packet_type() == eapol_packet_type_logoff) + { + status = eap_status_ok; + } + else if (m_is_client == false + && eapol.get_packet_type() == eapol_packet_type_start) + { + if (m_authentication_type != eapol_key_authentication_type_RSNA_EAP + && m_authentication_type != eapol_key_authentication_type_WPA_EAP + && m_authentication_type != eapol_key_authentication_type_802_1X + && m_authentication_type != eapol_key_authentication_type_WFA_SC +#if defined(EAP_USE_WPXM) + && m_authentication_type != eapol_key_authentication_type_WPXM +#endif //#if defined(EAP_USE_WPXM) + ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::packet_process(): Illegal authentication type 0x%08x\n"), + m_authentication_type)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); + } + + // This call does not cause clean restart. On-going authentication is not terminated. + status = restart_authentication( + receive_network_id, + m_is_client, + false); + } +#if defined(USE_EAPOL_KEY_STATE) + else if (eapol.get_packet_type() == eapol_packet_type_key) + { + if (m_authentication_type != eapol_key_authentication_type_RSNA_EAP + && m_authentication_type != eapol_key_authentication_type_RSNA_PSK + && m_authentication_type != eapol_key_authentication_type_WPA_EAP + && m_authentication_type != eapol_key_authentication_type_WPA_PSK + && m_authentication_type != eapol_key_authentication_type_802_1X +#if defined(EAP_USE_WPXM) + && m_authentication_type != eapol_key_authentication_type_WPXM +#endif //#if defined(EAP_USE_WPXM) + ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::packet_process(): Illegal authentication type 0x%08x\n"), + m_authentication_type)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); + } + + // Indicates EAP-Core of received EAPOL-Key message. + // This is indication of finished EAP-authentication. + // NOTE, we do not care of the status. + // Some EAP-types does not implement this function. + (void) eap_acknowledge(receive_network_id); + + if (eapol_key_state != 0) + { + status = eapol_key_state->process_eapol_key_frame( + receive_network_id, + packet_data, + packet_length); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: process_eapol_key_frame() failed, no eapol_key_state_c object\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + } +#endif //#if defined(USE_EAPOL_KEY_STATE) +#if ! defined(USE_EAPOL_KEY_STATE) + else if ( + m_is_client == true + && eapol.get_packet_type() == eapol_packet_type_key) + { + // Handle EAPOL-Key frame. + // Here is assumed the EAPOL-Key frame includes RC4 Key Descriptor. + /** + * @{ Here we need to check the Descriptor Type field. + * It may be RC4 Key Descriptor, RSNA Key Descriptor or other descriptor. } + */ + + eapol_RC4_key_header_c eapol_key_msg( + m_am_tools, + eapol.get_header_buffer(eapol.get_header_buffer_length()), + eapol.get_header_buffer_length()); + if (eapol_key_msg.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (eapol_key_msg.check_header() != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = handle_RC4_key_descriptor( + receive_network_id, + &eapol_key_msg, + packet_length); + } +#endif //#if ! defined(USE_EAPOL_KEY_STATE) + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: %s, packet_type=0x%02x=%s not handled, data length 0x%04x.\n"), + (m_is_client == true) ? "client": "server", + eapol.get_packet_type(), + eapol.get_type_string(), + eapol.get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" source"), receive_network_id->get_source(), receive_network_id->get_source_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("destination"), receive_network_id->get_destination(), receive_network_id->get_destination_length())); + + status = eap_status_wrong_eapol_type; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + EAP_ASSERT(header_offset < sent_packet->get_data_length()); + EAP_ASSERT(data_length <= sent_packet->get_data_length()); + EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); + + if (header_offset < eap_header_wr_c::get_header_length()) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eapol_header_wr_c eapol( + m_am_tools, + sent_packet->get_data_offset( + header_offset-eap_header_wr_c::get_header_length(), data_length), + data_length); + + if (eapol.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eapol.set_version(eapol_protocol_version_1); + eapol.set_packet_type(eapol_packet_type_eap); + eapol.set_data_length(static_cast(data_length)); + + { + eap_network_id_selector_c state_selector( + m_am_tools, + send_network_id); + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eapol_key_state_c *session = m_eapol_key_state_map.get_handler(&state_selector); + + bool encryption_on(false); + + if (session != 0 + && session->get_is_valid() == true) + { + encryption_on = session->get_is_encryption_on(); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Read EAPOL-Key session: encryption is %s\n"), + ((encryption_on == true) ? "on" : "off"))); + + sent_packet->set_encrypt(encryption_on); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("<- EAPOL: %s, version=0x%02x, packet_type=0x%02x=%s, data_length=0x%04x, packet_length 0x%04x\n"), + (m_is_client == true) ? "client": "server", + eapol.get_version(), + eapol.get_packet_type(), + eapol.get_type_string(), + eapol.get_data_length(), + data_length)); + + if (m_shutdown_was_called == true + && m_is_client == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAP_Core: %s, eapol_core_c::packet_send(): %s packet dropped quietly because shutdown was already called.\n"), + (m_is_client == true) ? "client": "server", + eapol.get_type_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + eap_status_e status = m_partner->packet_send( + send_network_id, sent_packet, header_offset-eapol_header_wr_c::get_header_length(), + data_length+eapol_header_wr_c::get_header_length(), buffer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eapol_core_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const u32_t offset = m_partner->get_header_offset(MTU, trailer_length); + (*MTU) -= eapol_header_wr_c::get_header_length(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return offset+eapol_header_wr_c::get_header_length(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::eap_acknowledge( + const eap_am_network_id_c * const receive_network_id) +{ + // Any Network Protocol packet is accepted as a success indication. + // This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (m_eap_core == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = m_eap_core->eap_acknowledge(receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = m_partner->load_module( + type, + tunneling_type, + partner, + eap_type, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->unload_module(type); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::restart_authentication(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::restart_authentication()"); + + eap_status_e status = eap_status_process_general_error; + + if (receive_network_id->get_type() != eapol_ethernet_type_pae + && receive_network_id->get_type() != eapol_ethernet_type_preauthentication) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::restart_authentication(): Illegal Ethernet type %d\n"), + receive_network_id->get_type())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ethernet_type_not_supported); + } + + if (is_client_when_true == true) + { + // Client sends a EAPOL-Start message. + (void) m_partner->cancel_timer( + this, + EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); + +#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) +#if !defined(NO_EAP_SESSION_CORE) + // First we remove possible EAP session. + (void) m_eap_core->synchronous_remove_eap_session(receive_network_id); +#endif +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_buf_chain_wr_c start_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (start_packet.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t buffer_size = EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH; + EAP_ASSERT_ALWAYS(m_MTU > m_trailer_length); + if (m_MTU-m_trailer_length < buffer_size) + { + buffer_size = m_MTU-m_trailer_length; + } + + EAP_ASSERT_ALWAYS(buffer_size >= m_eapol_header_offset); + eapol_header_wr_c eapol( + m_am_tools, + start_packet.get_data_offset( + m_eapol_header_offset, + (buffer_size-m_eapol_header_offset)), + (buffer_size-m_eapol_header_offset)); + + if (eapol.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eapol.set_version(eapol_protocol_version_1); + eapol.set_packet_type(eapol_packet_type_start); + eapol.set_data_length(0); + + start_packet.set_data_length( + m_eapol_header_offset + +eapol_header_wr_c::get_header_length() + +eapol.get_data_length()); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("<- EAPOL: %s, version=0x%02x, packet_type=0x%02x=%s, data_length=0x%04x, packet length 0x%04x\n"), + (m_is_client == true) ? "client": "server", + eapol.get_version(), + eapol.get_packet_type(), + eapol.get_type_string(), + eapol.get_data_length(), + eapol_header_wr_c::get_header_length()+eapol.get_data_length())); + + status = m_partner->packet_send( + &send_network_id, + &start_packet, + m_eapol_header_offset, + eapol_header_wr_c::get_header_length()+eapol.get_data_length(), + buffer_size); + + if (from_timer == false) + { + // Reset EAPOL-Start counter because this is not a resending. + m_eapol_starts_sent = 1; + // Send notification + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + true, // m_is_client + eap_state_notification_generic, + eap_protocol_layer_eapol, + eap_type_none, + eapol_state_none, + eapol_state_start_sent, + 0 /* EAP identifier not valid here */, + false); + state_notification(¬ification); + } + + // This copy is important because timer needs data that is allocated from heap. + eap_am_network_id_c * const copy_receive_network_id = receive_network_id->copy(); + eap_automatic_variable_c automatic_copy_receive_network_id( + m_am_tools, + copy_receive_network_id); + + if (copy_receive_network_id == 0 + || copy_receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Timer will hold copy_send_network_id data. + automatic_copy_receive_network_id.do_not_free_variable(); + + status = m_partner->set_timer( + this, + EAPOL_CORE_TIMER_SEND_START_AGAIN_ID, + copy_receive_network_id, + m_eapol_start_interval); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAPOL_CORE_TIMER_SEND_START_AGAIN_ID set %d ms.\n"), + (m_is_client == true ? "client": "server"), + m_eapol_start_interval)); + + } +#if defined(USE_EAP_CORE_SERVER) + else + { + // Server. + + if (m_eap_core == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (force_clean_restart == true) + { + // It is bad idea to terminate on-going authentication + // when EAPOL-Start is received. + // Because of that synchronous_remove_eap_session() is called + // only when force_clean_restart is true. +#if !defined(NO_EAP_SESSION_CORE) + bool previous_block = m_block_state_notifications; + m_block_state_notifications = true; + (void) m_eap_core->synchronous_remove_eap_session(receive_network_id); + m_block_state_notifications = previous_block; +#endif + } + + if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP + || m_authentication_type == eapol_key_authentication_type_WPA_EAP + || m_authentication_type == eapol_key_authentication_type_802_1X +#if defined(EAP_USE_WPXM) + || m_authentication_type == eapol_key_authentication_type_WPXM +#endif //#if defined(EAP_USE_WPXM) + || m_authentication_type == eapol_key_authentication_type_WFA_SC + ) + { + status = m_eap_core->send_eap_identity_request(receive_network_id); + } + else + { + status = eap_status_ok; + } + } + +#else + + EAP_UNREFERENCED_PARAMETER(force_clean_restart); // Only server version uses this. + +#endif //#if defined(USE_EAP_CORE_SERVER) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::check_pmksa_cache( + eap_array_c * const bssid_sta_receive_network_ids, + const eapol_key_authentication_type_e selected_eapol_key_authentication_type, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::check_pmksa_cache(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::check_pmksa_cache()"); + + eap_status_e status = eap_status_ok; + + for (u32_t ind = 0ul; ind < bssid_sta_receive_network_ids->get_object_count();) + { + eap_am_network_id_c * const receive_network_id = bssid_sta_receive_network_ids->get_object(ind); + if (receive_network_id == 0) + { + bssid_sta_receive_network_ids->reset(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + bssid_sta_receive_network_ids->reset(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c state_selector( + m_am_tools, + &send_network_id); + if (state_selector.get_is_valid() == false) + { + bssid_sta_receive_network_ids->reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("check_pmksa_cache(): checks PMKSA EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eapol_key_state_c *session = m_eapol_key_state_map.get_handler(&state_selector); + + if (session == 0 + || selected_eapol_key_authentication_type == eapol_key_authentication_type_RSNA_PSK + || selected_eapol_key_authentication_type == eapol_key_authentication_type_WPA_PSK + || session->check_pmksa_cache( + selected_eapol_key_authentication_type, + pairwise_key_cipher_suite, + group_key_cipher_suite) != eap_status_ok) + { + // No cached PMKID for this address and security suite. + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("No cached PMKID for this address"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + status = bssid_sta_receive_network_ids->remove_object(ind); + if (status != eap_status_ok) + { + bssid_sta_receive_network_ids->reset(); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Note here we do not increase index because we removed the current object. + } + else + { + // Check the next index. + ++ind; + } + } // for() + + if (bssid_sta_receive_network_ids->get_object_count() > 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); + } +} + +//-------------------------------------------------- + +/** + * This function removes PMKSA from cache. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. + * MAC address of Supplicant should be in destination address. + */ +EAP_FUNC_EXPORT eap_status_e eapol_core_c::remove_pmksa_from_cache( + const eap_am_network_id_c * const receive_network_id + ) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::remove_pmksa_from_cache().\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::remove_pmksa_from_cache()"); + + if (receive_network_id == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = remove_eapol_key_state( + &send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::disassociation(): ") + EAPL("remove_eapol_key_state(), eap_status_e %d\n"), + status)); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::start_preauthentication( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::start_preauthentication().\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::start_preauthentication()"); + +#if defined(USE_EAPOL_KEY_STATE) + + if (receive_network_id->get_type() != eapol_ethernet_type_preauthentication) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::start_preauthentication(): Illegal Ethernet type 0x%04x\n"), + receive_network_id->get_type())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ethernet_type_not_supported); + } + + + if (m_authentication_type != authentication_type) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::start_preauthentication(): Illegal authentication type 0x%08x, ") + EAPL("it should be 0x%08x\n"), + authentication_type, + m_authentication_type)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type); + } + + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c state_selector( + m_am_tools, + &send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("start_preauthentication(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + + eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + + if (eapol_key_state != 0) + { + // Reuse the session. + eapol_key_state->unset_marked_removed(); + + status = eapol_key_state->reset(); + if (status != eap_status_ok) + { + // We cannot reuse the session. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("start_preauthentication(): eapol_key_state NOT reused.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + if (eapol_key_state == 0) + { + eapol_key_state = new eapol_key_state_c( + m_am_tools, + this, + m_partner, + m_is_client, + receive_network_id, + authentication_type); + if (eapol_key_state == 0 + || eapol_key_state->get_is_valid() == false) + { + if (eapol_key_state != 0) + { + eapol_key_state->shutdown(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::start_preauthentication(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), + eapol_key_state)); + } + delete eapol_key_state; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = eapol_key_state->initialize_preauthentication( + receive_network_id, + authentication_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_eapol_key_state_map.add_handler(&state_selector, eapol_key_state); + if (status != eap_status_ok) + { + eapol_key_state->shutdown(); + delete eapol_key_state; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = eapol_key_state->initialize_preauthentication( + receive_network_id, + authentication_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + status = eapol_key_state->configure(); + if (status != eap_status_ok) + { + status = remove_eapol_key_state( + &send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::start_preauthentication(): remove_eapol_key_state(), eap_status_e %d\n"), + status)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // This call does cause clean restart. On-going authentication is terminated. + status = restart_authentication( + receive_network_id, + m_is_client, + true, + false); + +#endif //#if defined(USE_EAPOL_KEY_STATE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_core_c::copy_eapol_key_state( + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id ///< source includes remote address, destination includes local address. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::copy_eapol_key_state()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::copy_eapol_key_state()"); + + eap_status_e status(eap_status_process_general_error); + + if (old_receive_network_id == 0 + || old_receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (new_receive_network_id == 0 + || new_receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + +#if defined(USE_EAPOL_KEY_STATE) + + // Here we swap the addresses. + eap_am_network_id_c old_send_network_id( + m_am_tools, + old_receive_network_id->get_destination_id(), + old_receive_network_id->get_source_id(), + old_receive_network_id->get_type()); + if (old_send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c old_state_selector( + m_am_tools, + &old_send_network_id); + + if (old_state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("copy_eapol_key_state(): old EAPOL-Key session"), + old_state_selector.get_data(), + old_state_selector.get_data_length())); + + eapol_key_state_c *old_eapol_key_state = m_eapol_key_state_map.get_handler(&old_state_selector); + + if (old_eapol_key_state != 0) + { + { + // Here we remove the old state from map. Note the old state is not deleted. + // Later we add the modified old map to new location in the map. + status = m_eapol_key_state_map.remove_handler(&old_state_selector, false); + if (status != eap_status_ok) + { + old_eapol_key_state->shutdown(); + delete old_eapol_key_state; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Set up the old state and add it to m_eapol_key_state_map. + + // Here we swap the addresses. + eap_am_network_id_c new_send_network_id( + m_am_tools, + new_receive_network_id->get_destination_id(), + new_receive_network_id->get_source_id(), + new_receive_network_id->get_type()); + if (new_send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(EAP_USE_WPXM) + status = old_eapol_key_state->set_WPXM_parameters(new_receive_network_id); + if (status != eap_status_ok) + { + old_eapol_key_state->shutdown(); + delete old_eapol_key_state; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if defined(EAP_USE_WPXM) + + eap_network_id_selector_c new_state_selector( + m_am_tools, + &new_send_network_id); + + if (new_state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("copy_eapol_key_state(): new EAPOL-Key session"), + new_state_selector.get_data(), + new_state_selector.get_data_length())); + + status = m_eapol_key_state_map.add_handler(&new_state_selector, old_eapol_key_state); + if (status != eap_status_ok) + { + old_eapol_key_state->shutdown(); + delete old_eapol_key_state; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + +#endif //#if defined(USE_EAPOL_KEY_STATE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_core_c::generate_new_pmksa( + eapol_key_state_c * * const new_eapol_key_state, + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id ///< source includes remote address, destination includes local address. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::generate_new_pmksa()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::generate_new_pmksa()"); + + eap_status_e status(eap_status_process_general_error); + + if (new_eapol_key_state == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (old_receive_network_id == 0 + || old_receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (new_receive_network_id == 0 + || new_receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + +#if defined(USE_EAPOL_KEY_STATE) + + // Here we swap the addresses. + eap_am_network_id_c old_send_network_id( + m_am_tools, + old_receive_network_id->get_destination_id(), + old_receive_network_id->get_source_id(), + old_receive_network_id->get_type()); + if (old_send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c old_state_selector( + m_am_tools, + &old_send_network_id); + + if (old_state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_new_pmksa(): old EAPOL-Key session"), + old_state_selector.get_data(), + old_state_selector.get_data_length())); + + eapol_key_state_c *old_eapol_key_state = m_eapol_key_state_map.get_handler(&old_state_selector); + + if (old_eapol_key_state != 0) + { + *new_eapol_key_state = old_eapol_key_state->copy(new_receive_network_id); + + if (*new_eapol_key_state == 0 + || (*new_eapol_key_state)->get_is_valid() == false) + { + if (*new_eapol_key_state != 0) + { + (*new_eapol_key_state)->shutdown(); + delete *new_eapol_key_state; + *new_eapol_key_state = 0; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (*new_eapol_key_state != 0) + { + // Here we swap the addresses. + eap_am_network_id_c new_send_network_id( + m_am_tools, + new_receive_network_id->get_destination_id(), + new_receive_network_id->get_source_id(), + new_receive_network_id->get_type()); + if (new_send_network_id.get_is_valid_data() == false) + { + (*new_eapol_key_state)->shutdown(); + delete *new_eapol_key_state; + *new_eapol_key_state = 0; + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c new_state_selector( + m_am_tools, + &new_send_network_id); + + if (new_state_selector.get_is_valid() == false) + { + (*new_eapol_key_state)->shutdown(); + delete *new_eapol_key_state; + *new_eapol_key_state = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_new_pmksa(): new EAPOL-Key session"), + new_state_selector.get_data(), + new_state_selector.get_data_length())); + + status = m_eapol_key_state_map.add_handler(&new_state_selector, *new_eapol_key_state); + if (status != eap_status_ok) + { + (*new_eapol_key_state)->shutdown(); + delete *new_eapol_key_state; + *new_eapol_key_state = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + status = eap_status_not_found; + } + +#endif //#if defined(USE_EAPOL_KEY_STATE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_core_c::read_reassociation_parameters( + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address. + const eapol_key_authentication_type_e authentication_type, + eap_variable_data_c * const PMKID, + const eap_variable_data_c * const received_WPA_ie, + const eap_variable_data_c * const sent_WPA_ie) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::read_reassociation_parameters()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::read_reassociation_parameters()"); + + eap_status_e status(eap_status_process_general_error); + +#if defined(USE_EAPOL_KEY_STATE) + + // No need to check authentication type anymore. It can be changed in reassociation. + +#if defined(EAP_USE_WPXM) + if (authentication_type == eapol_key_authentication_type_WPXM) + { + status = copy_eapol_key_state(old_receive_network_id, new_receive_network_id); + if (status != eap_status_ok) + { + // We cannot copy the session. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eapol_core_c::read_reassociation_parameters(): cannot copy eapol_key_state.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#else + EAP_UNREFERENCED_PARAMETER(old_receive_network_id); +#endif //#if defined(EAP_USE_WPXM) + + // Here we swap the addresses. + eap_am_network_id_c new_send_network_id( + m_am_tools, + new_receive_network_id->get_destination_id(), + new_receive_network_id->get_source_id(), + new_receive_network_id->get_type()); + if (new_send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c state_selector( + m_am_tools, + &new_send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("read_reassociation_parameters(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + + if (eapol_key_state == 0 + && authentication_type == eapol_key_authentication_type_RSNA_EAP) + { + // Creates a new PMKSA based on old PMKSA and the new MAC address of new access point. + status = generate_new_pmksa(&eapol_key_state, old_receive_network_id, new_receive_network_id); + if (status != eap_status_ok) + { + // We cannot generate a new PMKSA. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::read_reassociation_parameters(): new eapol_key_state NOT generated.\n"))); + status = eap_status_not_found; + } + } + + if (eapol_key_state != 0) + { + status = eapol_key_state->reset_cached_pmksa(); + if (status != eap_status_ok) + { + // We cannot reuse the session. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eapol_core_c::read_reassociation_parameters(): eapol_key_state NOT reused.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // We have state for this connection. + status = eapol_key_state->read_reassociation_parameters( + new_receive_network_id, ///< source includes remote address, destination includes local address. + authentication_type, + PMKID, + received_WPA_ie, + sent_WPA_ie); + if (status != eap_status_ok) + { + // ERROR, Cannot reassociate. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::read_reassociation_parameters(): Cannot reassociate.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = eap_status_not_found; + } + +#endif //#if defined(USE_EAPOL_KEY_STATE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::start_reassociation( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const /*PMKID*/) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::start_reassociation()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::start_reassociation()"); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c state_selector( + m_am_tools, + &send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("start_reassociation(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eap_status_e status(eap_status_process_general_error); + + eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + + if (eapol_key_state != 0) + { + status = eapol_key_state->reset_cached_pmksa(); + if (status != eap_status_ok) + { + // We cannot reuse the session. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eapol_core_c::start_reassociation(): eapol_key_state NOT reused.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_EAPOL_KEY_STATE) + if (m_skip_start_4_way_handshake == true + && (authentication_type == eapol_key_authentication_type_RSNA_EAP + || authentication_type == eapol_key_authentication_type_RSNA_PSK + || authentication_type == eapol_key_authentication_type_WPA_EAP + || authentication_type == eapol_key_authentication_type_WPA_PSK)) + { + // This is test to skip 4-Way Handshake start. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::start_reassociation(): ") + EAPL("skips start_4_way_handshake()\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else +#endif //#if defined(USE_EAPOL_KEY_STATE) + { +#if !defined(NO_EAPOL_KEY_STATE_SERVER) + status = eapol_key_state->start_4_way_handshake( + receive_network_id); +#endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) + } + +#if !defined(NO_EAPOL_KEY_STATE_SERVER) + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::start_reassociation(): ") + EAPL("start_4_way_handshake() failed, eap_status_e %d\n"), + status)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::start_reassociation(): ") + EAPL("start_4_way_handshake(), eap_status_e %d\n"), + status)); + } +#endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_core_c::complete_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const received_WPA_IE, + const eap_variable_data_c * const sent_WPA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::complete_reassociation()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::complete_reassociation()"); + +#if defined(USE_EAPOL_KEY_STATE) + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + // No need to check previous authentication type. It can be changed in reassociation. + m_authentication_type = authentication_type; + + + eap_network_id_selector_c state_selector( + m_am_tools, + &send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_reassociation(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + + if (eapol_key_state != 0) + { + // We have state for this connection. + eap_status_e status = eapol_key_state->complete_reassociation( + reassociation_result, + receive_network_id, + authentication_type, + received_WPA_IE, + sent_WPA_IE, + pairwise_key_cipher_suite, + group_key_cipher_suite + ); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else +#endif //#if defined(USE_EAPOL_KEY_STATE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::send_logoff( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::send_logoff()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::send_logoff()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status(eap_status_not_supported); + + if (m_eap_core == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (receive_network_id == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_buf_chain_wr_c logoff_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (logoff_packet.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t data_length = EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH; + + if (data_length > 0) + { + data_length = 0; + } + + eapol_header_wr_c eapol( + m_am_tools, + logoff_packet.get_data_offset( + m_eapol_header_offset, m_eapol_header_offset+data_length), + m_eapol_header_offset+data_length); + + if (eapol.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eapol.set_version(eapol_protocol_version_1); + eapol.set_packet_type(eapol_packet_type_logoff); + eapol.set_data_length(static_cast(data_length)); + + logoff_packet.set_data_length(m_eapol_header_offset+eapol_header_wr_c::get_header_length()+data_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("<- EAPOL: %s, version=0x%02x, packet_type=0x%02x=%s, data_length=0x%04x, packet length 0x%04x\n"), + (m_is_client == true) ? "client": "server", + eapol.get_version(), + eapol.get_packet_type(), + eapol.get_type_string(), + eapol.get_data_length(), + eapol.get_header_length()+eapol.get_data_length())); + + status = m_partner->packet_send( + &send_network_id, &logoff_packet, m_eapol_header_offset, + eapol.get_header_length()+eapol.get_data_length(), EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::packet_data_crypto_keys()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::packet_data_crypto_keys()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (master_session_key->get_is_valid() == true) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("master session key"), + master_session_key->get_data(master_session_key->get_data_length()), + master_session_key->get_data_length())); + } + +#if defined(USE_EAPOL_KEY_STATE) + + eap_network_id_selector_c state_selector( + m_am_tools, + send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_data_crypto_keys(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + + if (eapol_key_state != 0) + { + status = eapol_key_state->set_pairwise_PMK( + master_session_key, + send_network_id); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: packet_data_crypto_keys() failed, no eapol_key_state_c object\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + +#else + + // Store the session key so it can be used when EAPOL-Key is received. + m_master_session_key.reset(); + + status = m_master_session_key.set_copy_of_buffer(master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#endif //#if defined(USE_EAPOL_KEY_STATE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::packet_data_session_key()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::packet_data_session_key()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (key->get_is_valid() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol session key: type 0x%02x, index 0x%02x, tx %d\n"), + key->get_key_type(), + key->get_key_index(), + key->get_key_tx_bit())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol session key"), + key->get_key()->get_data(key->get_key()->get_data_length()), + key->get_key()->get_data_length())); + } + + // Forward the keys to lower layers + status = m_partner->packet_data_session_key( + send_network_id, + key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if !defined(USE_EAPOL_KEY_STATE) + +// +eap_status_e eapol_core_c::handle_RC4_key_descriptor( + const eap_am_network_id_c * const receive_network_id, + eapol_RC4_key_header_c* const packet, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::handle_RC4_key_descriptor()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::handle_RC4_key_descriptor()"); + + eap_status_e status = eap_status_process_general_error; + + // Check the packet length + if (static_cast(packet->get_header_length()) != packet_length + && static_cast(packet->get_header_length() + packet->get_key_length()) != packet_length) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Illegal EAPOL-Key frame length, packet->get_header_length() %d, packet_length %d\n"), + packet->get_header_length(), + packet_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + // Get MS-MPPE-Recv-Key and MS-MPPE-Send-Key + // Recv-Key is the first 32 bytes of master session key and Send-Key is the next 32 bytes. + eap_variable_data_c mppe_recv_key(m_am_tools); + eap_variable_data_c mppe_send_key(m_am_tools); + if (m_master_session_key.get_data_length() == 16ul) + { + status = mppe_recv_key.set_buffer( + m_master_session_key.get_data(m_master_session_key.get_data_length()), + m_master_session_key.get_data_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = mppe_send_key.set_buffer( + m_master_session_key.get_data(m_master_session_key.get_data_length()), + m_master_session_key.get_data_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = mppe_recv_key.set_buffer( + m_master_session_key.get_data(MPPE_KEY_LENGTH), + MPPE_KEY_LENGTH, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = mppe_send_key.set_buffer( + m_master_session_key.get_data_offset(MPPE_KEY_LENGTH, MPPE_KEY_LENGTH), + MPPE_KEY_LENGTH, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (mppe_recv_key.get_is_valid() == false + || mppe_send_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Verify the the MD5 signature in Eapol-Key + crypto_md5_c md5(m_am_tools); + crypto_hmac_c hmac_md5(m_am_tools, &md5, false); + if (hmac_md5.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // MPPE-Send-Key is used as the signature key. + if (hmac_md5.hmac_set_key(&mppe_send_key) != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: hmac_md5_init failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Save the signature from the packet + eap_variable_data_c signature(m_am_tools); + status = signature.set_copy_of_buffer(packet->get_key_signature(), EAPOL_RC4_KEY_SIGNATURE_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Replace the signature with zeros. + packet->zero_key_signature(m_am_tools); + + // Send the data to HMAC-MD5 module + if (hmac_md5.hmac_update(packet->get_header_buffer(packet_length), packet_length) != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: hmac_md5_update failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Get the calculated signature + u8_t tmp_signature[EAPOL_RC4_KEY_SIGNATURE_LENGTH]; + u32_t length = EAPOL_RC4_KEY_SIGNATURE_LENGTH; + if (hmac_md5.hmac_final(tmp_signature, &length) != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: hmac_md5_final failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Compare the calculated and original signature + if (m_am_tools->memcmp( + tmp_signature, + signature.get_data( + EAPOL_RC4_KEY_SIGNATURE_LENGTH), + EAPOL_RC4_KEY_SIGNATURE_LENGTH) != 0) + { + // Signatures did not match. Something's wrong. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAPOL-Key HMAC-MD5 check failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAPOL-Key HMAC-MD5 check passed.\n"))); + + eap_variable_data_c key_out(m_am_tools); + // Decrypt the RC4 encrypted key + if (packet->get_key() == 0) + { + // EAPOL-Key does not contain the key. This means that we should use + // the first bytes from MS-MPPE-Recv-Key as the key. There is a slight + // confusion in draft-congdon-radius-8021x-23.txt regarding this but this is how + // it works. + if (packet->get_key_length() > 0) + { + status = key_out.set_copy_of_buffer(mppe_recv_key.get_data(packet->get_key_length()), packet->get_key_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Key message with no key length? + // Just ignore the message. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got empty WEP unicast key message.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + else + { + // Set-up RC4 key. Key is the IV and the MS-MPPE-Recv-Key truncated together. + eap_variable_data_c rc4_key(m_am_tools); + status = rc4_key.set_copy_of_buffer(packet->get_key_IV(), EAPOL_RC4_KEY_IV_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + rc4_key.add_data(&mppe_recv_key); + + // Set-up RC4 module + crypto_rc4_c rc4(m_am_tools); + // Set the key for RC4 + if (rc4.set_key(&rc4_key) != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: rc4_set_key failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Decrypt the key to key_out + key_out.set_buffer_length(packet->get_key_length()); + if (rc4.decrypt_data(packet->get_key(), key_out.get_data(packet->get_key_length()), packet->get_key_length()) != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: rc4 failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + key_out.set_data_length(packet->get_key_length()); + } + + // Find out the key type. At the moment only WEP keys are supported. + eapol_key_type_e key_type; + switch (packet->get_key_flag()) + { + case eapol_RC4_key_flag_broadcast: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got WEP broadcast key\n"))); + key_type = eapol_key_type_broadcast; + break; + case eapol_RC4_key_flag_unicast: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got WEP unicast key\n"))); + key_type = eapol_key_type_unicast; + break; + default: + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Key"), + key_out.get_data(key_out.get_data_length()), + key_out.get_data_length())); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eapol_session_key_c wep_key( + m_am_tools, + &key_out, + key_type, + packet->get_key_index(), + true); + + // Forward the keys to lower layers + status = m_partner->packet_data_session_key( + &send_network_id, + &wep_key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if !defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::configure() +{ + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::configure()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::configure()"); + + m_eapol_header_offset = m_partner->get_header_offset( + &m_MTU, &m_trailer_length); + + eap_status_e status = eap_status_process_general_error; + + { + eap_variable_data_c max_eapol_starts(m_am_tools); + + status = read_configure( + cf_str_EAPOL_CORE_starts_max_count.get_field(), + &max_eapol_starts); + if (status != eap_status_ok + || max_eapol_starts.get_is_valid_data() == false + || max_eapol_starts.get_data_length() < sizeof(u32_t)) + { + // Probably not found from db. Use the default value. + m_max_eapol_starts = EAPOL_CORE_MAX_EAPOL_START_SENDINGS; + } + else + { + m_max_eapol_starts = *reinterpret_cast( + max_eapol_starts.get_data(sizeof(u32_t))); + } + } + + { + eap_variable_data_c eapol_start_interval(m_am_tools); + + status = read_configure( + cf_str_EAPOL_CORE_send_start_interval.get_field(), + &eapol_start_interval); + if (status != eap_status_ok + || eapol_start_interval.get_is_valid_data() == false + || eapol_start_interval.get_data_length() < sizeof(u32_t)) + { + // Probably not found from db. Use the default value. + m_eapol_start_interval = EAPOL_CORE_TIMER_SEND_START_AGAIN_TIMEOUT; + } + else + { + m_eapol_start_interval = *reinterpret_cast( + eapol_start_interval.get_data(sizeof(u32_t))); + } + } + +#if defined(USE_EAP_CORE_SERVER) + if (m_is_client == false) + { + eap_variable_data_c data(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAPOL_CORE_skip_start_4_way_handshake.get_field(), + &data); + if (status == eap_status_ok + && data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + u32_t *flag = reinterpret_cast(data.get_data(data.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_skip_start_4_way_handshake = true; + } + else + { + m_skip_start_4_way_handshake = false; + } + } + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + + return EAP_STATUS_RETURN(m_am_tools, m_eap_core->configure()); +} + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::shutdown_operation( + eapol_key_state_c * const handler, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + eap_status_e status = handler->shutdown(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::shutdown() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::shutdown(), m_shutdown_was_called=%d\n"), + (m_is_client == true) ? "client": "server", + m_shutdown_was_called)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::shutdown()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + eap_status_e status; +#if defined(USE_EAPOL_KEY_STATE) + status = m_eapol_key_state_map.for_each(shutdown_operation, true); +#endif //#if defined(USE_EAPOL_KEY_STATE) + + if (m_eap_core != 0) + { + status = m_eap_core->shutdown(); + } + + // This will cancel all timers of this object. + m_partner->cancel_timer(this, EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); +#if defined(USE_EAPOL_KEY_STATE) + m_partner->cancel_timer(this, EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID); +#endif //#if defined(USE_EAPOL_KEY_STATE) + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->read_configure(field, data); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_core_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->write_configure(field, data); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eapol_core_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eapol_core_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::timer_expired( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: [0x%08x]->eapol_core_c::timer_expired(id 0x%02x, data 0x%08x).\n"), + (m_is_client == true) ? "client": "server", + this, + id, + data)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::timer_expired()"); + + if (id == EAPOL_CORE_TIMER_SEND_START_AGAIN_ID) + { + const eap_am_network_id_c * const receive_network_id + = reinterpret_cast(data); + if (m_eapol_starts_sent < m_max_eapol_starts) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAPOL_CORE_TIMER_SEND_START_AGAIN_ID expired, re-start authentication.\n"), + (m_is_client == true ? "client": "server"), + m_eapol_start_interval)); + + m_eapol_starts_sent++; + restart_authentication(receive_network_id , m_is_client, true, true); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TIMER: %s: EAPOL_CORE_TIMER_SEND_START_AGAIN_ID expired, too many re-starts, notifies lower layers.\n"), + (m_is_client == true ? "client": "server"), + m_eapol_start_interval)); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // EAPOL-Start has been sent enough times. Send notification to lower layers. + // After this EAPOL stays quiet and waits for incoming + // packets or authentication restarting. + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + true, // m_is_client + eap_state_notification_generic, + eap_protocol_layer_eapol, + eap_type_none, + eapol_state_start_sent, + eapol_state_no_start_response, + 0 /* EAP identifier not valid here */, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + state_notification(¬ification); + } + } +#if defined(USE_EAPOL_KEY_STATE) + else if (id == EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID elapsed, %s.\n"), + (m_is_client == true) ? "client": "server")); + + const eap_am_network_id_c * const send_network_id + = reinterpret_cast(data); + if (send_network_id->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + (void) remove_eapol_key_state(send_network_id); + } +#endif //#if defined(USE_EAPOL_KEY_STATE) + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::timer_delete_data( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: [0x%08x]->eapol_core_c::timer_delete_data(id 0x%02x, data 0x%08x).\n"), + (m_is_client == true) ? "client": "server", + this, id, data)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::timer_delete_data()"); + + if (id == EAPOL_CORE_TIMER_SEND_START_AGAIN_ID) + { + const eap_am_network_id_c * const send_network_id + = reinterpret_cast(data); + delete send_network_id; + } +#if defined(USE_EAPOL_KEY_STATE) + else if (id == EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID) + + { + const eap_am_network_id_c * const send_network_id + = reinterpret_cast(data); + delete send_network_id; + } +#endif //#if defined(USE_EAPOL_KEY_STATE) + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::init_eapol_key_pmksa_caching_timeout( + const eap_am_network_id_c * const send_network_id) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::init_eapol_key_pmksa_caching_timeout().\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::init_eapol_key_pmksa_caching_timeout()"); + + // Initialize PMK caching timeout of EAPOL Key state. + eap_network_id_selector_c state_selector( + m_am_tools, + send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("init_eapol_key_pmksa_caching_timeout(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + + if (eapol_key_state == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("session not found.\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + eap_status_e status = eapol_key_state->init_pmksa_caching_timeout(); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::init_eapol_key_pmksa_caching_timeout(): ") + EAPL("eapol_key_state->init_pmksa_caching_timeout(), eap_status_e %d\n"), + status)); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::indicate_eapol_key_state_started_eap_authentication( + const eap_am_network_id_c * const send_network_id) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::indicate_eapol_key_state_started_eap_authentication().\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::indicate_eapol_key_state_started_eap_authentication()"); + + // Remove possible EAPOL Key state. + eap_network_id_selector_c state_selector( + m_am_tools, + send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("indicate_eapol_key_state_started_eap_authentication(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + + eap_status_e status(eap_status_handler_does_not_exists_error); + + if (eapol_key_state != 0) + { + status = eapol_key_state->started_eap_authentication(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::indicate_eapol_key_state_started_eap_authentication(): Cannot run eapol_key_state->started_eap_authentication() 0x%08x\n"), + eapol_key_state)); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::remove_eapol_key_state( + const eap_am_network_id_c * const send_network_id) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::remove_eapol_key_state().\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::remove_eapol_key_state()"); + + // Remove possible EAPOL Key state. + eap_network_id_selector_c state_selector( + m_am_tools, + send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("remove_eapol_key_state(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + + if (eapol_key_state != 0) + { + if (eapol_key_state->get_marked_removed() == false) + { + // Do not remove object in use. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::remove_eapol_key_state(): Cannot removed used object 0x%08x\n"), + eapol_key_state)); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + eapol_key_state->shutdown(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::remove_eapol_key_state(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), + eapol_key_state)); + } + + eap_status_e status = m_eapol_key_state_map.remove_handler(&state_selector, true); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::remove_eapol_key_state(): ") + EAPL("eapol_key_state->remove_handler(), eap_status_e %d\n"), + status)); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) + +// +eap_status_e eapol_core_c::asynchronous_init_remove_eapol_key_state( + const eap_am_network_id_c * const send_network_id) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::asynchronous_init_remove_eapol_key_state().\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::asynchronous_init_remove_eapol_key_state()"); + + // NOTE: we cannot delete the eapol_key_state_c object directly, because we will + // return from here to removed object. + + eap_status_e status = eap_status_process_general_error; + + eap_network_id_selector_c state_selector( + m_am_tools, + send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("asynchronous_init_remove_eapol_key_state(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eapol_key_state_c *session = m_eapol_key_state_map.get_handler(&state_selector); + + if (session != 0) + { + session->set_marked_removed(); + + // So we initiate a timer to remove session identified by state_selector. + eap_am_network_id_c * const copy_send_network_id = send_network_id->copy(); + if (copy_send_network_id == 0 + || copy_send_network_id->get_is_valid_data() == false) + { + delete copy_send_network_id; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_partner->set_timer( + this, + EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID, + copy_send_network_id, + EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_TIMEOUT); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::asynchronous_init_remove_eapol_key_state()") + EAPL(": %s: EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID timer set %d ms.\n"), + (m_is_client == true) ? "client": "server", + EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_TIMEOUT)); + } + else + { + // Not found, cannot remove. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::asynchronous_init_remove_eapol_key_state()") + EAPL(": %s: failed session not found.\n"), + (m_is_client == true) ? "client": "server")); + + status = eap_status_ok; + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eapol_core_c::state_notification( + const abs_eap_state_notification_c * const state) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::state_notification(): m_block_state_notifications=%d.\n"), + (m_is_client == true) ? "client": "server", + m_block_state_notifications)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::state_notification()"); + + if (m_block_state_notifications == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::state_notification(): Blocks state notification") + EAPL("Protocol layer %d, Protocol %d, State transition ") + EAPL("from %d=%s to %d=%s, client %d\n"), + state->get_protocol_layer(), + state->get_protocol(), + state->get_previous_state(), + state->get_previous_state_string(), + state->get_current_state(), + state->get_current_state_string(), + state->get_is_client())); + + return; + } + + if (state->get_protocol_layer() == eap_protocol_layer_eap) + { + if (state->get_current_state() == eap_state_identity_request_received + || state->get_current_state() == eap_state_eap_response_sent) + { + if (state->get_current_state() == eap_state_identity_request_received) + { + (void) m_partner->cancel_timer( + this, + EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); + } + + if (state->get_current_state() == eap_state_identity_request_received + || state->get_current_state() == eap_state_eap_response_sent) + { +#if defined(USE_EAPOL_KEY_STATE) + // Indicate EAPOL Key state the started EAP-authentication. + status = indicate_eapol_key_state_started_eap_authentication( + state->get_send_network_id()); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::state_notification(): ") + EAPL("indicate_eapol_key_state_started_eap_authentication(), eap_status_e %d\n"), + status)); + } +#endif //#if defined(USE_EAPOL_KEY_STATE) + } + + } + else if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::state_notification(): %s: EAP-authentication FAILED\n"), + (state->get_is_client() == true ? "client": "server"))); + +#if defined(USE_EAPOL_KEY_STATE) + // Remove possible EAPOL Key state. + status = remove_eapol_key_state( + state->get_send_network_id()); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::state_notification(): ") + EAPL("remove_eapol_key_state(), eap_status_e %d\n"), + status)); + } +#endif //#if defined(USE_EAPOL_KEY_STATE) + + } + else if (state->get_current_state() == eap_state_authentication_finished_successfully) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): %s: EAP authentication SUCCESS\n"), + (state->get_is_client() == true ? "client": "server"))); + +#if defined(USE_EAPOL_KEY_STATE) + eap_network_id_selector_c state_selector( + m_am_tools, + state->get_send_network_id()); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("state_notification(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + eapol_key_state_c *eapol_key_state + = m_eapol_key_state_map.get_handler(&state_selector); + +#if !defined(NO_EAPOL_KEY_STATE_SERVER) + if (m_is_client == false) + { + // server + if (eapol_key_state != 0) + { + // Here we swap the addresses. + eap_am_network_id_c receive_network_id( + m_am_tools, + state->get_send_network_id()->get_destination_id(), + state->get_send_network_id()->get_source_id(), + state->get_send_network_id()->get_type()); + if (receive_network_id.get_is_valid_data() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::state_notification(): ") + EAPL("start_4_way_handshake() failed, allocation error\n"), + status)); + return; + } + + if (m_skip_start_4_way_handshake == true + && (m_authentication_type == eapol_key_authentication_type_RSNA_EAP + || m_authentication_type == eapol_key_authentication_type_RSNA_PSK + || m_authentication_type == eapol_key_authentication_type_WPA_EAP + || m_authentication_type == eapol_key_authentication_type_WPA_PSK + || m_authentication_type == eapol_key_authentication_type_WPXM)) + { + // This is test to skip 4-Way Handshake start. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::state_notification(): ") + EAPL("skips start_4_way_handshake()\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + else + { + status = eapol_key_state->start_4_way_handshake( + &receive_network_id); + } + + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::state_notification(): ") + EAPL("start_4_way_handshake() failed, eap_status_e %d\n"), + status)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): ") + EAPL("start_4_way_handshake(), eap_status_e %d\n"), + status)); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::state_notification(): ") + EAPL("start_4_way_handshake() failed, no eapol_key_state_c object\n"))); + } + } + else +#endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) + { + if (eapol_key_state != 0) + { + eap_status_e status = eapol_key_state->allow_4_way_handshake(); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::state_notification(): ") + EAPL("allow_4_way_handshake() failed, eap_status_e %d\n"), + status)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): ") + EAPL("allow_4_way_handshake(), eap_status_e %d\n"), + status)); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::state_notification(): ") + EAPL("allow_4_way_handshake() failed, no eapol_key_state_c object\n"))); + } + } +#endif //#if defined(USE_EAPOL_KEY_STATE) + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): Unknown notification: ") + EAPL("Protocol layer %d, Protocol %d, State transition ") + EAPL("from %d=%s to %d=%s, client %d\n"), + state->get_protocol_layer(), + state->get_protocol(), + state->get_previous_state(), + state->get_previous_state_string(), + state->get_current_state(), + state->get_current_state_string(), + state->get_is_client())); + } + } +#if defined(USE_EAPOL_KEY_STATE) + else if (state->get_protocol_layer() == eap_protocol_layer_eapol_key) + { + // This nofifation is from eapol_key_state_c object. + if (state->get_current_state() + == eapol_key_state_802_11i_authentication_terminated_unsuccessfull) + { + if (state->get_protocol() == eapol_key_handshake_type_4_way_handshake) + { + // 4-Way Handshake failed. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::state_notification(): ") + EAPL("%s: 4-Way Handshake FAILED\n"), + (state->get_is_client() == true ? "client": "server"))); + } + else if (state->get_protocol() == eapol_key_handshake_type_group_key_handshake) + { + // Group Key Handshake failed. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_core_c::state_notification(): ") + EAPL("%s: Group Key Handshake FAILED\n"), + (state->get_is_client() == true ? "client": "server"))); + } + } + else if (state->get_current_state() + == eapol_key_state_802_11i_authentication_finished_successfull) + { + if (state->get_protocol() == eapol_key_handshake_type_4_way_handshake) + { + // 4-Way Handshake succesfull. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): %s: 4-Way Handshake SUCCESS.\n"), + (state->get_is_client() == true ? "client": "server"))); + } + else if (state->get_protocol() == eapol_key_handshake_type_group_key_handshake) + { + // Group Key Handshake succesfull. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): %s: Group Key Handshake SUCCESS.\n"), + (state->get_is_client() == true ? "client": "server"))); + } + else if (state->get_protocol() == eapol_key_handshake_type_802_11i_handshake) + { + // Full 802.11i authentication succesfull. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): %s: ") + EAPL("Full 802.11i authentication SUCCESS.\n"), + (state->get_is_client() == true ? "client": "server"))); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): Unknown notification: ") + EAPL("Protocol layer %d, Protocol %d, State transition ") + EAPL("from %d=%s to %d=%s, client %d\n"), + state->get_protocol_layer(), + state->get_protocol(), + state->get_previous_state(), + state->get_previous_state_string(), + state->get_current_state(), + state->get_current_state_string(), + state->get_is_client())); + } + } +#if defined(EAP_USE_WPXM) + else if (state->get_current_state() + == eapol_key_state_wpxm_reassociation_finished_successfull) + { + if (state->get_protocol() == eapol_key_handshake_type_WPXM_reassociation) + { + // WPXM reassociation succesfull. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): %s: ") + EAPL("WPXM reassociation SUCCESS.\n"), + (state->get_is_client() == true ? "client": "server"))); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): Unknown notification: ") + EAPL("Protocol layer %d, Protocol %d, State transition ") + EAPL("from %d=%s to %d=%s, client %d\n"), + state->get_protocol_layer(), + state->get_protocol(), + state->get_previous_state(), + state->get_previous_state_string(), + state->get_current_state(), + state->get_current_state_string(), + state->get_is_client())); + } + } +#endif //#if defined(EAP_USE_WPXM) + else if (state->get_current_state() + == eapol_key_state_group_key_handshake_successfull) + { + if (state->get_protocol() == eapol_key_handshake_type_group_key_handshake) + { + // Group Key Handshake succesfull. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): %s: Group Key Handshake SUCCESS.\n"), + (state->get_is_client() == true ? "client": "server"))); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): Unknown notification: ") + EAPL("Protocol layer %d, Protocol %d, State transition ") + EAPL("from %d=%s to %d=%s, client %d\n"), + state->get_protocol_layer(), + state->get_protocol(), + state->get_previous_state(), + state->get_previous_state_string(), + state->get_current_state(), + state->get_current_state_string(), + state->get_is_client())); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::state_notification(): Unknown notification: ") + EAPL("Protocol layer %d, Protocol %d, State transition ") + EAPL("from %d=%s to %d=%s, client %d\n"), + state->get_protocol_layer(), + state->get_protocol(), + state->get_previous_state(), + state->get_previous_state_string(), + state->get_current_state(), + state->get_current_state_string(), + state->get_is_client())); + } + } +#endif //#if defined(USE_EAPOL_KEY_STATE) + + + m_partner->state_notification(state); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const /* send_network_id */) +{ + // eapol_core_c object does not support asynchronous_init_remove_eap_session(). + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::asynchronous_start_authentication( + const eap_am_network_id_c * const /* receive_network_id */, + const bool /* is_client_when_true */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_core_c::check_is_valid_eap_type( + const eap_type_value_e eap_type) +{ + eap_status_e status = m_partner->check_is_valid_eap_type(eap_type); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_core_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + eap_status_e status = m_partner->get_eap_type_list(eap_type_list); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::cancel_authentication_session( + eapol_key_state_c * const handler, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::cancel_authentication_session(): this = 0x%08x => 0x%08x.\n"), + handler, + dynamic_cast(handler))); + + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + eap_status_e status = handler->cancel_authentication_session(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_core_c::cancel_all_authentication_sessions() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_core_c::cancel_all_authentication_sessions(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::cancel_all_authentication_sessions()"); + + eap_status_e status(eap_status_ok); + + + bool previous_block = m_block_state_notifications; + m_block_state_notifications = true; + +#if !defined(NO_EAP_SESSION_CORE) + if (m_eap_core != 0) + { + status = m_eap_core->synchronous_cancel_all_eap_sessions(); + } +#endif //#if !defined(NO_EAP_SESSION_CORE) + + +#if defined(USE_EAPOL_KEY_STATE) + status = m_eapol_key_state_map.for_each(cancel_authentication_session, true); +#endif //#if defined(USE_EAPOL_KEY_STATE) + + m_block_state_notifications = previous_block; + + + // This will cancel all timers of this object. + m_partner->cancel_timer(this, EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); +#if defined(USE_EAPOL_KEY_STATE) + m_partner->cancel_timer(this, EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID); +#endif //#if defined(USE_EAPOL_KEY_STATE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) + +EAP_FUNC_EXPORT eap_status_e eapol_core_c::get_and_increment_global_key_counter( + eap_variable_data_c * const key_counter) +{ + key_counter->reset(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) +/** + * Function creates a state for later use. This is for optimazing 4-Way Handshake. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. MAC address of + * Supplicant should be in destination address. + * @param authentication_type is the selected authentication type. + */ +EAP_FUNC_EXPORT eap_status_e eapol_core_c::create_state( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type + ) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::create_state().\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::create_state()"); + + if (receive_network_id->get_type() != eapol_ethernet_type_pae) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::create_state(): Illegal Ethernet type %d\n"), + receive_network_id->get_type())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ethernet_type_not_supported); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c state_selector( + m_am_tools, + &send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_authentication_type = authentication_type; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("create_state(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + + eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + + if (eapol_key_state != 0) + { + // Reuse the session. + eapol_key_state->unset_marked_removed(); + + if (m_is_client == false) + { + // In test version do not reset server. + } + else + { + status = eapol_key_state->reset(); + if (status != eap_status_ok) + { + // We cannot reuse the session. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eapol_core_c::create_state(): eapol_key_state NOT reused.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + + if (eapol_key_state == 0) + { + eapol_key_state = new eapol_key_state_c( + m_am_tools, + this, + m_partner, + m_is_client, + receive_network_id, + authentication_type); + if (eapol_key_state == 0 + || eapol_key_state->get_is_valid() == false) + { + if (eapol_key_state != 0) + { + eapol_key_state->shutdown(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::create_state(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), + eapol_key_state)); + } + delete eapol_key_state; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = eapol_key_state->initialize( + receive_network_id, + authentication_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_eapol_key_state_map.add_handler(&state_selector, eapol_key_state); + if (status != eap_status_ok) + { + if (eapol_key_state != 0) + { + eapol_key_state->shutdown(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::create_state(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), + eapol_key_state)); + } + delete eapol_key_state; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = eapol_key_state->initialize( + receive_network_id, + authentication_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = eapol_key_state->configure(); + if (status != eap_status_ok) + { + status = remove_eapol_key_state( + &send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::create_state(): ") + EAPL("remove_eapol_key_state(), eap_status_e %d\n"), + status)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) +/** + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. MAC address of + * Supplicant should be in destination address. + * @param authenticator_RSNA_IE is RSN IE of authenticator. Authenticator + * sends this in Beacon or Probe message. + * @param supplicant_RSNA_IE is RSN IE of supplicant. Supplicant sends + * this in (re)association request message. + * @param eapol_pairwise_cipher is the selected pairwise cipher. + * @param eapol_group_cipher is the selected group cipher. + */ +EAP_FUNC_EXPORT eap_status_e eapol_core_c::association( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const authenticator_RSNA_IE, + const eap_variable_data_c * const supplicant_RSNA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher, + const eap_variable_data_c * const pre_shared_key_PSK + ) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::association().\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::association()"); + + if (receive_network_id->get_type() != eapol_ethernet_type_pae) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::association(): Illegal Ethernet type %d\n"), + receive_network_id->get_type())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ethernet_type_not_supported); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c state_selector( + m_am_tools, + &send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_authentication_type = authentication_type; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("association(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + + eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + +#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + if (eapol_key_state != 0) + { + // Reuse the session. + eapol_key_state->unset_marked_removed(); + + if (m_is_client == false) + { + // In test version do not reset server. + } + else + { + status = eapol_key_state->reset(); + if (status != eap_status_ok) + { + // We cannot reuse the session. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eapol_core_c::association(): eapol_key_state NOT reused.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } +#endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + + if (eapol_key_state == 0) + { + +#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + eapol_key_state = new eapol_key_state_c( + m_am_tools, + this, + m_partner, + m_is_client, + receive_network_id, + authentication_type, + authenticator_RSNA_IE, + supplicant_RSNA_IE, + eapol_pairwise_cipher, + eapol_group_cipher, + pre_shared_key_PSK); + if (eapol_key_state == 0 + || eapol_key_state->get_is_valid() == false) + { + if (eapol_key_state != 0) + { + eapol_key_state->shutdown(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::association(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), + eapol_key_state)); + } + delete eapol_key_state; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = eapol_key_state->initialize( + receive_network_id, + authentication_type, + authenticator_RSNA_IE, + supplicant_RSNA_IE, + eapol_pairwise_cipher, + eapol_group_cipher, + pre_shared_key_PSK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_eapol_key_state_map.add_handler(&state_selector, eapol_key_state); + if (status != eap_status_ok) + { + if (eapol_key_state != 0) + { + eapol_key_state->shutdown(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::association(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), + eapol_key_state)); + } + delete eapol_key_state; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#else + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + +#endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + } + else + { + status = eapol_key_state->initialize( + receive_network_id, + authentication_type, + authenticator_RSNA_IE, + supplicant_RSNA_IE, + eapol_pairwise_cipher, + eapol_group_cipher, + pre_shared_key_PSK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + +#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + status = eapol_key_state->configure(); + if (status != eap_status_ok) + { + status = remove_eapol_key_state( + &send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::association(): ") + EAPL("remove_eapol_key_state(), eap_status_e %d\n"), + status)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + + if (authentication_type == eapol_key_authentication_type_RSNA_PSK + || authentication_type == eapol_key_authentication_type_WPA_PSK) + { + +#if !defined(NO_EAPOL_KEY_STATE_SERVER) + if (m_is_client == false) + { +#if defined(USE_EAPOL_KEY_STATE) + if (m_skip_start_4_way_handshake == true) + { + // This is test to skip 4-Way Handshake start. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::association(): ") + EAPL("skips start_4_way_handshake()\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else +#endif //#if defined(USE_EAPOL_KEY_STATE) + { + status = eapol_key_state->start_4_way_handshake( + receive_network_id); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else +#endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) + { + eapol_key_state->allow_4_way_handshake(); + } + } +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + else if (authentication_type == eapol_key_authentication_type_RSNA_EAP + || authentication_type == eapol_key_authentication_type_WPA_EAP + || authentication_type == eapol_key_authentication_type_802_1X + || authentication_type == eapol_key_authentication_type_WPXM + || authentication_type == eapol_key_authentication_type_WFA_SC) + { + // Creates a EAP-session. + status = m_eap_core->synchronous_create_eap_session(receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) +/** + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. + * MAC address of Supplicant should be in destination address. + */ +EAP_FUNC_EXPORT eap_status_e eapol_core_c::disassociation( + const eap_am_network_id_c * const receive_network_id + ) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::disassociation().\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::disassociation()"); + + if (receive_network_id == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + (void) m_partner->cancel_timer(this, EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); + +#if !defined(NO_EAP_SESSION_CORE) + // First we remove possible EAP session. + (void) m_eap_core->synchronous_remove_eap_session(receive_network_id); +#endif + + status = init_eapol_key_pmksa_caching_timeout( + &send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::disassociation(): ") + EAPL("init_eapol_key_pmksa_caching_timeout(), eap_status_e %d\n"), + status)); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +/// @see abs_eap_core_c::add_rogue_ap(). +EAP_FUNC_EXPORT eap_status_e eapol_core_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::add_rogue_ap().\n"), + (m_is_client == true) ? "client": "server")); + + const eap_status_e status = m_partner->add_rogue_ap(rogue_ap_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_core_c::tkip_mic_failure( + const eap_am_network_id_c * const receive_network_id, + const bool fatal_failure_when_true, + const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::tkip_mic_failure().\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = eap_status_process_general_error; + +#if defined(USE_EAPOL_KEY_STATE) + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c state_selector( + m_am_tools, + &send_network_id); + + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tkip_mic_failure(): EAPOL-Key session"), + state_selector.get_data(state_selector.get_data_length()), + state_selector.get_data_length())); + + + eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); + + if (eapol_key_state != 0) + { + status = eapol_key_state->tkip_mic_failure( + fatal_failure_when_true, + tkip_mic_failure_type); + } + else + { + status = eap_status_handler_does_not_exists_error; + } + +#else + + status = eap_status_not_supported; + +#endif //#if defined(USE_EAPOL_KEY_STATE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::set_session_timeout( + const u32_t /* session_timeout_ms */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_handle_tlv_message_data.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_handle_tlv_message_data.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2506 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 40 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_automatic_variable.h" +#include "eapol_handle_tlv_message_data.h" +#include "eap_variable_data.h" +#include "eap_am_network_id.h" +#include "eap_buffer.h" +#include "eapol_session_key.h" +#include "abs_eap_state_notification.h" +#include "eap_state_notification.h" + +#if defined(USE_EAP_SIMPLE_CONFIG) +#include "simple_config_types.h" +#include "simple_config_credential.h" +#include "simple_config_payloads.h" +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + +/** @file */ + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_handle_tlv_message_data_c::~eapol_handle_tlv_message_data_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_handle_tlv_message_data_c::eapol_handle_tlv_message_data_c( + abs_eap_am_tools_c * const tools) + : eap_tlv_message_data_c(tools) + , m_am_tools(tools) + , m_is_valid(true) +{ +} + +//------------------------------------------------------------------- + +/** + * This function should increase reference count. + */ +EAP_FUNC_EXPORT void eapol_handle_tlv_message_data_c::object_increase_reference_count() +{ +} + +//------------------------------------------------------------------- + +/** + * This function should first decrease reference count + * and second return the remaining reference count. + * Reference count must not be decreased when it is zero. + */ +EAP_FUNC_EXPORT u32_t eapol_handle_tlv_message_data_c::object_decrease_reference_count() +{ + return 0; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eapol_handle_tlv_message_data_c::get_is_valid() +{ + return m_is_valid && eap_tlv_message_data_c::get_is_valid(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eapol_handle_tlv_message_data_c::get_payload_size( + const eap_am_network_id_c * const network_id) const +{ + return + (3ul * eap_tlv_header_c::get_header_length() // Each attribute have their own header. + + network_id->get_source_id()->get_data_length() + + network_id->get_destination_id()->get_data_length() + + sizeof(network_id->get_type())); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eapol_handle_tlv_message_data_c::get_payload_size( + const abs_eap_state_notification_c * const state) const +{ + return + (7ul * eap_tlv_header_c::get_header_length()) // Each attribute have their own header. + + (get_payload_size(state->get_send_network_id()) + + sizeof(u32_t) // eap_protocol_layer_e + + sizeof(state->get_protocol()) + + eap_expanded_type_c::get_eap_expanded_type_size() + + sizeof(state->get_current_state()) + + sizeof(u32_t) // bool is_client + + sizeof(u32_t) // eap_status_e authentication error + ); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eapol_handle_tlv_message_data_c::get_payload_size( + const eapol_session_key_c * const session_key) const +{ + return + ((5ul * eap_tlv_header_c::get_header_length()) // Each attribute have their own header. + + session_key->get_key()->get_data_length() + + session_key->get_sequence_number()->get_data_length() + + sizeof(u32_t) // const eapol_key_type_e m_key_type + + sizeof(session_key->get_key_index()) + + sizeof(u32_t) // const bool m_key_tx_bit + ); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT u32_t eapol_handle_tlv_message_data_c::get_payload_size( + network_key_and_index_c * key) const +{ + u32_t size(0ul); + + if (key != 0) + { + size += eap_tlv_header_c::get_header_length() + + sizeof(key->get_network_key_index()) // Size of Network Key Index + + eap_tlv_header_c::get_header_length() + + key->get_network_key()->get_data_length() // Size of Network Key + ; + } + + return (size); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT u32_t eapol_handle_tlv_message_data_c::get_payload_size( + EAP_TEMPLATE_CONST eap_array_c * network_keys) const +{ + u32_t size(0ul); + + for (u32_t ind_network_key = 0ul; ind_network_key < network_keys->get_object_count(); ind_network_key++) + { + network_key_and_index_c * const key = network_keys->get_object(ind_network_key); + if (key != 0) + { + size += eap_tlv_header_c::get_header_length() // Size of structure header + + get_payload_size(key); // Size of Network Key + } + } // for () + + return (size); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT u32_t eapol_handle_tlv_message_data_c::get_payload_size( + simple_config_credential_c * const credential) const +{ + u32_t size(0ul); + + if (credential != 0) + { + size += eap_tlv_header_c::get_header_length() + + sizeof(credential->get_network_index()) // Size of Network Index + + eap_tlv_header_c::get_header_length() + + credential->get_SSID()->get_data_length() // Size of SSID + + eap_tlv_header_c::get_header_length() + + sizeof(u16_t) // Size of Authentiction type + + eap_tlv_header_c::get_header_length() + + sizeof(u16_t) // Size of Encryption type + ; + + size += eap_tlv_header_c::get_header_length() // Size of header of Array + + get_payload_size(credential->get_network_keys()); + + size += eap_tlv_header_c::get_header_length() + + credential->get_MAC_address()->get_data_length() // Size of MAC Address + ; + } + + return (size); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT u32_t eapol_handle_tlv_message_data_c::get_payload_size( + EAP_TEMPLATE_CONST eap_array_c * const credential_array) const +{ + u32_t size(0ul); + + for (u32_t ind_credential = 0ul; ind_credential < credential_array->get_object_count(); ind_credential++) + { + simple_config_credential_c * const credential = credential_array->get_object(ind_credential); + if (credential != 0) + { + size += eap_tlv_header_c::get_header_length() // Size of structure header + + get_payload_size(credential); + } + } // for () + + return (size); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_structured_parameter_header( + const eapol_tlv_message_type_e type, + const u32_t length) +{ + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_structured_parameter_header(): type=%s\n"), + get_type_string(type))); + + return add_message_header( + type, + length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const eapol_tlv_message_type_e type, + const u32_t integer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(type))); + + const u32_t network_order_integer(eap_htonl(integer)); + + eap_status_e status = add_message_data( + type, + sizeof(network_order_integer), + &network_order_integer); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const u64_t long_integer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_u64_t))); + + const u64_t network_order_long_integer(eap_htonll(long_integer)); + + eap_status_e status = add_message_data( + eapol_tlv_message_type_u64_t, + sizeof(network_order_long_integer), + &network_order_long_integer); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const u32_t integer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_u32_t))); + + const u32_t network_order_integer(eap_htonl(integer)); + + eap_status_e status = add_message_data( + eapol_tlv_message_type_u32_t, + sizeof(network_order_integer), + &network_order_integer); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const u16_t short_integer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_u16_t))); + + const u16_t network_order_short_integer(eap_htons(short_integer)); + + eap_status_e status = add_message_data( + eapol_tlv_message_type_u16_t, + sizeof(network_order_short_integer), + &network_order_short_integer); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const u8_t byte_integer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_u8_t))); + + eap_status_e status = add_message_data( + eapol_tlv_message_type_u8_t, + sizeof(byte_integer), + &byte_integer); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const bool boolean) +{ + const u32_t value((boolean == false) ? 0u: 1u); + + return add_parameter_data( + eapol_tlv_message_type_boolean, + value); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const eap_status_e status) +{ + const u32_t value(static_cast(status)); + + return add_parameter_data( + eapol_tlv_message_type_eap_status, + value); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const eapol_tlv_message_type_function_e function) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s, function=%s\n"), + get_type_string(eapol_tlv_message_type_function), + get_function_string(function))); + + if (function < eapol_tlv_message_type_function_none + || function >= eapol_tlv_message_type_function_illegal_value) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t network_order_function(eap_htonl(function)); + + eap_status_e status = add_message_data( + eapol_tlv_message_type_function, + sizeof(network_order_function), + &network_order_function); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const eap_variable_data_c * const variable_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_variable_data))); + + if (variable_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_process_general_error); + + if (variable_data->get_is_valid_data() == false) + { + // Empty variable data. Add just the header. + status = add_structured_parameter_header( + eapol_tlv_message_type_variable_data, + 0ul); + } + else + { + status = add_message_data( + eapol_tlv_message_type_variable_data, + variable_data->get_data_length(), + variable_data->get_data()); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const eap_am_network_id_c * const network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_network_id))); + + if (network_id == 0 + || network_id->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t size_of_network_id = get_payload_size(network_id); + + eap_status_e status = add_structured_parameter_header( + eapol_tlv_message_type_network_id, + size_of_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data( + network_id->get_source_id()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data( + network_id->get_destination_id()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data( + network_id->get_type()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const eap_buf_chain_wr_c * const packet_buffer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_variable_data))); + + if (packet_buffer == 0 + || packet_buffer->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = add_message_data( + eapol_tlv_message_type_variable_data, + packet_buffer->get_data_length(), + packet_buffer->get_data(packet_buffer->get_data_length())); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const eapol_session_key_c * const session_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_session_key))); + + if (session_key == 0 + || session_key->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t size_of_session_key(get_payload_size(session_key)); + + eap_status_e status = add_structured_parameter_header( + eapol_tlv_message_type_session_key, + size_of_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data( + session_key->get_key()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data( + session_key->get_sequence_number()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data( + eapol_tlv_message_type_eapol_key_type, + static_cast(session_key->get_key_type())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(session_key->get_key_index()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(session_key->get_key_tx_bit()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const abs_eap_state_notification_c * const state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_eap_state_notification))); + + if (state == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t size_of_state(get_payload_size(state)); + + eap_status_e status = add_structured_parameter_header( + eapol_tlv_message_type_eap_state_notification, + size_of_state); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(state->get_send_network_id()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data( + eapol_tlv_message_type_eap_protocol_layer, + static_cast(state->get_protocol_layer())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(state->get_protocol()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(state->get_eap_type()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(state->get_current_state()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(state->get_is_client()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(state->get_authentication_error()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_eap_type))); + + void * type_buffer = 0; + + eap_status_e status = allocate_message_buffer( + eapol_tlv_message_type_eap_type, + eap_expanded_type_c::get_eap_expanded_type_size(), + &type_buffer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_expanded_type_c::write_type( + m_am_tools, + 0ul, ///< Index is from 0 to n. Index 0 is the first EAP type field after base EAP header. + type_buffer, + eap_expanded_type_c::get_eap_expanded_type_size(), + true, ///< True value writes always Extented Type. + eap_type ///< The EAP type to be written. + ); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eap_tlv_message_data_c::add_message_data(): type %2d=0x%08x, length %3d=0x%08x\n"), + eapol_tlv_message_type_eap_type, + eapol_tlv_message_type_eap_type, + eap_expanded_type_c::get_eap_expanded_type_size(), + eap_expanded_type_c::get_eap_expanded_type_size())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("add_message_data()"), + type_buffer, + eap_expanded_type_c::get_eap_expanded_type_size())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + const eap_general_header_base_c * const packet_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_variable_data))); + + if (packet_data == 0 + || packet_data->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = add_message_data( + eapol_tlv_message_type_variable_data, + packet_data->get_header_buffer_length(), + packet_data->get_header_buffer(packet_data->get_header_buffer_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data( + EAP_TEMPLATE_CONST eap_array_c * const credential_array) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::add_parameter_data(): type=%s\n"), + get_type_string(eapol_tlv_message_type_protected_setup_credential))); + + if (credential_array == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t size_of_credential_array(get_payload_size(credential_array)); + + eap_status_e status = add_structured_parameter_header( + eapol_tlv_message_type_array, + size_of_credential_array); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + for (u32_t ind_credential = 0ul; ind_credential < credential_array->get_object_count(); ind_credential++) + { + simple_config_credential_c * const credential = credential_array->get_object(ind_credential); + if (credential != 0) + { + const u32_t size_of_credential(get_payload_size(credential)); + + eap_status_e status = add_structured_parameter_header( + eapol_tlv_message_type_protected_setup_credential, + size_of_credential); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(credential->get_network_index()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(credential->get_SSID()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(static_cast(credential->get_Authentication_Type())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(static_cast(credential->get_Encryption_Type())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t size_of_network_key_array(get_payload_size(credential->get_network_keys())); + + status = add_structured_parameter_header( + eapol_tlv_message_type_array, + size_of_network_key_array); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (u32_t ind_network_key = 0ul; ind_network_key < credential->get_network_keys()->get_object_count(); ind_network_key++) + { + network_key_and_index_c * const network_key = credential->get_network_keys()->get_object(ind_network_key); + if (network_key != 0) + { + const u32_t size_of_network_key(get_payload_size(network_key)); + + status = add_structured_parameter_header( + eapol_tlv_message_type_network_key, + size_of_network_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(network_key->get_network_key_index()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_parameter_data(network_key->get_network_key()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } // for () + + status = add_parameter_data(credential->get_MAC_address()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } // for () + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const integer_header, + u64_t * const value) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(integer_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(u64_t *)"), + integer_header->get_header_buffer(integer_header->get_header_buffer_length()), + integer_header->get_header_buffer_length())); + + if (static_cast(integer_header->get_type()) + != eapol_tlv_message_type_u64_t) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + const u8_t * const data = integer_header->get_value(sizeof(u64_t)); + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + *value = + eap_read_u64_t_network_order( + data, + sizeof(u64_t)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const integer_header, + u32_t * const value) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(integer_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(u32_t *)"), + integer_header->get_header_buffer(integer_header->get_header_buffer_length()), + integer_header->get_header_buffer_length())); + + if (static_cast(integer_header->get_type()) + != eapol_tlv_message_type_boolean + && static_cast(integer_header->get_type()) + != eapol_tlv_message_type_eap_protocol_layer + && static_cast(integer_header->get_type()) + != eapol_tlv_message_type_eapol_key_802_11_authentication_mode + && static_cast(integer_header->get_type()) + != eapol_tlv_message_type_eapol_key_authentication_type + && static_cast(integer_header->get_type()) + != eapol_tlv_message_type_eapol_key_type + && static_cast(integer_header->get_type()) + != eapol_tlv_message_type_eapol_tkip_mic_failure_type + && static_cast(integer_header->get_type()) + != eapol_tlv_message_type_eapol_wlan_authentication_state + && static_cast(integer_header->get_type()) + != eapol_tlv_message_type_error + && static_cast(integer_header->get_type()) + != eapol_tlv_message_type_function + && static_cast(integer_header->get_type()) + != eapol_tlv_message_type_RSNA_cipher + && static_cast(integer_header->get_type()) + != eapol_tlv_message_type_u32_t + && static_cast(integer_header->get_type()) + != eapol_tlv_message_type_eap_status + ) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + const u8_t * const data = integer_header->get_value(sizeof(u32_t)); + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + *value = + eap_read_u32_t_network_order( + data, + sizeof(u32_t)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const integer_header, + u16_t * const value) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(integer_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(u16_t *)"), + integer_header->get_header_buffer(integer_header->get_header_buffer_length()), + integer_header->get_header_buffer_length())); + + if (static_cast(integer_header->get_type()) + != eapol_tlv_message_type_u16_t) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + const u8_t * const data = integer_header->get_value(sizeof(u16_t)); + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + *value = + eap_read_u16_t_network_order( + data, + sizeof(u16_t)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const integer_header, + u8_t * const value) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(integer_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(u8_t *)"), + integer_header->get_header_buffer(integer_header->get_header_buffer_length()), + integer_header->get_header_buffer_length())); + + if (static_cast(integer_header->get_type()) + != eapol_tlv_message_type_u8_t) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + const u8_t * const data = integer_header->get_value(sizeof(u8_t)); + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + *value = *data; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const function_header, + eapol_tlv_message_type_function_e * const function) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(function_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(eapol_tlv_message_type_function_e *)"), + function_header->get_header_buffer(function_header->get_header_buffer_length()), + function_header->get_header_buffer_length())); + + if (static_cast(function_header->get_type()) + != eapol_tlv_message_type_function) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u32_t host_order(0ul); + + eap_status_e status = get_parameter_data( + function_header, + &host_order); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *function = static_cast(host_order); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s, function=%s\n"), + get_type_string(eapol_tlv_message_type_function), + get_function_string(*function) + )); + + if (*function < eapol_tlv_message_type_function_none + || eapol_tlv_message_type_function_illegal_value <= *function) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const network_id_header, + eap_am_network_id_c * const new_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(network_id_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(eap_am_network_id_c *)"), + network_id_header->get_header_buffer(network_id_header->get_header_buffer_length()), + network_id_header->get_header_buffer_length())); + + if (static_cast(network_id_header->get_type()) + != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + eapol_handle_tlv_message_data_c network_id_data(m_am_tools); + + if (network_id_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = network_id_data.set_message_data( + network_id_header->get_value_length(), + network_id_header->get_value(network_id_header->get_value_length())); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_array_c network_id_members(m_am_tools); + + status = network_id_data.parse_message_data(&network_id_members); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u32_t member_index(0ul); + + eap_variable_data_c source_id( + m_am_tools); + + if (source_id.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + const eap_tlv_header_c * const source_id_header = network_id_members.get_object(member_index); + if (source_id_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = network_id_data.get_parameter_data(source_id_header, &source_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++member_index; + + eap_variable_data_c destination_id( + m_am_tools); + + if (destination_id.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + const eap_tlv_header_c * const destination_id_header = network_id_members.get_object(member_index); + if (destination_id_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = network_id_data.get_parameter_data(destination_id_header, &destination_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++member_index; + + u16_t type_value(0ul); + + { + const eap_tlv_header_c * const type_header = network_id_members.get_object(member_index); + if (type_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = network_id_data.get_parameter_data(type_header, &type_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + status = new_network_id->set_copy_of_am_network_id( + source_id.get_data(), + source_id.get_data_length(), + destination_id.get_data(), + destination_id.get_data_length(), + type_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const variable_data_header, + eap_variable_data_c * const variable_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(variable_data_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(eap_variable_data_c *)"), + variable_data_header->get_header_buffer(variable_data_header->get_header_buffer_length()), + variable_data_header->get_header_buffer_length())); + + if (static_cast(variable_data_header->get_type()) + != eapol_tlv_message_type_variable_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + eap_status_e status = variable_data->set_copy_of_buffer( + variable_data_header->get_value(variable_data_header->get_value_length()), + variable_data_header->get_value_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const session_key_header, + eapol_session_key_c * const session_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(session_key_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(eapol_session_key_c *)"), + session_key_header->get_header_buffer(session_key_header->get_header_buffer_length()), + session_key_header->get_header_buffer_length())); + + if (static_cast(session_key_header->get_type()) + != eapol_tlv_message_type_session_key) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + eapol_handle_tlv_message_data_c session_key_data(m_am_tools); + + if (session_key_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = session_key_data.set_message_data( + session_key_header->get_value_length(), + session_key_header->get_value(session_key_header->get_value_length())); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_array_c session_key_members(m_am_tools); + + status = session_key_data.parse_message_data(&session_key_members); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t member_index(0ul); + + { + const eap_tlv_header_c * const tmp_session_key_header = session_key_members.get_object(member_index); + if (tmp_session_key_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_variable_data_c key( + m_am_tools); + + if (key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = session_key_data.get_parameter_data(tmp_session_key_header, &key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = session_key->set_key(&key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + ++member_index; + + { + const eap_tlv_header_c * const sequence_number_header = session_key_members.get_object(member_index); + if (sequence_number_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_variable_data_c sequence_number( + m_am_tools); + + if (sequence_number.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = session_key_data.get_parameter_data(sequence_number_header, &sequence_number); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = session_key->set_sequence_number(&sequence_number); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + ++member_index; + + { + const eap_tlv_header_c * const key_type_header = session_key_members.get_object(member_index); + if (key_type_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t value(0ul); + + status = session_key_data.get_parameter_data(key_type_header, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + session_key->set_key_type(static_cast(value)); + } + + ++member_index; + + { + const eap_tlv_header_c * const key_index_header = session_key_members.get_object(member_index); + if (key_index_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t value(0ul); + + status = session_key_data.get_parameter_data(key_index_header, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + session_key->set_key_index(value); + } + + ++member_index; + + { + const eap_tlv_header_c * const key_tx_bit_header = session_key_members.get_object(member_index); + if (key_tx_bit_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t value(0ul); + + status = session_key_data.get_parameter_data(key_tx_bit_header, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + session_key->set_key_tx_bit((value == 0) ? false : true); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const state_header, + eap_state_notification_c * * const state) + +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(state_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(eap_state_notification_c *)"), + state_header->get_header_buffer(state_header->get_header_buffer_length()), + state_header->get_header_buffer_length())); + + if (static_cast(state_header->get_type()) + != eapol_tlv_message_type_eap_state_notification) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + eapol_handle_tlv_message_data_c session_key_data(m_am_tools); + + if (session_key_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = session_key_data.set_message_data( + state_header->get_value_length(), + state_header->get_value(state_header->get_value_length())); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_array_c session_key_members(m_am_tools); + + status = session_key_data.parse_message_data(&session_key_members); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u32_t member_index(0ul); + + eap_am_network_id_c send_network_id(m_am_tools); + + { + const eap_tlv_header_c * const send_network_id_header = session_key_members.get_object(member_index); + if (send_network_id_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = get_parameter_data(send_network_id_header, &send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++member_index; + + eap_protocol_layer_e protocol_layer(eap_protocol_layer_none); + + { + const eap_tlv_header_c * const protocol_layer_header = session_key_members.get_object(member_index); + if (protocol_layer_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t value(0ul); + + status = session_key_data.get_parameter_data(protocol_layer_header, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + protocol_layer = static_cast(value); + } + + + ++member_index; + + u32_t protocol(0ul); + + { + const eap_tlv_header_c * const protocol_header = session_key_members.get_object(member_index); + if (protocol_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = session_key_data.get_parameter_data(protocol_header, &protocol); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++member_index; + + eap_type_value_e eap_type(eap_type_none); + + { + const eap_tlv_header_c * const eap_type_header = session_key_members.get_object(member_index); + if (eap_type_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = session_key_data.get_parameter_data(eap_type_header, &eap_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++member_index; + + u32_t current_state(0ul); + + { + const eap_tlv_header_c * const current_state_header = session_key_members.get_object(member_index); + if (current_state_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = session_key_data.get_parameter_data(current_state_header, ¤t_state); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++member_index; + + bool is_client(true); + + { + const eap_tlv_header_c * const is_client_header = session_key_members.get_object(member_index); + if (is_client_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t value(0ul); + + status = session_key_data.get_parameter_data(is_client_header, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + is_client = (value == 0ul) ? false : true; + } + + + ++member_index; + + eap_status_e authentication_error(eap_status_ok); + + { + const eap_tlv_header_c * const authentication_error_header = session_key_members.get_object(member_index); + if (authentication_error_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t value(0ul); + + status = session_key_data.get_parameter_data(authentication_error_header, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + authentication_error = static_cast(value); + } + + + if (eap_type != eap_type_none) + { + *state = new eap_state_notification_c( + m_am_tools, + &send_network_id, + is_client, + eap_state_notification_eap, + protocol_layer, + eap_type, + current_state, + current_state, + 0ul, + false); + } + else + { + + + *state = new eap_state_notification_c( + m_am_tools, + &send_network_id, + is_client, + eap_state_notification_generic, + protocol_layer, + protocol, + current_state, + current_state, + 0ul, + false); + } + + if ((*state) == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + (*state)->set_authentication_error(authentication_error); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const eap_type_header, + eap_type_value_e * const eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(eap_type_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(eap_type_value_e *)"), + eap_type_header->get_header_buffer(eap_type_header->get_header_buffer_length()), + eap_type_header->get_header_buffer_length())); + + if (static_cast(eap_type_header->get_type()) + != eapol_tlv_message_type_eap_type) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + eap_status_e status = eap_expanded_type_c::read_type( + m_am_tools, + 0ul, + eap_type_header->get_value(eap_type_header->get_value_length()), + eap_type_header->get_value_length(), + eap_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const network_key_header, + network_key_and_index_c * const network_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(network_key_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(simple_config_credential_c *)"), + network_key_header->get_header_buffer(network_key_header->get_header_buffer_length()), + network_key_header->get_header_buffer_length())); + + if (static_cast(network_key_header->get_type()) + != eapol_tlv_message_type_network_key) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + eapol_handle_tlv_message_data_c credential_data(m_am_tools); + + if (credential_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = credential_data.set_message_data( + network_key_header->get_value_length(), + network_key_header->get_value(network_key_header->get_value_length())); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_array_c credential_members(m_am_tools); + + status = credential_data.parse_message_data(&credential_members); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t member_index(0ul); + + u8_t network_key_index(0ul); + + { + const eap_tlv_header_c * const network_key_index_header = credential_members.get_object(member_index); + if (network_key_index_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = credential_data.get_parameter_data(network_key_index_header, &network_key_index); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + ++member_index; + + eap_variable_data_c key(m_am_tools); + + { + const eap_tlv_header_c * const key_header = credential_members.get_object(member_index); + if (key_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = credential_data.get_parameter_data(key_header, &key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + ++member_index; + + network_key->set_network_key_index(network_key_index); + + status = network_key->get_network_key()->set_copy_of_buffer(&key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const network_keys_array_header, + eap_array_c * const network_keys_array) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(network_keys_array_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(eap_array_c *)"), + network_keys_array_header->get_header_buffer(network_keys_array_header->get_header_buffer_length()), + network_keys_array_header->get_header_buffer_length())); + + if (static_cast(network_keys_array_header->get_type()) + != eapol_tlv_message_type_array) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + eapol_handle_tlv_message_data_c credential_array_data(m_am_tools); + + if (credential_array_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = credential_array_data.set_message_data( + network_keys_array_header->get_value_length(), + network_keys_array_header->get_value(network_keys_array_header->get_value_length())); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_array_c credential_array_members(m_am_tools); + + status = credential_array_data.parse_message_data(&credential_array_members); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + for (u32_t ind_member = 0ul; ind_member < credential_array_members.get_object_count(); ind_member++) + { + network_key_and_index_c * const network_key = new network_key_and_index_c(m_am_tools); + + eap_automatic_variable_c automatic_network_key(m_am_tools, network_key); + + if (network_key == 0 + || network_key->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + const eap_tlv_header_c * const simple_config_credential_header = credential_array_members.get_object(ind_member); + if (simple_config_credential_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = credential_array_data.get_parameter_data(simple_config_credential_header, network_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + automatic_network_key.do_not_free_variable(); + + status = network_keys_array->add_object(network_key, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } // for () + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const credential_header, + simple_config_credential_c * const credential) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(credential_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(simple_config_credential_c *)"), + credential_header->get_header_buffer(credential_header->get_header_buffer_length()), + credential_header->get_header_buffer_length())); + + if (static_cast(credential_header->get_type()) + != eapol_tlv_message_type_protected_setup_credential) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + eapol_handle_tlv_message_data_c credential_data(m_am_tools); + + if (credential_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = credential_data.set_message_data( + credential_header->get_value_length(), + credential_header->get_value(credential_header->get_value_length())); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_array_c credential_members(m_am_tools); + + status = credential_data.parse_message_data(&credential_members); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t member_index(0ul); + + u8_t network_index(0ul); + + { + const eap_tlv_header_c * const network_index_header = credential_members.get_object(member_index); + if (network_index_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = credential_data.get_parameter_data(network_index_header, &network_index); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + ++member_index; + + eap_variable_data_c SSID(m_am_tools); + + { + const eap_tlv_header_c * const SSID_header = credential_members.get_object(member_index); + if (SSID_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = credential_data.get_parameter_data(SSID_header, &SSID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + ++member_index; + + simple_config_Authentication_Type_e authentication_type(simple_config_Authentication_Type_None); + + { + const eap_tlv_header_c * const authentication_type_header = credential_members.get_object(member_index); + if (authentication_type_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u16_t integer_value(0ul); + + status = credential_data.get_parameter_data(authentication_type_header, &integer_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + authentication_type = static_cast(integer_value); + } + + ++member_index; + + simple_config_Encryption_Type_e encryption_type(simple_config_Encryption_Type_None); + + { + const eap_tlv_header_c * const encryption_type_header = credential_members.get_object(member_index); + if (encryption_type_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u16_t integer_value(0ul); + + status = credential_data.get_parameter_data(encryption_type_header, &integer_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + encryption_type = static_cast(integer_value); + } + + ++member_index; + + eap_array_c network_keys_array(m_am_tools); + + { + const eap_tlv_header_c * const network_keys_array_header = credential_members.get_object(member_index); + if (network_keys_array_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = credential_data.get_parameter_data(network_keys_array_header, &network_keys_array); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + ++member_index; + + eap_variable_data_c MAC_address(m_am_tools); + + { + const eap_tlv_header_c * const MAC_address_header = credential_members.get_object(member_index); + if (MAC_address_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = credential_data.get_parameter_data(MAC_address_header, &MAC_address); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + ++member_index; + + + credential->set_network_index(network_index); + + status = credential->get_SSID()->set_copy_of_buffer(&SSID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + credential->set_Authentication_Type(authentication_type); + + credential->set_Encryption_Type(encryption_type); + + status = copy( + &network_keys_array, + credential->get_network_keys(), + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = credential->get_MAC_address()->set_copy_of_buffer(&MAC_address); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data( + const eap_tlv_header_c * const credential_array_header, + eap_array_c * const credential_array) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_handle_tlv_message_data_c::get_parameter_data(): type=%s\n"), + get_type_string(static_cast(credential_array_header->get_type())))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("get_parameter_data(eap_array_c *)"), + credential_array_header->get_header_buffer(credential_array_header->get_header_buffer_length()), + credential_array_header->get_header_buffer_length())); + + if (static_cast(credential_array_header->get_type()) + != eapol_tlv_message_type_array) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + eapol_handle_tlv_message_data_c credential_array_data(m_am_tools); + + if (credential_array_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = credential_array_data.set_message_data( + credential_array_header->get_value_length(), + credential_array_header->get_value(credential_array_header->get_value_length())); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_array_c credential_array_members(m_am_tools); + + status = credential_array_data.parse_message_data(&credential_array_members); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + for (u32_t ind_member = 0ul; ind_member < credential_array_members.get_object_count(); ind_member++) + { + simple_config_credential_c * const simple_config_credential = new simple_config_credential_c(m_am_tools); + + eap_automatic_variable_c automatic_simple_config_credential(m_am_tools, simple_config_credential); + + if (simple_config_credential == 0 + || simple_config_credential->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + const eap_tlv_header_c * const simple_config_credential_header = credential_array_members.get_object(ind_member); + if (simple_config_credential_header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = credential_array_data.get_parameter_data(simple_config_credential_header, simple_config_credential); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + automatic_simple_config_credential.do_not_free_variable(); + + status = credential_array->add_object(simple_config_credential, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } // for () + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eapol_handle_tlv_message_data_c::get_type_string(const eapol_tlv_message_type_e type) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_none) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_array) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_boolean) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_eap_protocol_layer) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_eap_state_notification) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_eap_type) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_eapol_key_802_11_authentication_mode) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_eapol_key_authentication_type) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_eapol_key_type) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_eapol_tkip_mic_failure_type) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_eapol_wlan_authentication_state) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_error) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_function) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_network_id) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_RSNA_cipher) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_session_key) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_u8_t) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_u16_t) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_u32_t) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_u64_t) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_variable_data) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_network_key) + else EAP_IF_RETURN_STRING(type, eapol_tlv_message_type_protected_setup_credential) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(type); + + return EAPL("Unknown EAPOL-TLV message type"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eapol_handle_tlv_message_data_c::get_function_string(const eapol_tlv_message_type_function_e function) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_none) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_check_pmksa_cache) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_start_authentication) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_complete_association) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_disassociation) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_start_preauthentication) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_start_reassociation) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_complete_reassociation) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_start_WPXM_reassociation) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_complete_WPXM_reassociation) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_packet_process) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_tkip_mic_failure) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_eap_acknowledge) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_update_header_offset) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_complete_check_pmksa_cache) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_packet_send) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_associate) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_disassociate) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_packet_data_session_key) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_state_notification) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_reassociate) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_update_wlan_database_reference_values) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_complete_start_WPXM_reassociation) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_new_protected_setup_credentials) + else EAP_IF_RETURN_STRING(function, eapol_tlv_message_type_function_illegal_value) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(function); + + return EAPL("Unknown EAPOL-TLV message function"); + } +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_key_state_client.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_key_state_client.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2644 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 49 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eapol_key_state.h" +#include "eapol_key_header.h" +#include "eap_crypto_api.h" +#include "abs_eap_am_mutex.h" +#include "eap_state_notification.h" +#include "eap_automatic_variable.h" +#include "eapol_rsna_key_data_gtk_header.h" +#include "eap_buffer.h" +#include "eapol_rsna_key_data_payloads.h" +#include "abs_eapol_key_state.h" +#include "eapol_rc4_key_header.h" +#include "eapol_key_state_string.h" + +//-------------------------------------------------- +// +eap_status_e eapol_key_state_c::create_4_way_handshake_message_2( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const u64_t received_key_replay_counter, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::create_4_way_handshake_message_2()\n"), + (m_is_client == true ? "client": "server"))); + + // Only client (Supplicant) could create 4-Way Handshake message 2. + EAP_ASSERT_ALWAYS(m_is_client == true); + + if (sent_packet == 0 + || sent_packet->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_SNonce.get_is_valid_data() == false + || m_SNonce.get_data_length() != eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_4_way_handshake_message_2(): ") + EAPL("m_SNonce is missing or corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_supplicant_RSNA_IE.get_is_valid_data() == false + || m_supplicant_RSNA_IE.get_data_length() == 0ul + || m_supplicant_RSNA_IE.get_data_length() + > eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_MAXIMUM_RSN_IE_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_4_way_handshake_message_2(): ") + EAPL("m_supplicant_RSNA_IE is missing or corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + u32_t eapol_key_data_length + = eapol_RSNA_key_header_c::get_header_length() + + m_supplicant_RSNA_IE.get_data_length(); + + *buffer_length + = eapol_header_offset + + eapol_key_data_length; + + status = sent_packet->set_buffer_length( + *buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sent_packet->set_data_length( + sent_packet->get_buffer_length()); + + eapol_RSNA_key_header_c eapol_key_message( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + sent_packet->get_data_offset(eapol_header_offset, eapol_key_data_length), + sent_packet->get_data_length()); + + if (eapol_key_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + status = eapol_key_message.reset_header( + 0ul, + m_authentication_type, + m_eapol_pairwise_cipher, + received_key_replay_counter, + true, // Pairwise key type bit is on. + false, // Install bit is NOT set. + false, // Key Ack bit is NOT set. + true, // Key MIC bit is on. + false, // Secure bit is NOT set. + false, // Error bit is NOT set. + false, // Request bit is NOT set. + false, // STAKey bit is NOT set. + false, // Encrypted Key Data bit is NOT set. + received_eapol_version, + received_key_descriptor_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + { + // Add SNonce. + u8_t * const nonce_field = eapol_key_message.get_key_NONCE(); + if (nonce_field == 0 + || m_SNonce.get_data_length() != eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_am_tools->memmove( + nonce_field, + m_SNonce.get_data(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE); + } + + + u32_t total_key_data_length(0ul); + + status = add_RSN_IE_payload( + &eapol_key_message, + &m_supplicant_RSNA_IE, + &total_key_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (total_key_data_length > 0xffff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + status = eapol_key_message.set_key_data_length( + static_cast(total_key_data_length)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + status = eapol_key_message.set_eapol_packet_body_length( + static_cast(*data_length - eapol_header_base_c::get_header_length())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const eap_variable_data_c * confirmation_key = &m_confirmation_KCK; +#if defined(EAP_USE_WPXM) + if (get_is_WPXM() == true) + { + confirmation_key = &m_WPXM_WPXK1; + } +#endif //#if defined(EAP_USE_WPXM) + + status = create_key_mic( + &eapol_key_message, + confirmation_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_EAPOL_KEY_TEST_FAILURES) + if (m_create_key_failure == eapol_key_state_wait_4_way_handshake_message_1) + { + m_create_key_failure = eapol_key_state_wait_4_way_handshake_message_3; + + status = eapol_key_message.zero_key_MIC(m_am_tools); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: error generated in eapol_key_state_c::create_4_way_handshake_message_2()\n"), + (m_is_client == true ? "client": "server"))); + } +#endif //#if defined(USE_EAPOL_KEY_TEST_FAILURES) + + sent_packet->set_data_length( + eapol_header_offset + *data_length); + + TRACE_EAPOL_KEY_MESSAGE( + "Send 4-Way Handshake Message 2", + &eapol_key_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::create_4_way_handshake_message_4( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const u64_t received_key_replay_counter, + const bool received_secure_bit, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::create_4_way_handshake_message_4()\n"), + (m_is_client == true ? "client": "server"))); + + // Only client (Supplicant) could create 4-Way Handshake message 4. + EAP_ASSERT_ALWAYS(m_is_client == true); + + if (sent_packet == 0 + || sent_packet->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t eapol_key_data_length + = eapol_RSNA_key_header_c::get_header_length(); + + *buffer_length + = eapol_header_offset + + eapol_key_data_length; + + status = sent_packet->set_buffer_length( + *buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sent_packet->set_data_length( + sent_packet->get_buffer_length()); + + eapol_RSNA_key_header_c eapol_key_message( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + sent_packet->get_data_offset(eapol_header_offset, eapol_key_data_length), + sent_packet->get_data_length()); + + if (eapol_key_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + bool secure_bit = received_secure_bit; // Secure bit is the same as in the received WPA 4-Way Handshake message 3. + + if (get_is_RSNA() == true) + { + secure_bit = true; // Secure bit is on in RSNA. + } + + status = eapol_key_message.reset_header( + 0ul, + m_authentication_type, + m_eapol_pairwise_cipher, + received_key_replay_counter, + true, // Pairwise key type bit is on. + false, // Install bit is NOT set. + false, // Key Ack bit is NOT set. + true, // Key MIC bit is on. + secure_bit, + false, // Error bit is NOT set. + false, // Request bit is NOT set. + false, // STAKey bit is NOT set. + false, // Encrypted Key Data bit is NOT set. + received_eapol_version, + received_key_descriptor_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eapol_key_message.set_key_data_length(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + status = eapol_key_message.set_eapol_packet_body_length( + static_cast(*data_length - eapol_header_base_c::get_header_length())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = create_key_mic( + &eapol_key_message, + &m_confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_EAPOL_KEY_TEST_FAILURES) + if (m_create_key_failure == eapol_key_state_wait_4_way_handshake_message_3) + { + m_create_key_failure = eapol_key_state_4_way_handshake_successfull; + + status = eapol_key_message.zero_key_MIC(m_am_tools); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: error generated in eapol_key_state_c::create_4_way_handshake_message_4()\n"), + (m_is_client == true ? "client": "server"))); + } +#endif //#if defined(USE_EAPOL_KEY_TEST_FAILURES) + + sent_packet->set_data_length( + eapol_header_offset + *data_length); + + TRACE_EAPOL_KEY_MESSAGE( + "Send 4-Way Handshake Message 4", + &eapol_key_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_4_way_handshake_message_1( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t /* packet_length */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status = eap_status_process_general_error; + + eapol_key_state_string_c state_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::process_4_way_handshake_message_1(): eapol_key_descriptor_type = %s = 0x%02x\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_descriptor_type_string(eapol_key_message->get_key_descriptor_type()), + eapol_key_message->get_key_descriptor_type())); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_key_state_c::process_4_way_handshake_message_1()"); + + // Only client (supplicant) could receive 4-Way Handshake message 1. + EAP_ASSERT_ALWAYS(m_is_client == true); + + if (m_eapol_key_handshake_type == eapol_key_handshake_type_none) + { + // 4-Way Handshake started again. + m_eapol_key_handshake_type = eapol_key_handshake_type_4_way_handshake; + set_eapol_key_state(eapol_key_state_wait_4_way_handshake_message_1); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: process_4_way_handshake_message_1(): 4-Way Handshake restarted.\n"), + (m_is_client == true ? "client": "server"))); + } + + if (get_eapol_key_state() != eapol_key_state_wait_4_way_handshake_message_1 + && get_eapol_key_state() != eapol_key_state_wait_4_way_handshake_message_3 + && get_eapol_key_state() != eapol_key_state_4_way_handshake_successfull + && get_eapol_key_state() != eapol_key_state_preauthenticated +#if defined(EAP_USE_WPXM) + && get_eapol_key_state() != eapol_key_state_wpxm_reassociation_finished_successfull +#endif //#if defined(EAP_USE_WPXM) + ) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_4_way_handshake_message_1(): wrong state %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + // Some APs seems to behave incorrectly and + // fills the IV field with non-zero stuff. For this reason don't verify the field to be 0. + + status = verify_field_is_zero( + eapol_key_message->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + /** + * @{ In 802.11i D3.0 this field is Key ID instead of STA MAC address. } + */ + status = verify_field_is_zero( + eapol_key_message->get_key_STA_MAC_address(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_allow_non_zero_mic_and_reserved_in_message_1 == false) + { + status = verify_field_is_zero( + eapol_key_message->get_key_reserved(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RESERVED_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_MIC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // Save ANonce. + const u8_t * const ANonce = eapol_key_message->get_key_NONCE(); + if (ANonce == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + status = m_ANonce.set_copy_of_buffer( + ANonce, + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (get_is_RSNA() == true) + { + u32_t received_buffer_length = eapol_key_message->get_key_data_length(); + + if (m_allow_missing_PMKID_in_message_1 == false + && received_buffer_length == 0u) + { + // No payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (received_buffer_length > 0u) + { + if (received_buffer_length > eapol_key_message->get_header_buffer_length() + || eapol_key_message->get_key_data(received_buffer_length) == 0) + { + // Not enough payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + eapol_rsna_key_data_payloads_c key_data_payloads( + m_am_tools, + get_is_RSNA(), + get_is_WPXM()); + + eapol_rsna_key_data_header_c key_data( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + eapol_key_message->get_key_data(received_buffer_length), + received_buffer_length); + if (key_data.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: No EAPOL-Key data payloads.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = key_data.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: EAPOL-Key data payload header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = parse_key_data( + eapol_key_message->get_key_descriptor_type(), + &key_data, + &received_buffer_length, + &key_data_payloads, + eapol_key_state_wait_4_way_handshake_message_1, + eapol_key_message->get_key_information_key_descriptor_version()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_e PMKID_existence( + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_be); + + if (m_allow_missing_PMKID_in_message_1 == true) + { + PMKID_existence = eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_optional; + } + + // Check the valid payload is included. + if (false == key_data_payloads.check_payloads( + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_not_be, // key_id_and_group_key + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_not_be, // STAKey + PMKID_existence, // PMKID + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_not_be // One or more RSN IE + )) + { + // Not correct EAPOL Key Data payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_1(): ") + EAPL("Not correct EAPOL Key Data payloads are included.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (key_data_payloads.get_PMKID()->get_is_valid_data() == true) + { + // We do have the expected PMKID, save it. + status = get_received_PMKID()->set_copy_of_buffer(key_data_payloads.get_PMKID()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // We do not get mandatory PMKID. + // Access point is broken and cached PMKSA is not used. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_1(): ") + EAPL("Not correct EAPOL Key Data payloads are included, mandatory PMKID is missing.\n"))); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_1(): ") + EAPL("Not correct EAPOL Key Data payloads are included, mandatory PMKID is missing.\n"))); + } + } + +#if defined(EAP_USE_WPXM) + if (get_is_WPXM() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_1(): ") + EAPL("m_WPXM_WPXC=%d.\n"), + m_WPXM_WPXC)); + + status = derive_WPXM_WPXK1_WPXK2(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = derive_WPXM_PTK(eapol_key_constant_wpxm_initial_wpxc_counter_value); + } + else +#endif //#if defined(EAP_USE_WPXM) + { + status = derive_PTK(); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_buf_chain_wr_c sent_packet( + eap_write_buffer, + m_am_tools); + + if (sent_packet.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t send_data_length = 0ul; + u32_t send_buffer_length = 0ul; + + status = create_4_way_handshake_message_2( + &sent_packet, + m_eapol_header_offset, + &send_data_length, + &send_buffer_length, + eapol_key_message->get_key_replay_counter(), + eapol_key_message->get_eapol_protocol_version(), + eapol_key_message->get_key_descriptor_type()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = packet_send( + &m_send_network_id, + &sent_packet, + m_eapol_header_offset, + send_data_length, + send_buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + cancel_4_way_handshake_start_timeout(); + + set_eapol_key_state(eapol_key_state_wait_4_way_handshake_message_3); + + m_eapol_key_handshake_type = eapol_key_handshake_type_4_way_handshake; + + set_key_reply_counter(eapol_key_message->get_key_replay_counter()); + + status = init_handshake_timeout(m_handshake_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // This is notification to eapol_core_c object. + // 4-Way Handshake started successfully. + eap_state_notification_c * notification = new eap_state_notification_c( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_4_way_handshake, + eapol_key_state_4_way_handshake_running, + eapol_key_state_4_way_handshake_running, + 0ul, + false); + if (notification == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_key_state_partner->state_notification(notification); + + delete notification; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_4_way_handshake_message_3_payloads_a( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length, + bool * const group_key_received) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status = eap_status_process_general_error; + + // Only client (supplicant) could receive 4-Way Handshake message 3. + EAP_ASSERT_ALWAYS(m_is_client == true); + + + { + u32_t received_buffer_length = eapol_key_message->get_key_data_length(); + + if (received_buffer_length > eapol_key_message->get_header_buffer_length() + || eapol_key_message->get_key_data(received_buffer_length) == 0) + { + // Not enough payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + eapol_rsna_key_data_payloads_c key_data_payloads( + m_am_tools, + get_is_RSNA(), + get_is_WPXM()); + + eapol_rsna_key_data_header_c key_data( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + eapol_key_message->get_key_data(received_buffer_length), + packet_length); + if (key_data.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: No EAPOL-Key data payloads.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = key_data.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: EAPOL-Key data payload header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = parse_key_data( + eapol_key_message->get_key_descriptor_type(), + &key_data, + &received_buffer_length, + &key_data_payloads, + eapol_key_state_wait_4_way_handshake_message_3, + eapol_key_message->get_key_information_key_descriptor_version()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Check the valid payload is included. + if (false == key_data_payloads.check_payloads( + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_optional, // key_id_and_group_key + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_not_be, // STAKey + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_not_be, // PMKID + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_be // One or more RSN IE + )) + { + // Not correct EAPOL Key Data payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_3_payloads_a(): ") + EAPL("Not correct EAPOL Key Data payloads are included.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // We do have the expected RSN IE, compare it. + if (get_authenticator_RSNA_IE()->compare( + key_data_payloads.get_RSN_IE()->get_object(0ul)) != 0) + { + // Illegal RSN IE. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_3_payloads_a(): ") + EAPL("Not correct RSN IE received.\n"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL(" Local RSN IE"), + get_authenticator_RSNA_IE()->get_data( + get_authenticator_RSNA_IE()->get_data_length()), + get_authenticator_RSNA_IE()->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Received RSN IE"), + key_data_payloads.get_RSN_IE()->get_object(0ul)->get_data( + key_data_payloads.get_RSN_IE()->get_object(0ul)->get_data_length()), + key_data_payloads.get_RSN_IE()->get_object(0ul)->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Check the optional second RSN IE. + if (key_data_payloads.get_RSN_IE()->get_object_count() > 1ul + && key_data_payloads.get_RSN_IE()->get_object(1ul) != 0 + && key_data_payloads.get_RSN_IE()->get_object(1ul)->get_is_valid_data() == true) + { + // If a second RSN IE is provided in the message, the Supplicant shall use + // the unicast cipher suite specified in the second RSN IE or deauthenticate. + status = get_unicast_cipher_suite_RSNA_IE()->set_copy_of_buffer( + key_data_payloads.get_RSN_IE()->get_object(1ul)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + if (get_is_RSNA() == true + || (get_is_WPXM() == true + && eapol_key_message->get_key_descriptor_type() == eapol_key_descriptor_type_RSNA)) + { + if (m_eapol_group_cipher != eapol_RSNA_key_header_c::eapol_RSNA_cipher_none + && key_data_payloads.get_group_key()->get_is_valid_data() == true) + { + // We do have the expected GTK, save it. + status = m_group_GTK.set_copy_of_buffer( + key_data_payloads.get_group_key()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_group_GTK_ID = key_data_payloads.get_group_key_id(); + m_group_GTK_Tx_bit = key_data_payloads.get_group_key_tx(); + + *group_key_received = true; + } + else if (m_eapol_group_cipher != eapol_RSNA_key_header_c::eapol_RSNA_cipher_none + && key_data_payloads.get_group_key()->get_is_valid_data() == false + && eapol_key_message->get_key_descriptor_type() == eapol_key_descriptor_type_RSNA) + { + // ERROR, required GTK is missing. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_3_payloads_a(): ") + EAPL("Required GTK is missing.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (m_eapol_group_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none + && key_data_payloads.get_group_key()->get_is_valid_data() == true) + { + // ERROR, unexpected GTK received. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_3_payloads_a(): ") + EAPL("Unexpected GTK received.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_4_way_handshake_message_3_payloads_b( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t /* packet_length */, + const bool group_key_received) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status = eap_status_process_general_error; + + // Only client (supplicant) could receive 4-Way Handshake message 3. + EAP_ASSERT_ALWAYS(m_is_client == true); + + { + eap_buf_chain_wr_c sent_packet( + eap_write_buffer, + m_am_tools); + + if (sent_packet.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t send_data_length = 0ul; + u32_t send_buffer_length = 0ul; + + status = create_4_way_handshake_message_4( + &sent_packet, + m_eapol_header_offset, + &send_data_length, + &send_buffer_length, + eapol_key_message->get_key_replay_counter(), + eapol_key_message->get_key_information_secure(), + eapol_key_message->get_eapol_protocol_version(), + eapol_key_message->get_key_descriptor_type()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = packet_send( + &m_send_network_id, + &sent_packet, + m_eapol_header_offset, + send_data_length, + send_buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (get_eapol_key_state() == eapol_key_state_wait_4_way_handshake_message_3) + { + // We set the keys only on the first received 4-Way Handshake Message 3. + + status = packet_data_session_key( + &m_temporal_TK, + eapol_key_type_unicast, + 0ul, + false, + eapol_key_message->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + { + // This notification to eapol_core_c object. + // 4-Way Handshake finished successfully. + eap_state_notification_c * notification = new eap_state_notification_c( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_4_way_handshake, + get_eapol_key_state(), + eapol_key_state_4_way_handshake_successfull, + 0ul, + false); + if (notification == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_key_state_partner->state_notification(notification); + + delete notification; + } + + + if ((get_is_RSNA() == true + && m_eapol_group_cipher != eapol_RSNA_key_header_c::eapol_RSNA_cipher_none) + || (get_is_WPXM() == true + && eapol_key_message->get_key_descriptor_type() == eapol_key_descriptor_type_RSNA)) + { + if (group_key_received == true) + { + // We do have the expected GTK, pass it to lower layers. + status = packet_data_session_key( + &m_group_GTK, + eapol_key_type_broadcast, + m_group_GTK_ID, + m_group_GTK_Tx_bit, + eapol_key_message->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // This notification to eapol_core_c object. + // Group Key Handshake finished successfully. + eap_state_notification_c * notification = new eap_state_notification_c( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_group_key_handshake, + get_eapol_key_state(), + eapol_key_state_group_key_handshake_successfull, + 0ul, + false); + if (notification == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_key_state_partner->state_notification(notification); + + delete notification; + } + } + else + { + // ERROR, no GTK received. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_3_payloads_b(): ") + EAPL("No GTK received.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + } + else + { + eapol_key_state_string_c state_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_3_payloads_b(): ") + EAPL("No keys are set on state %d=%s.\n"), + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_4_way_handshake_message_3( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status = eap_status_process_general_error; + + eapol_key_state_string_c state_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::process_4_way_handshake_message_3(): eapol_key_descriptor_type = %s = 0x%02x\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_descriptor_type_string(eapol_key_message->get_key_descriptor_type()), + eapol_key_message->get_key_descriptor_type())); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_key_state_c::process_4_way_handshake_message_3()"); + + // Only client (supplicant) could receive 4-Way Handshake message 3. + EAP_ASSERT_ALWAYS(m_is_client == true); + + // NOTE, this could be re-transmitted message. + // Authenticator did not get the 4-Way Handshake message 4. + if (m_eapol_key_handshake_type != eapol_key_handshake_type_4_way_handshake + && m_eapol_key_handshake_type != eapol_key_handshake_type_group_key_handshake) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_4_way_handshake_message_3(): wrong handshake type %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (get_eapol_key_state() != eapol_key_state_wait_4_way_handshake_message_3 + && get_eapol_key_state() != eapol_key_state_4_way_handshake_successfull +#if defined(EAP_USE_WPXM) + && get_eapol_key_state() != eapol_key_state_wpxm_reassociation_finished_successfull +#endif //#if defined(EAP_USE_WPXM) + ) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_4_way_handshake_message_3(): wrong state %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + // We do have the expected ANonce, compare it. + if (m_am_tools->memcmp( + get_ANonce()->get_data( + get_ANonce()->get_data_length()), + eapol_key_message->get_key_NONCE(), + get_ANonce()->get_data_length()) != 0) + { + // Illegal ANonce. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_3(): ") + EAPL("Not correct ANonce received.\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Local ANonce "), + get_ANonce()->get_data( + get_ANonce()->get_data_length()), + get_ANonce()->get_data_length())); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Received ANonce"), + eapol_key_message->get_key_NONCE(), + get_ANonce()->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u32_t received_data_length = eapol_key_message->get_key_data_length(); + + if (received_data_length == 0u) + { + // No payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (received_data_length > eapol_key_message->get_header_buffer_length() + || eapol_key_message->get_key_data(received_data_length) == 0) + { + // Not enough payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (m_eapol_pairwise_cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP) + { + status = m_EAPOL_key_IV.set_copy_of_buffer( + eapol_key_message->get_EAPOL_key_IV(), + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + if (m_allow_non_zero_mic_and_reserved_in_message_1 == false) + { + status = verify_field_is_zero( + eapol_key_message->get_EAPOL_key_IV(), + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + status = verify_field_is_zero( + eapol_key_message->get_key_STA_MAC_address(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_reserved(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RESERVED_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = verify_key_mic( + eapol_key_message, + &m_confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if ((get_is_RSNA() == true + || get_is_WPXM() == true) + && eapol_key_message->get_key_information_encrypted_key_data() == true) + { + status = decrypt_key_data(eapol_key_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Decryption may change data length. + received_data_length = eapol_key_message->get_key_data_length(); + + if (received_data_length > eapol_key_message->get_header_buffer_length() + || eapol_key_message->get_key_data(received_data_length) == 0) + { + // Not enough payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + } + + + // This split of process_4_way_handshake_message_3_payloads() function + // is fix internal compiler error. + bool group_key_received(false); + + status = process_4_way_handshake_message_3_payloads_a( + receive_network_id, + eapol_key_message, + packet_length, + &group_key_received); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = process_4_way_handshake_message_3_payloads_b( + receive_network_id, + eapol_key_message, + packet_length, + group_key_received); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (get_eapol_key_state() == eapol_key_state_wait_4_way_handshake_message_3) + { + if (get_is_RSNA() == true + || (get_is_WPXM() == true + && eapol_key_message->get_key_descriptor_type() == eapol_key_descriptor_type_RSNA)) + { + if (m_indicate_pmkid_to_lower_layer == true) + { + // In some platforms lower layers uses PMKID. + status = create_PMKID(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = packet_data_session_key( + &m_PMKID, + eapol_key_type_pmkid, + 0ul, + false, + 0, + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + { + // This notification to eapol_core_c object. + // 802.11i authentication finished successfully. + eap_state_notification_c * notification = new eap_state_notification_c( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_802_11i_handshake, + get_eapol_key_state(), + eapol_key_state_802_11i_authentication_finished_successfull, + 0ul, + false); + if (notification == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_key_state_partner->state_notification(notification); + + delete notification; + } + + cancel_handshake_timeout(); + } + else + { + // Note the WPA version always does separate Group Key Handshake. + // Authentication is successfull after the Group Key Handshake + // Finishes successfully. + } + + set_eapol_key_state(eapol_key_state_4_way_handshake_successfull); + + // A new Group Key Handshake can happen at any time. + m_eapol_key_handshake_type = eapol_key_handshake_type_group_key_handshake; + + set_key_reply_counter(eapol_key_message->get_key_replay_counter()); + + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: 4-Way Handshake SUCCESS\n"), + (m_is_client == true ? "client": "server"))); + } + else + { + eapol_key_state_string_c state_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_3(): ") + EAPL("No keys are set on state %d=%s.\n"), + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::create_eapol_key_handshake_message_0( + const bool true_when_4_way_handshake, ///< With false initiates Group Key Handshake. + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const u64_t received_key_replay_counter, + const eapol_protocol_version_e received_eapol_version) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::create_eapol_key_handshake_message_0()\n"), + (m_is_client == true ? "client": "server"))); + + // Only client (Supplicant) could create 4-Way or Group Key Handshake message 0. + EAP_ASSERT_ALWAYS(m_is_client == true); + + u32_t eapol_key_data_length + = eapol_RSNA_key_header_c::get_header_length(); + + *buffer_length + = eapol_header_offset + + eapol_key_data_length; + + status = sent_packet->set_buffer_length( + *buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sent_packet->set_data_length( + sent_packet->get_buffer_length()); + + eapol_RSNA_key_header_c eapol_key_message( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + sent_packet->get_data_offset(eapol_header_offset, eapol_key_data_length), + sent_packet->get_data_length()); + + if (eapol_key_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + status = eapol_key_message.reset_header( + 0ul, + m_authentication_type, + m_eapol_pairwise_cipher, + received_key_replay_counter, + true_when_4_way_handshake, + false, // Install bit is NOT set. + false, // Key Ack bit is NOT set. + true, // Key MIC bit is set on + false, // Secure bit is NOT set. + false, // Error bit is NOT set. + true, // Request bit is set on. + false, // STAKey bit is NOT set. + false, // Encrypted Key Data bit is NOT set. + received_eapol_version, +#if defined(EAP_USE_WPXM) + m_EAPOL_WPXM_key_descriptor_type +#else + eapol_key_descriptor_type_RSNA +#endif //#if defined(EAP_USE_WPXM) + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eapol_key_message.set_key_data_length(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + status = eapol_key_message.set_eapol_packet_body_length( + static_cast(*data_length - eapol_header_base_c::get_header_length())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + sent_packet->set_data_length( + eapol_header_offset + *data_length); + + if (true_when_4_way_handshake == true) + { + TRACE_EAPOL_KEY_MESSAGE( + "Send 4-Way Handshake Message 0", + &eapol_key_message); + } + else + { + status = create_key_mic( + &eapol_key_message, + &m_confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + TRACE_EAPOL_KEY_MESSAGE( + "Send Group Key Handshake Message 0", + &eapol_key_message); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::create_group_key_handshake_message_2( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const u64_t received_key_replay_counter, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::create_group_key_handshake_message_2()\n"), + (m_is_client == true ? "client": "server"))); + + // Only client (Supplicant) could create Group Key Handshake message 2. + EAP_ASSERT_ALWAYS(m_is_client == true); + + if (sent_packet == 0 + || sent_packet->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t eapol_key_data_length + = eapol_RSNA_key_header_c::get_header_length(); + + *buffer_length + = eapol_header_offset + + eapol_key_data_length; + + status = sent_packet->set_buffer_length( + *buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sent_packet->set_data_length( + sent_packet->get_buffer_length()); + + eapol_RSNA_key_header_c eapol_key_message( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + sent_packet->get_data_offset(eapol_header_offset, eapol_key_data_length), + sent_packet->get_data_length()); + + if (eapol_key_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + status = eapol_key_message.reset_header( + m_group_GTK_ID, + m_authentication_type, + m_eapol_pairwise_cipher, + received_key_replay_counter, + false, // Pairwise key type bit NOT set. + false, // Install bit is NOT set. + false, // Key Ack bit is NOT set. + true, // Key MIC bit is on. + true, // Secure bit is on. + false, // Error bit is NOT set. + false, // Request bit is NOT set. + false, // STAKey bit is NOT set. + false, // Encrypted Key Data bit is NOT set. + received_eapol_version, + received_key_descriptor_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eapol_key_message.set_key_data_length(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + status = eapol_key_message.set_eapol_packet_body_length( + static_cast(*data_length - eapol_header_base_c::get_header_length())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = create_key_mic( + &eapol_key_message, + &m_confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_EAPOL_KEY_TEST_FAILURES) + if (m_create_key_failure == eapol_key_state_4_way_handshake_successfull) + { + m_create_key_failure = eapol_key_state_group_key_handshake_successfull; + + status = eapol_key_message.zero_key_MIC(m_am_tools); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: error generated in eapol_key_state_c::create_group_key_handshake_message_2()\n"), + (m_is_client == true ? "client": "server"))); + } +#endif //#if defined(USE_EAPOL_KEY_TEST_FAILURES) + + sent_packet->set_data_length( + eapol_header_offset + *data_length); + + TRACE_EAPOL_KEY_MESSAGE( + "Send Group Key Handshake Message 2", + &eapol_key_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_group_key_handshake_message_1( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::process_group_key_handshake_message_1()\n"), + (m_is_client == true ? "client": "server"))); + + // Only client (supplicant) could receive Group Key Handshake message 1. + EAP_ASSERT_ALWAYS(m_is_client == true); + + if (get_eapol_key_state() == eapol_key_state_4_way_handshake_successfull + || get_eapol_key_state() == eapol_key_state_group_key_handshake_successfull +#if defined(EAP_USE_WPXM) + || get_eapol_key_state() == eapol_key_state_wpxm_reassociation_finished_successfull +#endif //#if defined(EAP_USE_WPXM) + ) + { + // At this point we know the 4-Way handshake or Group key handshake was successfull. + m_eapol_key_handshake_type = eapol_key_handshake_type_group_key_handshake; + } + + if (m_eapol_key_handshake_type != eapol_key_handshake_type_none + && m_eapol_key_handshake_type != eapol_key_handshake_type_group_key_handshake) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: start_group_key_handshake(): wrong handshake type %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (get_eapol_key_state() != eapol_key_state_4_way_handshake_successfull + && get_eapol_key_state() != eapol_key_state_group_key_handshake_successfull + && get_eapol_key_state() != eapol_key_state_preauthenticated +#if defined(EAP_USE_WPXM) + && get_eapol_key_state() != eapol_key_state_wpxm_reassociation_finished_successfull +#endif //#if defined(EAP_USE_WPXM) + ) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_group_key_handshake_message_1(): wrong state %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + u32_t received_data_length = eapol_key_message->get_key_data_length(); + + if (received_data_length == 0u) + { + // No payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (received_data_length > eapol_key_message->get_header_buffer_length() + || eapol_key_message->get_key_data(received_data_length) == 0) + { + // Not enough payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + + if (get_is_RSNA() == true) + { + if (m_allow_non_zero_mic_and_reserved_in_message_1 == false) + { + status = verify_field_is_zero( + eapol_key_message->get_key_NONCE(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + // WPA sends GNonse for debugging purposes. + } + + + status = verify_field_is_zero( + eapol_key_message->get_key_STA_MAC_address(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_reserved(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RESERVED_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (m_eapol_group_cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP + || m_eapol_group_cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP + || m_eapol_group_cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40 + || m_eapol_group_cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104) + { + status = m_EAPOL_key_IV.set_copy_of_buffer( + eapol_key_message->get_EAPOL_key_IV(), + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = verify_field_is_zero( + eapol_key_message->get_EAPOL_key_IV(), + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + status = verify_key_mic( + eapol_key_message, + &m_confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = decrypt_key_data(eapol_key_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Decryption may change data length. + received_data_length = eapol_key_message->get_key_data_length(); + + if (received_data_length > eapol_key_message->get_header_buffer_length() + || eapol_key_message->get_key_data(received_data_length) == 0) + { + // Not enough payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + + if (get_is_RSNA() == true) + { + eapol_rsna_key_data_payloads_c key_data_payloads( + m_am_tools, + get_is_RSNA(), + get_is_WPXM()); + + eapol_rsna_key_data_header_c key_data( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + eapol_key_message->get_key_data(received_data_length), + packet_length); + if (key_data.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: No EAPOL-Key data payloads.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = key_data.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: EAPOL-Key data payload header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = parse_key_data( + eapol_key_message->get_key_descriptor_type(), + &key_data, + &received_data_length, + &key_data_payloads, + eapol_key_state_wait_group_key_handshake_message_1, + eapol_key_message->get_key_information_key_descriptor_version()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Check the valid payload is included. + if (false == key_data_payloads.check_payloads( + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_be, // key_id_and_group_key + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_not_be, // STAKey + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_not_be, // PMKID + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_not_be // One or more RSN IE + )) + { + // Not correct EAPOL Key Data payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::process_group_key_handshake_message_1(): ") + EAPL("Not correct EAPOL Key Data payloads are included.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // We do have the expected GTK, save it. + status = m_group_GTK.set_copy_of_buffer( + key_data_payloads.get_group_key()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_group_GTK_ID = key_data_payloads.get_group_key_id(); + m_group_GTK_Tx_bit = key_data_payloads.get_group_key_tx(); + } + else + { + // WPA + EAP_UNREFERENCED_PARAMETER(packet_length); + + // According to Draft 3 the GTK is not encapsulated in any way. + status = m_group_GTK.set_copy_of_buffer( + eapol_key_message->get_key_data(received_data_length), + received_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_group_GTK_ID = eapol_key_message->get_key_information_key_index(); + } + + + eap_buf_chain_wr_c sent_packet( + eap_write_buffer, + m_am_tools); + + if (sent_packet.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t send_data_length = 0ul; + u32_t send_buffer_length = 0ul; + + u64_t reply_counter(eapol_key_message->get_key_replay_counter()); + + if (get_is_WPXM() == true + && reply_counter == 0ul) + { + // Here we must increase the saved Reply Counter. + // WPXM seems to work against RSN specification that says + // every packet must be sent with new Reply Counter. + // WPXM starts Group Key Handshake with Reply Counter 0 after successfull + // 4-Way Handshake. + reply_counter = get_key_reply_counter() + 1ul; + } + + status = create_group_key_handshake_message_2( + &sent_packet, + m_eapol_header_offset, + &send_data_length, + &send_buffer_length, + reply_counter, + eapol_key_message->get_eapol_protocol_version(), + eapol_key_message->get_key_descriptor_type()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = packet_send( + &m_send_network_id, + &sent_packet, + m_eapol_header_offset, + send_data_length, + send_buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (get_eapol_key_state() == eapol_key_state_4_way_handshake_successfull + || get_eapol_key_state() == eapol_key_state_preauthenticated + || get_eapol_key_state() == eapol_key_state_group_key_handshake_successfull +#if defined(EAP_USE_WPXM) + || get_eapol_key_state() == eapol_key_state_wpxm_reassociation_finished_successfull +#endif //#if defined(EAP_USE_WPXM) + ) + { + status = packet_data_session_key( + &m_group_GTK, + eapol_key_type_broadcast, + m_group_GTK_ID, + m_group_GTK_Tx_bit, + eapol_key_message->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This is notification to eapol_core_c object. + // Group Key Handshake finished successfully. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_group_key_handshake, + get_eapol_key_state(), + eapol_key_state_group_key_handshake_successfull, + 0ul, + false); + m_key_state_partner->state_notification(¬ification); + + if (get_is_RSNA() == false) + { + // Note the WPA version always does separate Group Key Handshake. + // Authentication is successfull after the Group Key Handshake + // Finishes successfully. + + { + // This notification to eapol_core_c object. + // WPA authentication finished successfully. + eap_state_notification_c * notification = new eap_state_notification_c( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_802_11i_handshake, + get_eapol_key_state(), + eapol_key_state_802_11i_authentication_finished_successfull, + 0ul, + false); + if (notification == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_key_state_partner->state_notification(notification); + + delete notification; + } + } + + set_eapol_key_state(eapol_key_state_group_key_handshake_successfull); + + m_eapol_key_handshake_type = eapol_key_handshake_type_none; + + if (get_is_WPXM() == true) + { + // Here we must increase the Reply Counter. + // WPXM seems to work against RSN specification that says + // every packet must be sent with new Reply Counter. + // WPXM starts Group Key Handshake with Reply Counter 0 after successfull + // 4-Way Handshake. + set_key_reply_counter(get_key_reply_counter() + 1ul); + } + else + { + set_key_reply_counter(eapol_key_message->get_key_replay_counter()); + } + + cancel_handshake_timeout(); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: Group Key Handshake SUCCESS\n"), + (m_is_client == true ? "client": "server"))); + } + else + { + eapol_key_state_string_c state_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::process_group_key_handshake_message_1(): ") + EAPL("No keys are set on state %d=%s.\n"), + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_RC4_key_descriptor( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status = eap_status_process_general_error; + + if (packet_length < eapol_RC4_key_header_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if (m_eapol_key_handshake_type != eapol_key_handshake_type_dynamic_WEP) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAPOL_KEY: %s: process_RC4_key_descriptor(): wrong handshake type %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (get_eapol_key_state() != eapol_key_state_wait_rc4_key_message) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_RC4_key_descriptor(): wrong state %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eapol_RC4_key_header_c eapol_key_message( + m_am_tools, + packet_data->get_header_buffer(packet_data->get_header_buffer_length()), + packet_data->get_header_buffer_length()); + if (eapol_key_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (eapol_key_message.check_header() != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // Check the packet length + u32_t rc4_packet_data_length = eapol_header_base_c::get_header_length() + + static_cast(eapol_key_message.get_eapol_packet_body_length()); + + if (eapol_RC4_key_header_c::get_header_length() > packet_length + || rc4_packet_data_length > packet_length) + { + // ERROR. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key frame length, ") + EAPL("eapol_key_message.get_header_length() %d, eapol_key_message.get_packet_body_length() %d, packet_length %d\n"), + eapol_key_message.get_header_length(), + eapol_key_message.get_eapol_packet_body_length(), + packet_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + // Get MS-MPPE-Recv-Key and MS-MPPE-Send-Key + eap_variable_data_c mppe_recv_key(m_am_tools); + eap_variable_data_c mppe_send_key(m_am_tools); + + if (m_pairwise_PMK_WPXK3.get_data_length() == eapol_key_state_mppe_key_length_leap) + { + // LEAP only generates 16 bytes PMK. Also with LEAP the receive and send keys are the same. + status = mppe_recv_key.set_buffer( + m_pairwise_PMK_WPXK3.get_data( + eapol_key_state_mppe_key_length_leap), + eapol_key_state_mppe_key_length_leap, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = mppe_send_key.set_buffer( + m_pairwise_PMK_WPXK3.get_data( + eapol_key_state_mppe_key_length_leap), + eapol_key_state_mppe_key_length_leap, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + else if (m_pairwise_PMK_WPXK3.get_data_length() >= 64ul) + { + // Usually types generate at least 64 bytes PMK. + // Recv-Key is the first 32 bytes of master session key and Send-Key is the next 32 bytes. + status = mppe_recv_key.set_buffer( + m_pairwise_PMK_WPXK3.get_data( + eapol_key_state_mppe_key_length), + eapol_key_state_mppe_key_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = mppe_send_key.set_buffer( + m_pairwise_PMK_WPXK3.get_data_offset( + eapol_key_state_mppe_key_length, + eapol_key_state_mppe_key_length), + eapol_key_state_mppe_key_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: Unsupported PMK key length for RC4 EAPOL-key handshake.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + + // Verify the the MD5 signature in Eapol-Key + crypto_md5_c md5(m_am_tools); + crypto_hmac_c hmac_md5(m_am_tools, &md5, false); + if (hmac_md5.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (hmac_md5.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // MPPE-Send-Key is used as the signature key. + if (hmac_md5.hmac_set_key(&mppe_send_key) != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Save the signature from the packet + eap_variable_data_c signature(m_am_tools); + status = signature.set_copy_of_buffer( + eapol_key_message.get_key_signature(), + EAPOL_RC4_KEY_SIGNATURE_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Replace the signature with zeros. + eapol_key_message.zero_key_signature(m_am_tools); + + // Send the data to HMAC-MD5 module + if (hmac_md5.hmac_update( + eapol_key_message.get_header_buffer(rc4_packet_data_length), + rc4_packet_data_length) + != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Get the calculated signature + u8_t tmp_signature[EAPOL_RC4_KEY_SIGNATURE_LENGTH]; + u32_t length; + if (hmac_md5.hmac_final(tmp_signature, &length) != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Compare the calculated and original signature + if (m_am_tools->memcmp( + tmp_signature, + signature.get_data( + EAPOL_RC4_KEY_SIGNATURE_LENGTH), + EAPOL_RC4_KEY_SIGNATURE_LENGTH) != 0) + { + // Signatures did not match. Something's wrong. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: EAPOL-Key HMAC-MD5 check passed.\n"))); + + eap_variable_data_c key_out(m_am_tools); + // Decrypt the RC4 encrypted key + if (eapol_key_message.get_key() == 0) + { + // EAPOL-Key does not contain the key. This means that we should use + // the first bytes from MS-MPPE-Recv-Key as the key. There is a slight + // confusion in draft-congdon-radius-8021x-23.txt regarding this but this is how + // it works. + if (eapol_key_message.get_key_length() > 0) + { + status = key_out.set_copy_of_buffer( + mppe_recv_key.get_data( + eapol_key_message.get_key_length()), + eapol_key_message.get_key_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Key message with no key length? + // Just ignore the message. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: Got empty WEP unicast key message.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + else + { + // Set-up RC4 key. Key is the IV and the MS-MPPE-Recv-Key truncated together. + eap_variable_data_c rc4_key(m_am_tools); + status = rc4_key.set_copy_of_buffer(eapol_key_message.get_key_IV(), EAPOL_RC4_KEY_IV_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4_key.add_data(&mppe_recv_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Set-up RC4 module + crypto_rc4_c rc4(m_am_tools); + if (rc4.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Set the key for RC4 + if (rc4.set_key(&rc4_key) != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Decrypt the key to key_out + status = key_out.set_buffer_length(eapol_key_message.get_key_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = rc4.decrypt_data( + eapol_key_message.get_key(), + key_out.get_buffer( + eapol_key_message.get_key_length()), + eapol_key_message.get_key_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = key_out.set_data_length(eapol_key_message.get_key_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // Find out the key type. At the moment only WEP keys are supported. + eapol_key_type_e key_type; + switch (eapol_key_message.get_key_flag()) + { + case eapol_RC4_key_flag_broadcast: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAPOL_KEY: Got WEP broadcast key\n"))); + key_type = eapol_key_type_broadcast; + m_received_802_1x_keys[eapol_key_type_broadcast] = true; + break; + case eapol_RC4_key_flag_unicast: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAPOL_KEY: Got WEP unicast key\n"))); + key_type = eapol_key_type_unicast; + m_received_802_1x_keys[eapol_key_type_unicast] = true; + break; + default: + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RC4 Key"), + key_out.get_data(key_out.get_data_length()), + key_out.get_data_length())); + + status = packet_data_session_key( + &key_out, + key_type, + eapol_key_message.get_key_index(), + true, + 0, + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + { + bool finished_keys(true); + + for (u32_t key_type = 0ul; key_type <= eapol_key_type_unicast; key_type++) + { + if (m_received_802_1x_keys[key_type] == false) + { + // Not all keys are received. + finished_keys = false; + break; + } + } + + if (finished_keys == true) + { + // This is notification to eapol_core_c object. + // Dynamic WEP (802.1x) authentication finished successfully. + eap_state_notification_c * notification = new eap_state_notification_c( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_dynamic_WEP, + get_eapol_key_state(), + eapol_key_state_802_11i_authentication_finished_successfull, + 0ul, + false); + if (notification == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_key_state_partner->state_notification(notification); + + delete notification; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::initialize_4_way_handshake( + const eap_am_network_id_c * const receive_network_id, + const eapol_protocol_version_e used_eapol_version) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status = eap_status_process_general_error; + + // Only client (supplicant) could call this. + EAP_ASSERT_ALWAYS(m_is_client == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::initialize_4_way_handshake()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_eapol_key_handshake_type != eapol_key_handshake_type_none + && m_eapol_key_handshake_type != eapol_key_handshake_type_group_key_handshake + && m_eapol_key_handshake_type != eapol_key_handshake_type_4_way_handshake) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: initialize_4_way_handshake(): wrong handshake type %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_buf_chain_wr_c sent_packet( + eap_write_buffer, + m_am_tools); + + if (sent_packet.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t send_data_length = 0ul; + u32_t send_buffer_length = 0ul; + + status = create_eapol_key_handshake_message_0( + true, + &sent_packet, + m_eapol_header_offset, + &send_data_length, + &send_buffer_length, + m_client_send_key_reply_counter, + used_eapol_version); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = packet_send( + &m_send_network_id, + &sent_packet, + m_eapol_header_offset, + send_data_length, + send_buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_eapol_key_state(eapol_key_state_wait_4_way_handshake_message_1); + + m_eapol_key_handshake_type = eapol_key_handshake_type_4_way_handshake; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_key_state_common.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_key_state_common.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,7028 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 50 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eapol_key_state.h" +#include "eapol_key_header.h" +#include "eap_crypto_api.h" +#include "abs_eap_am_mutex.h" +#include "eap_state_notification.h" +#include "eap_automatic_variable.h" +#include "eapol_rsna_key_data_gtk_header.h" +#include "abs_eapol_core.h" +#include "abs_eapol_key_state.h" +#include "eap_core_retransmission.h" +#include "eapol_rsna_key_data_payloads.h" +#include "eap_buffer.h" +#include "eapol_session_key.h" +#include "eapol_key_state_string.h" + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::save_parameters( + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const authenticator_RSNA_IE, + const eap_variable_data_c * const supplicant_RSNA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + m_authentication_type = authentication_type; + m_eapol_pairwise_cipher = eapol_pairwise_cipher; + m_eapol_group_cipher = eapol_group_cipher; + + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::save_parameters(): m_authentication_type=%s, ") + EAPL("m_eapol_pairwise_cipher=%d, m_eapol_group_cipher=%d.\n"), + (m_is_client == true) ? "client": "server", + state_string.get_eapol_key_authentication_type_string(m_authentication_type), + m_eapol_pairwise_cipher, + m_eapol_group_cipher)); + + + if (get_is_RSNA() == true + || get_is_WPA() == true +#if defined(EAP_USE_WPXM) + || get_is_WPXM() == true +#endif //#if defined(EAP_USE_WPXM) + ) + { + if (authenticator_RSNA_IE->get_is_valid_data() == true) + { + status = m_authenticator_RSNA_IE.set_copy_of_buffer( + authenticator_RSNA_IE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Authenticator RSN IE"), + get_authenticator_RSNA_IE()->get_data( + get_authenticator_RSNA_IE()->get_data_length()), + get_authenticator_RSNA_IE()->get_data_length())); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (supplicant_RSNA_IE->get_is_valid_data() == true) + { + status = m_supplicant_RSNA_IE.set_copy_of_buffer( + supplicant_RSNA_IE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Supplicant RSN IE"), + get_supplicant_RSNA_IE()->get_data( + get_supplicant_RSNA_IE()->get_data_length()), + get_supplicant_RSNA_IE()->get_data_length())); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::initialize( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const authenticator_RSNA_IE, + const eap_variable_data_c * const supplicant_RSNA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher, + const eap_variable_data_c * const pre_shared_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = save_parameters( + authentication_type, + authenticator_RSNA_IE, + supplicant_RSNA_IE, + eapol_pairwise_cipher, + eapol_group_cipher); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if ((m_authentication_type == eapol_key_authentication_type_RSNA_PSK + || m_authentication_type == eapol_key_authentication_type_WPA_PSK) + && (pre_shared_key == 0 + || pre_shared_key->get_is_valid_data() == false + || pre_shared_key->get_data_length() < EAPOL_RSNA_PMK_LENGTH_BYTES)) + { + if (pre_shared_key != 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal pre shared key 0x%08x, PSK length %d.\n"), + pre_shared_key->get_data(pre_shared_key->get_data_length()), + pre_shared_key->get_data_length())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + else if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP + && (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal pairwise cipher suite %d.\n"), + m_eapol_pairwise_cipher)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + else if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP + && (m_eapol_group_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal group cipher suite %d.\n"), + m_eapol_group_cipher)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + else if (m_authentication_type == eapol_key_authentication_type_WPA_EAP + && (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal pairwise cipher suite %d.\n"), + m_eapol_pairwise_cipher)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + else if (m_authentication_type == eapol_key_authentication_type_WPA_EAP + && (m_eapol_group_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal group cipher suite %d.\n"), + m_eapol_group_cipher)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + else if (m_authentication_type == eapol_key_authentication_type_802_1X) + { + // OK, cannot check the pairwise and group ciphers. + // AP will tell these in the EAPOL RC4 Key message. + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = set_mac_addresses(receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_eapol_key_state(eapol_key_state_none); + m_eapol_key_handshake_type = eapol_key_handshake_type_none; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_authentication_type == eapol_key_authentication_type_RSNA_PSK + || m_authentication_type == eapol_key_authentication_type_WPA_PSK) + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = set_pairwise_PMK( + pre_shared_key, + &send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + { + m_is_associated = true; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::initialize(): m_is_associated=%s.\n"), + (m_is_client == true) ? "client": "server", + (m_is_associated == true) ? "true": "false")); + } +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::initialize( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + reset(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + m_authentication_type = authentication_type; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = set_mac_addresses(receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_eapol_key_state(eapol_key_state_none); + m_eapol_key_handshake_type = eapol_key_handshake_type_none; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + // Creates SNonce. This is done here in early phase of authentication. + // This will reduce the CPU load when time critical first message + // of 4-Way handshake is processed. + status = create_nonce(&m_SNonce, EAPOL_RSNA_NONCE_LENGTH_BYTES); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::set_mac_addresses( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + const eap_variable_data_c * authenticator_MAC_address = 0; + const eap_variable_data_c * supplicant_MAC_address = 0; + + if (m_is_client == true) + { + authenticator_MAC_address = receive_network_id->get_source_id(); + supplicant_MAC_address = receive_network_id->get_destination_id(); + } + else + { + authenticator_MAC_address = receive_network_id->get_destination_id(); + supplicant_MAC_address = receive_network_id->get_source_id(); + } + + + status = m_authenticator_MAC_address.set_copy_of_buffer( + authenticator_MAC_address); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_supplicant_MAC_address.set_copy_of_buffer( + supplicant_MAC_address); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + const eap_variable_data_c * destination = 0; + const eap_variable_data_c * source = 0; + + if (m_is_client == true) + { + destination = &m_authenticator_MAC_address; + source = &m_supplicant_MAC_address; + } + else + { + destination = &m_supplicant_MAC_address; + source = &m_authenticator_MAC_address; + } + + + eap_am_network_id_c send_network_id(m_am_tools, + source, + destination, + eapol_ethernet_type_pae); + + status = m_send_network_id.set_copy_of_network_id(&send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_key_state_c::~eapol_key_state_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::~eapol_key_state_c(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + EAP_ASSERT(m_shutdown_was_called == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_key_state_c::eapol_key_state_c( + abs_eap_am_tools_c * const tools, + abs_eapol_key_state_c * const key_state_partner, + abs_eapol_core_c * const eapol_partner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const authenticator_RSNA_IE, + const eap_variable_data_c * const supplicant_RSNA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher, + const eap_variable_data_c * const pre_shared_key) + : m_am_tools(tools) + , m_key_state_partner(key_state_partner) + , m_eapol_partner(eapol_partner) + , m_send_network_id(tools) + , m_authenticator_RSNA_IE(tools) + , m_unicast_cipher_suite_RSNA_IE(tools) + , m_supplicant_RSNA_IE(tools) + , m_received_PMKID(tools) + , m_supplicant_MAC_address(tools) + , m_authenticator_MAC_address(tools) + , m_ANonce(tools) + , m_SNonce(tools) + , m_EAPOL_key_IV(tools) + , m_pairwise_PMK_WPXK3(tools) + , m_PMKID(tools) + , m_transient_PTK(tools) + , m_confirmation_KCK(tools) + , m_encryption_KEK(tools) + , m_temporal_TK(tools) + , m_group_GTK(tools) +#if defined(EAP_USE_WPXM) + , m_WPXM_WPXK1(tools) + , m_WPXM_WPXK2(tools) + , m_WPXM_WPXC(eapol_key_constant_wpxm_initial_wpxc_counter_value) +#endif //#if defined(EAP_USE_WPXM) + , m_group_GTK_ID(0u) + , m_group_GTK_Tx_bit(false) + , m_eapol_header_offset(0ul) + , m_MTU(0ul) + , m_trailer_length(0ul) + , m_retransmission(0) + , m_retransmission_time(EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT) + , m_retransmission_counter(EAPOL_KEY_STATE_RETRANSMISSION_COUNTER) + , m_handshake_timeout(EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_TIMEOUT) +#if defined(EAP_USE_WPXM) + , m_wpxm_reassociate_timeout(EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT) + , m_EAPOL_WPXM_key_descriptor_type(eapol_key_descriptor_type_none) +#endif //#if defined(EAP_USE_WPXM) + , m_authentication_type(authentication_type) + , m_eapol_pairwise_cipher(eapol_pairwise_cipher) + , m_eapol_group_cipher(eapol_group_cipher) + , m_eapol_key_state(eapol_key_state_none) + , m_eapol_key_handshake_type(eapol_key_handshake_type_none) + , m_create_key_failure(eapol_key_state_none) + , m_pmksa_caching_timeout(EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT) + , m_key_reply_counter(0ul) + , m_client_send_key_reply_counter(0ul) + , m_is_client(is_client_when_true) + , m_is_valid(false) + , m_marked_removed(false) + , m_shutdown_was_called(false) + , m_allow_missing_PMKID_in_message_1(false) + , m_skip_PMKID_key_data_in_message_1(false) + , m_allow_non_zero_mic_and_reserved_in_message_1(false) + , m_indicate_pmkid_to_lower_layer(false) + , m_handshake_timeout_set(false) + , m_server_TEST_group_key_update(false) +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + , m_is_associated(false) +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(receive_network_id); + EAP_UNREFERENCED_PARAMETER(authenticator_RSNA_IE); + EAP_UNREFERENCED_PARAMETER(supplicant_RSNA_IE); + EAP_UNREFERENCED_PARAMETER(pre_shared_key); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::eapol_key_state_c(1): %s\n"), + (m_is_client == true) ? "client": "server")); + + for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++) + { + m_received_802_1x_keys[key_type] = false; + } + + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_key_state_c::eapol_key_state_c( + abs_eap_am_tools_c * const tools, + abs_eapol_key_state_c * const key_state_partner, + abs_eapol_core_c * const eapol_partner, + const bool is_client_when_true, + const eap_am_network_id_c * const /* receive_network_id */, + const eapol_key_authentication_type_e authentication_type) + : m_am_tools(tools) + , m_key_state_partner(key_state_partner) + , m_eapol_partner(eapol_partner) + , m_send_network_id(tools) + , m_authenticator_RSNA_IE(tools) + , m_unicast_cipher_suite_RSNA_IE(tools) + , m_supplicant_RSNA_IE(tools) + , m_received_PMKID(tools) + , m_supplicant_MAC_address(tools) + , m_authenticator_MAC_address(tools) + , m_ANonce(tools) + , m_SNonce(tools) + , m_EAPOL_key_IV(tools) + , m_pairwise_PMK_WPXK3(tools) + , m_PMKID(tools) + , m_transient_PTK(tools) + , m_confirmation_KCK(tools) + , m_encryption_KEK(tools) + , m_temporal_TK(tools) + , m_group_GTK(tools) +#if defined(EAP_USE_WPXM) + , m_WPXM_WPXK1(tools) + , m_WPXM_WPXK2(tools) + , m_WPXM_WPXC(eapol_key_constant_wpxm_initial_wpxc_counter_value) +#endif //#if defined(EAP_USE_WPXM) + , m_group_GTK_ID(0u) + , m_group_GTK_Tx_bit(false) + , m_eapol_header_offset(0ul) + , m_MTU(0ul) + , m_trailer_length(0ul) + , m_retransmission(0) + , m_retransmission_time(EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT) + , m_retransmission_counter(EAPOL_KEY_STATE_RETRANSMISSION_COUNTER) + , m_handshake_timeout(EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_TIMEOUT) +#if defined(EAP_USE_WPXM) + , m_wpxm_reassociate_timeout(EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT) + , m_EAPOL_WPXM_key_descriptor_type(eapol_key_descriptor_type_none) +#endif //#if defined(EAP_USE_WPXM) + , m_authentication_type(authentication_type) + , m_eapol_pairwise_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none) + , m_eapol_group_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none) + , m_eapol_key_state(eapol_key_state_none) + , m_eapol_key_handshake_type(eapol_key_handshake_type_none) + , m_create_key_failure(eapol_key_state_none) + , m_pmksa_caching_timeout(EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT) + , m_key_reply_counter(0ul) + , m_client_send_key_reply_counter(0ul) + , m_is_client(is_client_when_true) + , m_is_valid(false) + , m_marked_removed(false) + , m_shutdown_was_called(false) + , m_allow_missing_PMKID_in_message_1(false) + , m_skip_PMKID_key_data_in_message_1(false) + , m_allow_non_zero_mic_and_reserved_in_message_1(false) + , m_indicate_pmkid_to_lower_layer(false) + , m_handshake_timeout_set(false) + , m_server_TEST_group_key_update(false) +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + , m_is_associated(false) +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::eapol_key_state_c(2): %s\n"), + (m_is_client == true) ? "client": "server")); + + for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++) + { + m_received_802_1x_keys[key_type] = false; + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::configure(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + m_eapol_header_offset = m_eapol_partner->get_header_offset(&m_MTU, &m_trailer_length); + + for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++) + { + m_received_802_1x_keys[key_type] = false; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_is_client == false) + { + eap_variable_data_c retransmission_time(m_am_tools); + + eap_status_e status = m_key_state_partner->read_configure( + cf_str_EAPOL_key_state_retransmission_time.get_field(), + &retransmission_time); + if (status == eap_status_ok + && retransmission_time.get_is_valid_data() == true) + { + u32_t *retransmission_time_value = reinterpret_cast( + retransmission_time.get_data(sizeof(u32_t))); + if (retransmission_time_value != 0) + { + m_retransmission_time = *retransmission_time_value; + } + else + { + m_retransmission_time = EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT; + } + } + else + { + m_retransmission_time = EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT; + } + } + + if (m_is_client == false) + { + eap_variable_data_c retransmission_counter(m_am_tools); + + eap_status_e status = m_key_state_partner->read_configure( + cf_str_EAPOL_key_state_retransmission_counter.get_field(), + &retransmission_counter); + if (status == eap_status_ok + && retransmission_counter.get_is_valid_data() == true) + { + u32_t *retransmission_counter_value = reinterpret_cast( + retransmission_counter.get_data(sizeof(u32_t))); + if (retransmission_counter_value != 0) + { + m_retransmission_counter = *retransmission_counter_value; + } + } + } + + + { + eap_variable_data_c session_timeout(m_am_tools); + + eap_status_e status = m_key_state_partner->read_configure( + cf_str_EAPOL_key_state_handshake_timeout.get_field(), + &session_timeout); + if (status == eap_status_ok + && session_timeout.get_is_valid_data() == true) + { + u32_t *handler_timeout = reinterpret_cast( + session_timeout.get_data(sizeof(u32_t))); + if (handler_timeout != 0) + { + m_handshake_timeout = *handler_timeout; + } + } + } + + +#if defined(EAP_USE_WPXM) + + { + eap_variable_data_c wpxm_reassociation_timeout(m_am_tools); + + eap_status_e status = m_key_state_partner->read_configure( + cf_str_EAPOL_key_state_wpxm_reassociate_timeout.get_field(), + &wpxm_reassociation_timeout); + if (status == eap_status_ok + && wpxm_reassociation_timeout.get_is_valid_data() == true) + { + u32_t *handler_timeout = reinterpret_cast( + wpxm_reassociation_timeout.get_data(sizeof(u32_t))); + if (handler_timeout != 0) + { + m_wpxm_reassociate_timeout = *handler_timeout; + } + } + } + + + if (m_is_client == false) + { + eap_variable_data_c EAPOL_WPXM_type(m_am_tools); + + eap_status_e status = m_key_state_partner->read_configure( + cf_str_EAPOL_WPXM_type.get_field(), + &EAPOL_WPXM_type); + if (status == eap_status_ok + && EAPOL_WPXM_type.get_is_valid() == true + && EAPOL_WPXM_type.get_data_length() > 0ul + && EAPOL_WPXM_type.get_data( + EAPOL_WPXM_type.get_data_length()) != 0) + { + if (cf_str_EAPOL_key_authentication_type_config_value_RSNA_EAP + .get_field()->compare( + m_am_tools, + &EAPOL_WPXM_type) == true) + { + m_EAPOL_WPXM_key_descriptor_type = eapol_key_descriptor_type_RSNA; + } + else if (cf_str_EAPOL_key_authentication_type_config_value_WPA_EAP + .get_field()->compare( + m_am_tools, + &EAPOL_WPXM_type) == true) + { + m_EAPOL_WPXM_key_descriptor_type = eapol_key_descriptor_type_WPA; + } + } + } + +#endif //#if defined(EAP_USE_WPXM) + + + { + eap_variable_data_c pmksa_caching_timeout(m_am_tools); + + eap_status_e status = m_key_state_partner->read_configure( + cf_str_EAPOL_key_state_pmksa_caching_timeout.get_field(), + &pmksa_caching_timeout); + if (status == eap_status_ok + && pmksa_caching_timeout.get_is_valid_data() == true) + { + u32_t *handler_timeout = reinterpret_cast( + pmksa_caching_timeout.get_data(sizeof(u32_t))); + if (handler_timeout != 0) + { + m_pmksa_caching_timeout = *handler_timeout; + } + } + } + + + if (m_is_client == true) + { + { + eap_variable_data_c allow_missing_PMKID_in_message_1(m_am_tools); + + eap_status_e status = m_key_state_partner->read_configure( + cf_str_EAPOL_key_state_allow_missing_PMKID_in_message_1.get_field(), + &allow_missing_PMKID_in_message_1); + if (status == eap_status_ok + && allow_missing_PMKID_in_message_1.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast( + allow_missing_PMKID_in_message_1.get_data(sizeof(u32_t))); + if (flag != 0 + && *flag != 0) + { + m_allow_missing_PMKID_in_message_1 = true; + } + } + } + + { + eap_variable_data_c allow_non_zero_mic_in_message_1(m_am_tools); + + eap_status_e status = m_key_state_partner->read_configure( + cf_str_EAPOL_key_state_allow_non_zero_mic_in_message_1.get_field(), + &allow_non_zero_mic_in_message_1); + if (status == eap_status_ok + && allow_non_zero_mic_in_message_1.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast( + allow_non_zero_mic_in_message_1.get_data(sizeof(u32_t))); + if (flag != 0 + && *flag != 0) + { + m_allow_non_zero_mic_and_reserved_in_message_1 = true; + } + } + } + + { + eap_variable_data_c indicate_pmkid_to_lower_layer(m_am_tools); + + eap_status_e status = m_key_state_partner->read_configure( + cf_str_EAPOL_key_state_indicate_pmkid_to_lower_layer.get_field(), + &indicate_pmkid_to_lower_layer); + if (status == eap_status_ok + && indicate_pmkid_to_lower_layer.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast( + indicate_pmkid_to_lower_layer.get_data(sizeof(u32_t))); + if (flag != 0 + && *flag != 0) + { + m_indicate_pmkid_to_lower_layer = true; + } + } + } + + } + + if (m_is_client == false) + { + { + eap_variable_data_c skip_PMKID_key_data_in_message_1(m_am_tools); + + eap_status_e status = m_key_state_partner->read_configure( + cf_str_EAPOL_key_state_skip_PMKID_key_data_in_message_1.get_field(), + &skip_PMKID_key_data_in_message_1); + if (status == eap_status_ok + && skip_PMKID_key_data_in_message_1.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast( + skip_PMKID_key_data_in_message_1.get_data(sizeof(u32_t))); + if (flag != 0 + && *flag != 0) + { + m_skip_PMKID_key_data_in_message_1 = true; + } + } + } + + { + eap_variable_data_c EAPOL_key_state_TEST_group_key_update(m_am_tools); + + eap_status_e status = m_key_state_partner->read_configure( + cf_str_EAPOL_key_state_TEST_group_key_update.get_field(), + &EAPOL_key_state_TEST_group_key_update); + if (status == eap_status_ok + && EAPOL_key_state_TEST_group_key_update.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast( + EAPOL_key_state_TEST_group_key_update.get_data(sizeof(u32_t))); + if (flag != 0 + && *flag != 0) + { + m_server_TEST_group_key_update = true; + } + } + } + + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eapol_key_state_c::send_error_notification(const eap_status_e error) +{ + // Notifies the lower level of an authentication error. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_general, + eapol_key_handshake_type_none, + eap_state_none, + eap_general_state_authentication_error, + 0, + false); + + notification.set_authentication_error(error); + + m_key_state_partner->state_notification(¬ification); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::set_reassociation_parameters( + const eap_variable_data_c * const pairwise_PMK_WPXK3, + const eap_variable_data_c * const PMKID, + const eap_variable_data_c * const transient_PTK, + const eap_variable_data_c * const confirmation_KCK, + const eap_variable_data_c * const encryption_KEK, + const eap_variable_data_c * const temporal_TK, + const eap_variable_data_c * const WPXM_WPXK1, + const eap_variable_data_c * const WPXM_WPXK2, + const u32_t WPXM_WPXC, + const eapol_key_handshake_type_e eapol_key_handshake_type, + const eapol_key_authentication_type_e authentication_type + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::set_reassociation_parameters(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()), + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type))); + + eap_status_e status = m_pairwise_PMK_WPXK3.set_copy_of_buffer(pairwise_PMK_WPXK3); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_PMKID.set_copy_of_buffer(PMKID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_transient_PTK.set_copy_of_buffer(transient_PTK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_confirmation_KCK.set_copy_of_buffer(confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_encryption_KEK.set_copy_of_buffer(encryption_KEK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_temporal_TK.set_copy_of_buffer(temporal_TK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(EAP_USE_WPXM) + status = m_WPXM_WPXK1.set_copy_of_buffer(WPXM_WPXK1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_WPXM_WPXK2.set_copy_of_buffer(WPXM_WPXK2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_WPXM_WPXC = WPXM_WPXC; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::set_reassociation_parameters(): ") + EAPL("Set m_WPXM_WPXC=%d.\n"), + m_WPXM_WPXC)); + + + m_eapol_key_handshake_type = eapol_key_handshake_type; + m_authentication_type = authentication_type; +#else + EAP_UNREFERENCED_PARAMETER(WPXM_WPXK1); + EAP_UNREFERENCED_PARAMETER(WPXM_WPXK2); + EAP_UNREFERENCED_PARAMETER(WPXM_WPXC); +#endif //#if defined(EAP_USE_WPXM) + + set_eapol_key_state(eapol_key_state_preauthenticated); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::set_reassociation_parameters(): m_authentication_type=%s, ") + EAPL("m_eapol_pairwise_cipher=%d, m_eapol_group_cipher=%d.\n"), + (m_is_client == true) ? "client": "server", + state_string.get_eapol_key_authentication_type_string(m_authentication_type), + m_eapol_pairwise_cipher, + m_eapol_group_cipher)); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::started_eap_authentication() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::started_eap_authentication(): %s\n"), + (m_is_client == true) ? "client": "server")); + + (void) cancel_handshake_timeout(); + (void) cancel_reassociate_timeout(); + (void) cancel_pmksa_caching_timeout(); + (void) cancel_4_way_handshake_start_timeout(); + + + { + // Indicates lower layers the EAP authentication is running. + eap_state_notification_c * notification = new eap_state_notification_c( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_none, + eapol_key_state_eap_authentication_running, + eapol_key_state_eap_authentication_running, + 0ul, + false); + if (notification == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_key_state_partner->state_notification(notification); + + delete notification; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_key_state_c *eapol_key_state_c::copy(const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eapol_key_state_c * const new_state = new eapol_key_state_c( + m_am_tools, + m_key_state_partner, + m_eapol_partner, + m_is_client, + receive_network_id, + m_authentication_type, + &m_authenticator_RSNA_IE, + &m_supplicant_RSNA_IE, + m_eapol_pairwise_cipher, + m_eapol_group_cipher, + &m_pairwise_PMK_WPXK3); + + if (new_state == 0) + { + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + if (new_state->get_is_valid() == false) + { + new_state->shutdown(); + delete new_state; + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + eap_status_e status = new_state->configure(); + if (status != eap_status_ok) + { + new_state->shutdown(); + delete new_state; + (void) EAP_STATUS_RETURN(m_am_tools, status); + return 0; + } + + +#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + status = new_state->initialize( + receive_network_id, + m_authentication_type); + if (status != eap_status_ok) + { + new_state->shutdown(); + delete new_state; + (void) EAP_STATUS_RETURN(m_am_tools, status); + return 0; + } + +#endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + + eapol_key_handshake_type_e eapol_key_handshake_type(m_eapol_key_handshake_type); + + eapol_key_authentication_type_e authentication_type(m_authentication_type); + +#if defined(EAP_USE_WPXM) + if (authentication_type == eapol_key_authentication_type_WPXM) + { + eapol_key_handshake_type = eapol_key_handshake_type_WPXM_reassociation; + } +#endif //#if defined(EAP_USE_WPXM) + + + status = new_state->set_reassociation_parameters( + &m_pairwise_PMK_WPXK3, + &m_PMKID, + &m_transient_PTK, + &m_confirmation_KCK, + &m_encryption_KEK, + &m_temporal_TK, +#if defined(EAP_USE_WPXM) + &m_WPXM_WPXK1, + &m_WPXM_WPXK2, + m_WPXM_WPXC, +#else + 0, + 0, + 0ul, +#endif //#if defined(EAP_USE_WPXM) + eapol_key_handshake_type, + authentication_type + ); + if (status != eap_status_ok) + { + new_state->shutdown(); + delete new_state; + (void) EAP_STATUS_RETURN(m_am_tools, status); + return 0; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return new_state; +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::handshake_failure_notification() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eapol_key_state_string_c eapol_key_state_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::handshake_failure_notification(): %s, m_eapol_key_handshake_type=%s, get_eapol_key_state()=%s\n"), + (m_is_client == true) ? "client": "server", + eapol_key_state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type), + eapol_key_state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (m_eapol_key_handshake_type == eapol_key_handshake_type_4_way_handshake) + { + if (get_eapol_key_state() == eapol_key_state_preauthenticated) + { + // Do not notify lower layer. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Does not notify pre-authenticated state.\n"), + (m_is_client == true ? "client": "server"))); + } + else if (get_eapol_key_state() == eapol_key_state_none) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unused EAPOL Key state.\n"), + (m_is_client == true ? "client": "server"))); + } + else if (get_eapol_key_state() != eapol_key_state_4_way_handshake_successfull) + { + // This is notification to eapol_core_c object. + // 4-Way Handshake terminated unsuccessfully. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_4_way_handshake, + eapol_key_state_4_way_handshake_failed, + eapol_key_state_802_11i_authentication_terminated_unsuccessfull, + 0ul, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + m_key_state_partner->state_notification(¬ification); + + set_eapol_key_state(eapol_key_state_4_way_handshake_failed); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): 4-Way Handshake FAILED\n"), + (m_is_client == true ? "client": "server"))); + } + } + else if (m_eapol_key_handshake_type == eapol_key_handshake_type_group_key_handshake) + { + if (get_eapol_key_state() == eapol_key_state_preauthenticated) + { + // Do not notify lower layer. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Does not notify pre-authenticated state.\n"), + (m_is_client == true ? "client": "server"))); + } + else if (get_eapol_key_state() == eapol_key_state_none) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unused EAPOL Key state.\n"), + (m_is_client == true ? "client": "server"))); + } + else if (get_eapol_key_state() != eapol_key_state_group_key_handshake_successfull) + { + // This is notification to eapol_core_c object. + // Group Key Handshake terminated unsuccessfully. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_group_key_handshake, + eapol_key_state_group_key_handshake_failed, + eapol_key_state_802_11i_authentication_terminated_unsuccessfull, + 0ul, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + m_key_state_partner->state_notification(¬ification); + + set_eapol_key_state(eapol_key_state_4_way_handshake_failed); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Group Key Handshake FAILED\n"), + (m_is_client == true ? "client": "server"))); + } + } + else if (m_eapol_key_handshake_type == eapol_key_handshake_type_none) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unused EAPOL Key state.\n"), + (m_is_client == true ? "client": "server"))); + } + else + { + EAP_UNREFERENCED_PARAMETER(eapol_key_state_string); + + set_eapol_key_state(eapol_key_state_4_way_handshake_failed); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unknown Handshake FAILED\n"), + (m_is_client == true ? "client": "server"))); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::shutdown(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (m_shutdown_was_called == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::shutdown(): Already called.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + // This will cancel all timers of this object. + cancel_retransmission(); + cancel_handshake_timeout(); + cancel_pmksa_caching_timeout(); + cancel_reassociate_timeout(); + cancel_4_way_handshake_start_timeout(); + + eap_status_e status = handshake_failure_notification(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::set_s_nonce( + const eap_variable_data_c * const s_nonce) +{ + eap_status_e status = m_SNonce.set_copy_of_buffer(s_nonce); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::check_pmksa_cache( + const eapol_key_authentication_type_e selected_eapol_key_authentication_type, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::check_pmksa_cache(): %s\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = eap_status_ok; + + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::check_pmksa_cache(): this = 0x%08x, state %d=%s, selected_eapol_key_authentication_type %d=%s, m_authentication_type %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()), + selected_eapol_key_authentication_type, + state_string.get_eapol_key_authentication_type_string(selected_eapol_key_authentication_type), + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type))); + + + if (selected_eapol_key_authentication_type != eapol_key_authentication_type_RSNA_EAP + && selected_eapol_key_authentication_type != eapol_key_authentication_type_RSNA_PSK + && selected_eapol_key_authentication_type != eapol_key_authentication_type_WPXM) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + else if (selected_eapol_key_authentication_type != m_authentication_type + || pairwise_key_cipher_suite != m_eapol_pairwise_cipher + || group_key_cipher_suite != m_eapol_group_cipher) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::initialize_preauthentication( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::initialize_preauthentication(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()), + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type))); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_authentication_type != authentication_type) + { + // Illegal authentication type, must be the same as previously used. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_authentication_type == eapol_key_authentication_type_none + || m_authentication_type == eapol_key_authentication_type_RSNA_PSK + || m_authentication_type == eapol_key_authentication_type_WPA_PSK + || m_authentication_type == eapol_key_authentication_type_802_1X) + { + // Illegal authentication type. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + set_eapol_key_state(eapol_key_state_none); + m_eapol_key_handshake_type = eapol_key_handshake_type_none; + + reset(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = set_mac_addresses(receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_eapol_key_state(eapol_key_state_none); + m_eapol_key_handshake_type = eapol_key_handshake_type_none; + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::read_reassociation_parameters( + const eap_am_network_id_c * const /* receive_network_id */, ///< source includes remote address, destination includes local address. + const eapol_key_authentication_type_e required_authentication_type, + eap_variable_data_c * const PMKID, + const eap_variable_data_c * const received_WPA_ie, + const eap_variable_data_c * const sent_WPA_ie) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::read_reassociation_parameters(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()), + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type))); + + + (void) cancel_pmksa_caching_timeout(); + (void) cancel_handshake_timeout(); + (void) cancel_reassociate_timeout(); + (void) cancel_4_way_handshake_start_timeout(); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (received_WPA_ie != 0 + && received_WPA_ie->get_is_valid_data() == true) + { + status = m_authenticator_RSNA_IE.set_copy_of_buffer(received_WPA_ie); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (sent_WPA_ie != 0 + && sent_WPA_ie->get_is_valid_data() == true) + { + status = m_supplicant_RSNA_IE.set_copy_of_buffer(sent_WPA_ie); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + // Creates SNonce. This is done here in early phase of authentication. + // This will reduce the CPU load when time critical first message + // of 4-Way handshake is processed. + status = create_nonce(&m_SNonce, EAPOL_RSNA_NONCE_LENGTH_BYTES); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + status = init_handshake_timeout(m_handshake_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (get_eapol_key_state() != eapol_key_state_preauthenticated + || m_authentication_type != required_authentication_type) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAPOL_KEY: %s: eapol_key_state_c::read_reassociation_parameters(): this = 0x%08x, (get_eapol_key_state()=%d=%s) != (eapol_key_state_preauthenticated)\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAPOL_KEY: %s: || (m_authentication_type=%d=%s) != (required_authentication_type=%d=%s)\n"), + (m_is_client == true) ? "client": "server", + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type), + required_authentication_type, + state_string.get_eapol_key_authentication_type_string(required_authentication_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + if (get_is_RSNA() == true) + { + if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + status = create_PMKID(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = PMKID->set_copy_of_buffer(&m_PMKID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#if defined(EAP_USE_WPXM) + else if (get_is_WPXM() == true) + { + // We need to create a new PTKn. + ++m_WPXM_WPXC; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::read_reassociation_parameters(): ") + EAPL("m_WPXM_WPXC=%d.\n"), + m_WPXM_WPXC)); + + status = derive_WPXM_PTK(m_WPXM_WPXC); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = init_reassociate_timeout(m_wpxm_reassociate_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if defined(EAP_USE_WPXM) + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::complete_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const /* receive_network_id */, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const received_WPA_IE, + const eap_variable_data_c * const sent_WPA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::complete_reassociation(): %s\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status(eap_status_process_general_error); + + if (get_eapol_key_state() != eapol_key_state_preauthenticated + || m_authentication_type != authentication_type) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + if (reassociation_result == eapol_wlan_authentication_state_association_ok) + { + if (get_is_RSNA() == true) + { + status = allow_4_way_handshake(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = save_parameters( + authentication_type, + received_WPA_IE, + sent_WPA_IE, + pairwise_key_cipher_suite, + group_key_cipher_suite); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#if defined(EAP_USE_WPXM) + else if (get_is_WPXM() == true) + { + // OK, nothing to do here. + status = eap_status_ok; + } +#endif //#if defined(EAP_USE_WPXM) + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + { + m_is_associated = true; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::complete_reassociation(): m_is_associated=%s.\n"), + (m_is_client == true) ? "client": "server", + (m_is_associated == true) ? "true": "false")); + } +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + } + else + { + // Reassociation failed, clean-up state. + reset(); + + // Timeout value zero will remove state immediately. + status = init_handshake_timeout(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_RSNA() +{ + return (m_authentication_type == eapol_key_authentication_type_RSNA_EAP + || m_authentication_type == eapol_key_authentication_type_RSNA_PSK); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_WPA() +{ + return (m_authentication_type == eapol_key_authentication_type_WPA_EAP + || m_authentication_type == eapol_key_authentication_type_WPA_PSK); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::asynchronous_init_remove_eapol_key_state() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = handshake_failure_notification(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_key_state_partner->asynchronous_init_remove_eapol_key_state( + &m_send_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::timer_expired( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(data); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: [0x%08x]->eapol_key_state_c::timer_expired(id 0x%02x, data 0x%08x).\n"), + (m_is_client == true ? "client": "server"), + this, + id, + data)); + + if (id == EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID) + { + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID expired, eapol_key_state=%d=%s\n"), + (m_is_client == true ? "client": "server"), + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + if ((m_is_client == true + && get_eapol_key_state() == eapol_key_state_wait_4_way_handshake_message_3) + || (m_is_client == false + && get_eapol_key_state() == eapol_key_state_wait_4_way_handshake_message_2)) + { + if (m_authentication_type == eapol_key_authentication_type_RSNA_PSK + || m_authentication_type == eapol_key_authentication_type_WPA_PSK) + { + // Most propably the PSK is incorrect. + // There could be other problems too. + send_error_notification(eap_status_wrong_password); + } + else if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP + || m_authentication_type == eapol_key_authentication_type_WPA_EAP + || m_authentication_type == eapol_key_authentication_type_802_1X + || m_authentication_type == eapol_key_authentication_type_WPXM) + { + send_error_notification(eap_status_authentication_failure); + } + } + else if (get_eapol_key_state() != eapol_key_state_none) + { + send_error_notification(eap_status_authentication_failure); + } + + // Terminate the session. + status = asynchronous_init_remove_eapol_key_state(); + } + else if (id == EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID elapsed.\n"), + (m_is_client == true ? "client": "server"))); + + if (m_retransmission != 0 + && m_retransmission->get_is_valid() == true + && m_retransmission->get_retransmission_counter() > 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: new retransmission, m_retransmission->get_is_valid()=%d, ") + EAPL("m_retransmission->get_retransmission_counter()=%d.\n"), + m_retransmission->get_is_valid(), + m_retransmission->get_retransmission_counter())); + + // This packet send is initialized by timer event. + status = resend_packet( + m_retransmission->get_send_network_id(), + m_retransmission->get_sent_packet(), + m_retransmission->get_header_offset(), + m_retransmission->get_data_length(), + m_retransmission->get_buffer_size() + ); + + if (status == eap_status_ok) + { + if (m_retransmission->get_retransmission_counter() > 0u) + { + // OK, initialize the next time to retransmit. + u32_t next_retransmission_time(m_retransmission->get_next_retransmission_time()); + + status = m_key_state_partner->set_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID, 0, + next_retransmission_time); + if (status != eap_status_ok) + { + delete m_retransmission; + m_retransmission = 0; + } + else + { + m_retransmission->get_next_retransmission_counter(); // This decrements the counter. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID set %d ms, retransmission_counter %d.\n"), + next_retransmission_time, + m_retransmission->get_retransmission_counter())); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + delete m_retransmission; + m_retransmission = 0; + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: no retransmission, m_retransmission=0x%08x.\n"), + m_retransmission)); + if (m_retransmission != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: no retransmission, m_retransmission->get_is_valid()=%d, ") + EAPL("m_retransmission->get_retransmission_counter()=%d.\n"), + m_retransmission->get_is_valid(), + m_retransmission->get_retransmission_counter())); + } + + // No good EAPOL-Key-Response received to EAPOL-Key-Requests. + // Terminate the session. + status = asynchronous_init_remove_eapol_key_state(); + } + } + else if (id == EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID expired.\n"), + (m_is_client == true ? "client": "server"))); + + // Caching timeout. + // Remove the cached session. + status = asynchronous_init_remove_eapol_key_state(); + } +#if defined(EAP_USE_WPXM) + else if (id == EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID expired.\n"), + (m_is_client == true ? "client": "server"))); + + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_WPXM_reassociation, + get_eapol_key_state(), + eapol_key_state_reassociation_failed, + 0ul, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + m_key_state_partner->state_notification(¬ification); + + // Remove the cached session. + status = asynchronous_init_remove_eapol_key_state(); + } +#endif //#if defined(EAP_USE_WPXM) + else if (id == EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID expired.\n"), + (m_is_client == true ? "client": "server"))); + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + m_send_network_id.get_destination_id(), + m_send_network_id.get_source_id(), + m_send_network_id.get_type()); + if (receive_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = start_group_key_handshake( + &receive_network_id, + eapol_protocol_version_2, +#if defined(EAP_USE_WPXM) + m_EAPOL_WPXM_key_descriptor_type +#else + eapol_key_descriptor_type_RSNA +#endif //#if defined(EAP_USE_WPXM) + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (id == EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID expired.\n"), + (m_is_client == true ? "client": "server"))); + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + m_send_network_id.get_destination_id(), + m_send_network_id.get_source_id(), + m_send_network_id.get_type()); + if (receive_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = initialize_4_way_handshake( + &receive_network_id, + eapol_protocol_version_2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::timer_delete_data( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(data); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: [0x%08x]->eapol_key_state_c::timer_delete_data(id 0x%02x, data 0x%08x).\n"), + (m_is_client == true) ? "client": "server", + this, + id, + data)); + + if (id == EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID) + { + // Nothing to delete. + } + else if (id == EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID) + { + if (m_retransmission != 0 + && m_retransmission->get_is_valid() == true + && m_retransmission->get_retransmission_counter() > 0) + { + // Do not delete yet. + // cancel_retransmission() will delete m_retransmission. + } + else if (m_retransmission != 0) + { + delete m_retransmission; + m_retransmission = 0; + } + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::trace_eapol_key_message( + const i8_t * const prefix, + eapol_RSNA_key_header_c * const eapol_key_message) +{ + EAP_UNREFERENCED_PARAMETER(prefix); + EAP_UNREFERENCED_PARAMETER(eapol_key_message); + +#if defined(USE_EAP_TRACE) + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + u32_t key_replay_counter_high = static_cast(eap_shift_right_64_bit( + eapol_key_message->get_key_replay_counter(), 32)); + u32_t key_replay_counter_low = static_cast(eapol_key_message->get_key_replay_counter()); + + EAP_UNREFERENCED_PARAMETER(key_replay_counter_high); + EAP_UNREFERENCED_PARAMETER(key_replay_counter_low); + + if (get_is_RSNA() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): eapol version 0x%02x, eapol packet type 0x%02x, ") + EAPL("eapol packet body length 0x%04x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_eapol_protocol_version(), + (eapol_key_message)->get_eapol_packet_type(), + (eapol_key_message)->get_eapol_packet_body_length() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): eapol key descriptor type 0x%02x, ") + EAPL("key information 0x%04x, ") + EAPL("key information key descriptor version 0x%01x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_key_descriptor_type(), + (eapol_key_message)->get_key_information(), + (eapol_key_message)->get_key_information_key_descriptor_version() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): key information key type 0x%01x, ") + EAPL("key information reserved 0x%01x, ") + EAPL("key information install 0x%01x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_key_information_key_type(), + (eapol_key_message)->get_key_information_reserved_a(), + (eapol_key_message)->get_key_information_install() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): key information key ack 0x%01x, ") + EAPL("key information key MIC 0x%01x, ") + EAPL("key information secure 0x%01x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_key_information_key_ack(), + (eapol_key_message)->get_key_information_key_MIC(), + (eapol_key_message)->get_key_information_secure() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): key information error 0x%01x, ") + EAPL("key information request 0x%01x, ") + EAPL("key information encrypted key data 0x%01x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_key_information_error(), + (eapol_key_message)->get_key_information_request(), + (eapol_key_message)->get_key_information_encrypted_key_data() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): key information reserved 0x%01x, ") + EAPL("key length 0x%04x, key reply counter 0x%08x%08x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_key_information_reserved_b(), + (eapol_key_message)->get_key_length(), + key_replay_counter_high, + key_replay_counter_low + )); + } + else if (get_is_WPA() == true +#if defined(EAP_USE_WPXM) + || get_is_WPXM() == true +#endif //#if defined(EAP_USE_WPXM) + ) + { + // According to 802.11i D3.0 + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): eapol version 0x%02x, eapol packet type 0x%02x, ") + EAPL("eapol packet body length 0x%04x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_eapol_protocol_version(), + (eapol_key_message)->get_eapol_packet_type(), + (eapol_key_message)->get_eapol_packet_body_length() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): eapol key descriptor type 0x%02x, ") + EAPL("key information 0x%04x, ") + EAPL("key information key descriptor version 0x%01x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_key_descriptor_type(), + (eapol_key_message)->get_key_information(), + (eapol_key_message)->get_key_information_key_descriptor_version() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): key information key type 0x%01x, ") + EAPL("key information key index 0x%01x, ") + EAPL("key information install 0x%01x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_key_information_key_type(), + (eapol_key_message)->get_key_information_key_index(), + (eapol_key_message)->get_key_information_install() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): key information key ack 0x%01x, ") + EAPL("key information key MIC 0x%01x, ") + EAPL("key information secure 0x%01x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_key_information_key_ack(), + (eapol_key_message)->get_key_information_key_MIC(), + (eapol_key_message)->get_key_information_secure() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): key information error 0x%01x, ") + EAPL("key information request 0x%01x, ") + EAPL("key information encrypted key data 0x%01x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_key_information_error(), + (eapol_key_message)->get_key_information_request(), + (eapol_key_message)->get_key_information_encrypted_key_data() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): key information reserved 0x%02x, ") + EAPL("key length 0x%04x, key reply counter 0x%08x%08x\n"), + prefix, + (eapol_key_message), + (eapol_key_message)->get_key_information_reserved_b(), + (eapol_key_message)->get_key_length(), + key_replay_counter_high, + key_replay_counter_low + )); + } + else + { + // ERROR. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("key nonce"), + (eapol_key_message)->get_key_NONCE(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL-Key IV"), + (eapol_key_message)->get_EAPOL_key_IV(), + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Key RSC"), + (eapol_key_message)->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("STA MAC address"), + (eapol_key_message)->get_key_STA_MAC_address(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("reserved"), + (eapol_key_message)->get_key_reserved(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RESERVED_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Key MIC"), + (eapol_key_message)->get_key_MIC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Key Data"), + (eapol_key_message)->get_key_data((eapol_key_message)->get_key_data_length()), + (eapol_key_message)->get_key_data_length())); + +#endif //#if defined(USE_EAP_TRACE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------- + + +// +eap_status_e eapol_key_state_c::trace_eapol_rsna_key_data_payload( + const bool is_RSNA, + const bool is_WPXM, + const eapol_key_descriptor_type_e eapol_key_descriptor_type, + const i8_t * const prefix, + const eapol_rsna_key_data_header_c * const key_data_payload, + const u32_t buffer_length) +{ + EAP_UNREFERENCED_PARAMETER(is_RSNA); + EAP_UNREFERENCED_PARAMETER(prefix); + EAP_UNREFERENCED_PARAMETER(key_data_payload); + EAP_UNREFERENCED_PARAMETER(buffer_length); + EAP_UNREFERENCED_PARAMETER(is_WPXM); + EAP_UNREFERENCED_PARAMETER(eapol_key_descriptor_type); + +#if defined(USE_EAP_TRACE) + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if ((is_RSNA == true + || (is_WPXM == true && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA)) + && key_data_payload->get_descriptor_type() == eapol_RSNA_key_data_type_RSN_key_data) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s\n"), + prefix, + key_data_payload, + key_data_payload->get_descriptor_type(), + key_data_payload->get_descriptor_type_string())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): key_data_payload 0x%04x=%s\n"), + prefix, + key_data_payload, + key_data_payload->get_payload_type(), + key_data_payload->get_payload_type_string())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x.\n"), + prefix, + key_data_payload, + key_data_payload->get_header_and_body_length(), + buffer_length)); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: key_data_payload"), + (key_data_payload->get_header_buffer(key_data_payload->get_header_buffer_length())), + key_data_payload->get_header_buffer_length())); + } + else if ((is_RSNA == true + || (is_WPXM == true && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA)) + && key_data_payload->get_descriptor_type() == eapol_RSNA_key_data_type_RSN_IE) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s.\n"), + prefix, + key_data_payload, + key_data_payload->get_descriptor_type(), + key_data_payload->get_descriptor_type_string())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x, RSN IE.\n"), + prefix, + key_data_payload, + key_data_payload->get_header_and_body_length(), + buffer_length)); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: RSN IE"), + (key_data_payload->get_header_buffer(key_data_payload->get_header_buffer_length())), + key_data_payload->get_header_buffer_length())); + } + else if (key_data_payload->get_descriptor_type() == eapol_RSNA_key_data_type_WPA_IE + && eapol_key_descriptor_type == eapol_key_descriptor_type_WPA) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s.\n"), + prefix, + key_data_payload, + key_data_payload->get_descriptor_type(), + key_data_payload->get_descriptor_type_string())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x, WPA IE.\n"), + prefix, + key_data_payload, + key_data_payload->get_header_and_body_length(), + buffer_length)); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: WPA IE"), + (key_data_payload->get_header_buffer(key_data_payload->get_header_buffer_length())), + key_data_payload->get_header_buffer_length())); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s.\n"), + prefix, + key_data_payload, + key_data_payload->get_descriptor_type(), + key_data_payload->get_descriptor_type_string())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x, Unknown data.\n"), + prefix, + key_data_payload, + key_data_payload->get_header_and_body_length(), + buffer_length)); + + u32_t max_length = (buffer_length < key_data_payload->get_header_buffer_length()) + ? buffer_length : key_data_payload->get_header_buffer_length(); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: Unknown data"), + (key_data_payload->get_header_buffer(max_length)), + max_length)); + } + +#endif //#if defined(USE_EAP_TRACE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_authenticator_RSNA_IE() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_authenticator_RSNA_IE; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_unicast_cipher_suite_RSNA_IE() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_unicast_cipher_suite_RSNA_IE; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_supplicant_RSNA_IE() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_supplicant_RSNA_IE; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_received_PMKID() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_received_PMKID; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_supplicant_MAC_address() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_supplicant_MAC_address; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_authenticator_MAC_address() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_authenticator_MAC_address; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u64_t eapol_key_state_c::get_key_reply_counter() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_key_reply_counter; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eapol_key_state_c::increase_key_reply_counter() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + ++m_key_reply_counter; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Incresed Local Reply Counter"), + &m_key_reply_counter, + sizeof(m_key_reply_counter))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eapol_key_state_c::set_key_reply_counter(const u64_t reply_counter) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_key_reply_counter = reply_counter; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Set Local Reply Counter"), + &m_key_reply_counter, + sizeof(m_key_reply_counter))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u64_t eapol_key_state_c::get_client_send_key_reply_counter() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_client_send_key_reply_counter; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eapol_key_state_c::increase_client_send_key_reply_counter() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + ++m_client_send_key_reply_counter; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Increased Client Send Reply Counter"), + &m_client_send_key_reply_counter, + sizeof(m_client_send_key_reply_counter))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eapol_key_state_c::set_client_send_key_reply_counter(const u64_t reply_counter) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_client_send_key_reply_counter = reply_counter; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Set Client Send Reply Counter"), + &m_client_send_key_reply_counter, + sizeof(m_client_send_key_reply_counter))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_ANonce() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_ANonce; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_SNonce() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_SNonce; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_confirmation_KCK() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_confirmation_KCK; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_encryption_KEK() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_encryption_KEK; +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::check_is_aes_key_wrap_padding( + const eapol_RSNA_key_descriptor_type_e /* current_key_data_type */, + eapol_rsna_key_data_header_c * const key_data_payload, + const u32_t key_data_max_length + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (key_data_max_length > 1ul) + { + u8_t * const data = key_data_payload->get_header_buffer(key_data_max_length); + + // The first byte is eapol_RSNA_key_data_type_RSN_key_data. + // The following padding bytes are zero bytes. + for (u32_t ind = 1ul; ind < key_data_max_length; ind++) + { + if (data[ind] != 0ul) + { + // Padding must be zero byte. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_illegal_padding; + } + } // for() + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::parse_generic_key_data_payload( + const eapol_key_descriptor_type_e eapol_key_descriptor_type, + const eapol_RSNA_key_descriptor_type_e current_key_descriptor_type, + eapol_rsna_key_data_header_c * const key_data_payload, + u32_t * const key_data_max_length, + eapol_rsna_key_data_payloads_c * const p_rsna_key_data_payloads, + const eapol_key_state_e expected_key_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD( + get_is_RSNA(), + get_is_WPXM(), + eapol_key_descriptor_type, + "eapol_key_state_c::parse_generic_key_data_payload(): Parsing EAPOL Key Data key_data_payload", + key_data_payload, + *key_data_max_length); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_key_state_c::parse_generic_key_data_payload()"); + + { + eapol_key_state_string_c debug_string; + EAP_UNREFERENCED_PARAMETER(debug_string); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("current key_data_payload_type 0x%04x=%s.\n"), + key_data_payload, + current_key_descriptor_type, + key_data_payload->get_descriptor_type_string())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("eapol_key_descriptor_type 0x%02x=%s.\n"), + key_data_payload, + eapol_key_descriptor_type, + debug_string.get_eapol_key_descriptor_type_string(eapol_key_descriptor_type))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("payload length is 0x%04x, key_data_max_length is 0x%08x.\n"), + key_data_payload, + key_data_payload->get_header_and_body_length(), + *key_data_max_length)); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("expected_key_message = %s = 0x%08x.\n"), + key_data_payload, + debug_string.get_eapol_key_state_string(expected_key_message), + expected_key_message)); + } + + if (get_is_RSNA() == true + && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA + && current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_key_data + && check_is_aes_key_wrap_padding( + current_key_descriptor_type, + key_data_payload, + *key_data_max_length) == eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): AES key wrapping padding\n"), + key_data_payload)); + + // This is AES key wrap padding. + *key_data_max_length = 0ul; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (*key_data_max_length < eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE + || key_data_payload->get_header_and_body_length() == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("current key_data_payload_type 0x%04x=%s, payload length is 0x%04x, key_data_max_length is 0x%08x.\n"), + key_data_payload, + current_key_descriptor_type, + key_data_payload->get_descriptor_type_string(), + key_data_payload->get_header_and_body_length(), + *key_data_max_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + if ((get_is_RSNA() == true + || get_is_WPXM() == true) + && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA + && current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_key_data) + { + eapol_RSNA_key_payload_type_e current_key_data_type = key_data_payload->get_payload_type(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): current_key_data_type = %s = 0x%02x\n"), + key_data_payload, + key_data_payload->get_payload_type_string(), + current_key_data_type)); + + if (current_key_data_type == eapol_RSNA_key_payload_type_group_key_and_id + && m_is_client == true + && (expected_key_message == eapol_key_state_wait_4_way_handshake_message_3 + || expected_key_message == eapol_key_state_wait_group_key_handshake_message_1)) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): Key ID and Group Key\n"), + key_data_payload)); + + /* Key ID and Group Key: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type = 0xdd | Length | OUI 3 octets ...| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ... OUI | Data Type 1 | Key ID and Tx | Reserved 0 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | GTK (Length - 6) octets | + * +- -+ + * : : + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (key_data_payload->get_key_data_payload_length() + < eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_ID_AND_GROUP_KEY_MINIMUM_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("current key_data_payload 0x%04x=%s, data length incorrect 0x%04x.\n"), + key_data_payload, + current_key_data_type, + key_data_payload->get_descriptor_type_string(), + key_data_payload->get_key_data_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + const u32_t buffer_length = key_data_payload->get_key_data_payload_length(); + + u8_t * const buffer + = static_cast(key_data_payload->get_key_data_payload(buffer_length)); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("current key_data_payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + key_data_payload, + current_key_data_type, + key_data_payload->get_payload_type_string(), + key_data_payload->get_key_data_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + eapol_rsna_key_data_gtk_header_c gtk_header( + m_am_tools, + buffer, + buffer_length); + if (gtk_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = gtk_header.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + p_rsna_key_data_payloads->set_group_key_id(gtk_header.get_key_index()); + p_rsna_key_data_payloads->set_group_key_tx(gtk_header.get_tx_bit()); + + u32_t group_key_header_length = eapol_rsna_key_data_gtk_header_c::get_header_length(); + + // Note here we get a reference to the data bytes of the received packet. + status = p_rsna_key_data_payloads->get_group_key()->set_buffer( + key_data_payload, + gtk_header.get_gtk(key_data_payload->get_key_data_payload_length()-group_key_header_length), + key_data_payload->get_key_data_payload_length()-group_key_header_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("received RSN Group Key ID %d, Tx %d\n"), + p_rsna_key_data_payloads->get_group_key_id(), + p_rsna_key_data_payloads->get_group_key_tx())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("received RSN Group Key"), + p_rsna_key_data_payloads->get_group_key()->get_data( + p_rsna_key_data_payloads->get_group_key()->get_data_length()), + p_rsna_key_data_payloads->get_group_key()->get_data_length())); + } + else if (current_key_data_type == eapol_RSNA_key_payload_type_sta_key) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): STAKey\n"), + key_data_payload)); + + /* STAKey: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type = 0xdd | Length | OUI 3 octets ...| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ... OUI | Data Type 2 | Ecrypted STAKey | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -+ + * : (Length - 4) octets : + * +- -+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (key_data_payload->get_key_data_payload_length() < eapol_rsna_key_data_header_c::EAPOL_RSNA_STAKEY_MINIMUM_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("current key_data_payload 0x%04x=%s, data length incorrect 0x%04x.\n"), + key_data_payload, current_key_data_type, key_data_payload->get_payload_type_string(), + key_data_payload->get_key_data_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(key_data_payload->get_key_data_payload( + key_data_payload->get_key_data_payload_length())); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("current key_data_payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + key_data_payload, + current_key_data_type, + key_data_payload->get_payload_type_string(), + key_data_payload->get_key_data_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + eap_status_e status = p_rsna_key_data_payloads->get_STAKey()->set_buffer( + key_data_payload, buffer, key_data_payload->get_key_data_payload_length(), false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (current_key_data_type == eapol_RSNA_key_payload_type_pmkid) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): PMKID\n"), + key_data_payload)); + + /* PMKID: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type = 0xdd | Length | OUI 3 octets ...| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ... OUI | Data Type 3 | PMKID plaintext | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -+ + * : (Length - 4) octets : + * +- -+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (key_data_payload->get_key_data_payload_length() < eapol_rsna_key_data_header_c::EAPOL_RSNA_PMKID_MINIMUM_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("current key_data_payload 0x%04x=%s, data length incorrect 0x%04x.\n"), + key_data_payload, current_key_data_type, key_data_payload->get_payload_type_string(), + key_data_payload->get_key_data_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(key_data_payload->get_key_data_payload( + key_data_payload->get_key_data_payload_length())); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("current key_data_payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + key_data_payload, + current_key_data_type, + key_data_payload->get_payload_type_string(), + key_data_payload->get_key_data_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + eap_status_e status = p_rsna_key_data_payloads->get_PMKID()->set_buffer( + key_data_payload, buffer, key_data_payload->get_key_data_payload_length(), false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (current_key_descriptor_type == eapol_RSNA_key_data_type_WPA_IE + && key_data_payload->get_header_and_body_length() >= eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): WPA Information element\n"), + key_data_payload)); + + /* This is WPA Information element. NOTE the 2 first bytes match with + * EAPOL Key Data Encapsulation format. + * + * 0 1 2 3 4 5 6 7 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Element ID 48=0x30 (WPA 221=0xdd) 1 octet | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Length 1 octet | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Version 2 octets | + * +- -+ + * | | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Group Key Cipher Suite 4 octets | + * +- -+ + * | optional | + * +- -+ + * | | + * +- -+ + * | | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Pairwise Key Cipher Suite Count (m) 2 octets | + * +- -+ + * | optional | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Pairwise Key Cipher Suite List m*4 octets | + * +- -+ + * | optional | + * +- -+ + * | | + * +- -+ + * | | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Authentication and Key Management Suite Count (n) 2 octets | + * +- -+ + * | optional | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Authentication and Key Management Suite List n*4 octets | + * +- -+ + * | optional | + * +- -+ + * | | + * +- -+ + * | | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | RSN Capabilities 2 octets | + * +- -+ + * | optional | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | PMKID Count (s) 2 octets | + * +- -+ + * | optional | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | PMKID List s*16 octets | + * +- -+ + * : optional : + * +- -+ + * | | + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + */ + + // The second byte is the length of the RSN IE. Also the Type and Length fields are included. + const u32_t length_of_the_RSN_IE = key_data_payload->get_header_and_body_length(); + + if (length_of_the_RSN_IE < eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("RSN IE length 0x%04x too less, at least 0x%04x bytes required.\n"), + key_data_payload, + length_of_the_RSN_IE, + eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + // RSN IE is the whole key_data_payload. + u8_t * buffer = reinterpret_cast(key_data_payload->get_header_buffer(length_of_the_RSN_IE)); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("current key_data_payload length 0x%04x data buffer incorrect.\n"), + key_data_payload, + length_of_the_RSN_IE)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const rsn_ie = new eap_variable_data_c(m_am_tools); + if (rsn_ie == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Parsed WPA IE"), + buffer, + length_of_the_RSN_IE)); + + // Note here we get a reference to the data bytes of the received packet. + eap_status_e status = rsn_ie->set_buffer( + buffer, + length_of_the_RSN_IE, + false, + false); + if (status != eap_status_ok) + { + delete rsn_ie; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // eap_array_c object will free rsn_ie. + status = p_rsna_key_data_payloads->get_RSN_IE()->add_object(rsn_ie, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Unknown payloads are quietly ignored. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(): ") + EAPL("Ignores unknown EAPOL Key Data type %d=0x%08x and payload %d=0x%08x, length %d.\n"), + current_key_descriptor_type, + current_key_descriptor_type, + current_key_data_type, + current_key_data_type, + key_data_payload->get_header_and_body_length())); + } + + *key_data_max_length -= key_data_payload->get_header_and_body_length(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (get_is_WPA() == true + && eapol_key_descriptor_type == eapol_key_descriptor_type_WPA + && expected_key_message == eapol_key_state_wait_group_key_handshake_message_1) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): GTK\n"), + key_data_payload)); + + // Data includes GTK. + // key_data_payload points to the GTK of length (*key_data_max_length). + + u8_t * const buffer + = reinterpret_cast(key_data_payload); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("length 0x%04x, data buffer incorrect.\n"), + key_data_payload, + *key_data_max_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + eap_status_e status = p_rsna_key_data_payloads->get_group_key()->set_buffer( + key_data_payload, buffer, + *key_data_max_length, false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("received WPA Group Key"), + p_rsna_key_data_payloads->get_group_key()->get_data( + p_rsna_key_data_payloads->get_group_key()->get_data_length()), + p_rsna_key_data_payloads->get_group_key()->get_data_length())); + + *key_data_max_length = 0ul; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if ((get_is_RSNA() == true + && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA + && current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_IE) + || (get_is_WPA() == true + && eapol_key_descriptor_type == eapol_key_descriptor_type_WPA + && current_key_descriptor_type == eapol_RSNA_key_data_type_WPA_IE) +#if defined(EAP_USE_WPXM) + || (get_is_WPXM() == true + && (current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_IE + || current_key_descriptor_type == eapol_RSNA_key_data_type_WPA_IE)) +#endif //#if defined(EAP_USE_WPXM) + ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): RSN Information element\n"), + key_data_payload)); + + /* This is RSN or WPA Information element. NOTE the 2 first bytes match with + * EAPOL Key Data Encapsulation format. + * + * 0 1 2 3 4 5 6 7 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Element ID 48=0x30 (WPA 221=0xdd) 1 octet | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Length 1 octet | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Version 2 octets | + * +- -+ + * | | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Group Key Cipher Suite 4 octets | + * +- -+ + * | optional | + * +- -+ + * | | + * +- -+ + * | | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Pairwise Key Cipher Suite Count (m) 2 octets | + * +- -+ + * | optional | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Pairwise Key Cipher Suite List m*4 octets | + * +- -+ + * | optional | + * +- -+ + * | | + * +- -+ + * | | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Authentication and Key Management Suite Count (n) 2 octets | + * +- -+ + * | optional | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Authentication and Key Management Suite List n*4 octets | + * +- -+ + * | optional | + * +- -+ + * | | + * +- -+ + * | | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | RSN Capabilities 2 octets | + * +- -+ + * | optional | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | PMKID Count (s) 2 octets | + * +- -+ + * | optional | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | PMKID List s*16 octets | + * +- -+ + * : optional : + * +- -+ + * | | + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + */ + + // The second byte is the length of the RSN IE. Also the Type and Length fields are included. + const u32_t length_of_the_RSN_IE = key_data_payload->get_header_and_body_length(); + + if (length_of_the_RSN_IE < eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("RSN IE length 0x%04x too less, at least 0x%04x bytes required.\n"), + key_data_payload, + length_of_the_RSN_IE, + eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + // RSN IE is the whole key_data_payload. + u8_t * buffer = reinterpret_cast(key_data_payload->get_header_buffer(length_of_the_RSN_IE)); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") + EAPL("current key_data_payload length 0x%04x data buffer incorrect.\n"), + key_data_payload, + length_of_the_RSN_IE)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const rsn_ie = new eap_variable_data_c(m_am_tools); + if (rsn_ie == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Parsed RSN IE"), + buffer, + length_of_the_RSN_IE)); + + // Note here we get a reference to the data bytes of the received packet. + eap_status_e status = rsn_ie->set_buffer( + buffer, + length_of_the_RSN_IE, + false, + false); + if (status != eap_status_ok) + { + delete rsn_ie; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // eap_array_c object will free rsn_ie. + status = p_rsna_key_data_payloads->get_RSN_IE()->add_object(rsn_ie, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + buffer += length_of_the_RSN_IE; + + *key_data_max_length -= length_of_the_RSN_IE; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + // Unknown payloads are quietly ignored. + eapol_RSNA_key_payload_type_e current_key_data_type = key_data_payload->get_payload_type(); + EAP_UNREFERENCED_PARAMETER(current_key_data_type); + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(): ") + EAPL("Unknown EAPOL Key Data type %d=0x%08x and payload %d=0x%08x, length %d.\n"), + current_key_descriptor_type, + current_key_descriptor_type, + current_key_data_type, + current_key_data_type, + key_data_payload->get_header_and_body_length())); + + *key_data_max_length -= key_data_payload->get_header_and_body_length(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::parse_key_data( + const eapol_key_descriptor_type_e eapol_key_descriptor_type, + const eapol_rsna_key_data_header_c * const p_payload, + u32_t * const buffer_length, + eapol_rsna_key_data_payloads_c * const p_rsna_key_data_payloads, + const eapol_key_state_e expected_key_message, + const eapol_RSNA_key_header_c::key_descriptor_version_e key_descriptor_version) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::parse_key_data()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_key_state_c::parse_key_data()"); + + eapol_rsna_key_data_header_c payload( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + p_payload->get_header_buffer(*buffer_length), + *buffer_length); // Const correctness is gone. + + eapol_RSNA_key_descriptor_type_e current_payload = payload.get_descriptor_type(); + + eap_status_e status = eap_status_header_corrupted; + + if (payload.get_is_valid() == true + && current_payload != eapol_RSNA_key_data_type_none) + { + + if (get_is_RSNA() == true + || expected_key_message != eapol_key_state_wait_group_key_handshake_message_1 // WPA must check the expected message. + ) + { + if (*buffer_length < payload.get_header_and_body_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(0x%08x): ") + EAPL("current payload 0x%04x=%s, payload length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload, + payload.get_payload_type_string(), + payload.get_header_and_body_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(): ") + EAPL("EAPOl Key Data-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + + status = parse_generic_key_data_payload( + eapol_key_descriptor_type, + current_payload, + &payload, + buffer_length, + p_rsna_key_data_payloads, + expected_key_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + while(*buffer_length >= payload.get_header_length() + && payload.get_is_valid() == true + && payload.get_header_buffer_length() + >= (payload.get_header_and_body_length())) + { + payload.set_header_buffer( + payload.get_next_header(), + payload.get_header_buffer_length() + -(payload.get_header_and_body_length())); + if (payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + current_payload = payload.get_descriptor_type(); + + if (*buffer_length < payload.get_header_and_body_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(0x%08x): ") + EAPL("current payload 0x%04x=%s, payload length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload, + payload.get_payload_type_string(), + payload.get_header_and_body_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(): ") + EAPL("EAPOl Key Data-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_key_data_payload( + eapol_key_descriptor_type, + current_payload, + &payload, + buffer_length, + p_rsna_key_data_payloads, + expected_key_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + if (*buffer_length != 0u) + { + if (key_descriptor_version == eapol_RSNA_key_header_c::m_key_descriptor_version_1) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(): ") + EAPL("EAPOl Key Data-header is corrupted. Buffer length ") + EAPL("and payload length does not match. %lu illegal bytes.\n"), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::rsna_prf( + const eap_variable_data_c * const key_K, + const eap_variable_data_c * const label_A, + const eap_variable_data_c * const input_B, + const u32_t output_length_bits, + eap_variable_data_c * const output + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + crypto_sha1_c sha1(m_am_tools); + status = sha1.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + crypto_hmac_c hmac(m_am_tools, &sha1, false); + + if (hmac.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t required_digest_count = (output_length_bits+159)/160; + u32_t required_buffer_length = hmac.get_digest_length()*required_digest_count; + u32_t required_octet_count = output_length_bits/8ul; + + output->reset(); + status = output->set_buffer_length(required_buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + output->set_data_length(output->get_buffer_length()); + + eap_variable_data_c input(m_am_tools); + if (input.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u8_t zero = 0ul; + + status = input.set_buffer_length( + label_A->get_data_length() + + sizeof(zero) + + input_B->get_data_length() + + sizeof(u8_t)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (u8_t ind = 0ul; ind < required_digest_count; ind++) + { + status = input.reset_start_offset_and_data_length(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac.hmac_set_key(key_K); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (label_A->get_is_valid_data() == true) + { + status = input.add_data(label_A); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = input.add_data(&zero, sizeof(zero)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = input.add_data(input_B); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = input.add_data(&ind, sizeof(ind)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac.hmac_update( + input.get_data(input.get_data_length()), + input.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t md_length = hmac.get_digest_length(); + + status = hmac.hmac_final( + output->get_data_offset( + ind*hmac.get_digest_length(), + hmac.get_digest_length()), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } // for() + + output->set_data_length(required_octet_count); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::select_minimum( + const eap_variable_data_c * const input_a, + const eap_variable_data_c * const input_b, + const eap_variable_data_c ** const minimum, + const eap_variable_data_c ** const maximum) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (input_a == 0 + || input_b == 0 + || minimum == 0 + || maximum == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (input_a->get_data_length() > input_b->get_data_length()) + { + *minimum = input_b; + *maximum = input_a; + } + else if (input_a->get_data_length() < input_b->get_data_length()) + { + *minimum = input_a; + *maximum = input_b; + } + else + { + const i32_t cmp = input_a->compare(input_b); + if (cmp < 0) + { + *minimum = input_a; + *maximum = input_b; + } + else // if (cmp >= 0) NOTE this includes equal case too. + { + *minimum = input_b; + *maximum = input_a; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::derive_PTK() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::derive_PTK(): %s\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = eap_status_process_general_error; + + if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ") + EAPL("Pairwise Master Key (PMK) is missing.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_supplicant_MAC_address.get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ") + EAPL("Supplicant MAC address is missing.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_authenticator_MAC_address.get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ") + EAPL("Authenticator MAC address is missing.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_ANonce.get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ") + EAPL("Authenticator nonce (ANonce) is missing.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_SNonce.get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ") + EAPL("Supplicant nonce (m_SNonce) is missing.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key m_supplicant_MAC_address"), + m_supplicant_MAC_address.get_data(m_supplicant_MAC_address.get_data_length()), + m_supplicant_MAC_address.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key m_authenticator_MAC_address"), + m_authenticator_MAC_address.get_data(m_authenticator_MAC_address.get_data_length()), + m_authenticator_MAC_address.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key m_SNonce"), + m_SNonce.get_data(m_SNonce.get_data_length()), + m_SNonce.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key m_ANonce"), + m_ANonce.get_data(m_ANonce.get_data_length()), + m_ANonce.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key m_pairwise_PMK_WPXK3"), + m_pairwise_PMK_WPXK3.get_data(m_pairwise_PMK_WPXK3.get_data_length()), + m_pairwise_PMK_WPXK3.get_data_length())); + + + const eap_variable_data_c * minimum_MAC_address = 0; + const eap_variable_data_c * maximum_MAC_address = 0; + const eap_variable_data_c * minimum_nonce = 0; + const eap_variable_data_c * maximum_nonce = 0; + + status = select_minimum( + &m_supplicant_MAC_address, + &m_authenticator_MAC_address, + &minimum_MAC_address, + &maximum_MAC_address); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = select_minimum( + &m_ANonce, + &m_SNonce, + &minimum_nonce, + &maximum_nonce); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + + eap_variable_data_c input(m_am_tools); + + status = input.set_buffer_length( + minimum_MAC_address->get_data_length() + + maximum_MAC_address->get_data_length() + + minimum_nonce->get_data_length() + + maximum_nonce->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = input.add_data(minimum_MAC_address); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = input.add_data(maximum_MAC_address); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = input.add_data(minimum_nonce); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = input.add_data(maximum_nonce); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Default is TKIP. + u32_t PTK_length = EAPOL_RSNA_TKIP_PTK_LENGTH_BITS; + u32_t tk_length_bytes = EAPOL_RSNA_TKIP_TK_LENGTH_BYTES; + + if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) + { + PTK_length = EAPOL_RSNA_CCMP_PTK_LENGTH_BITS; + tk_length_bytes = EAPOL_RSNA_CCMP_TK_LENGTH_BYTES; + } + else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40) + { + tk_length_bytes = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_40; + } + else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104) + { + tk_length_bytes = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_104; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c label(m_am_tools); + + status = label.set_copy_of_buffer( + EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL, + EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rsna_prf( + &m_pairwise_PMK_WPXK3, + &label, + &input, + PTK_length, + &m_transient_PTK); + if (status != eap_status_ok) + { + m_transient_PTK.reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Split PTK to KCK, KEK and TK. + status = m_confirmation_KCK.set_buffer( + m_transient_PTK.get_data_offset(EAPOL_RSNA_KCK_OFFSET_BYTES, EAPOL_RSNA_KCK_LENGTH_BYTES), + EAPOL_RSNA_KCK_LENGTH_BYTES, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_encryption_KEK.set_buffer( + m_transient_PTK.get_data_offset(EAPOL_RSNA_KEK_OFFSET_BYTES, EAPOL_RSNA_KEK_LENGTH_BYTES), + EAPOL_RSNA_KEK_LENGTH_BYTES, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_temporal_TK.set_buffer( + m_transient_PTK.get_data_offset(EAPOL_RSNA_TK_OFFSET_BYTES, tk_length_bytes), + tk_length_bytes, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key KCK"), + m_confirmation_KCK.get_data(m_confirmation_KCK.get_data_length()), + m_confirmation_KCK.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key KEK"), + m_encryption_KEK.get_data(m_encryption_KEK.get_data_length()), + m_encryption_KEK.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key TK"), + m_temporal_TK.get_data(m_temporal_TK.get_data_length()), + m_temporal_TK.get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::create_nonce( + eap_variable_data_c * const nonce, const u32_t nonce_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::create_nonce(): %s\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = eap_status_process_general_error; + + status = nonce->set_buffer_length(nonce_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + nonce->set_data_length(nonce_length); + + crypto_random_c rand(m_am_tools); + + if (rand.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = rand.get_rand_bytes( + nonce->get_data(nonce->get_data_length()), + nonce->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key new nonce"), + nonce->get_data(nonce->get_data_length()), + nonce->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::create_PMKID() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_PMKID(): ") + EAPL("Pairwise Master Key (PMK) is missing.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_supplicant_MAC_address.get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_PMKID(): ") + EAPL("Supplicant MAC address is missing.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_authenticator_MAC_address.get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_PMKID(): ") + EAPL("Authenticator MAC address is missing.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + crypto_sha1_c sha1(m_am_tools); + + status = sha1.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + crypto_hmac_c hmac(m_am_tools, &sha1, false); + + if (hmac.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = hmac.hmac_set_key(&m_pairwise_PMK_WPXK3); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac.hmac_update( + EAPOL_RSNA_PMK_NAME_LABEL, + EAPOL_RSNA_PMK_NAME_LABEL_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac.hmac_update( + m_authenticator_MAC_address.get_data(m_authenticator_MAC_address.get_data_length()), + m_authenticator_MAC_address.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac.hmac_update( + m_supplicant_MAC_address.get_data(m_supplicant_MAC_address.get_data_length()), + m_supplicant_MAC_address.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + { + m_PMKID.reset(); + + status = m_PMKID.set_buffer_length(hmac.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_PMKID.set_data_length(hmac.get_digest_length()); + + u32_t md_length = hmac.get_digest_length(); + + status = hmac.hmac_final( + m_PMKID.get_data(hmac.get_digest_length()), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (md_length < eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + // This cuts the PMKID to 128 bits. + m_PMKID.set_data_length(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key PMKID"), + m_PMKID.get_data(), + m_PMKID.get_data_length())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::encrypt_key_data( + eapol_RSNA_key_header_c * const eapol_key_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + if (m_encryption_KEK.get_is_valid_data() == false + || m_encryption_KEK.get_data_length() == 0ul) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::encrypt_key_data(): ") + EAPL("m_encryption_KEK is missing or corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + if (m_eapol_pairwise_cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP + || m_eapol_group_cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: AES-WRAP encryption algorithm.\n"))); + + crypto_aes_wrap_c aes_wrap(m_am_tools); + + if (aes_wrap.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = aes_wrap.set_encryption_key( + m_encryption_KEK.get_data(), + m_encryption_KEK.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t padding_length(0ul); + u32_t min_key_data_length = 2ul * aes_wrap.get_block_size(); + + if (eapol_key_message->get_key_data_length() < min_key_data_length) + { + padding_length = min_key_data_length - eapol_key_message->get_key_data_length(); + } + else if ((eapol_key_message->get_key_data_length() % aes_wrap.get_block_size()) != 0) + { + padding_length = aes_wrap.get_block_size() + - (eapol_key_message->get_key_data_length() % aes_wrap.get_block_size()); + } + + u32_t padding_offset = eapol_key_message->get_key_data_length(); + + // AES-Wrap increases message length with one block. + status = eapol_key_message->set_key_data_length( + static_cast(eapol_key_message->get_key_data_length() + + padding_length + + aes_wrap.get_block_size())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (padding_length > 0ul) + { + aes_wrap.add_padding_bytes( + eapol_key_message->get_key_data_offset( + padding_offset, + padding_length), + padding_length); + } + + if (eapol_key_message->get_key_data_length() < aes_wrap.get_block_size()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = aes_wrap.encrypt_block( + eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), + eapol_key_message->get_key_data_length()-aes_wrap.get_block_size(), + eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), + eapol_key_message->get_key_data_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP + || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40 + || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: RC4 encryption algorithm.\n"))); + + if (m_EAPOL_key_IV.get_is_valid_data() == false + || m_EAPOL_key_IV.get_data_length() == 0ul) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::encrypt_key_data(): ") + EAPL("m_EAPOL_key_IV is missing or corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + abs_crypto_stream_algorithm_c * const rc4 = new crypto_rc4_c(m_am_tools); + eap_automatic_variable_c automatic_rc4(m_am_tools, rc4); + + if (rc4 == 0 + || rc4->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c key(m_am_tools); + + status = key.set_copy_of_buffer(&m_EAPOL_key_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = key.add_data(&m_encryption_KEK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key encrypt key"), + key.get_data(key.get_data_length()), + key.get_data_length())); + + status = rc4->set_key(&key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // The first 256 octets of RC4 key stream are discarded. + status = rc4->discard_stream(EAPOL_RSNA_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key plaintext data"), + eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), + eapol_key_message->get_key_data_length())); + + status = rc4->encrypt_data( + eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), + eapol_key_message->get_key_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key encrypted data"), + eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), + eapol_key_message->get_key_data_length())); + + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::decrypt_key_data( + eapol_RSNA_key_header_c * const eapol_key_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + + if (m_eapol_pairwise_cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP + || m_eapol_group_cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: AES-WRAP decryption algorithm.\n"))); + + crypto_aes_wrap_c aes_wrap(m_am_tools); + + if (aes_wrap.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = aes_wrap.set_decryption_key( + m_encryption_KEK.get_data(), + m_encryption_KEK.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = aes_wrap.decrypt_block( + eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), + eapol_key_message->get_key_data_length(), + eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), + eapol_key_message->get_key_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // AES-Wrap increases message length with one block. + // Here we remove the block. + status = eapol_key_message->set_key_data_length( + static_cast(eapol_key_message->get_key_data_length() + - aes_wrap.get_block_size())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP + || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40 + || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: RC4 decryption algorithm.\n"))); + + abs_crypto_stream_algorithm_c * const rc4 = new crypto_rc4_c(m_am_tools); + eap_automatic_variable_c automatic_rc4(m_am_tools, rc4); + + if (rc4 == 0 + || rc4->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c key(m_am_tools); + + status = key.set_copy_of_buffer(&m_EAPOL_key_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = key.add_data(&m_encryption_KEK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key decrypt key"), + key.get_data(key.get_data_length()), + key.get_data_length())); + + status = rc4->set_key(&key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // The first 256 octets of RC4 key stream are discarded. + status = rc4->discard_stream(EAPOL_RSNA_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key encrypted data"), + eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), + eapol_key_message->get_key_data_length())); + + status = rc4->decrypt_data( + eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), + eapol_key_message->get_key_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key plaintext data"), + eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), + eapol_key_message->get_key_data_length())); + + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + +// +eap_status_e eapol_key_state_c::create_key_mic( + eapol_RSNA_key_header_c * const eapol_key_message, + const eap_variable_data_c * const confirmation_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + if (eapol_key_message == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (confirmation_key->get_is_valid_data() == false + || confirmation_key->get_data_length() == 0ul) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_key_mic(): ") + EAPL("confirmation_key is missing or corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = eapol_key_message->zero_key_MIC(m_am_tools); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + crypto_hmac_c * hmac = 0; + abs_crypto_hash_algorithm_c * hash = 0; + + if (m_eapol_pairwise_cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP + || m_eapol_group_cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: HMAC-SHA1 MIC algorithm.\n"))); + + hash = new crypto_sha1_c(m_am_tools); + } + else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP + || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40 + || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: HMAC-MD5 MIC algorithm.\n"))); + + hash = new crypto_md5_c(m_am_tools); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + eap_automatic_variable_c automatic_hash(m_am_tools, hash); + + if (hash == 0 + || hash->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + hmac = new crypto_hmac_c(m_am_tools, hash, true); + automatic_hash.do_not_free_variable(); + eap_automatic_variable_c automatic_hmac(m_am_tools, hmac); + if (hmac == 0 + || hmac->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key MIC key"), + confirmation_key->get_data(), + confirmation_key->get_data_length())); + + status = hmac->hmac_set_key(confirmation_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // MIC is calculated over the whole EAPOL-Key message. + status = hmac->hmac_update( + eapol_key_message->get_header_buffer( + eapol_key_message->get_header_buffer_length()), + eapol_key_message->get_eapol_packet_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key MIC data"), + eapol_key_message->get_header_buffer( + eapol_key_message->get_header_buffer_length()), + eapol_key_message->get_eapol_packet_length())); + + + { + eap_variable_data_c mic(m_am_tools); + + status = mic.set_buffer_length(hmac->get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + mic.set_data_length(hmac->get_digest_length()); + + u32_t md_length = hmac->get_digest_length(); + + status = hmac->hmac_final( + mic.get_data(hmac->get_digest_length()), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (md_length < eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + // This cuts the PMKID to 128 bits. + mic.set_data_length(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE); + + // Copy MIC to EAPOL-Key message. + m_am_tools->memmove( + eapol_key_message->get_key_MIC(), + mic.get_data(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL-Key message"), + eapol_key_message->get_header_buffer( + eapol_key_message->get_header_buffer_length()), + eapol_key_message->get_eapol_packet_length())); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::verify_key_mic( + eapol_RSNA_key_header_c * const eapol_key_message, + const eap_variable_data_c * const confirmation_key) +{ + eap_variable_data_c original_MIC(m_am_tools); + + // Here we save the original received MIC. + eap_status_e status = original_MIC.set_copy_of_buffer( + eapol_key_message->get_key_MIC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This function writes a new MIC to message. + status = create_key_mic( + eapol_key_message, + confirmation_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This will compare the saved original MIC and new created MIC are the same. + if (m_am_tools->memcmp( + original_MIC.get_data(original_MIC.get_data_length()), + eapol_key_message->get_key_MIC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE) != 0) + { + // MIC failure. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: MIC failed.\n"))); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Received MIC"), + original_MIC.get_data(original_MIC.get_data_length()), + original_MIC.get_data_length())); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL(" Local MIC"), + eapol_key_message->get_key_MIC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: MIC OK.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::add_RSN_GTK_payload( + const eapol_RSNA_key_header_c * const eapol_key_message, + eap_variable_data_c * const group_GTK, + u32_t * const eapol_data_length) +{ + // Add GTK to Key Data. + + if (eapol_key_message == 0 + || eapol_key_message->get_is_valid() == false + || group_GTK == 0 + || group_GTK->get_is_valid_data() == false + || eapol_data_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t GTK_length = group_GTK->get_data_length(); + + u32_t gtk_data_length = + eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_ID_AND_GROUP_KEY_HEADER_SIZE + + GTK_length; + + u32_t key_data_buffer_length = + eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_HEADER_LENGTH + + gtk_data_length; + + eapol_rsna_key_data_header_c key_data_header( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + eapol_key_message->get_key_data_offset(*eapol_data_length, key_data_buffer_length), + key_data_buffer_length); + if (key_data_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = key_data_header.reset_header(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // Here Type and Length fields are NOT included. + u32_t key_data_length = + key_data_buffer_length + - 2ul; + + if (key_data_length > 0xff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + status = key_data_header.set_length( + static_cast(key_data_length)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = key_data_header.set_payload_type(eapol_RSNA_key_payload_type_group_key_and_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RSN Group Key"), + group_GTK->get_data(GTK_length), + GTK_length)); + + if (gtk_data_length == GTK_length + eapol_rsna_key_data_gtk_header_c::get_header_length()) + { + // Add authenticator GTK to Key Data. + eapol_rsna_key_data_gtk_header_c gtk_header( + m_am_tools, + key_data_header.get_key_data_payload(gtk_data_length), + gtk_data_length); + if (gtk_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = gtk_header.reset_header(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_group_GTK_ID = 1ul; + status = gtk_header.set_key_index(m_group_GTK_ID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_group_GTK_Tx_bit = true; + status = gtk_header.set_tx(m_group_GTK_Tx_bit); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * data_field_of_GTK + = gtk_header.get_gtk(GTK_length); + if (data_field_of_GTK == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + data_field_of_GTK, + group_GTK->get_data(GTK_length), + GTK_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send RSN Group Key ID %d, Tx %d\n"), + gtk_header.get_key_index(), + gtk_header.get_tx_bit())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send RSN Group Key payload"), + gtk_header.get_header_buffer(gtk_header.get_header_buffer_length()), + gtk_header.get_header_buffer_length())); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *eapol_data_length += key_data_buffer_length; + + EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD( + get_is_RSNA(), + get_is_WPXM(), + eapol_key_message->get_key_descriptor_type(), + "Added EAPOL Key Data key_data_payload", + &key_data_header, + *eapol_data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::add_RSN_IE_payload( + const eapol_RSNA_key_header_c * const eapol_key_message, + eap_variable_data_c * const RSNA_IE, + u32_t * const eapol_data_length) +{ + // Add RSN IE to Key Data. + + if (eapol_key_message == 0 + || eapol_key_message->get_is_valid() == false + || RSNA_IE == 0 + || RSNA_IE->get_is_valid_data() == false + || eapol_data_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t rsn_ie_data_length(RSNA_IE->get_data_length()); + + u8_t * const data_field_of_RSN_IE + = reinterpret_cast( + eapol_key_message->get_key_data_offset(*eapol_data_length, rsn_ie_data_length)); + if (data_field_of_RSN_IE == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + data_field_of_RSN_IE, + RSNA_IE->get_data(rsn_ie_data_length), + rsn_ie_data_length); + + // NOTE, only two first bytes of RSN IE match with EAPOL Key Data. + eapol_rsna_key_data_header_c key_data_header( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + data_field_of_RSN_IE, + rsn_ie_data_length); + if (key_data_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *eapol_data_length += rsn_ie_data_length; + + EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD( + get_is_RSNA(), + get_is_WPXM(), + eapol_key_message->get_key_descriptor_type(), + "Added EAPOL RSN IE", + &key_data_header, + *eapol_data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::process_eapol_key_frame( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_not_supported; + + if (packet_length < eapol_header_wr_c::get_header_length() + || packet_data->get_header_buffer_length() < eapol_header_wr_c::get_header_length() + || packet_data->get_header_buffer_length() < packet_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c: process_eapol_key_frame(): m_pairwise_PMK_WPXK3 is not valid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); + } + + eapol_header_wr_c eapol_header( + m_am_tools, + packet_data->get_header_buffer(packet_data->get_header_buffer_length()), + packet_data->get_header_buffer_length()); + if (eapol_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (eapol_header.check_header() != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Data length must be at least size of Descriptor Type. + const u32_t EAPOL_DESCRIPTOR_TYPE_LENGTH = sizeof(u8_t); + if (eapol_header.get_data_length() < EAPOL_DESCRIPTOR_TYPE_LENGTH) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + const u8_t * const descriptor_type = eapol_header.get_data(EAPOL_DESCRIPTOR_TYPE_LENGTH); + if (descriptor_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + switch(static_cast(*descriptor_type)) + { + case eapol_key_descriptor_type_RC4: + status = process_RC4_key_descriptor(receive_network_id, packet_data, packet_length); + break; + case eapol_key_descriptor_type_RSNA: + case eapol_key_descriptor_type_WPA: + status = process_RSNA_key_descriptor(receive_network_id, packet_data, packet_length); + break; + default: + status = eap_status_not_supported; + break; + } + + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(packet_data, false); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eapol_key_state_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eapol_key_state_c::object_increase_reference_count() +{ + // Do nothing. +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eapol_key_state_c::object_decrease_reference_count() +{ + // Do nothing. + return 0ul; +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_encryption_on() +{ + /** + * @{ Add functionality of get_is_encryption_on() function } + */ + return false; +} + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + +EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_associated() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::get_is_associated(): m_is_associated=%s.\n"), + (m_is_client == true) ? "client": "server", + (m_is_associated == true) ? "true": "false")); + + return m_is_associated; +} + +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eapol_key_state_c::set_eapol_key_state(const eapol_key_state_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eapol_key_state_string_c state_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::set_eapol_key_state(): set_eapol_key_state() from %s to %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(m_eapol_key_state), + state_string.get_eapol_key_state_string(state))); + + m_eapol_key_state = state; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_key_state_e eapol_key_state_c::get_eapol_key_state() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_eapol_key_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + cancel_retransmission(); + + if (m_is_client == false + && sent_packet->get_do_packet_retransmission() == true) + { + // Only EAPOL-server initializes re-transmission. + // EAPOL-server will re-transmit the packet when timer elapses and no response is received. + init_retransmission( + send_network_id, + sent_packet, + header_offset, + data_length, + eap_code_none, + 0ul, + eap_type_none); + } + + + // NOTE: send packet directly to partner object of eapol_core_c object. + eap_status_e status = m_eapol_partner->packet_send( + send_network_id, + sent_packet, + header_offset, + data_length, + buffer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::resend_packet( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("<- EAPOL_KEY: %s: eapol_key_state_c::resend_packet().\n"), + (m_is_client == true) ? "client": "server")); + + // We make a copy because random error test may corrupt the data. + eap_buf_chain_wr_c * const copy_packet = sent_packet->copy(); + + if (copy_packet == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT(m_eapol_header_offset < sent_packet->get_data_length()); + EAP_ASSERT(data_length <= sent_packet->get_data_length()); + EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); + + // NOTE: send packet directly to partner object of eapol_core_c object. + // This will skip initialization of re-transmission for re-transmitted packet. + eap_status_e status = m_eapol_partner->packet_send( + send_network_id, + copy_packet, + header_offset, + data_length, + buffer_length + ); + + delete copy_packet; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_handshake_timeout() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_handshake_timeout_set = false; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_handshake_timeout(): this = 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + this)); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID cancelled.\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_handshake_timeout( + const u32_t timeout) +{ + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_handshake_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()), + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type))); + + if (m_handshake_timeout_set == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::init_handshake_timeout(): Already active.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + m_handshake_timeout_set = true; + + eap_status_e status = m_key_state_partner->set_timer( + this, + EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID, + 0, + timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID set %d ms.\n"), + (m_is_client == true ? "client": "server"), + timeout)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eapol_key_state_c::cancel_reassociate_timeout() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_reassociate_timeout(): this = 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + this)); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID cancelled.\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eapol_key_state_c::init_reassociate_timeout( + const u32_t timeout) +{ + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_reassociate_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()), + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type))); + + eap_status_e status = m_key_state_partner->set_timer( + this, + EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID, + 0, + timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID set %d ms.\n"), + (m_is_client == true ? "client": "server"), + timeout)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eapol_key_state_c::cancel_4_way_handshake_start_timeout() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_4_way_handshake_start_timeout(): this = 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + this)); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID cancelled.\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eapol_key_state_c::init_4_way_handshake_start_timeout() +{ + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_4_way_handshake_start_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()), + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type))); + + eap_status_e status = m_key_state_partner->set_timer( + this, + EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID, + 0, + EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID set %d ms.\n"), + (m_is_client == true ? "client": "server"), + EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_pmksa_caching_timeout() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_pmksa_caching_timeout(): this = 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + this)); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID cancelled.\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_authentication_session() +{ + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_authentication_session(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()), + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type))); + + eap_status_e status(eap_status_process_general_error); + + // RSNA could cache the current PMKSA. + status = init_pmksa_caching_timeout(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_pmksa_caching_timeout() +{ + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_pmksa_caching_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()), + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type))); + + eap_status_e status(eap_status_process_general_error); + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + { + m_is_associated = false; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_pmksa_caching_timeout(): m_is_associated=%s.\n"), + (m_is_client == true) ? "client": "server", + (m_is_associated == true) ? "true": "false")); + } +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + if ((m_authentication_type == eapol_key_authentication_type_RSNA_EAP +#if defined(EAP_USE_WPXM) + || get_is_WPXM() == true +#endif //#if defined(EAP_USE_WPXM) + ) + && (get_eapol_key_state() == eapol_key_state_4_way_handshake_successfull + || get_eapol_key_state() == eapol_key_state_group_key_handshake_successfull + || get_eapol_key_state() == eapol_key_state_preauthenticated +#if defined(EAP_USE_WPXM) + || get_eapol_key_state() == eapol_key_state_wpxm_reassociation_finished_successfull +#endif //#if defined(EAP_USE_WPXM) + )) + { + set_eapol_key_state(eapol_key_state_preauthenticated); + reset_cached_pmksa(); + + u32_t timeout(m_pmksa_caching_timeout); + +#if defined(EAP_USE_WPXM) + if (get_is_WPXM() == true) + { + timeout = EAPOL_KEY_STATE_TIMER_WPXM_CACHE_TIMEOUT; + } +#endif //#if defined(EAP_USE_WPXM) + + status = m_key_state_partner->set_timer( + this, + EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID, + 0, + timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID set %d ms.\n"), + (m_is_client == true ? "client": "server"), + m_pmksa_caching_timeout)); + + set_eapol_key_state(eapol_key_state_preauthenticated); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: Removes PMKSA cache\n"), + (m_is_client == true ? "client": "server"))); + + // Other authentication modes do not use PMKSA cache, clean-up state. + reset(); + + // Timeout value zero will remove state immediately. + status = init_handshake_timeout(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_retransmission() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (m_is_client == false) + { + // Only EAP-server uses timer to re-transmits EAP-packets. + m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID); + } + + if (m_retransmission != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID cancelled.\n"))); + + if (m_retransmission != 0) + { + delete m_retransmission; + m_retransmission = 0; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_retransmission( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const eap_code_value_e eap_code, + const u8_t eap_identifier, + const eap_type_value_e eap_type + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (m_retransmission_time == 0u + || m_retransmission_counter == 0u) + { + // No retransmission. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + EAP_ASSERT(send_network_id->get_source() != 0); + EAP_ASSERT(send_network_id->get_destination() != 0); + + if (m_is_client == false) + { + // Only EAP-server uses timer to re-transmits EAP-packets. + m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID); + } + + if (m_retransmission != 0) + { + delete m_retransmission; + m_retransmission = 0; + } + + m_retransmission = new eap_core_retransmission_c( + m_am_tools, + send_network_id, + sent_packet, + header_offset, + data_length, + m_retransmission_time, + m_retransmission_counter, + eap_code, + eap_identifier, + eap_type + ); + + if (m_retransmission == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_retransmission->get_is_valid() == true) + { + // Because this object do re-transmission other layers must not do re-transmission of this packet. + sent_packet->set_do_packet_retransmission(false); + + if (m_is_client == false) + { + // Only EAP-server uses timer to re-transmits EAP-packets. + u32_t next_retransmission_time(m_retransmission->get_next_retransmission_time()); + + eap_status_e status = m_key_state_partner->set_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID, 0, + next_retransmission_time); + if (status != eap_status_ok) + { + delete m_retransmission; + m_retransmission = 0; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID set %d ms.\n"), + next_retransmission_time)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + else + { + delete m_retransmission; + m_retransmission = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_group_key_update_timeout() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_group_key_update_timeout(): this = 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + this)); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID cancelled.\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_group_key_update_timeout( + const u32_t timeout) +{ + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_group_key_update_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()), + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type))); + + eap_status_e status = m_key_state_partner->set_timer( + this, + EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID, + 0, + timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID set %d ms.\n"), + (m_is_client == true ? "client": "server"), + timeout)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eapol_key_state_c::get_marked_removed() +{ + return m_marked_removed; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eapol_key_state_c::set_marked_removed() +{ + m_marked_removed = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eapol_key_state_c::unset_marked_removed() +{ + m_marked_removed = false; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::reset_cached_pmksa() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eapol_key_state_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::reset_cached_pmksa(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_eapol_key_state(), + state_string.get_eapol_key_state_string(get_eapol_key_state()), + m_authentication_type, + state_string.get_eapol_key_authentication_type_string(m_authentication_type))); + + eap_status_e status = eap_status_ok; + + for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++) + { + m_received_802_1x_keys[key_type] = false; + } + + (void) cancel_retransmission(); + (void) cancel_handshake_timeout(); + (void) cancel_pmksa_caching_timeout(); + (void) cancel_reassociate_timeout(); + (void) cancel_4_way_handshake_start_timeout(); + + if (get_eapol_key_state() == eapol_key_state_preauthenticated) + { + // We must save the preauthenticated PMK and authentication type. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::reset_cached_pmksa(): OK save PMKSA.\n"), + (m_is_client == true) ? "client": "server")); + } + else + { + // In other states PMK and authentication type is reset. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: eapol_key_state_c::reset_cached_pmksa(): removes PMKSA.\n"), + (m_is_client == true) ? "client": "server")); + + if (m_is_client == true) + { + // Only client resets these pameters, test server will need these parameters. + + m_pairwise_PMK_WPXK3.reset(); + + // Cannot reset m_authentication_type and m_eapol_key_state. These are needed later when possible error notification is send to lower layer. + + m_supplicant_MAC_address.reset(); + m_authenticator_MAC_address.reset(); + + m_eapol_pairwise_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_none; + m_eapol_group_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_none; + + m_authenticator_RSNA_IE.reset(); + m_supplicant_RSNA_IE.reset(); + +#if defined(EAP_USE_WPXM) + m_WPXM_WPXK1.reset(); + m_WPXM_WPXK2.reset(); + m_WPXM_WPXC = eapol_key_constant_wpxm_initial_wpxc_counter_value; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::reset_cached_pmksa(): ") + EAPL("Reset m_WPXM_WPXC=%d.\n"), + m_WPXM_WPXC)); +#endif //#if defined(EAP_USE_WPXM) + + } + else + { + set_eapol_key_state(eapol_key_state_none); + } + + m_PMKID.reset(); + m_transient_PTK.reset(); + m_confirmation_KCK.reset(); + m_encryption_KEK.reset(); + m_temporal_TK.reset(); + + // Cannot remove m_send_network_id because it is used + // as a reference of this eapol_key_state_c object. + + m_ANonce.reset(); + m_SNonce.reset(); + + } + + m_received_PMKID.reset(); + m_unicast_cipher_suite_RSNA_IE.reset(); + m_EAPOL_key_IV.reset(); + + if (m_is_client == true) + { + set_key_reply_counter(0ul); + set_client_send_key_reply_counter(0ul); + + // Cannot reset m_eapol_key_handshake_type. This is needed later when possible error notification is send to lower layer. + } + else + { + m_eapol_key_handshake_type = eapol_key_handshake_type_none; + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::reset(): this = 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + this)); + + eap_status_e status = reset_cached_pmksa(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::create_tkip_mic_failure_message( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type, + const eapol_protocol_version_e received_eapol_version) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::create_tkip_mic_failure_message()\n"), + (m_is_client == true ? "client": "server"))); + + // Only client (Supplicant) could create TKIP MIC failure message. + EAP_ASSERT_ALWAYS(m_is_client == true); + + u32_t eapol_key_data_length + = eapol_RSNA_key_header_c::get_header_length(); + + *buffer_length + = eapol_header_offset + + eapol_key_data_length; + + status = sent_packet->set_buffer_length( + *buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sent_packet->set_data_length( + sent_packet->get_buffer_length()); + + eapol_RSNA_key_header_c eapol_key_message( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + sent_packet->get_data_offset(eapol_header_offset, eapol_key_data_length), + sent_packet->get_data_length()); + + if (eapol_key_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + bool pairwise_key = true; + if (tkip_mic_failure_type == eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_group_key) + { + pairwise_key = false; + } + + status = eapol_key_message.reset_header( + 0ul, + m_authentication_type, + m_eapol_pairwise_cipher, + get_client_send_key_reply_counter(), + pairwise_key, // Pairwise key type bit. + false, // Install bit is NOT set. + false, // Key Ack bit is NOT set. + true, // Key MIC bit is on. + false, // Secure bit is NOT set. + true, // Error bit is on. + true, // Request bit is on. + false, // STAKey bit is NOT set. + false, // Encrypted Key Data bit is NOT set. + received_eapol_version, + eapol_key_descriptor_type_none); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + increase_client_send_key_reply_counter(); + + status = eapol_key_message.set_key_data_length(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + status = eapol_key_message.set_eapol_packet_body_length( + static_cast(*data_length - eapol_header_base_c::get_header_length())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = create_key_mic(&eapol_key_message, &m_confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + sent_packet->set_data_length( + eapol_header_offset + *data_length); + + TRACE_EAPOL_KEY_MESSAGE( + "Send TKIP MIC failure Message", + &eapol_key_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::tkip_mic_failure( + const bool fatal_failure_when_true, + const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(fatal_failure_when_true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::tkip_mic_failure(%d, %d).\n"), + fatal_failure_when_true, + tkip_mic_failure_type)); + + eap_status_e status = eap_status_not_supported; + + eap_buf_chain_wr_c sent_packet( + eap_write_buffer, + m_am_tools); + + if (sent_packet.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t send_data_length = 0ul; + u32_t send_buffer_length = 0ul; + + status = create_tkip_mic_failure_message( + &sent_packet, + m_eapol_header_offset, + &send_data_length, + &send_buffer_length, + tkip_mic_failure_type, + eapol_protocol_version_2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = packet_send( + &m_send_network_id, + &sent_packet, + m_eapol_header_offset, + send_data_length, + send_buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::set_pairwise_PMK( + const eap_variable_data_c * const key, + const eap_am_network_id_c * const send_network_id) +{ + if (key == 0 + || key->get_is_valid_data() == false + || key->get_data_length() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t pmk_key_length = key->get_data_length(); + + if (m_authentication_type == eapol_key_authentication_type_none) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + else if (m_authentication_type != eapol_key_authentication_type_802_1X) + { + // Truncate PMK only in WPA and RSN case + if (pmk_key_length > EAPOL_RSNA_PMK_LENGTH_BYTES) + { + pmk_key_length = EAPOL_RSNA_PMK_LENGTH_BYTES; + } + else if (pmk_key_length < EAPOL_RSNA_PMK_LENGTH_BYTES) + { + // No need to expand key. The short key is used as is. + } + } + + + if (send_network_id->get_type() == eapol_ethernet_type_preauthentication) + { + set_eapol_key_state(eapol_key_state_preauthenticated); + } + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_key_state_c::set_pairwise_PMK(): key"), + key->get_data(pmk_key_length), + pmk_key_length)); + + eap_status_e status = m_pairwise_PMK_WPXK3.set_copy_of_buffer( + key->get_data(pmk_key_length), + pmk_key_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::verify_field_is_zero( + const u8_t * const field, + const u32_t field_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; + + for (u32_t ind = 0ul; ind < field_length; ind++) + { + if (field[ind] != 0) + { + status = eap_status_illegal_padding; + break; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::packet_data_session_key( + eap_variable_data_c * const key, ///< Here is the key. + const eapol_key_type_e key_type, ///< This the type of the key. + const u32_t key_index, ///< This is the index of the key. + const bool key_tx_bit, ///< This is the TX bit of the key. + const u8_t * const key_RSC, ///< This is the RSC counter + const u32_t key_RSC_size ///< This is the size of RSC counter + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eapol_session_key_c * eapol_session_key = new eapol_session_key_c( + m_am_tools, + key, + key_type, + key_index, + key_tx_bit, + key_RSC, + key_RSC_size + ); + if (eapol_session_key == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (eapol_session_key->get_is_valid() == false) + { + delete eapol_session_key; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + eap_status_e status = m_key_state_partner->packet_data_session_key( + &m_send_network_id, + eapol_session_key); + + delete eapol_session_key; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::allow_4_way_handshake() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake()\n"), + (m_is_client == true ? "client": "server"))); + + // Only client (supplicant) could allow 4-Way Handshake. + EAP_ASSERT_ALWAYS(m_is_client == true); + + // First check do we need 4-Way Handshake. + if (get_is_RSNA() == true + || get_is_WPA() == true +#if defined(EAP_USE_WPXM) + || get_is_WPXM() == true +#endif //#if defined(EAP_USE_WPXM) + ) + { + // OK, we need 4-Way Handshake. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake(): ") + EAPL("Allow 4-Way Handshake, m_authentication_type=%d\n"), + (m_is_client == true ? "client": "server"), + m_authentication_type)); + + m_eapol_key_handshake_type = eapol_key_handshake_type_4_way_handshake; + m_eapol_key_state = eapol_key_state_wait_4_way_handshake_message_1; + } + else if (m_authentication_type == eapol_key_authentication_type_802_1X) + { + // No 4-Way Handshake needed. + // AP will send unicast and broad cast keys in EAPOL key messages. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake(): ") + EAPL("Dynamic WEP, m_authentication_type=%d\n"), + (m_is_client == true ? "client": "server"), + m_authentication_type)); + + m_eapol_key_handshake_type = eapol_key_handshake_type_dynamic_WEP; + m_eapol_key_state = eapol_key_state_wait_rc4_key_message; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + // No 4-Way Handshake needed. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake(): ") + EAPL("No 4-Way Handshake, m_authentication_type=%d\n"), + (m_is_client == true ? "client": "server"), + m_authentication_type)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + +#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + // Creates SNonce. This is done here in early phase of authentication. + // This will reduce the CPU load when time critical first message + // of 4-Way handshake is processed. + status = create_nonce(&m_SNonce, EAPOL_RSNA_NONCE_LENGTH_BYTES); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + status = init_handshake_timeout(m_handshake_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_EAPOL_KEY_TEST_FAILURES) + #pragma message ( "WARNING: USE_EAPOL_KEY_TEST_FAILURES compiler flag used. This is test code, NOT for final release." ) + m_create_key_failure = eapol_key_state_wait_4_way_handshake_message_3; +#endif //#if defined(USE_EAPOL_KEY_TEST_FAILURES) + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::start_group_key_handshake( + const eap_am_network_id_c * const receive_network_id, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status = eap_status_process_general_error; + + // server and client could call this. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::start_group_key_handshake()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_eapol_key_handshake_type != eapol_key_handshake_type_none + && m_eapol_key_handshake_type != eapol_key_handshake_type_group_key_handshake + && m_eapol_key_handshake_type != eapol_key_handshake_type_4_way_handshake) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: start_group_key_handshake(): wrong handshake type %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (get_eapol_key_state() != eapol_key_state_4_way_handshake_successfull + && get_eapol_key_state() != eapol_key_state_group_key_handshake_successfull) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: start_group_key_handshake(): wrong state %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_buf_chain_wr_c sent_packet( + eap_write_buffer, + m_am_tools); + + if (sent_packet.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t send_data_length = 0ul; + u32_t send_buffer_length = 0ul; + eapol_key_state_e next_state = eapol_key_state_group_key_handshake_failed; + + if (m_is_client == true) + { + status = create_eapol_key_handshake_message_0( + false, + &sent_packet, + m_eapol_header_offset, + &send_data_length, + &send_buffer_length, + 0ul, + received_eapol_version); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + next_state = eapol_key_state_wait_group_key_handshake_message_1; + } + else + { + +#if !defined(NO_EAPOL_KEY_STATE_SERVER) + + increase_key_reply_counter(); + + status = create_group_key_handshake_message_1( + &sent_packet, + m_eapol_header_offset, + &send_data_length, + &send_buffer_length, + received_eapol_version, + received_key_descriptor_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + next_state = eapol_key_state_wait_group_key_handshake_message_2; +#else + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + +#endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) + + } + + status = packet_send( + &m_send_network_id, + &sent_packet, + m_eapol_header_offset, + send_data_length, + send_buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_eapol_key_state(next_state); + + m_eapol_key_handshake_type = eapol_key_handshake_type_group_key_handshake; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::get_key_length( + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e cipher, + u16_t * const key_length) +{ + if (cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) + { + *key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_CCMP; + } + else if (cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP) + { + *key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_TKIP; + } + else if (cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40) + { + *key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_40; + } + else if (cipher + == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104) + { + *key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_104; + } + else + { + *key_length = 0ul; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_4_way_handshake_message( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + + +#if !defined(NO_EAPOL_KEY_STATE_SERVER) + if (m_is_client == false + && eapol_key_message->get_key_information_request() == true + && eapol_key_message->get_key_information_key_MIC() == true + && eapol_key_message->get_key_information_key_ack() == false + && eapol_key_message->get_key_information_install() == false + && eapol_key_message->get_key_data_length() == 0ul) + { + // Message 0 to start 4-Way Handshake. Only server handles this. + status = process_4_way_handshake_message_0( + receive_network_id, + eapol_key_message, + packet_length); + } + else +#endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) + if (m_is_client == true + && eapol_key_message->get_key_information_key_MIC() == false + && eapol_key_message->get_key_information_key_ack() == true + && eapol_key_message->get_key_information_install() == false) + { + // Message 1 of 4-Way Handshake. Only client handles this. + status = process_4_way_handshake_message_1( + receive_network_id, + eapol_key_message, + packet_length); + } + else +#if !defined(NO_EAPOL_KEY_STATE_SERVER) + if (m_is_client == false + && eapol_key_message->get_key_information_key_MIC() == true + && eapol_key_message->get_key_information_key_ack() == false + && eapol_key_message->get_key_information_install() == false + && eapol_key_message->get_key_data_length() != 0ul) + { + // Message 2 of 4-Way Handshake. Only server handles this. + status = process_4_way_handshake_message_2( + receive_network_id, + eapol_key_message, + packet_length); + } + else +#endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) + if (m_is_client == true + && eapol_key_message->get_key_information_key_MIC() == true + && eapol_key_message->get_key_information_key_ack() == true + && eapol_key_message->get_key_information_install() == true + && eapol_key_message->get_key_data_length() != 0ul) + { + // Message 3 of 4-Way Handshake. Only client handles this. + status = process_4_way_handshake_message_3( + receive_network_id, + eapol_key_message, + packet_length); + } + else +#if !defined(NO_EAPOL_KEY_STATE_SERVER) + if (m_is_client == false + && eapol_key_message->get_key_information_key_MIC() == true + && eapol_key_message->get_key_information_key_ack() == false + && eapol_key_message->get_key_information_install() == false + && eapol_key_message->get_key_data_length() == 0ul) + { + // Message 4 of 4-Way Handshake. Only server handles this. + status = process_4_way_handshake_message_4( + receive_network_id, + eapol_key_message, + packet_length); + } + else +#endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) + { + // ERROR. Drop packet. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key 4-Way Handshake frame: ") + EAPL("IsClient: %d MIC %d, Key Ack %d, Install %d, Key Length %d\n"), + m_is_client, + eapol_key_message->get_key_information_key_MIC(), + eapol_key_message->get_key_information_key_ack(), + eapol_key_message->get_key_information_install(), + eapol_key_message->get_key_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_group_key_handshake_message( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + +#if !defined(NO_EAPOL_KEY_STATE_SERVER) + if (m_is_client == false + && eapol_key_message->get_key_information_key_MIC() == true + && eapol_key_message->get_key_information_key_ack() == false + && eapol_key_message->get_key_information_request() == true) + { + // Message 0 of Group Key Handshake. Only server handles this. + status = process_group_key_handshake_message_0( + receive_network_id, + eapol_key_message, + packet_length); + } + else +#endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) + if (m_is_client == true + && eapol_key_message->get_key_information_key_MIC() == true + && eapol_key_message->get_key_information_key_ack() == true + && eapol_key_message->get_key_information_request() == false) + { + // Message 1 of Group Key Handshake. Only client handles this. + status = process_group_key_handshake_message_1( + receive_network_id, + eapol_key_message, + packet_length); + } + else +#if !defined(NO_EAPOL_KEY_STATE_SERVER) + if (m_is_client == false + && eapol_key_message->get_key_information_key_MIC() == true + && eapol_key_message->get_key_information_key_ack() == false + && eapol_key_message->get_key_information_request() == false) + { + // Message 2 of Group Key Handshake. Only server handles this. + status = process_group_key_handshake_message_2( + receive_network_id, + eapol_key_message, + packet_length); + } + else +#endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) + { + // ERROR. Drop packet. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key Group Key Handshake frame: ") + EAPL("MIC %d, Key Ack %d, Request %d\n"), + eapol_key_message->get_key_information_key_MIC(), + eapol_key_message->get_key_information_key_ack(), + eapol_key_message->get_key_information_request())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_RSNA_key_descriptor( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + if (packet_length < eapol_RSNA_key_header_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eapol_RSNA_key_header_c eapol_key_message( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + packet_data->get_header_buffer(packet_data->get_header_buffer_length()), + packet_data->get_header_buffer_length()); + if (eapol_key_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = eapol_key_message.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + TRACE_EAPOL_KEY_MESSAGE( + "Received EAPOL Handshake Message", + &eapol_key_message); + + u64_t packet_reply_counter = eapol_key_message.get_key_replay_counter(); + + // compare_u64() function is used because in some platforms + // unsigned 64-bit comparison is actually signed 64-bit comparison, + // because unsigned 64-bit integer is implemented as a signed 64-bit integer. + // This causes failures in test if broken AP sends Key Replay Counter with + // highest bit set 1. + i32_t comparison(m_am_tools->compare_u64(get_key_reply_counter(), packet_reply_counter)); + + if (m_is_client == true) + { + // On client Key Reply Counter must be bigger + // than on any other previous frame. + //if (get_key_reply_counter() > packet_reply_counter) + if (comparison > 0) + { + // ERROR. Drop packet. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key frame Reply Counter\n"))); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Local Reply Counter"), + &m_key_reply_counter, + sizeof(m_key_reply_counter))); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Packet Reply Counter"), + &packet_reply_counter, + sizeof(packet_reply_counter))); + + if (get_is_WPXM() == true) + { + // Here we must ignore the Reply Counter failure. + // WPXM seems to work against RSN specification that says + // every packet must be sent with new Reply Counter. + // WPXM starts Group Key Handshake with Reply Counter 0 after successfull + // 4-Way Handshake. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: Illegal EAPOL-Key frame Reply Counter in WPXM.\n"))); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + } + else if (comparison == 0) + { + // This may be re-transmitted request. + // Send the saved previous response + // or process this message again. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: EAPOL-Key frame Reply Counter same as previous request.\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: Local Reply Counter"), + &m_key_reply_counter, + sizeof(m_key_reply_counter))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: Packet Reply Counter"), + &packet_reply_counter, + sizeof(packet_reply_counter))); + } + } + else + { + if (eapol_key_message.get_key_information_request() == true) + { + // Reply Counter of request packets are not checked. + comparison = 0; + } + + // On server Key Reply Counter must be same + // as the sent request frame. + if (comparison != 0) + { + // ERROR. Drop packet. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key frame Reply Counter\n"))); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Local Reply Counter"), + &m_key_reply_counter, + sizeof(m_key_reply_counter))); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Packet Reply Counter"), + &packet_reply_counter, + sizeof(packet_reply_counter))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + } + + + if (eapol_key_message.get_key_information_key_type() == true) + { + // 4-Way Handshake message. + status = process_4_way_handshake_message( + receive_network_id, + &eapol_key_message, + packet_length); + } + else if (eapol_key_message.get_key_information_key_type() == false) + { + // Group Key Handshake message. + status = process_group_key_handshake_message( + receive_network_id, + &eapol_key_message, + packet_length); + } + else + { + // Unknown message received and dropped quietly. + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("WARNING: EAPOL_KEY: Handshake in NOT supported in m_eapol_key_handshake_type %s.\n"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_key_state_server.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_key_state_server.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2488 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 51 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#if !defined(NO_EAPOL_KEY_STATE_SERVER) + +#include "eap_am_memory.h" +#include "eapol_key_state.h" +#include "eapol_key_header.h" +#include "eap_crypto_api.h" +#include "abs_eap_am_mutex.h" +#include "eap_state_notification.h" +#include "eap_automatic_variable.h" +#include "eapol_rsna_key_data_gtk_header.h" +#include "eap_buffer.h" +#include "eapol_rsna_key_data_payloads.h" +#include "abs_eapol_key_state.h" +#include "eapol_rc4_key_header.h" +#include "eapol_key_state_string.h" + + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::create_4_way_handshake_message_1( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const eapol_protocol_version_e used_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::create_4_way_handshake_message_1()\n"), + (m_is_client == true ? "client": "server"))); + + // Only server (Authenticator) could create 4-Way Handshake message 1. + EAP_ASSERT_ALWAYS(m_is_client == false); + + if (sent_packet == 0 + || sent_packet->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_ANonce.get_is_valid_data() == false + || m_ANonce.get_data_length() != eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_4_way_handshake_message_1(): ") + EAPL("m_ANonce is missing or corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_PMKID.get_is_valid_data() == false + || m_PMKID.get_data_length() + != eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_4_way_handshake_message_1(): ") + EAPL("m_PMKID is missing or corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + u32_t eapol_key_data_length + = eapol_RSNA_key_header_c::get_header_length(); + + if (get_is_RSNA() == true) + { + eapol_key_data_length += EAPOL_RSNA_4_WAY_HANDSHAKE_MESSAGE_1_KEY_DATA_LENGTH_BYTES; + } + + *buffer_length + = eapol_header_offset + + eapol_key_data_length; + + status = sent_packet->set_buffer_length( + *buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sent_packet->set_data_length( + sent_packet->get_buffer_length()); + + eapol_RSNA_key_header_c eapol_key_message( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + sent_packet->get_data_offset(eapol_header_offset, eapol_key_data_length), + sent_packet->get_data_length()); + + if (eapol_key_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + status = eapol_key_message.reset_header( + 0ul, + m_authentication_type, + m_eapol_pairwise_cipher, + get_key_reply_counter(), + true, // Pairwise key type bit is on. + false, // Install bit is NOT set. + true, // Key Ack bit is on. + false, // Key MIC bit is NOT set. + false, // Secure bit is NOT set. + false, // Error bit is NOT set. + false, // Request bit is NOT set. + false, // STAKey bit is NOT set. + false, // Encrypted Key Data bit is NOT set. + used_eapol_version, + received_key_descriptor_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + { + // Add ANonce. + u8_t * const nonce_field = eapol_key_message.get_key_NONCE(); + if (nonce_field == 0 + || m_ANonce.get_data_length() != eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_am_tools->memmove( + nonce_field, + m_ANonce.get_data(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE); + } + + + if (get_is_RSNA() == true) + { + if (m_skip_PMKID_key_data_in_message_1 == false) + { + // Add PMKID to Key Data. + eapol_rsna_key_data_header_c key_data_header( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + eapol_key_message.get_key_data( + EAPOL_RSNA_4_WAY_HANDSHAKE_MESSAGE_1_KEY_DATA_LENGTH_BYTES), + EAPOL_RSNA_4_WAY_HANDSHAKE_MESSAGE_1_KEY_DATA_LENGTH_BYTES); + if (key_data_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = key_data_header.reset_header(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Here Type and Length fields are NOT included. + status = key_data_header.set_length( + EAPOL_RSNA_4_WAY_HANDSHAKE_MESSAGE_1_KEY_DATA_LENGTH_BYTES - 2ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = key_data_header.set_payload_type(eapol_RSNA_key_payload_type_pmkid); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const PMKID_field = key_data_header.get_key_data_payload( + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE); + if (PMKID_field == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAPOL_KEY: PMKID_field = 0x%08x\n"), + PMKID_field)); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("m_PMKID"), + m_PMKID.get_data(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE)); + + m_am_tools->memmove( + PMKID_field, + m_PMKID.get_data(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE); + + EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD( + get_is_RSNA(), + get_is_WPXM(), + eapol_key_message.get_key_descriptor_type(), + "Added EAPOL Key Data key_data_payload", + &key_data_header, + 0ul); + + status = eapol_key_message.set_key_data_length( + EAPOL_RSNA_4_WAY_HANDSHAKE_MESSAGE_1_KEY_DATA_LENGTH_BYTES); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + u16_t key_length(0ul); + + status = get_key_length( + m_eapol_pairwise_cipher, + &key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eapol_key_message.set_key_length(key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + status = eapol_key_message.set_eapol_packet_body_length( + static_cast(*data_length - eapol_header_base_c::get_header_length())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + sent_packet->set_data_length( + eapol_header_offset + *data_length); + + TRACE_EAPOL_KEY_MESSAGE( + "Send 4-Way Handshake Message 1", + &eapol_key_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::create_4_way_handshake_message_3( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const eapol_protocol_version_e used_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_process_general_error); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::create_4_way_handshake_message_3()\n"), + (m_is_client == true ? "client": "server"))); + + // Only server (Authenticator) could create 4-Way Handshake message 3. + EAP_ASSERT_ALWAYS(m_is_client == false); + + if (m_ANonce.get_is_valid_data() == false + || m_ANonce.get_data_length() != eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_4_way_handshake_message_3(): ") + EAPL("m_ANonce is missing or corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_authenticator_RSNA_IE.get_is_valid_data() == false + || m_authenticator_RSNA_IE.get_data_length() == 0ul + || m_authenticator_RSNA_IE.get_data_length() + > eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_MAXIMUM_RSN_IE_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_4_way_handshake_message_3(): ") + EAPL("m_authenticator_RSNA_IE is missing or corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + u32_t eapol_key_data_length + = eapol_RSNA_key_header_c::get_header_length() + + m_authenticator_RSNA_IE.get_data_length(); + + u32_t extra_encryption_padding_and_block(0ul); + + if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP + || m_eapol_group_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) + { + extra_encryption_padding_and_block = 2ul * EAP_CRYPTO_AES_WRAP_BLOCK_SIZE; + } + + if ((get_is_RSNA() == true + && m_eapol_group_cipher != eapol_RSNA_key_header_c::eapol_RSNA_cipher_none) + || (get_is_WPXM() == true + && received_key_descriptor_type == eapol_key_descriptor_type_RSNA)) + { + u16_t GTK_length = 0ul; + + status = get_key_length(m_eapol_group_cipher, >K_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Creates GTK. + status = create_nonce(&m_group_GTK, GTK_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eapol_key_data_length += + eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_HEADER_LENGTH + + eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_ID_AND_GROUP_KEY_HEADER_SIZE + + m_group_GTK.get_data_length(); + } + + + *buffer_length + = eapol_header_offset + + eapol_key_data_length + + extra_encryption_padding_and_block; + + status = sent_packet->set_buffer_length( + *buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sent_packet->set_data_length( + sent_packet->get_buffer_length()); + + eapol_RSNA_key_header_c eapol_key_message( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + sent_packet->get_data_offset(eapol_header_offset, eapol_key_data_length), + sent_packet->get_data_length()); + + if (eapol_key_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + bool secure_bit = false; // Secure bit is NOT set in WPA. + bool encrypted_key_data = false; // Encrypted Key Data bit is NOT set in WPA. + + if (get_is_RSNA() == true + || (get_is_WPXM() == true + && received_key_descriptor_type == eapol_key_descriptor_type_RSNA)) + { + secure_bit = true; // Secure bit is on in RSNA. + encrypted_key_data = true; // Encrypted Key Data bit is on in RSNA. + } + + + status = eapol_key_message.reset_header( + 0ul, + m_authentication_type, + m_eapol_pairwise_cipher, + get_key_reply_counter(), + true, // Pairwise key type bit is on. + true, // Install bit is on. /** @{ This could be false when AP does not support key mapping keys. } */ + true, // Key Ack bit is on. + true, // Key MIC bit is on. + secure_bit, + false, // Error bit is NOT set. + false, // Request bit is NOT set. + false, // STAKey bit is NOT set. + encrypted_key_data, + used_eapol_version, + received_key_descriptor_type); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + { + // Add ANonce. + u8_t * const nonce_field = eapol_key_message.get_key_NONCE(); + if (nonce_field == 0 + || m_ANonce.get_data_length() != eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + nonce_field, + m_ANonce.get_data(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE); + } + + if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP) + { + // Add Key IV. + // Creates EAPOL-Key IV. + status = create_nonce(&m_EAPOL_key_IV, eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const key_iv_field = eapol_key_message.get_EAPOL_key_IV(); + if (key_iv_field == 0 + || m_EAPOL_key_IV.get_data_length() < eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Note only the lower sixteen octets of the counter are value are used. + u32_t offset = m_EAPOL_key_IV.get_data_length() - eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE; + u8_t * const iv_data = m_EAPOL_key_IV.get_data_offset(offset, eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + + if (iv_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + m_am_tools->memmove( + key_iv_field, + iv_data, + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + } + + /** + * @{ Missing payload: starting sequence Authenticator's STA will use in packets protected by GTK. } + */ + + u32_t total_key_data_length(0ul); + + status = add_RSN_IE_payload( + &eapol_key_message, + &m_authenticator_RSNA_IE, + &total_key_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + /** + * @{ Missing payload: a second RSN IE that is Authenticator's unicast cipher suite assigment. } + */ + + /** + * @{ Missing payload: GTK when multicast cipher has been negotiated. } + */ + + if ((get_is_RSNA() == true + && m_eapol_group_cipher != eapol_RSNA_key_header_c::eapol_RSNA_cipher_none) + || (get_is_WPXM() == true + && received_key_descriptor_type == eapol_key_descriptor_type_RSNA)) + { + status = add_RSN_GTK_payload( + &eapol_key_message, + &m_group_GTK, + &total_key_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (total_key_data_length > 0xffff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + status = eapol_key_message.set_key_data_length( + static_cast(total_key_data_length)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + status = eapol_key_message.set_eapol_packet_body_length( + static_cast(*data_length - eapol_header_base_c::get_header_length())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (get_is_RSNA() == true + || (get_is_WPXM() == true + && received_key_descriptor_type == eapol_key_descriptor_type_RSNA)) + { + status = encrypt_key_data(&eapol_key_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // NOTE the encryption may increase length of the key data field. + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + status = eapol_key_message.set_eapol_packet_body_length( + static_cast(*data_length - eapol_header_base_c::get_header_length())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + status = create_key_mic( + &eapol_key_message, + &m_confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Encryption may change the length of EAPOL-Key data. + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + sent_packet->set_data_length( + eapol_header_offset + *data_length); + + TRACE_EAPOL_KEY_MESSAGE( + "Send 4-Way Handshake Message 3", + &eapol_key_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::send_RC4_eapol_key_message( + const eapol_RC4_key_flags_e flags) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + u8_t unicast_test_key[] = "12345"; + u32_t unicast_test_key_length = sizeof(unicast_test_key)-1ul; + + const u32_t eapol_key_data_length + = eapol_RC4_key_header_c::get_header_length() + + unicast_test_key_length; + + const u32_t buffer_length + = m_eapol_header_offset + + eapol_key_data_length; + + eap_buf_chain_wr_c sent_packet( + eap_write_buffer, + m_am_tools); + if (sent_packet.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = sent_packet.set_buffer_length( + buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sent_packet.set_data_length( + sent_packet.get_buffer_length()); + + eapol_RC4_key_header_c eapol_key_message( + m_am_tools, + sent_packet.get_data_offset(m_eapol_header_offset, eapol_key_data_length), + sent_packet.get_data_length()); + if (eapol_key_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Create IV. + eap_variable_data_c RC4_IV(m_am_tools); + + status = create_nonce(&RC4_IV, EAPOL_RC4_KEY_IV_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_am_tools->memmove(eapol_key_message.get_key_IV(), RC4_IV.get_data(), EAPOL_RC4_KEY_IV_LENGTH); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eapol_key_message.set_eapol_protocol_version(eapol_protocol_version_1); + + eapol_key_message.set_eapol_packet_type(eapol_packet_type_key); + + eapol_key_message.set_eapol_packet_body_length(static_cast(eapol_key_data_length - eapol_header_base_c::get_header_length())); + + eapol_key_message.set_key_descriptor_type(eapol_key_descriptor_type_RC4); + + m_am_tools->memset(eapol_key_message.get_replay_counter(), 0, EAPOL_RC4_KEY_REPLAY_COUNTER_LENGTH); + + eapol_key_message.set_key_flag(flags); + + eapol_key_message.set_key_index(0ul); + + eapol_key_message.set_key_length(static_cast(unicast_test_key_length)); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Get MS-MPPE-Recv-Key and MS-MPPE-Send-Key + eap_variable_data_c mppe_recv_key(m_am_tools); + eap_variable_data_c mppe_send_key(m_am_tools); + + if (m_pairwise_PMK_WPXK3.get_data_length() == eapol_key_state_mppe_key_length_leap) + { + // LEAP only generates 16 bytes PMK. Also with LEAP the receive and send keys are the same. + status = mppe_recv_key.set_buffer( + m_pairwise_PMK_WPXK3.get_data( + eapol_key_state_mppe_key_length_leap), + eapol_key_state_mppe_key_length_leap, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = mppe_send_key.set_buffer( + m_pairwise_PMK_WPXK3.get_data( + eapol_key_state_mppe_key_length_leap), + eapol_key_state_mppe_key_length_leap, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + else if (m_pairwise_PMK_WPXK3.get_data_length() >= 64ul) + { + // Usually types generate at least 64 bytes PMK. + // Recv-Key is the first 32 bytes of master session key and Send-Key is the next 32 bytes. + status = mppe_recv_key.set_buffer( + m_pairwise_PMK_WPXK3.get_data( + eapol_key_state_mppe_key_length), + eapol_key_state_mppe_key_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = mppe_send_key.set_buffer( + m_pairwise_PMK_WPXK3.get_data_offset( + eapol_key_state_mppe_key_length, + eapol_key_state_mppe_key_length), + eapol_key_state_mppe_key_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: Unsupported PMK key length for RC4 EAPOL-key handshake.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Set-up RC4 key. Key is the IV and the MS-MPPE-Recv-Key truncated together. + eap_variable_data_c rc4_key(m_am_tools); + status = rc4_key.set_copy_of_buffer(eapol_key_message.get_key_IV(), EAPOL_RC4_KEY_IV_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4_key.add_data(&mppe_recv_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Set-up RC4 module + crypto_rc4_c rc4(m_am_tools); + if (rc4.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Set the key for RC4 + if (rc4.set_key(&rc4_key) != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Decrypt the key to key_out + status = rc4.encrypt_data( + unicast_test_key, + eapol_key_message.get_key(), + unicast_test_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Create the the MD5 signature in Eapol-Key + + crypto_md5_c md5(m_am_tools); + crypto_hmac_c hmac_md5(m_am_tools, &md5, false); + if (hmac_md5.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (hmac_md5.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // MPPE-Send-Key is used as the signature key. + if (hmac_md5.hmac_set_key(&mppe_send_key) != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Replace the signature with zeros. + eapol_key_message.zero_key_signature(m_am_tools); + + // Send the data to HMAC-MD5 module + if (hmac_md5.hmac_update( + eapol_key_message.get_header_buffer(eapol_key_data_length), + eapol_key_data_length) + != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Get the calculated signature + u8_t tmp_signature[EAPOL_RC4_KEY_SIGNATURE_LENGTH]; + u32_t length; + if (hmac_md5.hmac_final(tmp_signature, &length) != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Copy the calculated signature to message. + m_am_tools->memmove( + eapol_key_message.get_key_signature(), + tmp_signature, + EAPOL_RC4_KEY_SIGNATURE_LENGTH); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = packet_send( + &m_send_network_id, + &sent_packet, + m_eapol_header_offset, + eapol_key_data_length, + sent_packet.get_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::send_RC4_eapol_key_messages() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + status = send_RC4_eapol_key_message(eapol_RC4_key_flag_unicast); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_RC4_eapol_key_message(eapol_RC4_key_flag_broadcast); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // This is notification to eapol_core_c object. + // Dynamic WEP (802.1x) authentication finished successfully. + eap_state_notification_c * notification = new eap_state_notification_c( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_dynamic_WEP, + get_eapol_key_state(), + eapol_key_state_802_11i_authentication_finished_successfull, + 0ul, + false); + if (notification == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_key_state_partner->state_notification(notification); + + delete notification; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::start_4_way_handshake( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status(eap_status_process_general_error); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::start_4_way_handshake()\n"), + (m_is_client == true ? "client": "server"))); + + // Only server (Authenticator) could start 4-Way Handshake. + EAP_ASSERT_ALWAYS(m_is_client == false); + + // First check do we need 4-Way Handshake. + if (get_is_RSNA() == true + || get_is_WPA() == true +#if defined(EAP_USE_WPXM) + || get_is_WPXM() == true +#endif //#if defined(EAP_USE_WPXM) + ) + { + // OK, we need 4-Way Handshake. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::start_4_way_handshake(): ") + EAPL("Start 4-Way Handshake, m_authentication_type=%d\n"), + (m_is_client == true ? "client": "server"), + m_authentication_type)); + } + else if (m_authentication_type == eapol_key_authentication_type_802_1X) + { + // No 4-Way Handshake needed. + // AP will send unicast and broad cast keys in EAPOL key messages. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::start_4_way_handshake(): ") + EAPL("Dynamic WEP, m_authentication_type=%d\n"), + (m_is_client == true ? "client": "server"), + m_authentication_type)); + + m_eapol_key_handshake_type = eapol_key_handshake_type_dynamic_WEP; + + send_RC4_eapol_key_messages(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + // No 4-Way Handshake needed. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::start_4_way_handshake(): ") + EAPL("No 4-Way Handshake, m_authentication_type=%d\n"), + (m_is_client == true ? "client": "server"), + m_authentication_type)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + if (m_eapol_key_handshake_type != eapol_key_handshake_type_none + && m_eapol_key_handshake_type != eapol_key_handshake_type_4_way_handshake) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: start_4_way_handshake(): wrong handshake type %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (get_eapol_key_state() != eapol_key_state_none + && get_eapol_key_state() != eapol_key_state_preauthenticated + && get_eapol_key_state() != eapol_key_state_group_key_handshake_successfull) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: start_4_way_handshake(): wrong state %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + // Creates ANonce. + status = create_nonce(&m_ANonce, EAPOL_RSNA_NONCE_LENGTH_BYTES); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ANonce"), + m_ANonce.get_data( + m_ANonce.get_data_length()), + m_ANonce.get_data_length())); + + // Create PMKID. + status = create_PMKID(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_key_reply_counter(0ul); + increase_key_reply_counter(); + + eap_buf_chain_wr_c sent_packet( + eap_write_buffer, + m_am_tools); + + if (sent_packet.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t send_data_length = 0ul; + u32_t send_buffer_length = 0ul; + + status = create_4_way_handshake_message_1( + &sent_packet, + m_eapol_header_offset, + &send_data_length, + &send_buffer_length, + eapol_protocol_version_2, +#if defined(EAP_USE_WPXM) + m_EAPOL_WPXM_key_descriptor_type +#else + eapol_key_descriptor_type_RSNA +#endif //#if defined(EAP_USE_WPXM) + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = packet_send( + &m_send_network_id, + &sent_packet, + m_eapol_header_offset, + send_data_length, + send_buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = init_handshake_timeout(m_handshake_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_eapol_key_state(eapol_key_state_wait_4_way_handshake_message_2); + + m_eapol_key_handshake_type = eapol_key_handshake_type_4_way_handshake; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_4_way_handshake_message_2_payloads( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status = eap_status_process_general_error; + + u32_t received_buffer_length = eapol_key_message->get_key_data_length(); + + if (received_buffer_length == 0u) + { + // No payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (received_buffer_length > eapol_key_message->get_header_buffer_length() + || eapol_key_message->get_key_data(received_buffer_length) == 0) + { + // Not enough payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + eapol_rsna_key_data_payloads_c key_data_payloads( + m_am_tools, + get_is_RSNA(), + get_is_WPXM()); + + eapol_rsna_key_data_header_c key_data( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + eapol_key_message->get_key_data(received_buffer_length), + packet_length); + if (key_data.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: No EAPOL-Key data payloads.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = key_data.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: EAPOL-Key data payload header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = parse_key_data( + eapol_key_message->get_key_descriptor_type(), + &key_data, + &received_buffer_length, + &key_data_payloads, + eapol_key_state_wait_4_way_handshake_message_2, + eapol_key_message->get_key_information_key_descriptor_version()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Check the valid payload is included. + if (false == key_data_payloads.check_payloads( + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_not_be, // key_id_and_group_key + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_not_be, // STAKey + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_not_be, // PMKID + eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_must_be // One or more RSN IE + )) + { + // Not correct EAPOL Key Data payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_2_payloads(): ") + EAPL("Not correct EAPOL Key Data payloads are included.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + +#if defined(EAP_USE_WPXM) + // Derive PTK. + if (get_is_WPXM() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_2_payloads(): ") + EAPL("m_WPXM_WPXC=%d.\n"), + m_WPXM_WPXC)); + + status = derive_WPXM_WPXK1_WPXK2(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = derive_WPXM_PTK(eapol_key_constant_wpxm_initial_wpxc_counter_value); + } + else +#endif //#if defined(EAP_USE_WPXM) + { + status = derive_PTK(); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const eap_variable_data_c * confirmation_key = &m_confirmation_KCK; +#if defined(EAP_USE_WPXM) + if (get_is_WPXM() == true) + { + confirmation_key = &m_WPXM_WPXK1; + } +#endif //#if defined(EAP_USE_WPXM) + + // Check MIC. + status = verify_key_mic( + eapol_key_message, + confirmation_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // We do have the expected RSN IE, compare it. + if (get_supplicant_RSNA_IE()->compare( + key_data_payloads.get_RSN_IE()->get_object(0ul)) != 0) + { + // Illegal RSN IE. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::process_4_way_handshake_message_2_payloads(): ") + EAPL("Not correct RSN IE received.\n"))); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Supplicant RSN IE"), + get_supplicant_RSNA_IE()->get_data( + get_supplicant_RSNA_IE()->get_data_length()), + get_supplicant_RSNA_IE()->get_data_length())); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("Received RSN IE"), + key_data_payloads.get_RSN_IE()->get_object(0ul)->get_data( + key_data_payloads.get_RSN_IE()->get_object(0ul)->get_data_length()), + key_data_payloads.get_RSN_IE()->get_object(0ul)->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_4_way_handshake_message_0( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t /* packet_length */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status = eap_status_process_general_error; + + eapol_key_state_string_c state_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::process_4_way_handshake_message_0(): eapol_key_descriptor_type = %s = 0x%02x\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_descriptor_type_string(eapol_key_message->get_key_descriptor_type()), + eapol_key_message->get_key_descriptor_type())); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_key_state_c::process_4_way_handshake_message_0()"); + + // Only server (Authenticator) could receive 4-Way Handshake message 0. + // Client initializes the 4-Way Handshake with this message. + EAP_ASSERT_ALWAYS(m_is_client == false); + + if (m_eapol_key_handshake_type == eapol_key_handshake_type_none) + { + m_eapol_key_handshake_type = eapol_key_handshake_type_4_way_handshake; + } + else if (m_eapol_key_handshake_type != eapol_key_handshake_type_4_way_handshake) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_4_way_handshake_message_0(): wrong handshake type %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (get_eapol_key_state() != eapol_key_state_none + && get_eapol_key_state() != eapol_key_state_preauthenticated + && get_eapol_key_state() != eapol_key_state_group_key_handshake_successfull + ) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_4_way_handshake_message_0(): wrong state %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (eapol_key_message->get_key_length() != 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + status = verify_field_is_zero( + eapol_key_message->get_EAPOL_key_IV(), + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_STA_MAC_address(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_reserved(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RESERVED_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = start_4_way_handshake( + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_4_way_handshake_message_2( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + eap_status_e status = eap_status_process_general_error; + + eapol_key_state_string_c state_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::process_4_way_handshake_message_2(): eapol_key_descriptor_type = %s = 0x%02x\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_descriptor_type_string(eapol_key_message->get_key_descriptor_type()), + eapol_key_message->get_key_descriptor_type())); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_key_state_c::process_4_way_handshake_message_2()"); + + // Only server (Authenticator) could receive 4-Way Handshake message 2. + EAP_ASSERT_ALWAYS(m_is_client == false); + + if (m_eapol_key_handshake_type != eapol_key_handshake_type_4_way_handshake) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_4_way_handshake_message_0(): wrong handshake type %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (get_eapol_key_state() != eapol_key_state_wait_4_way_handshake_message_2) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_4_way_handshake_message_2(): wrong state %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (eapol_key_message->get_key_length() != 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + status = verify_field_is_zero( + eapol_key_message->get_EAPOL_key_IV(), + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_STA_MAC_address(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_reserved(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RESERVED_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // Save SNonce. + const u8_t * const SNonce = eapol_key_message->get_key_NONCE(); + if (SNonce == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + status = m_SNonce.set_copy_of_buffer( + SNonce, + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = process_4_way_handshake_message_2_payloads( + receive_network_id, + eapol_key_message, + packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_buf_chain_wr_c sent_packet( + eap_write_buffer, + m_am_tools); + + if (sent_packet.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t send_data_length = 0ul; + u32_t send_buffer_length = 0ul; + + increase_key_reply_counter(); + + status = create_4_way_handshake_message_3( + &sent_packet, + m_eapol_header_offset, + &send_data_length, + &send_buffer_length, + eapol_key_message->get_eapol_protocol_version(), + eapol_key_message->get_key_descriptor_type()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = packet_send( + &m_send_network_id, + &sent_packet, + m_eapol_header_offset, + send_data_length, + send_buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_eapol_key_state(eapol_key_state_wait_4_way_handshake_message_4); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_4_way_handshake_message_4( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(packet_length); + + eap_status_e status = eap_status_process_general_error; + + eapol_key_state_string_c state_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::process_4_way_handshake_message_4(): eapol_key_descriptor_type = %s = 0x%02x\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_descriptor_type_string(eapol_key_message->get_key_descriptor_type()), + eapol_key_message->get_key_descriptor_type())); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_key_state_c::process_4_way_handshake_message_4()"); + + // Only server (Authenticator) could receive 4-Way Handshake message 4. + EAP_ASSERT_ALWAYS(m_is_client == false); + + if (m_eapol_key_handshake_type != eapol_key_handshake_type_4_way_handshake) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: start_4_way_handshake(): wrong handshake type %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (get_eapol_key_state() != eapol_key_state_wait_4_way_handshake_message_4) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_4_way_handshake_message_4(): wrong state %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (eapol_key_message->get_key_length() != 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_NONCE(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_EAPOL_key_IV(), + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_STA_MAC_address(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_reserved(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RESERVED_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (eapol_key_message->get_key_data_length() != 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + + status = verify_key_mic( + eapol_key_message, + &m_confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + +#if defined(EAP_USE_WPXM) + if (get_is_WPXM() == true) + { + status = packet_data_session_key( + &m_WPXM_WPXK1, + eapol_key_type_wpxm_wpxk1, + 0ul, + false, + 0, + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(EAP_USE_WPXM) + + + status = packet_data_session_key( + &m_temporal_TK, + eapol_key_type_unicast, + 0ul, + false, + 0, + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + { + // This is notification to eapol_core_c object. + // 4-Way Handshake finished successfully. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_4_way_handshake, + get_eapol_key_state(), + eapol_key_state_4_way_handshake_successfull, + 0ul, + false); + m_key_state_partner->state_notification(¬ification); + } + + + if (get_is_RSNA() == true + && m_eapol_group_cipher != eapol_RSNA_key_header_c::eapol_RSNA_cipher_none + && m_group_GTK.get_is_valid_data() == true) + { + // We do have the expected GTK, pass it to lower layers. + status = packet_data_session_key( + &m_group_GTK, + eapol_key_type_broadcast, + m_group_GTK_ID, + m_group_GTK_Tx_bit, + eapol_key_message->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // This is notification to eapol_core_c object. + // Group Key Handshake finished successfully. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_group_key_handshake, + get_eapol_key_state(), + eapol_key_state_group_key_handshake_successfull, + 0ul, + false); + m_key_state_partner->state_notification(¬ification); + } + } + + if (get_is_RSNA() == true) + { + { + // This is notification to eapol_core_c object. + // 802.11i authentication finished successfully. + eap_state_notification_c * notification = new eap_state_notification_c( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_802_11i_handshake, + get_eapol_key_state(), + eapol_key_state_802_11i_authentication_finished_successfull, + 0ul, + false); + if (notification == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_key_state_partner->state_notification(notification); + + delete notification; + } + + cancel_handshake_timeout(); + } + else + { + // Note the WPA version always does separate Group Key Handshake. + // Authentication is successfull after the Group Key Handshake + // Finishes successfully. + } + + set_eapol_key_state(eapol_key_state_4_way_handshake_successfull); + + m_eapol_key_handshake_type = eapol_key_handshake_type_none; + + cancel_retransmission(); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: 4-Way Handshake SUCCESS\n"), + (m_is_client == true ? "client": "server"))); + + status = start_group_key_handshake( + receive_network_id, + eapol_key_message->get_eapol_protocol_version(), + eapol_key_message->get_key_descriptor_type()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::create_group_key_handshake_message_1( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const eapol_protocol_version_e used_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::create_group_key_handshake_message_1()\n"), + (m_is_client == true ? "client": "server"))); + + // Only server (Authenticator) could create Group Key Handshake message 1. + EAP_ASSERT_ALWAYS(m_is_client == false); + + if (m_confirmation_KCK.get_is_valid_data() == false + || m_confirmation_KCK.get_data_length() == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_group_key_handshake_message_1(): ") + EAPL("m_confirmation_KCK is missing or corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_encryption_KEK.get_is_valid_data() == false + || m_encryption_KEK.get_data_length() == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, + (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_group_key_handshake_message_1(): ") + EAPL("m_encryption_KEK is missing or corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u16_t GTK_length = 0ul; + + status = get_key_length(m_eapol_group_cipher, >K_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Creates GTK. + status = create_nonce(&m_group_GTK, GTK_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u32_t eapol_key_data_length + = eapol_RSNA_key_header_c::get_header_length() + + eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_HEADER_LENGTH + +eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_ID_AND_GROUP_KEY_HEADER_SIZE + +GTK_length; + + + u32_t extra_encryption_padding_and_block(0ul); + + if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP + || m_eapol_group_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) + { + extra_encryption_padding_and_block = 2ul * EAP_CRYPTO_AES_WRAP_BLOCK_SIZE; + } + + + *buffer_length + = eapol_header_offset + + eapol_key_data_length + + extra_encryption_padding_and_block; + + status = sent_packet->set_buffer_length( + *buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sent_packet->set_data_length( + sent_packet->get_buffer_length()); + + eapol_RSNA_key_header_c eapol_key_message( + m_am_tools, + get_is_RSNA(), + get_is_WPXM(), + sent_packet->get_data_offset(eapol_header_offset, eapol_key_data_length), + sent_packet->get_data_length()); + + if (eapol_key_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + status = eapol_key_message.reset_header( + 1ul, + m_authentication_type, + m_eapol_pairwise_cipher, + get_key_reply_counter(), + false, // Pairwise key type bit is NOT set. + true, // Install bit is on. Use group key for send and receive. + true, // Key Ack bit is on. + true, // Key MIC bit is on. + true, // Secure bit is on. + false, // Error bit is NOT set. + false, // Request bit is NOT set. + false, // STAKey bit is NOT set. + true, // Encrypted Key Data bit is on. + used_eapol_version, + received_key_descriptor_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP) + { + // Add Key IV. + // Creates EAPOL-Key IV. + status = create_nonce(&m_EAPOL_key_IV, eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const key_iv_field = eapol_key_message.get_EAPOL_key_IV(); + if (key_iv_field == 0 + || m_EAPOL_key_IV.get_data_length() < eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Note only the lower sixteen octets of the counter are value are used. + u32_t offset = m_EAPOL_key_IV.get_data_length() - eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE; + + u8_t * const iv_data = m_EAPOL_key_IV.get_data_offset(offset, eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (iv_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + m_am_tools->memmove( + key_iv_field, + iv_data, + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + } + + /** + * @{ Missing payload: last transmit sequence number for GTK. } + */ + + + u32_t eapol_data_length(0ul); + + if (get_is_RSNA() == true) + { + status = add_RSN_GTK_payload( + &eapol_key_message, + &m_group_GTK, + &eapol_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Add authenticator GTK to Key Data. + u8_t * data_field_of_GTK + = eapol_key_message.get_key_data( + GTK_length); + if (data_field_of_GTK == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + data_field_of_GTK, + m_group_GTK.get_data(GTK_length), + GTK_length); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send WPA Group Key"), + m_group_GTK.get_data(GTK_length), + GTK_length)); + + eapol_data_length = GTK_length; + } + + + + if (eapol_data_length > 0xffff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + status = eapol_key_message.set_key_data_length( + static_cast(eapol_data_length)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + status = eapol_key_message.set_eapol_packet_body_length( + static_cast(*data_length - eapol_header_base_c::get_header_length())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = encrypt_key_data(&eapol_key_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // NOTE the encryption may increase length of the key data field. + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + status = eapol_key_message.set_eapol_packet_body_length( + static_cast(*data_length - eapol_header_base_c::get_header_length())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = create_key_mic( + &eapol_key_message, + &m_confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Encryption may change the length of EAPOL-Key data. + *data_length + = eapol_key_message.get_header_length() + + eapol_key_message.get_key_data_length(); + + sent_packet->set_data_length( + eapol_header_offset + *data_length); + + TRACE_EAPOL_KEY_MESSAGE( + "Send Group Key Handshake Message 1", + &eapol_key_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_group_key_handshake_message_0( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(packet_length); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::process_group_key_handshake_message_0()\n"), + (m_is_client == true ? "client": "server"))); + + // Only server (Authenticator) could receive Group Key Handshake message 0. + EAP_ASSERT_ALWAYS(m_is_client == false); + + if (m_eapol_key_handshake_type != eapol_key_handshake_type_none) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_group_key_handshake_message_0(): wrong handshake type %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (get_eapol_key_state() != eapol_key_state_4_way_handshake_successfull + && get_eapol_key_state() != eapol_key_state_group_key_handshake_successfull) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_group_key_handshake_message_0(): wrong state %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + + if (eapol_key_message->get_key_length() != 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_NONCE(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_EAPOL_key_IV(), + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_STA_MAC_address(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_reserved(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RESERVED_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (eapol_key_message->get_key_data_length() != 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + + status = verify_key_mic( + eapol_key_message, + &m_confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = start_group_key_handshake( + receive_network_id, + eapol_key_message->get_eapol_protocol_version(), + eapol_key_message->get_key_descriptor_type()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::process_group_key_handshake_message_2( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + EAP_UNREFERENCED_PARAMETER(packet_length); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: eapol_key_state_c::process_group_key_handshake_message_2()\n"), + (m_is_client == true ? "client": "server"))); + + // Only server (Authenticator) could receive Group Key Handshake message 2. + EAP_ASSERT_ALWAYS(m_is_client == false); + + if (m_eapol_key_handshake_type != eapol_key_handshake_type_group_key_handshake) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: start_group_key_handshake(): wrong handshake type %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + if (get_eapol_key_state() != eapol_key_state_wait_group_key_handshake_message_2) + { + eapol_key_state_string_c state_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAPOL_KEY: %s: process_group_key_handshake_message_2(): wrong state %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_eapol_key_state_string(get_eapol_key_state()))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + + if (eapol_key_message->get_key_length() != 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_NONCE(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_EAPOL_key_IV(), + eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_STA_MAC_address(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = verify_field_is_zero( + eapol_key_message->get_key_reserved(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RESERVED_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (eapol_key_message->get_key_data_length() != 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + + status = verify_key_mic( + eapol_key_message, + &m_confirmation_KCK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = packet_data_session_key( + &m_group_GTK, + eapol_key_type_broadcast, + m_group_GTK_ID, + m_group_GTK_Tx_bit, + eapol_key_message->get_key_RSC(), + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // This is notification to eapol_core_c object. + // Group Key Handshake finished successfully. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_group_key_handshake, + get_eapol_key_state(), + eapol_key_state_group_key_handshake_successfull, + 0ul, + false); + m_key_state_partner->state_notification(¬ification); + + + cancel_group_key_update_timeout(); + + if (m_server_TEST_group_key_update == true) + { + init_group_key_update_timeout(EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT); + } + } + + if (get_is_RSNA() == false) + { + // Note the WPA version always does separate Group Key Handshake. + // Authentication is successfull after the Group Key Handshake + // Finishes successfully. + + { + // This is notification to eapol_core_c object. + // WPA authentication finished successfully. + eap_state_notification_c * notification = new eap_state_notification_c( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eapol_key, + eapol_key_handshake_type_802_11i_handshake, + get_eapol_key_state(), + eapol_key_state_802_11i_authentication_finished_successfull, + 0ul, + false); + if (notification == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_key_state_partner->state_notification(notification); + + delete notification; + } + } + + set_eapol_key_state(eapol_key_state_group_key_handshake_successfull); + + m_eapol_key_handshake_type = eapol_key_handshake_type_none; + + cancel_retransmission(); + cancel_handshake_timeout(); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: Group Key Handshake SUCCESS\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_key_state_string.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_key_state_string.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,164 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 50 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eapol_key_state_string.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_key_state_string_c::~eapol_key_state_string_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_key_state_string_c::eapol_key_state_string_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eapol_key_state_string_c::get_eapol_key_state_string( + const eapol_key_state_e state) const +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(state, eapol_key_state_none) + else EAP_IF_RETURN_STRING(state, eapol_key_state_preauthenticated) + else EAP_IF_RETURN_STRING(state, eapol_key_state_eap_authentication_running) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_4_way_handshake_start) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_4_way_handshake_message_1) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_4_way_handshake_message_2) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_4_way_handshake_message_3) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_4_way_handshake_message_4) + else EAP_IF_RETURN_STRING(state, eapol_key_state_4_way_handshake_running) + else EAP_IF_RETURN_STRING(state, eapol_key_state_4_way_handshake_failed) + else EAP_IF_RETURN_STRING(state, eapol_key_state_4_way_handshake_successfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_group_key_handshake_message_1) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_group_key_handshake_message_2) + else EAP_IF_RETURN_STRING(state, eapol_key_state_group_key_handshake_failed) + else EAP_IF_RETURN_STRING(state, eapol_key_state_group_key_handshake_successfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wait_rc4_key_message) + else EAP_IF_RETURN_STRING(state, eapol_key_state_802_11i_authentication_terminated_unsuccessfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_802_11i_authentication_finished_successfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_reassociation_failed) +#if defined(EAP_USE_WPXM) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wpxm_reassociation_finished_successfull) +#endif //#if defined(EAP_USE_WPXM) +#if defined(USE_WAPI_CORE) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wapi_authentication_terminated_unsuccessfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wapi_authentication_finished_successfull) + else EAP_IF_RETURN_STRING(state, eapol_key_state_wapi_authentication_running) +#endif //#if defined(USE_WAPI_CORE) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(state); + + return EAPL("Unknown EAPOL-Key Handshake state"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eapol_key_state_string_c::get_eapol_key_handshake_type_string( + const eapol_key_handshake_type_e handshake_type) const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(handshake_type, eapol_key_handshake_type_none) + else EAP_IF_RETURN_STRING(handshake_type, eapol_key_handshake_type_4_way_handshake) + else EAP_IF_RETURN_STRING(handshake_type, eapol_key_handshake_type_group_key_handshake) + else EAP_IF_RETURN_STRING(handshake_type, eapol_key_handshake_type_STAKey_handshake) + else EAP_IF_RETURN_STRING(handshake_type, eapol_key_handshake_type_802_11i_handshake) + else EAP_IF_RETURN_STRING(handshake_type, eapol_key_handshake_type_dynamic_WEP) +#if defined(EAP_USE_WPXM) + else EAP_IF_RETURN_STRING(handshake_type, eapol_key_handshake_type_WPXM_reassociation) +#endif //#if defined(EAP_USE_WPXM) +#if defined(USE_WAPI_CORE) + else EAP_IF_RETURN_STRING(handshake_type, eapol_key_handshake_type_wai_handshake) +#endif //#if defined(USE_WAPI_CORE) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(handshake_type); + + return EAPL("Unknown EAPOL-Key Handshake type"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eapol_key_state_string_c::get_eapol_key_authentication_type_string( + const eapol_key_authentication_type_e authentication_type) const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(authentication_type, eapol_key_authentication_type_none) + else EAP_IF_RETURN_STRING(authentication_type, eapol_key_authentication_type_RSNA_EAP) + else EAP_IF_RETURN_STRING(authentication_type, eapol_key_authentication_type_RSNA_PSK) + else EAP_IF_RETURN_STRING(authentication_type, eapol_key_authentication_type_WPA_EAP) + else EAP_IF_RETURN_STRING(authentication_type, eapol_key_authentication_type_WPA_PSK) + else EAP_IF_RETURN_STRING(authentication_type, eapol_key_authentication_type_802_1X) +#if defined(EAP_USE_WPXM) + else EAP_IF_RETURN_STRING(authentication_type, eapol_key_authentication_type_WPXM) +#endif //#if defined(EAP_USE_WPXM) + else EAP_IF_RETURN_STRING(authentication_type, eapol_key_authentication_type_WFA_SC) +#if defined(USE_WAPI_CORE) + else EAP_IF_RETURN_STRING(authentication_type, eapol_key_authentication_type_WAI_PSK) + else EAP_IF_RETURN_STRING(authentication_type, eapol_key_authentication_type_WAI_certificate) +#endif //#if defined(USE_WAPI_CORE) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(authentication_type); + + return EAPL("Unknown EAPOL-Key Authentication type"); + } +} + +//-------------------------------------------------- + +eap_const_string eapol_key_state_string_c::get_eapol_key_descriptor_type_string( + const eapol_key_descriptor_type_e key_descriptor_type) const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(key_descriptor_type, eapol_key_descriptor_type_none) + else EAP_IF_RETURN_STRING(key_descriptor_type, eapol_key_descriptor_type_RC4) + else EAP_IF_RETURN_STRING(key_descriptor_type, eapol_key_descriptor_type_RSNA) + else EAP_IF_RETURN_STRING(key_descriptor_type, eapol_key_descriptor_type_WPA) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(key_descriptor_type); + + return EAPL("Unknown EAPOL-Key Description type"); + } +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_message_wlan_authentication.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_message_wlan_authentication.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3345 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 575 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eapol_message_wlan_authentication.h" +#include "eapol_wlan_database_reference.h" +#include "eap_am_memory.h" +#include "abs_eap_state_notification.h" +#include "eap_crypto_api.h" +#include "eap_header_string.h" +#include "eap_buffer.h" +#include "eapol_session_key.h" +#include "eapol_handle_tlv_message_data.h" +#include "eap_automatic_variable.h" +#include "eap_array_algorithms.h" +#include "eap_config.h" + +//-------------------------------------------------- + +#if defined(USE_TEST_WLAN_AUTHENTICATION_MUTEX) && defined(USE_EAPOL_WLAN_AUTHENTICATION_MUTEX) + #error "You cannot define both USE_EAPOL_WLAN_AUTHENTICATION_MUTEX and USE_TEST_WLAN_AUTHENTICATION_MUTEX." +#endif + +#if !defined(USE_TEST_WLAN_AUTHENTICATION_MUTEX) && defined(USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_ASYNCRONOUS_TEST) + #error "You must define USE_TEST_WLAN_AUTHENTICATION_MUTEX if USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_ASYNCRONOUS_TEST is used." +#endif + +//-------------------------------------------------- + +/** + * This is the timer ID used with abs_eap_am_tools_c::set_timer() and abs_eap_am_tools_c::cancel_timer(). + */ +enum eapol_core_timer_id +{ + EAPOL_MESSAGE_TIMER_PROCESS_DATA_ID, + EAPOL_MESSAGE_TIMER_SEND_DATA_ID, +}; + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_message_wlan_authentication_c::~eapol_message_wlan_authentication_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_message_wlan_authentication_c::eapol_message_wlan_authentication_c( + abs_eap_am_tools_c * const tools, + abs_eapol_message_wlan_authentication_c * const partner) + : m_am_tools(tools) + , m_wauth(0) + , m_partner(partner) + , m_wlan_database_reference(tools) + , m_header_offset(0ul) + , m_MTU(0ul) + , m_trailer_length(0ul) + , m_error_code(wlan_eap_if_send_status_ok) + , m_error_function(eapol_tlv_message_type_function_none) + , m_use_asyncronous_test(false) + , m_is_valid(true) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::configure( + const u32_t header_offset, + const u32_t MTU, + const u32_t trailer_length) +{ + eap_status_e status(eap_status_ok); + + //---------------------------------------------------------- + + m_header_offset = header_offset; + m_MTU = MTU; + m_trailer_length = trailer_length; + + //---------------------------------------------------------- + + // eapol_wlan_authentication_c object uses the tools object. + m_wauth = eapol_wlan_authentication_c::new_eapol_wlan_authentication( + m_am_tools, + this, + true, + this); + if (m_wauth != 0 + && m_wauth->get_is_valid() == true) + { + status = m_wauth->configure(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAPOL_TEST_use_asyncronous_test(m_am_tools); + + eap_status_e status = m_wauth->read_configure( + cf_str_EAPOL_TEST_use_message_asyncronous_test.get_field(), + &EAPOL_TEST_use_asyncronous_test); + if (status == eap_status_ok + && EAPOL_TEST_use_asyncronous_test.get_is_valid_data() == true) + { + u32_t *use_asyncronous_test = reinterpret_cast( + EAPOL_TEST_use_asyncronous_test.get_data(sizeof(u32_t))); + if (use_asyncronous_test != 0 + && *use_asyncronous_test != 0) + { + m_use_asyncronous_test = true; + } + } + } + + //---------------------------------------------------------- + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::shutdown() +{ + // After use the eapol_wlan_authentication_c object must be deleted first. + if (m_wauth != 0) + { + m_wauth->shutdown(); + delete m_wauth; + m_wauth = 0; + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eapol_message_wlan_authentication_c::get_is_valid() +{ + return m_is_valid; +} + +// ---------------------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::timer_expired( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eapol_message_wlan_authentication_c::timer_expired") + EAPL("(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + +#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_ASYNCRONOUS_TEST) + + if (id == EAPOL_MESSAGE_TIMER_PROCESS_DATA_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eapol_message_wlan_authentication_c::timer_expired: EAPOL_MESSAGE_TIMER_PROCESS_DATA_ID") + EAPL("(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + + eapol_handle_tlv_message_data_c * const message = reinterpret_cast(data); + if (message != 0) + { + eap_status_e status = process_message(message); + + (void) EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (id == EAPOL_MESSAGE_TIMER_SEND_DATA_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eapol_message_wlan_authentication_c::timer_expired: EAPOL_MESSAGE_TIMER_SEND_DATA_ID") + EAPL("(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + + eapol_handle_tlv_message_data_c * const message = reinterpret_cast(data); + if (message != 0) + { + wlan_eap_if_send_status_e send_status = m_partner->send_data( + message->get_message_data(), + message->get_message_data_length()); + + if (send_status != wlan_eap_if_send_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, + wlan_eap_if_send_status_conversion_c::convert(send_status)); + } + } + } + +#else + + EAP_UNREFERENCED_PARAMETER(id); + EAP_UNREFERENCED_PARAMETER(data); + +#endif + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +// ---------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::timer_delete_data( + const u32_t id, void * data) +{ + +#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_ASYNCRONOUS_TEST) + + if (id == EAPOL_MESSAGE_TIMER_PROCESS_DATA_ID + || id == EAPOL_MESSAGE_TIMER_SEND_DATA_ID) + { + eapol_handle_tlv_message_data_c * const message = reinterpret_cast(data); + if (message != 0) + { + delete message; + } + } + +#else + + EAP_UNREFERENCED_PARAMETER(id); + EAP_UNREFERENCED_PARAMETER(data); + +#endif + + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + if (sent_packet->get_do_length_checks() == true) + { + if (header_offset != m_header_offset) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: packet_send: packet buffer corrupted (header_offset != %d).\n"), + m_header_offset)); + EAP_ASSERT_ALWAYS(header_offset == m_header_offset); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + else if (header_offset+data_length != sent_packet->get_data_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: packet_send: packet buffer corrupted ") + EAPL("(data_length %d != sent_packet->get_data_length() %d).\n"), + header_offset+data_length, + sent_packet->get_data_length())); + EAP_ASSERT_ALWAYS(data_length == sent_packet->get_buffer_length()); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + else if (header_offset+data_length > buffer_length) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: packet_send: packet buffer corrupted ") + EAPL("(header_offset+data_length %d > buffer_length %d).\n"), + header_offset+data_length, + buffer_length)); + EAP_ASSERT_ALWAYS(header_offset+data_length <= buffer_length); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + else if (header_offset+data_length > m_MTU) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: packet_send: packet buffer corrupted ") + EAPL("(header_offset+data_length %d > m_MTU %d).\n"), + header_offset+data_length, + m_MTU)); + EAP_ASSERT_ALWAYS(header_offset+data_length <= m_MTU); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + else + { + // Always we need at least the Ethernet header. + if (sent_packet->get_data_length() + < eapol_ethernet_header_wr_c::get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: packet_send: packet buffer corrupted ") + EAPL("(sent_packet->get_data_length() %d < ") + EAPL("eapol_ethernet_header_wr_c::get_header_length() %d).\n"), + sent_packet->get_data_length(), + eapol_ethernet_header_wr_c::get_header_length())); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + + eapol_ethernet_header_wr_c eth( + m_am_tools, + sent_packet->get_data_offset(header_offset, data_length), + data_length); + if (eth.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + + { + // Creates message data composed of Attribute-Value Pairs. + eapol_handle_tlv_message_data_c message(m_am_tools); + + if (message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message.add_parameter_data(eapol_tlv_message_type_function_packet_send); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(sent_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_message(&message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eapol_message_wlan_authentication_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Header of this module is in the beging of the buffer + // no additional header are used. + *MTU = m_MTU; + *trailer_length = m_trailer_length; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_header_offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::associate( + eapol_key_802_11_authentication_mode_e authentication_mode) +{ + eap_status_e status(eap_status_ok); + + { + // Creates message data composed of Attribute-Value Pairs. + eapol_handle_tlv_message_data_c message(m_am_tools); + + if (message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message.add_parameter_data(eapol_tlv_message_type_function_associate); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data( + eapol_tlv_message_type_eapol_key_802_11_authentication_mode, + static_cast(authentication_mode)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_message(&message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::disassociate( + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + const bool self_disassociation) +{ + eap_status_e status(eap_status_ok); + + { + // Creates message data composed of Attribute-Value Pairs. + eapol_handle_tlv_message_data_c message(m_am_tools); + + if (message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message.add_parameter_data(eapol_tlv_message_type_function_disassociate); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(self_disassociation); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_message(&message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + if (key == 0 + || key->get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: test_eapol_c::packet_data_session_key(), invalid key.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("test_eapol_c::packet_data_session_key(): key_type 0x%02x, key_index %d\n"), + key->get_key_type(), + key->get_key_index())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("test_eapol_c::packet_data_session_key"), + key->get_key()->get_data(key->get_key()->get_data_length()), + key->get_key()->get_data_length())); + + { + // Creates message data composed of Attribute-Value Pairs. + eapol_handle_tlv_message_data_c message(m_am_tools); + + if (message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message.add_parameter_data(eapol_tlv_message_type_function_packet_data_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_message(&message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eapol_message_wlan_authentication_c::state_notification( + const abs_eap_state_notification_c * const state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + { + // Creates message data composed of Attribute-Value Pairs. + eapol_handle_tlv_message_data_c message(m_am_tools); + + if (message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + + status = message.add_parameter_data(eapol_tlv_message_type_function_state_notification); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + status = message.add_parameter_data(state); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + status = send_message(&message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::add_rogue_ap(eap_array_c & /* rogue_ap_list */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::reassociate( + const eap_am_network_id_c * const send_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const PMKID) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + if (PMKID == 0 + || PMKID->get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_message_wlan_authentication_c::reassociate(), invalid PMKID.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_message_wlan_authentication_c::reassociate"), + PMKID->get_data(PMKID->get_data_length()), + PMKID->get_data_length())); + + { + // Creates message data composed of Attribute-Value Pairs. + eapol_handle_tlv_message_data_c message(m_am_tools); + + if (message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message.add_parameter_data(eapol_tlv_message_type_function_reassociate); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data( + eapol_tlv_message_type_eapol_key_authentication_type, + static_cast(authentication_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(PMKID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_message(&message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::get_wlan_database_reference_values( + eap_variable_data_c * const reference) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_wlan_database_reference.get_is_valid_data() == true + && m_wlan_database_reference.get_data_length() > 0ul) + { + + return reference->set_copy_of_buffer(&m_wlan_database_reference); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: get_header_offset(): no completed parameters.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT) + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::send_error_message( + const eap_status_e function_status, + const eapol_tlv_message_type_function_e function) +{ + wlan_eap_if_send_status_e error_code = wlan_eap_if_send_status_conversion_c::convert(function_status); + + eap_status_e status(eap_status_ok); + + { + // Creates message data composed of Attribute-Value Pairs. + eapol_handle_tlv_message_data_c message(m_am_tools); + + if (message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message.add_parameter_data( + eapol_tlv_message_type_error, + static_cast(error_code)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(function); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_message(&message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +// +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::save_simple_config_session( + const simple_config_state_e /* state */, + EAP_TEMPLATE_CONST eap_array_c * const credential_array, + const eap_variable_data_c * const /* new_password */, + const simple_config_Device_Password_ID_e /* Device_Password_ID */, + const simple_config_payloads_c * const /* other_configuration */) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_message_wlan_authentication_c::save_simple_config_session()\n"))); + + // Message is formatted as: + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | Type = Function | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 4 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Value = New_protected_setup_credentials | + // +#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+ <= start of Array of Protected setup credential + // | Type = Array | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 137 | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ <= start of Array of Protected setup credential value + // | Type = Protected setup credential | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 129 | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | Type = Unsigned 8 bit integer | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 1 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | u8_t value | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | Type = Variable data | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 12 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Value = SSID string | + // +-+-+-+- -+-+-+-+ + // | | + // +-+-+-+- -+-+-+-+ + // | | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | Type = Unsigned 16 bit integer | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 2 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | u16_t Authentication type | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | Type = Unsigned 16 bit integer | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 2 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | u16_t Encryption type | + // +#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+ <= start of Array of Network key + // | Type = Array | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 66 | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ <= start of Array of Network key value + // | Type = Network key | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 25 | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | Type = Unsigned 8 bit integer | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 1 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | u8_t value | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | Type = Variable data | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 8 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Value = Network key | + // +-+-+-+- -+-+-+-+ + // | | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | Type = Network key | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 25 | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | Type = Unsigned 8 bit integer | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 1 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | u8_t value | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | Type = Variable data | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 8 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Value = Network key | + // +-+-+-+- -+-+-+-+ + // | | + // +#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+ <= end of Array of Network key + // | Type = Variable data | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Length = 6 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Value = MAC address | + // +-+-+-+- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // +#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+ <= end of Array of Protected setup credential + + + eap_status_e status(eap_status_ok); + + { + // Creates message data composed of Attribute-Value Pairs. + eapol_handle_tlv_message_data_c message(m_am_tools); + + if (message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message.add_parameter_data(eapol_tlv_message_type_function_new_protected_setup_credentials); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(credential_array); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_message(&message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::process_message_type_error( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + eap_status_e status(eap_status_ok); + + { + // Error payload is the first in this case. + const eap_tlv_header_c * const error_header = parameters->get_object(eapol_message_payload_index_function); + + if (error_header == 0 + || error_header->get_type() != eapol_tlv_message_type_error) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(error_header, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_error_code = static_cast(value); + } + + { + // Fuction payload is the second in this case. + const eap_tlv_header_c * const function_header = parameters->get_object(eapol_message_payload_index_first_parameter); + + if (function_header == 0 + || function_header->get_type() != eapol_tlv_message_type_function) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(function_header, &m_error_function); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::send_message(eapol_handle_tlv_message_data_c * const message) +{ + // Sends message data composed of Attribute-Value Pairs. + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_message_wlan_authentication_c::send_message()"), + message->get_message_data(), + message->get_message_data_length())); + +#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_ASYNCRONOUS_TEST) + + if (m_use_asyncronous_test == true) + { + eap_status_e status(eap_status_ok); + + eapol_handle_tlv_message_data_c * copy_message = new eapol_handle_tlv_message_data_c(m_am_tools); + + eap_automatic_variable_c automatic_message(m_am_tools, copy_message); + + if (copy_message == 0 + || copy_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + status = eap_status_allocation_error; + + (void) send_error_message( + status, + eapol_tlv_message_type_function_none); + + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = copy_message->copy_message_data( + message->get_message_data_length(), + message->get_message_data()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + (void) send_error_message( + status, + eapol_tlv_message_type_function_none); + + return EAP_STATUS_RETURN(m_am_tools, status); + } + + automatic_message.do_not_free_variable(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: eapol_message_wlan_authentication_c::process_data(): sets EAPOL_MESSAGE_TIMER_SEND_DATA_ID\n"))); + + status = m_am_tools->am_set_timer( + this, + EAPOL_MESSAGE_TIMER_SEND_DATA_ID, + copy_message, + 0ul); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + +#endif + + { + wlan_eap_if_send_status_e send_status = m_partner->send_data( + message->get_message_data(), + message->get_message_data_length()); + if (send_status != wlan_eap_if_send_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, + wlan_eap_if_send_status_conversion_c::convert(send_status)); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, + wlan_eap_if_send_status_conversion_c::convert(send_status)); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT wlan_eap_if_send_status_e eapol_message_wlan_authentication_c::process_data(const void * const data, const u32_t length) +{ + // Parses message data composed of Attribute-Value Pairs. + + eap_status_e status(eap_status_ok); + +#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_ASYNCRONOUS_TEST) + + if (m_use_asyncronous_test == true) + { + eapol_handle_tlv_message_data_c * message = new eapol_handle_tlv_message_data_c(m_am_tools); + + eap_automatic_variable_c automatic_message(m_am_tools, message); + + if (message == 0 + || message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + status = eap_status_allocation_error; + + (void) send_error_message( + status, + eapol_tlv_message_type_function_none); + + return wlan_eap_if_send_status_conversion_c::convert( + EAP_STATUS_RETURN(m_am_tools, status)); + } + + status = message->copy_message_data(length, data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + (void) send_error_message( + status, + eapol_tlv_message_type_function_none); + + return wlan_eap_if_send_status_conversion_c::convert( + EAP_STATUS_RETURN(m_am_tools, status)); + } + + automatic_message.do_not_free_variable(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: eapol_message_wlan_authentication_c::process_data(): sets EAPOL_MESSAGE_TIMER_PROCESS_DATA_ID\n"))); + + status = m_am_tools->am_set_timer( + this, + EAPOL_MESSAGE_TIMER_PROCESS_DATA_ID, + message, + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return wlan_eap_if_send_status_conversion_c::convert( + EAP_STATUS_RETURN(m_am_tools, status)); + } + } + else + +#endif + + { + eapol_handle_tlv_message_data_c message(m_am_tools); + + if (message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + status = eap_status_allocation_error; + + (void) send_error_message( + status, + eapol_tlv_message_type_function_none); + + return wlan_eap_if_send_status_conversion_c::convert( + EAP_STATUS_RETURN(m_am_tools, status)); + } + + status = message.set_message_data(length, data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + (void) send_error_message( + status, + eapol_tlv_message_type_function_none); + + return wlan_eap_if_send_status_conversion_c::convert( + EAP_STATUS_RETURN(m_am_tools, status)); + } + + status = process_message(&message); + } + + return wlan_eap_if_send_status_conversion_c::convert( + EAP_STATUS_RETURN(m_am_tools, status)); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::process_message(eapol_handle_tlv_message_data_c * const message) +{ + // Parses message data composed of Attribute-Value Pairs. + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("eapol_message_wlan_authentication_c::process_message()"), + message->get_message_data(), + message->get_message_data_length())); + + eap_array_c parameters(m_am_tools); + + eap_status_e status = message->parse_message_data(¶meters); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + (void) send_error_message( + status, + eapol_tlv_message_type_function_none); + + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (parameters.get_object_count() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + status = eap_status_illegal_parameter; + + (void) send_error_message( + status, + eapol_tlv_message_type_function_none); + + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const eap_tlv_header_c * const function_header = parameters.get_object(eapol_message_payload_index_function); + if (function_header == 0 + || (function_header->get_type() != eapol_tlv_message_type_error + && function_header->get_type() != eapol_tlv_message_type_function)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + status = eap_status_illegal_parameter; + + (void) send_error_message( + status, + eapol_tlv_message_type_function_none); + + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (function_header->get_type() == eapol_tlv_message_type_error) + { + status = process_message_type_error(¶meters); + } + else // function_header->get_type() == eapol_tlv_message_type_function + { + eapol_tlv_message_type_function_e function(eapol_tlv_message_type_function_none); + + status = message->get_parameter_data(function_header, &function); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + (void) send_error_message( + status, + eapol_tlv_message_type_function_none); + + return EAP_STATUS_RETURN(m_am_tools, status); + } + + switch(function) + { + case eapol_tlv_message_type_function_check_pmksa_cache: + status = check_pmksa_cache(¶meters); + break; + case eapol_tlv_message_type_function_start_authentication: + status = start_authentication(¶meters); + break; + case eapol_tlv_message_type_function_complete_association: + status = complete_association(¶meters); + break; + case eapol_tlv_message_type_function_disassociation: + status = disassociation(¶meters); + break; + case eapol_tlv_message_type_function_start_preauthentication: + status = start_preauthentication(¶meters); + break; + case eapol_tlv_message_type_function_start_reassociation: + status = start_reassociation(¶meters); + break; + case eapol_tlv_message_type_function_complete_reassociation: + status = complete_reassociation(¶meters); + break; + case eapol_tlv_message_type_function_start_WPXM_reassociation: + status = start_WPXM_reassociation(¶meters); + break; + case eapol_tlv_message_type_function_complete_WPXM_reassociation: + status = complete_WPXM_reassociation(¶meters); + break; + case eapol_tlv_message_type_function_packet_process: + status = packet_process(¶meters); + break; + case eapol_tlv_message_type_function_tkip_mic_failure: + status = tkip_mic_failure(¶meters); + break; + case eapol_tlv_message_type_function_eap_acknowledge: + status = eap_acknowledge(¶meters); + break; + case eapol_tlv_message_type_function_update_header_offset: + status = update_header_offset(¶meters); + break; + case eapol_tlv_message_type_function_update_wlan_database_reference_values: + status = update_wlan_database_reference_values(¶meters); + break; + default: + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: process_data(): unknown function %d.\n"), + function)); + + status = eap_status_illegal_parameter; + }; + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_pending_request + && status != eap_status_completed_request + && status != eap_status_drop_packet_quietly) + { + (void) send_error_message( + status, + function); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::check_pmksa_cache( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eap_array_c bssid_sta_receive_network_ids(m_am_tools); + + { + const eap_tlv_header_c * const array_of_network_ids + = parameters->get_object(parameter_index); + + if (array_of_network_ids == 0 + || array_of_network_ids->get_type() != eapol_tlv_message_type_array) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c array_data(m_am_tools); + + if (array_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = array_data.set_message_data( + array_of_network_ids->get_value_length(), + array_of_network_ids->get_value(array_of_network_ids->get_value_length())); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_array_c network_ids(m_am_tools); + + status = array_data.parse_message_data( + &network_ids); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (u32_t ind = 0ul; ind < network_ids.get_object_count(); ++ind) + { + const eap_tlv_header_c * const header = network_ids.get_object(ind); + + if (header == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_network_id_c * const new_network_id = new eap_am_network_id_c(m_am_tools); + if (new_network_id == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_automatic_variable_c automatic_new_network_id(m_am_tools, new_network_id); + + status = array_data.get_parameter_data(header, new_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + automatic_new_network_id.do_not_free_variable(); + + status = bssid_sta_receive_network_ids.add_object( + new_network_id, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } // for() + } + + + ++parameter_index; + + eapol_key_authentication_type_e selected_eapol_key_authentication_type(eapol_key_authentication_type_none); + + { + const eap_tlv_header_c * const authentication_type + = parameters->get_object(parameter_index); + + if (authentication_type == 0 + || authentication_type->get_type() != eapol_tlv_message_type_eapol_key_authentication_type) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(authentication_type, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + selected_eapol_key_authentication_type = static_cast(value); + } + + + ++parameter_index; + + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none); + + { + const eap_tlv_header_c * const authentication_type + = parameters->get_object(parameter_index); + + if (authentication_type == 0 + || authentication_type->get_type() != eapol_tlv_message_type_RSNA_cipher) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(authentication_type, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + pairwise_key_cipher_suite = static_cast(value); + } + + + ++parameter_index; + + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none); + + { + const eap_tlv_header_c * const authentication_type + = parameters->get_object(parameter_index); + + if (authentication_type == 0 + || authentication_type->get_type() != eapol_tlv_message_type_RSNA_cipher) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(authentication_type, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + group_key_cipher_suite = static_cast(value); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_wauth->check_pmksa_cache( + &bssid_sta_receive_network_ids, + selected_eapol_key_authentication_type, + pairwise_key_cipher_suite, + group_key_cipher_suite); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (status == eap_status_ok + || status == eap_status_not_found) + { + // Creates message data composed of Attribute-Value Pairs. + eapol_handle_tlv_message_data_c message(m_am_tools); + + if (message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message.add_parameter_data( + eapol_tlv_message_type_function_complete_check_pmksa_cache); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t network_id_parameters_size(0ul); + u32_t ind = 0ul; + + // Calculates the message size. + for (ind = 0ul; ind < bssid_sta_receive_network_ids.get_object_count(); ++ind) + { + const eap_am_network_id_c * const network_id = bssid_sta_receive_network_ids.get_object(ind); + if (network_id == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + network_id_parameters_size += + eap_tlv_header_c::get_header_length() + + message.get_payload_size(network_id); + } + + status = message.add_structured_parameter_header( + eapol_tlv_message_type_array, + network_id_parameters_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Adds network ID array objects to message. + for (ind = 0ul; ind < bssid_sta_receive_network_ids.get_object_count(); ++ind) + { + const eap_am_network_id_c * const network_id = bssid_sta_receive_network_ids.get_object(ind); + if (network_id == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = message.add_parameter_data( + network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = send_message(&message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::start_authentication( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eap_variable_data_c SSID(m_am_tools); + + if (SSID.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + const eap_tlv_header_c * const ssid_parameter + = parameters->get_object(parameter_index); + + if (ssid_parameter == 0 + || ssid_parameter->get_type() != eapol_tlv_message_type_variable_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(ssid_parameter, &SSID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + eapol_key_authentication_type_e selected_eapol_key_authentication_type(eapol_key_authentication_type_none); + + { + const eap_tlv_header_c * const authentication_type_parameter + = parameters->get_object(parameter_index); + + if (authentication_type_parameter == 0 + || authentication_type_parameter->get_type() != eapol_tlv_message_type_eapol_key_authentication_type) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(authentication_type_parameter, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + selected_eapol_key_authentication_type = static_cast(value); + } + + + ++parameter_index; + + eap_variable_data_c wpa_preshared_key(m_am_tools); + + { + const eap_tlv_header_c * const wpa_preshared_key_parameter + = parameters->get_object(parameter_index); + + if (wpa_preshared_key_parameter == 0 + || wpa_preshared_key_parameter->get_type() != eapol_tlv_message_type_variable_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(wpa_preshared_key_parameter, &wpa_preshared_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + bool WPA_override_enabled(false); + + { + const eap_tlv_header_c * const WPA_override_enabled_parameter + = parameters->get_object(parameter_index); + + if (WPA_override_enabled_parameter == 0 + || WPA_override_enabled_parameter->get_type() != eapol_tlv_message_type_boolean) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(WPA_override_enabled_parameter, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + WPA_override_enabled = (value == 0) ? false: true; + } + + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + ++parameter_index; + + eap_am_network_id_c receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (receive_network_id_parameter == 0 + || receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_wauth->start_authentication( + &SSID, + selected_eapol_key_authentication_type, + &wpa_preshared_key, + WPA_override_enabled +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + , &receive_network_id +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::complete_association( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eapol_wlan_authentication_state_e association_result(eapol_wlan_authentication_state_none); + + { + const eap_tlv_header_c * const association_result_parameter + = parameters->get_object(parameter_index); + + if (association_result_parameter == 0 + || association_result_parameter->get_type() != eapol_tlv_message_type_eapol_wlan_authentication_state) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(association_result_parameter, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + association_result = static_cast(value); + } + + + ++parameter_index; + + eap_am_network_id_c receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (receive_network_id_parameter == 0 + || receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + eap_variable_data_c received_WPA_IE(m_am_tools); + + { + const eap_tlv_header_c * const received_WPA_IE_parameter + = parameters->get_object(parameter_index); + + if (received_WPA_IE_parameter == 0 + || received_WPA_IE_parameter->get_type() != eapol_tlv_message_type_variable_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(received_WPA_IE_parameter, &received_WPA_IE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + eap_variable_data_c sent_WPA_IE(m_am_tools); + + { + const eap_tlv_header_c * const sent_WPA_IE_parameter + = parameters->get_object(parameter_index); + + if (sent_WPA_IE_parameter == 0 + || sent_WPA_IE_parameter->get_type() != eapol_tlv_message_type_variable_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(sent_WPA_IE_parameter, &sent_WPA_IE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none); + + { + const eap_tlv_header_c * const pairwise_key_cipher_suite_parameter + = parameters->get_object(parameter_index); + + if (pairwise_key_cipher_suite_parameter == 0 + || pairwise_key_cipher_suite_parameter->get_type() != eapol_tlv_message_type_RSNA_cipher) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(pairwise_key_cipher_suite_parameter, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + pairwise_key_cipher_suite = static_cast(value); + } + + ++parameter_index; + + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none); + + { + const eap_tlv_header_c * const group_key_cipher_suite_parameter + = parameters->get_object(parameter_index); + + if (group_key_cipher_suite_parameter == 0 + || group_key_cipher_suite_parameter->get_type() != eapol_tlv_message_type_RSNA_cipher) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(group_key_cipher_suite_parameter, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + group_key_cipher_suite = static_cast(value); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_wauth->complete_association( + association_result, + &receive_network_id, ///< source includes remote address, destination includes local address. + &received_WPA_IE, // WLM must give only the WPA IE to EAPOL + &sent_WPA_IE, + pairwise_key_cipher_suite, + group_key_cipher_suite + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::disassociation( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eap_am_network_id_c receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (receive_network_id_parameter == 0 + || receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_wauth->disassociation( + &receive_network_id ///< source includes remote address, destination includes local address. + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::start_preauthentication( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eap_am_network_id_c receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (receive_network_id_parameter == 0 + || receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_wauth->start_preauthentication( + &receive_network_id ///< source includes remote address, destination includes local address. + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::start_reassociation( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eap_am_network_id_c old_receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const old_receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (old_receive_network_id_parameter == 0 + || old_receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(old_receive_network_id_parameter, &old_receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + ++parameter_index; + + eap_am_network_id_c new_receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const new_receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (new_receive_network_id_parameter == 0 + || new_receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(new_receive_network_id_parameter, &new_receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + eapol_key_authentication_type_e selected_eapol_key_authentication_type(eapol_key_authentication_type_none); + + { + const eap_tlv_header_c * const authentication_type + = parameters->get_object(parameter_index); + + if (authentication_type == 0 + || authentication_type->get_type() != eapol_tlv_message_type_eapol_key_authentication_type) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(authentication_type, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + selected_eapol_key_authentication_type = static_cast(value); + } + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_wauth->start_reassociation( + &old_receive_network_id, + &new_receive_network_id, + selected_eapol_key_authentication_type); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::complete_reassociation( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eapol_wlan_authentication_state_e association_result(eapol_wlan_authentication_state_none); + + { + const eap_tlv_header_c * const association_result_parameter + = parameters->get_object(parameter_index); + + if (association_result_parameter == 0 + || association_result_parameter->get_type() != eapol_tlv_message_type_eapol_wlan_authentication_state) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(association_result_parameter, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + association_result = static_cast(value); + } + + + ++parameter_index; + + eap_am_network_id_c receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (receive_network_id_parameter == 0 + || receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + eap_variable_data_c received_WPA_IE(m_am_tools); + + { + const eap_tlv_header_c * const received_WPA_IE_parameter + = parameters->get_object(parameter_index); + + if (received_WPA_IE_parameter == 0 + || received_WPA_IE_parameter->get_type() != eapol_tlv_message_type_variable_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(received_WPA_IE_parameter, &received_WPA_IE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + eap_variable_data_c sent_WPA_IE(m_am_tools); + + { + const eap_tlv_header_c * const sent_WPA_IE_parameter + = parameters->get_object(parameter_index); + + if (sent_WPA_IE_parameter == 0 + || sent_WPA_IE_parameter->get_type() != eapol_tlv_message_type_variable_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(sent_WPA_IE_parameter, &sent_WPA_IE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none); + + { + const eap_tlv_header_c * const pairwise_key_cipher_suite_parameter + = parameters->get_object(parameter_index); + + if (pairwise_key_cipher_suite_parameter == 0 + || pairwise_key_cipher_suite_parameter->get_type() != eapol_tlv_message_type_RSNA_cipher) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(pairwise_key_cipher_suite_parameter, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + pairwise_key_cipher_suite = static_cast(value); + } + + ++parameter_index; + + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none); + + { + const eap_tlv_header_c * const group_key_cipher_suite_parameter + = parameters->get_object(parameter_index); + + if (group_key_cipher_suite_parameter == 0 + || group_key_cipher_suite_parameter->get_type() != eapol_tlv_message_type_RSNA_cipher) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(group_key_cipher_suite_parameter, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + group_key_cipher_suite = static_cast(value); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_wauth->complete_reassociation( + association_result, + &receive_network_id, ///< source includes remote address, destination includes local address. + &received_WPA_IE, // WLM must give only the WPA IE to EAPOL + &sent_WPA_IE, + pairwise_key_cipher_suite, + group_key_cipher_suite + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::start_WPXM_reassociation( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eap_am_network_id_c old_receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (receive_network_id_parameter == 0 + || receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(receive_network_id_parameter, &old_receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + ++parameter_index; + + eap_am_network_id_c new_receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (receive_network_id_parameter == 0 + || receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(receive_network_id_parameter, &new_receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + ++parameter_index; + + eap_variable_data_c send_reassociation_request_ie(m_am_tools); + + { + const eap_tlv_header_c * const send_reassociation_request_ie_parameter + = parameters->get_object(parameter_index); + + if (send_reassociation_request_ie_parameter == 0 + || send_reassociation_request_ie_parameter->get_type() != eapol_tlv_message_type_variable_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(send_reassociation_request_ie_parameter, &send_reassociation_request_ie); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + ++parameter_index; + + eap_variable_data_c received_WPA_ie(m_am_tools); + + if (parameters->get_object_count() > parameter_index) + { + const eap_tlv_header_c * const send_reassociation_request_ie_parameter + = parameters->get_object(parameter_index); + + if (send_reassociation_request_ie_parameter != 0 + && send_reassociation_request_ie_parameter->get_type() == eapol_tlv_message_type_variable_data) + { + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(send_reassociation_request_ie_parameter, &received_WPA_ie); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + ++parameter_index; + + eap_variable_data_c sent_WPA_ie(m_am_tools); + + if (parameters->get_object_count() > parameter_index) + { + const eap_tlv_header_c * const send_reassociation_request_ie_parameter + = parameters->get_object(parameter_index); + + if (send_reassociation_request_ie_parameter != 0 + && send_reassociation_request_ie_parameter->get_type() == eapol_tlv_message_type_variable_data) + { + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(send_reassociation_request_ie_parameter, &sent_WPA_ie); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_wauth->start_WPXM_reassociation( + &old_receive_network_id, + &new_receive_network_id, + &send_reassociation_request_ie, + &received_WPA_ie, + &sent_WPA_ie); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (status == eap_status_ok) + { + // Creates message data composed of Attribute-Value Pairs. + eapol_handle_tlv_message_data_c message(m_am_tools); + + if (message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message.add_parameter_data(eapol_tlv_message_type_function_complete_start_WPXM_reassociation); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(&new_receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message.add_parameter_data(&send_reassociation_request_ie); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_message(&message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::complete_WPXM_reassociation( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eapol_wlan_authentication_state_e reassociation_result(eapol_wlan_authentication_state_none); + + { + const eap_tlv_header_c * const reassociation_result_parameter + = parameters->get_object(parameter_index); + + if (reassociation_result_parameter == 0 + || reassociation_result_parameter->get_type() != eapol_tlv_message_type_eapol_wlan_authentication_state) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(reassociation_result_parameter, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + reassociation_result = static_cast(value); + } + + + ++parameter_index; + + eap_am_network_id_c receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (receive_network_id_parameter == 0 + || receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + eap_variable_data_c received_reassociation_ie(m_am_tools); + + { + const eap_tlv_header_c * const received_reassociation_ie_parameter + = parameters->get_object(parameter_index); + + if (received_reassociation_ie_parameter == 0 + || received_reassociation_ie_parameter->get_type() != eapol_tlv_message_type_variable_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(received_reassociation_ie_parameter, &received_reassociation_ie); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_wauth->complete_WPXM_reassociation( + reassociation_result, + &receive_network_id, + &received_reassociation_ie); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::packet_process( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eap_am_network_id_c receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (receive_network_id_parameter == 0 + || receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + eap_variable_data_c packet_data_payload(m_am_tools); + + { + const eap_tlv_header_c * const packet_data_parameter + = parameters->get_object(parameter_index); + + if (packet_data_parameter == 0 + || packet_data_parameter->get_type() != eapol_tlv_message_type_variable_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(packet_data_parameter, &packet_data_payload); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eapol_ethernet_header_wr_c eth( + m_am_tools, + packet_data_payload.get_data(), + packet_data_payload.get_data_length()); + if (eth.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_wauth->packet_process( + &receive_network_id, + ð, + packet_data_payload.get_data_length() + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::tkip_mic_failure( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eap_am_network_id_c receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (receive_network_id_parameter == 0 + || receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + ++parameter_index; + + bool fatal_failure_when_true(false); + + { + const eap_tlv_header_c * const fatal_failure_when_true_parameter + = parameters->get_object(parameter_index); + + if (fatal_failure_when_true_parameter == 0 + || fatal_failure_when_true_parameter->get_type() != eapol_tlv_message_type_boolean) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(fatal_failure_when_true_parameter, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + fatal_failure_when_true = (value == 0) ? false: true; + } + + + ++parameter_index; + + eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type(eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_group_key); + + { + const eap_tlv_header_c * const tkip_mic_failure_type_parameter + = parameters->get_object(parameter_index); + + if (tkip_mic_failure_type_parameter == 0 + || tkip_mic_failure_type_parameter->get_type() != eapol_tlv_message_type_eapol_tkip_mic_failure_type) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t value(0ul); + + status = message_data.get_parameter_data(tkip_mic_failure_type_parameter, &value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + tkip_mic_failure_type = static_cast(value); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_wauth->tkip_mic_failure( + &receive_network_id, + fatal_failure_when_true, + tkip_mic_failure_type + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::eap_acknowledge( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + eap_am_network_id_c receive_network_id(m_am_tools); + + { + const eap_tlv_header_c * const receive_network_id_parameter + = parameters->get_object(parameter_index); + + if (receive_network_id_parameter == 0 + || receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_wauth->eap_acknowledge( + &receive_network_id ///< source includes remote address, destination includes local address. + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::update_header_offset( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + { + const eap_tlv_header_c * const header_offset_value_parameter + = parameters->get_object(parameter_index); + + if (header_offset_value_parameter == 0 + || header_offset_value_parameter->get_type() != eapol_tlv_message_type_u32_t) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(header_offset_value_parameter, &m_header_offset); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + { + const eap_tlv_header_c * const MTU_value_parameter + = parameters->get_object(parameter_index); + + if (MTU_value_parameter == 0 + || MTU_value_parameter->get_type() != eapol_tlv_message_type_u32_t) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(MTU_value_parameter, &m_MTU); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + ++parameter_index; + + { + const eap_tlv_header_c * const trailer_length_parameter + = parameters->get_object(parameter_index); + + if (trailer_length_parameter == 0 + || trailer_length_parameter->get_type() != eapol_tlv_message_type_u32_t) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(trailer_length_parameter, &m_trailer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_message_wlan_authentication_c::update_wlan_database_reference_values( + EAP_TEMPLATE_CONST eap_array_c * const parameters) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + u32_t parameter_index(eapol_message_payload_index_first_parameter); + + { + const eap_tlv_header_c * const reference_parameter + = parameters->get_object(parameter_index); + + if (reference_parameter == 0 + || reference_parameter->get_type() != eapol_tlv_message_type_variable_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eapol_handle_tlv_message_data_c message_data(m_am_tools); + + if (message_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_data.get_parameter_data(reference_parameter, &m_wlan_database_reference); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- +// End of file. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_rc4_key_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_rc4_key_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,369 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 52 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eapol_rc4_key_header.h" + + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_RC4_key_header_c::~eapol_RC4_key_header_c() +{ +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_RC4_key_header_c::eapol_RC4_key_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) +{ +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_protocol_version_e eapol_RC4_key_header_c::get_eapol_protocol_version() const +{ + const u8_t * const data = get_header_offset(m_offset_eapol_version, sizeof(u8_t)); + if (data != 0) + { + return static_cast(*data); + } + else + { + return eapol_protocol_version_none; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_packet_type_e eapol_RC4_key_header_c::get_eapol_packet_type() const +{ + const u8_t * const data = get_header_offset(m_offset_eapol_type, sizeof(u8_t)); + if (data != 0) + { + return static_cast(*data); + } + else + { + return eapol_packet_type_no_type; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u16_t eapol_RC4_key_header_c::get_eapol_packet_body_length() const +{ + const u8_t * const data = get_header_offset(m_offset_eapol_packet_body_length, sizeof(u16_t)); + if (data != 0) + { + return eap_read_u16_t_network_order(data, sizeof(u16_t)); + } + else + { + return 0ul; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_key_descriptor_type_e eapol_RC4_key_header_c::get_key_descriptor_type() const +{ + const u8_t * const data = get_header_offset(m_offset_key_descriptor_type, sizeof(u8_t)); + if (data != 0) + { + return static_cast(*data); + } + else + { + return eapol_key_descriptor_type_none; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u16_t eapol_RC4_key_header_c::get_key_length() const +{ + const u8_t * const data = get_header_offset(m_offset_key_length, sizeof(u16_t)); + if (data != 0) + { + return eap_read_u16_t_network_order(data, sizeof(u16_t)); + } + else + { + return 0ul; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t *eapol_RC4_key_header_c::get_replay_counter() +{ + u8_t * const data = get_header_offset(m_offset_replay_counter, EAPOL_RC4_KEY_REPLAY_COUNTER_LENGTH); + return data; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t *eapol_RC4_key_header_c::get_key_IV() +{ + u8_t * const data = get_header_offset(m_offset_key_IV, EAPOL_RC4_KEY_IV_LENGTH); + return data; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_RC4_key_flags_e eapol_RC4_key_header_c::get_key_flag() const +{ + const u8_t * const data = get_header_offset(m_offset_key_index, sizeof(u8_t)); + if (data != 0) + { + return static_cast((((*data) & m_flag_mask_key_flag) >> m_flag_shift_key_flag)); + } + else + { + return eapol_RC4_key_flag_none; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t eapol_RC4_key_header_c::get_key_index() const +{ + const u8_t * const data = get_header_offset(m_offset_key_index, sizeof(u8_t)); + if (data != 0) + { + return static_cast(((*data) & ~m_flag_mask_key_flag)); + } + else + { + // This is illegal index. + return 0xff; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t *eapol_RC4_key_header_c::get_key_signature() const +{ + u8_t * const data = get_header_offset(m_offset_key_signature, EAPOL_RC4_KEY_SIGNATURE_LENGTH); + return data; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u16_t eapol_RC4_key_header_c::get_header_length() +{ + return m_offset_data; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t * eapol_RC4_key_header_c::get_key() const +{ + if (get_eapol_packet_body_length() > SIZE_OF_EMPTY_EAPOL_RC4_KEY_BODY) + { + u8_t * const data = get_header_offset( + m_offset_data, + get_header_buffer_length() - SIZE_OF_EMPTY_EAPOL_RC4_KEY_FRAME); + return data; // Data begins after the header. + } + return 0; +} + +//------------------------------------------------------ +//------------------------------------------------------ +//------------------------------------------------------ + +EAP_FUNC_EXPORT eap_status_e eapol_RC4_key_header_c::set_eapol_protocol_version(eapol_protocol_version_e version) +{ + u8_t * const data = get_header_offset(m_offset_eapol_version, sizeof(u8_t)); + if (data != 0) + { + *data = static_cast(version); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +EAP_FUNC_EXPORT eap_status_e eapol_RC4_key_header_c::set_eapol_packet_type(eapol_packet_type_e type) +{ + u8_t * const data = get_header_offset(m_offset_eapol_type, sizeof(u8_t)); + if (data != 0) + { + *data = static_cast(type); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +EAP_FUNC_EXPORT eap_status_e eapol_RC4_key_header_c::set_eapol_packet_body_length(u16_t eapol_length) +{ + if (eapol_length - eapol_header_base_c::get_header_length() > eapol_RC4_key_header_c::EAPOL_RC4_EAPOL_KEY_MAXIMUM_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + u8_t * const data = get_header_offset(m_offset_eapol_packet_body_length, sizeof(u16_t)); + if (data != 0) + { + const u16_t eapol_length_u16_t = static_cast(eapol_length); + return eap_write_u16_t_network_order(data, sizeof(u16_t), eapol_length_u16_t); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +EAP_FUNC_EXPORT eap_status_e eapol_RC4_key_header_c::set_key_descriptor_type(eapol_key_descriptor_type_e eapol_key_descriptor_type) +{ + u8_t * const data = get_header_offset(m_offset_key_descriptor_type, sizeof(u8_t)); + if (data != 0) + { + *data = static_cast(eapol_key_descriptor_type); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +EAP_FUNC_EXPORT eap_status_e eapol_RC4_key_header_c::set_key_length(u16_t length) +{ + u8_t * const data = get_header_offset(m_offset_key_length, sizeof(u16_t)); + if (data != 0) + { + return eap_write_u16_t_network_order(data, sizeof(u16_t), length); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +EAP_FUNC_EXPORT eap_status_e eapol_RC4_key_header_c::set_key_flag(eapol_RC4_key_flags_e flags) +{ + u8_t * const data = get_header_offset(m_offset_key_index, sizeof(u8_t)); + if (data != 0) + { + *data = ((*data) & ~m_flag_mask_key_flag) | static_cast((((flags << m_flag_shift_key_flag) & m_flag_mask_key_flag))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +EAP_FUNC_EXPORT eap_status_e eapol_RC4_key_header_c::set_key_index(u8_t index) +{ + u8_t * const data = get_header_offset(m_offset_key_index, sizeof(u8_t)); + if (data != 0) + { + *data = ((*data) & m_flag_mask_key_flag) | static_cast((index & ~m_flag_mask_key_flag)); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + + +//------------------------------------------------------ +//------------------------------------------------------ +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT void eapol_RC4_key_header_c::zero_key_signature( + abs_eap_am_tools_c * const m_am_tools + ) +{ + u8_t * const signature = get_key_signature(); + m_am_tools->memset(signature, 0, EAPOL_RC4_KEY_SIGNATURE_LENGTH); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RC4_key_header_c::check_header() const +{ + if (get_eapol_protocol_version() == eapol_protocol_version_none) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_version); + } + else if (get_eapol_packet_type() > eapol_packet_type_enc_asf_alert) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------ +//------------------------------------------------------ +//------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_rsna_key_data_gtk_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_rsna_key_data_gtk_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,260 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 53 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eapol_rsna_key_data_gtk_header.h" + + +//------------------------------------------------------ + +// +eapol_rsna_key_data_gtk_header_c::~eapol_rsna_key_data_gtk_header_c() +{ +} + +//------------------------------------------------------ + +// +eapol_rsna_key_data_gtk_header_c::eapol_rsna_key_data_gtk_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) +{ +} + +//------------------------------------------------------ + +// +u8_t eapol_rsna_key_data_gtk_header_c::get_key_index() const +{ + const u8_t * const data = get_header_offset(m_offset_flags, EAPOL_RSNA_KEY_DATA_FLAGS_FIELD_SIZE); + if (data != 0) + { + return static_cast(((*data) & EAPOL_RSNA_KEY_DATA_GTK_INDEX_MASK) >> EAPOL_RSNA_KEY_DATA_GTK_INDEX_SHIFT); + } + else + { + return EAPOL_RSNA_KEY_DATA_INVALID_GTK_INDEX; + } +} + +//------------------------------------------------------ + +// +bool eapol_rsna_key_data_gtk_header_c::get_tx_bit() const +{ + const u8_t * const data = get_header_offset(m_offset_flags, EAPOL_RSNA_KEY_DATA_FLAGS_FIELD_SIZE); + if (data != 0) + { + u8_t flag = static_cast(((*data) & EAPOL_RSNA_KEY_DATA_TX_MASK) >> EAPOL_RSNA_KEY_DATA_TX_SHIFT); + if (flag != 0) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } +} + +//------------------------------------------------------ + +// +u8_t * eapol_rsna_key_data_gtk_header_c::get_gtk_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + u32_t GTK_buffer_length = get_header_buffer_length() - get_header_length(); + + if (GTK_buffer_length >= offset+contignuous_bytes) + { + // This is pointer to the offset of the Data. + u8_t * const data = get_header_offset(m_offset_gtk, offset+contignuous_bytes); + if (data != 0) + { + return &data[offset]; + } + else + { + return 0; + } + } + else + { + EAP_ASSERT_ALWAYS(GTK_buffer_length >= offset+contignuous_bytes); + } + return 0; +} + +//------------------------------------------------------ + +// +u8_t * eapol_rsna_key_data_gtk_header_c::get_gtk(const u32_t contignuous_bytes) const +{ + return get_gtk_offset(0u, contignuous_bytes); +} + +//------------------------------------------------------ + +// +u16_t eapol_rsna_key_data_gtk_header_c::get_header_length() +{ + return m_offset_gtk; +} + +//------------------------------------------------------ + +// +eap_status_e eapol_rsna_key_data_gtk_header_c::set_key_index(const u32_t index) +{ + u8_t * const data = get_header_offset(m_offset_flags, EAPOL_RSNA_KEY_DATA_FLAGS_FIELD_SIZE); + if (data != 0) + { + *data = static_cast(((*data) && ~EAPOL_RSNA_KEY_DATA_GTK_INDEX_MASK) + | ((index <(((*data) && ~EAPOL_RSNA_KEY_DATA_TX_MASK) + | ((tx <(((*data) && ~EAPOL_RSNA_KEY_DATA_RESERVED_MASK) + | ((index <(reserved); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +eap_status_e eapol_rsna_key_data_gtk_header_c::check_header() const +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------ + +// +eap_status_e eapol_rsna_key_data_gtk_header_c::reset_header() +{ + eap_status_e status(eap_status_process_general_error); + + m_am_tools->memset( + get_header_buffer(get_header_buffer_length()), + 0ul, + get_header_buffer_length()); + + status = set_key_index(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_tx(false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_reserved_flag(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_reserved_field(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_rsna_key_data_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_rsna_key_data_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,424 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 54 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eapol_rsna_key_data_header.h" + + +//------------------------------------------------------ + +// +eapol_rsna_key_data_header_c::~eapol_rsna_key_data_header_c() +{ +} + +//------------------------------------------------------ + +// +eapol_rsna_key_data_header_c::eapol_rsna_key_data_header_c( + abs_eap_am_tools_c * const tools, + const bool is_RSNA_when_true, + const bool is_WPXM_when_true, + void * const header_begin, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) + , m_is_RSNA_when_true(is_RSNA_when_true) + , m_is_WPXM_when_true(is_WPXM_when_true) +{ +} + +//------------------------------------------------------ + +// +eapol_RSNA_key_descriptor_type_e eapol_rsna_key_data_header_c::get_descriptor_type() const +{ + const u8_t * const data = get_header_offset(m_offset_type, EAPOL_RSNA_KEY_DATA_TYPE_FIELD_SIZE); + if (data != 0) + { + return static_cast(*data); + } + else + { + return eapol_RSNA_key_data_type_none; + } +} + +//------------------------------------------------------ + +// +u32_t eapol_rsna_key_data_header_c::get_header_and_body_length() const +{ + return get_length() + 2ul; +} + +//------------------------------------------------------ + +// +u8_t eapol_rsna_key_data_header_c::get_length() const +{ + const u8_t * const data = get_header_offset(m_offset_length, EAPOL_RSNA_KEY_DATA_LENGTH_FIELD_SIZE); + if (data != 0) + { + return *data; + } + else + { + return 0ul; + } +} + +//------------------------------------------------------ + +// +u32_t eapol_rsna_key_data_header_c::get_oui() const +{ + const u8_t * const data = get_header_offset(m_offset_oui, EAPOL_RSNA_KEY_DATA_OUI_FIELD_SIZE); + if (data != 0) + { + return eap_read_u24_t_network_order(data, EAPOL_RSNA_KEY_DATA_OUI_FIELD_SIZE); + } + else + { + return 0ul; + } +} + +//------------------------------------------------------ + +// +eapol_RSNA_key_payload_type_e eapol_rsna_key_data_header_c::get_payload_type() const +{ + const u8_t * const data = get_header_offset(m_offset_key_data_payload_type, EAPOL_RSNA_KEY_PAYLOAD_TYPE_FIELD_SIZE); + if (data != 0) + { + return static_cast(*data); + } + else + { + return eapol_RSNA_key_payload_type_none; + } +} + +//------------------------------------------------------ + +// +u32_t eapol_rsna_key_data_header_c::get_key_data_payload_length() const +{ + const u32_t length = get_length(); + if (length >= EAPOL_RSNA_KEY_DATA_LENGTH_FIELD_MINIMUM_SIZE) + { + return length - EAPOL_RSNA_KEY_DATA_LENGTH_FIELD_MINIMUM_SIZE; + } + else + { + return 0ul; + } +} + +//------------------------------------------------------ + +// +u8_t * eapol_rsna_key_data_header_c::get_key_data_payload_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + u32_t payload_length = get_key_data_payload_length(); + + if (payload_length >= offset+contignuous_bytes) + { + // This is pointer to the offset of the Data. + u8_t * const data = get_header_offset(m_offset_key_data_payload, offset+contignuous_bytes); + if (data != 0) + { + return &data[offset]; + } + else + { + return 0; + } + } + else + { + EAP_ASSERT_ALWAYS(payload_length >= offset+contignuous_bytes); + } + return 0; +} + +//------------------------------------------------------ + +// +u8_t * eapol_rsna_key_data_header_c::get_key_data_payload(const u32_t contignuous_bytes) const +{ + return get_key_data_payload_offset(0u, contignuous_bytes); +} + +//------------------------------------------------------ + +// +u8_t * eapol_rsna_key_data_header_c::get_next_header() const +{ + if (get_header_buffer_length() >= get_key_data_payload_length()+get_header_length()) + { + // NOTE get_key_data_payload_offset(get_key_data_payload_length(), get_header_length()) + // cannot be used here. + u8_t * const data = get_header_offset( + m_offset_key_data_payload, + get_key_data_payload_length()+get_header_length()); + if (data != 0) + { + return &data[get_key_data_payload_length()]; + } + else + { + return 0; + } + } + else + { + return 0; + } +} + +//------------------------------------------------------ + +// +u16_t eapol_rsna_key_data_header_c::get_header_length() +{ + return m_offset_key_data_payload; +} + +//------------------------------------------------------ + +// +eap_status_e eapol_rsna_key_data_header_c::set_type(const eapol_RSNA_key_descriptor_type_e type) +{ + u8_t * const data = get_header_offset(m_offset_type, EAPOL_RSNA_KEY_DATA_TYPE_FIELD_SIZE); + if (data != 0) + { + *data = static_cast(type); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +eap_status_e eapol_rsna_key_data_header_c::set_length(const u8_t length) +{ + u8_t * const data = get_header_offset(m_offset_length, EAPOL_RSNA_KEY_DATA_LENGTH_FIELD_SIZE); + if (data != 0) + { + *data = static_cast(length); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +eap_status_e eapol_rsna_key_data_header_c::set_oui(const u32_t oui) +{ + u8_t * const data = get_header_offset(m_offset_oui, EAPOL_RSNA_KEY_DATA_OUI_FIELD_SIZE); + if (data != 0) + { + return eap_write_u24_t_network_order(data, EAPOL_RSNA_KEY_DATA_OUI_FIELD_SIZE, oui); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +eap_status_e eapol_rsna_key_data_header_c::set_payload_type(const eapol_RSNA_key_payload_type_e type) +{ + u8_t * const data = get_header_offset(m_offset_key_data_payload_type, EAPOL_RSNA_KEY_PAYLOAD_TYPE_FIELD_SIZE); + if (data != 0) + { + *data = static_cast(type); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +eap_status_e eapol_rsna_key_data_header_c::check_header() const +{ + if (m_is_WPXM_when_true == true) + { + // OK, WPXM could use either RSN IE or WPA IE. + } + else if (m_is_RSNA_when_true == true) + { + // RSNA + if (get_descriptor_type() == eapol_RSNA_key_data_type_RSN_IE) + { + // OK + } + else if (get_descriptor_type() == eapol_RSNA_key_data_type_RSN_key_data) + { + if (get_length() < EAPOL_RSNA_KEY_DATA_LENGTH_FIELD_MINIMUM_SIZE) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_oui); + } + } + } + else + { + // WPA + if (get_descriptor_type() != eapol_RSNA_key_data_type_WPA_IE) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); + } + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------ + +// +eap_status_e eapol_rsna_key_data_header_c::reset_header() +{ + eap_status_e status(eap_status_process_general_error); + + if (m_is_RSNA_when_true == true + || m_is_WPXM_when_true == true) + { + // RSNA or WPXM + status = set_type(eapol_RSNA_key_data_type_RSN_key_data); + } + else + { + // WPA + status = set_type(eapol_RSNA_key_data_type_WPA_IE); + } + + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_length(EAPOL_RSNA_KEY_DATA_LENGTH_FIELD_MINIMUM_SIZE); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_oui(eapol_RSNA_key_data_oui_IEEE); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_payload_type(eapol_RSNA_key_payload_type_none); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------ + +// +eap_const_string eapol_rsna_key_data_header_c::get_descriptor_type_string() const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + const eapol_RSNA_key_descriptor_type_e type = get_descriptor_type(); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + + if (m_is_RSNA_when_true == true + || m_is_WPXM_when_true == true) + { +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(type, eapol_RSNA_key_data_type_RSN_IE) + else EAP_IF_RETURN_STRING(type, eapol_RSNA_key_data_type_RSN_key_data) + else EAP_IF_RETURN_STRING(type, eapol_RSNA_key_data_type_none) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown EAPOL Descriptor type"); + } + } + else + { +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(type, eapol_RSNA_key_data_type_WPA_IE) + else EAP_IF_RETURN_STRING(type, eapol_RSNA_key_data_type_none) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown EAPOL Descriptor type"); + } + } +} + +//------------------------------------------------------ + +// +eap_const_string eapol_rsna_key_data_header_c::get_payload_type_string() const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + const eapol_RSNA_key_payload_type_e type = get_payload_type(); + + EAP_IF_RETURN_STRING(type, eapol_RSNA_key_payload_type_reserved) + else EAP_IF_RETURN_STRING(type, eapol_RSNA_key_payload_type_group_key_and_id) + else EAP_IF_RETURN_STRING(type, eapol_RSNA_key_payload_type_sta_key) + else EAP_IF_RETURN_STRING(type, eapol_RSNA_key_payload_type_pmkid) + else EAP_IF_RETURN_STRING(type, eapol_RSNA_key_payload_type_none) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown EAPOL Key Data type"); + } +} + +//------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_rsna_key_data_payloads.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_rsna_key_data_payloads.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,224 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 55 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eapol_rsna_key_data_payloads.h" +#include "abs_eap_am_tools.h" +#include "eap_tools.h" + + + +EAP_FUNC_EXPORT eapol_rsna_variable_data_c::~eapol_rsna_variable_data_c() +{ +} + +EAP_FUNC_EXPORT eapol_rsna_variable_data_c::eapol_rsna_variable_data_c( + abs_eap_am_tools_c * const tools, + const bool is_RSNA_when_true, + const bool is_WPXM_when_true) + : eap_variable_data_c(tools) + , m_am_tools(tools) + , m_original_header(tools, is_RSNA_when_true, is_WPXM_when_true, 0, 0) +{ +} + +EAP_FUNC_EXPORT const eapol_rsna_key_data_header_c * eapol_rsna_variable_data_c::get_original_header() const +{ + return &m_original_header; +} + +EAP_FUNC_EXPORT eap_status_e eapol_rsna_variable_data_c::set_buffer(const eapol_rsna_key_data_header_c * const original_header, + u8_t *buffer, const u32_t buffer_length, + const bool free_buffer, const bool is_writable) +{ + m_original_header.set_header_buffer( + original_header->get_header_buffer(original_header->get_header_buffer_length()), + original_header->get_header_buffer_length()); + if (m_original_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_status_e status = eap_variable_data_c::set_buffer(buffer, buffer_length, free_buffer, is_writable); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + + +EAP_FUNC_EXPORT eapol_rsna_key_data_payloads_c::~eapol_rsna_key_data_payloads_c() +{ +} + +EAP_FUNC_EXPORT eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payloads_c( + abs_eap_am_tools_c * const tools, + const bool is_RSNA_when_true, + const bool is_WPXM_when_true) + : m_am_tools(tools) + , m_group_key(tools, is_RSNA_when_true, is_WPXM_when_true) + , m_group_key_id(0ul) + , m_group_key_tx_bit(false) + , m_STAKey(tools, is_RSNA_when_true, is_WPXM_when_true) + , m_PMKID(tools, is_RSNA_when_true, is_WPXM_when_true) + , m_RSN_IE(tools) + , m_is_valid(false) +{ + m_is_valid = true; +} + +EAP_FUNC_EXPORT bool eapol_rsna_key_data_payloads_c::check_one_payload( + const eapol_rsna_key_data_payload_status_e status, + const eapol_rsna_variable_data_c * const payload) +{ + if (status == eapol_rsna_key_data_payload_status_optional) + { + return true; + } + else if (status == eapol_rsna_key_data_payload_status_must_not_be + && payload->eap_variable_data_c::get_is_valid_data() == false) + { + return true; + } + else if (status == eapol_rsna_key_data_payload_status_must_be + && payload->eap_variable_data_c::get_is_valid_data() == true) + { + return true; + } + else + { + return false; + } +} + +EAP_FUNC_EXPORT bool eapol_rsna_key_data_payloads_c::check_one_payload( + const eapol_rsna_key_data_payload_status_e status, + const eap_array_c * const payload) +{ + if (status == eapol_rsna_key_data_payload_status_optional) + { + return true; + } + else if (status == eapol_rsna_key_data_payload_status_must_not_be + && (payload->get_object_count() == 0ul + || payload->get_object(0ul) == 0 + || payload->get_object(0ul)->get_is_valid_data() == false)) + { + return true; + } + else if (status == eapol_rsna_key_data_payload_status_must_be + && (payload->get_object_count() != 0ul + && payload->get_object(0ul) != 0 + && payload->get_object(0ul)->get_is_valid_data() == true)) + { + return true; + } + else + { + return false; + } +} + +EAP_FUNC_EXPORT bool eapol_rsna_key_data_payloads_c::check_payloads( + const eapol_rsna_key_data_payload_status_e key_id_and_group_key, + const eapol_rsna_key_data_payload_status_e sta_key, + const eapol_rsna_key_data_payload_status_e pmkid, + const eapol_rsna_key_data_payload_status_e one_or_more_RSN_IE + ) +{ + if (check_one_payload(key_id_and_group_key, get_group_key()) == true + && check_one_payload(sta_key, get_STAKey()) == true + && check_one_payload(pmkid, get_PMKID()) == true + && check_one_payload(one_or_more_RSN_IE, get_RSN_IE()) == true // This will check at least one RSN IE exists if any is required. + ) + { + return true; + } + else + { + return false; + } +} + +u8_t eapol_rsna_key_data_payloads_c::get_group_key_id() +{ + return m_group_key_id; +} + +bool eapol_rsna_key_data_payloads_c::get_group_key_tx() +{ + return m_group_key_tx_bit; +} + +eapol_rsna_variable_data_c * eapol_rsna_key_data_payloads_c::get_group_key() +{ + return static_cast(&m_group_key); +} + +eapol_rsna_variable_data_c * eapol_rsna_key_data_payloads_c::get_STAKey() +{ + return static_cast(&m_STAKey); +} + +eapol_rsna_variable_data_c * eapol_rsna_key_data_payloads_c::get_PMKID() +{ + return static_cast(&m_PMKID); +} + +eap_array_c * eapol_rsna_key_data_payloads_c::get_RSN_IE() +{ + return &m_RSN_IE; +} + +bool eapol_rsna_key_data_payloads_c::get_is_valid() const +{ + return m_is_valid; +} + + +void eapol_rsna_key_data_payloads_c::set_group_key_id(const u8_t key_index) +{ + m_group_key_id = key_index; +} + +void eapol_rsna_key_data_payloads_c::set_group_key_tx(const bool key_tx_bit) +{ + m_group_key_tx_bit = key_tx_bit; +} + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_rsna_key_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_rsna_key_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1175 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 56 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eapol_rsna_key_header.h" +#include "eap_automatic_variable.h" +#include "eapol_key_state_string.h" + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_RSNA_key_header_c::~eapol_RSNA_key_header_c() +{ +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_RSNA_key_header_c::eapol_RSNA_key_header_c( + abs_eap_am_tools_c * const tools, + const bool is_RSNA_when_true, + const bool is_WPXM_when_true, + void * const header_begin, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) + , m_is_RSNA_when_true(is_RSNA_when_true) + , m_is_WPXM_when_true(is_WPXM_when_true) +{ +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_information(const u16_t info) +{ + u8_t * const data = get_header_offset(m_offset_key_information, sizeof(u16_t)); + if (data != 0) + { + return eap_write_u16_t_network_order(data, sizeof(u16_t), info); + } + else + { + // ERROR. + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_protocol_version_e eapol_RSNA_key_header_c::get_eapol_protocol_version() const +{ + const u8_t * const data = get_header_offset(m_offset_eapol_version, sizeof(u8_t)); + if (data != 0) + { + return static_cast(*data); + } + else + { + return eapol_protocol_version_none; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_packet_type_e eapol_RSNA_key_header_c::get_eapol_packet_type() const +{ + const u8_t * const data = get_header_offset(m_offset_eapol_type, sizeof(u8_t)); + if (data != 0) + { + return static_cast(*data); + } + else + { + return eapol_packet_type_no_type; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u16_t eapol_RSNA_key_header_c::get_eapol_packet_body_length() const +{ + const u8_t * const data = get_header_offset(m_offset_eapol_packet_body_length, sizeof(u16_t)); + if (data != 0) + { + return eap_read_u16_t_network_order(data, sizeof(u16_t)); + } + else + { + return 0ul; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u16_t eapol_RSNA_key_header_c::get_eapol_packet_length() const +{ + // m_offset_key_descriptor_type is the length of the EAPOL header. + // Including fields Version, Type and Packet Body Length. + return static_cast(get_eapol_packet_body_length() + m_offset_key_descriptor_type); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_key_descriptor_type_e eapol_RSNA_key_header_c::get_key_descriptor_type() const +{ + const u8_t * const data = get_header_offset(m_offset_key_descriptor_type, sizeof(u8_t)); + if (data != 0) + { + return static_cast(*data); + } + else + { + return eapol_key_descriptor_type_none; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u16_t eapol_RSNA_key_header_c::get_key_information() const +{ + const u8_t * const data = get_header_offset(m_offset_key_information, sizeof(u16_t)); + if (data != 0) + { + return eap_read_u16_t_network_order(data, sizeof(u16_t)); + } + else + { + // ERROR. + return 0ul; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eapol_RSNA_key_header_c::key_descriptor_version_e eapol_RSNA_key_header_c::get_key_information_key_descriptor_version() const +{ + const u16_t key_information = get_key_information(); + return static_cast((key_information & m_key_information_mask_key_descriptor_version) + >> m_key_information_mask_key_descriptor_version_shift); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT bool eapol_RSNA_key_header_c::get_key_information_key_type() const +{ + const u16_t key_information = get_key_information(); + const u16_t key_type = static_cast(key_information & m_key_information_mask_key_type); + if (key_type != 0) + { + return true; + } + else + { + return false; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t eapol_RSNA_key_header_c::get_key_information_reserved_a() const +{ + EAP_ASSERT(m_is_RSNA_when_true == true || m_is_WPXM_when_true == true); + + const u16_t key_information = get_key_information(); + return static_cast((key_information & m_key_information_mask_reserved_a_RSNA) + >> m_key_information_mask_reserved_a_shift_RSNA); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t eapol_RSNA_key_header_c::get_key_information_key_index() const +{ + EAP_ASSERT(m_is_RSNA_when_true == false || m_is_WPXM_when_true == true); + + const u16_t key_information = get_key_information(); + return static_cast((key_information & m_key_information_mask_key_index_WPA) + >> m_key_information_mask_key_index_shift_WPA); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT bool eapol_RSNA_key_header_c::get_key_information_install() const +{ + const u16_t key_information = get_key_information(); + const u16_t key_type = static_cast(key_information & m_key_information_mask_install); + if (key_type != 0) + { + return true; + } + else + { + return false; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT bool eapol_RSNA_key_header_c::get_key_information_key_ack() const +{ + const u16_t key_information = get_key_information(); + const u16_t key_type = static_cast(key_information & m_key_information_mask_key_ack); + if (key_type != 0) + { + return true; + } + else + { + return false; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT bool eapol_RSNA_key_header_c::get_key_information_key_MIC() const +{ + const u16_t key_information = get_key_information(); + const u16_t key_type = static_cast(key_information & m_key_information_mask_key_MIC); + if (key_type != 0) + { + return true; + } + else + { + return false; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT bool eapol_RSNA_key_header_c::get_key_information_secure() const +{ + const u16_t key_information = get_key_information(); + const u16_t key_type = static_cast(key_information & m_key_information_mask_secure); + if (key_type != 0) + { + return true; + } + else + { + return false; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT bool eapol_RSNA_key_header_c::get_key_information_error() const +{ + const u16_t key_information = get_key_information(); + const u16_t key_type = static_cast(key_information & m_key_information_mask_error); + if (key_type != 0) + { + return true; + } + else + { + return false; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT bool eapol_RSNA_key_header_c::get_key_information_request() const +{ + const u16_t key_information = get_key_information(); + const u16_t key_type = static_cast(key_information & m_key_information_mask_request); + if (key_type != 0) + { + return true; + } + else + { + return false; + } +} + + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT bool eapol_RSNA_key_header_c::get_key_information_encrypted_key_data() const +{ + const u16_t key_information = get_key_information(); + const u16_t key_type = static_cast(key_information & m_key_information_mask_encrypted_key_data_RSNA); + if (key_type != 0) + { + return true; + } + else + { + return false; + } +} + + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t eapol_RSNA_key_header_c::get_key_information_reserved_b() const +{ + const u16_t key_information = get_key_information(); + + if (m_is_RSNA_when_true == true || m_is_WPXM_when_true == true) + { + return static_cast((key_information & m_key_information_mask_reserved_b_RSNA) + >> m_key_information_mask_reserved_b_shift_RSNA); + } + else + { + return static_cast((key_information & m_key_information_mask_reserved_b_WPA) + >> m_key_information_mask_reserved_b_shift_WPA); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u16_t eapol_RSNA_key_header_c::get_key_length() const +{ + const u8_t * const data = get_header_offset(m_offset_key_length, sizeof(u16_t)); + if (data != 0) + { + return eap_read_u16_t_network_order(data, sizeof(u16_t)); + } + else + { + return 0ul; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u64_t eapol_RSNA_key_header_c::get_key_replay_counter() const +{ + const u8_t * const data = get_header_offset(m_offset_key_replay_counter, EAPOL_RSNA_KEY_REPLY_COUNTER_SIZE); + if (data != 0) + { + return eap_read_u64_t_network_order(data, EAPOL_RSNA_KEY_REPLY_COUNTER_SIZE); + } + else + { + return 0ul; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t * eapol_RSNA_key_header_c::get_key_NONCE() const +{ + u8_t * const data = get_header_offset(m_offset_key_NONCE, EAPOL_RSNA_KEY_NONCE_SIZE); + return data; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t * eapol_RSNA_key_header_c::get_EAPOL_key_IV() const +{ + u8_t * const data = get_header_offset(m_offset_EAPOL_key_IV, EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + return data; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t * eapol_RSNA_key_header_c::get_key_RSC() const +{ + u8_t * const data = get_header_offset(m_offset_key_RSC, EAPOL_RSNA_KEY_RSC_SIZE); + return data; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t * eapol_RSNA_key_header_c::get_key_STA_MAC_address() const +{ + u8_t * const data = get_header_offset(m_offset_key_STA_MAC_address, EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE); + return data; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t * eapol_RSNA_key_header_c::get_key_reserved() const +{ + u8_t * const data = get_header_offset(m_offset_key_reserved, EAPOL_RSNA_KEY_RESERVED_SIZE); + return data; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t * eapol_RSNA_key_header_c::get_key_MIC() const +{ + u8_t * const data = get_header_offset(m_offset_key_MIC, EAPOL_RSNA_KEY_MIC_SIZE); + return data; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u16_t eapol_RSNA_key_header_c::get_key_data_length() const +{ + const u8_t * const data = get_header_offset(m_offset_key_data_length, EAPOL_RSNA_KEY_DATA_LENGTH_SIZE); + if (data != 0) + { + return eap_read_u16_t_network_order(data, EAPOL_RSNA_KEY_DATA_LENGTH_SIZE); + } + else + { + return 0ul; + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t * eapol_RSNA_key_header_c::get_key_data(const u32_t key_length) const +{ + u8_t * const data = get_header_offset( + m_offset_key_data, + key_length); + + return data; // Data begins after the header. +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u8_t * eapol_RSNA_key_header_c::get_key_data_offset(const u32_t offset, const u32_t key_length) const +{ + u8_t * const data = get_header_offset( + m_offset_key_data + offset, + key_length); + + return data; // Data begins after the header. +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u16_t eapol_RSNA_key_header_c::get_header_length() +{ + return m_offset_key_data; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_eapol_protocol_version(const eapol_protocol_version_e version) +{ + u8_t * const data = get_header_offset(m_offset_eapol_version, sizeof(u8_t)); + if (data != 0) + { + *data = static_cast(version); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_eapol_packet_type(const eapol_packet_type_e type) +{ + u8_t * const data = get_header_offset(m_offset_eapol_type, sizeof(u8_t)); + if (data != 0) + { + *data = static_cast(type); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_eapol_packet_body_length(const u32_t eapol_length) +{ + if (eapol_length - eapol_header_base_c::get_header_length() > eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_MAXIMUM_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + u8_t * const data = get_header_offset(m_offset_eapol_packet_body_length, sizeof(u16_t)); + if (data != 0) + { + const u16_t eapol_length_u16_t = static_cast(eapol_length); + return eap_write_u16_t_network_order(data, sizeof(u16_t), eapol_length_u16_t); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_descriptor_type(const eapol_key_descriptor_type_e eapol_key_descriptor_type) +{ + u8_t * const data = get_header_offset(m_offset_key_descriptor_type, sizeof(u8_t)); + if (data != 0) + { + *data = static_cast(eapol_key_descriptor_type); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT u16_t eapol_RSNA_key_header_c::set_bits_on( + u16_t key_information, + const u16_t set_bits, + const u32_t mask, + const u32_t shift) +{ + key_information = + static_cast((key_information & ~mask) + | ((set_bits << shift) & mask)); + + return key_information; +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_information_key_descriptor_version(const u8_t version) +{ + u16_t key_information = get_key_information(); + + key_information = set_bits_on( + key_information, + static_cast(version), + m_key_information_mask_key_descriptor_version, + m_key_information_mask_key_descriptor_version_shift); + + return set_key_information(key_information); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_information_key_type(const bool key_type_bit_on_when_true) +{ + u16_t key_information = get_key_information(); + + u16_t key_type_bit = 0; + if (key_type_bit_on_when_true == true) + { + key_type_bit = 1; + } + + key_information = set_bits_on( + key_information, + key_type_bit, + m_key_information_mask_key_type, + m_key_information_mask_key_type_shift); + + return set_key_information(key_information); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_information_key_index(const u8_t key_index) +{ + EAP_ASSERT(m_is_RSNA_when_true == false || m_is_WPXM_when_true == true); + + u16_t key_information = get_key_information(); + + key_information = set_bits_on( + key_information, + static_cast(key_index), + m_key_information_mask_key_index_WPA, + m_key_information_mask_key_index_shift_WPA); + + return set_key_information(key_information); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_information_install(const bool install_bit_on_when_true) +{ + u16_t key_information = get_key_information(); + + u16_t install_bit = 0; + if (install_bit_on_when_true == true) + { + install_bit = 1; + } + + key_information = set_bits_on( + key_information, + install_bit, + m_key_information_mask_install, + m_key_information_mask_install_shift); + + return set_key_information(key_information); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_information_key_ack(const bool key_ack_bit_on_when_true) +{ + u16_t key_information = get_key_information(); + + u16_t key_ack_bit = 0; + if (key_ack_bit_on_when_true == true) + { + key_ack_bit = 1; + } + + key_information = set_bits_on( + key_information, + key_ack_bit, + m_key_information_mask_key_ack, + m_key_information_mask_key_ack_shift); + + return set_key_information(key_information); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_information_key_MIC(const bool key_MIC_bit_on_when_true) +{ + u16_t key_information = get_key_information(); + + u16_t key_MIC_bit = 0; + if (key_MIC_bit_on_when_true == true) + { + key_MIC_bit = 1; + } + + key_information = set_bits_on( + key_information, + key_MIC_bit, + m_key_information_mask_key_MIC, + m_key_information_mask_key_MIC_shift); + + return set_key_information(key_information); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_information_secure(const bool secure_bit_on_when_true) +{ + u16_t key_information = get_key_information(); + + u16_t secure_bit = 0; + if (secure_bit_on_when_true == true) + { + secure_bit = 1; + } + + key_information = set_bits_on( + key_information, + secure_bit, + m_key_information_mask_secure, + m_key_information_mask_secure_shift); + + return set_key_information(key_information); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_information_error(const bool error_bit_on_when_true) +{ + u16_t key_information = get_key_information(); + + u16_t error_bit = 0; + if (error_bit_on_when_true == true) + { + error_bit = 1; + } + + key_information = set_bits_on( + key_information, + error_bit, + m_key_information_mask_error, + m_key_information_mask_error_shift); + + return set_key_information(key_information); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_information_request(const bool request_bit_is_on_when_true) +{ + u16_t key_information = get_key_information(); + + u16_t request_bit = 0; + if (request_bit_is_on_when_true == true) + { + request_bit = 1; + } + + key_information = set_bits_on( + key_information, + request_bit, + m_key_information_mask_request, + m_key_information_mask_request_shift); + + return set_key_information(key_information); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_information_encrypted_key_data(const bool encrypted_key_data_bit_is_on_when_true) +{ + EAP_ASSERT(m_is_RSNA_when_true == true || m_is_WPXM_when_true == true); + + u16_t key_information = get_key_information(); + + u16_t encrypted_key_data_bit = 0; + if (encrypted_key_data_bit_is_on_when_true == true) + { + encrypted_key_data_bit = 1; + } + + key_information = set_bits_on( + key_information, + encrypted_key_data_bit, + m_key_information_mask_encrypted_key_data_RSNA, + m_key_information_mask_encrypted_key_data_shift_RSNA); + + return set_key_information(key_information); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_length(const u16_t length) +{ + u8_t * const data = get_header_offset(m_offset_key_length, sizeof(u16_t)); + if (data != 0) + { + return eap_write_u16_t_network_order(data, sizeof(u16_t), length); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_replay_counter(const u64_t reply_counter) +{ + u8_t * const data = get_header_offset(m_offset_key_replay_counter, EAPOL_RSNA_KEY_REPLY_COUNTER_SIZE); + if (data != 0) + { + return eap_write_u64_t_network_order(data, EAPOL_RSNA_KEY_REPLY_COUNTER_SIZE, reply_counter); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::set_key_data_length(const u16_t key_data_length) +{ + u8_t * const data = get_header_offset(m_offset_key_data_length, EAPOL_RSNA_KEY_DATA_LENGTH_SIZE); + if (data != 0) + { + return eap_write_u16_t_network_order(data, EAPOL_RSNA_KEY_DATA_LENGTH_SIZE, key_data_length); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::zero_EAPOL_header_and_Key_descriptor( + abs_eap_am_tools_c * const tools + ) +{ + u8_t * const data = get_header_offset(0ul, get_header_length()); + if (data != 0) + { + tools->memset(data, 0, get_header_length()); + return EAP_STATUS_RETURN(tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::zero_key_MIC( + abs_eap_am_tools_c * const tools + ) +{ + u8_t * const data = get_key_MIC(); + if (data != 0) + { + tools->memset(data, 0, EAPOL_RSNA_KEY_MIC_SIZE); + return EAP_STATUS_RETURN(tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::zero_key_NONCE( + abs_eap_am_tools_c * const tools + ) +{ + u8_t * const data = get_key_NONCE(); + if (data != 0) + { + tools->memset(data, 0, EAPOL_RSNA_KEY_NONCE_SIZE); + return EAP_STATUS_RETURN(tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::zero_EAPOL_key_IV( + abs_eap_am_tools_c * const tools + ) +{ + u8_t * const data = get_EAPOL_key_IV(); + if (data != 0) + { + tools->memset(data, 0, EAPOL_RSNA_EAPOL_KEY_IV_SIZE); + return EAP_STATUS_RETURN(tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::zero_key_RSC( + abs_eap_am_tools_c * const tools + ) +{ + u8_t * const data = get_key_RSC(); + if (data != 0) + { + tools->memset(data, 0, EAPOL_RSNA_KEY_RSC_SIZE); + return EAP_STATUS_RETURN(tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::zero_key_STA_MAC_address( + abs_eap_am_tools_c * const tools + ) +{ + u8_t * const data = get_key_STA_MAC_address(); + if (data != 0) + { + tools->memset(data, 0, EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE); + return EAP_STATUS_RETURN(tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::zero_key_reserved( + abs_eap_am_tools_c * const tools + ) +{ + u8_t * const data = get_key_reserved(); + if (data != 0) + { + tools->memset(data, 0, EAPOL_RSNA_KEY_RESERVED_SIZE); + return EAP_STATUS_RETURN(tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(tools, eap_status_allocation_error); + } +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::check_header() const +{ + if (get_eapol_protocol_version() == eapol_protocol_version_none) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_version); + } + else if (get_eapol_packet_type() > eapol_packet_type_enc_asf_alert) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); + } + else if (get_key_information_key_descriptor_version() != m_key_descriptor_version_1 + && get_key_information_key_descriptor_version() != m_key_descriptor_version_2) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------ + +// +EAP_FUNC_EXPORT eap_status_e eapol_RSNA_key_header_c::reset_header( + const u8_t key_index, + const eapol_key_authentication_type_e authentication_type, + const eapol_RSNA_cipher_e eapol_pairwise_cipher, + const u64_t key_reply_counter, + const bool key_type_bit_on_when_true, + const bool install_bit_on_when_true, + const bool key_ack_bit_on_when_true, + const bool key_MIC_bit_on_when_true, + const bool secure_bit_on_when_true, + const bool error_bit_on_when_true, + const bool requst_bit_on_when_true, + const bool STAKey_bit_on_when_true, + const bool encrypted_key_data_bit_on_when_true, + const eapol_protocol_version_e used_rsna_eapol_protocol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type) +{ + EAP_UNREFERENCED_PARAMETER(encrypted_key_data_bit_on_when_true); + EAP_UNREFERENCED_PARAMETER(STAKey_bit_on_when_true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_RSNA_key_header_c::reset_header()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_RSNA_key_header_c::reset_header()"); + + + eap_status_e status = zero_EAPOL_header_and_Key_descriptor(m_am_tools); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eapol_protocol_version_e eapol_version(eapol_protocol_version_1); + eapol_key_descriptor_type_e eapol_key_descriptor_type(eapol_key_descriptor_type_WPA); + + if (authentication_type == eapol_key_authentication_type_RSNA_EAP + || authentication_type == eapol_key_authentication_type_RSNA_PSK) + { + eapol_version = used_rsna_eapol_protocol_version; + eapol_key_descriptor_type = eapol_key_descriptor_type_RSNA; + } + else if (authentication_type == eapol_key_authentication_type_WPXM) + { + eapol_version = used_rsna_eapol_protocol_version; + + if (received_key_descriptor_type != eapol_key_descriptor_type_none) + { + eapol_key_descriptor_type = received_key_descriptor_type; + } + } + + eapol_key_state_string_c debug_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: eapol_RSNA_key_header_c::reset_header(): eapol_key_descriptor_type = %s = 0x%02x\n"), + debug_string.get_eapol_key_descriptor_type_string(eapol_key_descriptor_type), + eapol_key_descriptor_type)); + + status = set_eapol_protocol_version(eapol_version); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = set_eapol_packet_type(eapol_packet_type_key); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_key_descriptor_type(eapol_key_descriptor_type); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (eapol_pairwise_cipher == eapol_RSNA_cipher_TKIP + || eapol_pairwise_cipher == eapol_RSNA_cipher_WEP_40 + || eapol_pairwise_cipher == eapol_RSNA_cipher_WEP_104) + { + status = set_key_information_key_descriptor_version(m_key_descriptor_version_1); + } + else if (eapol_pairwise_cipher == eapol_RSNA_cipher_CCMP) + { + status = set_key_information_key_descriptor_version(m_key_descriptor_version_2); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + status = set_key_information_key_type(key_type_bit_on_when_true); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_key_information_install(install_bit_on_when_true); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_key_information_key_ack(key_ack_bit_on_when_true); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_key_information_key_MIC(key_MIC_bit_on_when_true); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_key_information_secure(secure_bit_on_when_true); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_key_information_error(error_bit_on_when_true); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_key_information_request(requst_bit_on_when_true); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_is_RSNA_when_true == true || m_is_WPXM_when_true == true) + { + // RSNA + status = set_key_information_encrypted_key_data( + encrypted_key_data_bit_on_when_true); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // WPA + status = set_key_information_key_index(key_index); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = set_key_replay_counter(key_reply_counter); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +// +//------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_wlan_authentication.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_wlan_authentication.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3934 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 57 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "eap_am_memory.h" + +#include "eap_am_tools.h" +#include "eap_variable_data.h" +#include "eap_tools.h" +#include "eap_type_all.h" + +#include "eapol_wlan_authentication.h" +#include "eapol_ethernet_header.h" +#include "ethernet_core.h" +#include "eap_crypto_api.h" +#include "eap_header_string.h" +#include "eap_rogue_ap_entry.h" +#include "abs_eap_state_notification.h" +#include "eapol_session_key.h" +#include "eap_buffer.h" +#include "eap_config.h" +#include "eap_array_algorithms.h" +#include "eap_state_notification.h" +#include "eap_automatic_variable.h" + +// LOCAL CONSTANTS + +enum eapol_am_core_timer_id_e +{ + EAPOL_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID, + EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID, + EAPOL_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID, + EAPOL_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID +}; + +#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MUTEX) + + #if defined(USE_TEST_WLAN_AUTHENTICATION_MUTEX) + #error "You cannot define both USE_EAPOL_WLAN_AUTHENTICATION_MUTEX and USE_TEST_WLAN_AUTHENTICATION_MUTEX." + #endif + + #define WAUTH_ENTER_MUTEX(tools) { tools->enter_global_mutex(); } + + #define WAUTH_LEAVE_MUTEX(tools) { tools->leave_global_mutex(); } + +#else + + #define WAUTH_ENTER_MUTEX(tools) + + #define WAUTH_LEAVE_MUTEX(tools) + +#endif //#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MUTEX) + +// ================= MEMBER FUNCTIONS ======================= + +EAP_FUNC_EXPORT eapol_wlan_authentication_c * eapol_wlan_authentication_c::new_eapol_wlan_authentication( + abs_eap_am_tools_c * const tools, + abs_eapol_wlan_authentication_c * const partner, + const bool is_client_when_true, + const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference + ) +{ + EAP_TRACE_DEBUG( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::new_eapol_wlan_authentication()\n"))); + + EAP_TRACE_RETURN_STRING(tools, "returns to partner: eapol_wlan_authentication_c::new_eapol_wlan_authentication()"); + + eapol_am_wlan_authentication_c * m_am_wauth = eapol_am_wlan_authentication_c::new_eapol_am_wlan_authentication( + tools, + is_client_when_true, + wlan_database_reference); + if (m_am_wauth == 0 + || m_am_wauth->get_is_valid() == false) + { + // ERROR. + if (m_am_wauth != 0) + { + EAP_TRACE_DEBUG( + tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::new_eapol_wlan_authentication(): m_am_wauth->shutdown(): %s.\n"), + (is_client_when_true == true) ? "client": "server")); + + m_am_wauth->shutdown(); + delete m_am_wauth; + m_am_wauth = 0; + } + return 0; + } + + eapol_wlan_authentication_c * wauth = new eapol_wlan_authentication_c(tools, partner, m_am_wauth, is_client_when_true); + if (wauth == 0 + || wauth->get_is_valid() == false) + { + // ERROR. + if (wauth != 0) + { + wauth->shutdown(); + delete wauth; + } + return 0; + } + + EAP_TRACE_DEBUG( + tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::new_eapol_wlan_authentication(): m_am_wauth->set_am_partner(): %s.\n"), + (is_client_when_true == true) ? "client": "server")); + + m_am_wauth->set_am_partner( + wauth +#if defined(USE_EAP_SIMPLE_CONFIG) + , wauth +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + ); + + return wauth; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_wlan_authentication_c::eapol_wlan_authentication_c( + abs_eap_am_tools_c * const tools, + abs_eapol_wlan_authentication_c * const partner, + eapol_am_wlan_authentication_c * const am_wauth, ///< eapol_wlan_authentication_c must always delete the am_wauth object. + const bool is_client_when_true) +: m_partner(partner) +, m_am_wauth(am_wauth) +, m_ethernet_core(0) +, m_am_tools(tools) +, m_selected_eap_types(tools) +, m_wpa_preshared_key_hash(tools) +, m_authentication_type(eapol_key_authentication_type_none) +, m_802_11_authentication_mode(eapol_key_802_11_authentication_mode_none) +, m_received_WPA_IE(tools) // WLM must give only the WPA IE to EAPOL +, m_sent_WPA_IE(tools) +, m_group_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none) +, m_pairwise_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none) +, m_current_eap_index(0ul) +, m_authentication_counter(0u) +, m_successful_authentications(0u) +, m_failed_authentications(0u) +, m_is_valid(false) +, m_is_client(is_client_when_true) +, m_shutdown_was_called(false) +#if defined(USE_EAP_ERROR_TESTS) +, m_randomly_drop_packets(false) +, m_randomly_drop_packets_probability(0u) +, m_error_probability(0u) +, m_generate_multiple_error_packets(0u) +, m_packet_index(0u) +, m_enable_random_errors(false) +, m_manipulate_ethernet_header(false) +, m_send_original_packet_first(false) +#endif //#if defined(USE_EAP_ERROR_TESTS) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("starts: eapol_wlan_authentication_c::eapol_wlan_authentication_c(): %s, this = 0x%08x => 0x%08x, compiled %s %s.\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this), + __DATE__, + __TIME__)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_wlan_authentication_c::eapol_wlan_authentication_c()"); + + if (m_am_wauth == 0 + || m_am_wauth->get_is_valid() == false) + { + // ERROR. + if (m_am_wauth != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::eapol_wlan_authentication_c(): m_am_wauth->shutdown(): %s.\n"), + (is_client_when_true == true) ? "client": "server")); + + m_am_wauth->shutdown(); + delete am_wauth; + } + return; + } + + if (m_am_tools == 0 + || m_am_tools->get_is_valid() == false) + { + // ERROR. + if (m_am_wauth != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::eapol_wlan_authentication_c(): m_am_wauth->shutdown(): %s.\n"), + (is_client_when_true == true) ? "client": "server")); + + m_am_wauth->shutdown(); + delete am_wauth; + } + return; + } + + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_wlan_authentication_c::~eapol_wlan_authentication_c() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::~eapol_wlan_authentication_c(): this = 0x%08x\n"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::~eapol_wlan_authentication_c()"); + + EAP_ASSERT(m_shutdown_was_called == true); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::shutdown(); %s, m_shutdown_was_called=%d\n"), + (m_is_client == true) ? "client": "server", + m_shutdown_was_called)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::shutdown()"); + + if (m_shutdown_was_called == true) + { + // Shutdown was already called once. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + // Cancel timer + cancel_all_timers(); + + // Delete upper stack if it still exists + if (m_ethernet_core != 0) + { + WAUTH_ENTER_MUTEX(m_am_tools); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::shutdown(): m_ethernet_core->shutdown(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_ethernet_core->shutdown(); + EAP_UNREFERENCED_PARAMETER(status); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::shutdown(): m_ethernet_core->shutdown(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + WAUTH_LEAVE_MUTEX(m_am_tools); + + delete m_ethernet_core; + m_ethernet_core = 0; + } + + // Print some statistics + if (m_is_client) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_TEST_VECTORS, + (EAPL("eapol_wlan_authentication_c::shutdown(): client authentication SUCCESS %d, FAILED %d, count %d\n"), + m_successful_authentications, + m_failed_authentications, + m_authentication_counter)); + } + else + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_TEST_VECTORS, + (EAPL("eapol_wlan_authentication_c::shutdown(): server authentication SUCCESS %d, FAILED %d, count %d\n"), + m_successful_authentications, + m_failed_authentications, + m_authentication_counter)); + } + + + if (m_am_wauth != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::shutdown(): m_am_wauth->shutdown(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + m_am_wauth->shutdown(); + delete m_am_wauth; + m_am_wauth = 0; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WAUTH EXITING.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +// +eap_status_e eapol_wlan_authentication_c::cancel_all_authentication_sessions() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::cancel_all_authentication_sessions(): %s\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status(eap_status_process_general_error); + + if (m_ethernet_core != 0) + { + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::cancel_all_authentication_sessions(): m_ethernet_core->cancel_all_authentication_sessions(): %s.\n"), + (m_is_client == true) ? "client": "server")); + status = m_ethernet_core->cancel_all_authentication_sessions(); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::cancel_all_authentication_sessions(): m_ethernet_core->cancel_all_authentication_sessions(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::cancel_all_authentication_sessions(): Stack did not exists.\n"))); + status = eap_status_process_general_error; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::start_authentication( + const eap_variable_data_c * const SSID, + const eapol_key_authentication_type_e selected_eapol_key_authentication_type, + const eap_variable_data_c * const wpa_preshared_key, + const bool WPA_override_enabled +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + , + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::start_authentication(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Starting authentication, selected_eapol_key_authentication_type = %d.\n"), + selected_eapol_key_authentication_type)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::start_authentication()"); + + eap_status_e status(eap_status_ok); + + status = cancel_all_authentication_sessions(); + if (status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, status); + } + + m_authentication_type = selected_eapol_key_authentication_type; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::start_authentication(): m_am_wauth->set_wlan_parameters(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_am_wauth->set_wlan_parameters( + SSID, + WPA_override_enabled, + wpa_preshared_key, + selected_eapol_key_authentication_type); + if (status != eap_status_ok) + { + (void) disassociation(0); // Note we have no addresses yet. + + (void) eapol_indication( + 0, // Note we have no addresses yet. + eapol_wlan_authentication_state_failed_completely); + + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::start_authentication(): m_am_wauth->reset_eap_configuration(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_am_wauth->reset_eap_configuration(); + if (status != eap_status_ok) + { + (void) disassociation(0); // Note we have no addresses yet. + + (void) eapol_indication( + 0, // Note we have no addresses yet. + eapol_wlan_authentication_state_failed_completely); + + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::start_authentication(): m_am_wauth->get_selected_eap_types(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_am_wauth->get_selected_eap_types(&m_selected_eap_types); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::start_authentication(): m_am_wauth->get_wlan_configuration(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_am_wauth->get_wlan_configuration( + &m_wpa_preshared_key_hash); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Start new authentication from scratch. + + if (m_authentication_type == eapol_key_authentication_type_RSNA_PSK + || m_authentication_type == eapol_key_authentication_type_WPA_PSK) + { + // WPA Pre-shared key mode + m_802_11_authentication_mode = eapol_key_802_11_authentication_mode_open; + + if (m_authentication_type == eapol_key_authentication_type_RSNA_PSK) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("start_authentication(): Trying auth mode OPEN and WPA2-PSK.\n"))); + } + else + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("start_authentication(): Trying auth mode OPEN and WPA-PSK.\n"))); + } + } + else //if (wpa_preshared_key == 0 + //|| wpa_preshared_key->get_is_valid_data() == false + //|| WPA_override_enabled == false) + { + // Check the first enabled type + eap_type_selection_c * eap_type = 0; + u32_t ind_type = 0ul; + + for (ind_type = 0; ind_type < m_selected_eap_types.get_object_count(); ind_type++) + { + // Check if type is enabled + eap_type = m_selected_eap_types.get_object(ind_type); + + if (eap_type->get_is_enabled() == true) + { + break; + } + } + + if (ind_type >= m_selected_eap_types.get_object_count()) + { + // No enabled EAP types. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("No enabled EAP types.\n"))); + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: eap_status_failed_completely.\n"))); + + (void) disassociation(0); // Note we have no addresses yet. + + status = eapol_indication( + 0, // Note we have no addresses yet. + eapol_wlan_authentication_state_failed_completely); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + // reset index (start from the first enabled EAP type) + m_current_eap_index = ind_type; + + if (eap_type->get_type() == eap_type_leap) + { + if (m_authentication_type == eapol_key_authentication_type_802_1X) + { + // LEAP uses it's own 802.11 authentication mode when 802.1X (dynamic WEP) is used. + m_802_11_authentication_mode = eapol_key_802_11_authentication_mode_leap; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("start_authentication(): Trying auth mode LEAP (802.1x mode).\n"))); + } + else + { + // If security mode is WPA or RSNA then even LEAP uses open authentication! + m_802_11_authentication_mode = eapol_key_802_11_authentication_mode_open; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("start_authentication(): Trying auth mode OPEN (LEAP in WPA mode).\n"))); + } + + } + else + { + m_802_11_authentication_mode = eapol_key_802_11_authentication_mode_open; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("start_authentication(): Trying auth mode OPEN.\n"))); + } + } + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::start_authentication(): m_ethernet_core->create_state(): %s.\n"), + (m_is_client == true) ? "client": "server")); + status = m_ethernet_core->create_state( + receive_network_id, + selected_eapol_key_authentication_type + ); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::start_authentication(): m_ethernet_core->create_state(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::start_authentication(): m_partner->associate(%d).\n"), + m_802_11_authentication_mode)); + + status = m_partner->associate(m_802_11_authentication_mode); + (void)EAP_STATUS_RETURN(m_am_tools, status); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::start_authentication(): %s: m_partner->associate(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::complete_association( + const eapol_wlan_authentication_state_e association_result, + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + const eap_variable_data_c * const received_WPA_IE, ///< WLM must give only the WPA IE to EAPOL + const eap_variable_data_c * const sent_WPA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::complete_association(): %s: association_result=%d\n"), + (m_is_client == true) ? "client": "server", + association_result)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::complete_association()"); + + eap_status_e status(eap_status_ok); + + // ASSOCIATION UNSUCCESSFUL + if (association_result != eapol_wlan_authentication_state_association_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_association: Unsuccessful.\n"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Got AP MAC address"), + receive_network_id->get_source(), + receive_network_id->get_source_length())); + + // Report rogue AP if we tried LEAP and it failed + if (m_802_11_authentication_mode == eapol_key_802_11_authentication_mode_leap) + { + // Only add rogue AP if the error code is correct + if (association_result == eapol_wlan_authentication_state_802_11_auth_algorithm_not_supported) + { + eap_rogue_ap_entry_c rogue_entry(m_am_tools); + + rogue_entry.set_mac_address(receive_network_id->get_source()); + rogue_entry.set_rogue_reason(rogue_ap_association_failed); + + eap_array_c rogue_list(m_am_tools); + status = rogue_list.add_object(&rogue_entry, false); + if (status == eap_status_ok) + { + status = add_rogue_ap(rogue_list); + // Ignore return value on purpose - it's not fatal if this fails + } + } + } + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Could not associate to the AP.\n"))); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: eap_status_this_ap_failed.\n"))); + + (void) disassociation(receive_network_id); + + status = eapol_indication( + receive_network_id, + eapol_wlan_authentication_state_this_ap_failed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + + } + + // ASSOCIATION SUCCESSFUL + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("complete_association: Successful.\n"))); + + // Store parameters + + if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP + || m_authentication_type == eapol_key_authentication_type_RSNA_PSK + || m_authentication_type == eapol_key_authentication_type_WPA_EAP + || m_authentication_type == eapol_key_authentication_type_WPA_PSK +#if defined(EAP_USE_WPXM) + || m_authentication_type == eapol_key_authentication_type_WPXM +#endif //#if defined(EAP_USE_WPXM) + ) + { + status = m_received_WPA_IE.set_copy_of_buffer(received_WPA_IE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_sent_WPA_IE.set_copy_of_buffer(sent_WPA_IE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + m_group_key_cipher_suite = group_key_cipher_suite; + + m_pairwise_key_cipher_suite = pairwise_key_cipher_suite; + + eap_variable_data_c * wpa_preshared_key = 0; + + if (m_authentication_type == eapol_key_authentication_type_RSNA_PSK + || m_authentication_type == eapol_key_authentication_type_WPA_PSK) + { + wpa_preshared_key = &m_wpa_preshared_key_hash; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::complete_association(): m_am_wauth->association(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_am_wauth->association(receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::complete_association(): m_ethernet_core->association(): %s.\n"), + (m_is_client == true) ? "client": "server")); + status = m_ethernet_core->association( + receive_network_id, + m_authentication_type, + &m_received_WPA_IE, + &m_sent_WPA_IE, + pairwise_key_cipher_suite, + group_key_cipher_suite, + wpa_preshared_key); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::complete_association(): m_ethernet_core->association(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + if (status != eap_status_ok) + { + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("m_ethernet_core->association call failed.\n"))); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: eap_status_failed_completely.\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::complete_association(): this->disassociation(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + (void) disassociation(receive_network_id); + + status = eapol_indication( + receive_network_id, + eapol_wlan_authentication_state_failed_completely); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP + || m_authentication_type == eapol_key_authentication_type_WPA_EAP + || m_authentication_type == eapol_key_authentication_type_802_1X + || m_authentication_type == eapol_key_authentication_type_WFA_SC +#if defined(EAP_USE_WPXM) + || m_authentication_type == eapol_key_authentication_type_WPXM +#endif //#if defined(EAP_USE_WPXM) + ) + { + // Start authentication if mode is not pre-shared key. If mode is pre-shared key then + // just wait for EAPOL-Key frames. + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::complete_association(): m_ethernet_core->start_authentication(): %s.\n"), + (m_is_client == true) ? "client": "server")); + status = m_ethernet_core->start_authentication(receive_network_id, m_is_client); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::complete_association(): m_ethernet_core->start_authentication(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::start_preauthentication( + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::start_preauthentication(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::start_preauthentication()"); + + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::start_preauthentication(): m_ethernet_core->start_preauthentication(): %s.\n"), + (m_is_client == true) ? "client": "server")); + eap_status_e status = m_ethernet_core->start_preauthentication( + receive_network_id, + m_authentication_type); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::start_preauthentication(): m_ethernet_core->start_preauthentication(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::check_pmksa_cache( + eap_array_c * const bssid_sta_receive_network_ids, + const eapol_key_authentication_type_e selected_eapol_key_authentication_type, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::check_pmksa_cache(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::check_pmksa_cache()"); + + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::check_pmksa_cache(): m_ethernet_core->check_pmksa_cache(): %s.\n"), + (m_is_client == true) ? "client": "server")); + eap_status_e status = m_ethernet_core->check_pmksa_cache( + bssid_sta_receive_network_ids, + selected_eapol_key_authentication_type, + pairwise_key_cipher_suite, + group_key_cipher_suite); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::check_pmksa_cache(): m_ethernet_core->check_pmksa_cache(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + if (bssid_sta_receive_network_ids->get_object_count() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_wlan_authentication_c::check_pmksa_cache(): %s: No PMKSA:s found in cache.\n"), + (m_is_client == true) ? "client": "server")); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::start_reassociation( + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address. + const eapol_key_authentication_type_e selected_eapol_key_authentication_type ///< In WPXM this must be the same in old and new APs, other connections can change authentication type. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::start_reassociation(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::start_reassociation()"); + + { + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("old_receive_network_id source:"), + old_receive_network_id->get_source_id()->get_data(), + old_receive_network_id->get_source_id()->get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("old_receive_network_id destination:"), + old_receive_network_id->get_destination_id()->get_data(), + old_receive_network_id->get_destination_id()->get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("new_receive_network_id source:"), + new_receive_network_id->get_source_id()->get_data(), + new_receive_network_id->get_source_id()->get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("new_receive_network_id destination:"), + new_receive_network_id->get_destination_id()->get_data(), + new_receive_network_id->get_destination_id()->get_data_length())); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status = cancel_all_authentication_sessions(); + if (status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::start_reassociation(): m_am_wauth->reset_eap_configuration(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_am_wauth->reset_eap_configuration(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c reassociation_PMKID(m_am_tools); + + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::start_reassociation(): m_ethernet_core->read_reassociation_parameters(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_ethernet_core->read_reassociation_parameters( + old_receive_network_id, + new_receive_network_id, + selected_eapol_key_authentication_type, + &reassociation_PMKID, + 0, + 0); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::start_reassociation(): m_ethernet_core->read_reassociation_parameters(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + if (status == eap_status_ok) + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + new_receive_network_id->get_destination_id(), + new_receive_network_id->get_source_id(), + new_receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_authentication_type = selected_eapol_key_authentication_type; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::start_reassociation(): %s: m_partner->reassociate(): m_authentication_type=%d.\n"), + (m_is_client == true) ? "client": "server", + m_authentication_type)); + + status = m_partner->reassociate( + &send_network_id, + m_authentication_type, + &reassociation_PMKID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::start_reassociation(): %s: m_partner->reassociate(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::complete_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eap_variable_data_c * const received_WPA_IE, // WLM must give only the WPA IE to EAPOL + const eap_variable_data_c * const sent_WPA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::complete_reassociation(): %s, reassociation_result=%d\n"), + (m_is_client == true) ? "client": "server", + reassociation_result)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::complete_reassociation()"); + + eap_status_e status(eap_status_process_general_error); + + if (reassociation_result != eapol_wlan_authentication_state_association_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_reassociation: Unsuccessful.\n"))); + + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::complete_reassociation(): m_ethernet_core->remove_pmksa_from_cache(): %s.\n"), + (m_is_client == true) ? "client": "server")); + status = m_ethernet_core->remove_pmksa_from_cache( + receive_network_id); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::complete_reassociation(): m_ethernet_core->remove_pmksa_from_cache(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_reassociation: Successful.\n"))); + + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::complete_reassociation(): m_ethernet_core->complete_reassociation(): %s.\n"), + (m_is_client == true) ? "client": "server")); + status = m_ethernet_core->complete_reassociation( + reassociation_result, + receive_network_id, + m_authentication_type, + received_WPA_IE, + sent_WPA_IE, + pairwise_key_cipher_suite, + group_key_cipher_suite); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::complete_reassociation(): m_ethernet_core->complete_reassociation(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::packet_process( + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + eap_general_header_base_c * const packet_data, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::packet_process(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::packet_process()"); + + if (packet_length < eapol_ethernet_header_wr_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eapol_ethernet_header_wr_c eth_header( + m_am_tools, + packet_data->get_header_buffer(packet_length), + packet_length); + + eap_status_e status(eap_status_process_general_error); + + if (eth_header.get_type() == eapol_ethernet_type_pae + || eth_header.get_type() == eapol_ethernet_type_preauthentication) + { + // Forward the packet to the Ethernet layer of the EAPOL stack. + // Ignore return value. Failure is signalled using state_notification. + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::packet_process(): m_ethernet_core->packet_process(): %s.\n"), + (m_is_client == true) ? "client": "server")); + status = m_ethernet_core->packet_process( + receive_network_id, + ð_header, + packet_length); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::packet_process(): m_ethernet_core->packet_process(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, ð_header); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Not supported ethernet type 0x%04x\n"), eth_header.get_type())); + status = eap_status_ethernet_type_not_supported; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eapol_wlan_authentication_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eapol_wlan_authentication_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eapol_wlan_authentication_c::increment_authentication_counter() +{ + ++m_authentication_counter; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eapol_wlan_authentication_c::get_authentication_counter() +{ + return m_authentication_counter; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eapol_wlan_authentication_c::get_is_client() +{ + return m_is_client; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_ok); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::packet_data_session_key(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::packet_data_session_key()"); + + const eap_variable_data_c * const key_data = key->get_key(); + if (key_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::packet_data_session_key(): %s: key_type 0x%02x=%s, key_index %d\n"), + (m_is_client == true) ? "client": "server", + key->get_key_type(), + eapol_session_key_c::get_eapol_key_type_string(key->get_key_type()), + key->get_key_index())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_data_session_key:"), + key_data->get_data(key_data->get_data_length()), + key_data->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_data_session_key send source"), + send_network_id->get_source(), + send_network_id->get_source_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_data_session_key send destination"), + send_network_id->get_destination(), + send_network_id->get_destination_length())); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::packet_data_session_key(): %s: m_partner->packet_data_session_key()\n"), + (m_is_client == true) ? "client": "server")); + + status = m_partner->packet_data_session_key(send_network_id, key); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::packet_data_session_key(): %s: m_partner->packet_data_session_key(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::packet_send(data_length=%d): %s.\n"), + data_length, + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::packet_send()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (header_offset != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + else if (header_offset+data_length != sent_packet->get_data_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: packet_send: packet buffer corrupted (data_length != sent_packet->get_data_length()).\n"))); + EAP_ASSERT(data_length == sent_packet->get_buffer_length()); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_status_e status(eap_status_ok); + + +#if defined(USE_EAP_ERROR_TESTS) + + sent_packet->set_is_client(true); + + if (m_randomly_drop_packets == true) + { + u32_t random_guard; + crypto_random_c rand(m_am_tools); + status = rand.get_rand_bytes( + reinterpret_cast(&random_guard), + sizeof(random_guard)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This is simple limiter to the probability of a packet drop. + // probability = m_randomly_drop_packets_probability / (2^32) + if (random_guard < m_randomly_drop_packets_probability) + { + // Drops this packet. + + if (sent_packet->get_stack_address() == 0) + { + // Initialize error testing data. + sent_packet->set_stack_address(this); + m_am_tools->increase_packet_index(); + sent_packet->set_send_packet_index(++m_packet_index); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send packet dropped\n"), + sent_packet->get_stack_address(), + sent_packet->get_send_packet_index())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + } + + if (m_send_original_packet_first == true) + { + if (sent_packet->get_stack_address() == 0) + { + // Initialize error testing data. + sent_packet->set_stack_address(this); + sent_packet->set_send_packet_index(++m_packet_index); + } + + if (m_enable_random_errors == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send original packet\n"), + sent_packet->get_stack_address(), + sent_packet->get_send_packet_index())); + } + + u8_t * const packet_data = sent_packet->get_data_offset(header_offset, data_length); + if (packet_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::packet_send(): %s: m_partner->packet_send()\n"), + (m_is_client == true) ? "client": "server")); + + // Here we send the original packet. + status = m_partner->packet_send( + send_network_id, + sent_packet, + header_offset, + data_length, + buffer_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::packet_send(): %s: m_partner->packet_send(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + } + + if (m_enable_random_errors == true + && status == eap_status_ok) + { + if (m_generate_multiple_error_packets > 0ul) + { + // First create a copy of sent packet. Original correct packet will will be sent last. + for (u32_t ind = 0ul; ind < m_generate_multiple_error_packets; ind++) + { + eap_buf_chain_wr_c *copy_packet = sent_packet->copy(); + + if (copy_packet != 0 + && copy_packet->get_is_valid_data() == true) + { + copy_packet->set_send_packet_index(++m_packet_index); + + // Make a random error to the copy message. + m_am_tools->generate_random_error( + copy_packet, + true, + copy_packet->get_send_packet_index(), + 0UL, + m_error_probability, + eapol_ethernet_header_wr_c::get_header_length()); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send error packet\n"), + copy_packet->get_stack_address(), + copy_packet->get_send_packet_index())); + + u8_t * const packet_data = copy_packet->get_data_offset(header_offset, data_length); + if (packet_data == 0) + { + delete copy_packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::packet_send(): %s: m_partner->packet_send()\n"), + (m_is_client == true) ? "client": "server")); + + // Here we send the copied and manipulated packet. + status = m_partner->packet_send( + send_network_id, + copy_packet, + header_offset, + data_length, + buffer_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::packet_send(): %s: m_partner->packet_send(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + } + + delete copy_packet; + } // for() + } + else + { + if (sent_packet->get_stack_address() == 0) + { + // Initialize error testing data. + sent_packet->set_stack_address(this); + sent_packet->set_send_packet_index(++m_packet_index); + } + + eap_buf_chain_wr_c *copy_packet = sent_packet->copy(); + + if (copy_packet != 0 + && copy_packet->get_is_valid_data() == true) + { + copy_packet->set_send_packet_index(++m_packet_index); + + // Make a random error to the copy message. + m_am_tools->generate_random_error( + copy_packet, + false, + copy_packet->get_send_packet_index(), + 0UL, + m_error_probability, + eapol_ethernet_header_wr_c::get_header_length()); + + if (copy_packet->get_is_manipulated() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send error packet\n"), + copy_packet->get_stack_address(), + copy_packet->get_send_packet_index())); + + u8_t * const packet_data = copy_packet->get_data_offset(header_offset, data_length); + if (packet_data == 0) + { + delete copy_packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::packet_send(): %s: m_partner->packet_send()\n"), + (m_is_client == true) ? "client": "server")); + + // Here we send the copied and manipulated packet. + status = m_partner->packet_send( + send_network_id, + copy_packet, + header_offset, + data_length, + buffer_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::packet_send(): %s: m_partner->packet_send(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + } + } + + delete copy_packet; + } + } + + + if (m_send_original_packet_first == false + && status == eap_status_ok) + { + if (sent_packet->get_stack_address() == 0) + { + // Initialize error testing data. + sent_packet->set_stack_address(this); + sent_packet->set_send_packet_index(++m_packet_index); + } + + if (m_enable_random_errors == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send original packet\n"), + sent_packet->get_stack_address(), + sent_packet->get_send_packet_index())); + } + + u8_t * const packet_data = sent_packet->get_data_offset(header_offset, data_length); + if (packet_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + +#endif //#if defined(USE_EAP_ERROR_TESTS) + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::packet_send(): %s: m_partner->packet_send()\n"), + (m_is_client == true) ? "client": "server")); + + // Here we send the original packet. + status = m_partner->packet_send( + send_network_id, + sent_packet, + header_offset, + data_length, + buffer_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::packet_send(): %s: m_partner->packet_send(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + +#if defined(USE_EAP_ERROR_TESTS) + } +#endif //#if defined(USE_EAP_ERROR_TESTS) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_wlan_authentication_c::cancel_timer_this_ap_failed() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = cancel_timer( + this, + EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::cancel_timer_this_ap_failed(): Cancels timer EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_wlan_authentication_c::cancel_timer_failed_completely() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = cancel_timer( + this, + EAPOL_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::cancel_timer_failed_completely(): Cancels timer EAPOL_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_wlan_authentication_c::cancel_timer_no_response() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = cancel_timer( + this, + EAPOL_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::cancel_timer_no_response(): Cancels timer EAPOL_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_wlan_authentication_c::cancel_timer_authentication_cancelled() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = cancel_timer( + this, + EAPOL_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::cancel_timer_authentication_cancelled(): Cancels timer EAPOL_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eapol_wlan_authentication_c::state_notification( + const abs_eap_state_notification_c * const state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::state_notification()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::state_notification()"); + + if (state == 0 + || state->get_send_network_id() == 0 + || state->get_send_network_id()->get_is_valid_data() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Illegal state notification state=0x%08x, state->get_send_network_id()=0x%08x.\n"), + state, + ((state != 0) ? state->get_send_network_id() : 0))); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + return; + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send source"), + state->get_send_network_id()->get_source(), + state->get_send_network_id()->get_source_length())); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send destination"), + state->get_send_network_id()->get_destination(), + state->get_send_network_id()->get_destination_length())); + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + state->get_send_network_id()->get_destination_id(), + state->get_send_network_id()->get_source_id(), + state->get_send_network_id()->get_type()); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_am_network_id_c* send_network_id = new eap_am_network_id_c( + m_am_tools, + state->get_send_network_id()); + + eap_automatic_variable_c + automatic_send_network_id(m_am_tools, send_network_id); + + if (send_network_id == 0 + || send_network_id->get_is_valid_data() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: No network identity: Indication sent to WLM: eap_status_failed_completely.\n"))); + + (void) cancel_timer_failed_completely(); + + set_timer( + this, + EAPOL_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID, + send_network_id, + 0); + + automatic_send_network_id.do_not_free_variable(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Sets timer ") + EAPL("EAPOL_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID.\n"))); + } + + + { + eap_status_string_c status_string; + eap_header_string_c eap_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::state_notification() %s: protocol layer %d=%s, protocol %d=%s, EAP-type 0x%08x=%s\n"), + (state->get_is_client() == true ? "client": "server"), + state->get_protocol_layer(), + state->get_protocol_layer_string(), + state->get_protocol(), + state->get_protocol_string(), + convert_eap_type_to_u32_t(state->get_eap_type()), + eap_string.get_eap_type_string(state->get_eap_type()))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::state_notification() %s: current state %d=%s, error %d=%s\n"), + (state->get_is_client() == true ? "client": "server"), + state->get_current_state(), + state->get_current_state_string(), + state->get_authentication_error(), + status_string.get_status_string(state->get_authentication_error()))); + } + + +#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"), + (m_is_client == true) ? "client": "server")); + + // Calls lower layer. + // Note the optimization prevents most of the state notifications to lower layer. + m_partner->state_notification(state); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"), + (m_is_client == true) ? "client": "server")); + +#endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + if(state->get_protocol_layer() == eap_protocol_layer_general) + { + if (state->get_current_state() == eap_general_state_authentication_cancelled) + { + // Authentication was cancelled. Cannot continue. + cancel_timer_authentication_cancelled(); + + set_timer(this, EAPOL_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID, send_network_id, 0); + automatic_send_network_id.do_not_free_variable(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Authentication was cancelled. Sets timer ") + EAPL("EAPOL_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID.\n"))); + + // This indication is sent synchronously to WLAN engine. That prevent other indications to bypass this indication. + eap_status_e status = eapol_indication( + &receive_network_id, + eapol_wlan_authentication_state_authentication_cancelled); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + } + else if (state->get_current_state() == eap_general_state_configuration_error) + { + // Configuration error. Cannot continue. + (void) cancel_timer_failed_completely(); + + set_timer(this, EAPOL_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID, send_network_id, 0); + automatic_send_network_id.do_not_free_variable(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Configuration error. Sets timer ") + EAPL("EAPOL_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID.\n"))); + } + else if (state->get_current_state() == eap_general_state_authentication_error) + { + // An authentication error from EAPOL-stack. + + eap_status_string_c status_string; + eap_header_string_c eap_string; + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_wlan_authentication_c::state_notification() %s: protocol layer %d=%s, protocol %d=%s, EAP-type 0x%08x=%s\n"), + (state->get_is_client() == true ? "client": "server"), + state->get_protocol_layer(), + state->get_protocol_layer_string(), + state->get_protocol(), + state->get_protocol_string(), + convert_eap_type_to_u32_t(state->get_eap_type()), + eap_string.get_eap_type_string(state->get_eap_type()))); + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_wlan_authentication_c::state_notification() %s: current state %d=%s, error %d=%s\n"), + (state->get_is_client() == true ? "client": "server"), + state->get_current_state(), + state->get_current_state_string(), + state->get_authentication_error(), + status_string.get_status_string(state->get_authentication_error()))); + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"), + (m_is_client == true) ? "client": "server")); + + // Calls lower layer. + // Note the optimization prevents most of the state notifications to lower layer. + m_partner->state_notification(state); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"), + (m_is_client == true) ? "client": "server")); + +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + (void) cancel_timer_this_ap_failed(); + + set_timer( + this, + EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID, + send_network_id, + 0); + automatic_send_network_id.do_not_free_variable(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Sets timer EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID.\n"))); + } + else if (state->get_current_state() == eap_general_state_immediate_reconnect) + { + // An provision protocol ready. Do immediate reconnect to use the new credentials. + + eap_status_string_c status_string; + eap_header_string_c eap_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::state_notification() %s: protocol layer %d=%s, protocol %d=%s, EAP-type 0x%08x=%s\n"), + (state->get_is_client() == true ? "client": "server"), + state->get_protocol_layer(), + state->get_protocol_layer_string(), + state->get_protocol(), + state->get_protocol_string(), + convert_eap_type_to_u32_t(state->get_eap_type()), + eap_string.get_eap_type_string(state->get_eap_type()))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::state_notification() %s: current state %d=%s, error %d=%s\n"), + (state->get_is_client() == true ? "client": "server"), + state->get_current_state(), + state->get_current_state_string(), + state->get_authentication_error(), + status_string.get_status_string(state->get_authentication_error()))); + + eap_status_e status = eapol_indication( + &receive_network_id, + eapol_wlan_authentication_state_immediate_reconnect); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + } + } + else if(state->get_protocol_layer() == eap_protocol_layer_eap) // Check if this is EAP layer notification + { + switch (state->get_current_state()) + { + case eap_state_none: + break; + case eap_state_identity_request_sent: + // This is for server only so no need to notify WLM. + break; + case eap_state_identity_request_received: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP authentication running...\n"))); + } + break; + case eap_state_identity_response_received: + // This is for server only so no need to notify WLM. + break; + case eap_state_authentication_finished_successfully: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::state_notification(): m_am_wauth->authentication_finished(): %s.\n"), + (m_is_client == true) ? "client": "server")); + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"), + (m_is_client == true) ? "client": "server")); + + // Calls lower layer. + // Note the optimization prevents most of the state notifications to lower layer. + m_partner->state_notification(state); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"), + (m_is_client == true) ? "client": "server")); + +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + m_am_wauth->authentication_finished( + true, + state->get_eap_type(), + m_authentication_type); + +#if defined(USE_EAP_EXPANDED_TYPES) + if (state->get_eap_type() == eap_expanded_type_simple_config.get_type()) + { + increment_authentication_counter(); + m_successful_authentications++; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: EAP WFA Protected Setup SUCCESS\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eapol_indication( + &receive_network_id, + eapol_wlan_authentication_state_authentication_successfull); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + } + break; + case eap_state_authentication_terminated_unsuccessfully: + { + increment_authentication_counter(); + m_failed_authentications++; + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"), + (m_is_client == true) ? "client": "server")); + + // Calls lower layer. + // Note the optimization prevents most of the state notifications to lower layer. + m_partner->state_notification(state); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"), + (m_is_client == true) ? "client": "server")); + +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::state_notification(): m_am_wauth->authentication_finished(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + m_am_wauth->authentication_finished( + false, + state->get_eap_type(), + m_authentication_type); + + (void) cancel_timer_this_ap_failed(); + + set_timer( + this, + EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID, + send_network_id, + 0); + automatic_send_network_id.do_not_free_variable(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Sets timer EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID.\n"))); + } + break; + default: + break; + } + } + else if(state->get_protocol_layer() == eap_protocol_layer_eapol) + { + switch (state->get_current_state()) + { + case eapol_state_no_start_response: + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Indication sent to WLM: ENoResponse.\n"))); + + { + (void) cancel_timer_no_response(); + + set_timer( + this, + EAPOL_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID, + send_network_id, + 0); + automatic_send_network_id.do_not_free_variable(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Sets timer ") + EAPL("EAPOL_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID.\n"))); + } + break; + default: + break; + } + } + else if(state->get_protocol_layer() == eap_protocol_layer_eapol_key) + { + switch (state->get_current_state()) + { + + case eapol_key_state_eap_authentication_running: + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: EAP authentication RUNNING\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eapol_indication( + &receive_network_id, + eapol_wlan_authentication_state_eap_authentication_running); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + break; + + case eapol_key_state_4_way_handshake_running: + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: 4-Way Handshake RUNNING\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eapol_indication( + &receive_network_id, + eapol_wlan_authentication_state_4_way_handshake_running); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + break; + + case eapol_key_state_802_11i_authentication_terminated_unsuccessfull: + case eapol_key_state_reassociation_failed: + { + increment_authentication_counter(); + m_failed_authentications++; + + // Consider EAPOL layer failures fatal. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Unsuccessful authentication on EAPOL level.\n"))); + + (void) cancel_timer_this_ap_failed(); + + set_timer( + this, + EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID, + send_network_id, + 0); + automatic_send_network_id.do_not_free_variable(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Sets timer EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID.\n"))); + } + break; + + case eapol_key_state_802_11i_authentication_finished_successfull: +#if defined(EAP_USE_WPXM) + case eapol_key_state_wpxm_reassociation_finished_successfull: +#endif //#if defined(EAP_USE_WPXM) + { + // This is used in dynamic WEP (802.1x), WPA and WPA2 (RNS) authentications. + increment_authentication_counter(); + m_successful_authentications++; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: Authentication SUCCESS\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eapol_indication( + &receive_network_id, + eapol_wlan_authentication_state_authentication_successfull); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + break; + + default: + break; + } + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::state_notification(): m_am_wauth->state_notification(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + // AM could have to show some notification to user. + m_am_wauth->state_notification(state); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::timer_expired( + const u32_t id, + void * data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::timer_expired(): id = %d, data = 0x%08x.\n"), + id, + data)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::timer_expired()"); + + eap_am_network_id_c * const send_network_id = static_cast(data); + if (send_network_id == 0 + || send_network_id->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + send_network_id->get_destination_id(), + send_network_id->get_source_id(), + send_network_id->get_type()); + + + switch (id) + { + case EAPOL_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID elapsed: ") + EAPL("Indication sent to WLM: eap_status_failed_completely.\n"))); + + (void) disassociation_mutex_must_be_reserved(&receive_network_id); + + eap_status_e status = eapol_indication( + &receive_network_id, + eapol_wlan_authentication_state_failed_completely); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + break; + + case EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID elapsed: ") + EAPL("Indication sent to WLM: eap_status_this_ap_failed.\n"))); + + (void) disassociation_mutex_must_be_reserved(&receive_network_id); + + eap_status_e status = eapol_indication( + &receive_network_id, + eapol_wlan_authentication_state_this_ap_failed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + break; + + case EAPOL_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID elapsed: ") + EAPL("Indication sent to WLM: eap_status_no_response.\n"))); + + (void) disassociation_mutex_must_be_reserved(&receive_network_id); + + eap_status_e status = eapol_indication( + &receive_network_id, + eapol_wlan_authentication_state_no_response); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + break; + + case EAPOL_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID elapsed: ") + EAPL("Indication sent to WLM: eapol_wlan_authentication_state_authentication_cancelled.\n"))); + + (void) disassociation_mutex_must_be_reserved(&receive_network_id); + } + break; + + default: + break; + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::timer_delete_data( + const u32_t id, + void *data) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::timer_delete_data(): id = %d, data = 0x%08x.\n"), + id, + data)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::timer_delete_data()"); + + eap_am_network_id_c * const send_network_id = static_cast(data); + if (send_network_id == 0 + || send_network_id->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + switch (id) + { + //case EAPOL_WLAN_AUTHENTICATION_TIMER_RESTART_AUTHENTICATION_ID: + //case EAPOL_WLAN_AUTHENTICATION_TIMER_DELETE_STACK_ID: + case EAPOL_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID: + case EAPOL_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID: + case EAPOL_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID: + case EAPOL_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID: + delete send_network_id; + break; + default: + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::timer_delete_data: deleted unknown timer.\n"))); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eapol_wlan_authentication_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::get_header_offset()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::get_header_offset()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::get_header_offset(): %s: m_partner->get_header_offset()\n"), + (m_is_client == true) ? "client": "server")); + + const u32_t offset = m_partner->get_header_offset(MTU, trailer_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::get_header_offset(): %s: m_partner->get_header_offset(): offset = %d\n"), + (m_is_client == true) ? "client": "server", + offset)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return offset; + +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::unload_module( + const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::unload_module(type 0x%08x=%s): \n"), + convert_eap_type_to_u32_t(type), + eap_header_string_c::get_eap_type_string(type) + )); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::unload_module()"); + + eap_status_e status(eap_status_type_does_not_exists_error); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::unload_module(): m_am_wauth->unload_module(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_am_wauth->unload_module(type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::eap_acknowledge( + const eap_am_network_id_c * const receive_network_id) +{ + // Any Network Protocol packet is accepted as a success indication. + // This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::eap_acknowledge()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::eap_acknowledge()"); + + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::eap_acknowledge(): m_ethernet_core->eap_acknowledge(): %s.\n"), + (m_is_client == true) ? "client": "server")); + eap_status_e status = m_ethernet_core->eap_acknowledge(receive_network_id); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::eap_acknowledge(): m_ethernet_core->eap_acknowledge(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type_if, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::load_module(type 0x%08x=%s, tunneling_type 0x%08x=%s), %s\n"), + convert_eap_type_to_u32_t(type), + eap_header_string_c::get_eap_type_string(type), + convert_eap_type_to_u32_t(tunneling_type), + eap_header_string_c::get_eap_type_string(tunneling_type), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::load_module()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::load_module(): m_am_wauth->load_module(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->load_module( + type, + tunneling_type, + partner, + eap_type_if, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_wlan_authentication_c::disassociation_mutex_must_be_reserved( + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::disassociation_mutex_must_be_reserved(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::disassociation_mutex_must_be_reserved()"); + + // reset index + m_current_eap_index = 0UL; + + eap_status_e status(eap_status_process_general_error); + + if (m_ethernet_core != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::disassociation_mutex_must_be_reserved(): m_ethernet_core->disassociation(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_ethernet_core->disassociation(receive_network_id); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::disassociation_mutex_must_be_reserved(): m_ethernet_core->disassociation(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + if (status == eap_status_handler_does_not_exists_error) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::disassociation_mutex_must_be_reserved(): Association did not exists.\n"))); + status = eap_status_ok; + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::disassociation_mutex_must_be_reserved(): Stack did not exists.\n"))); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::disassociation_mutex_must_be_reserved(): m_am_wauth->disassociation(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + // This call indicates the disassociation to adaptation. + status = m_am_wauth->disassociation(receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::disassociation_mutex_must_be_reserved(): m_am_wauth->disassociation() failed.\n"))); + (void) EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::disassociation( + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::disassociation(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::disassociation()"); + + eap_status_e status(eap_status_ok); + + WAUTH_ENTER_MUTEX(m_am_tools); + status = disassociation_mutex_must_be_reserved(receive_network_id); + WAUTH_LEAVE_MUTEX(m_am_tools); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::tkip_mic_failure( + const eap_am_network_id_c * const receive_network_id, + const bool fatal_failure_when_true, + const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::tkip_mic_failure(%d, %d).\n"), + fatal_failure_when_true, + tkip_mic_failure_type)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::tkip_mic_failure()"); + + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::tkip_mic_failure(): m_ethernet_core->tkip_mic_failure(): %s.\n"), + (m_is_client == true) ? "client": "server")); + const eap_status_e status = m_ethernet_core->tkip_mic_failure( + receive_network_id, + fatal_failure_when_true, + tkip_mic_failure_type); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::tkip_mic_failure(): m_ethernet_core->tkip_mic_failure(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::configure() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::configure(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::configure()"); + + //---------------------------------------------------------- + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::configure(): m_am_wauth->configure(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_ERROR_TESTS) + + { + eap_variable_data_c EAP_ERROR_TEST_randomly_drop_packets(m_am_tools); + + status = read_configure( + cf_str_EAP_ERROR_TEST_randomly_drop_packets.get_field(), + &EAP_ERROR_TEST_randomly_drop_packets); + if (status == eap_status_ok + && EAP_ERROR_TEST_randomly_drop_packets.get_is_valid_data() == true) + { + u32_t *randomly_drop_packets = reinterpret_cast( + EAP_ERROR_TEST_randomly_drop_packets.get_data(sizeof(u32_t))); + if (randomly_drop_packets != 0 + && *randomly_drop_packets != 0) + { + m_randomly_drop_packets = true; + } + } + } + + { + eap_variable_data_c EAP_ERROR_TEST_randomly_drop_packets_probability(m_am_tools); + + status = read_configure( + cf_str_EAP_ERROR_TEST_randomly_drop_packets_probability.get_field(), + &EAP_ERROR_TEST_randomly_drop_packets_probability); + if (status == eap_status_ok + && EAP_ERROR_TEST_randomly_drop_packets_probability.get_is_valid_data() == true) + { + u32_t *randomly_drop_packets_probability = reinterpret_cast( + EAP_ERROR_TEST_randomly_drop_packets_probability.get_data(sizeof(u32_t))); + if (randomly_drop_packets_probability != 0) + { + m_randomly_drop_packets_probability = *randomly_drop_packets_probability; + } + } + } + + { + eap_variable_data_c EAP_ERROR_TEST_enable_random_errors(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_ERROR_TEST_enable_random_errors.get_field(), + &EAP_ERROR_TEST_enable_random_errors); + if (status == eap_status_ok + && EAP_ERROR_TEST_enable_random_errors.get_is_valid_data() == true) + { + u32_t *enable_random_errors = reinterpret_cast( + EAP_ERROR_TEST_enable_random_errors.get_data(sizeof(u32_t))); + if (enable_random_errors != 0 + && *enable_random_errors != 0) + { + m_enable_random_errors = true; + } + } + } + + { + eap_variable_data_c EAP_ERROR_TEST_send_original_packet_first(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_ERROR_TEST_send_original_packet_first.get_field(), + &EAP_ERROR_TEST_send_original_packet_first); + if (status == eap_status_ok + && EAP_ERROR_TEST_send_original_packet_first.get_is_valid_data() == true) + { + u32_t *send_original_packet_first = reinterpret_cast( + EAP_ERROR_TEST_send_original_packet_first.get_data(sizeof(u32_t))); + if (send_original_packet_first != 0 + && *send_original_packet_first != 0) + { + m_send_original_packet_first = true; + } + } + } + + { + eap_variable_data_c EAP_ERROR_TEST_generate_multiple_error_packets(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_ERROR_TEST_generate_multiple_error_packets.get_field(), + &EAP_ERROR_TEST_generate_multiple_error_packets); + if (status == eap_status_ok + && EAP_ERROR_TEST_generate_multiple_error_packets.get_is_valid_data() == true) + { + u32_t *generate_multiple_error_packets = reinterpret_cast( + EAP_ERROR_TEST_generate_multiple_error_packets.get_data(sizeof(u32_t))); + if (generate_multiple_error_packets != 0 + && *generate_multiple_error_packets != 0) + { + m_generate_multiple_error_packets = *generate_multiple_error_packets; + } + } + } + + + { + eap_variable_data_c EAP_ERROR_TEST_manipulate_ethernet_header(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_ERROR_TEST_manipulate_ethernet_header.get_field(), + &EAP_ERROR_TEST_manipulate_ethernet_header); + if (status == eap_status_ok + && EAP_ERROR_TEST_manipulate_ethernet_header.get_is_valid_data() == true) + { + u32_t *manipulate_ethernet_header = reinterpret_cast( + EAP_ERROR_TEST_manipulate_ethernet_header.get_data(sizeof(u32_t))); + if (manipulate_ethernet_header != 0 + && *manipulate_ethernet_header != 0) + { + m_manipulate_ethernet_header = true; + } + } + } + + { + eap_variable_data_c EAP_ERROR_TEST_error_probability(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_ERROR_TEST_error_probability.get_field(), + &EAP_ERROR_TEST_error_probability); + if (status == eap_status_ok + && EAP_ERROR_TEST_error_probability.get_is_valid_data() == true) + { + u32_t *error_probability = reinterpret_cast( + EAP_ERROR_TEST_error_probability.get_data(sizeof(u32_t))); + if (error_probability != 0) + { + m_error_probability = *error_probability; + } + } + } + + { + eap_variable_data_c EAP_disable_function_traces(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_enable_function_traces.get_field(), + &EAP_disable_function_traces); + if (status == eap_status_ok + && EAP_disable_function_traces.get_is_valid_data() == true) + { + u32_t *disable_function_traces = reinterpret_cast( + EAP_disable_function_traces.get_data(sizeof(u32_t))); + if (disable_function_traces != 0 + && *disable_function_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | eap_am_tools_c::eap_trace_mask_functions + ); + } + } + } + +#endif //#if defined(USE_EAP_ERROR_TESTS) + + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_disable_traces(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_disable_traces.get_field(), + &EAP_TRACE_disable_traces); + if (status == eap_status_ok + && EAP_TRACE_disable_traces.get_is_valid_data() == true) + { + u32_t *disable_traces = reinterpret_cast( + EAP_TRACE_disable_traces.get_data(sizeof(u32_t))); + if (disable_traces != 0 + && *disable_traces != 0) + { + m_am_tools->set_trace_mask(eap_am_tools_c::eap_trace_mask_none); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_activate_only_trace_masks_always_and_error(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_activate_only_trace_masks_always_and_error.get_field(), + &EAP_TRACE_activate_only_trace_masks_always_and_error); + if (status == eap_status_ok + && EAP_TRACE_activate_only_trace_masks_always_and_error.get_is_valid_data() == true) + { + u32_t *activate_trace_mask_always = reinterpret_cast( + EAP_TRACE_activate_only_trace_masks_always_and_error.get_data(sizeof(u32_t))); + if (activate_trace_mask_always != 0 + && *activate_trace_mask_always != 0) + { + m_am_tools->set_trace_mask( + eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_error + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_activate_trace_on_error(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_activate_trace_on_error.get_field(), + &EAP_TRACE_activate_trace_on_error); + if (status == eap_status_ok + && EAP_TRACE_activate_trace_on_error.get_is_valid_data() == true) + { + u32_t *activate_trace_on_error = reinterpret_cast( + EAP_TRACE_activate_trace_on_error.get_data(sizeof(u32_t))); + if (activate_trace_on_error != 0 + && *activate_trace_on_error != 0) + { + m_am_tools->set_activate_trace_on_error(); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_enable_timer_traces(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_enable_timer_traces.get_field(), + &EAP_TRACE_enable_timer_traces); + if (status == eap_status_ok + && EAP_TRACE_enable_timer_traces.get_is_valid_data() == true) + { + u32_t *enable_timer_traces = reinterpret_cast( + EAP_TRACE_enable_timer_traces.get_data(sizeof(u32_t))); + if (enable_timer_traces != 0 + && *enable_timer_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | TRACE_FLAGS_TIMER + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_enable_timer_queue_traces(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_enable_timer_queue_traces.get_field(), + &EAP_TRACE_enable_timer_queue_traces); + if (status == eap_status_ok + && EAP_TRACE_enable_timer_queue_traces.get_is_valid_data() == true) + { + u32_t *enable_timer_queue_traces = reinterpret_cast( + EAP_TRACE_enable_timer_queue_traces.get_data(sizeof(u32_t))); + if (enable_timer_queue_traces != 0 + && *enable_timer_queue_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | TRACE_FLAGS_TIMER_QUEUE + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_enable_ok_return_traces(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_enable_ok_return_traces.get_field(), + &EAP_TRACE_enable_ok_return_traces); + if (status == eap_status_ok + && EAP_TRACE_enable_ok_return_traces.get_is_valid_data() == true) + { + u32_t *enable_ok_return_traces = reinterpret_cast( + EAP_TRACE_enable_ok_return_traces.get_data(sizeof(u32_t))); + if (enable_ok_return_traces != 0 + && *enable_ok_return_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | TRACE_FLAGS_OK_RETURNS + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_enable_message_data_traces(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_enable_message_data_traces.get_field(), + &EAP_TRACE_enable_message_data_traces); + if (status == eap_status_ok + && EAP_TRACE_enable_message_data_traces.get_is_valid_data() == true) + { + u32_t *enable_message_data_traces = reinterpret_cast( + EAP_TRACE_enable_message_data_traces.get_data(sizeof(u32_t))); + if (enable_message_data_traces != 0 + && *enable_message_data_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | EAP_TRACE_FLAGS_MESSAGE_DATA + ); + } + } + } + + //---------------------------------------------------------- + + // Create stack if it does not already exist. + status = create_upper_stack(); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // All of the configuration options are optional. + // So we return OK. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::read_configure(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::read_configure()"); + + EAP_ASSERT_ALWAYS(data != 0); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::read_configure(): m_am_wauth->read_configure(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->read_configure(field, data); + + m_am_tools->trace_configuration( + status, + field, + data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::write_configure(): %s\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::write_configure()"); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::write_configure(): m_am_wauth->write_configure(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->write_configure(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::set_timer(): id = %d, data = 0x%08x, time = %d\n"), + p_id, + p_data, + p_time_ms)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::set_timer()"); + + const eap_status_e status = m_am_tools->am_set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::cancel_timer(): initializer = 0x%08x, id = %d\n"), + p_initializer, + p_id)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::cancel_timer()"); + + const eap_status_e status = m_am_tools->am_cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::cancel_all_timers()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::cancel_all_timers()"); + + eap_status_e status = eap_status_ok; + + if (m_am_tools != 0) + { + WAUTH_ENTER_MUTEX(m_am_tools); + status = m_am_tools->am_cancel_all_timers(); + WAUTH_LEAVE_MUTEX(m_am_tools); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::check_is_valid_eap_type( + const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::check_is_valid_eap_type()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::check_is_valid_eap_type()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::check_is_valid_eap_type(): m_am_wauth->check_is_valid_eap_type(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->check_is_valid_eap_type(eap_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::get_eap_type_list()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::get_eap_type_list()"); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls: eapol_wlan_authentication_c::get_eap_type_list(): m_am_wauth->get_eap_type_list(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_am_wauth->get_eap_type_list(eap_type_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::eapol_indication( + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + const eapol_wlan_authentication_state_e wlan_authentication_state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::eapol_indication()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::eapol_indication()"); + + eap_status_e status(eap_status_ok); + + eap_am_network_id_c send_network_id(m_am_tools); + + if (receive_network_id != 0) + { + // Here we swap the addresses. + eap_am_network_id_c tmp_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + status = send_network_id.set_copy_of_network_id(&tmp_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_wlan_authentication, + eap_type_none, // EAP-type is unknown. + eapol_wlan_authentication_state_none, // Previous state is unknown. + wlan_authentication_state, // The current indicated state. + 0UL, // EAP-identifier is unknown. + false // This is not applicable here. + ); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_wlan_authentication_c::eapol_indication(): Sending state notification to Engine. state=%s=%d\n"), + notification.get_state_string( notification.get_protocol_layer() ,wlan_authentication_state ), + wlan_authentication_state)); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send source"), + send_network_id.get_source(), + send_network_id.get_source_length())); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send destination"), + send_network_id.get_destination(), + send_network_id.get_destination_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::eapol_indication(): %s: m_partner->state_notification()\n"), + (m_is_client == true) ? "client": "server")); + + m_partner->state_notification(¬ification); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::eapol_indication(): %s: m_partner->state_notification(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::create_upper_stack() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::create_upper_stack()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::create_upper_stack()"); + + eap_status_e status(eap_status_ok); + + if (m_ethernet_core == 0) + { + m_ethernet_core = new ethernet_core_c(m_am_tools, this, m_is_client); + if (m_ethernet_core == 0 + || m_ethernet_core->get_is_valid() != true) + { + if (m_ethernet_core != 0) + { + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::create_upper_stack(): m_ethernet_core->shutdown(): %s.\n"), + (m_is_client == true) ? "client": "server")); + status = m_ethernet_core->shutdown(); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::create_upper_stack(): m_ethernet_core->shutdown(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + delete m_ethernet_core; + m_ethernet_core = 0; + } + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Stack creation failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Initialise upper stack + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::create_upper_stack(): m_ethernet_core->configure(): %s.\n"), + (m_is_client == true) ? "client": "server")); + status = m_ethernet_core->configure(); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::create_upper_stack(): m_ethernet_core->configure(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + if (status != eap_status_ok) + { + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::create_upper_stack(): m_ethernet_core->shutdown(): %s.\n"), + (m_is_client == true) ? "client": "server")); + status = m_ethernet_core->shutdown(); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::create_upper_stack(): m_ethernet_core->shutdown(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + delete m_ethernet_core; + m_ethernet_core = 0; + + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Stack creation failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + else + { + status = eap_status_already_exists; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::add_rogue_ap()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::add_rogue_ap()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status(eap_status_ok); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::add_rogue_ap(): %s: m_partner->add_rogue_ap()\n"), + (m_is_client == true) ? "client": "server")); + + status = m_partner->add_rogue_ap(rogue_ap_list); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::add_rogue_ap(): %s: m_partner->add_rogue_ap(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eapol_wlan_authentication_c::get_current_eap_index() +{ + return m_current_eap_index; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eapol_wlan_authentication_c::set_current_eap_index(u32_t eap_index) +{ + m_current_eap_index = eap_index; +} + +//-------------------------------------------------- + +#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + +EAP_FUNC_EXPORT u32_t eapol_wlan_authentication_c::get_wrong_send_packet_index() +{ + return 0ul; +} + +#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + +//-------------------------------------------------- + +#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + +EAP_FUNC_EXPORT void eapol_wlan_authentication_c::reset_authentication_can_succeed() +{ +} + +#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + +//-------------------------------------------------- + +#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + +EAP_FUNC_EXPORT void eapol_wlan_authentication_c::set_authentication_can_succeed() +{ +} + +#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + +//-------------------------------------------------- + +#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + +EAP_FUNC_EXPORT void eapol_wlan_authentication_c::restore_authentication_can_succeed() +{ +} + +#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + +//-------------------------------------------------- + +#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + +EAP_FUNC_EXPORT void eapol_wlan_authentication_c::set_authentication_must_not_succeed( + const u32_t /* wrong_packet_index */, + const u32_t /* packet_index */, + const void * const /* wrong_packet_stack */) +{ +} + +#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::start_WPXM_reassociation( + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address. + eap_variable_data_c * const send_reassociation_request_ie, + const eap_variable_data_c * const received_WPA_ie, + const eap_variable_data_c * const sent_WPA_ie + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::start_WPXM_reassociation(): %s\n"), + (m_is_client == true) ? "client": "server")); + + { + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("old_receive_network_id source:"), + old_receive_network_id->get_source_id()->get_data(), + old_receive_network_id->get_source_id()->get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("old_receive_network_id destination:"), + old_receive_network_id->get_destination_id()->get_data(), + old_receive_network_id->get_destination_id()->get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("new_receive_network_id source:"), + new_receive_network_id->get_source_id()->get_data(), + new_receive_network_id->get_source_id()->get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("new_receive_network_id destination:"), + new_receive_network_id->get_destination_id()->get_data(), + new_receive_network_id->get_destination_id()->get_data_length())); + } + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::start_WPXM_reassociation()"); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status = cancel_all_authentication_sessions(); + if (status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c reassociation_PMKID(m_am_tools); + + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::start_reassociation(): m_ethernet_core->read_reassociation_parameters(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_ethernet_core->read_reassociation_parameters( + old_receive_network_id, + new_receive_network_id, + m_authentication_type, + &reassociation_PMKID, + received_WPA_ie, + sent_WPA_ie); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::start_reassociation(): m_ethernet_core->read_reassociation_parameters(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + if (status == eap_status_ok) + { + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::start_WPXM_reassociation(): m_ethernet_core->start_WPXM_reassociation(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + status = m_ethernet_core->start_WPXM_reassociation( + new_receive_network_id, + m_authentication_type, + send_reassociation_request_ie); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::start_WPXM_reassociation(): m_ethernet_core->start_WPXM_reassociation(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::complete_WPXM_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eap_variable_data_c * const received_reassociation_ie + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("partner calls: eapol_wlan_authentication_c::complete_WPXM_reassociation(): %s, reassociation_result=%d\n"), + (m_is_client == true) ? "client": "server", + reassociation_result)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: eapol_wlan_authentication_c::complete_WPXM_reassociation()"); + + eap_status_e status(eap_status_process_general_error); + + if (reassociation_result != eapol_wlan_authentication_state_association_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_WPXM_reassociation: Unsuccessful.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_WPXM_reassociation: Successful.\n"))); + + WAUTH_ENTER_MUTEX(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls eapol: eapol_wlan_authentication_c::complete_WPXM_reassociation(): m_ethernet_core->complete_WPXM_reassociation(): %s.\n"), + (m_is_client == true) ? "client": "server")); + status = m_ethernet_core->complete_WPXM_reassociation( + reassociation_result, + receive_network_id, + m_authentication_type, + received_reassociation_ie); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from eapol: eapol_wlan_authentication_c::complete_WPXM_reassociation(): m_ethernet_core->complete_WPXM_reassociation(): %s, status = %s.\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + WAUTH_LEAVE_MUTEX(m_am_tools); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +// +EAP_FUNC_EXPORT eap_status_e eapol_wlan_authentication_c::save_simple_config_session( + const simple_config_state_e state, + EAP_TEMPLATE_CONST eap_array_c * const credential_array, + const eap_variable_data_c * const new_password, + const simple_config_Device_Password_ID_e Device_Password_ID, + const simple_config_payloads_c * const other_configuration) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol calls: eapol_wlan_authentication_c::save_simple_config_session(): %s\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: eapol_wlan_authentication_c::save_simple_config_session()"); + + for (u32_t ind = 0ul; ind < credential_array->get_object_count(); ind++) + { + simple_config_credential_c * const credential = credential_array->get_object(ind); + + if (credential != 0 + && credential->get_is_valid() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: network_index=%d\n"), + credential->get_network_index())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: SSID"), + credential->get_SSID()->get_data(), + credential->get_SSID()->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: Authentication_Type=%d\n"), + credential->get_Authentication_Type())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: Encryption_Type=%d\n"), + credential->get_Encryption_Type())); + + for (u32_t ind = 0ul; ind < credential->get_network_keys()->get_object_count(); ++ind) + { + network_key_and_index_c * const key = credential->get_network_keys()->get_object(ind); + if (key != 0) + { + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: network_key_index=%d\n"), + key->get_network_key_index())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: Key"), + key->get_network_key()->get_data(), + key->get_network_key()->get_data_length())); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: MAC_address"), + credential->get_MAC_address()->get_data(), + credential->get_MAC_address()->get_data_length())); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: new_password"), + new_password->get_data(), + new_password->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: Device_Password_ID=%d\n"), + Device_Password_ID)); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("calls partner: eapol_wlan_authentication_c::save_simple_config_session(): %s: m_partner->save_simple_config_session()\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = m_partner->save_simple_config_session( + state, + credential_array, + new_password, + Device_Password_ID, + other_configuration); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("returns from partner: eapol_wlan_authentication_c::save_simple_config_session(): %s: m_partner->save_simple_config_session(): status = %s\n"), + (m_is_client == true) ? "client": "server", + eap_status_string_c::get_status_string(status))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_wlan_database_reference.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_wlan_database_reference.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 58 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eapol_wlan_database_reference.h" +#include "eap_am_tools.h" +#include "eap_tools.h" + +//-------------------------------------------------- + + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/eapol_wlan_state.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/eapol_wlan_state.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 59 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eapol_wlan_state.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_wlan_state_c::~eapol_wlan_state_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_wlan_state_c::eapol_wlan_state_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_is_valid(true) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eapol_wlan_state_c::get_is_valid() const +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/ethernet_core.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/ethernet_core.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,957 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 62 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_variable_data.h" +#include "eap_tools.h" +#include "ethernet_core.h" +#include "eapol_ethernet_header.h" +#include "eap_buffer.h" +#include "eapol_session_key.h" +#include "eap_automatic_variable.h" + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT ethernet_core_c::~ethernet_core_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ethernet_core_c::~ethernet_core_c(): this = 0x%08x\n"), + this)); + + EAP_ASSERT(m_shutdown_was_called == true); + + delete m_eapol_core; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +// +EAP_FUNC_EXPORT ethernet_core_c::ethernet_core_c( + abs_eap_am_tools_c * const tools, + abs_ethernet_core_c * const partner, + const bool is_client_when_true) +: m_partner(partner) +, m_eapol_core(new eapol_core_c(tools, this, is_client_when_true)) +, m_am_tools(tools) +, m_is_client(is_client_when_true) +, m_is_valid(false) +, m_shutdown_was_called(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ethernet_core_c::ethernet_core_c(): %s, this = 0x%08x, compiled %s %s.\n"), + (m_is_client == true) ? "client": "server", + this, + __DATE__, + __TIME__)); + + if (m_eapol_core != 0 + && m_eapol_core->get_is_valid() == true) + { + set_is_valid(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_base_type_c * ethernet_core_c::load_type(const eap_type_value_e /* type */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::packet_process( + const eap_am_network_id_c * const /* receive_network_id */, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("####################################################################\n"))); + + if (m_eapol_core == 0) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("####################################################################\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (packet_length < eapol_ethernet_header_rd_c::get_header_length()) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("####################################################################\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + eapol_ethernet_header_wr_c eth_header( + m_am_tools, + packet_data->get_header_buffer(packet_data->get_header_buffer_length()), + packet_data->get_header_buffer_length()); + + if (eth_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (packet_length < eth_header.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("-> ETHERNET: %s: type=0x%04x, packet_length 0x%04x\n"), + (m_is_client == true) ? "client": "server", + eth_header.get_type(), + packet_length)); + + if (m_is_client == true) + { + EAP_TRACE_DATA_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("-> ETHERNET packet client"), + eth_header.get_header_buffer(eth_header.get_header_buffer_length()), + packet_length)); + } + else + { + EAP_TRACE_DATA_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("-> ETHERNET packet server"), + eth_header.get_header_buffer(eth_header.get_header_buffer_length()), + packet_length)); + } + + if (eth_header.get_type() == eapol_ethernet_type_pae + || eth_header.get_type() == eapol_ethernet_type_preauthentication) + { + eap_am_network_id_c receive_network_id( + m_am_tools, + eth_header.get_source(), + eth_header.get_source_length(), + eth_header.get_destination(), + eth_header.get_destination_length(), + eth_header.get_type(), + false, + false); + + eapol_header_wr_c eapol( + m_am_tools, + eth_header.get_eapol_header(), + eth_header.get_data_length()); + if (eapol.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = m_eapol_core->packet_process( + &receive_network_id, + &eapol, + packet_length-eapol_ethernet_header_rd_c::get_header_length()); + + EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eapol); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Not supported ethernet type 0x%04x\n"), eth_header.get_type())); + status = eap_status_ethernet_type_not_supported; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("####################################################################\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(header_offset < sent_packet->get_data_length()); + EAP_ASSERT(data_length <= sent_packet->get_data_length()); + EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); + + if (send_network_id->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (header_offset < eapol_ethernet_header_wr_c::get_header_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eapol_ethernet_header_wr_c eth( + m_am_tools, + sent_packet->get_data_offset( + header_offset-eapol_ethernet_header_wr_c::get_header_length(), + eapol_ethernet_header_wr_c::get_header_length()), + eapol_ethernet_header_wr_c::get_header_length()); + + if (eth.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + + eth.set_type(static_cast(send_network_id->get_type())); + + m_am_tools->memmove( + eth.get_destination(), + send_network_id->get_destination(), + send_network_id->get_destination_length()); + + m_am_tools->memmove( + eth.get_source(), + send_network_id->get_source(), + send_network_id->get_source_length()); + + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("<- ETHERNET: %s: type=0x%04x, packet_length 0x%04x\n"), + (m_is_client == true) ? "client": "server", + eth.get_type(), + data_length)); + + if (m_is_client == true) + { + EAP_TRACE_DATA_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("<- ETHERNET packet client"), + eth.get_header_buffer(eth.get_header_buffer_length()), + data_length+eapol_ethernet_header_wr_c::get_header_length())); + } + else + { + EAP_TRACE_DATA_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("<- ETHERNET packet server"), + eth.get_header_buffer(eth.get_header_buffer_length()), + data_length+eapol_ethernet_header_wr_c::get_header_length())); + } + + sent_packet->set_is_client(m_is_client); + + eap_status_e status = m_partner->packet_send( + send_network_id, + sent_packet, + header_offset-eapol_ethernet_header_wr_c::get_header_length(), + data_length+eapol_ethernet_header_wr_c::get_header_length(), + buffer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t ethernet_core_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const u32_t offset = m_partner->get_header_offset(MTU, trailer_length); + (*MTU) -= eapol_ethernet_header_wr_c::get_header_length(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return offset+eapol_ethernet_header_wr_c::get_header_length(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + const eap_status_e status = m_partner->unload_module(type); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::eap_acknowledge( + const eap_am_network_id_c * const receive_network_id) +{ + // Any Network Protocol packet is accepted as a success indication. + // This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_eapol_core == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = m_eapol_core->eap_acknowledge(receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = m_partner->load_module( + type, + tunneling_type, + partner, + eap_type, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::start_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_eapol_core == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = m_eapol_core->restart_authentication(receive_network_id, is_client_when_true, true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::start_preauthentication( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ethernet_core_c::start_preauthentication()\n"))); + + if (m_eapol_core == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = m_eapol_core->start_preauthentication(receive_network_id, authentication_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e ethernet_core_c::read_reassociation_parameters( + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address. + const eapol_key_authentication_type_e authentication_type, + eap_variable_data_c * const PMKID, + const eap_variable_data_c * const received_WPA_ie, + const eap_variable_data_c * const sent_WPA_ie) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ethernet_core_c::read_reassociation_parameters()\n"))); + + if (m_eapol_core == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = m_eapol_core->read_reassociation_parameters( + old_receive_network_id, + new_receive_network_id, + authentication_type, + PMKID, + received_WPA_ie, + sent_WPA_ie); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::start_reassociation( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const PMKID) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_eapol_core->start_reassociation( + receive_network_id, + authentication_type, + PMKID); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e ethernet_core_c::complete_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const received_WPA_IE, // WLM must give only the WPA IE to EAPOL + const eap_variable_data_c * const sent_WPA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + status = m_eapol_core->complete_reassociation( + reassociation_result, + receive_network_id, + authentication_type, + received_WPA_IE, + sent_WPA_IE, + pairwise_key_cipher_suite, + group_key_cipher_suite); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::send_logoff( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_eapol_core == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = m_eapol_core->send_logoff(receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void ethernet_core_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool ethernet_core_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::configure() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ethernet_core_c::configure()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ethernet_core_c::configure()"); + + eap_status_e status = m_eapol_core->configure(); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::shutdown() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: ethernet_core_c::shutdown(), m_shutdown_was_called=%d\n"), + (m_is_client == true) ? "client": "server", + m_shutdown_was_called)); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + eap_status_e status(eap_status_ok); + + if (m_eapol_core != 0) + { + status = m_eapol_core->shutdown(); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (key == 0 + || key->get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: ethernet_core_c::packet_data_session_key(), invalid key.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ethernet_core_c::packet_data_session_key(): key_type 0x%02x=%s, key_index %d\n"), + key->get_key_type(), + eapol_session_key_c::get_eapol_key_type_string(key->get_key_type()), + key->get_key_index())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ethernet_core_c::packet_data_session_key():"), + key->get_key()->get_data(key->get_key()->get_data_length()), + key->get_key()->get_data_length())); + + const eap_status_e status = m_partner->packet_data_session_key( + send_network_id, + key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + const eap_status_e status = m_partner->read_configure(field, data); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + const eap_status_e status = m_partner->write_configure(field, data); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void ethernet_core_c::state_notification( + const abs_eap_state_notification_c * const state) +{ + m_partner->state_notification(state); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::check_is_valid_eap_type(const eap_type_value_e eap_type) +{ + eap_status_e status = m_partner->check_is_valid_eap_type(eap_type); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + eap_status_e status = m_partner->get_eap_type_list(eap_type_list); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::cancel_all_authentication_sessions() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ethernet_core_c::cancel_all_authentication_sessions()\n"))); + + eap_status_e status = m_eapol_core->cancel_all_authentication_sessions(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::check_pmksa_cache( + eap_array_c * const bssid_sta_receive_network_ids, + const eapol_key_authentication_type_e selected_eapol_key_authentication_type, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ethernet_core_c::check_pmksa_cache()\n"))); + + eap_status_e status = m_eapol_core->check_pmksa_cache( + bssid_sta_receive_network_ids, + selected_eapol_key_authentication_type, + pairwise_key_cipher_suite, + group_key_cipher_suite); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif // #if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) +/** + * This function removes PMKSA from cache. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. + * MAC address of Supplicant should be in destination address. + */ +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::remove_pmksa_from_cache( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ethernet_core_c::remove_pmksa_from_cache()\n"))); + + eap_status_e status = m_eapol_core->remove_pmksa_from_cache( + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif // #if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) +/** + * Function creates a state for later use. This is for optimazing 4-Way Handshake. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. MAC address of + * Supplicant should be in destination address. + * @param authentication_type is the selected authentication type. + */ +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::create_state( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type + ) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + status = m_eapol_core->create_state( + receive_network_id, + authentication_type); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) +/** + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. MAC address of Supplicant should be in destination address. + * @param authenticator_RSNA_IE is RSN IE of authenticator. Authenticator sends this in Beacon or Probe message. + * @param supplicant_RSNA_IE is RSN IE of supplicant. Supplicant sends this in (re)association request message. + * @param eapol_pairwise_cipher is the selected pairwise cipher. + * @param eapol_group_cipher is the selected group cipher. + */ +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::association( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const authenticator_RSNA_IE, + const eap_variable_data_c * const supplicant_RSNA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher, + const eap_variable_data_c * const pre_shared_key + ) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + status = m_eapol_core->association( + receive_network_id, + authentication_type, + authenticator_RSNA_IE, + supplicant_RSNA_IE, + eapol_pairwise_cipher, + eapol_group_cipher, + pre_shared_key); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif // #if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) +/** + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. MAC address of Supplicant should be in destination address. + */ +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::disassociation( + const eap_am_network_id_c * const receive_network_id + ) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + status = m_eapol_core->disassociation( + receive_network_id); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::add_rogue_ap(eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_partner->add_rogue_ap(rogue_ap_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::tkip_mic_failure( + const eap_am_network_id_c * const receive_network_id, + const bool fatal_failure_when_true, + const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_eapol_core->tkip_mic_failure( + receive_network_id, + fatal_failure_when_true, + tkip_mic_failure_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/core/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/core/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,35 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/core/eap_core.cpp \ + $(WLAN_COMMON)/core/eapol_core.cpp \ + $(WLAN_COMMON)/core/ethernet_core.cpp \ + $(WLAN_COMMON)/core/eap_core_nak_info.cpp \ + $(WLAN_COMMON)/core/eap_core_retransmission.cpp \ + $(WLAN_COMMON)/core/eapol_key_state_common.cpp \ + $(WLAN_COMMON)/core/eapol_key_state_client.cpp \ + $(WLAN_COMMON)/core/eapol_key_state_server.cpp \ + $(WLAN_COMMON)/core/eapol_key_state_string.cpp \ + $(WLAN_COMMON)/core/eapol_rsna_key_data_payloads.cpp \ + $(WLAN_COMMON)/core/eapol_rc4_key_header.cpp \ + $(WLAN_COMMON)/core/eapol_rsna_key_data_header.cpp \ + $(WLAN_COMMON)/core/eapol_rsna_key_data_gtk_header.cpp \ + $(WLAN_COMMON)/core/eapol_rsna_key_header.cpp \ + $(WLAN_COMMON)/core/eap_type_selection.cpp \ + +ifndef NO_EAP_SESSION_CORE +SRC_FILES_CPP := $(SRC_FILES_CPP) \ + $(WLAN_COMMON)/core/eap_session_core.cpp +endif + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eap_base_timer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eap_base_timer.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_BASE_TIMER_H_) +#define _ABS_EAP_BASE_TIMER_H_ + +#include "eap_status.h" +#include "eap_am_export.h" + + +/// An interface class of timer events. +/// Each class whishing to use timer must be derived from class abs_eap_base_timer_c. +class EAP_EXPORT abs_eap_base_timer_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_eap_base_timer_c class does nothing special. + */ + virtual ~abs_eap_base_timer_c() + { + } + + /** + * The constructor of the abs_eap_base_timer_c class does nothing special. + */ + abs_eap_base_timer_c() + { + } + + /** + * Function timer_expired() is called after the timer is elapsed. + * @param id and data are set by caller of abs_eap_am_tools::set_timer() function. + * @param id could be used to separate different timer events. + * @param data could be pointer to any data that is needed in timer processing. + */ + virtual eap_status_e timer_expired( + const u32_t id, void *data) = 0; + + /** + * This function is called when timer event is deleted. + * Initialiser of the data must delete the data. + * Only the initializer knows the real type of data. + * @param id could be used to separate different timer events. + * @param data could be pointer to any data that is needed in timer processing. + */ + virtual eap_status_e timer_delete_data( + const u32_t id, void *data) = 0; + + //-------------------------------------------------- +}; // class abs_eap_base_timer_c + +#endif //#if !defined(_ABS_EAP_BASE_TIMER_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eap_base_type.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eap_base_type.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,331 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_BASE_TYPE_H_) +#define _ABS_EAP_BASE_TYPE_H_ + +#include "eap_am_export.h" +#include "eap_header.h" +#include "eap_array.h" + +class eap_base_type_c; +class eap_am_network_id_c; +class eap_network_id_selector_c; +class eap_configuration_field_c; +class abs_eap_state_notification_c; +class eap_rogue_ap_entry_c; +class eap_master_session_key_c; + +/// The class is the interface to partner class of the eap_base_type class. +/// This declares the pure virtual member functions EAP-type class could call. +class EAP_EXPORT abs_eap_base_type_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_eap_base_type_c class does nothing special. + */ + virtual ~abs_eap_base_type_c() + { + } + + /** + * The constructor of the abs_eap_base_type_c class does nothing special. + */ + abs_eap_base_type_c() + { + } + + /** + * The derived class could send packets to partner class with this function. + * @param network_id carries the addresses (network identity) and type of the packet. + * @param sent_packet includes the buffer for the whole packet and initialized + * EAP-packet in correct offset. + * @param header_offset is offset of the EAP-header within the sent_packet. + * @param data_length is length in bytes of the EAP-packet. + * @param buffer_length is length in bytes of the whole packet buffer. + * + * Now some ascii graphics follows. + * @code + * + * +---------------------+-----+---------------------------------------+-------------+ + * | | EAP | data | | + * +---------------------+-----+---------------------------------------+-------------+ + * | | | | + * |<---header_offset--->|<-------------data_length------------------->|<--trailer-->| + * | | + * |<------------------------buffer_length------------------------------------------>| + * + * trailer is the free space in the end of the packet buffer. + * @endcode + * + */ + virtual eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) = 0; + + /** + * This function restarts authentication to send_network_id. + * @param send_network_id is network identity of target. + * @param is_client_when_true indicates whether this object should act as a client (true) + * or server (false), in terms of EAP-protocol whether this network entity is EAP-supplicant (true) + * or EAP-authenticator (false). + */ + virtual eap_status_e restart_authentication( + const eap_am_network_id_c * const send_network_id, + const bool is_client_when_true) = 0; + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @param MTU_length is pointer to variable to store the maximum transfer unit (MTU). + * MTU is the maximum EAP-packet length in bytes + * @param trailer_length is pointer to the variable to store length + * of trailer needed by lower levels. + * @return Function returns the offset of EAP-header. + * + * The needed buffer length is ((offset) + (EAP-packet length) + (trailer)) bytes. + * Each layer adds the length of the header to offset. + * Each layer removes the length of the header and trailer from MTU. + * + * Now some ascii graphics follows. + * @code + * |<-------------------------buffer length----------------------------------------->| + * | | + * | +-----+---------------------------------------+ | + * | | EAP | data | | + * | +-----+---------------------------------------+ | + * |<----offset--------->|<----MTU------------------------------------>|<--trailer-->| + * | | | | + * | +-------+---------------------------------------------+ | + * | | EAPOL | data | | + * | +-------+---------------------------------------------+ | + * |<--offset--->|<----MTU-------------------------------------------->|<--trailer-->| + * | | | | + * +-------------+-----------------------------------------------------+-------------+ + * | ETHERNET | data | trailer | + * +-------------+-----------------------------------------------------+-------------+ + * |<----MTU------------------------------------------------------------------------>| + * @endcode + * + */ + virtual u32_t get_header_offset( + u32_t * const MTU_length, + u32_t * const trailer_length) = 0; + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @param master_session_key is pointer to the first byte of the master session key. + * @param master_session_length is count of bytes in the master session key. + */ + virtual eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + * + * EAP-type should store it's parameters to an own database. The own database should be accessed + * through adaptation module of EAP-type. See eap_am_type_gsmsim_simulator_c::type_configure_read. + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + * + * EAP-type should store it's parameters to an own database. The own database should be accessed + * through adaptation module of EAP-type. See eap_am_type_gsmsim_simulator_c::type_configure_write. + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. EAP-type MUST send these + * two notifications to lower layer. + * These two notifications are sent using EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + * See also eap_state_notification_c. + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * Client object of EAP-type calls this function. + * This function completes asyncronously query_eap_identity() function call. + * @param send_network_id is network identity of target. + * @param identity is pointer to object that includes the identity. + * @param eap_identifier is EAP-Identifier for EAP-Response/Identity packet. + */ + virtual eap_status_e complete_eap_identity_query( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const identity, + const u8_t eap_identifier) = 0; + + /** + * Client object of EAP-type calls this function. + * This function gets the EAP-identity queried from previous EAP-type. + * + * First EAP-type A is default. The eap_core_c object queries EAP-identity from EAP-type A. + * Server process EAP-Response/Identity but there the default EAP-type is B. + * Server sends EAP-Request/B. Client loads new EAP-type B + * and forwards EAP-Request/B to it. EAP-Request/B is the first EAP-packet EAP-type B receive. + * It must continue using the EAP-identity obtained with EAP-type A. Now EAP-type B could get the EAP-identity + * obtained with EAP-type A with this function. + */ + virtual eap_status_e get_saved_eap_identity(eap_variable_data_c * const identity) = 0; + + /** + * The set_session_timeout() function changes the session timeout timer to be elapsed after session_timeout_ms milliseconds. + */ + virtual eap_status_e set_session_timeout( + const u32_t session_timeout_ms) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * @param time_ms is the time of timer in milli seconds. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * @param initializer is pointer to object which set the cancelled timer. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + /** + * This is needed by PEAP type. + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + * @param receive_network_id includes the addresses (network identity) and packet type. + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + /** + * This is needed by PEAP type. + * The unload_module() function unloads the module of a EAP-type. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e unload_module(const eap_type_value_e eap_type) = 0; + + /** + * This is needed by PEAP type. + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + virtual eap_status_e set_authentication_role(const bool when_true_set_client) = 0; + + virtual eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list) = 0; + + virtual bool get_is_tunneled_eap() const = 0; + + //-------------------------------------------------- +}; // class abs_eap_base_type_c + +#endif //#if !defined(_ABS_EAP_BASE_TYPE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eap_configuration_if.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eap_configuration_if.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_ABS_EAPOL_WLAN_CONFIGURATION_REFERENCE_IF_H_) +#define _ABS_EAPOL_WLAN_CONFIGURATION_REFERENCE_IF_H_ + +//-------------------------------------------------- + +#include "eap_am_export.h" +#include "eap_am_types.h" +#include "eap_status.h" + +#if defined(USE_EAP_SIMPLE_CONFIG) +#include "simple_config_types.h" +#include "simple_config_credential.h" +#include "simple_config_payloads.h" +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + +/// This class is abstract interface to configure EAP settings. +class EAP_EXPORT abs_eap_configuration_if_c +{ + +private: + //-------------------------------------------------- + + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + /** + * This function tells AM to save SIMPLE_CONFIG configuration parameters. + * This is always syncronous call. + */ + virtual eap_status_e save_simple_config_session( + const simple_config_state_e state, + EAP_TEMPLATE_CONST eap_array_c * const credential_array, + const eap_variable_data_c * const new_password, + const simple_config_Device_Password_ID_e Device_Password_ID, + const simple_config_payloads_c * const other_configuration + ) = 0; +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +}; // class abs_eapol_wlan_configuration_reference_if_c + + +#endif //#if !defined(_ABS_EAPOL_WLAN_CONFIGURATION_REFERENCE_IF_H_) + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eap_core.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eap_core.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,254 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_CORE_H_) +#define _ABS_EAP_CORE_H_ + +#include "eap_header.h" +#include "eap_array.h" + +class eap_am_network_id_c; +class eap_buf_chain_wr_c; +class eap_configuration_field_c; +class eap_variable_data_c; +class abs_eap_base_type_c; +class abs_eap_state_notification_c; +class eap_base_type_c; +class eap_rogue_ap_entry_c; +class eap_master_session_key_c; + + +/// This class defines the interface the eap_core_c class +/// will use with the partner class (lower layer). +class EAP_EXPORT abs_eap_core_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_eap_core class does nothing special. + */ + virtual ~abs_eap_core_c() + { + } + + /** + * The constructor of the abs_eap_core class does nothing special. + */ + abs_eap_core_c() + { + } + + /** + * The derived class could send packets to partner class with this function. + * @see abs_eap_base_type_c::packet_send(). + */ + virtual eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) = 0; + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @see abs_eap_base_type_c::get_header_offset(). + */ + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + /** + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + * @param receive_network_id includes the addresses (network identity) and packet type. + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + /** + * The unload_module() function unloads the module of a EAP-type. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e unload_module(const eap_type_value_e eap_type) = 0; + + /** + * The session calls the restart_authentication() function + * when EAP-authentication is needed with another peer. + * This is also used when session restarts authentication. + * @param receive_network_id includes the addresses (network identity) and packet type. + * @param is_client_when_true indicates whether the EAP-type should act as a client or server, + * in terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + * @param force_clean_restart this selects whether the server removes this session (true) or not (false). + * @param from_timer tells whether the timer calls this function (true) or not (false). + */ + virtual eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer = false) = 0; + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @see abs_eap_base_type_c::packet_data_crypto_keys(). + */ + virtual eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + * These two notifications tells the end state of authentication session. These are the only + * reliable indications of the final status of authentication session. + * You MUST NOT make decision based on the return value of abs_eap_stack_interface_c::packet_process(). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * This function tells lower layer to remove EAP session object asyncronously. + * @param eap_type is pointer to selector that identifies the removed EAP session. + */ + virtual eap_status_e asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * @param time_ms is the time of timer in milli seconds. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * @param initializer is pointer to object which set the cancelled timer. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + /** + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + virtual eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list) = 0; + + /** + * The set_session_timeout() function changes the session timeout timer to be elapsed after session_timeout_ms milliseconds. + */ + virtual eap_status_e set_session_timeout( + const u32_t session_timeout_ms) = 0; + + //-------------------------------------------------- +}; // class abs_eap_core_c + +#endif //#if !defined(_ABS_EAP_CORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eap_core_map.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eap_core_map.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_TYPE_MAP_H_) +#define _ABS_EAP_TYPE_MAP_H_ + + +/// This class is the interface to partner class of the eap_core_map_c class. +/// This declares the pure virtual member functions eap_core_map_c class could call. +/// Currently this interface is empty. No functions are defined. +class EAP_EXPORT abs_eap_core_map_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_eap_core_map class does nothing special. + */ + virtual ~abs_eap_core_map_c() + { + } + + /** + * The constructor of the abs_eap_core_map class does nothing special. + */ + abs_eap_core_map_c() + { + } + + //-------------------------------------------------- +}; // class abs_eap_core_map_c + +#endif //#if !defined(_ABS_EAP_TYPE_MAP_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eap_stack_interface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eap_stack_interface.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,117 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_STACK_INTERFACE_H_) +#define _ABS_EAP_STACK_INTERFACE_H_ + +#include "eap_am_export.h" + +class eap_am_network_id_c; +class eap_general_header_base_c; + + +/// The abs_eap_stack_interface_c class declares common pure virtual functions +/// a lower layer class of EAP-stack could call from upper layer class. +/// Main purpose of this interface is documenting those functions. +/// Note the each interface could include other functions too. +/// Those are defined in each individual interface. +class EAP_EXPORT abs_eap_stack_interface_c +{ +private: + //-------------------------------------------------- + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_eap_stack_interface_c class does nothing special. + */ + virtual ~abs_eap_stack_interface_c() + { + } + + /** + * The constructor of the abs_eap_stack_interface_c does nothing special. + */ + abs_eap_stack_interface_c() + { + } + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + * Needed configuration depends on the implementation. + */ + virtual eap_status_e configure() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + /** + * The packet_process() function processes the received packet. + * The return value of this function should be used only for traces + * and error counters. You MUST NOT make any decision of authentication session + * based on the return value. The stack calls abs_eap_core_c::state_notification() + * function when authentication session terminates unsuccessfully or ends successfully. + * You MUST make decision of authentication session based on the state_notification() call. + * See more abs_eap_core_c::state_notification(). + * @param receive_network_id carries the addresses and type of the received packet. + * @param packet_data includes the buffer of the packet. + * @param packet_length is length in bytes of the EAP-packet. + */ + virtual eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) = 0; + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + virtual bool get_is_valid() = 0; + + //-------------------------------------------------- +}; // class abs_eap_stack_interface_c + +#endif //#if !defined(_ABS_EAP_STACK_INTERFACE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eap_state_notification.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eap_state_notification.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,194 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_STATE_NOTIFICATION_H_) +#define _ABS_EAP_STATE_NOTIFICATION_H_ + +#include "eap_am_export.h" +#include "eap_protocol_layer.h" +#include "eap_header.h" + +class eap_am_network_id_c; + +enum eap_state_notification_eap_e +{ + eap_state_notification_eap, +}; + +enum eap_state_notification_generic_e +{ + eap_state_notification_generic, +}; + + +/// This class is the interface to state notification class. +/// This is mostly used for state indications, debugging and protocol testing. +/// The lower level could get information of the authentication states. +class EAP_EXPORT abs_eap_state_notification_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_eap_state_notification_c class does nothing special. + */ + virtual ~abs_eap_state_notification_c() + { + } + + /** + * The constructor of the abs_eap_state_notification_c class does nothing special. + */ + abs_eap_state_notification_c() + { + } + + /** + * This returns send network id. + */ + virtual const eap_am_network_id_c * get_send_network_id() const = 0; + + /** + * This returns the protocol layer that send this notification. + */ + virtual eap_protocol_layer_e get_protocol_layer() const = 0; + + /** + * This returns the protocol on the layer that send this notification. + * This is plain 32-bit value because of easy abstraction. + * Later we could do more detailed information. + * Each protocol layer and EAP type should define own internal states. + */ + virtual u32_t get_protocol() const = 0; + + /** + * This returns the protocol on the layer that send this notification. + * This is eap_type_value_e value. + * Before using this check the get_protocol_layer() returns eap_protocol_layer_eap, + * eap_protocol_layer_eap_type, eap_protocol_layer_general or eap_protocol_layer_internal_type. + */ + virtual eap_type_value_e get_eap_type() const = 0; + + /** + * This returns the previous state. + * This is plain 32-bit value because of easy abstraction. + * Later we could do more detailed information. + * Each protocol layer and EAP type should define own internal states. + */ + virtual u32_t get_previous_state() const = 0; + + /** + * This returns the previous state string. + */ + virtual eap_const_string get_previous_state_string() const = 0; + + /** + * This returns the current state. + * This is plain 32-bit value because of easy abstraction. + * Later we could do more detailed information. + * Each protocol layer and EAP type should define own internal states. + */ + virtual u32_t get_current_state() const = 0; + + /** + * This returns the current state string. + */ + virtual eap_const_string get_current_state_string() const = 0; + + /** + * This returns true when notifier is client, false when server. + */ + virtual bool get_is_client() const = 0; + + /** + * This returns EAP-Identifier. + */ + virtual u8_t get_eap_identifier() const = 0; + + /** + * This function sets flag that allows EAP-Core to send EAP-Response/Success. + */ + virtual bool get_allow_send_eap_success() const = 0; + + /** + * This function sets notification text that is displayed to user. + * Text must be localized string. Type of the string is known to adaptation modules. + * Type depends on the running environment. + * Value true of the parameter needs_confirmation_from_user tells whether + * there should be user action to confirm the text. + * When notification is information where user action is not needed + * the needs_confirmation_from_user parameter should be false. + * Mostly it is better to set this false to disrupt the user less. + */ + virtual eap_status_e set_notification_string( + const eap_variable_data_c * const notification_string, + const bool needs_confirmation_from_user) = 0; + + /** + * This function gets the notification text that is displayed to user. + */ + virtual const eap_variable_data_c * get_notification_string() const = 0; + + /** + * This function gets flag that tells whether + * there should be user action to confirm the text. + */ + virtual bool get_needs_confirmation_from_user() const = 0; + + /** + * The authentication error must be set when get_protocol_layer() returns eap_protocol_layer_general + * and get_current_state() returns eap_general_state_authentication_error. + */ + virtual void set_authentication_error(const eap_status_e error) = 0; + + /** + * This function returns the authentication error when get_protocol_layer() returns eap_protocol_layer_general + * and get_current_state() returns eap_general_state_authentication_error. + */ + virtual eap_status_e get_authentication_error() const = 0; + + /** + * This returns the protocol layer string string. + */ + virtual eap_const_string get_protocol_layer_string() const = 0; + + /** + * This returns the protocol string string. + */ + virtual eap_const_string get_protocol_string() const = 0; + + //-------------------------------------------------- +}; // class abs_eap_state_notification_c + +#endif //#if !defined(_ABS_EAP_STATE_NOTIFICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eap_wimax_authentication.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eap_wimax_authentication.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,92 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP stack interface for Wimax. +* +*/ + + + +#if !defined(_ABS_EAP_WIMAX_AUTHENTICATION_H_) +#define _ABS_EAP_WIMAX_AUTHENTICATION_H_ + +#include + + +/// This class defines the interface for +/// the eap_wimax_authentication_c class towards the Wimax engine. + +class EAP_EXPORT abs_eap_wimax_authentication_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eap_wimax_authentication_c() + { + } + + // + abs_eap_wimax_authentication_c() + { + } + + // Look at abs_eap_base_type_c::packet_send(). + virtual eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, ///< source includes local address, destination includes remote address. + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) = 0; + + // Look at abs_eap_base_type_c::get_header_offset(). + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + /** + * Look at abs_eap_base_type_c::packet_data_crypto_keys(). + */ + virtual eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, ///< source includes local address, destination includes remote address. + const eap_master_session_key_c * const master_session_key) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + //-------------------------------------------------- +}; // class abs_ea_wimax_authentication_c + + +#endif //#if !defined(_ABS_EAP_WIMAX_AUTHENTICATION_H_) + +//-------------------------------------------------- + + +// End of file + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eapol_core.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eapol_core.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,210 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAPOL_CORE_H_) +#define _ABS_EAPOL_CORE_H_ + +#include "eap_am_types.h" +#include "eapol_key_state.h" + +class eap_am_network_id_c; +class eapol_session_key_c; +class abs_eap_base_type_c; +class eap_rogue_ap_entry_c; +class eap_base_type_c; + + +/// The abs_eapol_core_c class defines the interface the eapol_core_c class +/// will use with the partner class. +/// Later eapol and ethernet could be integrated. Now I am too lazy. +class EAP_EXPORT abs_eapol_core_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor does nothing special. + */ + virtual ~abs_eapol_core_c() + { + } + + /** + * The constructor does nothing special. + */ + abs_eapol_core_c() + { + } + + /** + * The derived class could send packets to partner class with this function. + * @see abs_eap_base_type_c::packet_send(). + */ + virtual eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) = 0; + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @see abs_eap_base_type_c::get_header_offset(). + */ + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + /** + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @see abs_eap_core_c::load_module(). + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + /** + * The unload_module() function unloads the module of a EAP-type. + * @param type is the requested EAP-type. + */ + virtual eap_status_e unload_module( + const eap_type_value_e type) = 0; + + /** + * The packet_data_session_key() function passes one traffic encryption key to + * the lower layers. Ultimately the key can end up to the WLAN hardware. + * @param send_network_id carries the addresses (network identity) and type of the packet. + * @param key is the encryption key + * @param key_length is the length of the key + * @param key_type describes the type of the key (WEP or something else...) + * @param key_index is the index of the encryption key (there can be four broadcast keys in WEP for example) + */ + virtual eap_status_e packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key + ) = 0; + + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + /** + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + virtual eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list) = 0; + +//-------------------------------------------------- +}; // class abs_eapol_core_c + +#endif //#if !defined(_ABS_EAPOL_CORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eapol_key_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eapol_key_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,172 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAPOL_KEY_STATE_H_) +#define _ABS_EAPOL_KEY_STATE_H_ + +#include "eap_am_export.h" + +class eapol_session_key_c; + + +/// This class defines the interface the eapol_key_state_c class +/// will use with the partner class (lower layer). +class EAP_EXPORT abs_eapol_key_state_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_eap_core class does nothing special. + */ + virtual ~abs_eapol_key_state_c() + { + } + + /** + * The constructor of the abs_eap_core class does nothing special. + */ + abs_eapol_key_state_c() + { + } + + /** + * A eapol_key_state_c object calls this function when + * a new temporary key (PTK, GTK or STAKey) is generated. + */ + virtual eap_status_e packet_data_session_key( + const eap_am_network_id_c * const receive_network_id, + const eapol_session_key_c * const key + ) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + * These two notifications tells the end state of authentication session. These are the only + * reliable indications of the final status of authentication session. + * You MUST NOT make decision based on the return value of abs_eap_stack_interface_c::packet_process(). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * @param time_ms is the time of timer in milli seconds. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * @param initializer is pointer to object which set the cancelled timer. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + /** + * All STAs contain a global Key Counter which is 256 bits in size. + * It should be initialized at system boot up time to a fresh cryptographic quality random number. + * Refer to Annex I.9 on random number generation. It is recommended that the counter value is initialized to: + * PRF-256(Random number, "Init Counter", Local MAC Address || Time) + * The Local MAC Address should be AA on the Authenticator and SA on the Supplicant. + * The random number is 256 bits in size. Time should be the current time + * (from NTP or another time in NTP format) whenever possible. + * This initialization is to ensure that different initial Key Counter + * values occur across system restarts whether a real-time clock is available or not. + * The Key Counter must be incremented (all 256 bits) each time a value is used as a nonce or IV. + * The Key Counter must not be allowed to wrap to the initialization value. + */ + virtual eap_status_e get_and_increment_global_key_counter( + eap_variable_data_c * const key_counter) = 0; + + /** + * This function tells lower layer to remove EAPOL-Key Handshake session object asynchronously. + * @param send_netword_id carries the send addresses (network identity). + */ + virtual eap_status_e asynchronous_init_remove_eapol_key_state( + const eap_am_network_id_c * const send_netword_id) = 0; + + //-------------------------------------------------- +}; // class abs_eapol_key_state_c + +#endif //#if !defined(_ABS_EAPOL_KEY_STATE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eapol_key_state_map.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eapol_key_state_map.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAPOL_KEY_STATE_MAP_H_) +#define _ABS_EAPOL_KEY_STATE_MAP_H_ + + +/// This class is the interface to partner class of the eap_core_map_c class. +/// This declares the pure virtual member functions eap_core_map_c class could call. +/// Currently this interface is empty. No functions are defined. +class EAP_EXPORT abs_eapol_key_state_map_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_eap_core_map class does nothing special. + */ + virtual ~abs_eapol_key_state_map_c() + { + } + + /** + * The constructor of the abs_eap_core_map class does nothing special. + */ + abs_eapol_key_state_map_c() + { + } + + //-------------------------------------------------- +}; // class abs_eapol_key_state_map_c + +#endif //#if !defined(_ABS_EAPOL_KEY_STATE_MAP_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eapol_message_wlan_authentication.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eapol_message_wlan_authentication.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_ABS_EAPOL_MESSAGE_WLAN_AUTHENTICATION_H_) +#define _ABS_EAPOL_MESSAGE_WLAN_AUTHENTICATION_H_ + +//-------------------------------------------------- + +#include "eap_am_export.h" +#include "eap_am_types.h" +#include "eap_status.h" +#include "wlan_eap_if_send_status.h" + +/** @file */ + +/// This class is abstract interface to send data messages through abstract interface. +class EAP_EXPORT abs_eapol_message_wlan_authentication_c +{ + +private: + //-------------------------------------------------- + + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + virtual ~abs_eapol_message_wlan_authentication_c() + { + } + + /// Function sends the data message to lower layer. + /// Data is formatted to Attribute-Value Pairs. + /// Look at eap_tlv_header_c and eap_tlv_message_data_c. + virtual wlan_eap_if_send_status_e send_data(const void * const data, const u32_t length) = 0; + +}; // class abs_eapol_message_wlan_authentication_c + + +#endif //#if !defined(_ABS_EAPOL_MESSAGE_WLAN_AUTHENTICATION_H_) + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eapol_wlan_authentication.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eapol_wlan_authentication.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,153 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_WLAN_AUTHENTICATION_H_) +#define _ABS_WLAN_AUTHENTICATION_H_ + +#include "eap_header.h" +#include "eap_array.h" +#include "eapol_key_state.h" + +#if defined(USE_EAP_SIMPLE_CONFIG) +#include "simple_config_types.h" +#include "simple_config_credential.h" +#include "simple_config_payloads.h" +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + +class abs_eapol_core_c; +class eap_am_network_id_c; +class eap_buf_chain_wr_c; +class abs_eap_base_type_c; +class eap_base_type_c; +class eapol_session_key_c; +class abs_eap_state_notification_c; +class eap_rogue_ap_entry_c; +class eapol_wlan_state_c; + +/// The abs_eapol_wlan_authentication_c class defines the interface the eapol_wlan_authentication_c class +/// will use with the partner class. +class EAP_EXPORT abs_eapol_wlan_authentication_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eapol_wlan_authentication_c() + { + } + + // + abs_eapol_wlan_authentication_c() + { + } + + // Look at abs_eap_base_type_c::packet_send(). + virtual eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, ///< source includes local address, destination includes remote address. + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) = 0; + + // Look at abs_eap_base_type_c::get_header_offset(). + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + /** + * This function call tells lower layer to associate with the selected 802.11 authentication mode. + */ + virtual eap_status_e associate( + eapol_key_802_11_authentication_mode_e authentication_mode) = 0; + + /** + * Lower layer must return value of self_disassociation when + * it calls eapol_wlan_authentication_c::disassociation(). + * This tells eapol_wlan_authentication_c object the cause + * of disassociation. + */ + virtual eap_status_e disassociate( + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + const bool self_disassociation) = 0; + + /** + * The packet_data_session_key() function passes one traffic encryption key to + * the lower layers. Ultimately the key can end up to the WLAN hardware. + * @see abs_eapol_core_c::packet_data_session_key(). + */ + virtual eap_status_e packet_data_session_key( + const eap_am_network_id_c * const send_network_id, ///< source includes local address, destination includes remote address. + const eapol_session_key_c * const key + ) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + // Look at abs_eap_base_type_c::add_rogue_ap(). + virtual eap_status_e add_rogue_ap( + eap_array_c & rogue_ap_list) = 0; + + /** + * This function call tells lower layer to re-associate with the selected network ID, + * authentication type and PMKID. + */ + virtual eap_status_e reassociate( + const eap_am_network_id_c * const send_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const PMKID) = 0; + +#if defined(USE_EAP_SIMPLE_CONFIG) + /** + * This function call tells new network settings received from WFA Protected Setup Registrar. + */ + virtual eap_status_e save_simple_config_session( + const simple_config_state_e state, + EAP_TEMPLATE_CONST eap_array_c * const credential_array, + const eap_variable_data_c * const new_password, + const simple_config_Device_Password_ID_e Device_Password_ID, + const simple_config_payloads_c * const other_configuration) = 0; +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + + //-------------------------------------------------- +}; // class abs_eapol_wlan_authentication_c + +#endif //#if !defined(_ABS_WLAN_AUTHENTICATION_H_) + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_eapol_wlan_database_reference_if.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_eapol_wlan_database_reference_if.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_ABS_EAPOL_WLAN_DATABASE_REFERENCE_IF_H_) +#define _ABS_EAPOL_WLAN_DATABASE_REFERENCE_IF_H_ + +//-------------------------------------------------- + +#include "eap_am_export.h" +#include "eap_am_types.h" +#include "eap_status.h" + + +/// This class is abstract interface to reference of WLAN database of the current connection. +class EAP_EXPORT abs_eapol_wlan_database_reference_if_c +{ + +private: + //-------------------------------------------------- + + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + virtual ~abs_eapol_wlan_database_reference_if_c() + { + } + + /** + * The constructor of the abs_eapol_wlan_database_reference_if_c class does nothing special. + */ + virtual eap_status_e get_wlan_database_reference_values( + eap_variable_data_c * const reference) const = 0; + +}; // class abs_eapol_wlan_database_reference_if_c + + +#endif //#if !defined(_ABS_EAPOL_WLAN_DATABASE_REFERENCE_IF_H_) + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/abs_ethernet_core.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/abs_ethernet_core.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,182 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_ETHERNET_CORE_H_) +#define _ABS_ETHERNET_CORE_H_ + +#include "eap_header.h" +#include "eap_array.h" +#include "eapol_key_state.h" + + +class abs_eapol_core_c; +class eap_am_network_id_c; +class eap_buf_chain_wr_c; +class abs_eap_base_type_c; +class eap_base_type_c; +class eapol_session_key_c; +class abs_eap_state_notification_c; +class eap_rogue_ap_entry_c; + +/// The abs_ethernet_core_c class defines the interface the ethernet_core_c class +/// will use with the partner class. +/// Later eapol and ethernet could be integrated. +/// Now I am too lazy and there could be some benefit using separate eapol and ethernet layers. +class EAP_EXPORT abs_ethernet_core_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_ethernet_core_c() + { + } + + // + abs_ethernet_core_c() + { + } + + // + virtual eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) = 0; + + // + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + // + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + // + virtual eap_status_e unload_module(const eap_type_value_e type) = 0; + + /** + * The packet_data_session_key() function passes one traffic encryption key to + * the lower layers. Ultimately the key can end up to the WLAN hardware. + * @see abs_eapol_core_c::packet_data_session_key(). + */ + virtual eap_status_e packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key + ) = 0; + + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + virtual bool get_is_client() = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + /** + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + virtual eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list) = 0; + + //-------------------------------------------------- +}; // class abs_ethernet_core_c + +#endif //#if !defined(_ABS_ETHERNET_CORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/asn1_der_type.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/asn1_der_type.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,460 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ASN1_TYPE_H_) +#define _ASN1_TYPE_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_array.h" + +//-------------------------------------------------- + +class asn1_type_const_c; + +//-------------------------------------------------- + +class EAP_EXPORT asn1_der_type_c +{ + //-------------------------------------------------- +public: + //-------------------------------------------------- + + enum asn1_class_e + { + asn1_class_universal = 0x00, + asn1_class_application = 0x40, + asn1_class_context_specific = 0x80, + asn1_class_private = 0xC0, + + asn1_class_none = 0xffffffff, + }; + + enum asn1_pc_e + { + asn1_pc_primitive = 0x00, + asn1_pc_constructed = 0x20, + + asn1_pc_none = 0xffffffff, + }; + + enum asn1_tag_e + { + asn1_tag_end_of_content = 0, + asn1_tag_boolean = 1, + asn1_tag_integer = 2, + asn1_tag_bit_string = 3, + asn1_tag_octet_string = 4, + asn1_tag_null = 5, + asn1_tag_object_identifier = 6, + asn1_tag_object_descriptor = 7, + asn1_tag_external = 8, + asn1_tag_real = 9, + asn1_tag_enumerated = 10, + asn1_tag_empedded_pdv = 11, + asn1_tag_utf8_string = 12, + asn1_tag_relative_oid = 13, + asn1_tag_unknown_14 = 14, + asn1_tag_unknown_15 = 15, + asn1_tag_sequence = 16, + asn1_tag_set = 17, + asn1_tag_numeric_string = 18, + asn1_tag_printable_string = 19, + asn1_tag_t61_string = 20, + asn1_tag_videotex_string = 21, + asn1_tag_ia5_string = 22, + asn1_tag_utc_time = 23, + asn1_tag_unknown_24 = 24, + asn1_tag_graphic_string = 25, + asn1_tag_visible_string = 26, + asn1_tag_general_string = 27, + asn1_tag_universal_string = 28, + asn1_tag_character_string = 29, + asn1_tag_bmp_string = 30, + + asn1_tag_extented = 0xfffffffe, + + asn1_tag_none = 0xffffffff, + }; + + enum asn1_identifier_mask_e + { + asn1_identifier_mask_class = 0xC0, + asn1_identifier_mask_pc = 0x20, + asn1_identifier_mask_tag = 0x1F, + asn1_high_bit_mask_tag = 0x80, + }; + + enum asn1_identifier_const_e + { + asn1_identifier_const_simple_tag_size = sizeof(u8_t), + asn1_identifier_const_short_length_size = sizeof(u8_t), + asn1_length_field_base = 256ul, + }; + + + EAP_FUNC_IMPORT virtual ~asn1_der_type_c(); + + EAP_FUNC_IMPORT asn1_der_type_c( + abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the asn1_der_type_c object. + * @return True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid() const; + + EAP_FUNC_IMPORT u32_t get_index() const; + + /** + * The decode() function decodes ASN.1/DER data. + * @return eap_status_ok indicates successfull operation. + */ + EAP_FUNC_IMPORT eap_status_e decode(const eap_variable_data_c * const asn1_der_data); + + /** + * The get_class() returns Class of ASN.1/DER type. + */ + EAP_FUNC_IMPORT asn1_class_e get_class() const; + + /** + * The get_pc() returns Primitiva/Constructed flag of ASN.1/DER type. + */ + EAP_FUNC_IMPORT asn1_pc_e get_pc() const; + + /** + * The get_pc() returns Tag of ASN.1/DER type. + */ + EAP_FUNC_IMPORT asn1_tag_e get_tag() const; + + /** + * The get_pc() returns pointer to extented Tag of ASN.1/DER type. + */ + EAP_FUNC_IMPORT eap_status_e get_extented_tag(const u8_t ** const extented_tag, u32_t * const extented_tag_size) const; + + // Function returns count of octets in header of ASN.1/DER type. + // This includes Identifier and Length octets. + EAP_FUNC_IMPORT u32_t get_header_length() const; + + + // Function returns count of octets in Contents of ASN.1/DER type. + EAP_FUNC_IMPORT u32_t get_content_length() const; + + // Function returns pointer to Contents of ASN.1/DER type. + EAP_FUNC_IMPORT const u8_t * get_content() const; + + + // Function returns count of octets in full data of ASN.1/DER type, including Identifier, Length and Content. + EAP_FUNC_IMPORT u32_t get_full_data_length() const; + + // Function returns pointer to full data of ASN.1/DER type, including Identifier, Length and Content. + EAP_FUNC_IMPORT const u8_t * get_full_data() const; + + + // Function returns pointer to array of ASN.1/DER sub types. + EAP_FUNC_IMPORT const eap_array_c * get_sub_types() const; + + // Function returns pointer to ASN.1/DER sub type. + EAP_FUNC_IMPORT const asn1_der_type_c * get_sub_type(const asn1_type_const_c * const asn1_type) const; + + EAP_FUNC_IMPORT const asn1_der_type_c * get_previous_type() const; + + EAP_FUNC_IMPORT const asn1_der_type_c * get_next_type() const; + + EAP_FUNC_IMPORT u16_t get_count_of_sub_types() const; + + EAP_FUNC_IMPORT void increase_count_of_sub_types(); + + EAP_FUNC_IMPORT eap_const_string get_class_string() const; + + EAP_FUNC_IMPORT eap_const_string get_pc_string() const; + + EAP_FUNC_IMPORT eap_const_string get_tag_string() const; + + EAP_FUNC_IMPORT eap_status_e compare_object_identifier(const u8_t * const der_encoded_oid, const u32_t oid_length) const; + + EAP_FUNC_IMPORT eap_status_e compare_object_identifier(eap_const_string oid, const u32_t oid_length) const; + + //-------------------------------------------------- +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + bool m_is_valid; + + u16_t m_index; + + u16_t m_count_of_sub_types; + + // Shows the recursion of ANS.1 type. The outer most have value 0. + u16_t m_recursion; + + // +--------------+--------------+--------------+ + // | Identifier | Length | Content | + // +--------------+--------------+--------------+ + // + // +--------------------------------------------+ + // m_input_data_length in octets + u32_t m_input_data_length; + + // +--------------+--------------+--------------+ + // | Identifier | Length | Content | + // +--------------+--------------+--------------+ + // ^ + // | + // This is pointer to begin of the input data. + const u8_t * m_input_data; + + // Tells how many octets of tha data is used by sub types. + u32_t m_used_octets; + + // +--------------+--------------+--------------+ + // | Identifier | Length | Content | + // +--------------+--------------+--------------+ + // + // +--------------+ + // offset + u16_t m_offset_of_length_field; + + // +--------------+--------------+--------------+ + // | Identifier | Length | Content | + // +--------------+--------------+--------------+ + // + // +-----------------------------+ + // offset + u16_t m_offset_of_contents_field; + + // This is pointer to parent type. + asn1_der_type_c * m_parent_type; + + // This array includes all sub types. + eap_array_c * m_sub_types; + + //-------------------------------------------------- + +#if defined(USE_EAP_DEBUG_TRACE) + + enum asn1_debug_const_e + { + MAX_DEBUG_BUFFER = 256, + MAX_STACK_BUFFER = 64, + SIZE_OF_ONE_OCTET_STRING = 3ul, + COUNT_OF_OCTETS = 16ul, + OID_HIGH_BIT = 0x80, + }; + + eap_status_e debug_create_prefix(const u32_t recursion, u8_t * const prefix, const u32_t max_prefix, u32_t * const pregix_length); + + eap_status_e debug_header(eap_variable_data_c * const debug_buffer); + + eap_status_e debug_content(eap_variable_data_c * const debug_buffer); + + eap_status_e debug_data(eap_variable_data_c * const debug_buffer); + + eap_status_e debug_object_identifier(eap_variable_data_c * const debug_buffer); + +#endif //#if defined(USE_EAP_DEBUG_TRACE) + + eap_status_e add_sub_type(asn1_der_type_c * const sub_type); + + eap_status_e initialize( + const u32_t length, + const u8_t * const data, + const u16_t recursion, + const u32_t index, + eap_variable_data_c * const debug_buffer); + + u16_t get_offset_of_length_field(); + + u16_t get_offset_of_contents_field(); + + void set_parent_type(asn1_der_type_c * const parent_type); + + asn1_der_type_c * get_parent_type() const; + + u32_t get_input_data_length() const; + + const u8_t * get_input_data() const; + + u16_t get_recursion() const; + + void add_used_octets(const u32_t used_octets); + + u32_t get_used_octets() const; + + u32_t get_unused_data_length() const; + + const u8_t * get_unused_data() const; + + eap_status_e encode_oid_from_string(eap_const_string oid, const u32_t oid_length, eap_variable_data_c * const buffer) const; + + //-------------------------------------------------- +}; + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- + +class asn1_type_object_c +{ +public: + + ~asn1_type_object_c() + { + } + + asn1_der_type_c::asn1_class_e get_asn1_class() const + { + return m_asn1_class; + } + + asn1_der_type_c::asn1_tag_e get_asn1_tag() const + { + return m_asn1_tag; + } + + u32_t get_index() const + { + return m_index; + } + + bool get_is_valid() const + { + return( + get_asn1_class() != asn1_der_type_c::asn1_class_none + && get_asn1_tag() != asn1_der_type_c::asn1_tag_none); + } + + bool compare( + abs_eap_am_tools_c * const /* tools */, + const asn1_type_object_c * const field) const + { + return field->get_asn1_class() == get_asn1_class() + && field->get_asn1_tag() == get_asn1_tag(); + } + +private: + asn1_der_type_c::asn1_class_e m_asn1_class; + asn1_der_type_c::asn1_tag_e m_asn1_tag; + u32_t m_index; +}; + +//-------------------------------------------------------------------------------------------------- + +class asn1_type_const_c +{ +public: + + inline const asn1_type_object_c * get_type() const; + + inline bool get_is_valid() const + { + return true; + } + + +public: + asn1_der_type_c::asn1_class_e m_asn1_class; + asn1_der_type_c::asn1_tag_e m_asn1_tag; + u32_t m_index; +}; + +//-------------------------------------------------------------------------------------------------- + +inline const asn1_type_object_c * asn1_type_const_c::get_type() const +{ + EAP_STATIC_ASSERT(sizeof(asn1_type_const_c) == sizeof(asn1_type_object_c)); + + return reinterpret_cast(this); +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- + +template +class asn1_named_object_const_c +{ +public: + + inline const eap_char * get_name() const; + + inline const asn1_type_const_c * get_array() const; + + inline bool get_is_valid() const + { + return true; + } + +public: + + eap_char m_name[max_name_length]; + asn1_type_const_c m_array[max_object_count]; + +}; + +//-------------------------------------------------------------------------------------------------- + +template +inline const eap_char * asn1_named_object_const_c::get_name() const +{ + return m_name; +} + +template +inline const asn1_type_const_c * asn1_named_object_const_c::get_array() const +{ + return m_array; +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- + +#define ASN1_TYPE_OBJECT(asn1_class, asn1_tag, index) \ + {asn1_class, static_cast(asn1_tag), index} + +#define ASN1_TYPE_OBJECT_TERMINATOR \ + {asn1_der_type_c::asn1_class_none, asn1_der_type_c::asn1_tag_none, 0ul} + +//-------------------------------------------------------------------------------------------------- + +#if defined(USE_EAP_DEBUG_TRACE) + #define ASN1_DEBUG_HEADER(type, debug_buffer) { (void) (type)->debug_header(debug_buffer); } + #define ASN1_DEBUG_DATA(type, debug_buffer) { (void) (type)->debug_content(debug_buffer); } +#else + #define ASN1_DEBUG_HEADER(type, debug_buffer) + #define ASN1_DEBUG_DATA(type, debug_buffer) +#endif //#if defined(USE_EAP_DEBUG_TRACE) + +#if defined(USE_ASN1_TYPE_DEBUG_TRACE) + #define ASN1_TYPE_TRACE_DEBUG EAP_TRACE_DEBUG + #define ASN1_TYPE_TRACE_DATA_DEBUG EAP_TRACE_DATA_DEBUG +#else + #define ASN1_TYPE_TRACE_DEBUG(object_name, flags, _parameter_list_) + #define ASN1_TYPE_TRACE_DATA_DEBUG(object_name, flags, _parameter_list_) +#endif + +#endif //#if !defined(_ASN1_TYPE_H_) + +//-------------------------------------------------------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_array.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_array.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,489 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_ARRAY_H_) +#define _EAP_ARRAY_H_ + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "eap_am_export.h" + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients +#endif + +#define EAP_ARRAY_SANITY_CHECK(this) \ + { \ + EAP_ASSERT(((this)->m_head == 0 && (this)->m_tail == 0 && (this)->m_object_count == 0) \ + || ((this)->m_head != 0 && (this)->m_tail != 0 && (this)->m_object_count != 0)); \ + \ + EAP_ASSERT(((this)->m_object_count == 0 && (this)->m_head == 0) \ + || ((this)->m_object_count == 1 && (this)->m_head != 0 \ + && (this)->m_head == (this)->m_tail && (this)->m_head->get_next_atom() == 0) \ + || ((this)->m_object_count > 1 && (this)->m_head != 0 \ + && (this)->m_head != (this)->m_tail && (this)->m_head->get_next_atom() != 0)); \ + \ + EAP_ASSERT(((this)->m_object_count == 0 && (this)->m_tail == 0) \ + || ((this)->m_object_count != 0 && (this)->m_tail != 0 && (this)->m_tail->get_next_atom() == 0)); \ + } + +//---------------------------------------------------------------------------------------- + +/** + * The eap_array_atom_c is a template class for single object stored to eap_array_c array. + * The array objects are stored as a linked list. + * @param Type template parameter is the actual type which is stored. + */ +template +class EAP_EXPORT eap_array_atom_c +{ +private: + + /// This is pointer to the tools class. + abs_eap_am_tools_c * m_am_tools; + + /// This is the pointer to the actual object + Type *m_data; + + /// Linked list pointer to the next atom + eap_array_atom_c *m_next_atom; + + /// This flag indicates whether eap_array deletes the stored object when it is destroyed. + bool m_free_atom; + +public: + + /** + * The destructor deletes the object in this atom if necessary. + */ + virtual ~eap_array_atom_c() + { + m_am_tools = 0; + + if (m_data != 0 + && m_free_atom == true) + { + delete m_data; + m_data = 0; + } + } + + /** + * The constructor sets the values for the member variables + */ + eap_array_atom_c( + abs_eap_am_tools_c * const tools, + Type * const p_data, + const bool free_atom) + : m_am_tools(tools) + , m_data(p_data) + , m_next_atom(0) + , m_free_atom(free_atom) + { + } + + // + Type * const get_data() + { + return m_data; + } + + // + void set_data(Type * const p_data) + { + m_data = p_data; + } + + eap_array_atom_c * const get_next_atom() const + { + return m_next_atom; + } + + void set_next_atom(eap_array_atom_c * const next) + { + m_next_atom = next; + } +}; + +//---------------------------------------------------------------------------------------- + +/** + * The eap_array_c template class includes an array for type of Type objects. + * The objects can be added, retrieved and their count can be queried. + * @param Type template parameter is the actual type which is stored. + */ +template +class EAP_EXPORT eap_array_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * m_am_tools; + + /// Head pointer for the object atom linked list. + eap_array_atom_c *m_head; + + /// Tail pointer for the object atom linked list. + eap_array_atom_c *m_tail; + + /// This is the number of objects + u32_t m_object_count; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The constructor initializes attributes using the passed parameter. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + */ + eap_array_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_head(0) + , m_tail(0) + , m_object_count(0) + { + } + + /** + * Destructor deletes all atoms. + */ + virtual ~eap_array_c() + { + (void) reset(); + m_am_tools = 0; + } + + // NOTE: This operator is NOT supported. This is unplemented prototype to cause linker error if assigment operator is used. + eap_array_c &operator = (const eap_array_c &right_type_value); + + + /** + * reset() deletes all atoms. + */ + eap_status_e reset() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ARRAY_SANITY_CHECK(this); + + if (m_head == 0) + { + // The array is empty + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + eap_array_atom_c *current; + eap_array_atom_c *last; + + // Go through the linked list and delete all + current = m_head; + + while (current != 0) + { + last = current; + current = last->get_next_atom(); + delete last; + } + + m_object_count = 0UL; + m_head = 0; + m_tail = 0; + + EAP_ARRAY_SANITY_CHECK(this); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + /** + * The function add_object_to_begin() adds one new object to the begin of the array. + * @param object is pointer to the added object + * @param m_free_object is flag that indicates whether the object should be deleted by eap_array_c + */ + eap_status_e add_object_to_begin( + Type * const object, + const bool m_free_object) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_array_atom_c *atom; + + if (object == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ARRAY_SANITY_CHECK(this); + + atom = new eap_array_atom_c(m_am_tools, object, m_free_object); + if (atom == 0 + || object == 0) + { + if (m_free_object == true) + { + delete object; + } + + EAP_ARRAY_SANITY_CHECK(this); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Check if this is the first item + if (m_head == 0) + { + // Yes + m_head = atom; + m_tail = atom; + } + else + { + // No. Add it to the begin. + atom->set_next_atom(m_head); + m_head = atom; + } + + m_object_count++; + + EAP_ARRAY_SANITY_CHECK(this); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + /** + * The function add_object() adds one new object to the array. + * @param object is pointer to the added object + * @param m_free_object is flag that indicates whether the object should be deleted by eap_array_c + */ + eap_status_e add_object( + Type * const object, + const bool m_free_object) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_array_atom_c *atom; + + if (object == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ARRAY_SANITY_CHECK(this); + + atom = new eap_array_atom_c(m_am_tools, object, m_free_object); + if (atom == 0) + { + if (m_free_object == true) + { + delete object; + } + + EAP_ARRAY_SANITY_CHECK(this); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Check if this is the first item + if (m_head == 0) + { + // Yes + m_head = atom; + m_tail = atom; + } + else + { + // No. Add it to the end. + m_tail->set_next_atom(atom); + m_tail = atom; + } + + m_object_count++; + + EAP_ARRAY_SANITY_CHECK(this); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + /** + * The get_object() function returns object based on the index given. + * @param index Indicates which object pointer is returned + * @return Object pointer + */ + Type * const get_object(const u32_t index) const + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT_ALWAYS(index < get_object_count()); + + EAP_ARRAY_SANITY_CHECK(this); + + eap_array_atom_c *atom; + Type *object = 0; + atom = m_head; + u32_t i = 0; + + // find the object needed by stepping through the array. + while (atom != 0) + { + // Is this the correct one? + if (index == i) + { + // Yes. + object = atom->get_data(); + break; + } + + // Nope. Get the next one + i++; + atom = atom->get_next_atom(); + } + + EAP_ARRAY_SANITY_CHECK(this); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return object; + } + + /** + * The remove_object() function removes object based on the index given. + * @param index Indicates which object pointer is returned + * @return Object pointer + */ + eap_status_e remove_object(const u32_t index) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT_ALWAYS(index < get_object_count()); + + EAP_ARRAY_SANITY_CHECK(this); + + eap_array_atom_c *atom; + eap_array_atom_c *prev_atom = 0; + atom = m_head; + u32_t i = 0; + eap_status_e status = eap_status_illegal_index; + + // find the object needed by stepping through the array. + while (atom != 0) + { + // Is this the correct one? + if (index == i) + { + // Yes. + if (index == 0 + && prev_atom == 0) + { + // this is the first on the array. + m_head = atom->get_next_atom(); + if (m_head == 0) + { + m_tail = 0; + } + } + else + { + prev_atom->set_next_atom(atom->get_next_atom()); + } + + if (m_tail == atom) + { + // This is the last on the array. + m_tail = prev_atom; + } + + delete atom; + --m_object_count; + + EAP_ARRAY_SANITY_CHECK(this); + + status = eap_status_ok; + break; + } + + // Nope. Get the next one + i++; + prev_atom = atom; + atom = atom->get_next_atom(); + + } // while() + + EAP_ARRAY_SANITY_CHECK(this); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + /** + * The get_object_count() function returns the number of objects in the array. + * @return number of objects + */ + const u32_t get_object_count() const + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_object_count; + } + + /** + * Gets last object. + * @return Object pointer or null if array is empty. + */ + Type * const get_last_object() const + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ARRAY_SANITY_CHECK(this); + + // find the object needed by stepping through the array. + if (get_object_count() > 0UL + && m_tail != 0) + { + // Yes. + Type * const object = m_tail->get_data(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return object; + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + } + + //-------------------------------------------------- +}; // class eap_array_c + +//---------------------------------------------------------------------------------------- + +#endif //#if !defined(_EAP_ARRAY_H_) + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_array_algorithms.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_array_algorithms.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,572 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_ARRAY_ALGORITHMS_H_) +#define _EAP_ARRAY_ALGORITHMS_H_ + +#include "eap_am_memory.h" +#include "eap_am_export.h" +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "eap_array.h" + +/** @file */ + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4275 ) // ingnores non dll-interface class 'abs_eap_array_compare_c' used as base for dll-interface class 'eap_fast_pac_store_data_compare_A_ID_reference_c' +#endif + +template +class EAP_EXPORT abs_eap_array_compare_c +{ + +public: + + virtual ~abs_eap_array_compare_c() + { + } + + virtual i32_t compare(const Type * const original_object_from_array, const Type * const searched_data) const = 0; +}; + + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +/** + * This template function copies class objects from original_array to copy_array. + * Type must have the following member functions: + * Type * copy(); + * bool get_is_valid(); + * bool get_is_valid_data(); + */ +template +eap_status_e copy( + EAP_TEMPLATE_CONST eap_array_c * const original_array, ///< Stupid Windows compiler cannot compile "const eap_array_c * const". + eap_array_c * const copy_array, + abs_eap_am_tools_c * const m_am_tools, + const bool when_true_add_objects) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; // Note original_array may be empty, then for loop will not be run. + + if (when_true_add_objects == false) + { + copy_array->reset(); + } + + for (u32_t ind = 0; ind < original_array->get_object_count(); ind++) + { + Type * const orig_object = original_array->get_object(ind); + if (orig_object == 0 + || orig_object->get_is_valid() == false) + { + EAP_UNREFERENCED_PARAMETER(m_am_tools); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("copy: orig_object=0x%08x, orig_object->get_is_valid()=%d"), + orig_object, + (orig_object != 0) ? orig_object->get_is_valid(): false)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + Type * const copy_object = orig_object->copy(); + if (copy_object == 0 + || copy_object->get_is_valid() == false) + { + delete copy_object; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Note the original object might be empty without data. + if (orig_object->get_is_valid_data() == true + && copy_object->get_is_valid_data() == false) + { + delete copy_object; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = copy_array->add_object(copy_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + + +/** + * This template function copies simple objects from original_array to copy_array. + * Simple types are u16_t, eap_status_e, ... + */ +template +eap_status_e copy_simple( + EAP_TEMPLATE_CONST eap_array_c * const original_array, ///< Stupid Windows compiler cannot compile "const eap_array_c * const". + eap_array_c * const copy_array, + abs_eap_am_tools_c * const m_am_tools, + const bool when_true_add_objects) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; // Note original_array may be empty, then for loop will not be run. + + if (when_true_add_objects == false) + { + copy_array->reset(); + } + + for (u32_t ind = 0; ind < original_array->get_object_count(); ind++) + { + Type * original_object = original_array->get_object(ind); + if (original_object == 0) + { + EAP_UNREFERENCED_PARAMETER(m_am_tools); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + Type * copy_object = new Type; + if (copy_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *copy_object = *original_object; + + status = copy_array->add_object(copy_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +/** + * This template function copies data of objects to a eap_variable_data_c object. + */ +template +eap_status_e add_data( + EAP_TEMPLATE_CONST eap_array_c * const source_array, ///< Stupid Windows compiler cannot compile "const eap_array_c * const". + eap_variable_data_c * const buffer, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; // Note source_array may be empty, then for loop will not be run. + + for (u32_t ind = 0; ind < source_array->get_object_count(); ind++) + { + Type * original_object = source_array->get_object(ind); + if (original_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = buffer->add_data( + original_object->get_data(original_object->get_data_length()), + original_object->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("data"), + original_object->get_data(original_object->get_data_length()), + original_object->get_data_length())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +/** + * This template function copies simple data of objects to a eap_variable_data_c object. + */ +template +eap_status_e add_simple_data( + EAP_TEMPLATE_CONST eap_array_c * const source_array, ///< Stupid Windows compiler cannot compile "const eap_array_c * const". + eap_variable_data_c * const buffer, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; // Note source_array may be empty, then for loop will not be run. + + for (u32_t ind = 0; ind < source_array->get_object_count(); ind++) + { + Type * original_object = source_array->get_object(ind); + if (original_object == 0) + { + EAP_UNREFERENCED_PARAMETER(m_am_tools); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = buffer->add_data( + original_object, + sizeof(*original_object)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("data"), + original_object, + sizeof(*original_object))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +/** + * This template function searches the supplied array for given object. + * Function returns the index to the found object or -1 if not found or there + * is some other error. + * Type must have the following member functions: + * i32_t compare(const Type * const data) + */ +template +const i32_t find( + EAP_TEMPLATE_CONST eap_array_c * const original_array, ///< Stupid Windows compiler cannot compile "const eap_array_c * const". + const Type * const searched_data, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + i32_t index = -1; + for (u32_t ind = 0; ind < original_array->get_object_count(); ind++) + { + Type * original_object = original_array->get_object(ind); + if (original_object == 0) + { + index = -1; + break; + } + if (!original_object->compare(const_cast (searched_data))) + { + // Found it + index = ind; + break; + } + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return index; +} + +//-------------------------------------------------- + +/** + * This template function searches the supplied array for given object starting from the last index. + * Function returns the index to the found object or -1 if not found or there + * is some other error. + * Type must have the following member functions: + * i32_t compare(const Type * const data) + */ +template +const i32_t find_next( + const i32_t last_index, + EAP_TEMPLATE_CONST eap_array_c * const original_array, ///< Stupid Windows compiler cannot compile "const eap_array_c * const". + const Type * const searched_data, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + i32_t index = -1; + for (u32_t ind = last_index+1; ind < original_array->get_object_count(); ind++) + { + Type * original_object = original_array->get_object(ind); + if (original_object == 0) + { + index = -1; + break; + } + if (!original_object->compare(const_cast (searched_data))) + { + // Found it + index = ind; + break; + } + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return index; +} + +//-------------------------------------------------- + +/** + * This template function searches the supplied array for given object. + * Function returns the index to the found object or -1 if not found or there + * is some other error. + * Type must have the following member functions: + * i32_t compare(const Type * const data) + */ +template +const i32_t find_with_compare( + const abs_eap_array_compare_c * const compare, + EAP_TEMPLATE_CONST eap_array_c * const original_array, ///< Stupid Windows compiler cannot compile "const eap_array_c * const". + const Type * const searched_data, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + i32_t index = -1; + for (u32_t ind = 0; ind < original_array->get_object_count(); ind++) + { + Type * original_object = original_array->get_object(ind); + if (original_object == 0) + { + index = -1; + break; + } + + if (!compare->compare(original_object, searched_data)) + { + // Found it + index = ind; + break; + } + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return index; +} + +//-------------------------------------------------- + +/** + * This template function searches the supplied array for given object starting from the last index. + * Function returns the index to the found object or -1 if not found or there + * is some other error. + * Type must have the following member functions: + * i32_t compare(const Type * const data) + */ +template +const i32_t find_next_with_compare( + const i32_t last_index, + const abs_eap_array_compare_c * const compare, + EAP_TEMPLATE_CONST eap_array_c * const original_array, ///< Stupid Windows compiler cannot compile "const eap_array_c * const". + const Type * const searched_data, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + i32_t index = -1; + for (u32_t ind = last_index+1; ind < original_array->get_object_count(); ind++) + { + Type * original_object = original_array->get_object(ind); + if (original_object == 0) + { + index = -1; + break; + } + + if (!compare->compare(original_object, searched_data)) + { + // Found it + index = ind; + break; + } + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return index; +} + +//-------------------------------------------------- + +/** + * This template function searches the supplied array for given simple type object. + * Simple types are u16_t, eap_status_e, ... + * It returns the index to the found object or -1 if not found or there + * is some other error. + */ +template +const i32_t find_simple( + EAP_TEMPLATE_CONST eap_array_c * const original_array, ///< Stupid Windows compiler cannot compile "const eap_array_c * const". + const Type * const searched_data, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + i32_t index = -1; + for (u32_t ind = 0; ind < original_array->get_object_count(); ind++) + { + Type * original_object = original_array->get_object(ind); + if (original_object == 0) + { + index = -1; + break; + } + if (*original_object == *searched_data) + { + // Found it + index = ind; + break; + } + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return index; +} + +//-------------------------------------------------- + +/** + * This template function searches the supplied array for given simple type object. + * Simple types are u16_t, eap_status_e, ... + * It returns the index to the found object or -1 if not found or there + * is some other error. + */ +template +const i32_t find_next_simple( + const i32_t last_index, + EAP_TEMPLATE_CONST eap_array_c * const original_array, ///< Stupid Windows compiler cannot compile "const eap_array_c * const". + const Type * const searched_data, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + i32_t index = -1; + for (u32_t ind = last_index+1; ind < original_array->get_object_count(); ind++) + { + Type * original_object = original_array->get_object(ind); + if (original_object == 0) + { + index = -1; + break; + } + if (*original_object == *searched_data) + { + // Found it + index = ind; + break; + } + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return index; +} + +//-------------------------------------------------- + +/** + * Template function for_each() runs supplied function to all type objects of the supplied array. + */ +template +eap_status_e for_each( + EAP_TEMPLATE_CONST eap_array_c * const original_array, ///< Stupid Windows compiler cannot compile "const eap_array_c * const". + eap_status_e (*function)( + Type * const value, + abs_eap_am_tools_c * const m_am_tools), + abs_eap_am_tools_c * const m_am_tools, + const bool do_not_care_errors) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; // Note original_array may be empty, then for loop will not be run. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("for_each(): function=0x%08x.\n"), + function)); + + + for (u32_t ind = 0; ind < original_array->get_object_count(); ind++) + { + Type * original_object = original_array->get_object(ind); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("for_each(): object=0x%08x, ") + EAPL("function=0x%08x.\n"), + original_object, + function)); + + if (do_not_care_errors == false + && original_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + else if (original_object != 0) + { + status = function(original_object, m_am_tools); + + if (do_not_care_errors == false + && status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#endif //#if !defined(_EAP_ARRAY_ALGORITHMS_H_) + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_automatic_variable.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_automatic_variable.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,288 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AUTOMATIC_VARIABLE_H_) +#define _EAP_AUTOMATIC_VARIABLE_H_ + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "eap_am_export.h" + +/** + * @{ Add some comments. } + */ +template +class EAP_EXPORT eap_automatic_variable_c +{ +private: + abs_eap_am_tools_c * const m_am_tools; + + /// This is the pointer to the actual object that will be deleted if different than zero. + Type *m_data; + +public: + + /** + * The destructor deletes the object in this atom if necessary. + */ + virtual ~eap_automatic_variable_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (m_data != 0) + { + delete m_data; + m_data = 0; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + /** + * The constructor sets the values for the member variables + */ + eap_automatic_variable_c( + abs_eap_am_tools_c * const tools, + Type * const p_data) + : m_am_tools(tools) + , m_data(p_data) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + /** + * The constructor sets the values for the member variables + */ + eap_automatic_variable_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_data(0) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + /** + * This function sets the data. + */ + void set_variable(Type * const p_data) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_data = p_data; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + // + void do_not_free_variable() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_data = 0; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } +}; + +//-------------------------------------------------- + +/** + * @{ Add some comments. } + */ +template +class EAP_EXPORT eap_automatic_array_variable_c +{ +private: + abs_eap_am_tools_c * const m_am_tools; + + /// This is the pointer to the actual object array that will be deleted if different than zero. + Type *m_data; + +public: + + /** + * The destructor deletes the object in this atom if necessary. + */ + virtual ~eap_automatic_array_variable_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (m_data != 0) + { + delete [] m_data; + m_data = 0; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + /** + * The constructor sets the values for the member variables + */ + eap_automatic_array_variable_c( + abs_eap_am_tools_c * const tools, + Type * const p_data) + : m_am_tools(tools) + , m_data(p_data) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + /** + * The constructor sets the values for the member variables + */ + void set_variable(Type * const p_data) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_data = p_data; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + // + void do_not_free_variable() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_data = 0; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } +}; + +//-------------------------------------------------- + +/** + * @{ Add some comments. } + */ +template +class EAP_EXPORT eap_automatic_simple_value_c +{ +private: + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to the variable that will be restored on destructor. + Type *m_restored_variable; + + /// This is the value that will be set on destructor. + Type m_data; + +public: + + /** + * The destructor deletes the object in this atom if necessary. + */ + virtual ~eap_automatic_simple_value_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_restored_variable != 0) + { + *m_restored_variable = m_data; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + /** + * The constructor sets the values for the member variables + */ + eap_automatic_simple_value_c( + abs_eap_am_tools_c * const tools, + Type * const p_restored_variable, + const Type p_data) + : m_am_tools(tools) + , m_restored_variable(p_restored_variable) + , m_data(p_data) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + // + void do_not_restore_variable() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_restored_variable = 0; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } +}; + + +//-------------------------------------------------- + +/** + * @{ Add some comments. } + */ +class EAP_EXPORT eap_automatic_trace_string_c +{ +private: + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to the string that will be traced on destructor. + eap_format_string m_string; + +public: + + /** + * The destructor traces the string. + */ + virtual ~eap_automatic_trace_string_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_string != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("<<< %s <<<\n"), m_string)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + /** + * The constructor sets the values for the member variables + */ + eap_automatic_trace_string_c( + abs_eap_am_tools_c * const tools, + eap_format_string string) + : m_am_tools(tools) + , m_string(string) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } +}; + + +#endif //#if !defined(_EAP_AUTOMATIC_VARIABLE_H_) + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_base_type.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_base_type.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,193 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_BASE_TYPE_H_) +#define _EAP_BASE_TYPE_H_ + +#include "eap_am_export.h" +#include "abs_eap_base_type.h" +#include "eap_header.h" + + +class abs_eap_base_type_c; +class eap_am_network_id_c; + +/// The eap_base_type_c class declares pure virtual functions +/// a user class of EAP-type class could call. +/// See also abs_eap_stack_interface_c. It includes +/// important functions too. +class EAP_EXPORT eap_base_type_c +//: public abs_eap_stack_interface_c This is not used here because packet_process() function differs. +{ + +private: + //-------------------------------------------------- + + /// This is back pointer to object which created this object. + /// The eap_base_type_c object sends packets to the network using m_type_partner object. + /// @see abs_eap_base_type_c. + abs_eap_base_type_c *m_type_partner; + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This is count of references to this EAP-type. + /// EAP-type is removed from eap_core_map_c after the reference count is zero. + u32_t m_reference_count; + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_base_type class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_base_type_c(); + + /** + * The constructor of the eap_base_type class simply initializes the attributes. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + * @param partner is back pointer to object which created this object. + * The eap_base_type_c object sends packets to the network using m_type_partner object. + */ + EAP_FUNC_IMPORT eap_base_type_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner); + + /** + * The object_increase_reference_count() function increases the reference count. + */ + EAP_FUNC_IMPORT void object_increase_reference_count(); + + /** + * The object_decrease_reference_count () function decreases + * the reference count and returns the remaining value. + * The EAP type is removed after there is no references to it. + */ + EAP_FUNC_IMPORT u32_t object_decrease_reference_count(); + + /** + * Type partner is object below the EAP-type object. + * @return The get_type_partner() function returns the pointer to the partner class. + */ + EAP_FUNC_IMPORT abs_eap_base_type_c * get_type_partner(); + + /** + * This function queries the identity of user using this type. + * @param must_be_synchronous tells whether this call must be synchronous. + * @param identity is buffer for queried identity in synchronous call. + * @param receive_network_id carries the addresses and type of the received packet. + * @param eap_identifier is EAP-Identifier for EAP-Response/Identity packet. + * + * Parameters receive_network_id and eap_identifier are used in asynchronous + * completion of this call. See abs_eap_base_type_c::complete_eap_identity_query(). + */ + virtual eap_status_e query_eap_identity( + const bool must_be_synchronous, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + * Needed configuration depends on the EAP-type. + */ + virtual eap_status_e configure() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + /** + * This function processes the received packet. + * The return value of this function should be used only for traces + * and error counters. You MUST NOT make any decision of authentication session + * based on the return value. The stack calls abs_eap_core_c::state_notification() + * function when authentication session terminates unsuccessfully or ends successfully. + * You MUST make decision of authentication session based on the state_notification() call. + * See more abs_eap_core_c::state_notification(). + * @param receive_network_id carries the addresses and type of the received packet. + * @param eap includes the buffer of the packet. + * @param packet_length is length in bytes of the EAP-packet. + */ + virtual eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_header_wr_c * const eap, + const u32_t packet_length) = 0; + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + virtual bool get_is_valid() = 0; + + /** + * This function resets the reused object. + */ + virtual eap_status_e reset() = 0; + + /** + * This function sets the initial EAP-Identifier to be used for the first sent packet. + * This function is only needed in Windows RAS. + */ + virtual eap_status_e set_initial_eap_identifier( + const eap_am_network_id_c * const receive_network_id, + const u8_t initial_identifier) = 0; + + /** + * The adaptation module calls the eap_acknowledge() function after + * any Network Protocol packet is received. This is used as a success indication. + * This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + * Mostly there is only one session in the client. + * The server does not need eap_acknowledge() function because + * server (EAP-authenticator) sends the EAP-success message. + */ + virtual eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id) = 0; + + //-------------------------------------------------- +}; // class eap_base_type_c + +#endif //#if !defined(_EAP_BASE_TYPE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_buffer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_buffer.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,692 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_BUFFER_H_) +#define _EAP_BUFFER_H_ + +#include "eap_am_assert.h" +#include "eap_variable_data.h" + +//-------------------------------------------------- + +const u32_t EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH = 1514; + +const u8_t EAP_MEM_GUARD_BYTE = 0x55; + +#if defined(_DEBUG) && defined(USE_EAP_MEM_GUARD) + + const u32_t EAP_MEM_GUARD_LENGTH = 256u; + + #define EAP_MEM_GUARDS(buffer_size) \ + (EAP_MEM_GUARD_LENGTH+(buffer_size)+EAP_MEM_GUARD_LENGTH) + +#else + + const u32_t EAP_MEM_GUARD_LENGTH = 0u; + + #define EAP_MEM_GUARDS(buffer_size) (buffer_size) + +#endif //#if defined(_DEBUG) && defined(USE_EAP_MEM_GUARD) + + + +enum eap_write_buffer_e +{ + eap_write_buffer +}; + + +enum eap_read_buffer_e +{ + eap_read_buffer +}; + +enum eap_random_error_type +{ + eap_random_error_type_manipulate_byte = 0, + eap_random_error_type_change_packet_length_longer, + eap_random_error_type_change_packet_length_shorter, + eap_random_error_type_none_keep_this_last_case, +}; + +//-------------------------------------------------- + +class abs_eap_am_tools_c; +class eapol_ethernet_header_wr_c; +class eapol_ethernet_header_rd_c; + + +/// Network packets are handled through eap_buf_chain_base_c class. +class EAP_EXPORT eap_buf_chain_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This struct decreases the memory print of eap_buf_chain_base_c. + struct eap_buf_chain_base_impl_str + { + /// This is the count of guard bytes allocated before and after the buffer. + u32_t m_mem_guard_length; + + eap_variable_data_c * m_buffer; + + /// This is pointer to the next buffer. NOTE this is NOT used in current version. + eap_buf_chain_base_c *m_next_buffer; + + /// This is used to test protocol with manipulated packets. This is used in testing. + eap_random_error_type m_random_error_type; + + /// This is used to test protocol with manipulated packets. This is used in testing. + u32_t m_send_packet_index; + + /// This the pointer of sender stack. + /// This is used in testing. + const void *m_stack_address; + + /// This indicates the buffer is initialized. + bool m_is_valid; + + /// This is used to mark packet if it is manipulated. This is used in testing. + bool m_is_manipulated; + + /// When this parameter is true eap_core_c activates re-transmission of this packet. + /// When this parameter is false eap_core_c does not activate re-transmission of this packet. + bool m_do_packet_retransmission; + + /// This is tells whether the sender is client or server. + /// This is used in testing. + bool m_is_client; + + /// This is used in testing. + bool m_do_length_checks; + + /// This flag tells whether this packet must be encrypted (true) or not (false). + /// Encryption means the WLAN data encryption on the air (WEP, TKIP or CCMP). + /// Using this flag to tell the encryption allows the configuration of the + /// temporal key beforehand the key is used. + /// This is optimization to fasten the key configuration. + bool m_encrypt; + }; + + /// This is pointer to data of eap_buf_chain_base_c. + /// This decreases memory print of eap_buf_chain_base_c. + /// This decreases stack usage of EAP_Core. + eap_buf_chain_base_impl_str * m_data; + + //-------------------------------------------------- + + /** + * This function initializes the eap_buf_chain_base_c object. + */ + EAP_FUNC_IMPORT eap_status_e initialize( + const u32_t mem_guard_length); + + /** + * Forses the inheritance. + */ + EAP_FUNC_IMPORT virtual void force_inheritance() = 0; + + /** + * Function checks the memory guard bytes. + */ + EAP_FUNC_IMPORT bool check_guard_bytes(const u8_t * const guard) const; + + /** + * Function sets the memory guard bytes. + */ + EAP_FUNC_IMPORT void set_mem_guard_bytes(); + + /** + * Function zeroes the data buffer. + */ + EAP_FUNC_IMPORT void reset_data_buffer(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + /** + * @return Returns pointer to the tools object. + */ + EAP_FUNC_IMPORT abs_eap_am_tools_c * get_am_tools(); + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Function checks the all memory guard bytes. + */ + EAP_FUNC_IMPORT bool check_guards() const; + + /** + * The destructor of the eap_buf_chain_base_c class checks memory guards + * and frees the allocated buffer. + */ + EAP_FUNC_IMPORT virtual ~eap_buf_chain_base_c(); + + /** + * The constructor of the eap_buf_chain_wr class initializes attributes using + * the parameters passes to it. + * @param eap_write_buffer_e separates the write and read-only constructors. + * @param tools parameter is pointer to the tools class. + * @param data is pointer to the buffer containing the message. + * @param data_length parameter is count of bytes in the buffer. + * @param reset_data parameter indicates whether the data bytes must be set zero. + * @param free_buffer parameter indicates whether the destructor must free the data buffer. + * @param mem_guard_length indicates the length of guard bytes both pre-fix and post-fix. + * + * NOTE the buffer allocated from the stack or from the heap must allocate additional + * bytes for memory guards. The EAP_MEM_GUARDS(size) macro increases the size with count + * of memory guard bytes. The example use of eap_buf_chain_wr is as follows. + * NOTE all sanity checks are ignored in the example. + * + * @code + * u8_t packet_buffer[EAP_MEM_GUARDS(EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH)]; + * eap_buf_chain_wr_c response_packet( + * eap_write_buffer, m_am_tools, packet_buffer, + * sizeof(packet_buffer), true, false, EAP_MEM_GUARD_LENGTH); + * const u32_t eap_header_offset = get_type_partner()->get_header_offset( + * &MTU, &trailer_length); + * eap_header_wr_c * const eap_response = (eap_header_wr_c * const) + * response_packet.get_data_offset(eap_header_offset, + * (EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH + * -(eap_header_offset+ trailer_length))); + * @endcode + */ + EAP_FUNC_IMPORT eap_buf_chain_base_c( + const eap_write_buffer_e, + abs_eap_am_tools_c * const tools, + u8_t * const data, + const u32_t data_length, + const bool reset_data, + const bool free_buffer, + const u32_t mem_guard_length); + + /** + * The constructor of the eap_buf_chain_wr class initializes attributes using + * the parameters passes to it. + * @param eap_read_buffer_e separates the write and read-only constructors. + * @param tools parameter is pointer to the tools class. + * @param data is pointer to the buffer containing the message. + * @param data_length parameter is count of bytes in the buffer. + * @param free_buffer parameter indicates whether the destructor must free the data buffer. + * + * The example use of eap_buf_chain_wr is as follows. + * NOTE all sanity checks are ignored in the example. + * + * @code + * u8_t packet_buffer[EAP_MEM_GUARDS(EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH)]; + * eap_buf_chain_rd_c response_packet( + * eap_read_buffer, m_am_tools, packet_buffer, + * sizeof(packet_buffer), false); + * const u32_t eap_header_offset = get_type_partner()->get_header_offset( + * &MTU, &trailer_length); + * eap_header_rd_c * const eap_response = (eap_header_rd_c * const) + * response_packet.get_data_offset(eap_header_offset, + * (EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH + * -(eap_header_offset+ trailer_length))); + * @endcode + */ + EAP_FUNC_IMPORT eap_buf_chain_base_c( + const eap_read_buffer_e, + abs_eap_am_tools_c * const tools, + const u8_t * const data, + const u32_t data_length, + const bool free_buffer); + + /** + * The constructor of the eap_buf_chain_wr class initializes attributes using + * the parameters passes to it. + * New buffer is allocated from heap. + * @param eap_write_buffer_e separates the write and read-only constructors. + * @param tools parameter is pointer to the tools class. + * @param data_length parameter is count of bytes in the buffer. + * + * The example use of eap_buf_chain_wr is as follows. + * NOTE all sanity checks are ignored in the example. + * + * @code + * eap_buf_chain_rd_c response_packet( + * eap_write_buffer_e, m_am_tools, + * PACKET_BUFFER_LENGTH); + * const u32_t eap_header_offset = get_type_partner()->get_header_offset( + * &MTU, &trailer_length); + * eap_header_rd_c * const eap_response = (eap_header_rd_c * const) + * response_packet.get_data_offset(eap_header_offset, + * (PACKET_BUFFER_LENGTH + * -(eap_header_offset+ trailer_length))); + * @endcode + */ + EAP_FUNC_IMPORT eap_buf_chain_base_c( + const eap_write_buffer_e, + abs_eap_am_tools_c * const tools, + const u32_t data_length); + + /** + * The constructor of the eap_buf_chain_rd class initializes attributes using + * the parameters passes to it. + * New buffer is allocated from heap. + * @param eap_write_buffer_e separates the write and read-only constructors. + * @param tools parameter is pointer to the tools class. + * @param data_length parameter is count of bytes in the buffer. + * + * The example use of eap_buf_chain_wr is as follows. + * NOTE all sanity checks are ignored in the example. + * + * @code + * eap_buf_chain_rd_c response_packet( + * eap_read_buffer, m_am_tools, + * PACKET_BUFFER_LENGTH); + * const u32_t eap_header_offset = get_type_partner()->get_header_offset( + * &MTU, &trailer_length); + * eap_header_rd_c * const eap_response = (eap_header_rd_c * const) + * response_packet.get_data_offset(eap_header_offset, + * (PACKET_BUFFER_LENGTH + * -(eap_header_offset+ trailer_length))); + * @endcode + */ + EAP_FUNC_IMPORT eap_buf_chain_base_c( + const eap_read_buffer_e, + abs_eap_am_tools_c * const tools, + const u32_t data_length); + + /** + * @return Returns count of memory guard bytes. + */ + EAP_FUNC_IMPORT u32_t get_mem_guard_length(); + + /** + * The get_buffer_length() function returns the length of buffer in bytes. + */ + EAP_FUNC_IMPORT u32_t get_buffer_length() const; + + /** + * The get_data_length() function returns count of data bytes in the buffer. + */ + EAP_FUNC_IMPORT u32_t get_data_length() const; + + /** + * The get_data_offset() function returns pointer to the data in offset (p_offset). + * @param p_offset indicates the required offset. + * @param p_continuous_bytes indicates how many bytes in continuous memory is needed. + * + * NOTE user of the eap_buf_chain_wr class must obtain the pointer to the data using + * this or the get_data() function. These functions can handle the memory guard. + */ + EAP_FUNC_IMPORT u8_t * get_data_offset(const u32_t p_offset, const u32_t p_continuous_bytes) const; + + /** + * The get_data() function function returns pointer to the data. + * @param p_continuous_bytes indicates how many bytes in continuous memory is needed. + * + * NOTE user of the eap_buf_chain_wr class must obtain the pointer to the data using + * this or the get_data_offset() function. These functions can handle the memory guard. + */ + EAP_FUNC_IMPORT u8_t * get_data(const u32_t p_continuous_bytes) const; + + /** + * The set_buffer_length() function allocates the buffer of length bytes. + */ + EAP_FUNC_IMPORT eap_status_e set_buffer_length(const u32_t length); + + /** + * The set_data_length() function set the data length in the buffer. + */ + EAP_FUNC_IMPORT eap_status_e set_data_length(const u32_t length); + + /** + * The get_is_valid() function returns the status of the object. + * @return True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid() const; + + /** + * The get_is_valid() function returns the status of the + * data included in object. + * @return True indicates the object includes valid data. + */ + EAP_FUNC_IMPORT bool get_is_valid_data() const; + + /** + * The set_is_manipulated() function sets flag to indicate this packet is manipulated. + * This is used for testing purposes. + */ + EAP_FUNC_IMPORT void set_is_manipulated(); + + /** + * The get_is_manipulated() function returns flag to indicate this packet is manipulated. + * This is used for testing purposes. + */ + EAP_FUNC_IMPORT bool get_is_manipulated(); + + /** + * This function sets the index of sent packet. + * This is used for testing purposes. + */ + EAP_FUNC_IMPORT void set_send_packet_index(const u32_t send_packet_index); + + /** + * This function returns the index of sent packet. + * This is used for testing purposes. + */ + EAP_FUNC_IMPORT u32_t get_send_packet_index(); + + /** + * The set_random_error_type() function sets the type of manipulation of the packet. + * This is used for testing purposes. + */ + EAP_FUNC_IMPORT void set_random_error_type(eap_random_error_type error_type); + + /** + * The get_random_error_type() function returns the type of manipulation of the packet. + * This is used for testing purposes. + */ + EAP_FUNC_IMPORT eap_random_error_type get_random_error_type(); + + /** + * The set_do_packet_retransmission() function sets the re-transmission flag of this packet. + * Packet will be re-transmitted by lower layer when do_packet_retransmission_when_true is true. + * Packet will not re-transmitted by lower layer when do_packet_retransmission_when_true is false. + */ + EAP_FUNC_IMPORT void set_do_packet_retransmission(const bool do_packet_retransmission_when_true); + + /** + * The set_do_packet_retransmission() function gets the re-transmission flag of this packet. + */ + EAP_FUNC_IMPORT bool get_do_packet_retransmission(); + + /** + * This sets whether the sender is client or server. + * This is used in testing. + */ + EAP_FUNC_IMPORT void set_is_client(const bool is_client_when_true); + + /** + * This gets whether the sender is client or server. + * This is used in testing. + */ + EAP_FUNC_IMPORT bool get_is_client() const; + + /** + * This is used in testing. + */ + EAP_FUNC_IMPORT void set_do_length_checks(const bool do_length_checks); + + /** + * This is used in testing. + */ + EAP_FUNC_IMPORT bool get_do_length_checks() const; + + + /** + * This sets whether this packet must be encrypted (true) or not (false). + * Encryption means the WLAN data encryption on the air (WEP, TKIP or CCMP). + * Using this flag to tell the encryption allows the configuration of the + * temporal key beforehand the key is used. + * This is optimization to fasten the key configuration. + */ + EAP_FUNC_IMPORT void set_encrypt(const bool encrypt_when_true); + + /** + * This gets whether this packet must be encrypted (true) or not (false). + * Encryption means the WLAN data encryption on the air (WEP, TKIP or CCMP). + * Using this flag to tell the encryption allows the configuration of the + * temporal key beforehand the key is used. + * This is optimization to fasten the key configuration. + */ + EAP_FUNC_IMPORT bool get_encrypt() const; + + + /** + * This sets the pointer of sender stack. + * This is used in testing. + */ + EAP_FUNC_IMPORT void set_stack_address(const void * const stack_address); + + /** + * This gets the pointer of sender stack. + * This is used in testing. + */ + EAP_FUNC_IMPORT const void * get_stack_address() const; + + /** + * The add_data() function adds data to the end of the buffer. + * If the buffer is empty the data is added to begin of the buffer. + * @param buffer points the data to be added. + * @param buffer_length is length of the buffer in bytes. + */ + EAP_FUNC_IMPORT eap_status_e add_data( + const void * const buffer, + const u32_t buffer_length); + + /** + * The add_data() function adds data to the end of the buffer. + * If the buffer is empty the data is added to begin of the buffer. + * @param buffer points the data to be added. + */ + EAP_FUNC_IMPORT eap_status_e add_data( + const eap_variable_data_c * const buffer); + + /** + * The add_data_to_offset() function adds data to the offset of the buffer. + * @param offset tells the place where data will begin. + * @param buffer points the data to be added. + * @param buffer_length is length of the buffer in bytes. + */ + EAP_FUNC_IMPORT eap_status_e add_data_to_offset( + const u32_t offset, + const void * const buffer, + const u32_t buffer_length); + + /** + * The add_data() function adds data to the offset of the buffer. + * @param offset tells the place where data will begin. + * @param buffer points the data to be added. + */ + EAP_FUNC_IMPORT eap_status_e add_data_to_offset( + const u32_t offset, + const eap_variable_data_c * const buffer); + + // + //-------------------------------------------------- +}; // class eap_buf_chain_base_c + + + +/// Write only network packets are handled through eap_buf_chain_base_c class. +/// Post-suffix _wr_c indicates the buffer has write attribute on. +/// The eap_buf_chain_wr_c class is derived from eap_buf_chain_base class. +class EAP_EXPORT eap_buf_chain_wr_c +: public eap_buf_chain_base_c +{ +private: + + /** + * Forses the inheritance. + */ + EAP_FUNC_IMPORT void force_inheritance(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_buf_chain_wr_c(); + + /** + * The costructor does nothing special. It just initializes all member attributes. + * This version uses preallocated buffer. + */ + EAP_FUNC_IMPORT eap_buf_chain_wr_c( + const eap_write_buffer_e, + abs_eap_am_tools_c * const tools, + u8_t * const data, + const u32_t data_length, + const bool reset_data, + const bool free_buffer, + const u32_t mem_guard_length); + + /** + * The costructor does nothing special. It just initializes all member attributes. + * This version allocates buffer from heap. + */ + EAP_FUNC_IMPORT eap_buf_chain_wr_c( + const eap_write_buffer_e, + abs_eap_am_tools_c * const tools, + const u32_t data_length); + + /** + * The costructor does nothing special. It just initializes all member attributes. + * This version does not allocate buffer. + * You must call set_buffer_length() member function to allocate buffer. + */ + EAP_FUNC_IMPORT eap_buf_chain_wr_c( + const eap_write_buffer_e, + abs_eap_am_tools_c * const tools); + + /** + * @return Returns the pointer to the ethernet header. + */ + EAP_FUNC_IMPORT u8_t * get_ethernet_header(); + + /** + * The copy() function copies the eap_buf_chain_wr object. + * Data is copied to new allocated buffer. + */ + EAP_FUNC_IMPORT eap_buf_chain_wr_c * copy(); + + // + //-------------------------------------------------- +}; // class eap_buf_chain_wr_c + + +/// Read only network packets are handled through eap_buf_chain_rd_c class. +/// Post-suffix _rd_c indicates the buffer has read only attribute on. +/// The eap_buf_chain_rd_c class is derived from eap_buf_chain_base class. +class EAP_EXPORT eap_buf_chain_rd_c +: public eap_buf_chain_base_c +{ +private: + + /** + * Forses the inheritance. + */ + EAP_FUNC_IMPORT void force_inheritance(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_buf_chain_rd_c class checks memory guards. + */ + EAP_FUNC_IMPORT virtual ~eap_buf_chain_rd_c(); + + /** + * The constructor of the eap_buf_chain_wr class initializes attributes using + * the parameters passes to it. + * @param eap_read_buffer_e separates the write and read-only constructors. + * @param tools parameter is pointer to the tools class. + * @param data is pointer to the buffer containing the message. + * @param data_length parameter is count of bytes in the buffer. + * @param free_buffer parameter indicates whether the destructor must free the data buffer. + * + * The example use of eap_buf_chain_wr is as follows. + * NOTE all sanity checks are ignored in the example. + * + * @code + * u8_t packet_buffer[EAP_MEM_GUARDS(EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH)]; + * eap_buf_chain_rd_c response_packet( + * eap_read_buffer, m_am_tools, packet_buffer, + * sizeof(packet_buffer), false); + * const u32_t eap_header_offset = get_type_partner()->get_header_offset( + * &MTU, &trailer_length); + * eap_header_rd_c * const eap_response = (eap_header_rd_c * const) + * response_packet.get_data_offset(eap_header_offset, + * (EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH + * -(eap_header_offset+ trailer_length))); + * @endcode + */ + EAP_FUNC_IMPORT eap_buf_chain_rd_c( + const eap_read_buffer_e, + abs_eap_am_tools_c * const tools, + const u8_t * const data, + const u32_t data_length, + const bool free_buffer); + + /** + * The costructor does nothing special. It just initializes all member attributes. + * This version allocates buffer from heap. + */ + EAP_FUNC_IMPORT eap_buf_chain_rd_c( + const eap_read_buffer_e, + abs_eap_am_tools_c * const tools, + const u32_t data_length); + + /** + * The get_data() function function returns pointer to the data. + * @param p_continuous_bytes indicates how many bytes in continuous memory is needed. + * + * NOTE user of the eap_buf_chain_wr class must obtain the pointer to the data using + * this or the get_data_offset() function. These functions can handle the memory guard. + */ + EAP_FUNC_IMPORT const u8_t * get_data(const u32_t p_continuous_bytes) const; + + /** + * The get_data_offset() function returns pointer to the data in offset (p_offset). + * @param p_offset indicates the required offset. + * @param p_continuous_bytes indicates how many bytes in continuous memory is needed. + * + * NOTE user of the eap_buf_chain_wr class must obtain the pointer to the data using + * this or the get_data() function. These functions can handle the memory guard. + */ + EAP_FUNC_IMPORT const u8_t * get_data_offset(const u32_t p_offset, const u32_t p_continuous_bytes) const; + + /** + * @return Returns the pointer to the ethernet header. + */ + EAP_FUNC_IMPORT const u8_t * get_ethernet_header() const; + + // + //-------------------------------------------------- +}; // class eap_buf_chain_rd_c + + +#endif //#if !defined(_EAP_BUFFER_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_config.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,790 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_CONFIG_H_) +#define _EAP_CONFIG_H_ + +#include "eap_configuration_field.h" + + +enum eap_type_default_constants_e +{ + eap_type_default_credential_timeout = 43200000, ///< Default timeout of EAP credentials is 12 hours = 43200000 milli seconds. +}; + +//-------------------------------------------------------------------------------------------------- + +/** + * @defgroup Common_EAP_config_options Common configuration options of EAP. + * The following configuration options are read through abs_eap_base_type_c::read_configure() function. + * @{ + */ + + + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_access_point_name, + "EAP_access_point_name", + eap_configure_type_section, + false); + + +/** + * This u32_t or hex data configuration option selects the default EAP type. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_default_type_hex_data, + "EAP_default_type", + eap_configure_type_hex_data, + false); +EAP_CONFIGURATION_FIELD( + cf_str_EAP_default_type_u32_t, + "EAP_default_type", + eap_configure_type_u32_t, + false); + +/** + * This string configuration option sets the additional routing realms + * to the NAI of EAP Identity-Response of the outer EAP method. The format of + * the string must be "realm1!realm2!realm3" in which realm1 is the first + * location in the route. The NAI becomes "realm2!realm3!homerealm!username@realm1". + * See RFC4242 for more info. Default value is an empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_outer_identity_routing, + "EAP_outer_identity_routing", + eap_configure_type_string, + false); + +/** + * This string configuration option sets the additional NAI decoration + * to the NAI of EAP Identity-Response of the outer EAP method. The given + * string (e.g. "{decoration}") is placed as such in front of the username. + * The NAI becomes "{decoration}username@realm". See RFC4242 for more info. + * Default value is an empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_outer_identity_decoration, + "EAP_outer_identity_decoration", + eap_configure_type_string, + false); + +/** + * This u32_t or hex data configuration option selects the default EAP type of EAP-server. + * Reason for this is we could test EAP-Core in a case where + * EAP-client and EAP-server have different default EAP-types. + * If this is not defined EAP-server uses EAP_default_type option. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_server_default_type_hex_data, + "EAP_server_default_type", + eap_configure_type_hex_data, + false); +EAP_CONFIGURATION_FIELD( + cf_str_EAP_server_default_type_u32_t, + "EAP_server_default_type", + eap_configure_type_u32_t, + false); + +/** + * This boolean configuration option enables EAP-Nak message handling immediately with true value. + * False value means EAP-Nak is prosessed after a timeout. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_process_EAP_Nak_immediately, + "EAP_CORE_process_EAP_Nak_immediately", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option disables EAP traces with true value. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_disable_traces, + "EAP_TRACE_disable_traces", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables EAP function traces with true value. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_enable_function_traces, + "EAP_TRACE_enable_function_traces", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables EAP timer traces with true value. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_enable_timer_traces, + "EAP_TRACE_enable_timer_traces", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables EAP timer queue traces with true value. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_enable_timer_queue_traces, + "EAP_TRACE_enable_timer_queue_traces", + eap_configure_type_boolean, + false); + + +/** + * This boolean configuration option enables EAP OK return traces with true value. + * There will be a lot of traces. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_enable_ok_return_traces, + "EAP_TRACE_enable_ok_return_traces", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables EAP message data traces with true value. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_enable_message_data_traces, + "EAP_TRACE_enable_message_data_traces", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables EAP core map traces with true value. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_enable_core_map_traces, + "EAP_TRACE_enable_core_map_traces", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables test vector traces. + * True value means only test vector traces of each EAP-type are traced. + * False value does not change traces. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_only_test_vectors, + "EAP_TRACE_only_test_vectors", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables test vector traces of SHA1. + * True value means SHA1 test vector traces are traced. + * False value does not change traces. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_crypto_test_vectors_sha1, + "EAP_TRACE_crypto_test_vectors_sha1", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables test vector traces of RC4. + * True value means RC4 test vector traces are traced. + * False value does not change traces. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_crypto_test_vectors_rc4, + "EAP_TRACE_crypto_test_vectors_rc4", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables test vector traces of MD4. + * True value means MD4 test vector traces are traced. + * False value does not change traces. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_crypto_test_vectors_md4, + "EAP_TRACE_crypto_test_vectors_md4", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables test vector traces of test random generator. + * True value means test random generator test vector traces are traced. + * Note this activates EAP_TRACE_crypto_test_vectors_sha1 traces too. + * False value does not change traces. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_crypto_test_vectors_test_random, + "EAP_TRACE_crypto_test_vectors_test_random", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables only message traces with true value. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_only_trace_messages, + "EAP_TRACE_only_trace_messages", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option with true value enables only + * always active traces and error traces. + * set_trace_mask(eap_trace_mask_always|eap_trace_mask_error). + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_activate_only_trace_masks_always_and_error, + "EAP_TRACE_activate_only_trace_masks_always_and_error", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option with true value enables activation of traces + * when error occurs. + * Look at the set_activate_trace_on_error() and eap_status_return() + * functions. NOTE the always active traces are only left active. + * That means set_activate_trace_on_error() function calls + * set_trace_mask(eap_trace_mask_always). + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_activate_trace_on_error, + "EAP_TRACE_activate_trace_on_error", + eap_configure_type_boolean, + false); + + +#if defined(USE_EAP_ERROR_TESTS) + +/** + * This variable is true (1) or false (0). + * True value means simulator EAP AM randomly drop send packets. + * False value means simulator EAP AM does not drop send packets. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_ERROR_TEST_randomly_drop_packets, + "EAP_ERROR_TEST_randomly_drop_packets", + eap_configure_type_boolean, + false); + +/** + * This u32_t configuration option selects probability of packet drop. + * Probability is EAP_ERROR_TEST_randomly_drop_packets_probability/(2^32). + * for example 8000000/(2^32) is about 0.00186. + * Value (2^32)=4294967295 gives probability 1, eg. every packet is dropped. + * Default value is 0, which means no packets are dropped. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_ERROR_TEST_randomly_drop_packets_probability, + "EAP_ERROR_TEST_randomly_drop_packets_probability", + eap_configure_type_u32_t, + false); + +/** + * This variable is true (1) or false (0). + * True value means simulator EAP AM activates random errors to send packets. + * False value means simulator EAP AM disables random errors to send packets. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_ERROR_TEST_enable_random_errors, + "EAP_ERROR_TEST_enable_random_errors", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option value true selects the original EAP-packet + * is sent first when EAP-packet randon error generation is enabled. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_ERROR_TEST_send_original_packet_first, + "EAP_ERROR_TEST_send_original_packet_first", + eap_configure_type_boolean, + false); + +/** + * This u32_t configuration option selects how many additional error packet are generated. + * Default value is 0, which means one error packet. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_ERROR_TEST_generate_multiple_error_packets, + "EAP_ERROR_TEST_generate_multiple_error_packets", + eap_configure_type_u32_t, + false); + +/** + * This boolean configuration option enables random error generation to ethernet packet with true value. + * True value means simulator EAP AM manipulates ethernet header with random errors. + * False value means simulator EAP AM does not manipulate ethernet header with random errors. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_ERROR_TEST_manipulate_ethernet_header, + "EAP_ERROR_TEST_manipulate_ethernet_header", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables random error generation to EAPOL packet with true value. + * True value means simulator EAP AM manipulates EAPOL header with random errors. + * False value means simulator EAP AM does not manipulate EAPOL header with random errors. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_ERROR_TEST_manipulate_eapol_header, + "EAP_ERROR_TEST_manipulate_eapol_header", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option enables random error generation only to EAPOL-Key packets with true value. + * True value means simulator EAP AM manipulates only EAPOL-Key packets with random errors. + * False value means simulator EAP AM does manipulate other packets too with random errors. + * This option works only when EAP_ERROR_TEST_enable_random_errors is true. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_ERROR_TEST_manipulate_only_eapol_key_messages, + "EAP_ERROR_TEST_manipulate_only_eapol_key_messages", + eap_configure_type_boolean, + false); + +/** + * This variable is true (1) or false (0). + * This boolean configuration option enables random error generation only to tunneled PEAP packets with true value. + * True value means tls_application_eap_core_c manipulates only PEAP tunneled packets with random errors. + * False value means simulator EAP AM does manipulate other packets too with random errors. + * This option works only when EAP_ERROR_TEST_enable_random_errors is true. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_ERROR_TEST_manipulate_only_tunneled_messages, + "EAP_ERROR_TEST_manipulate_only_tunneled_messages", + eap_configure_type_boolean, + false); + +/** + * This u32_t configuration option selects probability of errors generated. + * Probability is EAP_ERROR_TEST_error_probability/(2^32). + * for example 8000000/(2^32) is about 0.00186. + * Value (2^32)=4294967295 gives probability 1, eg. error is generated to every byte. + * Default value is 0, which means no errors. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_ERROR_TEST_error_probability, + "EAP_ERROR_TEST_error_probability", + eap_configure_type_u32_t, + false); + +#endif //#if defined(USE_EAP_ERROR_TESTS) + + +/** + * This string configuration option selects file and path name of trace log file. + * Default value is /tmp/eap_core.log. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_output_file_name, + "EAP_TRACE_output_file_name", + eap_configure_type_string, + false); + +/** + * This u32_t configuration option sets the maximum size of trace log file in bytes. + * Note this is not absolute value. New file is generated when size of trace log file + * exceeds this limitation. + * Default value is 100000000 bytes. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TRACE_max_trace_file_size, + "EAP_TRACE_max_trace_file_size", + eap_configure_type_u32_t, + false); + +/** + * This boolean configuration option value true activates random generator for test use. + * It does generate predictive pseudorandom data. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TEST_RANDOM_use_test_random_generator, + "EAP_TEST_RANDOM_use_test_random_generator", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option value true activates re-seeding of test random generator. + * It does generate unpredictive pseudorandom test data. Note this is just for testing. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TEST_RANDOM_use_test_random_reseeding, + "EAP_TEST_RANDOM_use_test_random_reseeding", + eap_configure_type_boolean, + false); + +/** + * This hex data configuration option value seed random generator for test use. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TEST_RANDOM_seed, + "EAP_TEST_RANDOM_seed", + eap_configure_type_hex_data, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_TEST_preshared_key, + "EAPOL_TEST_preshared_key", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_TEST_override_wpa_psk, + "EAPOL_TEST_override_wpa_psk", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_TEST_test_reassociation, + "EAPOL_TEST_test_reassociation", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_TEST_test_reassociation_randomly, + "EAPOL_TEST_test_reassociation_randomly", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_TEST_MTU, + "EAPOL_TEST_MTU", + eap_configure_type_u32_t, + false); + + +/** + * This hex data configuration option value client MAC address for test use. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_client_MAC_address, + "EAP_client_MAC_address", + eap_configure_type_hex_data, + false); + +/** + * This hex data configuration option value client MAC address for test use. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_server_MAC_address, + "EAP_server_MAC_address", + eap_configure_type_hex_data, + false); + + +/** + * This hex data or u32array configuration option value is list of EAP-types client accepts. + * Values are hex data or u32array of EAP Expanded Type. + * This is used in simulator testing. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_client_types_hex_data, + "EAP_client_types", + eap_configure_type_hex_data, + false); +EAP_CONFIGURATION_FIELD( + cf_str_EAP_client_types_u32array, + "EAP_client_types", + eap_configure_type_u32array, + false); + +/** + * This hex data or u32array configuration option value is list of EAP-types server accepts. + * Values in the array are type of u32_t. + * This is used in simulator testing. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_server_types_hex_data, + "EAP_server_types", + eap_configure_type_hex_data, + false); +EAP_CONFIGURATION_FIELD( + cf_str_EAP_server_types_u32array, + "EAP_server_types", + eap_configure_type_u32array, + false); + +/** + * This u32_t configuration option selects maximum count of sent EAPOL-Start messages. + * Default value is EAPOL_CORE_MAX_EAPOL_START_SENDINGS. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_CORE_starts_max_count, + "EAPOL_CORE_starts_max_count", + eap_configure_type_u32_t, + false); + +/** + * This u32_t configuration option selects timeout between sent EAPOL-Start messages. + * Default value is EAPOL_CORE_TIMER_SEND_START_AGAIN_TIMEOUT. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_CORE_send_start_interval, + "EAPOL_CORE_send_start_interval", + eap_configure_type_u32_t, + false); + +/** + * This boolean configuration option enables test to skip start of 4-Way Handshake in server. + * This is for testing purposes. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_CORE_skip_start_4_way_handshake, + "EAPOL_CORE_skip_start_4_way_handshake", + eap_configure_type_boolean, + false); + +/** + * This u32_t configuration option set the timer resolution. + * Default value is EAP_TIMER_RESOLUTION. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TIMER_resolution, + "EAP_TIMER_resolution", + eap_configure_type_u32_t, + false); + +/** + * This boolean configuration option enables EAP milli second timer with true value. + * Note the AM must support this feature. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TIMER_use_eap_millisecond_timer, + "EAP_TIMER_use_eap_millisecond_timer", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. True value activates session re-use in eap_session_core_c. + * It optimises stack load by re-using the existing stack. + * False value creates always a new stack. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SESSION_use_reset_session, + "EAP_SESSION_use_reset_session", + eap_configure_type_boolean, + false); + +/** + * This u32_t configuration option set the timeout value after the EAP-session is removed. + * Default value is EAP_CORE_REMOVE_SESSION_TIMEOUT. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_remove_session_timeout, + "EAP_CORE_remove_session_timeout", + eap_configure_type_u32_t, + false); + +/** + * This is boolean configuration option. True value activates use of expanded EAP type field of 64-bits in length. + * False value forces to use the normal 8-bit EAP type field. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_use_eap_expanded_type, + "EAP_CORE_use_eap_expanded_type", + eap_configure_type_boolean, + false); + + +#if defined(USE_EAP_MEMORY_FUNCTIONS) && defined(USE_EAP_MEMORY_FUNCTIONS_FAILURES) + +/** + * This u32_t configuration option sets the probability of memory failure. + * Note you must define USE_EAP_MEMORY_FUNCTIONS and USE_EAP_MEMORY_FUNCTIONS_FAILURES + * compiler flags in order to use this feature. + * Probability is EAP_CORE_memory_alloc_failures_probability/(2^32). + * for example 8000000/(2^32) is about 0.00186. + * Value (2^32)=4294967295 gives probability 1, eg. every memory allocation fails. + * Default value is 0, this means disabled. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_memory_alloc_failures_probability, + "EAP_CORE_memory_alloc_failures_probability", + eap_configure_type_u32_t, + false); + +/** + * This u32_t configuration option sets the skip count of memory allocations before failures are generated. + * Note you must define USE_EAP_MEMORY_FUNCTIONS and USE_EAP_MEMORY_FUNCTIONS_FAILURES + * compiler flags in order to use this feature. + * Default value is 0. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_memory_alloc_failures_skip_count, + "EAP_CORE_memory_alloc_failures_skip_count", + eap_configure_type_u32_t, + false); + +#endif //#if defined(USE_EAP_MEMORY_FUNCTIONS) && defined(USE_EAP_MEMORY_FUNCTIONS_FAILURES) + + +/** + * This boolean configuration option enables asyncronous test for EAPOL messages with true value. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_TEST_use_message_asyncronous_test, + "EAPOL_TEST_use_message_asyncronous_test", + eap_configure_type_boolean, + false); + + +#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) + /** + * This boolean configuration option skips user interactions in selected test cases with true value. + * Default value is false, then user interactions are enabled as normally. + */ + EAP_CONFIGURATION_FIELD( + cf_str_EAP_skip_user_interactions_for_testing_purposes, + "EAP_skip_user_interactions_for_testing_purposes", + eap_configure_type_boolean, + false); +#endif //#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) + + +/** @} */ // End of group Common_EAP_config_options. + +//-------------------------------------------------------------------------------------------------- + +/** + * @defgroup Common_EAP_RAS_config_options Common EAP RAS configuration options. + * The following configuration options are read through abs_eap_base_type_c::read_configure() function. + * @{ + */ + +/** + * This is boolean configuration option. + * True value means windows RAS AM sends Windows user name in EAP-Response/Identity. + * False value means windows RAS AM sends @realm in EAP-Response/Identity. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_RAS_use_windows_username, + "EAP_RAS_use_windows_username", + eap_configure_type_boolean, + false); + +/** + * This string configuration option is used in testing. It is the windows RAS username. + * This is used only when EAP_RAS_use_windows_username option is true. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_RAS_windows_username, + "EAP_RAS_windows_username", + eap_configure_type_string, + false); + +/** + * This is boolean configuration option. + * True value means windows RAS AM prompt user when authentication starts. + * False value means windows RAS AM does not prompt user. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_RAS_enable_prompt, + "EAP_RAS_enable_prompt", + eap_configure_type_boolean, + false); + +/** + * This string configuration option stores the latest IMSI used. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_RAS_latest_imsi, + "EAP_RAS_latest_imsi", + eap_configure_type_string, + false); + +/** + * This string configuration option stores the latest SSID used. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_RAS_latest_ssid, + "EAP_RAS_latest_ssid", + eap_configure_type_string, + false); + +/** + * This is u32_t configuration option. + * Value is limiter for authentication prompt. + * Maximum time without prompting for authentication if the SSID hasn't changed. + * Default value is 0, which means no limitation. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_RAS_prompt_threshold, + "EAP_RAS_prompt_threshold", + eap_configure_type_u32_t, + false); + +/** + * This is u32_t configuration option. + * Value is time stamp of last authentication. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_RAS_timestamp, + "EAP_RAS_timestamp", + eap_configure_type_u32_t, + false); + +/** @} */ // End of group Common_EAP_RAS_config_options. + +//-------------------------------------------------------------------------------------------------- + + +#endif //#if !defined(_EAP_CONFIG_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_configuration_field.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_configuration_field.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,255 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_CONFIGURATION_FIELD_H_) +#define _EAP_CONFIGURATION_FIELD_H_ + +#include "eap_am_memory.h" +#include "eap_am_types.h" +#include "eap_am_tools.h" + + +const char EAP_FILECONFIG_SECTION_SEPARATOR[] = ":"; +const u32_t EAP_FILECONFIG_SECTION_SEPARATOR_LENGTH = (sizeof(EAP_FILECONFIG_SECTION_SEPARATOR)-1ul); + + +//-------------------------------------------------------------------------------------------------- + +enum eap_configure_type_e +{ + eap_configure_type_none, + eap_configure_type_u32_t, + eap_configure_type_boolean, + eap_configure_type_string, + eap_configure_type_hex_data, + eap_configure_type_u32array, + eap_configure_type_section, + eap_configure_type_subsection, +}; + +//-------------------------------------------------------------------------------------------------- + +class eap_configuration_field_c +{ +public: + + ~eap_configuration_field_c() + { + delete m_subsection_name; + m_subsection_name = 0; + } + + const bool get_is_secret() const + { + return m_is_secret; + } + + const eap_configure_type_e get_type() const + { + return m_type; + } + + const u32_t get_field_length() const + { + return m_field_length; + } + + eap_config_string get_field() const + { + return m_field; + } + + eap_status_e set_subsection( + abs_eap_am_tools_c * const tools, + const eap_configuration_field_c * const p_subsection_name, + const eap_variable_data_c * const p_subsection_value) + { + delete m_subsection_name; + m_subsection_name = 0; + + m_subsection_name = new eap_variable_data_c(tools); + if (m_subsection_name == 0) + { + return EAP_STATUS_RETURN(tools, eap_status_allocation_error); + } + + eap_status_e status = m_subsection_name->add_data( + p_subsection_name->get_field(), + p_subsection_name->get_field_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(tools, status); + } + + status = m_subsection_name->add_data( + EAP_FILECONFIG_SECTION_SEPARATOR, + EAP_FILECONFIG_SECTION_SEPARATOR_LENGTH); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(tools, status); + } + + status = m_subsection_name->add_data( + p_subsection_value->get_data(), + p_subsection_value->get_data_length()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(tools, status); + } + + return EAP_STATUS_RETURN(tools, eap_status_ok); + } + + const eap_variable_data_c * get_subsection() const + { + return m_subsection_name; + } + + bool compare( + abs_eap_am_tools_c * const tools, + const eap_configuration_field_c * const field) const + { + return field->get_field_length() == get_field_length() + && tools->memcmp( + field->get_field(), + get_field(), + field->get_field_length()) == 0; + } + + + bool compare( + abs_eap_am_tools_c * const tools, + const eap_variable_data_c * const data) const + { + return data->get_data_length() == get_field_length() + && tools->memcmp( + data->get_data(), + get_field(), + data->get_data_length()) == 0; + } + + eap_configuration_field_c * copy( + abs_eap_am_tools_c * const tools, + const eap_configuration_field_c * const p_subsection_name, + const eap_variable_data_c * const p_subsection_value) const + { + // This allocates memory for object and following field. + u32_t data_length = sizeof(eap_configuration_field_c) + m_field_length; + u8_t * const new_buffer = new u8_t[data_length]; + if (new_buffer == 0) + { + return 0; + } + + eap_configuration_field_c * tmp = reinterpret_cast(new_buffer); + + tools->memmove(tmp, this, data_length); + + eap_status_e status = tmp->set_subsection( + tools, + p_subsection_name, + p_subsection_value); + if (status != eap_status_ok + || tmp->get_subsection() == 0) + { + delete tmp; + tmp = 0; + } + + return tmp; + } + +private: + bool m_is_secret; + eap_configure_type_e m_type; + eap_variable_data_c *m_subsection_name; + u32_t m_field_length; + i8_t m_field[1]; +}; + +//-------------------------------------------------------------------------------------------------- + +template +class eap_configuration_field_template_c +{ +public: + inline const eap_configuration_field_c * get_field() const; + + inline eap_status_e set_fields( + abs_eap_am_tools_c* const am_tools, + const void * const field, + const eap_configure_type_e type, + const bool is_secret) + { + m_is_secret = false; + m_type = eap_configure_type_none; + + u32_t field_length = (static_cast (am_tools))->strlen( + static_cast(field)); + if (field_length+1 > buffer_length) + { + m_field_length = 0ul; + m_field[0] = '\0'; + return EAP_STATUS_RETURN(am_tools, eap_status_allocation_error); + } + + m_is_secret = is_secret; + m_type = type; + am_tools->memmove(m_field, field, field_length+1); + m_field_length = field_length; + + return EAP_STATUS_RETURN(am_tools, eap_status_ok); + } + + inline bool get_is_valid() const + { + EAP_STATIC_ASSERT(sizeof(eap_configuration_field_template_c) >= sizeof(eap_configuration_field_c)); + return true; + } + + +public: + bool m_is_secret; + eap_configure_type_e m_type; + eap_variable_data_c *m_subsection_name; + u32_t m_field_length; + i8_t m_field[buffer_length]; +}; + +template +inline const eap_configuration_field_c * eap_configuration_field_template_c::get_field() const +{ + return reinterpret_cast(this); +} + +#define EAP_CONFIGURATION_FIELD(name, field, type, is_secret) \ + static const eap_configuration_field_template_c name \ + EAP_ATTRIBUTE_UNUSED = {is_secret, type, 0, sizeof(field)-1, field}; \ + EAP_AM_CONFIGURATION_FIELD_LITERAL(name, field) + +//-------------------------------------------------------------------------------------------------- + + +#endif //#if !defined(_EAP_CONFIGURATION_FIELD_H_) + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_core.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_core.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,939 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +/** + * @mainpage EAP Core documentation. + * + * @section intro Introduction + * This is a EAP Core documentation generated by doxygen. + * First read S60_3_1_EAP_Core.doc + * file from EAPOL/documentation directory. + * Release notes are in file release_notes.txt + * + * @section install Installation + * Installation instructions are in file EAPOL/readme.txt. + * + * @section classes Most crucial classes + * The most crucial classes are eap_core_c, abs_eap_core_c, + * eap_base_type_c and abs_eap_base_type_c. + * + * Header files are stored to a directory EAPOL/include. + * Implementation of eap_core_c class is in a file + * EAPOL/core/eap_core.cpp. Implementation of eap_base_type_c class is in a file + * EAPOL/common/eap_base_type.cpp. + * + * @section eap_types Implemented EAP-types + * + * @subsection GSMSIM EAP/SIM + * EAP/SIM implementation is in a directory + * EAPOL/type/gsmsim. + * EAP/SIM is specified in draft-haverinen-pppext-eap-sim-xx.txt. + * The most current is + * + * RFC 4186. + * IETF drafts and RFC are stored to a directory + * EAPOL/type/gsmsim/documentation. + * The document + * GSMSIM.doc + * includes implementation notes of GSMSIM. + * + * @subsection EAP_AKA EAP/AKA + * EAP/AKA implementation is in a directory + * EAPOL/type/aka. + * EAP/AKA is specified in draft-arkko-pppext-eap-aka-xx.txt. + * The most current is + * + * RFC 4187. + * IETF drafts are stored to a directory + * EAPOL/type/aka/documentation. + * + * @subsection EAP_TLS_PEAP EAP/TLS, PEAP and TTLS + * Implementation design and architecture of EAP/TLS, PEAP and TTLS is in + * EAP_TLS_PEAP.doc + * file in EAPOL/type/tls_peap/documentation directory. + * EAP/TLS and PEAP implementation will be in a directory + * EAPOL/type/tls_peap. + * TLS is specified in rfc2246.txt. + * EAP/TLS is specified in rfc2716.txt. + * PEAPv2 is specified in draft-josefsson-pppext-eap-tls-eap-08.txt. + * PEAPv1 is specified in draft-josefsson-pppext-eap-tls-eap-05.txt. + * Windows XP- PEAPv0 is specified in draft-kamath-pppext-peapv0-00.txt. + * TTLS is specified in draft-ietf-pppext-eap-ttls-04.txt. + * + * @subsection EAP_MsChapv2 EAP/MsChapv2 + * EAP/MsChapv2 implementation is in a directory + * EAPOL/type/mschapv2. + * EAP/MsChapv2 is specified in draft-kamath-pppext-eap-mschapv2-XX.txt, rfc2433.txt and rfc2759.txt. + * The most current is + * + * EAP/MsChapv2 draft version 2. + * See also rfc2433.txt + * and rfc2759.txt. + * IETF drafts are stored to a directory + * EAPOL/type/mschapv2/doc. + * + * @subsection EAP_SecurID_GTC EAP/SecurID and GTC + * EAP/SecurID implementation is in a directory + * EAPOL/type/securid. + * EAP/SecurID is specified in draft-josefsson-eap-securid-XX.txt. + * The most current is + * + * EAP/SecurID draft version 1. + * IETF drafts are stored to a directory + * EAPOL/type/securid/documentation. + * + * @subsection EAP_LEAP EAP/LEAP + * EAP/LEAP implementation is in a directory + * EAPOL/type/leap. + * EAP/LEAP documentation is not included here. + * + * @subsection SAE Experimental Security Association for EAPOL (not used) + * SAE implementation is in a directory EAPOL/SAE. + * Document defining SAE is EAPOL_SA.doc. + * This is a very experimental test implementation. + * Idea is to use Diffie-Hellman to create keys for a anonymous EAPOL tunnel. + * Any EAP-type could then run inside the tunnel. + * This fixes the problem of current EAPOL over WLAN. + * EAP was designed for poin to point environment and EAPOL to non-shared environment. + * + * NOTE SAE is not used anywhere. + * + * @section Symbian Symbian Plug-in + * EAP Type Plug-in Architecture for Symbian is specified in + * + * eap_plugin_architecture.doc. + * + */ + + +#if !defined(_EAP_CORE_H_) +#define _EAP_CORE_H_ + +#include "eap_am_export.h" +#include "abs_eap_base_type.h" +#include "eap_core_map.h" +#include "eap_am_network_id.h" +#include "abs_eap_stack_interface.h" +#include "eap_configuration_field.h" +#include "abs_eap_core_map.h" + +class abs_eap_core_c; +class abs_eap_am_tools_c; +class eap_core_retransmission_c; +class eap_base_type_c; +class eap_variable_data_c; + +//-------------------------------------------------------------------------------------------------- + +/** + * @defgroup EAP_Core_config_options Configuration options of EAP Core. + * The following configuration options are read through abs_eap_base_type_c::read_configure() function. + * @{ + */ + +/** + * This is u32_t configuration option. + * This is the maximum count EAP CORE Authenticator resents message again. + * This is used in simulator testing. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_retransmission_counter, + "EAP_CORE_retransmission_counter", + eap_configure_type_u32_t, + false); + +/** + * This is u32_t configuration option. + * This is the time after EAP CORE Authenticator resents message again. + * This is used in simulator testing. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_retransmission_time, + "EAP_CORE_retransmission_time", + eap_configure_type_u32_t, + false); + +/** + * This is u32_t configuration option. + * This is the maximum time EAP authentication could succeed. + * This timeout is same for every EAP-type. + * You must define EAP-type spesific configuration + * if you need different timeout for your EAP-type. + * Authentication is terminated after this time elapses. + * Time is in milli secons. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_session_timeout, + "EAP_CORE_session_timeout", + eap_configure_type_u32_t, + false); + +/** + * This is optional and only valid for server. + * This allows different values for client and server. + * This is u32_t configuration option. + * This is the maximum time EAP authentication could succeed. + * This timeout is same for every EAP-type. + * You must define EAP-type spesific configuration + * if you need different timeout for your EAP-type. + * Authentication is terminated after this time elapses. + * Time is in milli secons. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_server_session_timeout, + "EAP_CORE_server_session_timeout", + eap_configure_type_u32_t, + false); + + +/** + * This is optional and only valid for server. + * This is boolean configuration option. + * This flag selects whether EAP-Success is send after state notification is forwarded to lower layer (true) + * or EAP-Success is send before state notification is forwarded to lower layer (false). + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_send_eap_success_after_notification, + "EAP_CORE_send_eap_success_after_notification", + eap_configure_type_boolean, + false); + + +/** + * This is u32_t configuration option. + * This is the time after EAP-Failure is handled. + * Zero means EAP-Failure is handled immediately. + * Time is in milli secons. + * The default value is EAP_CORE_FAILURE_RECEIVED_TIMEOUT. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_failure_received_timeout, + "EAP_CORE_failure_received_timeout", + eap_configure_type_u32_t, + false); + + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) +/** + * This is u32_t configuration option. + * This is the maximum time client wait EAP-Request/Identity and EAP-Request/type packets. + * See EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID. + * Time is in milli seconds. + * The default value is EAP_CORE_WAIT_EAP_REQUEST_TYPE_TIMEOUT. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_wait_eap_request_type_timeout, + "EAP_CORE_wait_eap_request_type_timeout", + eap_configure_type_u32_t, + false); + +/** + * This is optional and only valid for server. + * This is boolean configuration option. + * This flag selects whether EAP-Request/Identity is send (true) or not (false). + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_CORE_skip_eap_request_identity, + "EAP_CORE_skip_eap_request_identity", + eap_configure_type_boolean, + false); + +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + +/** @} */ // End of group EAP_Core_config_options. + +//-------------------------------------------------------------------------------------------------- + + +/** + * This is the timer ID used with abs_eap_am_tools_c::set_timer() and abs_eap_am_tools_c::cancel_timer(). + */ +enum eap_core_timer_id +{ + EAP_CORE_TIMER_RETRANSMISSION_ID, ///< This is time after a EAP-Request message is resent again. This is for testing purposes. See USE_EAP_CORE_RETRANSMISSION compilation flag. +#if defined(USE_EAP_CORE_SERVER) + EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID, ///< See EAP_CORE_DELAYED_EAP_NAK_PROCESS_TIMEOUT. +#endif //#if defined(USE_EAP_CORE_SERVER) + EAP_CORE_SESSION_TIMEOUT_ID, ///< See EAP_CORE_TIMER_HANDLER_TIMEOUT_TIMEOUT. + EAP_CORE_FAILURE_RECEIVED_ID, ///< See EAP_CORE_FAILURE_RECEIVED_TIMEOUT. + EAP_CORE_REMOVE_SESSION_TIMEOUT_ID, ///< See EAP_CORE_REMOVE_SESSION_TIMEOUT. +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID, ///< See EAP_CORE_WAIT_EAP_REQUEST_TYPE_TIMEOUT. +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) +}; + +/** + * This is time after a EAP-Failure message is handled. + */ +const u32_t EAP_CORE_FAILURE_RECEIVED_TIMEOUT = 2000ul; + +#if defined(USE_EAP_CORE_SERVER) +/** + * This is time after a EAP-Response/Nak message is processes. + * We could wait if more suitable message is received. + */ +const u32_t EAP_CORE_DELAYED_EAP_NAK_PROCESS_TIMEOUT = 2000u; +#endif //#if defined(USE_EAP_CORE_SERVER) + +/** + * This is the size of the local send buffer. Please use atleast minimum ethernet packet length 60 bytes. + */ +const u32_t EAP_CORE_PACKET_BUFFER_LENGTH = 512u; + + +/** + * Re-transmission is used to test protocols. + * This is the maximum count EAP message is resent again. + * This is used in simulator testing. + * This is configurable parameter. See eap.conf EAP_CORE_retransmission_counter. + */ +const u32_t EAP_CORE_RETRANSMISSION_COUNTER = 5; + +/** + * Re-transmission is used to test protocols. + * This is the time after EAP message is resent again. + * This is used in simulator testing. + * This is configurable parameter. See eap.conf EAP_CORE_retransmission_time. + */ +const u32_t EAP_CORE_RETRANSMISSION_TIME = 1000u; /* milli seconds */ + +/** + * This is the maximum time EAP authentication could succeed. + * Authentication is terminated after this time elapses. + * This is configurable parameter. See eap.conf EAP_CORE_session_timeout. + * See EAP_CORE_SESSION_TIMEOUT_ID. + * Time is in milli seconds. + */ +const u32_t EAP_CORE_SESSION_TIMEOUT = 120000u; /* milli seconds */ + +/** + * This is the delay time after EAP-session is removed after authentication finished. + * This is configurable parameter. + * See EAP_CORE_REMOVE_SESSION_TIMEOUT_ID. + * Time is in milli seconds. + */ +const u32_t EAP_CORE_REMOVE_SESSION_TIMEOUT = 10000ul; /* milli seconds */ + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) +/** + * This is the maximum time client wait EAP-Request/Identity and EAP-Request/type packets. + * See EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID. + * Time is in milli seconds. + */ +const u32_t EAP_CORE_WAIT_EAP_REQUEST_TYPE_TIMEOUT = 5000ul; /* milli seconds */ +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + +#if defined(USE_EAP_CORE_SERVER) +/** + * This is default policy of EAP-Nak message. + * False value means EAP-Nak is prosessed after a timeout. + * True value means EAP-NAk is prosessed immediately. + */ +const bool EAP_CORE_PROCESS_EAP_NAK_IMMEDIATELY = true; +#endif //#if defined(USE_EAP_CORE_SERVER) + + + +/// A eap_core_c class implements the basic functionality of EAP-type. +class EAP_EXPORT eap_core_c +: public abs_eap_core_map_c +, public abs_eap_base_type_c +, public abs_eap_base_timer_c +, public abs_eap_stack_interface_c +{ +private: + //-------------------------------------------------- + + /// This is back pointer to object which created this object. + /// Packets are sent to the partner. + abs_eap_core_c *m_partner; + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This stores eap_base_type objects using eap_variable_data selector. + eap_core_map_c m_type_map; + + /// This stores the current EAP-type. When requested, we send our ID using + /// our default EAP-type. This is our best quess of other peer's EAP-type. + /// Other peer will sent the real EAP-type later and we can NAK it then + /// and send our own EAP-type. This is due the limitations of EAP-protocol. + eap_type_value_e m_current_eap_type; + + /// This is our default EAP-type. + eap_type_value_e m_default_eap_type; + + /// This is the queried EAP-identity. + /// This is saved because other EAP-types may be load afterwards + /// and they may query EAP-identity. + eap_variable_data_c m_eap_identity; + + /// This is offset in bytes of the EAP-type header. + u32_t m_eap_header_offset; + + /// This is maximum transfer unit in bytes. + u32_t m_MTU; + + /// This is length of the trailer in bytes. + u32_t m_trailer_length; + + /// This is network identity of the received packet. + eap_am_network_id_c m_receive_network_id; + + /// Re-transmission is used to test protocols. + /// This stores the information to resent a message. This is used for testing purposes. + eap_core_retransmission_c *m_retransmission; + + /// Re-transmission is used to test protocols. + /// This is the time after resent a message. This is used for testing purposes. + u32_t m_retransmission_time; + + /// Re-transmission is used to test protocols. + /// This is the maximum count of retransmission of one message. This is used for testing purposes. + u32_t m_retransmission_counter; + + /// This is the maximum time authentication could succeed. + /// Authentication is terminated after this time elapses. + /// The EAP-type could change the timeout by calling set_session_timeout() function. + u32_t m_session_timeout; + + u32_t m_eap_core_failure_received_timeout; + + u32_t m_remove_session_timeout; + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + u32_t m_wait_eap_request_type_timeout; + bool m_wait_eap_request_type_timeout_set; +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + /// Latest received EAP-identifier. Used only for EAP-Request/Identity handling in client. + /// Ensures that the EAP-Response/Identity is sent with the latest EAP-identifier. + u8_t m_eap_identity_request_identifier_client; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + /// This indicates whether the authentication role of this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entitys authentication role is EAP-supplicant (true) or EAP-authenticator (false). + /// NOTE the LEAP type changes authentication role during the authentication session. + bool m_is_client_role; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// Client has initiated restart. + bool m_client_restart_authentication_initiated; + + /// This flag indicates that this object is marked to removed asynchronously. + /// The very same object could be taken use before the removing timer elapses. + bool m_marked_removed; + + /// This flag prevents server receiving of multiple EAP-Response/Identity message. + /// This is set true after the server accepts EAP-Response/Identity message. + bool m_eap_identity_response_accepted; + + /// Function shutdown() is called already. + bool m_shutdown_was_called; + + /// Server received EAP-Response from client. Server must not sent any other EAP-type. Server could send EAP-Failure or EAP-Success. + /// Client sent a response. Client must not accept any other EAP-type. + bool m_eap_type_response_sent; + + /// Tells whether this is tunneled EAP-session. For example inside PEAP or TTLS tunnel. + /// This causes some changes to timeouts. + bool m_is_tunneled_eap; + +#if defined(USE_EAP_CORE_SERVER) + /// If this flag is true EAP-Response/Nak is processed immediately. + /// If this flag is false EAP-Response/Nak is processed after a timeout. + /// There might be received more suitable EAP-Response. + bool m_process_eap_nak_immediately; + + /// EAP-Response/Nak is initiated. + bool m_nak_process_timer_active; + + /// This flag prevents server sending of multiple EAP-Request/Identity message. + bool m_eap_identity_request_send; + + /// This is set true after the server receives EAP-Response/Identity message. + bool m_eap_identity_response_received; + + /// This flag is set true after a EAP-Failure is sent. + bool m_eap_failure_sent; + + /// This flag selects whether EAP-Success is send after state notification is forwarded to lower layer (true) + /// or EAP-Success is send before state notification is forwarded to lower layer (false). + bool m_send_eap_success_after_notification; + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + // This flag selects whether EAP-Request/Identity is send (true) or not (false). + bool m_skip_eap_request_identity; +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) +#endif //#if defined(USE_EAP_CORE_SERVER) + + bool m_use_eap_expanded_type; + + /// Some of the protocols terminates with EAP-Failure. This flag tells to ignore EAP-Failure. + bool m_ignore_eap_failure; + + bool m_ignore_notifications; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Re-transmission is used to test protocols. + * This function resends the packet. + */ + EAP_FUNC_IMPORT eap_status_e resend_packet( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_free, + const u32_t retransmission_counter + ); + + /** + * Re-transmission is used to test protocols. + * This function cancels retransmissions. + */ + EAP_FUNC_IMPORT eap_status_e cancel_retransmission(); + + /** + * Re-transmission is used to test protocols. + * This function inits retransmission of sent packet. + */ + EAP_FUNC_IMPORT eap_status_e init_retransmission( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const eap_code_value_e eap_code, + const u8_t eap_identifier, + const eap_type_value_e eap_type + ); + + /** + * This function cancels previous session timeout and initializes new timeout for the session. + */ + EAP_FUNC_IMPORT eap_status_e initialize_session_timeout( + const u32_t session_timeout_ms); + + /** + * This function cancels timeout for a session. + */ + EAP_FUNC_IMPORT eap_status_e cancel_session_timeout(); + + /** + * This function calls shutdown() for one eap_base_type_c object. + */ + EAP_FUNC_IMPORT static eap_status_e shutdown_operation( + eap_base_type_c * const value, + abs_eap_am_tools_c * const m_am_tools); + + /** + * This function calls reset() for one eap_base_type_c object. + */ + EAP_FUNC_IMPORT static eap_status_e reset_operation( + eap_base_type_c * const handler, + abs_eap_am_tools_c * const m_am_tools); + + EAP_FUNC_IMPORT eap_status_e client_proposes_eap_types( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier); + + /** + * This function processes EAP-packet with known EAP-type. + */ + EAP_FUNC_IMPORT eap_status_e packet_process_type( + const eap_type_value_e used_eap_type, + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length); + +#if defined(USE_EAP_CORE_SERVER) + /** + * This function re-starts authentication with new EAP-type. + * Only server calls this function. + */ + EAP_FUNC_IMPORT eap_status_e restart_with_new_type( + const eap_type_value_e used_eap_type, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier); +#endif //#if defined(USE_EAP_CORE_SERVER) + +#if defined(USE_EAP_CORE_SERVER) + EAP_FUNC_IMPORT eap_status_e handle_eap_identity_response( + eap_base_type_c * const handler, + const eap_type_value_e used_eap_type, + const eap_am_network_id_c * const receive_network_id, + eap_header_wr_c * const eap, + const u32_t packet_length); +#endif //#if defined(USE_EAP_CORE_SERVER) + + /** + * This function handles EAP-Request/Identity. + */ + EAP_FUNC_IMPORT eap_status_e handle_eap_identity_request( + const eap_type_value_e used_eap_type, + const u8_t eap_identifier, + const eap_am_network_id_c * const receive_network_id); + + /** + * This function creates EAP-Response/Identity. + */ + EAP_FUNC_IMPORT eap_status_e create_eap_identity_response( + eap_buf_chain_wr_c * const response_packet, + const eap_variable_data_c * const identity, + const u8_t eap_identifier + ); + + /** + * This function sends EAP-Response/Identity. + */ + EAP_FUNC_IMPORT eap_status_e send_eap_identity_response( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const identity, + const u8_t eap_identifier); + + /** + * This function sends EAP-Response/Notification. + */ + EAP_FUNC_IMPORT eap_status_e send_eap_notification_response( + const eap_am_network_id_c * const send_network_id, + const u8_t eap_identifier); + + /** + * This function initializes timeout for received EAP-Failure. + */ + EAP_FUNC_IMPORT eap_status_e set_eap_failure_timeout(); + + /** + * This function cancels timeout for received EAP-Failure. + */ + EAP_FUNC_IMPORT eap_status_e cancel_eap_failure_timeout(); + +#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + eap_status_e set_wait_eap_request_type_timeout(); + + eap_status_e cancel_wait_eap_request_type_timeout(); +#endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) + + EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_eap_session(); + + EAP_FUNC_IMPORT eap_status_e initialize_asynchronous_init_remove_eap_session( + const u32_t remove_session_timeout); + + EAP_FUNC_IMPORT eap_status_e cancel_asynchronous_init_remove_eap_session(); + + eap_status_e init_end_of_session( + const abs_eap_state_notification_c * const state); + + eap_status_e set_eap_identity_routing_info_and_nai_decoration( + eap_variable_data_c * const identity); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_core class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_core_c(); + + /** + * The constructor initializes member attributes using parameters passed to it. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + * @param partner is back pointer to object which created this object. + * @param is_client_when_true indicates whether the network entity should act + * @param is_tunneled_eap tells the EAP is run in tunnel (PEAP or other). + * as a client (true) or server (false), in terms of EAP-protocol + * whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + */ + EAP_FUNC_IMPORT eap_core_c( + abs_eap_am_tools_c * const tools, + abs_eap_core_c * const partner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + const bool is_tunneled_eap); + + /** + * The load_type() function function indicates the lower level to load + * new module including EAP-type. The type parameter is the requested EAP-type. + * @param type is the identifier of the required EAP type. + * @return Function returns pointer to the EAP type object. + */ + EAP_FUNC_IMPORT eap_base_type_c * load_type( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT void trace_eap_packet( + eap_const_string prefix, + const eap_header_wr_c * const eap_header); + + // This is documented in abs_eap_stack_interface_c::packet_process(). + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length); + + // This is documented in abs_eap_base_type_c::packet_send(). + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + /** + * The get_partner() function returns pointer to partner class. + */ + EAP_FUNC_IMPORT abs_eap_core_c * get_partner(); + + /** + * The set_partner() function sets pointer to partner class. + */ + EAP_FUNC_IMPORT void set_partner(abs_eap_core_c * const partner); + + // This is documented in abs_eap_base_type_c::get_header_offset(). + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + // This is documented in abs_eap_base_type_c::load_module(). + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + // This is documented in abs_eap_base_type_c::unload_module(). + EAP_FUNC_IMPORT eap_status_e unload_module( + const eap_type_value_e type); + + /** + * The adaptation module calls the eap_acknowledge() function after + * any Network Protocol packet is received. This is used as a success indication. + * This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + * Mostly there is only one session in the client. + * The server does not need eap_acknowledge() function because + * server (EAP-authenticator) sends the EAP-success message. + */ + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + + // This is documented in abs_eap_base_type_c::restart_authentication(). + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const send_network_id, + const bool is_client_when_true); + + /** + * The EAP Core calls the send_eap_nak_response() function + * when EAP-authentication with requested EAP type is not possible. + * @param receive_network_id includes the addresses (network identity) and packet type. + * @param eap_identifier is the EAP-Identifier to be used with EAP-Nak message. + * @param preferred_eap_type is the acceptable EAP-Type to be informed with an other peer. + */ + EAP_FUNC_IMPORT eap_status_e send_eap_nak_response( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const eap_array_c * const eap_type_list); + + +#if defined(USE_EAP_CORE_SERVER) + + /** + * The EAP Core calls the send_eap_identity_request() function + * when EAP-authentication is needed with another peer. + * @param network_id includes the addresses (network identity) and packet type. + */ + EAP_FUNC_IMPORT eap_status_e send_eap_identity_request( + const eap_am_network_id_c * const network_id); + + /** + * This function sends EAP-Success. + */ + EAP_FUNC_IMPORT eap_status_e send_eap_success( + const eap_am_network_id_c * const send_network_id, + const u8_t eap_identifier); + + /** + * This function sends EAP-Failure. + */ + EAP_FUNC_IMPORT eap_status_e send_eap_failure( + const eap_am_network_id_c * const send_network_id, + const u8_t eap_identifier); + +#endif //#if defined(USE_EAP_CORE_SERVER) + + + // This is documented in abs_eap_base_type_c::packet_data_crypto_keys(). + EAP_FUNC_IMPORT eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ); + + // This is documented in abs_eap_stack_interface_c::configure(). + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is documented in abs_eap_stack_interface_c::shutdown(). + EAP_FUNC_IMPORT eap_status_e shutdown(); + + // This is documented in abs_eap_base_type_c::read_configure(). + EAP_FUNC_IMPORT virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // This is documented in abs_eap_base_type_c::write_configure(). + EAP_FUNC_IMPORT virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // This is documented in abs_eap_stack_interface_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + + // This is documented in abs_eap_stack_interface_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + // This is documented in abs_eap_base_type_c::state_notification(). + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state); + + // See abs_eap_base_timer_c::timer_expired(). + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data); + + // See abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data); + + /** + * eap_core_map_c class increases reference count each time reference to stored object is get. + * Here is always just one state for one session so no references are used. + */ + EAP_FUNC_IMPORT void object_increase_reference_count(); + + /** + * eap_core_map_c class increases reference count each time reference to stored object is get. + * Here is always just one state for one session so no references are used. + */ + EAP_FUNC_IMPORT u32_t object_decrease_reference_count(); + + /** + * @{ Add configuration of accepted EAP-types. } + */ + // This is documented in abs_eap_base_type_c::check_is_valid_eap_type(). + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + // This is commented in abs_eap_base_type_c::get_eap_type_list(). + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + /** + * Gets flag whether this session is marked removed. + * Session is removed later if it is not reused. + */ + EAP_FUNC_IMPORT bool get_marked_removed(); + + /** + * Marks this session removed. + * Session is removed later if it is not reused. + */ + EAP_FUNC_IMPORT void set_marked_removed(); + + /** + * Marks this session not removed. + * Session is not removed it is reused. + */ + EAP_FUNC_IMPORT void unset_marked_removed(); + + /** + * Prevents all notifications. + */ + EAP_FUNC_IMPORT void ignore_notifications(); + + /** + * This function must reset the state of object to same as + * state was after the configure() function call. + * If object reset succeeds this function must return eap_status_ok. + * If object reset fails this function must return corresponding error status. + * @return This function returns the status of reset operation. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + // This is documented in abs_eap_base_type_c::complete_eap_identity_query(). + EAP_FUNC_IMPORT eap_status_e complete_eap_identity_query( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const identity, + const u8_t eap_identifier); + + // This is documented in abs_eap_base_type_c::get_saved_eap_identity(). + EAP_FUNC_IMPORT eap_status_e get_saved_eap_identity(eap_variable_data_c * const identity); + + // This is documented in abs_eap_base_type_c::set_session_timeout(). + EAP_FUNC_IMPORT eap_status_e set_session_timeout( + const u32_t session_timeout_ms); + + // This is documented in abs_eap_base_type_c::set_timer(). + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + // This is documented in abs_eap_base_type_c::cancel_timer(). + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + // This is documented in abs_eap_base_type_c::cancel_all_timers(). + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + // This is documented in abs_eap_base_type_c::set_authentication_role(). + EAP_FUNC_IMPORT eap_status_e set_authentication_role(const bool when_true_set_client); + + // This is documented in abs_eap_base_type_c::add_rogue_ap(). + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + // This is documented in abs_eap_base_type_c::get_is_tunneled(). + EAP_FUNC_IMPORT bool get_is_tunneled_eap() const; + + //-------------------------------------------------- +}; // class eap_core_c + + +#endif //#if !defined(_EAP_CORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_core_map.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_core_map.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,667 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TYPE_MAP_H_) +#define _EAP_TYPE_MAP_H_ + +#include "eap_am_memory.h" +#include "eap_am_export.h" +#include "abs_eap_core_map.h" +#include "eap_variable_data.h" +#include "eap_am_tools.h" + + +const u32_t EAP_MAP_SIZE = 256; + + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning (disable : 4251) +#endif + + +// +template +class EAP_EXPORT eap_state_map_atom_c +{ +private: + + abs_eap_am_tools_c * const m_am_tools; + + Type *m_object; + Selector_Type *m_selector; + eap_state_map_atom_c *m_next_atom; + + bool m_is_valid; + +public: + + // + virtual ~eap_state_map_atom_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: ~eap_state_map_atom_c(): this 0x%08x starts.\n"), + this)); + + if (m_selector != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: ~eap_state_map_atom_c(): delete m_selector starts: selector 0x%08x.\n"), + m_selector)); + + delete m_selector; + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: ~eap_state_map_atom_c(): delete m_selector ends.\n"))); + + m_selector = 0; + } + + if (m_object != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: ~eap_state_map_atom_c(): delete m_object starts: object 0x%08x.\n"), + m_object)); + + delete m_object; + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: ~eap_state_map_atom_c(): delete m_object ends.\n"))); + + m_object = 0; + } + + if (m_next_atom != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: ~eap_state_map_atom_c(): delete m_next_atom starts: next atom 0x%08x.\n"), + m_next_atom)); + + delete m_next_atom; + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: ~eap_state_map_atom_c(): delete m_next_atom ends.\n"))); + + m_next_atom = 0; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + // + eap_state_map_atom_c() + : m_am_tools(0) + , m_object(0) + , m_selector(0) + , m_next_atom(0) + , m_is_valid(false) + { + } + + // + eap_state_map_atom_c( + Selector_Type * const p_selector, + abs_eap_am_tools_c * const tools, + Type * const p_object) + : m_am_tools(tools) + , m_object(p_object) + , m_selector(p_selector) + , m_next_atom(0) + , m_is_valid(false) + { + if (m_am_tools == 0 + || m_am_tools->get_is_valid() == false + || m_object == 0 + || m_selector == 0) + { + return; + } + + set_is_valid(); + } + + // + Type * const get_object() + { + return m_object; + } + + // + const Type * const get_const_object() const + { + return m_object; + } + + // + void set_object(Type * const p_type) + { + m_object = p_type; + } + + const Selector_Type * const get_selector() const + { + return m_selector; + } + + eap_state_map_atom_c * const get_next_atom() const + { + return m_next_atom; + } + + void set_next_atom(eap_state_map_atom_c * const next) + { + m_next_atom = next; + } + + void set_is_valid() + { + m_is_valid = true; + } + + bool get_is_valid() + { + return m_is_valid; + } +}; + + +/// This template class stores the Type identified with Selector_Type. +/** + * A eap_core_map_c template class. + * The eap_core_map_c template class includes an array that is indexed with + * type of Selector_Type parameter. + * @param Type template parameter is the actual type which is stored. + * @param Abs_Type template parameter is the abstract partner type of Type. + * @param Selector_Type template type is the type of the selector object. + * The Selector_Type could be any class that offers three functions with + * the following prototypes: + * @code + * i32_t compare( + * const Selector_Type * const data) const; + * + * u32_t hash( + * const u32_t size) const; + * + * Selector_Type * const copy() const; + * @endcode + * + * The Type could be any class that offers two functions with + * the following prototypes: + * @code + * void object_increase_reference_count(); + * + * u32_t object_decrease_reference_count(); + * + * @endcode + * + */ +template +class EAP_EXPORT eap_core_map_c +{ +private: + //-------------------------------------------------- + + /// This is back pointer to object which created this object. + Abs_Type * const m_partner; + + /// This is hash-table to all objects stored to the eap_core_map object. + /// Objects are stored using the eap_state_map_atom template class. + eap_state_map_atom_c *m_map[EAP_MAP_SIZE]; + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_core_map template class deletes all stored objects. + */ + virtual ~eap_core_map_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + (void) reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + /** + * The constructor initializes attributes using the passed parameters. + * Each pointer of m_map array is initialized null. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + * @param partner is back pointer to object which created this object. + */ + eap_core_map_c( + abs_eap_am_tools_c * const tools, + Abs_Type * const partner) + : m_partner(partner) + , m_am_tools(tools) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + for (u32_t ind = 0u; ind < EAP_MAP_SIZE; ind++) + { + m_map[ind] = 0; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + u32_t get_atom_count() const + { + return EAP_MAP_SIZE; + } + + const eap_state_map_atom_c *get_atom(const u32_t index) const + { + if (index >= EAP_MAP_SIZE) + { + return 0; + } + + return m_map[index]; + } + + /** + * The add_handler() function stores a new type to the eap_core_map object. + * @param p_selector is pointer to a selector object. + * The p_selector object identifies the stored type. + * @param type is pointer to the stored object. + */ + eap_status_e add_handler( + const Selector_Type * const p_selector, + Type * const object) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const u32_t index = p_selector->hash(EAP_MAP_SIZE); + + if (index >= EAP_MAP_SIZE) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_hashed_index); + } + + eap_state_map_atom_c *cursor = m_map[index]; + eap_state_map_atom_c *last_cursor = 0; + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: add_handler(): index %d\n"), + index)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: selector"), + p_selector->get_data(p_selector->get_data_length()), + p_selector->get_data_length())); + + while (cursor != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: add_handler(): cursor 0x%08x\n"), + cursor)); + + if (p_selector->compare(cursor->get_selector()) == 0) + { + // match + break; + } + last_cursor = cursor; + cursor = cursor->get_next_atom(); + } + + if (cursor != 0) + { + // Already exists. + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_exists_error); + } + else + { + eap_state_map_atom_c *atom + = new eap_state_map_atom_c( + p_selector->copy(), m_am_tools, object); + + if (atom == 0 + || atom->get_is_valid() == false) + { + delete atom; + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: add_handler(): atom 0x%08x, object 0x%08x\n"), + atom, + object)); + + if (last_cursor != 0) + { + last_cursor->set_next_atom(atom); + } + else + { + m_map[index] = atom; + } + + object->object_increase_reference_count(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + + /** + * @return The get_handler() function returns a pointer to the type object or NULL. + * @param p_selector is pointer to a selector object. + * The p_selector object identifies the required object. + */ + Type * const get_handler( + const Selector_Type * const p_selector) const + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (p_selector->get_is_valid() == false) + { + return 0; + } + + Type *object = 0; + const u32_t index = p_selector->hash(EAP_MAP_SIZE); + + if (index >= EAP_MAP_SIZE) + { + return 0; + } + + eap_state_map_atom_c *cursor = m_map[index]; + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: get_handler(): index %d\n"), + index)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: selector"), + p_selector->get_data(p_selector->get_data_length()), + p_selector->get_data_length())); + + while (cursor != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: get_handler(): cursor 0x%08x\n"), + cursor)); + + if (p_selector->compare(cursor->get_selector()) == 0) + { + // match + break; + } + + cursor = cursor->get_next_atom(); + } + + if (cursor != 0) + { + object = cursor->get_object(); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: get_handler(): found cursor 0x%08x\n"), + cursor)); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: get_handler(): found object 0x%08x\n"), + object)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: get_handler(): NOT found\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return object; + } + + + /** + * The remove_handler() function removes and deletes the object from MAP. + * @param p_selector is pointer to a selector object. + * @param delete_object tells whether the object is deleted (true) or not (false). + * The p_selector object identifies the removed object. + */ + eap_status_e remove_handler( + const Selector_Type * const p_selector, + const bool delete_object) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const u32_t index = p_selector->hash(EAP_MAP_SIZE); + + if (index >= EAP_MAP_SIZE) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_hashed_index); + } + + eap_state_map_atom_c *cursor = m_map[index]; + eap_state_map_atom_c *last_cursor = 0; + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: remove_handler(): index %d\n"), + index)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: selector"), + p_selector->get_data(p_selector->get_data_length()), + p_selector->get_data_length())); + + while (cursor != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: remove_handler(): cursor 0x%08x\n"), + cursor)); + + if (p_selector->compare(cursor->get_selector()) == 0) + { + if (cursor->get_object()->object_decrease_reference_count() > 0u) + { + // Other users of the EAP-type are still active. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_state_reference_count_not_zero); + } + // match + break; + } + last_cursor = cursor; + cursor = cursor->get_next_atom(); + } + + if (cursor == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: remove_handler(): cursor 0x%08x, object 0x%08x\n"), + cursor, + cursor->get_object())); + + if (last_cursor != 0) + { + last_cursor->set_next_atom(cursor->get_next_atom()); + } + else + { + m_map[index] = cursor->get_next_atom(); + } + cursor->set_next_atom(0); + + if (delete_object == false) + { + // Object will be used on other location. + // We do not delete it here. + cursor->set_object(0); + } + + delete cursor; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + + /** + * The for_each() function runs function for the each object in the MAP. + * @param p_selector is pointer to a selector object. + * The p_selector object identifies the removed object. + */ + eap_status_e for_each( + eap_status_e (*function)( + Type * const value, + abs_eap_am_tools_c * const m_am_tools), + const bool /* do_not_care_errors */) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + u32_t index = 0ul; + + for (index = 0ul; index < EAP_MAP_SIZE; index++) + { + eap_state_map_atom_c *cursor = m_map[index]; + + while (cursor != 0) + { + eap_status_e status = function(cursor->get_object(), m_am_tools); + + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: ERROR: for_each(): cursor 0x%08x, status %d\n"), + cursor, + status)); + } + + cursor = cursor->get_next_atom(); + + } // while() + } // for() + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + bool get_is_valid() + { + return true; + } + + eap_status_e reset() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: eap_core_map_c::reset(): this 0x%08x starts.\n"), + this)); + + for (u32_t ind = 0u; ind < EAP_MAP_SIZE; ind++) + { + if (m_map[ind] != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: eap_core_map_c::reset(): delete m_map[%d], atom 0x%08x starts.\n"), + ind, + m_map[ind])); + + eap_state_map_atom_c *tmp = m_map[ind]; + m_map[ind] = 0; + delete tmp; + + EAP_TRACE_DEBUG( + m_am_tools, + EAP_TRACE_MASK_HASH_MAP, + (EAPL("CORE_MAP: eap_core_map_c::reset(): delete m_map[%d] ends.\n"), + ind)); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + //-------------------------------------------------- +}; // class eap_core_map_c + +#endif //#if !defined(_EAP_TYPE_MAP_H_) + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_core_nak_info.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_core_nak_info.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_CORE_NAK_INFO_H_) +#define _EAP_CORE_NAK_INFO_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_core.h" +#include "eap_base_type.h" +#include "abs_eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_core_map.h" +#include "eap_config.h" +#include "eap_am_network_id.h" +#include "abs_eap_am_mutex.h" +#include "eap_core_retransmission.h" +#include "abs_eap_stack_interface.h" + + +//-------------------------------------------------- + +/** + * This class stores the information of received EAP-Nak. + */ +class eap_core_nak_info_c +: public eap_am_network_id_c +{ + +private: + + eap_type_value_e m_proposed_eap_type; + + u8_t m_eap_identifier; + +public: + + /** + * The destructor of the eap_core_nak_info_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_core_nak_info_c(); + + /** + * The constructor initializes member attributes using parameters passed to it. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + * @param send_network_id is the network identity. + * @param proposed_eap_type is the proposed EAP type. + */ + EAP_FUNC_IMPORT eap_core_nak_info_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + const eap_type_value_e proposed_eap_type, + const u8_t eap_identifier); + + EAP_FUNC_IMPORT eap_type_value_e get_proposed_eap_type() const; + + EAP_FUNC_IMPORT u8_t get_eap_identifier() const; +}; + + +#endif //#if !defined(_EAP_CORE_NAK_INFO_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_core_retransmission.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_core_retransmission.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_GSMSIM_RETRANSMISSION_H_) +#define _GSMSIM_RETRANSMISSION_H_ + +//#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_am_crypto.h" +#include "eap_variable_data.h" + +/** + * This class stores the information of re-transmission of EAP-packet. + * @{ Add more comments. } + */ +class eap_core_retransmission_c +{ +private: + + abs_eap_am_tools_c * const m_am_tools; + + eap_am_network_id_c *m_send_network_id; + eap_buf_chain_wr_c *m_sent_packet; + const u32_t m_header_offset; + const u32_t m_data_length; + + bool m_is_valid; + + u32_t m_retransmission_time; + u32_t m_retransmission_counter; + + eap_code_value_e m_eap_code; + u8_t m_eap_identifier; + eap_type_value_e m_eap_type; + +public: + + EAP_FUNC_IMPORT virtual ~eap_core_retransmission_c(); + + EAP_FUNC_IMPORT eap_core_retransmission_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t retransmission_time, + const u32_t retransmission_counter, + const eap_code_value_e eap_code, + const u8_t eap_identifier, + const eap_type_value_e eap_type); + + EAP_FUNC_IMPORT bool get_is_valid() const; + + EAP_FUNC_IMPORT u32_t get_next_retransmission_counter(); + + EAP_FUNC_IMPORT u32_t get_retransmission_counter() const; + + EAP_FUNC_IMPORT u32_t get_next_retransmission_time(); + + EAP_FUNC_IMPORT eap_am_network_id_c *get_send_network_id(); + + EAP_FUNC_IMPORT eap_buf_chain_wr_c * get_sent_packet() const; + + EAP_FUNC_IMPORT u32_t get_header_offset() const; + + EAP_FUNC_IMPORT u32_t get_data_length() const; + + EAP_FUNC_IMPORT u32_t get_buffer_size() const; + + EAP_FUNC_IMPORT eap_code_value_e get_eap_code() const; + + EAP_FUNC_IMPORT u8_t get_eap_identifier() const; + + EAP_FUNC_IMPORT eap_type_value_e get_eap_type() const; +}; + + +#endif //#if !defined(_GSMSIM_RETRANSMISSION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_crypto_api.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_crypto_api.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2697 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_CRYPTO_API_H_ ) +#define _EAP_CRYPTO_API_H_ + +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "abs_eap_am_crypto.h" +#include "eap_array.h" + +#if defined(des_set_key) +// OpenSSL defines this. +#undef des_set_key +#endif //#if defined(des_set_key) + + +const u32_t HMAC_SHA1_SIZE = 20u; // bytes = 160 bits +const u32_t HMAC_SHA1_128_SIZE = 16u; // bytes = 128 bits +const u32_t HMAC_MD5_SIZE = 20u; // bytes = 160 bits +const u32_t HMAC_MD5_128_SIZE = 16u; // bytes = 128 bits + +const u32_t WPA_PSK_LENGTH = 32; + +/// The abs_crypto_block_algorithm_c class describes interface of CBC block encryption algorithm. +class EAP_EXPORT abs_crypto_cbc_block_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT virtual ~abs_crypto_cbc_block_algorithm_c(); + + /** + * The set_is_valid() function sets the state of the + * abs_crypto_block_algorithm_c object valid. The abs_crypto_block_algorithm_c object + * calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + + /** + * The get_is_valid() function returns the status of the abs_crypto_block_algorithm_c object. + * True indicates the object is initialized. + */ + virtual bool get_is_valid() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The get_encrypts() function returns true when encryption is initialized. + * It returns false when decryption is initialized. + */ + virtual bool get_encrypts() = 0; + + /** + * This function returns the length of AES key in bytes. + */ + virtual u32_t get_key_length() = 0; + + /** + * This function returns the length of AES block size in bytes. + */ + virtual u32_t get_block_size() = 0; + + /** + * Calculates the data length aligned to block size. + */ + virtual u32_t aligned_data_length( + u32_t data_length) = 0; + + /** + * This function returns the internally stored initialization vector. + * The last encrypted and decrypted block is stored to this buffer + * between subsequent encryption and decryption calls. + * User of crypto_cbc_c object could get the last stored block calling this function. + */ + virtual const eap_variable_data_c * get_tmp_IV() = 0; + + /** + * This function adds count padding bytes to buffer. All padding bytes are zero (0x00). + */ + virtual eap_status_e add_padding_bytes( + void * const buffer, + const u32_t buffer_length, + const u8_t padding_byte) = 0; + + /** + * This function checks the count padding bytes of buffer are zero (0x00). + */ + virtual eap_status_e check_padding_bytes( + const void * const buffer, + const u32_t buffer_length, + const u8_t padding_byte) = 0; + + /** + * This function sets the mode to encryption, + * sets the initialization vector and the encryption key. + */ + virtual eap_status_e set_encryption_key( + const void * const encryption_IV, + const u32_t encryption_IV_length, + const void * const key, + const u32_t key_length) = 0; + + /** + * This function sets the mode to decryption, + * sets the initialization vector and the decryption key. + */ + virtual eap_status_e set_decryption_key( + const void * const encryption_IV, + const u32_t encryption_IV_length, + const void * const key, + const u32_t key_length) = 0; + + /** + * This function encrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + virtual eap_status_e encrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length) = 0; + + /** + * This function encrypts continuous data bytes in data_in_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + virtual eap_status_e encrypt_data( + void * const data_in_out, + const u32_t data_length) = 0; + + /** + * This function decrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + virtual eap_status_e decrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length) = 0; + + /** + * This function decrypts continuous data bytes in data_in_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + virtual eap_status_e decrypt_data( + void * const data_in_out, + const u32_t data_length) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The update_non_aligned() function updates the context of + * AES-algorithm with data bytes. The direction (encryption/decryption) + * depends of the initialized context. NOTE the length of data feed in + * separate calls of update_non_aligned() does not need to be + * aligned to AES-block size. Only the sum of whole data must be aligned to AES-block size. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used + * taking advance from separate buffers. + */ + virtual eap_status_e update_non_aligned( + const void * const msg_in, + void * const msg_out, + const u32_t msg_size) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The update_non_aligned() function updates the context of + * AES-algorithm with data bytes. The direction (encryption/decryption) + * depends of the initialized context. NOTE the length of data feed in + * separate calls of update_non_aligned() does not need to be + * aligned to AES-block size. Only the sum of whole data must be aligned to AES-block size. + * This version takes one pointer to buffer. The buffer is used for input and output data. + */ + virtual eap_status_e update_non_aligned( + void * const msg_in_out, + const u32_t msg_size) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The finalize_non_aligned() finalizes the AES-context. + * The sum of length of feed data must be aligned to AES-block size + * before this function is called. + */ + virtual eap_status_e finalize_non_aligned() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - +}; + + + +/// The abs_crypto_block_algorithm_c class describes interface of block encryption algorithm. +class EAP_EXPORT abs_crypto_block_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT virtual ~abs_crypto_block_algorithm_c(); + + /** + * The set_is_valid() function sets the state of the + * abs_crypto_block_algorithm_c object valid. The abs_crypto_block_algorithm_c object + * calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + + /** + * The get_is_valid() function returns the status of the abs_crypto_block_algorithm_c object. + * True indicates the object is initialized. + */ + virtual bool get_is_valid() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The get_encrypts() function returns true when encryption is initialized. + * It returns false when decryption is initialized. + */ + virtual bool get_encrypts() = 0; + + /** + * This function returns the length of key in bytes. + */ + virtual u32_t get_key_length() = 0; + + /** + * This function returns the length of block size in bytes. + */ + virtual u32_t get_block_size() = 0; + + /** + * This function sets the mode to encryption, + * sets the initialization vector and the encryption key. + */ + virtual eap_status_e set_encryption_key( + const void * const key, + const u32_t key_length) = 0; + + /** + * This function sets the mode to decryption, + * sets the initialization vector and the decryption key. + */ + virtual eap_status_e set_decryption_key( + const void * const key, + const u32_t key_length) = 0; + + /** + * This function encrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + virtual eap_status_e encrypt_block( + const void * const data_in, + void * const data_out, + const u32_t data_length) = 0; + + /** + * This function decrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + virtual eap_status_e decrypt_block( + const void * const data_in, + void * const data_out, + const u32_t data_length) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - +}; + + + +/// The abs_crypto_stream_algorithm_c class describes interface of stream encryption algorithm. +class EAP_EXPORT abs_crypto_stream_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT virtual ~abs_crypto_stream_algorithm_c(); + + /** + * The set_is_valid() function sets the state of the + * abs_crypto_block_algorithm_c object valid. The abs_crypto_block_algorithm_c object + * calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + + /** + * The get_is_valid() function returns the status of the abs_crypto_block_algorithm_c object. + * True indicates the object is initialized. + */ + virtual bool get_is_valid() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function sets the key. + */ + virtual eap_status_e set_key( + const eap_variable_data_c * const key) = 0; + + /** + * This function discards desired count of stream. + */ + virtual eap_status_e discard_stream(const u32_t count_of_discarded_octets) = 0; + + /** + * This function encrypts continuous data bytes in data_in_out buffer. + */ + virtual eap_status_e encrypt_data( + void * const data_in_out, + const u32_t data_length) = 0; + + /** + * This function encrypts continuous data bytes from data_in to data_out buffer. + */ + virtual eap_status_e encrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length) = 0; + + /** + * This function encrypts continuous data bytes in data_in_out buffer. + */ + virtual eap_status_e decrypt_data( + void * const data_in_out, + const u32_t data_length) = 0; + + /** + * This function decrypts continuous data bytes from data_in to data_out buffer. + */ + virtual eap_status_e decrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - +}; + + + +/// The abs_crypto_hash_algorithm_c class describes interface the MAC algorithm. +class EAP_EXPORT abs_crypto_hash_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT virtual ~abs_crypto_hash_algorithm_c(); + + /** + * The set_is_valid() function sets the state of the + * abs_crypto_hash_algorithm_c object valid. The abs_crypto_hash_algorithm_c object + * calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + + /** + * The get_is_valid() function returns the status of the abs_crypto_hash_algorithm_c object. + * True indicates the object is initialized. + */ + virtual bool get_is_valid() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of HASH-algorithm. + */ + virtual u32_t get_digest_length() = 0; + + /** + * This function returns the block size of HASH-algorithm. + */ + virtual u32_t get_block_size() = 0; + + /** + * This function sets the mode to encryption, + * sets the initialization vector and the encryption key. + */ + virtual eap_status_e hash_init() = 0; + + /** + * This function updates the context of HASH-algorithm with data. + */ + virtual eap_status_e hash_update( + const void * const data, + const u32_t data_length) = 0; + + /** + * This function writes the message digest to buffer. + * Length is set if md_length_or_null is non-NULL. + */ + virtual eap_status_e hash_final( + void * const message_digest, + u32_t *md_length_or_null) = 0; + + /** + * This function cleans up the HMAC-SHA1 context. + */ + virtual eap_status_e hash_cleanup() = 0; + + /** + * This function returns a copy of the context of HASH-algorithm. + * Caller must free the copy. + */ + virtual abs_crypto_hash_algorithm_c * copy() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - +}; + + +//------------------------------------------------------------ + + +/// The abs_crypto_mac_algorithm_c class describes interface the HMAC algorithm. +class EAP_EXPORT abs_crypto_hmac_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT virtual ~abs_crypto_hmac_algorithm_c(); + + /** + * The set_is_valid() function sets the state of the + * abs_crypto_mac_algorithm_c object valid. The abs_crypto_mac_algorithm_c object + * calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + + /** + * The get_is_valid() function returns the status of the abs_crypto_mac_algorithm_c object. + * True indicates the object is initialized. + */ + virtual bool get_is_valid() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of HMAC-algorithm. + */ + virtual u32_t get_digest_length() = 0; + + /** + * This function sets the mode to encryption, + * sets the initialization vector and the encryption key. + */ + virtual eap_status_e hmac_set_key( + const eap_variable_data_c * const mac_key) = 0; + + /** + * This function updates the context of HMAC-algorithm with data. + */ + virtual eap_status_e hmac_update( + const void * const data, + const u32_t data_length) = 0; + + /** + * This function writes the message digest to buffer. + * Length is set if md_length_or_null is non-NULL. + */ + virtual eap_status_e hmac_final( + void * const message_digest, + u32_t *md_length_or_null) = 0; + + /** + * This function cleans up the HMAC context. + */ + virtual eap_status_e hmac_cleanup() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - +}; + + +//------------------------------------------------------------ + + +/// The crypto_hmac_c class describes HMAC algorithm. +class EAP_EXPORT crypto_hmac_c +: public abs_crypto_hmac_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to the block encryption algorithm. + abs_crypto_hash_algorithm_c * m_crypto_hash_algorithm; + + /// This is the initialized key. + eap_variable_data_c * m_key; + + /// This is the initialized inner pad. + eap_variable_data_c * m_ipad; + + /// This is the initialized outer pad. + eap_variable_data_c * m_opad; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This object must free m_crypto_hash_algorithm when this value is true. + bool m_free_crypto_hash_algorithm; + + + EAP_FUNC_IMPORT eap_status_e initialize_pad( + eap_variable_data_c * const p_pad, + const u8_t pad_value); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_hmac_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_hmac_c( + abs_eap_am_tools_c * const tools, + abs_crypto_hash_algorithm_c * const crypto_hash_algorithm, + const bool free_crypto_hash_algorithm); + + /** + * The set_is_valid() function sets the state of the + * abs_crypto_mac_algorithm_c object valid. The abs_crypto_mac_algorithm_c object + * calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * The get_is_valid() function returns the status of the abs_crypto_mac_algorithm_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of HMAC-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_digest_length(); + + /** + * This function sets the mode to encryption, + * sets the initialization vector and the encryption key. + */ + EAP_FUNC_IMPORT eap_status_e hmac_set_key( + const eap_variable_data_c * const hmac_key); + + /** + * This function updates the context of HMAC-algorithm with data. + */ + EAP_FUNC_IMPORT eap_status_e hmac_update( + const void * const data, + const u32_t data_length); + + /** + * This function writes the message digest to buffer. + * Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e hmac_final( + void * const message_digest, + u32_t *md_length_or_null); + + /** + * This function writes the message digest of HMAC of 128 bits in length to buffer. + * Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e hmac_128_final( + void * const message_digest, + u32_t *md_length_or_null); + + /** + * This function cleans up the HMAC context. + */ + EAP_FUNC_IMPORT eap_status_e hmac_cleanup(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +}; + + +//------------------------------------------------------------ + +/// The crypto_cbc_c class includes the state of +/// one instance of CBC block encryption algorithm. +class EAP_EXPORT crypto_cbc_c +: public abs_crypto_cbc_block_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to the block encryption algorithm. + abs_crypto_block_algorithm_c * m_crypto_block_algorithm; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This stores the initialization vector between subsequent + /// calls of encryption or decryption. + eap_variable_data_c * m_tmp_IV; + + /// This stores the offset of non-aligned data between + /// subsequent calls of encryption or decryption. + i32_t m_encr_offset; + + /// This stores pointers to non-aligned data targets between + /// subsequent calls of encryption or decryption. + u8_t **m_encr_dispatch; + + /// This stores the non-aligned data between subsequent + /// calls of encryption or decryption. + u8_t *m_encr_hold; + + u8_t *m_saved_in_buffer; + u8_t *m_saved_out_buffer; + + u8_t *m_iv_buffer_1; + u8_t *m_iv_buffer_2; + + bool m_free_crypto_block_algorithm; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT void reset(); + + /** + * Run xor to data and IV block. + */ + EAP_FUNC_IMPORT void cbc_xor_block( + const void * const encryption_IV, + void * const data_block, + const u32_t block_size, + const u32_t key_length); + + /** + * Copies source to target. + */ + EAP_FUNC_IMPORT void cbc_copy_block( + void * const target, + const void * const source, + const u32_t block_size, + const u32_t key_length); + + /** + * This function encrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e internal_encrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length); + + /** + * This function decrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e internal_decrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length); + + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_cbc_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_cbc_c( + abs_eap_am_tools_c * const tools, + abs_crypto_block_algorithm_c * const crypto_block_algorithm, + const bool free_crypto_block_algorithm); + + /** + * The get_encrypts() function returns true when encryption is initialized. + * It returns false when decryption is initialized. + */ + EAP_FUNC_IMPORT virtual bool get_encrypts(); + + /** + * This function returns the length of CBC key in bytes. + */ + EAP_FUNC_IMPORT virtual u32_t get_key_length(); + + /** + * This function returns the length of CBC block size in bytes. + */ + EAP_FUNC_IMPORT virtual u32_t get_block_size(); + + /** + * The set_is_valid() function sets the state of the + * crypto_cbc_c object valid. The crypto_cbc_c object + * calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * The get_is_valid() function returns the status of the crypto_cbc_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function returns the internally stored initialization vector. + * The last encrypted and decrypted block is stored to this buffer + * between subsequent encryption and decryption calls. + * User of crypto_cbc_c object could get the last stored block calling this function. + */ + EAP_FUNC_IMPORT const eap_variable_data_c * get_tmp_IV(); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Calculates the data length aligned to block size. + */ + EAP_FUNC_IMPORT u32_t aligned_data_length( + u32_t data_length); + + /** + * This function adds count padding bytes to buffer. All padding bytes are zero (0x00). + */ + EAP_FUNC_IMPORT eap_status_e add_padding_bytes( + void * const buffer, + const u32_t buffer_length, + const u8_t padding_byte); + + /** + * This function checks the count padding bytes of buffer are zero (0x00). + */ + EAP_FUNC_IMPORT eap_status_e check_padding_bytes( + const void * const buffer, + const u32_t buffer_length, + const u8_t padding_byte); + + /** + * This function sets the mode to encryption, + * sets the initialization vector and the encryption key. + */ + EAP_FUNC_IMPORT eap_status_e set_encryption_key( + const void * const encryption_IV, + const u32_t encryption_IV_length, + const void * const key, + const u32_t key_length); + + /** + * This function sets the mode to decryption, + * sets the initialization vector and the decryption key. + */ + EAP_FUNC_IMPORT eap_status_e set_decryption_key( + const void * const encryption_IV, + const u32_t encryption_IV_length, + const void * const key, + const u32_t key_length); + + /** + * This function encrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length); + + /** + * This function encrypts continuous data bytes in data_in_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_data( + void * const data_in_out, + const u32_t data_length); + + /** + * This function decrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length); + + /** + * This function decrypts continuous data bytes in data_in_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_data( + void * const data_in_out, + const u32_t data_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The update_non_aligned() function updates the context of + * CBC-algorithm with data bytes. The direction (encryption/decryption) + * depends of the initialized context. NOTE the length of data feed in + * separate calls of update_non_aligned() does not need to be + * aligned to CBC-block size. Only the sum of whole data must be aligned to CBC-block size. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used + * taking advance from separate buffers. + */ + EAP_FUNC_IMPORT eap_status_e update_non_aligned( + const void * const msg_in, + void * const msg_out, + const u32_t msg_size); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The update_non_aligned() function updates the context of + * CBC-algorithm with data bytes. The direction (encryption/decryption) + * depends of the initialized context. NOTE the length of data feed in + * separate calls of update_non_aligned() does not need to be + * aligned to CBC-block size. Only the sum of whole data must be aligned to CBC-block size. + * This version takes one pointer to buffer. The buffer is used for input and output data. + */ + EAP_FUNC_IMPORT eap_status_e update_non_aligned( + void * const msg_in_out, + const u32_t msg_size); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The finalize_non_aligned() finalizes the CBC-context. + * The sum of length of feed data must be aligned to CBC-block size + * before this function is called. + */ + EAP_FUNC_IMPORT eap_status_e finalize_non_aligned(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +}; + + +//------------------------------------------------------------ + +/// The crypto_aes_c class includes the state of +/// one instance of AES block encryption algorithm. +class EAP_EXPORT crypto_aes_c +: public abs_crypto_block_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// Context is stored to this variable. + /// This hides the whole implementation. + /// This includes the context of AES-block cipher. + /// This depends on the crypto library. + eap_variable_data_c m_aes_context; + + /// This is the used block size. + u32_t m_block_size; + + /// This is set true when encryption is the current mode. + /// Decryption initializes this false. + bool m_encrypt; + + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_aes_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_aes_c(abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT bool get_encrypts(); + + /** + * The set_is_valid() function sets the state of the + * crypto_aes_c object valid. The crypto_aes_c object + * calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * The get_is_valid() function returns the status of the crypto_aes_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function returns the length of AES key in bytes. + */ + EAP_FUNC_IMPORT u32_t get_key_length(); + + /** + * This function returns the length of AES block size in bytes. + */ + EAP_FUNC_IMPORT u32_t get_block_size(); + + + /** + * This function sets the mode to encryption, + * sets the initialization vector and the encryption key. + */ + EAP_FUNC_IMPORT eap_status_e set_encryption_key( + const void * const key, + const u32_t key_length); + + /** + * This function sets the mode to decryption, + * sets the initialization vector and the decryption key. + */ + EAP_FUNC_IMPORT eap_status_e set_decryption_key( + const void * const key, + const u32_t key_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function encrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_block( + const void * const data_in, + void * const data_out, + const u32_t data_length); + + /** + * This function decrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_block( + const void * const data_in, + void * const data_out, + const u32_t data_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - +}; + + +//------------------------------------------------------------ + +/// The crypto_3des_ede_c class includes the state of +/// one instance of 3DES-EDE block encryption algorithm. +class EAP_EXPORT crypto_3des_ede_c +: public abs_crypto_block_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// Context is stored to this variable. + /// This hides the whole implementation. + /// This includes the context of 3DES-EDE-block cipher. + /// This depends on the crypto library. + eap_variable_data_c m_context; + + /// This is the used block size. + u32_t m_block_size; + + /// This is set true when encryption is the current mode. + /// Decryption initializes this false. + bool m_encrypt; + + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_3des_ede_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_3des_ede_c(abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT bool get_encrypts(); + + /** + * The set_is_valid() function sets the state of the + * crypto_3des_ede_c object valid. The crypto_3des_ede_c object + * calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * The get_is_valid() function returns the status of the crypto_3des_ede_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function returns the length of 3DES-EDE key in bytes. + */ + EAP_FUNC_IMPORT u32_t get_key_length(); + + /** + * This function returns the length of 3DES-EDE block size in bytes. + */ + EAP_FUNC_IMPORT u32_t get_block_size(); + + + /** + * This function sets the mode to encryption, + * sets the initialization vector and the encryption key. + */ + EAP_FUNC_IMPORT eap_status_e set_encryption_key( + const void * const key, + const u32_t key_length); + + /** + * This function sets the mode to decryption, + * sets the initialization vector and the decryption key. + */ + EAP_FUNC_IMPORT eap_status_e set_decryption_key( + const void * const key, + const u32_t key_length); + + /** + * This function encrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_block( + const void * const data_in, + void * const data_out, + const u32_t data_length); + + /** + * This function decrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_block( + const void * const data_in, + void * const data_out, + const u32_t data_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - +}; + + +//------------------------------------------------------------ + + +const u8_t EAP_CRYPTO_AES_WRAP_DEFAULT_INITIAL_IV[] = { + 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, + }; + +const u64_t EAP_CRYPTO_AES_WRAP_BLOCK_SIZE = sizeof(u64_t); + + +/// The crypto_aes_wrap_c class describes interface of block encryption algorithm. +class EAP_EXPORT crypto_aes_wrap_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is the AES the block encryption algorithm. + crypto_aes_c m_aes; + + eap_variable_data_c m_key; + + /// This is set true when encryption is the current mode. + /// Decryption initializes this false. + bool m_encrypt; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT virtual ~crypto_aes_wrap_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_aes_wrap_c(abs_eap_am_tools_c * const tools); + + /** + * The set_is_valid() function sets the state of the + * crypto_aes_wrap_c object valid. The crypto_aes_wrap_c object + * calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * The get_is_valid() function returns the status of the crypto_aes_wrap_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The get_encrypts() function returns true when encryption is initialized. + * It returns false when decryption is initialized. + */ + EAP_FUNC_IMPORT bool get_encrypts(); + + /** + * This function returns the length of key in bytes. + */ + EAP_FUNC_IMPORT u32_t get_key_length(); + + /** + * This function returns the length of block size in bytes. + */ + EAP_FUNC_IMPORT u32_t get_block_size(); + + /** + * This function sets the mode to encryption, + * sets the initialization vector and the encryption key. + */ + EAP_FUNC_IMPORT eap_status_e set_encryption_key( + const void * const key, + const u32_t key_length); + + /** + * This function sets the mode to decryption, + * sets the initialization vector and the decryption key. + */ + EAP_FUNC_IMPORT eap_status_e set_decryption_key( + const void * const key, + const u32_t key_length); + + /** + * This function adds buffer_length padding bytes to buffer. + */ + EAP_FUNC_IMPORT eap_status_e add_padding_bytes( + void * const buffer, + const u32_t buffer_length); + + /** + * This function encrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_block( + const void * const data_in, + const u32_t data_in_length, + void * const data_out, + const u32_t data_out_length); + + /** + * This function decrypts continuous data bytes from data_in to data_out buffer. + * Note the length of the data must be aligned to block size of the cipher. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_block( + const void * const data_in, + const u32_t data_in_length, + void * const data_out, + const u32_t data_out_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - +}; + + + +//------------------------------------------------------------ + +/// The crypto_random_c class includes the state of +/// one instance of random generator. +class EAP_EXPORT crypto_random_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~crypto_random_c(); + + /** + * Constructor initializes the object. + */ + EAP_FUNC_IMPORT crypto_random_c(abs_eap_am_tools_c * const tools); + + /** + * The set_is_valid() function sets the state of the crypto_random_c object valid. + * The crypto_random_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * The get_is_valid() function returns the status of the crypto_random_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function copies count random bytes to buffer. + */ + EAP_FUNC_IMPORT eap_status_e get_rand_bytes( + void * const buffer, + const u32_t count); + + /** + * This function copies count random bytes to buffer. + */ + EAP_FUNC_IMPORT eap_status_e get_rand_bytes( + eap_variable_data_c * const buffer, + const u32_t count); + + /** + * This function creates random integer value between minimum and maximum inclusively. + */ + EAP_FUNC_IMPORT u32_t get_rand_integer( + const u32_t minimum, + const u32_t maximum); + + /** + * This function seeds the random generator with count bytes from buffer. + * User could call this function as many times as is needed and at any time. + */ + EAP_FUNC_IMPORT eap_status_e add_rand_seed( + const void * const buffer, + const u32_t count); + + /** + * This function seeds random generator with the hardware ticks. + * User could call this function as many times as is needed and at any time. + */ + EAP_FUNC_IMPORT eap_status_e add_rand_seed_hw_ticks(); + +}; + + +//------------------------------------------------------------ + +/// The crypto_sha_256_c class includes the state of +/// one instance of SHA-256 algorithm. +class EAP_EXPORT crypto_sha_256_c +: public abs_crypto_hash_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// Context is stored to this variable. + /// This hides the whole implementation. + /// includes the context of the SHA-256 algorithm. + /// This depends on the crypto library. + eap_variable_data_c m_sha_256_context; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_sha_256_c object invalid. + * The crypto_sha_256_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_sha_256_c object valid. + * The crypto_sha_256_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_sha_256_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_sha_256_c(abs_eap_am_tools_c * const tools); + + /** + * This function copies the context from parameter sha_256_context to this object. + */ + EAP_FUNC_IMPORT eap_status_e copy_context(const eap_variable_data_c * const sha_256_context); + + /** + * The get_is_valid() function returns the status of the crypto_sha_256_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function returns the size of message digest of SHA-256-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_digest_length(); + + /** + * This function returns the block size of SHA-256-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_block_size(); + + /** + * This function initializes the context of SHA-256-algorithm. + */ + EAP_FUNC_IMPORT eap_status_e hash_init(); + + /** + * This function updates the context of SHA-256-algorithm with data. + */ + EAP_FUNC_IMPORT eap_status_e hash_update( + const void * const data, + const u32_t data_length); + + /** + * This function writes the message digest to buffer. + * @param Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e hash_final( + void * const message_digest, + u32_t *md_length_or_null); + + /** + * This function cleans up the SHA-256 context. + */ + EAP_FUNC_IMPORT eap_status_e hash_cleanup(); + + /** + * This function returns a copy of the context of SHA-256-algorithm. + * Caller must free the copy. + */ + EAP_FUNC_IMPORT abs_crypto_hash_algorithm_c * copy(); +}; + + +//------------------------------------------------------------ + +/// The crypto_sha1_c class includes the state of +/// one instance of SHA1 algorithm. +class EAP_EXPORT crypto_sha1_c +: public abs_crypto_hash_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// Context is stored to this variable. + /// This hides the whole implementation. + /// includes the context of the SHA1 algorithm. + /// This depends on the crypto library. + eap_variable_data_c m_sha1_context; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_sha1_c object invalid. + * The crypto_sha1_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_sha1_c object valid. + * The crypto_sha1_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_sha1_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_sha1_c(abs_eap_am_tools_c * const tools); + + /** + * This function copies the context from parameter sha1_context to this object. + */ + EAP_FUNC_IMPORT eap_status_e copy_context(const eap_variable_data_c * const sha1_context); + + /** + * The get_is_valid() function returns the status of the crypto_sha1_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function returns the size of message digest of SHA1-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_digest_length(); + + /** + * This function returns the block size of SHA1-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_block_size(); + + /** + * This function initializes the context of SHA1-algorithm. + */ + EAP_FUNC_IMPORT eap_status_e hash_init(); + + /** + * This function updates the context of SHA1-algorithm with data. + */ + EAP_FUNC_IMPORT eap_status_e hash_update( + const void * const data, + const u32_t data_length); + + /** + * This function writes the message digest to buffer. + * @param Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e hash_final( + void * const message_digest, + u32_t *md_length_or_null); + + /** + * This function cleans up the SHA1 context. + */ + EAP_FUNC_IMPORT eap_status_e hash_cleanup(); + + /** + * This function returns a copy of the context of SHA1-algorithm. + * Caller must free the copy. + */ + EAP_FUNC_IMPORT abs_crypto_hash_algorithm_c * copy(); +}; + + +//------------------------------------------------------------ + +/// The crypto_ephemeral_diffie_hellman_c class includes +/// the state of one instance of ephemeral Diffie-Hellman key exchange algorithm. +class EAP_EXPORT crypto_ephemeral_diffie_hellman_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_ephemeral_diffie_hellman_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_ephemeral_diffie_hellman_c(abs_eap_am_tools_c * const tools); + + /** + * The set_is_valid() function sets the state of the crypto_ephemeral_diffie_hellman_c + * object valid. The crypto_ephemeral_diffie_hellman_c object calls this function + * after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * The get_is_valid() function returns the status of the crypto_ephemeral_diffie_hellman_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function creates the private and public keys using the prime and generator. + * Returns context in dh_context. It must be given to generate_g_power_to_xy and + * dh_cleanup. + */ + EAP_FUNC_IMPORT eap_status_e generate_diffie_hellman_keys( + eap_variable_data_c * const dh_context, + eap_variable_data_c * const own_public_dh_key, + const void * const prime, + const u32_t prime_length, + const void * const group_generator, + const u32_t group_generator_length); + + /** + * This function creates the shared Diffie-Hellman key using own private key, + * peer public key, prime and group generator. + */ + EAP_FUNC_IMPORT eap_status_e generate_g_power_to_xy( + const eap_variable_data_c * const dh_context, + const eap_variable_data_c * const peer_public_dh_key, + eap_variable_data_c * const shared_dh_key, + const void * const prime, + const u32_t prime_length, + const void * const group_generator, + const u32_t group_generator_length); + + EAP_FUNC_IMPORT eap_status_e dh_cleanup( + const eap_variable_data_c * const dh_context); + +}; + +//------------------------------------------------------------ + +/// The crypto_sha1_c class includes the state of +/// one instance of MD5 algorithm. +class EAP_EXPORT crypto_md5_c +: public abs_crypto_hash_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// Context is stored to this variable. + /// This hides the whole implementation. + /// includes the context of the MD5 algorithm. + /// This depends on the crypto library. + eap_variable_data_c m_md5_context; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_md5_c object invalid. + * The crypto_md5_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_md5_c object valid. + * The crypto_md5_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_md5_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_md5_c(abs_eap_am_tools_c * const tools); + + /** + * This function copies the context from parameter sha1_context to this object. + */ + EAP_FUNC_IMPORT eap_status_e copy_context(const eap_variable_data_c * const sha1_context); + + /** + * The get_is_valid() function returns the status of the crypto_md5_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function returns the size of message digest of MD5-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_digest_length(); + + /** + * This function returns the block size of MD5-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_block_size(); + + /** + * This function initializes the context of MD5-algorithm. + */ + EAP_FUNC_IMPORT eap_status_e hash_init(); + + /** + * This function updates the context of MD5-algorithm with data. + */ + EAP_FUNC_IMPORT eap_status_e hash_update( + const void * const data, + const u32_t data_length); + + /** + * This function writes the message digest to buffer. + * @param Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e hash_final( + void * const message_digest, + u32_t *md_length_or_null); + + /** + * This function cleans up the MD5 context. + */ + EAP_FUNC_IMPORT eap_status_e hash_cleanup(); + + /** + * This function returns a copy of the context of MD5-algorithm. + * Caller must free the copy. + */ + EAP_FUNC_IMPORT abs_crypto_hash_algorithm_c * copy(); +}; + + +//------------------------------------------------------------ + +/// The crypto_sha1_c class includes the state of +/// one instance of MD4 algorithm. +class EAP_EXPORT crypto_md4_c +: public abs_crypto_hash_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// Context is stored to this variable. + /// This hides the whole implementation. + /// includes the context of the MD4 algorithm. + /// This depends on the crypto library. + eap_variable_data_c m_md4_context; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_md4_c object invalid. + * The crypto_md4_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_md4_c object valid. + * The crypto_md4_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_md4_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_md4_c(abs_eap_am_tools_c * const tools); + + /** + * This function copies the context from parameter sha1_context to this object. + */ + EAP_FUNC_IMPORT eap_status_e copy_context(const eap_variable_data_c * const sha1_context); + + /** + * The get_is_valid() function returns the status of the crypto_md4_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function returns the size of message digest of MD4-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_digest_length(); + + /** + * This function returns the block size of MD4-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_block_size(); + + /** + * This function initializes the context of MD4-algorithm. + */ + EAP_FUNC_IMPORT eap_status_e hash_init(); + + /** + * This function updates the context of MD4-algorithm with data. + */ + EAP_FUNC_IMPORT eap_status_e hash_update( + const void * const data, + const u32_t data_length); + + /** + * This function writes the message digest to buffer. + * @param Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e hash_final( + void * const message_digest, + u32_t *md_length_or_null); + + /** + * This function cleans up the MD4 context. + */ + EAP_FUNC_IMPORT eap_status_e hash_cleanup(); + + /** + * This function returns a copy of the context of MD4-algorithm. + * Caller must free the copy. + */ + EAP_FUNC_IMPORT abs_crypto_hash_algorithm_c * copy(); +}; + + +//------------------------------------------------------------ +/// The crypto_rc4_c class includes the state of +/// one instance of RC4 algorithm. +class EAP_EXPORT crypto_rc4_c +: public abs_crypto_stream_algorithm_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// Context is stored to this variable. + /// This hides the whole implementation. + /// includes the context of the RC4 algorithm. + /// This depends on the crypto library. + eap_variable_data_c m_rc4_context; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_rc4_c object invalid. + * The crypto_rc4_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_rc4_c object valid. + * The crypto_rc4_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_rc4_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_rc4_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the crypto_rc4_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function sets the RC4 key. + */ + EAP_FUNC_IMPORT eap_status_e set_key(const eap_variable_data_c * const key); + + /** + * This function discards desired count of RC4 stream. + */ + EAP_FUNC_IMPORT eap_status_e discard_stream(const u32_t count_of_discarded_octets); + + /** + * This function encrypts continuous data bytes in data_in_out buffer. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_data( + void * const data_in_out, + const u32_t data_length); + + /** + * This function does RC4 encryption. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length); + + /** + * This function decrypts continuous data bytes in data_in_out buffer. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_data( + void * const data_in_out, + const u32_t data_length); + + /** + * This function does RC4 decryption. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_data( + const void * const data_in, + void * const data_out, + const u32_t data_length); + +}; + +//------------------------------------------------------------ + +/// The crypto_tls_base_prf_c class includes the state of +/// one instance of TLS-PRF base algorithms. +class EAP_EXPORT crypto_tls_base_prf_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_tls_base_prf_c object invalid. + * The crypto_tls_base_prf_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_tls_base_prf_c object valid. + * The crypto_tls_base_prf_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_tls_base_prf_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_tls_base_prf_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the crypto_tls_base_prf_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT eap_status_e tls_prf_A_value( + abs_crypto_hmac_algorithm_c * const hash, + eap_variable_data_c * const key, + eap_variable_data_c * const seed, + eap_variable_data_c * const A_md5_output); + + EAP_FUNC_IMPORT eap_status_e tls_prf_one_round( + abs_crypto_hmac_algorithm_c * const hash, + const eap_variable_data_c * const key, + eap_variable_data_c * const A_input, + eap_variable_data_c * const seed, + void * const out_buffer, + const u32_t out_buffer_length); + + /** + * This function cleans up the TLS-PRF context. + */ + EAP_FUNC_IMPORT eap_status_e tls_prf_cleanup(); + +}; + +//------------------------------------------------------------ + +/// The crypto_tls_sha1_prf_c class includes the state of +/// one instance of TLS-PRF SHA1 algorithm. +/// This is needed because compound authentication +/// binding of PEAP does use only P_SHA-1 for generating +/// compound keyed MACs and the compound session keys. +class EAP_EXPORT crypto_tls_sha1_prf_c +: public crypto_tls_base_prf_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + crypto_hmac_c * m_sha1_context; + crypto_hmac_c * m_A_sha1_context; + + eap_variable_data_c m_sha1_key; + + eap_variable_data_c m_seed; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_tls_sha1_prf_c object invalid. + * The crypto_tls_sha1_prf_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_tls_sha1_prf_c object valid. + * The crypto_tls_sha1_prf_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_tls_sha1_prf_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_tls_sha1_prf_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the crypto_tls_sha1_prf_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function initializes the context of TLS-PRF algorithm using the key. + */ + EAP_FUNC_IMPORT eap_status_e tls_prf_init( + const eap_variable_data_c * const secret, + const eap_variable_data_c * const label, + const eap_variable_data_c * const seed); + + /** + * This function writes the message digest to buffer. + * Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e tls_prf_output( + void * const pseudo_random_data, + const u32_t pseudo_random_data_length); + + /** + * This function cleans up the TLS-PRF context. + */ + EAP_FUNC_IMPORT eap_status_e tls_prf_cleanup(); + +}; + +//------------------------------------------------------------ + +/// The crypto_tls_md5_prf_c class includes the state of +/// one instance of TLS-PRF MD5 algorithm. +class EAP_EXPORT crypto_tls_md5_prf_c +: public crypto_tls_base_prf_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + crypto_hmac_c * m_md5_context; + crypto_hmac_c * m_A_md5_context; + + eap_variable_data_c m_md5_key; + + eap_variable_data_c m_seed; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_tls_md5_prf_c object invalid. + * The crypto_tls_md5_prf_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_tls_md5_prf_c object valid. + * The crypto_tls_md5_prf_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_tls_md5_prf_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_tls_md5_prf_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the crypto_tls_md5_prf_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function initializes the context of TLS-PRF algorithm using the key. + */ + EAP_FUNC_IMPORT eap_status_e tls_prf_init( + const eap_variable_data_c * const secret, + const eap_variable_data_c * const label, + const eap_variable_data_c * const seed); + + /** + * This function writes the message digest to buffer. + * Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e tls_prf_output( + void * const pseudo_random_data, + const u32_t pseudo_random_data_length); + + /** + * This function cleans up the TLS-PRF context. + */ + EAP_FUNC_IMPORT eap_status_e tls_prf_cleanup(); + +}; + +//------------------------------------------------------------ + +/// The crypto_tls_prf_c class includes the state of +/// one instance of TLS-PRF algorithm. +class EAP_EXPORT crypto_tls_prf_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + crypto_tls_md5_prf_c * m_tls_md5_prf; + crypto_tls_sha1_prf_c * m_tls_sha1_prf; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_tls_prf_c object invalid. + * The crypto_tls_prf_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_tls_prf_c object valid. + * The crypto_tls_prf_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_tls_prf_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_tls_prf_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the crypto_tls_prf_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function initializes the context of TLS-PRF algorithm using the key. + */ + EAP_FUNC_IMPORT eap_status_e tls_prf_init( + const eap_variable_data_c * const secret, + const eap_variable_data_c * const label, + const eap_variable_data_c * const seed); + + /** + * This function writes the message digest to buffer. + * Length is set if md_length_or_null is non-NULL. + */ + EAP_FUNC_IMPORT eap_status_e tls_prf_output( + void * const pseudo_random_data, + const u32_t pseudo_random_data_length); + + /** + * This function cleans up the TLS-PRF context. + */ + EAP_FUNC_IMPORT eap_status_e tls_prf_cleanup(); + +}; + +//------------------------------------------------------------ + + +/// The crypto_eap_fast_hmac_sha1_prf_c class includes the state of +/// one instance of T-PRF algorithm used in EAP-FAST. +class EAP_EXPORT crypto_eap_fast_hmac_sha1_prf_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + crypto_hmac_c * m_context; + + eap_variable_data_c m_key; + + eap_variable_data_c m_S_value; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_eap_fast_hmac_sha1_prf_c object invalid. + * The crypto_eap_fast_hmac_sha1_prf_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_eap_fast_hmac_sha1_prf_c object valid. + * The crypto_eap_fast_hmac_sha1_prf_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_eap_fast_hmac_sha1_prf_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_eap_fast_hmac_sha1_prf_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the crypto_eap_fast_hmac_sha1_prf_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function initializes the context of T-PRF algorithm using the key. + */ + EAP_FUNC_IMPORT eap_status_e t_prf_init( + const eap_variable_data_c * const key, + const eap_variable_data_c * const label, + const eap_variable_data_c * const seed); + + /** + * This function writes the message digest to buffer. + */ + EAP_FUNC_IMPORT eap_status_e t_prf_output( + void * const pseudo_random_data, + const u16_t pseudo_random_data_length); + + /** + * This function cleans up the T-PRF context. + */ + EAP_FUNC_IMPORT eap_status_e t_prf_cleanup(); + +}; + + +//------------------------------------------------------------ + +/// The crypto_tls_prf_c class includes the state of +/// one instance of RSA algorithm. +class EAP_EXPORT crypto_rsa_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// Context is stored to this variable. + /// This hides the whole implementation. + /// Includes the context of the RSA algorithm. + /// This depends on the crypto library. + eap_variable_data_c m_context; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_rsa_c object invalid. + * The crypto_rsa_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_rsa_c object valid. + * The crypto_rsa_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_rsa_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_rsa_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the crypto_rsa_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function initializes the context of RSA algorithm using the key. + */ + EAP_FUNC_IMPORT eap_status_e init(); + + EAP_FUNC_IMPORT eap_status_e encrypt_with_public_key( + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + EAP_FUNC_IMPORT eap_status_e decrypt_with_public_key( + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + EAP_FUNC_IMPORT eap_status_e encrypt_with_private_key( + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + EAP_FUNC_IMPORT eap_status_e decrypt_with_private_key( + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + EAP_FUNC_IMPORT eap_status_e sign( + const eap_variable_data_c * const private_dsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash); + + EAP_FUNC_IMPORT eap_status_e verify( + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash); + + /** + * This function cleans up the RSA context. + */ + EAP_FUNC_IMPORT eap_status_e cleanup(); + +}; + +//------------------------------------------------------------ + +/// The crypto_tls_prf_c class includes the state of +/// one instance of DSA algorithm. +class EAP_EXPORT crypto_dsa_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// Context is stored to this variable. + /// This hides the whole implementation. + /// Includes the context of the DSA algorithm. + /// This depends on the crypto library. + eap_variable_data_c m_context; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_dsa_c object invalid. + * The crypto_dsa_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_dsa_c object valid. + * The crypto_dsa_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_dsa_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_dsa_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the crypto_dsa_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function initializes the context of DSA algorithm using the key. + */ + EAP_FUNC_IMPORT eap_status_e init(); + + EAP_FUNC_IMPORT eap_status_e sign( + const eap_variable_data_c * const private_dsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash); + + EAP_FUNC_IMPORT eap_status_e verify( + const eap_variable_data_c * const public_dsa_key, + const eap_variable_data_c * const dsa_param_p, + const eap_variable_data_c * const dsa_param_q, + const eap_variable_data_c * const dsa_param_g, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash); + + /** + * This function cleans up the DSA context. + */ + EAP_FUNC_IMPORT eap_status_e cleanup(); + +}; + +//------------------------------------------------------------ + +/// The crypto_wpa_psk_password_hash_c class includes the functions for +/// generating WPA PSK from an ASCII password +class EAP_EXPORT crypto_wpa_psk_password_hash_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_rc4_c object invalid. + * The crypto_rc4_c object calls this function after it is initialized. + */ + void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_rc4_c object valid. + * The crypto_rc4_c object calls this function after it is initialized. + */ + void set_is_valid(); + + /** + * Calculates the PSK hash from an ASCII password + */ + eap_status_e password_hash_F( + const eap_variable_data_c * const password, + const eap_variable_data_c * const ssid, + u32_t iterations, + u32_t count, + eap_variable_data_c * const output, + void * object, + eap_status_e (*progress_callback)(void*, u32_t)); + + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_wpa_psk_password_hash_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_wpa_psk_password_hash_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the crypto_wpa_psk_password_hash object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * Calculates the PSK hash from an ASCII password + */ + EAP_FUNC_IMPORT eap_status_e password_hash( + const eap_variable_data_c * const password, + const eap_variable_data_c * const ssid, + eap_variable_data_c * const output, + void * object = 0, + eap_status_e (*progress_callback)(void*, u32_t) = 0); + +}; + +//------------------------------------------------------------ + +/// The crypto_wpa_psk_password_hash_c class includes the functions for +/// generating WPA PSK from an ASCII password +class EAP_EXPORT crypto_nt_hash_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_rc4_c object invalid. + * The crypto_rc4_c object calls this function after it is initialized. + */ + void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_rc4_c object valid. + * The crypto_rc4_c object calls this function after it is initialized. + */ + void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_nt_hash_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_nt_hash_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the crypto_wpa_psk_password_hash object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT eap_status_e nt_password_hash( + const eap_variable_data_c * const password_utf8, + eap_variable_data_c * const password_hash, + const u32_t digest_size); + + EAP_FUNC_IMPORT eap_status_e hash_nt_password_hash( + const eap_variable_data_c * const password_hash, + eap_variable_data_c * const password_hash_hash, + const u32_t digest_size); + + /* RFC 3079 */ + + EAP_FUNC_IMPORT eap_status_e get_master_key( + const eap_variable_data_c * const password_hash_hash, + const eap_variable_data_c * const nt_response, + eap_variable_data_c * const master_key, + const u32_t in_master_key_length); + + EAP_FUNC_IMPORT eap_status_e get_asymmetric_start_key( + const eap_variable_data_c * const in_master_key, + eap_variable_data_c * const out_session_key, + const u32_t in_session_key_length, + const bool in_is_send, + const bool in_is_server); + + EAP_FUNC_IMPORT eap_status_e get_new_key_from_sha( + const eap_variable_data_c * const in_start_key, + const eap_variable_data_c * const in_session_key, + eap_variable_data_c * const out_interim_key, + const u32_t in_interim_key_length); + +}; + +//------------------------------------------------------------ + +/// The crypto_kd_hmac_sha256_c class includes the functions for +/// KD-HMAC-SHA256. +class EAP_EXPORT crypto_kd_hmac_sha256_c +{ + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_invalid() function sets the state of the crypto_kd_hmac_sha256_c object invalid. + * The crypto_kd_hmac_sha256_c object calls this function after it is initialized. + */ + void set_is_invalid(); + + /** + * The set_is_valid() function sets the state of the crypto_kd_hmac_sha256_c object valid. + * The crypto_kd_hmac_sha256_c object calls this function after it is initialized. + */ + void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor resets the used internal buffers. + */ + EAP_FUNC_IMPORT virtual ~crypto_kd_hmac_sha256_c(); + + /** + * Constructor initializes the used internal buffers. + */ + EAP_FUNC_IMPORT crypto_kd_hmac_sha256_c(abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the crypto_kd_hmac_sha256_c object. + * True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT eap_status_e expand_key( + eap_variable_data_c * const output, + const u32_t required_output_size, + const eap_variable_data_c * const key, + const eap_variable_data_c * const label + ); +}; + +//------------------------------------------------------------ + +#endif //#if !defined( _EAP_CRYPTO_API_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_expanded_type.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_expanded_type.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,307 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined(_EAP_EXPANDED_TYPE_H_) +#define _EAP_EXPANDED_TYPE_H_ + + +#include "eap_general_header_base.h" + + +/** @file */ + +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- + +/// Enumeration of the EAP-Code values. +enum eap_code_value_e +{ + eap_code_none = 0, ///< This is internal value for no type case. + eap_code_request = 1, ///< This is EAP-Request. + eap_code_response = 2, ///< This is EAP-Response. + eap_code_success = 3, ///< This is EAP-Success. + eap_code_failure = 4, ///< This is EAP-Failure. +}; + + +#if defined(USE_EAP_EXPANDED_TYPES) +/// Enumeration of the IETF defined EAP-Type values. +enum eap_type_ietf_values_e +#else +/// This is the original enumeration of the EAP-Type values. +enum eap_type_value_e +#endif //#if defined(USE_EAP_EXPANDED_TYPES) +{ + eap_type_none = 0, ///< This is internal value for no type case. + eap_type_identity = 1, ///< This is Identity. + eap_type_notification = 2, ///< This is Notification. + eap_type_nak = 3, ///< This is Nak. + eap_type_md5_challenge = 4, ///< This is EAP-MD5 type. + eap_type_one_time_password = 5, ///< This is One Time Password (OTP) type. + eap_type_generic_token_card = 6, ///< This is Generic Token Card (GTC) type. + eap_type_tls = 13, ///< This is Transport Layer Security (TLS) type. + eap_type_leap = 17, ///< This is LEAP type. + eap_type_gsmsim = 18, ///< This is SIM type. + eap_type_ttls = 21, ///< This is tunneled TLS. + eap_type_aka = 23, ///< This is AKA type. + eap_type_peap = 25, ///< This is PEAP type. + eap_type_mschapv2 = 26, ///< This is MsChapv2 type. + eap_type_securid = 32, ///< This is SecurID type. + eap_type_tlv_extensions = 33, ///< This is type/length/value extension type for PEAP payloads. +#if defined(USE_FAST_EAP_TYPE) + eap_type_fast = 43, ///< This is EAP-FAST type. +#endif //#if defined(USE_FAST_EAP_TYPE) + + eap_type_ttls_plain_pap = 98, // This is for TTLS/PAP. + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + eap_type_plain_mschapv2 = 99, ///< This is used to indicate plain MSChapv2 inside TTLS tunnel. +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + eap_type_saesim = 252, ///< This is just a test EAP-type. + eap_type_dummy_sim = 253, ///< This is just a test EAP-type. + + eap_type_expanded_type = 254, ///< This is Expanded Type. + eap_type_experimental_type = 255, ///< This is Experimental Type. +}; + + +#if !defined(USE_EAP_EXPANDED_TYPES) + typedef eap_type_value_e eap_type_ietf_values_e; +#endif //#if !defined(USE_EAP_EXPANDED_TYPES) + + + +enum eap_type_vendor_id_e +{ + eap_type_vendor_id_ietf = 0, + eap_type_vendor_id_broadcom = 0x0000113d, + eap_type_vendor_id_WFA = 0x00372A, + eap_type_vendor_id_hack = 0xFFFFFF, // This is for plain MCHAPv2 and TTLS +}; + +enum eap_type_vendor_type_e +{ + eap_type_vendor_type_secure_easy_setup = 10, + eap_type_vendor_type_WFA_simple_config = 1, + eap_type_vendor_type_ttls_plain_pap_hack = eap_type_ttls_plain_pap, // This is for TTLS/PAP. +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + eap_type_vendor_type_plain_MSCHAPv2_hack = eap_type_plain_mschapv2, // This is for plain MCHAPv2 and TTLS +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) +}; + +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- + +class EAP_EXPORT eap_expanded_type_c +{ + +public: + + enum sizes + { + m_ietf_type_size = sizeof(u8_t), + m_vendor_id_size = 3ul*sizeof(u8_t), + m_vendor_type_size = sizeof(u32_t), + m_eap_expanded_type_size = m_ietf_type_size+m_vendor_id_size+m_vendor_type_size, + }; + + EAP_FUNC_IMPORT ~eap_expanded_type_c(); + + EAP_FUNC_IMPORT eap_expanded_type_c(); + + EAP_FUNC_IMPORT eap_expanded_type_c( + const eap_type_vendor_id_e vendor_id, + const u32_t vendor_type); + + EAP_FUNC_IMPORT eap_expanded_type_c( + const eap_type_ietf_values_e type); + + EAP_FUNC_IMPORT static bool is_expanded_type(const eap_type_ietf_values_e eap_type); + +#if defined(USE_EAP_EXPANDED_TYPES) + EAP_FUNC_IMPORT static bool is_ietf_type(const eap_expanded_type_c eap_type); +#else + EAP_FUNC_IMPORT static bool is_ietf_type(const eap_type_ietf_values_e eap_type); +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + EAP_FUNC_IMPORT eap_status_e get_type_data( + abs_eap_am_tools_c * const am_tools, + eap_type_ietf_values_e * const type); + + EAP_FUNC_IMPORT eap_status_e get_type_data( + abs_eap_am_tools_c * const am_tools, + eap_expanded_type_c * const type); + + EAP_FUNC_IMPORT eap_status_e get_expanded_type_data( + abs_eap_am_tools_c * const am_tools, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e set_expanded_type_data( + abs_eap_am_tools_c * const am_tools, + const eap_variable_data_c * const data); + + EAP_FUNC_IMPORT void set_eap_type_values( + const eap_type_vendor_id_e vendor_id, + const u32_t vendor_type); + + EAP_FUNC_IMPORT eap_type_vendor_id_e get_vendor_id() const; + + EAP_FUNC_IMPORT u32_t get_vendor_type() const; + + EAP_FUNC_IMPORT static u32_t get_eap_expanded_type_size(); + + EAP_FUNC_IMPORT bool operator == (const eap_type_ietf_values_e right_type_value) const; + + EAP_FUNC_IMPORT bool operator != (const eap_type_ietf_values_e right_type_value) const; + + EAP_FUNC_IMPORT bool operator == (const eap_expanded_type_c &right_type_value) const; + + EAP_FUNC_IMPORT bool operator != (const eap_expanded_type_c &right_type_value) const; + + EAP_FUNC_IMPORT eap_expanded_type_c &operator = (const eap_type_ietf_values_e right_type_value); + + EAP_FUNC_IMPORT eap_expanded_type_c &operator = (const eap_expanded_type_c &right_type_value); + + EAP_FUNC_IMPORT eap_expanded_type_c *operator & (); + + EAP_FUNC_IMPORT const eap_expanded_type_c *operator & () const; + + /// This function reads EAP-type from offset. + EAP_FUNC_IMPORT static eap_status_e read_type( + abs_eap_am_tools_c * const am_tools, + const u32_t index, + const void * const buffer, + const u32_t buffer_length, +#if defined(USE_EAP_EXPANDED_TYPES) + eap_expanded_type_c * const type +#else + eap_type_ietf_values_e * const type +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + ); + + /// This function writes EAP-type to offset. + EAP_FUNC_IMPORT static eap_status_e write_type( + abs_eap_am_tools_c * const am_tools, + const u32_t index, ///< Index is from 0 to n. Index 0 is the first EAP type field after base EAP header. + void * const buffer, + const u32_t buffer_length, + const bool write_extented_type_when_true, ///< True value writes always Extented Type. +#if defined(USE_EAP_EXPANDED_TYPES) + const eap_expanded_type_c p_type ///< The EAP type to be written. +#else + const eap_type_ietf_values_e p_type ///< The EAP type to be written. +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + ); + +#if defined(USE_EAP_EXPANDED_TYPES) + EAP_FUNC_IMPORT i32_t compare(const eap_expanded_type_c * const data) const; +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + +private: + + eap_type_vendor_id_e m_vendor_id; ///< Here we use only 24 least significant bits. + u32_t m_vendor_type; +}; + +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- + +class EAP_EXPORT eap_static_expanded_type_c +{ +public: + + EAP_FUNC_IMPORT const eap_expanded_type_c & get_type() const; + +public: + + eap_type_vendor_id_e m_vendor_id; ///< Here we use only 24 least significant bits. + u32_t m_vendor_type; +}; + +#define EAP_EXPANDED_TYPE(name, vendor_id, vendor_type) \ + static const eap_static_expanded_type_c name={vendor_id, vendor_type} + + +// EAP Expanded Types. +EAP_EXPANDED_TYPE( + eap_expanded_type_broadcom_secure_easy_setup, + eap_type_vendor_id_broadcom, + eap_type_vendor_type_secure_easy_setup); + +EAP_EXPANDED_TYPE( + eap_expanded_type_nak, + eap_type_vendor_id_ietf, + eap_type_nak); + +EAP_EXPANDED_TYPE( + eap_expanded_type_simple_config, + eap_type_vendor_id_WFA, + eap_type_vendor_type_WFA_simple_config); + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + EAP_EXPANDED_TYPE( + eap_expanded_type_ttls_plain_mschapv2, + eap_type_vendor_id_hack, + eap_type_vendor_type_plain_MSCHAPv2_hack); +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + EAP_EXPANDED_TYPE( + eap_expanded_type_ttls_plain_pap, + eap_type_vendor_id_hack, + eap_type_vendor_type_ttls_plain_pap_hack); + +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- + + +#if defined(USE_EAP_EXPANDED_TYPES) + + typedef eap_expanded_type_c eap_type_value_e; + + EAP_C_FUNC_IMPORT u32_t convert_eap_type_to_u32_t(eap_type_value_e type); + + EAP_C_FUNC_IMPORT u64_t convert_eap_type_to_u64_t(eap_type_value_e type); + +#else + + EAP_C_FUNC_IMPORT u32_t convert_eap_type_to_u32_t(eap_type_value_e type); + + EAP_C_FUNC_IMPORT u64_t convert_eap_type_to_u64_t(eap_type_value_e type); + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- + +#endif //#if !defined(_EAP_EXPANDED_TYPE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_general_header_base.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_general_header_base.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,142 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined(_EAP_GENERAL_HEADER_BASE_H_) +#define _EAP_GENERAL_HEADER_BASE_H_ + + +#include "eap_am_assert.h" +#include "eap_am_tools.h" +#include "eap_tools.h" + +/** @file */ + +/** This is general base class defining the view to packet header. + */ +class EAP_EXPORT eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to the header buffer. + u8_t * m_header_buffer; + + /// This is length of the header buffer. + u32_t m_header_buffer_length; + +#if defined(USE_EAP_ERROR_TESTS) + /// This flag tells whether protocol detected error on packet. + /// This is used in error testing. + /// Value of this attribute is initialized to true. + /// Protocol should change attribute value to false + /// after it accepts this packet. + bool m_error_detected; +#endif //#if defined(USE_EAP_ERROR_TESTS) + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing special. + /// NOTE the header buffer is not deleted here. + EAP_FUNC_IMPORT virtual ~eap_general_header_base_c(); + + /// Constructor does nothing special. + /// The tools parameter is pointer to tools object. + /// The header_buffer parameter is pointer to buffer of the packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT eap_general_header_base_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + /// This function returns the pointer to the offset of the data of the packet. + EAP_FUNC_IMPORT u8_t * get_header_offset(const u32_t offset, const u32_t data_length) const; + + /// This function returns the pointer to the data of the packet. + EAP_FUNC_IMPORT u8_t * get_header_buffer(const u32_t data_length) const; + + /// This function sets the buffer of the packet. + /// The header_buffer parameter is pointer to buffer of the packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT void set_header_buffer(u8_t * const header_buffer, const u32_t header_buffer_length); + + /// This function returns the length of the header buffer. + EAP_FUNC_IMPORT u32_t get_header_buffer_length() const; + + /// This function returns validity of the object. + EAP_FUNC_IMPORT bool get_is_valid() const; + + /// This function returns pointer to the tools object. + EAP_FUNC_IMPORT abs_eap_am_tools_c * get_am_tools() const; + + /// This function checks the validity of derived header. + virtual eap_status_e check_header() const = 0; + + +#if defined(USE_EAP_ERROR_TESTS) + + EAP_FUNC_IMPORT void set_error_detected(const bool error_detected); + + EAP_FUNC_IMPORT bool get_error_detected(); + +#endif //#if defined(USE_EAP_ERROR_TESTS) + + // + //-------------------------------------------------- +}; // class eap_general_header_base_c + + +#if defined(USE_EAP_ERROR_TESTS) + + #define EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(destination, source) \ + { \ + (destination)->set_error_detected((source)->get_error_detected()); \ + } + + #define EAP_GENERAL_HEADER_SET_ERROR_DETECTED(packet, true_or_false) \ + { \ + (packet)->set_error_detected((true_or_false)); \ + } + +#else + + #define EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(destination, source) + + #define EAP_GENERAL_HEADER_SET_ERROR_DETECTED(packet, true_or_false) + +#endif //#if defined(USE_EAP_ERROR_TESTS) + + +#endif //#if !defined(_EAP_GENERAL_HEADER_BASE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_handle.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_handle.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,79 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#error Do not use this anymore. + +#if !defined(_EAP_HANDLE_H_) +#define _EAP_HANDLE_H_ + +#include "eap_am_types.h" +#include "eap_am_network_id.h" +#include "eap_am_export.h" +#include "abs_eap_am_tools.h" +//#include "eap_am_memory.h" +#include "eap_am_assert.h" +#include "eap_header.h" +#include "eap_status.h" + +//-------------------------------------------------- + +/// This class stores connection information of one session. +class EAP_EXPORT eap_handle_c +: public eap_variable_data_c +{ +private: + + eap_am_network_id_c m_send_network_id; + + eap_type_value_e m_eap_type; + +public: + + EAP_FUNC_IMPORT virtual ~eap_handle_c(); + + EAP_FUNC_IMPORT eap_handle_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT eap_handle_c( + abs_eap_am_tools_c * const tools, + eap_variable_data_c * const selector, + const eap_am_network_id_c * const network_id, + const eap_type_value_e p_eap_type); + + EAP_FUNC_IMPORT eap_status_e set_handle( + eap_variable_data_c * const selector, + const eap_am_network_id_c * const network_id, + const eap_type_value_e p_eap_type); + + EAP_FUNC_IMPORT const eap_am_network_id_c * get_send_network_id() const; + + EAP_FUNC_IMPORT eap_type_value_e get_eap_type() const; + + EAP_FUNC_IMPORT void reset(); +}; + +//-------------------------------------------------- + + + +#endif //#if !defined(_EAP_HANDLE_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,308 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined(_EAP_HEADER_H_) +#define _EAP_HEADER_H_ + + +#include "eap_general_header_base.h" +#include "eap_expanded_type.h" + + +/** @file */ + +//----------------------------------------------------------------------------------------- + +/** This is base class defining the EAP-packet header. + * @code + * Original EAP-header. + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Code | Identifier | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Type data ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 0 1 2 3 + * + * EAP-header with expanded type field. + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Code | Identifier | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Vendor-Id | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Vendor-Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type data ... + * +-+-+-+-+-+-+-+-+ + * @endcode + */ +class EAP_EXPORT eap_header_base_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /** + * This enumeration defines the offsets of the EAP-header fields. + */ + enum offsets + { + m_code_offset = 0ul, ///< This is offset to code field. + m_identifier_offset = m_code_offset+sizeof(u8_t), ///< This is offset to identifier field. + m_length_offset = m_identifier_offset+sizeof(u8_t), ///< This is offset to length field. + + m_type_offset = m_length_offset+sizeof(u16_t), ///< This is offset to optional type field. + m_data_offset = m_type_offset+sizeof(u8_t), ///< This is offset to optional data field. + + m_exp_ietf_type_offset = 0ul, ///< This is offset of extented type IETF type field in the Extepanded Type field. + m_exp_vendor_id_offset = m_exp_ietf_type_offset+eap_expanded_type_c::m_ietf_type_size, ///< This is offset of extented type vendor ID field in the Extepanded Type field. + m_exp_vendor_type_offset = m_exp_vendor_id_offset+eap_expanded_type_c::m_vendor_id_size, ///< This is offset of extented type vendor type field in the Extepanded Type field. + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing special. + EAP_FUNC_IMPORT virtual ~eap_header_base_c(); + + /// Constructor does nothing special. + /// The tools parameter is pointer to tools object. + /// The header_buffer parameter is pointer to buffer of EAP-packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT eap_header_base_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + /// This function returns the header length of the EAP-packet. + EAP_FUNC_IMPORT static u32_t get_header_length(); + + /// This function returns the length of the ietf type field. + EAP_FUNC_IMPORT static u32_t get_ietf_type_field_length(); + + /// This function returns the length of the extented type field. + EAP_FUNC_IMPORT static u32_t get_expanded_type_field_length(); + + /// This function returns the offset of the IETF type field. + EAP_FUNC_IMPORT static u32_t get_expanded_ietf_type_offset(); + + /// This function returns the offset of the vendor ID of type field. + EAP_FUNC_IMPORT static u32_t get_expanded_vendor_id_offset(); + + /// This function returns the offset of the vendor type of type field. + EAP_FUNC_IMPORT static u32_t get_expanded_vendor_type_offset(); + + /// This function returns the offset of the start of the type data. + EAP_FUNC_IMPORT static u32_t get_type_data_start_offset( + const bool expanded_type_when_true); + + + /// This function returns the code field of EAP-header. + EAP_FUNC_IMPORT eap_code_value_e get_code() const; + + /// This function returns the identifier field of EAP-header. + EAP_FUNC_IMPORT u8_t get_identifier() const; + + /// This function returns the length field of EAP-header. + EAP_FUNC_IMPORT u16_t get_length() const; + + /// This function returns the IETF type field of EAP-header. + /// This means the first 8-bits of type field, whether it is short or expanded type. + EAP_FUNC_IMPORT eap_type_ietf_values_e get_ietf_type() const; + + /// This function returns the type field of EAP-header. + EAP_FUNC_IMPORT eap_type_value_e get_type() const; + + /// This function returns the length of type field of EAP-header. + EAP_FUNC_IMPORT u32_t get_type_field_length() const; + + /// This function returns the type data length of EAP-packet. + EAP_FUNC_IMPORT u16_t get_type_data_length() const; + + /// This function returns the data length of EAP-packet. + /// The data length includes type field. + EAP_FUNC_IMPORT u16_t get_data_length() const; + + /// This function returns the pointer to the offset of the type data field of EAP-packet. + EAP_FUNC_IMPORT u8_t * get_type_data_offset( + const u32_t p_offset, const u32_t p_continuous_bytes) const; + + /// This function returns the pointer to the offset of the data field of EAP-packet. + /// Data field includes type field. + EAP_FUNC_IMPORT u8_t * get_data_offset( + const u32_t p_offset, const u32_t p_continuous_bytes) const; + + /// This function returns the pointer to the type data field of EAP-packet. + EAP_FUNC_IMPORT u8_t * get_type_data( + const u32_t p_continuous_bytes) const; + + /// This function returns the pointer to the data field of EAP-packet. + /// Data field includes type field. + EAP_FUNC_IMPORT u8_t * get_data( + const u32_t p_continuous_bytes) const; + + /// This function sets the code field of the EAP-header. + EAP_FUNC_IMPORT void set_code(const eap_code_value_e p_code); + + /// This function sets the identifier field of the EAP-header. + EAP_FUNC_IMPORT void set_identifier(const u8_t p_identifier); + + /// This function sets the length field of the EAP-header. + EAP_FUNC_IMPORT void set_length( + const u16_t p_length, + const bool expanded_type_when_true); + + /// This function sets the length field of the EAP-header using the length of the type data. + EAP_FUNC_IMPORT void set_type_data_length( + const u16_t p_length, + const bool expanded_type_when_true); + + /// This function sets the type field of the EAP-header. + EAP_FUNC_IMPORT eap_status_e set_type( + const eap_type_value_e p_type, + const bool expanded_type_when_true); + + /// This function returns debug string of the code of the EAP-packet. + EAP_FUNC_IMPORT eap_const_string get_code_string() const; + + /// This function returns debug string of the type of the EAP-packet. + EAP_FUNC_IMPORT eap_const_string get_type_string() const; + + /// This function checks the validity of EAP-header. + EAP_FUNC_IMPORT eap_status_e check_header() const; + + // + //-------------------------------------------------- +}; // class eap_header_c + + +//----------------------------------------------------------------------------------------- + + +/// This class is read only EAP-packet header. +/// @{ This class can be removed. eap_header_base_c could be used instead. } +class EAP_EXPORT eap_header_rd_c +: public eap_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing special. + EAP_FUNC_IMPORT virtual ~eap_header_rd_c(); + + /// Constructor does nothing special. + /// The tools parameter is pointer to tools object. + /// The header_buffer parameter is pointer to buffer of EAP-packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT eap_header_rd_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length); + + + // + //-------------------------------------------------- +}; // class eap_header_rd_c + + +//----------------------------------------------------------------------------------------- + + +/// This class is read and write EAP-packet header. +/// @{ This class can be removed. eap_header_base_c could be used instead. } +class EAP_EXPORT eap_header_wr_c +: public eap_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing special. + EAP_FUNC_IMPORT virtual ~eap_header_wr_c(); + + /// Constructor does nothing special. + /// The tools parameter is pointer to tools object. + /// The header_buffer parameter is pointer to buffer of EAP-packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT eap_header_wr_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length); + + + /// This function returns the pointer to the type data field of EAP-packet. + EAP_FUNC_IMPORT u8_t * get_type_data( + const u32_t p_continuous_bytes) const; + + /// This function returns the pointer to the offset of the type data field of EAP-packet. + EAP_FUNC_IMPORT u8_t * get_type_data_offset( + const u32_t p_offset, + const u32_t p_continuous_bytes) const; + + /// This function resets the EAP-header. + /// The buffer_length parameter is the length of the EAP-header and the following data buffer. + EAP_FUNC_IMPORT void reset_header( + const u16_t buffer_length, + const bool expanded_type_when_true); + + // + //-------------------------------------------------- +}; // class eap_header_c + + +//----------------------------------------------------------------------------------------- + + + +#endif //#if !defined(_EAP_HEADER_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_header_string.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_header_string.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_HEADER_STRING_H_ ) +#define _EAP_HEADER_STRING_H_ + +/** @file */ + +#include "eap_variable_data.h" +#include "eap_status.h" +#include "eap_am_export.h" +#include "eap_header.h" + +/// This class includes the debug strings of the eap_header_base_c. +class EAP_EXPORT eap_header_string_c +{ +public: + + EAP_FUNC_IMPORT virtual ~eap_header_string_c(); + + EAP_FUNC_IMPORT eap_header_string_c(); + + /** + * Function returns string of eap_code_value_e. + * @param code is the queried string. + */ + EAP_FUNC_IMPORT static eap_const_string get_eap_code_string(const eap_code_value_e code); + + /** + * Function returns string of eap_type_value_e. + * @param type is the queried string. + */ + EAP_FUNC_IMPORT static eap_const_string get_eap_type_string(const eap_type_value_e type); + +}; + + +#endif //#if !defined( _EAP_HEADER_STRING_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_master_session_key.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_master_session_key.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,93 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_MASTER_SESSION_KEY_H_) +#define _EAP_MASTER_SESSION_KEY_H_ + +#include "eap_am_types.h" +#include "eap_am_export.h" +//#include "eap_am_memory.h" +#include "eap_am_assert.h" +#include "eap_status.h" +#include "eap_variable_data.h" +#include "eap_header.h" + +//-------------------------------------------------- + +class abs_eap_am_tools_c; + + +/// This class stores data of master session key. +class EAP_EXPORT eap_master_session_key_c +: public eap_variable_data_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c + abs_eap_am_tools_c * const m_am_tools; + + /// LEAP uses password in the RADIUS message generation too. + eap_variable_data_c m_leap_password; + + /// This is the EAP-type. + eap_type_value_e m_eap_type; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor of the eap_variable_data class will release + * the buffer if attribute m_free_buffer is true. + */ + EAP_FUNC_IMPORT virtual ~eap_master_session_key_c(); + + /** + * Constructor takes only one parameter called tools. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + */ + EAP_FUNC_IMPORT eap_master_session_key_c( + abs_eap_am_tools_c * const tools, + const eap_type_value_e eap_type); + + EAP_FUNC_IMPORT eap_type_value_e get_eap_type() const; + + EAP_FUNC_IMPORT void set_eap_type(eap_type_value_e type); + + EAP_FUNC_IMPORT const eap_variable_data_c * get_leap_password() const; + + EAP_FUNC_IMPORT eap_status_e copy_leap_password(const eap_variable_data_c * const key); + + EAP_FUNC_IMPORT eap_status_e set_copy(const eap_master_session_key_c * const msk); + + //-------------------------------------------------- +}; // class eap_master_session_key_c + + +#endif //#if !defined(_EAP_MASTER_SESSION_KEY_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_memory_store_variable_data.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_memory_store_variable_data.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAP_MEMORY_STORE_VARIABLE_DATA_H +#define EAP_MEMORY_STORE_VARIABLE_DATA_H + +// INCLUDES +#include "eap_am_memory_store_data.h" +#include "eap_am_tools.h" + +// CLASS DECLARATION + + +#endif // EAP_MEMORY_STORE_VARIABLE_DATA_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_network_id_selector.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_network_id_selector.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_NETWORK_ID_SELECTOR_H_) +#define _EAP_NETWORK_ID_SELECTOR_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_variable_data.h" +#include "eap_am_network_id.h" + + +//-------------------------------------------------- + +class EAP_EXPORT eap_network_id_selector_c +: public eap_variable_data_c +{ +private: + + abs_eap_am_tools_c * const m_am_tools; + +public: + + EAP_FUNC_IMPORT virtual ~eap_network_id_selector_c(); + + EAP_FUNC_IMPORT eap_network_id_selector_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT eap_network_id_selector_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const network_id); + + EAP_FUNC_IMPORT eap_status_e set_selector( + const eap_am_network_id_c * const network_id); + + EAP_FUNC_IMPORT eap_network_id_selector_c( + abs_eap_am_tools_c * const tools, + const eap_network_id_selector_c * const selector); + + + // + EAP_FUNC_IMPORT eap_network_id_selector_c * copy() const; + +}; + + +#endif //#if !defined(_EAP_NETWORK_ID_SELECTOR_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_protocol_layer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_protocol_layer.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,113 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_PROTOCOL_LAYER_H_) +#define _EAP_PROTOCOL_LAYER_H_ + +/** @file */ + +#define USE_EAP_PEAPV1_EXTENSIONS + +/** + * A EAP Core protocol layer enumeration. + * NOTE, do not change the values, these are used in interface. + */ +enum eap_protocol_layer_e +{ + eap_protocol_layer_none = 0, + eap_protocol_layer_general = 1, ///< This is general protocol layer, eap_general_state_variable_e uses this. + eap_protocol_layer_internal_type = 2, ///< This is any internal authentication type used by EAP-type. For example TLS. + eap_protocol_layer_am_eap_type = 3, ///< Adaptation module of EAP type. + eap_protocol_layer_radius = 4, ///< RADIUS protocol + eap_protocol_layer_eap_type = 5, ///< EAP type. + eap_protocol_layer_eap = 6, ///< EAP protocol, eap_state_variable_e uses this. + eap_protocol_layer_eapol = 7, ///< EAPOL protocol, eapol_state_variable_e uses this. + eap_protocol_layer_eapol_key = 8, ///< EAPOL-Key protocol, eapol_key_state_e uses this. + eap_protocol_layer_ethernet = 9, ///< Ethernet protocol. + eap_protocol_layer_wlan_authentication = 10, ///< WLAN authentication uses this. + eap_protocol_layer_authentication_server = 11, ///< authentication server uses this. +#if defined(USE_WAPI_CORE) + eap_protocol_layer_wapi = 12, ///< WAPI authentication notification to WLAN engine uses this. + eap_protocol_layer_wai = 13, ///< WAI authentication protocol uses this. +#endif +}; + + +/** + * A EAP state variable enumeration of eap_protocol_layer_e::eap_protocol_layer_general. + * NOTE, do not change the values, these are used in interface. + */ +enum eap_general_state_variable_e +{ + eap_general_state_none = 0, + eap_general_state_show_notification_string = 1, ///< Adaptation module should display notification string to user. + eap_general_state_configuration_error = 2, ///< Configuration was incorrect. Cannot continue. + eap_general_state_authentication_cancelled = 3, ///< Authentication was cancelled. Cannot continue. + eap_general_state_authentication_error = 4, ///< Error on authentication, show appropriate error to user. + eap_general_state_immediate_reconnect = 5, ///< This was a provisioning of credentials. Immediately reconnect so the credentials can be used. + eap_general_state_last_mark = 6, ///< Keep this the last one. +}; + +/** + * A EAP state variable enumeration of eap_protocol_layer_e::eap_protocol_layer_eap, + * eap_protocol_layer_e::eap_protocol_layer_internal_type, + * eap_protocol_layer_e::eap_protocol_layer_am_eap_type + * and eap_protocol_layer_e::eap_protocol_layer_eap_type. + * NOTE, do not change the values, these are used in interface. + */ +enum eap_state_variable_e +{ + eap_state_none = 0, + eap_state_identity_request_sent = 1, ///< Server sent the EAP-Request/Identity. + eap_state_identity_request_received = 2, ///< Client received the EAP-Request/Identity. + eap_state_identity_response_received = 3, ///< Server received the EAP-Response/Identity. + eap_state_eap_response_sent = 4, ///< Client sent the first EAP-Response. + eap_state_tppd_peapv1_authentication_finished_successfully_with_tunneled_eap_success = 5, ///< Client finished PEAP version 1 with tunneled EAP-Success. + eap_state_authentication_finished_successfully = 6, ///< Authentication was successfull and it is finished. + eap_state_authentication_terminated_unsuccessfully = 7, ///< Authentication was unsuccessfull and it is terminated. + eap_state_authentication_wait_tppd_peapv1_empty_acknowledge = 8, ///< Server waits empty akcnowledge of PEAPv1. + eap_state_use_eap_failure_in_termination = 9, ///< Simple Config ends always with EAP-Failure message. + eap_state_inner_eap_method_skipped = 10, ///< Inner EAP-method is not run. + eap_state_authentication_wait_eap_fast_empty_acknowledge = 11, ///< Server waits empty akcnowledge of EAP-FAST. + eap_state_wait_plain_eap_success = 12, ///< Client waits plain EAP-Success. +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + eap_state_authentication_finished_successfully_peapv1_extension = 13, ///< Client finished PEAP version 1 with tunneled Extension Response. + eap_state_authentication_terminated_unsuccessfully_peapv1_extension = 14, ///< Client finished PEAP version 1 with tunneled Extension Response. +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + eap_state_last_mark = 15, ///< Keep this the last one. +}; + +/** + * NOTE, do not change the values, these are used in interface. + */ +enum eapol_state_variable_e +{ + eapol_state_none = 0, + eapol_state_start_sent = 1, ///< Client has sent EAPOL-Start + eapol_state_no_start_response = 2, ///< Client did not receive response to EAPOL-Start +}; + +#endif //#if !defined(_EAP_PROTOCOL_LAYER_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_rogue_ap_entry.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_rogue_ap_entry.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,105 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAP_ROGUE_AP_ENTRY_H +#define EAP_ROGUE_AP_ENTRY_H + +// INCLUDES +#include "eap_am_tools.h" +#include "eapol_ethernet_address.h" + +enum eap_rogue_ap_reason_e +{ + rogue_ap_none, + rogue_ap_association_failed, + rogue_ap_timeout, + rogue_ap_challenge_to_client_failed, + rogue_ap_challenge_to_ap_failed +}; + +// CLASS DECLARATION + +class EAP_EXPORT eap_rogue_ap_entry_c +{ + public: + + // Constructors and destructor + + /** + * Constructor + * @param tools Pointer to EAP tools class + */ + EAP_FUNC_IMPORT eap_rogue_ap_entry_c( + abs_eap_am_tools_c * const tools); + + /** + * Destructor + */ + EAP_FUNC_IMPORT virtual ~eap_rogue_ap_entry_c(); + + /** + * Returns a copy of this object. + */ + EAP_FUNC_IMPORT eap_rogue_ap_entry_c * copy() const; + + /** + * Returns pointer to MAC address + * @return Pointer to MAC address + */ + EAP_FUNC_IMPORT u8_t * get_mac_address() const; + + /** + * Returns pointer to MAC address and copies MAC address into given pointer + * @param mac_address Copies MAC address into this + * @return Pointer to MAC address + */ + EAP_FUNC_IMPORT u8_t * get_mac_address(u8_t * const mac_address) const; + + /** + * Sets MAC address + * @param mac_address pointer to MAC address + */ + EAP_FUNC_IMPORT void set_mac_address(const u8_t * const mac_address); + + /** + * Sets Rogue reason code + * @param reason Rogue reson code + */ + EAP_FUNC_IMPORT void set_rogue_reason(const eap_rogue_ap_reason_e reason); + + /** + * Returns reson code of Rogue AP entry + * @return Rogue reson code + */ + EAP_FUNC_IMPORT eap_rogue_ap_reason_e get_rogue_reason() const; + + private: // Data + + /// Pointer to EAP tools + abs_eap_am_tools_c * const m_am_tools; + + eap_rogue_ap_reason_e m_rogue_ap_reason; + + u8_t m_rogue_ap_mac_address[EAPOL_ETHERNET_ADDRESS_LENGTH]; + +}; // class eap_rogue_ap_entry_c + +#endif // EAP_ROGUE_AP_ENTRY_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_session_core.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_session_core.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,385 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_SESSION_CORE_H_) +#define _EAP_SESSION_CORE_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_core.h" +#include "eap_core_map.h" +#include "abs_eap_stack_interface.h" + +class eap_core_c; +class eap_network_id_selector_c; + + +/** + * This is the timer ID used with abs_eap_am_tools_c::set_timer() and abs_eap_am_tools_c::cancel_timer(). + */ +enum eap_session_core_timer_id +{ + EAP_SESSION_CORE_REMOVE_SESSION_ID, ///< See EAP_SESSION_CORE_REMOVE_SESSION_TIMEOUT. +}; + +/** + * This is time after a EAP session is removed. This must be zero. + */ +const u32_t EAP_SESSION_CORE_REMOVE_SESSION_TIMEOUT = 0u; + + +/// A eap_session_core_c class implements mapping of EAP authentication sessions. +/// Network identity separates parallel EAP authentication sessions. +class EAP_EXPORT eap_session_core_c +: public abs_eap_core_c +, public abs_eap_core_map_c +, public abs_eap_base_timer_c +, public abs_eap_stack_interface_c +{ +private: + //-------------------------------------------------- + + /// This is back pointer to object which created this object. + /// Packets are sent to the partner. + abs_eap_core_c * const m_partner; + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This stores EAP authentication session objects using eap_variable_data selector. + eap_core_map_c m_session_map; + + u32_t m_remove_session_timeout; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + bool m_use_eap_session_core_reset_session; + + bool m_shutdown_was_called; + + + /** + * Function creates a new session. + */ + EAP_FUNC_IMPORT eap_core_c * create_new_session( + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT eap_status_e reset_or_remove_session( + eap_core_c ** const session, + const eap_network_id_selector_c * const selector, + const bool reset_immediately); + + + EAP_FUNC_IMPORT static eap_status_e shutdown_operation( + eap_core_c * const core, + abs_eap_am_tools_c * const m_am_tools); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_core class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_session_core_c(); + + /** + * The constructor initializes member attributes using parameters passed to it. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + * @param partner is back pointer to object which created this object. + * @param is_client_when_true indicates whether the network entity should act + * as a client (true) or server (false), in terms of EAP-protocol + * whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + */ + EAP_FUNC_IMPORT eap_session_core_c( + abs_eap_am_tools_c * const tools, + abs_eap_core_c * const partner, + const bool is_client_when_true); + + /** + * This function must reset the state of object to same as + * state was after the configure() function call. + * If object reset succeeds this function must return eap_status_ok. + * If object reset fails this function must return corresponding error status. + * @return This function returns the status of reset operation. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + /** + * This function cancels all EAP-sessions. + * If this succeeds this function must return eap_status_ok. + * If this fails this function must return corresponding error status. + * @return This function returns the status of operation. + */ + EAP_FUNC_IMPORT eap_status_e synchronous_cancel_all_eap_sessions(); + + // This is documented in abs_eap_stack_interface_c::packet_process(). + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length); + + /** + * The class could send packets to partner class with this function. + * @param send_network_id carries the addresses (network identity) and type of the packet. + * @param sent_packet includes the buffer for the whole packet and initialized + * EAP-packet in correct offset. + * @param header_offset is offset of the EAP-header within the sent_packet. + * @param data_length is length in bytes of the EAP-packet. + * @param buffer_length is length in bytes of the whole packet buffer. + */ + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + /** + * The get_partner() function returns pointer to partner class. + */ + EAP_FUNC_IMPORT abs_eap_core_c * get_partner(); + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @param MTU_length is pointer to variable to store the maximum transfer unit (MTU). + * MTU is the maximum EAP-packet length in bytes + * @param trailer_length is pointer to the variable to store length + * of trailer needed by lower levels. + * @return Function returns the offset of EAP-header. + * @see abs_eap_base_type_c::get_header_offset(). + */ + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + /** + * The unload_module() function initializes un-load of desired EAP-type. + * After the EAP-type is not needed this function should be called. + */ + EAP_FUNC_IMPORT eap_status_e unload_module( + const eap_type_value_e type); + + /** + * The adaptation module calls the eap_acknowledge() function after + * any Network Protocol packet is received. This is used as a success indication. + * This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + * @param connection_handle separates the context of the acknowledged session. + * Mostly there is only one session in the client. + * The server does not need eap_acknowledge() function because + * server (EAP-authenticator) sends the EAP-success message. + */ + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function restarts authentication using current object. + * This is used for testing. + */ + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const send_network_id, + const bool is_client_when_true); + +#if defined(USE_EAP_CORE_SERVER) + /** + * The EAP Core calls the send_eap_identity_request() function + * when EAP-authentication is needed with another peer. + * @param network_id includes the addresses (network identity) and packet type. + */ + EAP_FUNC_IMPORT eap_status_e send_eap_identity_request( + const eap_am_network_id_c * const network_id); +#endif //#if defined(USE_EAP_CORE_SERVER) + + /** + * The EAP Core calls the send_eap_nak_response() function + * when EAP-authentication with requested EAP type is not possible. + * @param network_id includes the addresses (network identity) and packet type. + * @param eap_identifier is the EAP-Identifier to be used with EAP-Nak message. + * @param preferred_eap_type is the acceptable EAP-Type to be informed with an other peer. + */ + EAP_FUNC_IMPORT eap_status_e send_eap_nak_response( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const eap_type_value_e preferred_eap_type); + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @param authentication_key is pointer to the first byte of the authentication key. + * @param auth_key_length is count of bytes in the authentication key. + * @param encryption_key is pointer to the first byte of the encryption key. + * @param encr_key_length is count of bytes in the encryption key. + */ + EAP_FUNC_IMPORT eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ); + + // This is documented in abs_eap_stack_interface_c::configure(). + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is documented in abs_eap_stack_interface_c::shutdown(). + EAP_FUNC_IMPORT eap_status_e shutdown(); + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // This is documented in abs_eap_stack_interface_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + + // This is documented in abs_eap_stack_interface_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + // See abs_eap_base_type_c::state_notification(). + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state); + + // See abs_eap_base_timer_c::timer_expired(). + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data); + + // See abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data); + + /** + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @see abs_eap_core_c::load_module(). + */ + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + /** + * The adaptation module calls the restart_authentication() function + * when EAP-authentication is needed with another peer. + * @see abs_eap_core_c::restart_authentication(). + */ + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer = false); + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + /** + * This function creates EAP session object synchronously. + * @param receive_network_id identifies the removed EAP session. + */ + EAP_FUNC_IMPORT eap_status_e synchronous_create_eap_session( + const eap_am_network_id_c * const receive_network_id); +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + /** + * This function removes EAP session object synchronously. + * @param receive_network_id identifies the removed EAP session. + */ + EAP_FUNC_IMPORT eap_status_e synchronous_remove_eap_session( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function removes EAP session object asynchronously. + * @param send_network_id identifies the removed EAP session. + */ + eap_status_e asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id); + + /** + * This function tells lower layer to remove EAP session object asynchronously. + * @param eap_type is pointer to selector that identifies the removed EAP session. + */ + EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_eap_session( + const eap_network_id_selector_c * const state_selector); + + // + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + // + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + // + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + /// @see abs_eap_core_c::get_eap_type_list(). + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + /// @see abs_eap_core_c::add_rogue_ap(). + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + // This is documented in abs_eap_core_c::set_session_timeout(). + EAP_FUNC_IMPORT eap_status_e set_session_timeout( + const u32_t session_timeout_ms); + + //-------------------------------------------------- +}; // class eap_session_core_c + +#endif //#if !defined(_EAP_SESSION_CORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_sort.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_sort.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,275 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_SORT_H_) +#define _EAP_SORT_H_ + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "eap_automatic_variable.h" + +/** @file */ + +//-------------------------------------------------- + +/** + * This template function copies array of objects from first to last + * to array of objects ending to result. + * Parameter first point to the first object of the source array. + * Parameter last points the next address after the last object of source array. + * Parameter result points the next address after the last object of the result array. + */ +template +void eap_sort_copy_backward( + const Type * const first, + const Type *last, + Type *result ) +{ + while (first != last) + { + *--result = *--last; + } +} + +//-------------------------------------------------- + +/** + * + */ +template +void eap_sort_unguarded_linear_insert( + Type *last, + const Type inserted_object, + bool (*compare_first_is_smaller)( + const Type * const first, + const Type * const second, + abs_eap_am_tools_c * const m_am_tools), + abs_eap_am_tools_c * const m_am_tools) +{ + Type *next = last; + + --next; + + while(compare_first_is_smaller(&inserted_object, next, m_am_tools) == true) + { + *last = *next; + last = next--; + } + + *last = inserted_object; +} + +//-------------------------------------------------- + +template +void eap_sort_linear_insert( + Type * const first, + Type * const last, + bool (*compare_first_is_smaller)( + const Type * const first, + const Type * const second, + abs_eap_am_tools_c * const m_am_tools), + abs_eap_am_tools_c * const m_am_tools) +{ + const Type value = *last; + + if(compare_first_is_smaller(&value, first, m_am_tools) == true) + { + eap_sort_copy_backward(first, last, last+1); + *first = value; + } + else + { + eap_sort_unguarded_linear_insert(last, value, compare_first_is_smaller, m_am_tools); + } +} + +//-------------------------------------------------- + +template +void eap_sort_insert_sort_area( + Type * const first, + const Type *last, + bool (*compare_first_is_smaller)( + const Type * const first, + const Type * const second, + abs_eap_am_tools_c * const m_am_tools), + abs_eap_am_tools_c * const m_am_tools) +{ + Type *tmp; + + ++last; + + for( tmp = first+1; tmp < last; tmp++ ) + { + eap_sort_linear_insert( first, tmp, compare_first_is_smaller, m_am_tools); + } +} + +//------------------------------------------------------------ + + +template +Type *eap_sort_divide_area( + Type *start, + Type *finish, + bool (*compare_first_is_smaller)( + const Type * const first, + const Type * const second, + abs_eap_am_tools_c * const m_am_tools), + abs_eap_am_tools_c * const m_am_tools) +{ + // selects the boundary object. + const Type boundary = *(start+((finish - start)/2)); + Type change; + + start--; + finish++; + + // Boundary is used as a middle object. + for(;;) + { + // Examine from begin to end is ++start smaller than boundary. + while(compare_first_is_smaller(++start, &boundary, m_am_tools) == true) + { + // Nothing to do. + } + + // Examine from end to begin is --finish bigger than boundary. + while(compare_first_is_smaller(&boundary, --finish, m_am_tools) == true) + { + // Nothing to do. + } + + + if( start < finish ) + { + // In case boundary isn't reached, it intent that two + // atom mutual side of boundary are in wrong order, + // so swap them. + change = *start; + *start = *finish; + *finish = change; + } + else + { + // Start and finish pointers are overlapping. + // Terminate loop and return pointer to finish. + return( finish ); + } + } // for() + +} + +//-------------------------------------------------- + +/** + * This function does quick-sort with non-recurvive alorithm. + * Parameter array is pointer to array including objects of type Type. + * Parameter object_count is count of objects in the array. + * Parameter compare_first_is_smaller is pointer to a function that compares objects of type Type. + */ +template +eap_status_e eap_sort_array( + Type * const array, + const u32_t object_count, + bool (*compare_first_is_smaller)( + const Type * const first, + const Type * const second, + abs_eap_am_tools_c * const m_am_tools), + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; // Note original_array may be empty or it includes only one object, then sort will not be run. + + if (object_count < 2ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t quicksort_finish = 10ul; + + // When there are atoms in the array fewer than quicksort_finish, + // then the array is sorted directly by eap_sort_insert_sort_area() function. + if (object_count >= quicksort_finish) + { + Type ** const sort_array = new Type *[object_count+1]; + eap_automatic_array_variable_c automatic_sort_array(m_am_tools, sort_array); + if (sort_array == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // first atom + Type *start = array; + // last point to the first address after the last atom. + Type *last = array+object_count; + Type *finish = last - 1; + sort_array[finish-array] = finish; + + // We continue until start come real array's end. + while (last != start) + { + if (static_cast(finish - start) > quicksort_finish) + { + Type *upper = eap_sort_divide_area(start, finish , compare_first_is_smaller, m_am_tools); + + // When is at least two unit in beginning. + // Divide sorting area under upper address. + // Upper areas end points are saved to sort_array. + sort_array[upper+1-array] = finish; + + // New sorting area. + // New start address is the same as start pointer of previous sort area. + // New finish address is preceding address of upper address. + finish = upper; + } + else + { + eap_sort_insert_sort_area(start, finish , compare_first_is_smaller, m_am_tools); + + start = ++finish; + finish = sort_array[start-array]; + } + } // while ( last != start ) + } + else + { + eap_sort_insert_sort_area(array, array+(object_count-1), compare_first_is_smaller, m_am_tools); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#endif //#if !defined(_EAP_SORT_H_) + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_state_notification.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_state_notification.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,197 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_STATE_NOTIFICATION_H_) +#define _EAP_STATE_NOTIFICATION_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_protocol_layer.h" +#include "abs_eap_state_notification.h" + + +/// A eap_state_notification_c class. +/// This is used for state change indications of EAP-protocol. +/// EAP-Success and EAP-Failure are sent based on eap_state_variable_e::eap_state_authentication_finished_successfully +/// and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully notifications. +class EAP_EXPORT eap_state_notification_c +: public abs_eap_state_notification_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; ///< This is pointer to the tools class. @see abs_eap_am_tools_c. + + eap_protocol_layer_e m_layer; ///< Here is the protocol layer (EAP type). + + eap_variable_data_c m_notification_string; ///< Here is the notification string. + + bool m_needs_confirmation_from_user; ///< This flag tells whether user interaction is required. + + u32_t m_protocol; ///< Here are other protocols than EAP-types. + + eap_type_value_e m_eap_type; ///< Here is the EAP type. This is needed for extented EAP-types. + + u32_t m_previous_state; ///< Here is the previous state of the EAP type. + + u32_t m_current_state; ///< Here is the current state of the EAP type. + + const eap_am_network_id_c *m_send_network_id; ///< This is the send network identity the notification concerns. + + bool m_is_client; ///< This indicates whether the notifier is client (true) or server (false). + + u8_t m_eap_identifier; ///< EAP-Identifier could be used in EAP packet send. EAP-Success and EAP-Failure are sent using this value. + + bool m_allow_send_eap_success; + + eap_status_e m_authentication_error; ///< This shows the error when m_layer is eap_protocol_layer_general and m_current_state is eap_general_state_authentication_error. + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_state_notification_c(); + + /** + * The constructor of the eap_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT eap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + + +#if defined(USE_EAP_EXPANDED_TYPES) + + EAP_FUNC_IMPORT eap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + + EAP_FUNC_IMPORT eap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + + // This is commented in abs_eap_state_notification_c::get_send_network_id(). + EAP_FUNC_IMPORT const eap_am_network_id_c * get_send_network_id() const; + + // This is commented in abs_eap_state_notification_c::get_protocol_layer(). + EAP_FUNC_IMPORT eap_protocol_layer_e get_protocol_layer() const; + + // This is commented in abs_eap_state_notification_c::get_protocol(). + EAP_FUNC_IMPORT u32_t get_protocol() const; + + // This is commented in abs_eap_state_notification_c::get_eap_type(). + EAP_FUNC_IMPORT eap_type_value_e get_eap_type() const; + + // This is commented in abs_eap_state_notification_c::get_previous_state(). + EAP_FUNC_IMPORT u32_t get_previous_state() const; + + // This is commented in abs_eap_state_notification_c::get_previous_state_string(). + EAP_FUNC_IMPORT eap_const_string get_previous_state_string() const; + + // This is commented in abs_eap_state_notification_c::get_current_state(). + EAP_FUNC_IMPORT u32_t get_current_state() const; + + // This is commented in abs_eap_state_notification_c::get_current_state_string(). + EAP_FUNC_IMPORT eap_const_string get_current_state_string() const; + + // This is commented in abs_eap_state_notification_c::get_is_client(). + EAP_FUNC_IMPORT bool get_is_client() const; + + // This is commented in abs_eap_state_notification_c::get_eap_identifier(). + EAP_FUNC_IMPORT u8_t get_eap_identifier() const; + + // This is commented in abs_eap_state_notification_c::get_allow_send_eap_success(). + EAP_FUNC_IMPORT bool get_allow_send_eap_success() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT eap_status_e set_notification_string( + const eap_variable_data_c * const notification_string, + const bool needs_confirmation_from_user); + + // This is commented in abs_eap_state_notification_c::get_notification_string(). + EAP_FUNC_IMPORT const eap_variable_data_c * get_notification_string() const; + + // This is commented in abs_eap_state_notification_c::get_needs_confirmation_from_user(). + EAP_FUNC_IMPORT bool get_needs_confirmation_from_user() const; + + + // This is commented in abs_eap_state_notification_c::set_authentication_error(). + EAP_FUNC_IMPORT void set_authentication_error(const eap_status_e error); + + // This is commented in abs_eap_state_notification_c::get_authentication_error(). + EAP_FUNC_IMPORT eap_status_e get_authentication_error() const; + + + EAP_FUNC_IMPORT static eap_const_string get_state_string(const u32_t protocol_layer, const u32_t state); + + + EAP_FUNC_IMPORT static eap_const_string get_protocol_layer_string(const u32_t protocol_layer); + + EAP_FUNC_IMPORT eap_const_string get_protocol_layer_string() const; + + + EAP_FUNC_IMPORT static eap_const_string get_protocol_string(const u32_t protocol_layer, const u32_t state); + + EAP_FUNC_IMPORT eap_const_string get_protocol_string() const; + + //-------------------------------------------------- +}; // class eap_state_notification_c + +#endif //#if !defined(_EAP_STATE_NOTIFICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_state_selector.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_state_selector.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_STATE_SELECTOR_H_) +#define _EAP_STATE_SELECTOR_H_ + +#error Do not use. + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_variable_data.h" +#include "sae_cookie.h" + + +//-------------------------------------------------- + +class EAP_EXPORT eap_state_selector_c +: public eap_variable_data_c +{ +private: + + abs_eap_am_tools_c * const m_am_tools; + +public: + + virtual ~eap_state_selector_c() + { + } + + eap_state_selector_c( + abs_eap_am_tools_c * const tools) + : eap_variable_data_c(tools) + , m_am_tools(tools) + { + } + + + eap_state_selector_c( + abs_eap_am_tools_c * const tools, + sae_cookie_c * const own_cookie, + sae_cookie_c * const peer_cookie) + : eap_variable_data_c(tools) + , m_am_tools(tools) + { + eap_status_e status = set_copy_of_buffer(own_cookie->get_data(), SAE_COOKIE_LENGTH); + if (status != eap_status_ok) + { + return; + } + status = add_data(peer_cookie->get_data(), SAE_COOKIE_LENGTH); + if (status != eap_status_ok) + { + return; + } + } + + eap_status_e set_selector( + sae_cookie_c * const own_cookie, + sae_cookie_c * const peer_cookie) + { + eap_status_e status = eap_status_process_general_error; + + status = set_copy_of_buffer(own_cookie->get_data(), SAE_COOKIE_LENGTH); + if (status != eap_status_ok) + { + return status; + } + + status = add_data(peer_cookie->get_data(), SAE_COOKIE_LENGTH); + if (status != eap_status_ok) + { + return status; + } + + return status; + } + + eap_state_selector_c( + abs_eap_am_tools_c * const tools, + const eap_state_selector_c * const selector) + : eap_variable_data_c(tools) + , m_am_tools(tools) + { + eap_status_e status = set_copy_of_buffer( + selector->get_data(selector->get_data_length()), + selector->get_data_length()); + if (status != eap_status_ok) + { + return; + } + } + + + // + eap_state_selector_c * const copy() const + { + eap_state_selector_c * const new_selector + = new eap_state_selector_c(m_am_tools, this); + + return new_selector; + } + +}; + +#endif //#if !defined(_EAP_STATE_SELECTOR_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_state_store.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_state_store.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,145 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_STATE_STORE_H_) +#define _EAP_STATE_STORE_H_ + +#error Do not use. + +#include "eap_am_memory.h" +#include "eap_am_tools.h" +#include "eap_tools.h" +#include "eap_am_export.h" + + +class EAP_EXPORT eap_base_type_state_c +{ +private: + //-------------------------------------------------- + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_base_type_state_c() + { + } + + // + eap_base_type_state_c() + { + } + + //-------------------------------------------------- +}; + + +const u32_t EAP_STATE_SIZE = (u32_t)(((~0u) & 0xff)+1u); + + +class EAP_EXPORT eap_state_store_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + eap_base_type_state_c *m_state[EAP_STATE_SIZE]; // Only 256 different identifier could exist. + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_state_store_c() + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + for (u32_t ind = 0; ind < EAP_STATE_SIZE; ind++) + { + delete m_state[ind]; + m_state[ind] = 0; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + // + eap_state_store_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + for (u32_t ind = 0; ind < EAP_STATE_SIZE; ind++) + { + m_state[ind] = 0; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + } + + // + eap_status_e add(eap_base_type_state_c * const state, const u8_t identifier) + { + if (m_state[identifier] == 0) + { + m_state[identifier] = state; + return eap_status_ok; + } + else + { + EAP_ASSERT_ALWAYS(m_state[identifier] == 0); + } + return eap_status_handler_does_not_exists_error; + } + + // + eap_base_type_state_c * const get(const u8_t identifier) + { + return m_state[identifier]; + } + + // + eap_status_e remove(const u8_t identifier) + { + if (m_state[identifier] != 0) + { + delete m_state[identifier]; + m_state[identifier] = 0; + return eap_status_ok; + } + else + { + EAP_ASSERT_ALWAYS(m_state[identifier] != 0); + } + return eap_status_handler_does_not_exists_error; + } + + //-------------------------------------------------- +}; + + +#endif //#if !defined(_EAP_STATE_STORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_status.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_status.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,209 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_STATUS_H_) +#define _EAP_STATUS_H_ + +/** @file */ + +/// This is enumeration of status values used in EAP_Core. +/** + * Most of the functions return type of eap_status value. + * Each value is defined in eap_status.h. The eap_status_ok value indicates no errors. + * The eap_status_success value indicates the EAP-authentication was successful. + * Other values try to be self-documenting. + * The return value of every function MUST be checked. + * Execution of the current function MUST handle error case generated by called function. + * In most cases this means immediately returning the erroneous status + * from the current function. User MUST free the memory allocated before the error occurs. + * Look at the following example. + * @code + * // A new EAP-type is needed. The load_type() allocates new object. + * eap_base_type *handler = load_type(used_eap_type); + * if (handler != 0) + * { + * if (handler->get_is_valid() == true) + * { + * eap_status status = handler->configure(); + * if (status != eap_status_ok) + * { + * // Configuration failed. + * delete handler; + * } + * EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + * return status; + * } + * else + * { + * // Handler not constructed successfully. + * delete handler; + * EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + * return eap_status_allocation_error; + * } + * } + * else + * { + * EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + * return eap_status_illegal_eap_type; + * } + * @endcode + */ + +enum eap_status_e +{ + eap_status_ok, ///< This means successfull status. + eap_status_success, ///< EAP-authentication is successful. + eap_status_pending_request, ///< Request is pending. It will be completed later. + eap_status_completed_request, ///< Request was completed already. + eap_status_drop_packet_quietly, ///< Packet was dropped quietly. Just forget that packet. + eap_status_not_supported, ///< You need to write some code to support this function. + eap_status_process_general_error, ///< Most propably you need debugger to found reason to this error. + eap_status_type_does_not_exists_error, ///< EAP-type is not implemented. + eap_status_allocation_error, ///< Memory allocation failed. Try again later or release memory. + eap_status_process_illegal_packet_error, + eap_status_ethernet_type_not_supported, + eap_status_illegal_eap_code, + eap_status_illegal_eap_type, + eap_status_illegal_eap_identity, + eap_status_authentication_failure, + eap_status_encryption_failure, + eap_status_decryption_failure, + eap_status_illegal_padding, + eap_status_randomize_failure, + eap_status_handler_exists_error, + eap_status_handler_does_not_exists_error, + eap_status_wrong_sae_state, + eap_status_wrong_eapol_version, + eap_status_wrong_eapol_type, + eap_status_wrong_eapol_oui, + eap_status_header_corrupted, + eap_status_wrong_sae_sequence_number, + eap_status_wrong_isakmp_header_version, + eap_status_wrong_isakmp_exchange_type, + eap_status_wrong_isakmp_flags, + eap_status_wrong_isakmp_message_id, + eap_status_wrong_isakmp_cookie, + eap_status_unsupported_isakmp_payload, + eap_status_key_error, + eap_status_too_many_offers, + eap_status_send_failed, + eap_status_data_length_not_aligned_to_block_size, + eap_status_wrong_network_id, + eap_status_illegal_handle, + eap_status_illegal_configure_field, + eap_status_illegal_configure_type, + eap_status_wrong_sae_header_version, + eap_status_wrong_sae_exchange_type, + eap_status_wrong_sae_flags, + eap_status_unsupported_sae_payload, + eap_status_wrong_sae_cookie, + eap_status_illegal_encryption_parameter_size, + eap_status_state_reference_count_not_zero, + eap_status_illegal_nai, + eap_status_illegal_nai_payload, + eap_status_illegal_data_payload, + eap_status_illegal_payload, + eap_status_illegal_hashed_index, + eap_status_wrong_gsmsim_state, + eap_status_wrong_eap_type_state, ///< Use this instead of eap_status_wrong_gsmsim_state. + eap_status_unsupported_gsmsim_payload, + eap_status_unsupported_payload, ///< Use this instead of eap_status_unsupported_gsmsim_payload. + eap_status_gsmsim_triplet_query_failed, + eap_status_illegal_index, + eap_status_timed_out, + eap_status_wrong_eap_subtype, + eap_status_exit_test, + eap_status_no_matching_protocol_version, + eap_status_too_short_message, + eap_status_too_long_message, + eap_status_hardware_not_ready, + eap_status_wrong_protocol, + eap_status_wrong_type, + eap_status_illegal_parameter, + eap_status_illegal_certificate, + eap_status_illegal_cipher_suite, + eap_status_bad_certificate, + eap_status_unsupported_certificate, + eap_status_certificate_revoked, + eap_status_certificate_expired, + eap_status_ca_certificate_unknown, + eap_status_user_certificate_unknown, + eap_status_unknown_ca, + eap_status_access_denied, + eap_status_unexpected_message, + eap_status_buffer_too_short, + eap_status_not_found, + eap_status_not_enough_challenges, + eap_status_not_fresh_challenges, + eap_status_already_exists, + eap_status_insufficient_security, + eap_status_syncronization_failure, + eap_status_file_does_not_exist, + eap_status_end_of_file, + eap_status_file_write_failed, + eap_status_wrong_authentication_type, + eap_status_section_ends, + eap_status_missing_payload, + eap_status_realm_check_failed, + eap_status_identity_query_failed, + eap_status_credential_query_failed, + eap_status_user_has_not_subscribed_to_the_requested_service, + eap_status_users_calls_are_barred, + eap_status_restricted_logon_hours, + eap_status_account_disabled, + eap_status_no_dialin_permission, + eap_status_password_expired, + eap_status_wrong_password, + eap_status_oob_interface_read_error, + eap_status_decryption_crc_failure, + eap_status_rf_band_2_4_ghz_not_supported, + eap_status_rf_band_5_0_ghz_not_supported, + eap_status_signal_too_weak, + eap_status_network_authentication_failure, + eap_status_network_association_failure, + eap_status_no_dhcp_response, + eap_status_failed_dhcp_configure, + eap_status_ip_address_conflict, + eap_status_could_not_connect_to_registrar, + eap_status_multiple_pbc_sessions_detected, + eap_status_rogue_activity_suspected, + eap_status_device_busy, + eap_status_setup_locked, + eap_status_message_timeout, + eap_status_registration_session_timeout, + eap_status_device_password_authentication_failure, + eap_status_pin_code_authentication_not_supported, + eap_status_push_button_authentication_not_supported, + eap_status_end_recursion, + eap_status_tunnel_compromise_error, + eap_status_unexpected_tlv_exhanged, + eap_status_no_pac_nor_certs_to_authenticate_with_provision_disabled, + eap_status_no_matching_pac_for_aid, + eap_status_pac_store_corrupted, + eap_status_user_cancel_authentication, + eap_status_no_match, +}; + + +#endif //#if !defined(_EAP_STATUS_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_status_string.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_status_string.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_STATUS_STRING_H_ ) +#define _EAP_STATUS_STRING_H_ + +/** @file */ + +#include "eap_am_compiler_flags.h" + +#include "eap_variable_data.h" +#include "eap_status.h" +#include "eap_am_export.h" + +//---------------------------------------------------------------------------------- + +/// This class includes the debug strings of the eap_status_e. +class EAP_EXPORT eap_status_string_c +{ +public: + + EAP_FUNC_IMPORT virtual ~eap_status_string_c(); + + EAP_FUNC_IMPORT eap_status_string_c(); + + /** + * Function returns string of eap_status_e. + * @param status is the queried string. + */ + EAP_FUNC_IMPORT static eap_const_string get_status_string(const eap_status_e status); + +}; + +//---------------------------------------------------------------------------------- + +#endif //#if !defined( _EAP_STATUS_STRING_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_timer_queue.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_timer_queue.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,554 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TIMER_QUEU_H_) +#define _EAP_TIMER_QUEU_H_ + +//#include "eap_am_memory.h" +#include "eap_am_tools.h" +#include "eap_tools.h" +#include "abs_eap_am_mutex.h" + + +/** @file */ + +const u32_t EAP_TIMER_RESOLUTION = 500u; ///< Timer resolution in milli seconds. + +const u32_t EAP_TIMER_QUEUE_LONG_SLEEP_TIME = 86400000; ///< Long timer sleep time of millisecond timer in milli seconds (24 hours). + +class eap_timer_queue_hash_c; + +// --------------------------------------------------------------------- + +/// This class is one timer event stored to timer queue. +class EAP_EXPORT eap_timer_queue_event_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + abs_eap_base_timer_c *m_initializer; ///< m_initializer is the initializer of timer event. Call backs are directed to initializer. + + u32_t m_id; ///< m_id is selected by caller. Caller could separate timer events by this value. + + void *m_data; ///< m_data is pointer to any data of initializer. + + u32_t m_time_ms; ///< m_time_ms is the time after this timer event should elapse. + + u32_t m_original_time_ms; ///< m_original_time_ms is the original set time. + + eap_timer_queue_event_c *m_prev; ///< m_prev is pointer to the previous timer event in the timer queue. + eap_timer_queue_event_c *m_next; ///< m_next is pointer to the next timer event in the timer queue. + + eap_timer_queue_hash_c *m_hash; + + eap_timer_queue_event_c *m_prev_same_time; ///< m_prev_same_time is pointer to the previous timer event with the same elapse time. + eap_timer_queue_event_c *m_next_same_time; ///< m_next_same_time is pointer to the next timer event with the same elapse time. + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_timer_queue_event_c(); + + //-------------------------------------------------- + + // + eap_timer_queue_event_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms); + + //-------------------------------------------------- + + // + u32_t get_time() const; + + //-------------------------------------------------- + + // + u32_t get_original_time() const; + + //-------------------------------------------------- + + // + eap_timer_queue_event_c *get_prev() const; + + //-------------------------------------------------- + + // + eap_timer_queue_event_c *get_next() const; + + //-------------------------------------------------- + + // + eap_timer_queue_event_c *get_prev_same_time() const; + + //-------------------------------------------------- + + // + eap_timer_queue_event_c *get_next_same_time() const; + + //-------------------------------------------------- + + // + eap_timer_queue_hash_c * get_hash() const; + + //-------------------------------------------------- + + // + u32_t pulse_time(const u32_t resolution); + + //-------------------------------------------------- + + // + void decrease_time_left(const u32_t decrease_time); + + //-------------------------------------------------- + + // + void increase_time_left(const u32_t increase_time); + + //-------------------------------------------------- + + // + void set_prev(eap_timer_queue_event_c * const prev); + + //-------------------------------------------------- + + // + void set_next(eap_timer_queue_event_c * const next); + + //-------------------------------------------------- + + // + void set_prev_same_time(eap_timer_queue_event_c * const prev_same_time); + + //-------------------------------------------------- + + // + void set_next_same_time(eap_timer_queue_event_c * const next_same_time); + + //-------------------------------------------------- + + // + void set_hash(eap_timer_queue_hash_c * const hash); + + //-------------------------------------------------- + + // + abs_eap_base_timer_c * get_initializer() const; + + //-------------------------------------------------- + + // + u32_t get_id() const; + + //-------------------------------------------------- + + // + void * get_data() const; + + //-------------------------------------------------- + + // + u32_t get_time_ms(); + + //-------------------------------------------------- +}; // class eap_timer_queue_event_c + + +// --------------------------------------------------------------------- + +/// This class is hash to timer event stored to timer queue. +/** + * Each timer event is stored to the timer queue (eap_timer_queue_c) with events (eap_timer_queue_event_c) + * and to the hash array of the timer events (eap_timer_queue_c::m_map). + */ +class EAP_EXPORT eap_timer_queue_hash_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + u32_t m_index; ///< Index in the hash array. + eap_timer_queue_event_c * m_atom; ///< Pointer to the time event. + + eap_timer_queue_hash_c *m_prev; ///< m_prev is pointer to the revious hash. + eap_timer_queue_hash_c *m_next; ///< m_next is pointer to the next hash. + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_timer_queue_hash_c(); + + //-------------------------------------------------- + + // + eap_timer_queue_hash_c( + abs_eap_am_tools_c * const tools, + eap_timer_queue_event_c * const atom, + const u32_t index); + + //-------------------------------------------------- + + // + eap_timer_queue_hash_c *get_next() const; + + //-------------------------------------------------- + + // + eap_timer_queue_hash_c *get_prev() const; + + //-------------------------------------------------- + + // + u32_t get_index() const; + + //-------------------------------------------------- + + // + void set_next(eap_timer_queue_hash_c * const next); + + // + void set_prev(eap_timer_queue_hash_c * const prev); + + eap_timer_queue_event_c * get_atom(); + + i32_t compare( + const abs_eap_base_timer_c * const a_initializer, + const u32_t a_id, + const abs_eap_base_timer_c * const b_initializer, + const u32_t b_id); + + //-------------------------------------------------- +}; // class eap_timer_queue_hash_c + +// --------------------------------------------------------------------- + +/// Size of the hash array of eap_timer_queue_hash_c elements. +/// Hash array optimizes the cancellation of timer event. +const u32_t EAP_TIMER_QUEUE_HASH_SIZE = 1024; + +/// This class implements the timer queue. +/** + * User of the timer queue must be inherited from abs_eap_base_timer_c. + * The abs_eap_base_timer_c class is the call back interface from timer queue to the user. + * @see Note the timer queue interface is used through abs_eap_am_tools_c. + * Functions are abs_eap_am_tools_c::get_timer_resolution_ms(), + * abs_eap_am_tools_c::set_timer(), + * abs_eap_am_tools_c::cancel_timer(), + * abs_eap_am_tools_c::cancel_all_timers() and + * abs_eap_am_tools_c::pulse_timer() + * + * In the following figure m_timer_queue is pointer to the first timer event in the list. + * The timer list is horizontal list right from m_timer_queue. + * Each timer event in the list represents one time segment + * that must elapse to zero before event is active. Timer event - the square box in the figure - + * is type of eap_timer_queue_event_c. + * Each time segment includes list of the same time values, the vertical lists. + * + * Place for new timer event is found by stepping the the horizontal timer list + * and adding the time values sum until the list ends + * or time sum is equal or greater than time of the new timer event. + * If time sum is equal to the time of the new timer event, the new timer event is + * added to the second in the vertical list. If time sum is greater than the time of the new timer event, + * the new timer event is added before the existing time event. In this case a new vertical list is created. + * If the list ends the new time event is added to the end of the timer queue. + * + * @code + * +---------------+ +---------------+ +---------------+ + * m_timer_queue->| m_time_ms 0 |->| m_time_ms 2000|->| m_time_ms 500 | // This horizontal list is the timer queue. + * +---------------+ +---------------+ +---------------+ + * | | | + * V V V + * +---------------+ +---------------+ +---------------+ + * | m_time_ms 0 | | m_time_ms 0 | | m_time_ms 0 | + * +---------------+ +---------------+ +---------------+ + * | | + * V V + * +---------------+ +---------------+ + * | m_time_ms 0 | | m_time_ms 0 | + * +---------------+ +---------------+ + * | + * V + * +---------------+ + * | m_time_ms 0 | + * +---------------+ + * // Each vertical list includes the timer events that have the same time. + * @endcode + */ +class EAP_EXPORT eap_timer_queue_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to the first timer event. + eap_timer_queue_event_c *m_timer_queue; + + /// These are begin and end of the list of new events + /// that are will be added to timer queue + /// during the next pulse_timer() function + /// call. + eap_timer_queue_event_c *m_new_event_begin; + eap_timer_queue_event_c *m_new_event_end; + + /// This is the resolution of this timer queue. + /// Each pulse is assumed to be this length. + /// This is also the minimum timer value. + u32_t m_timer_resolution_ms; + + /// This is hash array of timer events. + eap_timer_queue_hash_c * m_map[EAP_TIMER_QUEUE_HASH_SIZE]; + + /// This indicates whether this timer queue is active. Inactive timer queue does not accept new timer events. + bool m_is_active; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + bool m_use_eap_millisecond_timer; + + //-------------------------------------------------- + + /** + * this function traces one timer event. + */ + void trace_timer_event( + const eap_const_string prefix, + const eap_timer_queue_event_c * const event); + + /** + * This function traces all initialized timer events. + */ + void trace_timer(); + + eap_status_e add_hash_of_timer_event( + eap_timer_queue_event_c * const event, + const abs_eap_base_timer_c * const initializer, + const u32_t id); + + eap_timer_queue_event_c * get_hashed_timer_event( + const abs_eap_base_timer_c * const initializer, + const u32_t id); + + eap_status_e remove_hash_of_timer_event( + eap_timer_queue_event_c * const event); + + //-------------------------------------------------- + + // + u32_t hash( + const u32_t size, + const abs_eap_base_timer_c * const initializer, + const u32_t id) const; + + //-------------------------------------------------- + + /** + * This function deactivate this timer queue. + * This is called before the timer queue is deleted. + * Inactive timer queue does not accept new timer events. + */ + void deactivate_timer_queue(); + + /** + * This function adds the timer event immediately to timer queue. + */ + eap_status_e add_timer( + eap_timer_queue_event_c *event); + + /** + * New timer events are added with this function because the next pulse might + * be very long, and the long pulse will cause the new event expire immediately. + * By using this function the shortest timer events in the + * timer queue are handled and after that the new timer events + * are added to timer queue. + */ + eap_status_e add_pending_timer(); + + void add_end_of_vertical_list( + eap_timer_queue_event_c *begin, + eap_timer_queue_event_c *event); + + eap_status_e add_new_pending_timer( + eap_timer_queue_event_c *event); + + /** + * This function cancels all pending timer events. + */ + eap_status_e cancel_pending_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor does nothing special. + * Note user is assumed to call cancel_all_timers() + * before timer queue is deleted. + */ + virtual ~eap_timer_queue_c(); + + //-------------------------------------------------- + + /** + * Constructor initializes the timer queue. + * @param timer_resolution_ms is the resolution in milli seconds of this timer. + * The pulse() member function is assumed to be called using + * timer_resolution_ms interval. + */ + eap_timer_queue_c( + abs_eap_am_tools_c * const tools, + const u32_t timer_resolution_ms); + + //-------------------------------------------------- + + /** + * This function re-activates timer queue. + * Symbian AM call this function when AM-tools object is re-used. + * This can be called after cancel_all_timers() function. + * cancel_all_timers() function de-activated timer queue. + */ + eap_status_e re_activate_timer_queue(); + + //-------------------------------------------------- + + /** + * This function returns flag whether millisecond timer is in use (true) or not (false). + */ + bool get_use_eap_milli_second_timer(); + + //-------------------------------------------------- + + /** + * This function activates millisecond timer with true value. + */ + void set_use_eap_milli_second_timer(const bool use_eap_millisecond_timer); + + //-------------------------------------------------- + + /** + * @return Returns the initialized timer resolution. + */ + u32_t get_timer_resolution_ms(); + + //-------------------------------------------------- + + /** + * @return Sets the timer resolution. + */ + void set_timer_resolution_ms(const u32_t timer_resolution_ms); + + //-------------------------------------------------- + + /** + * The pulse() member function is assumed to be called using + * timer_resolution_ms interval. + * This function decreases the remaining time of the first timer event. + * When remaining time reaches zero the timer queue calls the timer_expired() function. + * Function returns the next sleep time in milli seconds. + */ + u32_t pulse_timer( + const u32_t elapsed_time_in_ms, + const bool can_call_timer_expired_when_true); + + //-------------------------------------------------- + + // + bool get_timer_queue_is_empty(); + + //-------------------------------------------------- + + /** + * This function initializes a new timer event. + * @param initializer is the caller of this function. Call backs are directed to initializer. + * @param id is selected by caller. Caller could separate timer events by this value. + * @param data is pointer to any data. After timer is alapsed or cancelled + * timer queue calls timer_delete_data() function. The initializer could delete possible + * allocated data. + * @param p_time_ms is the time after this timer event should elapse. + */ + eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t time_ms); + + //-------------------------------------------------- + + /** + * This function cancels the timer event. + * @param initializer is the caller of this function. Call backs are directed to initializer. + * @param id is selected by caller. Caller could separate timer events by this value. + */ + eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id); + + //-------------------------------------------------- + + /** + * This function cancels all timer events from this timer queue. + * This is called before the timer queue is deleted. + */ + eap_status_e cancel_all_timers(); + + //-------------------------------------------------- + + /** + * The get_is_valid() function returns the status of the eap_core object. + * True indicates the object is initialized succesfully. + */ + bool get_is_valid() const; + + //-------------------------------------------------- +}; // class eap_timer_queue_c + + +#endif //#if !defined(_EAP_TIMER_QUEU_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_tlv_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_tlv_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,162 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TLV_HEADER_H_) +#define _EAP_TLV_HEADER_H_ + +#include "eap_am_types.h" +#include "eap_tools.h" +#include "eap_general_header_base.h" + +/** @file */ + + +typedef u32_t eap_tlv_type_t; + +const eap_tlv_type_t eap_tlv_type_none = 0ul; + +//---------------------------------------------------------------------------- + + +/// This class defines header of Attribute-Value Pairs. +/** + * Here is a figure of header of Attribute-Value Pairs. + * Value data follows eap_tlv_header_c. + * @code + * EAP-TLV-header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Value... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + * + * @code + * The fields of this header are: + * 32-bits Type; This is a type of value. + * 32-bits value length (Length); This is a length field, the length (in bytes) of the following value. + * @endcode + * + */ +class EAP_EXPORT eap_tlv_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + /// This is enumeration of offsets to data fields. + enum offsets + { + m_type_offset = 0ul, ///< This is offset to fags and tlv type 32-bit field. + m_length_offset = m_type_offset+sizeof(u32_t), ///< This is offset to length 32-bit field. + m_data_offset = m_length_offset+sizeof(u32_t), ///< This is offset to data field. + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_tlv_header_c class does nothing. + */ + EAP_FUNC_IMPORT virtual ~eap_tlv_header_c(); + + /** + * The constructor of the eap_tlv_header_c class simply initializes the attributes. + */ + EAP_FUNC_IMPORT eap_tlv_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length); + + /** + * This function returns the type. + */ + EAP_FUNC_IMPORT eap_tlv_type_t get_type() const; + + /** + * This function returns the data length of value. + */ + EAP_FUNC_IMPORT u32_t get_value_length() const; + + /** + * This function returns the header length of TLV. + */ + EAP_FUNC_IMPORT static u32_t get_header_length(); + + /** + * This function returns pointer to the offset of value. + * @param offset is the offset of queried data in bytes. + * @param contignuous_bytes is the length of queried data in bytes. + */ + EAP_FUNC_IMPORT u8_t * get_value_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + + /** + * This function returns pointer to begin of value. + * @param contignuous_bytes is the length of queried data in bytes. + */ + EAP_FUNC_IMPORT u8_t * get_value(const u32_t contignuous_bytes) const; + + + /** + * This function checks the header is valid. + */ + EAP_FUNC_IMPORT eap_status_e check_header() const; + + /** + * This function returns the type. + */ + EAP_FUNC_IMPORT eap_status_e set_type(const eap_tlv_type_t type); + + /** + * This function sets the value length. + */ + EAP_FUNC_IMPORT eap_status_e set_value_length(const u32_t value_length); + + /** + * This function resets the TLV header. + */ + EAP_FUNC_IMPORT eap_status_e reset_header( + const eap_tlv_type_t type, + const u32_t value_length); + + // + //-------------------------------------------------- +}; // class eap_tlv_header_c + + +//-------------------------------------------------- + +#endif //#if !defined(_EAP_TLV_HEADER_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_tlv_message_data.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_tlv_message_data.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,205 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TLV_MESSAGE_DATA_H_) +#define _EAP_TLV_MESSAGE_DATA_H_ + +#include "eap_am_types.h" +#include "eap_tools.h" +#include "eap_array.h" +#include "eap_tlv_header.h" + +/** @file */ + + +//---------------------------------------------------------------------------- + + +/// This class defines message data composed of Attribute-Value Pairs (See eap_tlv_header_c). +/** + * Here is a figure of message data composed of Attribute-Value Pairs (See eap_tlv_header_c). + * Value data follows eap_tlv_message_data_c. + * @code + * EAP-TLV-message data: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Length = 8 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Value 1 | + * +-+- -+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Length = 4 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Value 2 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Length = 4 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Value 3 | + * +-+- -+-+ + * | | + * +-+- -+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * NOTE, the length of value could be anythin between 0 ... (2^32)-1. + * Only the free memory limits the length of the value. + * There are no padding between Attribute-Value Pairs. + * The next Attribute-Value Pair starts exactly after the previous + * Value of previous Attribute-Value Pair. + * @endcode + * + */ +class EAP_EXPORT eap_tlv_message_data_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + eap_variable_data_c m_message_data; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_tlv_message_data_c class does nothing. + */ + EAP_FUNC_IMPORT virtual ~eap_tlv_message_data_c(); + + /** + * The constructor of the eap_tlv_message_data_c class simply initializes the attributes. + */ + EAP_FUNC_IMPORT eap_tlv_message_data_c( + abs_eap_am_tools_c * const tools); + + /** + * This function should increase reference count. + */ + EAP_FUNC_IMPORT void object_increase_reference_count(); + + /** + * This function should first decrease reference count + * and second return the remaining reference count. + * Reference count must not be decreased when it is zero. + */ + EAP_FUNC_IMPORT u32_t object_decrease_reference_count(); + + /** + * This function returns the pointer to the data. + * Empty message return NULL pointer. + */ + EAP_FUNC_IMPORT void * get_message_data() const; + + /** + * This function returns the length of the data. + * Empty message return zero. + */ + EAP_FUNC_IMPORT u32_t get_message_data_length() const; + + EAP_FUNC_IMPORT eap_status_e allocate_message_data_buffer( + const u32_t approximate_buffer_requirement); + + /** + * This function copies message data. + * Data must be formatted as EAP-TLV-message data. + */ + EAP_FUNC_IMPORT eap_status_e copy_message_data( + const u32_t length, + const void * const value); + + /** + * This function sets message data. + * Note the data is referenced not copied. + * Data must be formatted as EAP-TLV-message data. + */ + EAP_FUNC_IMPORT eap_status_e set_message_data( + const u32_t length, + const void * const value); + + /** + * This function adds data to message. + */ + EAP_FUNC_IMPORT eap_status_e add_message_data( + const eap_tlv_type_t type, + const u32_t length, + const void * const data); + + /** + * This function adds array of data to message. + */ + EAP_FUNC_IMPORT eap_status_e add_message_data_array( + const eap_tlv_type_t type, + const u32_t length_of_each_data_block, + eap_array_c * const data_array); + + /** + * This function adds header of structured data to message. + */ + EAP_FUNC_IMPORT eap_status_e add_message_header( + const eap_tlv_type_t type, + const u32_t length); + + /** + * This function parses eap_tlv_header_c blocks from message to tlv_blocks. + */ + EAP_FUNC_IMPORT eap_status_e parse_message_data( + eap_array_c * const tlv_blocks); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function allocates buffer to message of specified type. + * Function returns pointer to the value field of specified length. + */ + EAP_FUNC_IMPORT eap_status_e allocate_message_buffer( + const eap_tlv_type_t type, + const u32_t length, + void * * const buffer); + + // + //-------------------------------------------------- +}; // class eap_tlv_message_data_c + + +//-------------------------------------------------- + +#endif //#if !defined(_EAP_TLV_MESSAGE_DATA_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_tools.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_tools.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,611 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_TOOLS_H_ ) +#define _EAP_TOOLS_H_ + +/** @file */ + +#include "eap_am_compiler_flags.h" + +#include "eap_variable_data.h" +#include "eap_status.h" +#include "eap_am_export.h" + +#if defined(USE_EAP_STACK_TRACE) || defined(USE_EAP_ASSERT_STACK_TRACE) + #include "eap_am_stack_trace.h" +#endif //#if defined(EAP_STACK_TRACE) + + +//---------------------------------------------------------------------------------- + +/** + * This function changes 16-bit unsigned integer from host order to network order. + */ +EAP_C_FUNC_IMPORT u16_t eap_htons(const u16_t value); + +/** + * This function changes 32-bit unsigned integer from host order to network order. + */ +EAP_C_FUNC_IMPORT u32_t eap_htonl(const u32_t value); + +/** + * This function changes 64-bit unsigned integer from host order to network order. + */ +EAP_C_FUNC_IMPORT u64_t eap_htonll(const u64_t value); + + +/** + * This function changes 16-bit unsigned integer from network order to host order. + */ +#define eap_ntohs(addr) eap_htons(addr) + +/** + * This function changes 32-bit unsigned integer from network order to host order. + */ +#define eap_ntohl(addr) eap_htonl(addr) + +/** + * This function changes 64-bit unsigned integer from network order to host order. + */ +#define eap_ntohll(addr) eap_htonll(addr) + + +/** + * This function changes 16-bit unsigned integer from host order to little endian order. + * This is used in some crypto algorithms. + */ +EAP_C_FUNC_IMPORT u16_t eap_host_to_little_endian_short(const u16_t value); + +/** + * This function changes 32-bit unsigned integer from host order to little endian order. + * This is used in some crypto algorithms. + */ +EAP_C_FUNC_IMPORT u32_t eap_host_to_little_endian_long(const u32_t value); + +/** + * This function changes 64-bit unsigned integer from host order to little endian order. + * This is used in some crypto algorithms. + */ +EAP_C_FUNC_IMPORT u64_t eap_host_to_little_endian_long(const u64_t value); + +/** + * This function write 16-bit unsigned integer which is in little endian order to memory. + */ +EAP_C_FUNC_IMPORT eap_status_e eap_write_u16_t_little_endian_order( + void * const p_data, + const u32_t data_length, + const u16_t value); + +/** + * This function write 32-bit unsigned integer which is in little endian order to memory. + */ +EAP_C_FUNC_IMPORT eap_status_e eap_write_u32_t_little_endian_order( + void * const p_data, + const u32_t data_length, + const u32_t value); + +/** + * This function write 64-bit unsigned integer which is in little endian order to memory. + */ +EAP_C_FUNC_IMPORT eap_status_e eap_write_u64_t_little_endian_order( + void * const p_data, + const u32_t data_length, + const u64_t value); + +/** + * This function reads 16-bit unsigned integer which is in little endian order from memory + * and returns value in host order. + */ +EAP_C_FUNC_IMPORT u16_t eap_read_u16_t_little_endian_order( + const void * const data, + const u32_t data_length); + +/** + * This function reads 32-bit unsigned integer which is in little endian order from memory + * and returns value in host order. + */ +EAP_C_FUNC_IMPORT u32_t eap_read_u32_t_little_endian_order( + const void * const p_data, + const u32_t data_length); + +/** + * This function reads 64-bit unsigned integer which is in little endian order from memory + * and returns value in host order. + */ +EAP_C_FUNC_IMPORT u64_t eap_read_u64_t_little_endian_order( + const void * const p_data, + const u32_t data_length); + +/** + * This function reads 16-bit unsigned integer which is in network order from memory + * and returns value in host order. + */ +EAP_C_FUNC_IMPORT u16_t eap_read_u16_t_network_order( + const void * const data, + const u32_t data_length); + +/** + * This function reads 24-bit unsigned integer which is in network order from memory + * and returns it in 32-bit value in host order. + */ +EAP_C_FUNC_IMPORT u32_t eap_read_u24_t_network_order( + const void * const data, + const u32_t data_length); + +/** + * This function reads 32-bit unsigned integer which is in network order from memory + * and returns value in host order. + */ +EAP_C_FUNC_IMPORT u32_t eap_read_u32_t_network_order( + const void * const data, + const u32_t data_length); + +/** + * This function reads 64-bit unsigned integer which is in network order from memory + * and returns value in host order. + */ +EAP_C_FUNC_IMPORT u64_t eap_read_u64_t_network_order( + const void * const data, + const u32_t data_length); + + +/** + * This function writes 16-bit unsigned integer to network order to memory + * and returns status eap_status_ok when successfull. + */ +EAP_C_FUNC_IMPORT eap_status_e eap_write_u16_t_network_order( + void * const data, + const u32_t data_length, + const u16_t value); + +/** + * This function writes 24-bit unsigned integer to network order to memory + * and returns status eap_status_ok when successfull. + * Note only 24-bit least significant bits are written from 32-bit value. + */ +EAP_C_FUNC_IMPORT eap_status_e eap_write_u24_t_network_order( + void * const data, + const u32_t data_length, + const u32_t value); + +/** + * This function writes 32-bit unsigned integer to network order to memory + * and returns status eap_status_ok when successfull. + */ +EAP_C_FUNC_IMPORT eap_status_e eap_write_u32_t_network_order( + void * const data, + const u32_t data_length, + const u32_t value); + +/** + * This function writes 64-bit unsigned integer to network order to memory + * and returns status eap_status_ok when successfull. + */ +EAP_C_FUNC_IMPORT eap_status_e eap_write_u64_t_network_order( + void * const data, + const u32_t data_length, + const u64_t value); + + + +EAP_C_FUNC_IMPORT u64_t eap_shift_left_64_bit(u64_t value, u32_t shift); + +EAP_C_FUNC_IMPORT u64_t eap_shift_right_64_bit(u64_t value, u32_t shift); + + +inline u64_t eap_read_u64_t_host_order( + const void * const p_data, + const u32_t data_length) +{ + #if defined(EAP_LITTLE_ENDIAN) /// byte 0 is least significant (i386) + return eap_read_u64_t_little_endian_order( + p_data, + data_length); + #elif defined(EAP_BIG_ENDIAN) /// byte 0 is most significant (mc68k) + return eap_read_u64_t_network_order( + p_data, + data_length); + #else + #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ + or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). + #endif +} + + +inline eap_status_e eap_write_u64_t_host_order( + void * const data, + const u32_t data_length, + const u64_t value) +{ + #if defined(EAP_LITTLE_ENDIAN) /// byte 0 is least significant (i386) + return eap_write_u64_t_little_endian_order( + data, + data_length, + value); + #elif defined(EAP_BIG_ENDIAN) /// byte 0 is most significant (mc68k) + return eap_write_u64_t_network_order( + data, + data_length, + value); + #else + #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ + or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). + #endif +} + +//---------------------------------------------------------------------------------- + +#if defined(__SYMBIAN32__) + /// This is name of default file for EAP Core traces. + const eap_const_string EAP_DEFAULT_TRACE_FILE = EAPL("c:\\logs\\eapol\\eap_core.log"); + #define __PRETTY_FUNCTION__ "function()" +#elif defined(__GNUC__) || defined(__arm) + /// This is name of default file for EAP Core traces. + const char * const EAP_DEFAULT_TRACE_FILE = "/tmp/eap_core.log"; +#elif defined(_WIN32) && !defined(__GNUC__) + #define __PRETTY_FUNCTION__ "function()" + /// This is name of default file for EAP Core traces. + const char * const EAP_DEFAULT_TRACE_FILE = "c:\\temp\\eap_core.log"; +#endif + + +#define EAP_NULL_FUNCTION /* do{}while(0) // This causes a lot of warning C4127: conditional expression is constant. */ + + +#if defined(NO_EAP_TRACE) +#error Use of NO_EAP_TRACE is deprecated. Please, define USE_EAP_TRACE when EAP traces are needed. +#endif //defined(NO_EAP_TRACE) + +#if defined(NO_EAP_DEBUG_TRACE) +#error Use of NO_EAP_DEBUG_TRACE is deprecated. Please, define USE_EAP_DEBUG_TRACE when EAP debug traces are needed. +#endif //defined(NO_EAP_DEBUG_TRACE) + +#if defined(NO_EAP_TRACE_STRINGS) +#error Use of NO_EAP_TRACE_STRINGS is deprecated. Please, define USE_EAP_TRACE_STRINGS when EAP debug trace strings are needed. +#endif //defined(NO_EAP_TRACE_STRINGS) + +#if defined(NO_EAP_ASSERTS) +#error Use of NO_EAP_ASSERTS is deprecated. Please, define USE_EAP_ASSERTS when EAP assertions are needed. +#endif //!defined(USE_EAP_ASSERTS) + +#if defined(NO_EAP_STATUS_RETURN) +#error Use of NO_EAP_STATUS_RETURN is deprecated. Please, define USE_EAP_STATUS_RETURN when EAP status return traces are needed. +#endif //!defined(NO_EAP_STATUS_RETURN) + +#if defined(NO_EAP_FUNCTION_TRACE) +#error Use of NO_EAP_FUNCTION_TRACE is deprecated. Please, define USE_EAP_FUNCTION_TRACE when heavy EAP function traces are needed. +#endif //!defined(NO_EAP_FUNCTION_TRACE) + + +#if !defined(USE_EAP_TRACE_ALWAYS) && !defined(USE_EAP_TRACE) + + #define EAP_TRACE_ALWAYS(object_name, flags, _parameter_list_) EAP_NULL_FUNCTION + + #define EAP_TRACE_DATA_ALWAYS(object_name, flags, _parameter_list_) EAP_NULL_FUNCTION + +#else + + /** + * This function traces formatted string with parameters to a file. + * For example + * @code + * EAP_TRACE_ALWAYS(m_am_tools, TRACE_FLAGS_TIMER, (EAPL("~eap_type_gsmsim_c(): 0x%08x\n"), this)); + * @endcode + * + */ + #define EAP_TRACE_ALWAYS(object_name, flags, _parameter_list_) \ + if (object_name != 0 && ((*(object_name)).get_trace_mask() & (flags))) \ + { \ + (*(object_name)).formatted_print _parameter_list_ ; \ + } \ + + /** + * This function traces data bytes to a file. + * For example + * @code + * EAP_TRACE_DATA_ALWAYS(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("new_nai"), + * new_nai->get_data(new_nai->get_data_length()), + * new_nai->get_data_length()));". + * @endcode + * + */ + #define EAP_TRACE_DATA_ALWAYS(object_name, flags, _parameter_list_) \ + if (object_name != 0 && ((*(object_name)).get_trace_mask() & (flags))) \ + { \ + (*(object_name)).trace_data _parameter_list_ ; \ + } \ + +#endif //#if !defined(USE_EAP_TRACE_ALWAYS) + + +#if !defined(USE_EAP_TRACE) + + #define EAP_TRACE_ERROR(object_name, flags, _parameter_list_) EAP_NULL_FUNCTION + + #define EAP_TRACE_DEBUG(object_name, flags, _parameter_list_) EAP_NULL_FUNCTION + + #define EAP_TRACE_FORMAT(object_name, _parameter_list_) EAP_NULL_FUNCTION + + #define EAP_TRACE_RETURN_STRING(object_name, string) EAP_NULL_FUNCTION + + #define EAP_TRACE_DATA_ERROR(object_name, flags, _parameter_list_) EAP_NULL_FUNCTION + + #define EAP_TRACE_DATA_DEBUG(object_name, flags, _parameter_list_) EAP_NULL_FUNCTION + + #define EAP_TRACE_BEGIN(object_name, flags) EAP_NULL_FUNCTION + + #define EAP_TRACE_END(object_name, flags) EAP_NULL_FUNCTION + +#else + + /** + * This function traces formatted string with parameters to a file. + * Trace includes ERROR string, file name and line number. + * For example + * @code + * EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_TIMER, (EAPL("~eap_type_gsmsim_c(): 0x%08x\n"), this)); + * @endcode + * + */ + #define EAP_TRACE_ERROR(object_name, flags, _parameter_list_) \ + if (object_name != 0) \ + { \ + (*(object_name)).check_activate_trace_on_error(); \ + if (((*(object_name)).get_trace_mask() & ((flags) | eap_am_tools_c::eap_trace_mask_error))) \ + { \ + (*(object_name)).formatted_print(EAPL("ERROR: source: %s:%d\n"), __FILE__, __LINE__); \ + (*(object_name)).formatted_print _parameter_list_ ; \ + } \ + } \ + + /** + * This function traces data bytes to a file. + * For example + * @code + * EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("new_nai"), + * new_nai->get_data(new_nai->get_data_length()), + * new_nai->get_data_length()));". + * @endcode + * + */ + #define EAP_TRACE_DATA_ERROR(object_name, flags, _parameter_list_) \ + if (object_name != 0) \ + { \ + (*(object_name)).check_activate_trace_on_error(); \ + if (((*(object_name)).get_trace_mask() & ((flags) | eap_am_tools_c::eap_trace_mask_error))) \ + { \ + (*(object_name)).trace_data _parameter_list_ ; \ + } \ + } \ + + /** + * @{ Remove debug traces in release version when appropriate. } + */ + //#if defined(_DEBUG) && defined(USE_EAP_DEBUG_TRACE) + #if defined(USE_EAP_DEBUG_TRACE) + + /** + * This function traces formatted string with parameters to a file. + * This is used only in debug version. + * For example + * @code + * EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_TIMER, (EAPL("~eap_type_gsmsim_c(): 0x%08x\n"), this)); + * @endcode + * + */ + #define EAP_TRACE_DEBUG(object_name, flags, _parameter_list_) \ + if (object_name != 0 && ((*(object_name)).get_trace_mask() & ((flags) | eap_am_tools_c::eap_trace_mask_error))) \ + { \ + if (((*(object_name)).get_trace_mask() & ((flags) & eap_am_tools_c::eap_trace_mask_error))) \ + { \ + (*(object_name)).formatted_print(EAPL("ERROR: source: %s:%d\n"), __FILE__, __LINE__); \ + (*(object_name)).formatted_print _parameter_list_ ; \ + } \ + else if (((*(object_name)).get_trace_mask() & (flags))) \ + { \ + (*(object_name)).formatted_print _parameter_list_ ; \ + } \ + else \ + { \ + /* Do nothing. This else is because lint complains the missing else. */ \ + } \ + } \ + + /** + * This function traces data bytes to a file. + * This is used only in debug version. + * For example + * @code + * EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("new_nai"), + * new_nai->get_data(new_nai->get_data_length()), + * new_nai->get_data_length()));". + * @endcode + * + */ + #define EAP_TRACE_DATA_DEBUG(object_name, flags, _parameter_list_) \ + if (object_name != 0 && ((*(object_name)).get_trace_mask() & (flags))) \ + { \ + (*(object_name)).trace_data _parameter_list_ ; \ + } \ + + /** + * This function formats string to a buffer. + * This is used only in debug version. + * For example + * @code + * EAP_TRACE_FORMAT(m_am_tools, (buffer, buffer_size, EAPL("new_nai %d, %s"), + * foo, + * EAPL("some string")));". + * @endcode + * + */ + #define EAP_TRACE_FORMAT(object_name, _parameter_list_) \ + if (object_name != 0 && (*(object_name)).get_trace_mask()) \ + { \ + (*(object_name)).snprintf _parameter_list_; \ + } \ + + #define EAP_TRACE_RETURN_STRING(object_name, string) \ + eap_automatic_trace_string_c __eap_trace_function_returns__(object_name, string); + + /** + * This flag indicates that the debug traces are active. + * Functions can use this flag to deduce whether debug related + * parameters should be introduced. + */ + #define EAP_DEBUG_TRACE_ACTIVE + + #else + + #define EAP_TRACE_DEBUG(object_name, flags, _parameter_list_) EAP_NULL_FUNCTION + + #define EAP_TRACE_DATA_DEBUG(object_name, flags, _parameter_list_) EAP_NULL_FUNCTION + + #define EAP_TRACE_FORMAT(object_name, _parameter_list_) EAP_NULL_FUNCTION + + #define EAP_TRACE_RETURN_STRING(object_name, string) EAP_NULL_FUNCTION + + #endif + + + #if !defined(USE_EAP_FUNCTION_TRACE) + + #define EAP_TRACE_BEGIN(object_name, flags) EAP_NULL_FUNCTION + + #define EAP_TRACE_END(object_name, flags) EAP_NULL_FUNCTION + + #else + /** + * This function traces begin of the function with name, file and line number to a file. + * For example + * @code + * EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + * @endcode + * + */ + #define EAP_TRACE_BEGIN(object_name, flags) \ + if (object_name != 0 && ((*(object_name)).get_trace_mask() & (eap_am_tools_c::eap_trace_mask_functions))) \ + { \ + (*(object_name)).formatted_print(EAPL("-> %s:%s:%d\n"), __PRETTY_FUNCTION__, __FILE__, __LINE__); \ + } \ + + /** + * This function traces end of the function with name, file and line number to a file. + * For example + * @code + * EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + * @endcode + * + */ + #define EAP_TRACE_END(object_name, flags) \ + if (object_name != 0 && ((*(object_name)).get_trace_mask() & (eap_am_tools_c::eap_trace_mask_functions))) \ + { \ + (*(object_name)).formatted_print(EAPL("<- %s:%s:%d\n"), __PRETTY_FUNCTION__, __FILE__, __LINE__); \ + } \ + + #endif + +#endif //#if !defined(USE_EAP_TRACE) + + + +#if defined(USE_EAP_STACK_TRACE) + + #define EAP_STACK_TRACE_TOOLS(am_tools, address) \ + { \ + stack_trace st_trace(am_tools); \ + st_trace.trace(address); \ + } \ + + #define EAP_STACK_TRACE(address) \ + EAP_STACK_TRACE_TOOLS(m_am_tools, address) + +#else + + #define EAP_STACK_TRACE_TOOLS(am_tools, address) EAP_NULL_FUNCTION + + #define EAP_STACK_TRACE(address) EAP_NULL_FUNCTION + +#endif //#if defined(EAP_STACK_TRACE) + + +#if defined(USE_EAP_ASSERT_STACK_TRACE) + + #define EAP_ASSERT_STACK_TRACE_TOOLS(am_tools, address) \ + { \ + stack_trace st_trace(am_tools); \ + st_trace.trace(address); \ + } \ + + #define EAP_ASSERT_STACK_TRACE(address) \ + EAP_ASSERT_STACK_TRACE_TOOLS(m_am_tools, address) + +#else + + #define EAP_ASSERT_STACK_TRACE_TOOLS(am_tools, address) EAP_NULL_FUNCTION + + #define EAP_ASSERT_STACK_TRACE(address) EAP_NULL_FUNCTION + +#endif //#if defined(EAP_STACK_TRACE) + + + +/// This defines one if case for a constant +/// that returns constant name string. +#define EAP_IF_RETURN_STRING(type, const_type) \ + if ((type) == (const_type)) \ + { \ + return EAPL(#const_type); \ + } + + +#if !defined(lint) + #if defined(__GNUC__) || defined(__ARMCC__) || defined(__arm) + /// This prevent compiler warning of unused variable. + #define EAP_UNREFERENCED_PARAMETER(P) \ + if ((&(P)) == (&(P))) \ + ; \ + + #else + /// This prevent compiler warning of unused variable. + #define EAP_UNREFERENCED_PARAMETER(P) (P) + #endif +#else // lint + // Note: lint -e530 says don't complain about uninitialized variables for + // this varible. Error 527 has to do with unreachable code. + // -restore restores checking to the -save state + /// This prevent compiler warning of unused variable. + #define EAP_UNREFERENCED_PARAMETER(P) \ + /*lint -save -e527 -e530 */ \ + {\ + (P) = (P); \ + } \ + + /*lint -restore */ +#endif // lint + +//---------------------------------------------------------------------------------- + +#endif //#if !defined( _EAP_TOOLS_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_type_all.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_type_all.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_EAP_TYPE_ALL_H_) +#define _EAP_TYPE_ALL_H_ + +//#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "abs_eap_base_type.h" +#include "eap_variable_data.h" + +class abs_eap_configuration_if_c; + +//-------------------------------------------------- + +/** @file */ + +/** + * This function creates a new instance of EAP-type. + * @param tools is pointer to the abs_eap_am_tools class created by the adaptation module. + * @param partner is pointer to the caller of the new_eap_type(). + * @param type is the EAP-type that will be created. + * + * NOTE one module could include many EAP-types. + * EAP-type will callback caller using the partner pointer. + */ +EAP_C_FUNC_IMPORT eap_base_type_c * const new_eap_type( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const eap_type_value_e eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if); + +//-------------------------------------------------- + +#endif //#if !defined(_EAP_TYPE_ALL_H_) + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_type_all_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_type_all_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TYPE_ALL_TYPES_H_) +#define _EAP_TYPE_ALL_TYPES_H_ + + +#endif //#if !defined(_EAP_TYPE_ALL_TYPES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_type_selection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_type_selection.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TYPE_SELECTION_H_) +#define _EAP_TYPE_SELECTION_H_ + +#include "eap_am_assert.h" +#include "eap_variable_data.h" +#include "eap_header.h" + +//-------------------------------------------------- + +class abs_eap_am_tools_c; + + +/// eap_type_selection_c class stores infofmation of one supported EAP-type. +class EAP_EXPORT eap_type_selection_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + const eap_type_value_e m_type; + + const bool m_is_enabled; + + bool m_is_valid; + + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_type_selection_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_type_selection_c(); + + /** + */ + EAP_FUNC_IMPORT eap_type_selection_c( + abs_eap_am_tools_c * const tools, + const eap_type_value_e type, + const bool is_enabled); + + /** + * The get_type() function returns EAP-type. + */ + EAP_FUNC_IMPORT eap_type_value_e get_type() const; + + /** + * The get_is_enabled() function returns true when EAP-type is enabled. + */ + EAP_FUNC_IMPORT bool get_is_enabled() const; + + /** + * The copy() function copies the eap_type_selection_c object and data. + */ + EAP_FUNC_IMPORT eap_type_selection_c * copy() const; + + /** + * The get_is_valid() function returns the status of the object. + * @return True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid() const; + + /** + * The get_is_valid_data() function returns the status of the + * data included in eap_type_selection_c object. + * @return True indicates the object includes valid data. + */ + EAP_FUNC_IMPORT bool get_is_valid_data() const; + +}; // class eap_type_selection_c + + +#endif //#if !defined(_EAP_TYPE_SELECTION_H_) + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_variable_data.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_variable_data.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,495 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_VARIABLE_DATA_H_) +#define _EAP_VARIABLE_DATA_H_ + +#include "eap_am_types.h" +#include "eap_am_export.h" +//#include "eap_am_memory.h" +#include "eap_am_assert.h" +#include "eap_status.h" + +//-------------------------------------------------- + +class abs_eap_am_tools_c; + + +/// This class stores any data in byte array. +class EAP_EXPORT eap_variable_data_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c + abs_eap_am_tools_c * const m_am_tools; + + /// This struct decreases the memory print of eap_variable_data_c. + struct eap_variable_data_impl_str + { + /// This is pointer to the buffer. + u8_t *m_buffer; + + /// This indicates the length of the buffer. + u32_t m_buffer_length; + + /// This indicates the start of the data in the buffer. + u32_t m_real_data_start_index; + + /// This indicates the length of data in the buffer. + u32_t m_real_data_length; + + /// This indicates the buffer is initialized. The attribute m_buffer points + /// to a memory buffer which length is m_buffer_length bytes. + bool m_is_valid; + + /// This indicates the buffer will be freed in destructor. + bool m_free_buffer; + + /// This indicates the buffer pointed by m_buffer can be modified. + bool m_is_writable; + }; + + /// This is pointer to data of eap_variable_data_c. + /// This decreases memory print of eap_variable_data_c. + /// This decreases stack usage of EAP_Core. + eap_variable_data_impl_str * m_data; + + + EAP_FUNC_IMPORT eap_status_e initialize_members(); + + EAP_FUNC_IMPORT eap_status_e allocate_buffer( + const u32_t required_buffer_length); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor of the eap_variable_data class will release + * the buffer if attribute m_free_buffer is true. + */ + EAP_FUNC_IMPORT virtual ~eap_variable_data_c(); + + /** + * Constructor takes only one parameter called tools. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + */ + EAP_FUNC_IMPORT eap_variable_data_c( + abs_eap_am_tools_c * const tools); + + /** + * Constructor takes five parameters. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + * @param buffer is pointer to the buffer. + * @param buffer_length is size of the buffer. + * @param free_buffer indicates whether the buffer must be freed in the destructor. + * @param is_writable indicates whether the buffer is writable. + */ + EAP_FUNC_IMPORT eap_variable_data_c( + abs_eap_am_tools_c * const tools, + const void * const buffer, + const u32_t buffer_length, + bool free_buffer, + bool is_writable); + + + /** + * The get_is_valid() function returns the status of the eap_variable_data object. + * @return True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid() const; + + + /** + * The get_is_valid_data() function returns the status of the + * data included in eap_variable_data object. + * Note the object may include zero length data, and that is valid data. + * @return True indicates the object includes valid data. + */ + EAP_FUNC_IMPORT bool get_is_valid_data() const; + + /** + * The set_is_valid() function sets the state of the eap_variable_data object valid. + * The eap_variable_data_c object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * The set_is_invalid() function sets the state of the eap_variable_data object invalid. + * The eap_variable_data_c object calls this function after it is uninitialized. + */ + EAP_FUNC_IMPORT void set_is_invalid(); + + /** + * This function returns flag that indicates whether this + * buffer is writeble (true) or read only (false). + */ + EAP_FUNC_IMPORT bool get_is_writable() const; + + /** + * The get_data_offset() function returns the pointer to the buffer. + * @param offset is offset from the begin of the buffer. + * @param buffer_length is required count of bytes. + */ + EAP_FUNC_IMPORT u8_t * get_buffer_offset( + const u32_t offset, + const u32_t buffer_length) const; + + /** + * The get_buffer() function returns the pointer to the buffer. + */ + EAP_FUNC_IMPORT u8_t * get_buffer(const u32_t buffer_length) const; + + /** + * The get_data_offset() function returns the pointer to the data. + * @param offset is offset from the begin of the data. + * @param data_length is required count of bytes. + */ + EAP_FUNC_IMPORT u8_t * get_data_offset( + const u32_t offset, + const u32_t data_length) const; + + /** + * The get_data() function returns the pointer to the begin of the data. + */ + EAP_FUNC_IMPORT u8_t * get_data(const u32_t data_length) const; + + + /** + * The get_data() function returns the pointer to the begin of the data. + * This function assumes the whole data is needed. + * User should test the validity of object and the length of the data before use of it. + * The purpose of this function is reduce code size. + */ +#if defined(USE_EAP_INLINE_FUNCTIONS) + EAP_INLINE u8_t * get_data() const + { + +#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + if (m_data != 0 + && m_data->m_is_valid == true) + { +#endif //#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + + return m_data->m_buffer + m_data->m_real_data_start_index; + +#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + } + else + { + return 0; + } +#endif //#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + + } + +#else + + EAP_FUNC_IMPORT u8_t * get_data() const; + +#endif //#if defined(USE_EAP_INLINE_FUNCTIONS) + + + /** + * The get_data_length() function returns the count of bytes stored to the buffer. + */ +#if defined(USE_EAP_INLINE_FUNCTIONS) + EAP_INLINE u32_t get_data_length() const + { + +#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + if (m_data != 0 + && m_data->m_is_valid == true) + { +#endif //#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + + return m_data->m_real_data_length; + +#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + } + else + { + return 0u; + } +#endif //#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + + } + +#else + + EAP_FUNC_IMPORT u32_t get_data_length() const; + +#endif //#if defined(USE_EAP_INLINE_FUNCTIONS) + + + /** + * The get_buffer_length() function returns the size of the buffer. + */ +#if defined(USE_EAP_INLINE_FUNCTIONS) + + EAP_INLINE u32_t get_buffer_length() const + { + +#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + if (m_data != 0 + && m_data->m_is_valid == true) + { +#endif //#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + + return m_data->m_buffer_length; + +#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + } + else + { + return 0u; + } +#endif //#if defined(USE_EAP_INLINE_FUNCTIONS_RUNTIME_CHECKS) + + } + +#else + + EAP_FUNC_IMPORT u32_t get_buffer_length() const; + +#endif //#if defined(USE_EAP_INLINE_FUNCTIONS) + + + /** + * The reset_start_offset_and_data_length() function sets the begin offset of the data to zero + * and the length of data to zero. + */ + EAP_FUNC_IMPORT eap_status_e reset_start_offset_and_data_length(); + + /** + * The set_start_offset() function sets the begin offset of the data to index. + * With this function data in the begin of the buffer can be removed + * without any copy operations. + */ + EAP_FUNC_IMPORT eap_status_e set_start_offset(const u32_t index); + + /** + * The set_data_length() function changes the length of the data. + * @param length is count of bytes in the buffer. + */ + EAP_FUNC_IMPORT eap_status_e set_data_length( + const u32_t length); + + /** + * The set_buffer() function initializes the eap_variable_data object + * using existing buffer. + * @param buffer is pointer to the buffer. + * @param buffer_length is size of the buffer. + * @param free_buffer indicates whether the buffer must be freed in the destructor. + * @param is_writable indicates whether the buffer is writable. + */ + EAP_FUNC_IMPORT eap_status_e set_buffer( + const void * const buffer, + const u32_t buffer_length, + bool free_buffer, + bool is_writable); + + /** + * The set_buffer() function initializes the eap_variable_data object + * using existing buffer. + * @param buffer is pointer to the buffer. + * @param buffer_length is size of the buffer. + * @param free_buffer indicates whether the buffer must be freed in the destructor. + * @param is_writable indicates whether the buffer is writable. + */ + EAP_FUNC_IMPORT eap_status_e set_buffer( + void * const buffer, + const u32_t buffer_length, + bool free_buffer, + bool is_writable); + + /** + * The set_buffer() function initializes the eap_variable_data object + * using existing buffer. Note the data will be in the same buffer. + * Data can be modified through both eap_variable_data objects. + * @param buffer is pointer to the buffer. + */ + EAP_FUNC_IMPORT eap_status_e set_buffer( + const eap_variable_data_c * const buffer); + + /** + * The set_copy_of_buffer() function copies the data of the buffer. + * @param buffer points the data to be copied. + * @param buffer_length is length of the buffer in bytes. + */ + EAP_FUNC_IMPORT eap_status_e set_copy_of_buffer( + const void * const buffer, + const u32_t buffer_length); + + /** + * The set_copy_of_buffer() function copies the data of the buffer. + * The first version copies data pointed by parameter buffer. + * @param buffer points the data to be copied. + */ + EAP_FUNC_IMPORT eap_status_e set_copy_of_buffer( + const eap_variable_data_c * const buffer); + + /** + * The set_buffer_length() function sets length ot the buffer + * atleast to buffer_length bytes. + * If the buffer is empty or less than buffer_length bytes, length of the buffer is set to buffer_length bytes. + * If the buffer includes data, data is kept in the buffer. + * @param buffer points the data to be added. + * @param buffer_length is length of the buffer in bytes. + */ + EAP_FUNC_IMPORT eap_status_e set_buffer_length( + const u32_t buffer_length); + + /** + * The add_data() function adds data to the end of the buffer. + * If the buffer is empty the data is added to begin of the buffer. + * @param buffer points the data to be added. + * @param buffer_length is length of the buffer in bytes. + */ + EAP_FUNC_IMPORT eap_status_e add_data( + const void * const buffer, + const u32_t buffer_length); + + /** + * The add_data() function adds data to the end of the buffer. + * If the buffer is empty the data is added to begin of the buffer. + * @param buffer points the data to be added. + */ + EAP_FUNC_IMPORT eap_status_e add_data( + const eap_variable_data_c * const buffer); + + /** + * The add_data_to_offset() function adds data to the offset of the buffer. + * @param offset tells the place where data will begin. + * @param buffer points the data to be added. + * @param buffer_length is length of the buffer in bytes. + */ + EAP_FUNC_IMPORT eap_status_e add_data_to_offset( + const u32_t offset, + const void * const buffer, + const u32_t buffer_length); + + /** + * The add_data() function adds data to the offset of the buffer. + * @param offset tells the place where data will begin. + * @param buffer points the data to be added. + */ + EAP_FUNC_IMPORT eap_status_e add_data_to_offset( + const u32_t offset, + const eap_variable_data_c * const buffer); + + /** + * The add_end_null() function adds 16-bit null ('\0\0') to the end of the buffer. + * This does not increase the data length. + * This function is usefull when null terminated strings are stored to + * eap_variable_data_c object. + */ + EAP_FUNC_IMPORT eap_status_e add_end_null(); + + /** + * The reset() function resets the eap_variable_data object. + * Memory of the buffer is freed if the m_free_buffer attribute is true. + * Object does not include data after this call and get_is_valid_data() + * returns false. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + /** + * The init() function initializes the eap_variable_data object. + * @param length is length of buffer in bytes that is allocated. + * Buffer is set empty, data length is set zero. + */ + EAP_FUNC_IMPORT eap_status_e init( + const u32_t length); + + /** + * The copy() function copies the eap_variable_data object and data. + */ + EAP_FUNC_IMPORT eap_variable_data_c * copy() const; + + + /** + * The compare_length() function compares first compare_length bytes of the objects. + * @return Function returns zero when first compare_length bytes of the data are equal. + * If the data of the caller object is shorter than compare_length bytes + * or the first different byte of the caller is smaller the function returns negative value. + * If the data of the parameter object is shorter than compare_length bytes + * or the first different byte of the caller is larger the function returns positive value. + */ + EAP_FUNC_IMPORT i32_t compare_length( + const void * const data, + const u32_t data_length, + const u32_t compare_length_of_data) const; + + /** + * The compare_length() function compares first compare_length bytes of the objects. + * @return Function returns zero when first compare_length bytes of the data are equal. + * If the data of the caller object is shorter than compare_length bytes + * or the first different byte of the caller is smaller the function returns negative value. + * If the data of the parameter object is shorter than compare_length bytes + * or the first different byte of the caller is larger the function returns positive value. + */ + EAP_FUNC_IMPORT i32_t compare_length( + const eap_variable_data_c * const data, + const u32_t compare_length_of_data) const; + + /** + * The compare() function compares the objects. + * @return Function returns zero when data lengths and the data are equal. + * If the data of the caller object is shorter or the first different byte + * of the caller is smaller the function returns negative value. + * If the data of the caller object is longer or the first different byte + * of the caller is larger the function returns positive value. + */ + EAP_FUNC_IMPORT i32_t compare( + const void * const data, + const u32_t data_length) const; + + /** + * The compare() function compares the objects. + * @return Function returns zero when data lengths and the data are equal. + * If the data of the caller object is shorter or the first different byte + * of the caller is smaller the function returns negative value. + * If the data of the caller object is longer or the first different byte + * of the caller is larger the function returns positive value. + */ + EAP_FUNC_IMPORT i32_t compare( + const eap_variable_data_c * const data) const; + + + /** + * The hash() function returns HASH-value calculated from the data. + * @return Maximum returned value is size-1. Minimum returned value is zero. + */ + EAP_FUNC_IMPORT u32_t hash( + const u32_t size) const; + + //-------------------------------------------------- +}; // class eap_variable_data_c + + +#endif //#if !defined(_EAP_VARIABLE_DATA_H_) + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eap_wimax_authentication.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eap_wimax_authentication.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,228 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP stack interface for Wimax. +* +*/ + + + +#if !defined(_EAP_WIMAX_AUTHENTICATION_H_) +#define _EAP_WIMAX_AUTHENTICATION_H_ + +#include +#include +#include +#include +#include +#include +#include + +// FORWARD DECLARATIONS +class abs_eapol_wlan_database_reference_if_c; +class eap_session_core_c; +class eap_am_tools_symbian_c; +class eap_file_config_c; + + +// CLASS DECLARATION +class EAP_EXPORT eap_wimax_authentication_c +: public abs_eap_am_wimax_authentication_c +, public abs_eap_core_c +{ +public: + + EAP_FUNC_IMPORT eap_wimax_authentication_c( + abs_eap_am_tools_c* const tools, + abs_eap_wimax_authentication_c* const partner, + eap_am_wimax_authentication_c* const am_wauth, + const bool is_client_when_true); + +#if defined(EXPORT_DESTRUCTORS) + EAP_FUNC_IMPORT virtual ~eap_wimax_authentication_c(); // For GCC compilation +#else + virtual ~eap_wimax_authentication_c(); // For RVCT compilation +#endif + + /////////////////////////////////// + /* These are called by the lower */ + /* layer (= Wimax engine). */ + + EAP_FUNC_IMPORT static eap_wimax_authentication_c* new_eap_wimax_authentication_c( + abs_eap_am_tools_c* const tools, + abs_eap_wimax_authentication_c* const partner, + const bool is_client_when_true, + const abs_eapol_wlan_database_reference_if_c* const wimax_database_reference); + + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT eap_status_e cancel_all_authentication_sessions(); + + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length); + + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT eap_status_e configure(); + + + /** + * This function indicates the routing realms and NAI decoration + * to the adaptation module. The values are needed in the generation of + * EAP (outer) Identity Response and need to be dynamically obtained from + * the Wimax engine scanning results. The EAP stack requests these values + * from the default EAP type when it needs to respond to an EAP Identity + * Request. More info (e.g. the allowed character set) is available + * in RFC 4242. + * + * @param routing_info is a null pointer if RoutingRealm is not used. Otherwise it contains + * a string in the format "RoutingRealm1!RoutingRealm2!RoutingRealm3" (no null termination) + * in which RoutingRealm1 is the 1st location on the route, RoutingRealm2 is the 2nd + * location and so on. The parameter does not contain the home realm, as the home realm + * is static and requested from the adapatation module separately (obtained from the + * provisioning data). From this info, the EAP stack generates a NAI such as + * "RoutingRealm2!RoutingRealm3!HomeRealm!{nai_decoration}username@RoutingRealm1". + * + * @param nai_decoration is null if NAI decoration is not used. Otherwise it contains + * a string in the format "{avp1|avp2|avp3}", which the EAP stack copies to NAI. The NAI + * above becomes + * "RoutingRealm2!RoutingRealm3!HomeRealm!{avp1|avp2|avp3}username@RoutingRealm1". + */ + + EAP_FUNC_IMPORT eap_status_e set_wimax_parameters( + eap_variable_data_c* const routing_info, + eap_variable_data_c* const nai_decoration); + + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT bool get_is_client(); + + + //-------------------------------------------------- + + + /////////////////////////////////////////// + /* These are called by eap_session_core. */ + /* See abs_eap_core.h for descriptions. */ + + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT eap_status_e unload_module(const eap_type_value_e eap_type); + + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer = false); + + EAP_FUNC_IMPORT eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ); + + EAP_FUNC_IMPORT eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state); + + EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id); + + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t time_ms); + + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id); + + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + EAP_FUNC_IMPORT eap_status_e set_session_timeout( + const u32_t session_timeout_ms); + + //-------------------------------------------------- + +private: + + EAP_FUNC_IMPORT eap_status_e create_upper_stack(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Pointer to the tools class + abs_eap_am_tools_c * m_am_tools; + + /// Pointer to the lower layer in the stack + abs_eap_wimax_authentication_c * m_partner; + + /// Pointer to the AM of WAUTH. + eap_am_wimax_authentication_c * m_am_wauth; + + /// Pointer to the upper layer in the stack + eap_session_core_c * m_eap_core; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + bool m_is_valid; + + bool m_is_client; + + bool m_shutdown_was_called; + + bool m_block_state_notifications; + +}; // class eap_wimax_authentication_c + + +#endif //#if !defined(_EAP_WIMAX_AUTHENTICATION_H_) + +//-------------------------------------------------- + + +// End of file + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_core.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_core.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,582 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_CORE_H_) +#define _EAPOL_CORE_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_core.h" +#include "eap_core.h" +#include "abs_eapol_core.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "abs_eap_am_mutex.h" +#if !defined(NO_EAP_SESSION_CORE) + #include "eap_session_core.h" +#endif +#include "abs_eap_stack_interface.h" +#include "abs_eapol_key_state.h" +#include "eapol_rsna_key_header.h" +#if defined(USE_EAPOL_KEY_STATE) + #include "eapol_key_state.h" + #include "abs_eapol_key_state_map.h" +#endif //#if defined(USE_EAPOL_KEY_STATE) + + +/** @file */ + +/** + * This is the timer ID used with abs_eap_am_tools_c::set_timer() and abs_eap_am_tools_c::cancel_timer(). + */ +enum eapol_core_timer_id +{ + EAPOL_CORE_TIMER_SEND_START_AGAIN_ID, ///< See EAPOL_CORE_TIMER_SEND_START_AGAIN_TIMEOUT. + EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID, +}; + +/** + * This is the default time after a EAPOL-Start message is sent again from client. + */ +const u32_t EAPOL_CORE_TIMER_SEND_START_AGAIN_TIMEOUT = 2000u; + +/** + * This is the time after a EAPOL-Key Handshake will be removed. + */ +const u32_t EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_TIMEOUT = 0ul; + +/** + * This is the default value for how many time EAPOL-Start is sent. + */ +const u32_t EAPOL_CORE_MAX_EAPOL_START_SENDINGS = 3u; + + +class eapol_RC4_key_header_c; + + +/// A eapol_core_c class implements the basic functionality of EAPOL. +class EAP_EXPORT eapol_core_c +: public abs_eap_core_c +, public abs_eap_base_timer_c +, public abs_eap_stack_interface_c +#if defined(USE_EAPOL_KEY_STATE) +, public abs_eapol_key_state_c +, public abs_eapol_key_state_map_c +#endif //#if defined(USE_EAPOL_KEY_STATE) +{ + +private: + //-------------------------------------------------- + + /// This is back pointer to object which created this object. + abs_eapol_core_c * const m_partner; + + /// This is pointer to the eap_core object. The eapol_core object gives + /// the received packets to the eap_core object. The eap_core object sends + /// packets through the eapol_core object. +#if !defined(NO_EAP_SESSION_CORE) + eap_session_core_c * const m_eap_core; +#else + eap_core_c * const m_eap_core; +#endif + +#if defined(USE_EAPOL_KEY_STATE) + /// This stores eapol_key_state_c objects using eap_variable_data selector. + /// Selector data includes send addresses of the Ethernet packet. + eap_core_map_c m_eapol_key_state_map; +#endif //#if defined(USE_EAPOL_KEY_STATE) + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is the master session key derived from a successful authentication + eap_variable_data_c m_master_session_key; + + eapol_key_authentication_type_e m_authentication_type; + + /// This is offset in bytes of the EAPOL header. + u32_t m_eapol_header_offset; + + /// This is maximum transfer unit in bytes. + u32_t m_MTU; + + /// This is length of the trailer in bytes. + u32_t m_trailer_length; + + /// This indicates the maximum number of EAPOL-starts to be sent. + u32_t m_max_eapol_starts; + + /// This indicates the interval for EAPOL-start sending. + u32_t m_eapol_start_interval; + + /// This is the counter for EAPOL-start sending. + u32_t m_eapol_starts_sent; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + bool m_shutdown_was_called; + + bool m_block_state_notifications; + +#if defined(USE_EAPOL_KEY_STATE) + /// This flag will skip start of 4-Way Handshake with true value. + bool m_skip_start_4_way_handshake; +#endif //#if defined(USE_EAPOL_KEY_STATE) + + +#if defined(USE_EAPOL_KEY_STATE) + EAP_FUNC_IMPORT eap_status_e indicate_eapol_key_state_started_eap_authentication( + const eap_am_network_id_c * const send_network_id); + + EAP_FUNC_IMPORT eap_status_e init_eapol_key_pmksa_caching_timeout( + const eap_am_network_id_c * const send_network_id); + + EAP_FUNC_IMPORT eap_status_e remove_eapol_key_state( + const eap_am_network_id_c * const send_network_id); + + eap_status_e copy_eapol_key_state( + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id ///< source includes remote address, destination includes local address. + ); + + eap_status_e generate_new_pmksa( + eapol_key_state_c * * const eapol_key_state, + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id ///< source includes remote address, destination includes local address. + ); +#endif //#if defined(USE_EAPOL_KEY_STATE) + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor deletes the m_eap_core object. + */ + EAP_FUNC_IMPORT virtual ~eapol_core_c(); + + /** + * The constructor creates the eap_core object and initializes the m_eap_core + * to point the eap_core object. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + * @param partner is back pointer to object which created this object. + * @param is_client_when_true indicates whether the network entity should act + * as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + */ + EAP_FUNC_IMPORT eapol_core_c( + abs_eap_am_tools_c * const tools, + abs_eapol_core_c * const partner, + const bool is_client_when_true); + + /** + * This function removes all authentication sessions. + * If this succeeds this function must return eap_status_ok. + * If this fails this function must return corresponding error status. + * @return This function returns the status of operation. + */ + EAP_FUNC_IMPORT eap_status_e cancel_all_authentication_sessions(); + + // This is documented in abs_eap_stack_interface_c::packet_process(). + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length); + + /** + * The class could send packets to partner class with this function. + * eapol_core_c adds EAPOL header to the send packet. + * @param send_network_id carries the addresses (network identity) and type of the packet. + * @param sent_packet includes the buffer for the whole packet and initialized + * EAP-packet in correct offset. + * @param header_offset is offset of the EAP-header within the sent_packet. + * @param data_length is length in bytes of the EAP-packet. + * @param buffer_length is length in bytes of the whole packet buffer. + */ + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @param MTU_length is pointer to variable to store the maximum transfer unit (MTU). + * MTU is the maximum EAP-packet length in bytes + * @param trailer_length is pointer to the variable to store length + * of trailer needed by lower levels. + * @return Function returns the offset of EAP-header. + * @see abs_eap_core_c::get_header_offset(). + */ + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + /** + * The adaptation module calls the eap_acknowledge() function after + * any Network Protocol packet is received. This is used as a success indication. + * This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + * @param connection_handle separates the context of the acknowledged session. + * Mostly there is only one session in the client. + * The server does not need eap_acknowledge() function because + * server (EAP-authenticator) sends the EAP-success message. + */ + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + + /** + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @see abs_eap_core_c::load_module(). + */ + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + /** + * The unload_module() function unloads the module of a EAP-type. + * @see abs_eap_core_c::unload_module(). + */ + EAP_FUNC_IMPORT eap_status_e unload_module( + const eap_type_value_e type); + + /** + * This function checks whether PMKSA is cached to each eap_am_network_id_c object. + * Function removes eap_am_network_id_c object from bssid_sta_receive_network_ids if there are + * no cached PMKSA for removes eap_am_network_id_c object. + * All eap_am_network_id_c objects that exist in bssid_sta_receive_network_ids + * after function returns have PMKSA cached and read_reassociation_parameters() can be called + * with those eap_am_network_id_c objects. + */ + EAP_FUNC_IMPORT eap_status_e check_pmksa_cache( + eap_array_c * const bssid_sta_receive_network_ids, + const eapol_key_authentication_type_e selected_eapol_key_authentication_type, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite); + + /** + * This function removes PMKSA from cache. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. + * MAC address of Supplicant should be in destination address. + */ + EAP_FUNC_IMPORT eap_status_e remove_pmksa_from_cache( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function starts the EAP-authentication. + * The first parameter includes the network addresses of the protocol + * over the EAP-packets are transmitted. + * The type attribute of the eap_am_network_id_c object MUST be set + * either eapol_ethernet_type_e::eapol_ethernet_type_pae. + * Value eapol_ethernet_type_e::eapol_ethernet_type_pae is used in normal EA-authentication. + * The second parameter is_client_when_true tells whether this stack + * is client (true) or server (false). + * The adaptation module calls the restart_authentication() function + * when EAP-authentication is needed with another peer. + * @see abs_eap_core_c::restart_authentication(). + */ + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer = false); + + /** + * This function starts the preauthentication. + * The first parameter includes the network addresses of the protocol + * over the EAP-packets are transmitted. + * The type attribute of the eap_am_network_id_c object MUST be set + * eapol_ethernet_type_e::eapol_ethernet_type_preauthentication. + * Value eapol_ethernet_type_e::eapol_ethernet_type_preauthentication is used 802.11i preauthentication. + * The adaptation module calls the start_preauthentication() function + * when preauthentication is needed with another AP. + */ + EAP_FUNC_IMPORT eap_status_e start_preauthentication( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type); + + EAP_FUNC_IMPORT eap_status_e read_reassociation_parameters( + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address. + const eapol_key_authentication_type_e authentication_type, + eap_variable_data_c * const PMKID, + const eap_variable_data_c * const received_WPA_ie, + const eap_variable_data_c * const sent_WPA_ie); + + EAP_FUNC_IMPORT eap_status_e start_reassociation( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const PMKID); + + EAP_FUNC_IMPORT eap_status_e complete_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const received_WPA_IE, // WLM must give only the WPA IE to EAPOL + const eap_variable_data_c * const sent_WPA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite); + + EAP_FUNC_IMPORT eap_status_e start_WPXM_reassociation( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + eap_variable_data_c * const send_reassociation_request_ie); + + EAP_FUNC_IMPORT eap_status_e complete_WPXM_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const received_reassociation_ie); + + /** + * he adaptation module calls the send_logoff() function to send a EAPOL-Logoff message. + */ + EAP_FUNC_IMPORT eap_status_e send_logoff( + const eap_am_network_id_c * const receive_network_id); + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @see abs_eap_base_type_c::packet_data_crypto_keys(). + */ + EAP_FUNC_IMPORT eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ); + + // See abs_eapol_key_state_c::packet_data_session_key(). + EAP_FUNC_IMPORT eap_status_e packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key); + + // This is documented in abs_eap_stack_interface_c::configure(). + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is documented in abs_eap_stack_interface_c::shutdown(). + EAP_FUNC_IMPORT eap_status_e shutdown(); + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + EAP_FUNC_IMPORT eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + EAP_FUNC_IMPORT eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // This is documented in abs_eap_stack_interface_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + + // This is documented in abs_eap_stack_interface_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + // See abs_eap_base_type_c::state_notification(). + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state); + + // See abs_eap_base_timer_c::timer_expired(). + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data); + + // See abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data); + + /** + * This function tells lower layer to remove EAP session object asyncronously. + * @param send_network_id is pointer to network id that identifies the removed EAP session. + */ + EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id); + + /** + * The upper layer calls the asynchronous_start_authentication() function + * when EAP-authentication is needed with another peer. + * @see abs_eap_core_c::asynchronous_start_authentication(). + */ + EAP_FUNC_IMPORT eap_status_e asynchronous_start_authentication( + const eap_am_network_id_c * const /* receive_network_id */, + const bool /* is_client_when_true */); + + // + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + // + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + // + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + // See abs_eap_core_c::get_eap_type_list(). + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + +#if defined(USE_EAPOL_KEY_STATE) + // See abs_eapol_key_state_c::get_and_increment_global_key_counter(). + EAP_FUNC_IMPORT eap_status_e get_and_increment_global_key_counter( + eap_variable_data_c * const key_counter); +#endif //#if defined(USE_EAPOL_KEY_STATE) + + +#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + /** + * Function creates a state for later use. This is for optimazing 4-Way Handshake. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. MAC address of + * Supplicant should be in destination address. + * @param authentication_type is the selected authentication type. + */ + EAP_FUNC_IMPORT eap_status_e create_state( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type + ); + +#endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + +#if defined(USE_EAPOL_KEY_STATE) + + /** + * This function need to be called when client STA (re)associates to AP. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. MAC address of Supplicant should be in destination address. + * @param authentication_type is the authentication type. One of RSNA, WPA or 802.1X. + * @param authenticator_RSNA_IE is RSN IE of authenticator. Authenticator sends this in Beacon or Probe message. + * @param supplicant_RSNA_IE is RSN IE of supplicant. Supplicant sends this in (re)association request message. + * @param eapol_pairwise_cipher is the selected pairwise cipher. + * @param eapol_group_cipher is the selected group cipher. + */ + EAP_FUNC_IMPORT eap_status_e association( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const authenticator_RSNA_IE, + const eap_variable_data_c * const supplicant_RSNA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher, + const eap_variable_data_c * const pre_shared_key); + +#endif //#if defined(USE_EAPOL_KEY_STATE) + + +#if defined(USE_EAPOL_KEY_STATE) + /** + * This function need to be called when client STA disassociates from AP. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. MAC address of Supplicant should be in destination address. + */ + EAP_FUNC_IMPORT eap_status_e disassociation( + const eap_am_network_id_c * const receive_network_id); +#endif //#if defined(USE_EAPOL_KEY_STATE) + +#if defined(USE_EAPOL_KEY_STATE) + EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_eapol_key_state( + const eap_am_network_id_c * const send_netword_id); +#endif //#if defined(USE_EAPOL_KEY_STATE) + +#if defined(USE_EAPOL_KEY_STATE) + EAP_FUNC_IMPORT static eap_status_e shutdown_operation( + eapol_key_state_c * const handler, + abs_eap_am_tools_c * const m_am_tools); +#endif //#if defined(USE_EAPOL_KEY_STATE) + +#if defined(USE_EAPOL_KEY_STATE) + EAP_FUNC_IMPORT static eap_status_e cancel_authentication_session( + eapol_key_state_c * const handler, + abs_eap_am_tools_c * const m_am_tools); +#endif //#if defined(USE_EAPOL_KEY_STATE) + + /// @see abs_eap_core_c::add_rogue_ap(). + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + EAP_FUNC_IMPORT eap_status_e tkip_mic_failure( + const eap_am_network_id_c * const receive_network_id, + const bool fatal_failure_when_true, + const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type); + + // This is documented in abs_eap_core_c::set_session_timeout(). + EAP_FUNC_IMPORT eap_status_e set_session_timeout( + const u32_t session_timeout_ms); + +private: + + +#if !defined(USE_EAPOL_KEY_STATE) + /** + * The handle_RC4_key_descriptor() function parses the EAPOL-Key frame + * that includes RC4 Key Descriptor. + * This function retrieves the traffic encryption key from it. It forwards the key + * to lower layers. The format of EAPOL-Key frame is described in + * draft-congdon-radius-8021x-23.txt (RFC ????) + * @param eapol is the received packet + * @param packet_length is the length of the packet + */ + eap_status_e handle_RC4_key_descriptor( + const eap_am_network_id_c * const receive_network_id, + eapol_RC4_key_header_c * const eapol, + const u32_t packet_length); +#endif //#if !defined(USE_EAPOL_KEY_STATE) + + //-------------------------------------------------- +}; // class eapol_core_c + +#endif //#if !defined(_EAPOL_CORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_ethernet_address.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_ethernet_address.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_ETHERNET_ADDRESS_H_) +#define _EAPOL_ETHERNET_ADDRESS_H_ + +#include "eap_tools.h" +#include "eapol_header.h" +#include "eap_general_header_base.h" + +const u32_t EAPOL_ETHERNET_ADDRESS_LENGTH = 6u; + + +class eap_eth_address_c +{ +private: + u8_t m_address[EAPOL_ETHERNET_ADDRESS_LENGTH]; +public: + + eap_eth_address_c() + { + } + + virtual ~eap_eth_address_c() + { + } + + u8_t * get_address() const + { + return const_cast(m_address); + } + + u32_t get_address_length() const + { + return sizeof(m_address); + } + + void set_address(abs_eap_am_tools_c * const m_am_tools, u8_t * const p_address, const u32_t length) + { + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + EAP_ASSERT_TOOLS(m_am_tools, length == EAPOL_ETHERNET_ADDRESS_LENGTH); + + for (u32_t ind = 0u; ind < length; ind++) + { + m_address[ind] = p_address[ind]; + } + } + + void reset_address() + { + for (u32_t ind = 0u; ind < EAPOL_ETHERNET_ADDRESS_LENGTH; ind++) + { + m_address[ind] = 0; + } + } +}; + + +#endif //#if !defined(_EAPOL_ETHERNET_ADDRESS_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_ethernet_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_ethernet_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,221 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_ETHERNET_HEADER_H_) +#define _EAP_ETHERNET_HEADER_H_ + +#include "eap_tools.h" +#include "eapol_header.h" +#include "eap_general_header_base.h" +#include "eapol_ethernet_address.h" + + +/** @file */ + +/** + * This is base class of Ethernet header used with EAPOL. + * @code + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Destination address | + * +- -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | Source address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Data ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ +class EAP_EXPORT eapol_ethernet_header_base_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + /** + * This enumeration defines the offsets of the Ethernet-header fields. + */ + enum offsets + { + m_destination_offset = 0ul, ///< This is offset to destination address field. + m_source_offset = m_destination_offset+EAPOL_ETHERNET_ADDRESS_LENGTH, ///< This is offset to source address field. + m_type_offset = m_source_offset+EAPOL_ETHERNET_ADDRESS_LENGTH, ///< This is offset to type field. + m_data_offset = m_type_offset+sizeof(u16_t), ///< This is offset to data field. + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing special. + EAP_FUNC_IMPORT virtual ~eapol_ethernet_header_base_c(); + + /// Constructor does nothing special. + /// The tools parameter is pointer to tools object. + /// The header_buffer parameter is pointer to buffer of Ethernet-packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT eapol_ethernet_header_base_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + /// This function returns pointer to the destination address of the Ethernet-packet. + EAP_FUNC_IMPORT u8_t * get_destination() const; + + /// This function returns pointer to the source address of the Ethernet-packet. + EAP_FUNC_IMPORT u8_t * get_source() const; + + /// This function returns length of the destination address of the Ethernet-packet. + EAP_FUNC_IMPORT u32_t get_destination_length() const; + + /// This function returns length of the source address of the Ethernet-packet. + EAP_FUNC_IMPORT u32_t get_source_length() const; + + /// This function returns the packet type field of Ethernet-header. + EAP_FUNC_IMPORT u16_t get_type() const; + + /// This function returns pointer to the data of the Ethernet-packet. + EAP_FUNC_IMPORT u8_t * get_data(const u32_t data_length) const; + + /// This function returns the length of the data of Ethernet-header. + EAP_FUNC_IMPORT u32_t get_data_length() const; + + /// This function returns the header length of the Ethernet-packet. + EAP_FUNC_IMPORT static u16_t get_header_length(); + + /// This function sets the packet type field of the Ethernet-header. + EAP_FUNC_IMPORT void set_type(const eapol_ethernet_type_e type); + + /// This function checks the validity of Ethernet-header. + EAP_FUNC_IMPORT eap_status_e check_header() const; + + // + //-------------------------------------------------- +}; // class eapol_ethernet_header_base_c + + + + + +/// @{ This class can be removed. eapol_ethernet_header_base_c could be used instead. } +class EAP_EXPORT eapol_ethernet_header_rd_c +: public eapol_ethernet_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing special. + EAP_FUNC_IMPORT virtual ~eapol_ethernet_header_rd_c(); + + /// Constructor does nothing special. + /// The tools parameter is pointer to tools object. + /// The header_buffer parameter is pointer to buffer of Ethernet-packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT eapol_ethernet_header_rd_c( + abs_eap_am_tools_c * const tools, + const u8_t * const header_buffer, + const u32_t header_buffer_length); + + /// This function returns pointer to the header of the EAPOL-packet included in the Ethernet-packet. + EAP_FUNC_IMPORT u8_t * get_eapol_header() const; + + // + //-------------------------------------------------- +}; // class eapol_ethernet_header_rd_c + + + +/// @{ This class can be removed. eapol_ethernet_header_base_c could be used instead. } +class EAP_EXPORT eapol_ethernet_header_wr_c +: public eapol_ethernet_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing special. + EAP_FUNC_IMPORT virtual ~eapol_ethernet_header_wr_c(); + + /// Constructor does nothing special. + /// The tools parameter is pointer to tools object. + /// The header_buffer parameter is pointer to buffer of Ethernet-packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT eapol_ethernet_header_wr_c( + abs_eap_am_tools_c * const tools, + const u8_t * const header_buffer, + const u32_t header_buffer_length); + + /// This function returns pointer to the header of the EAPOL-packet included in the Ethernet-packet. + EAP_FUNC_IMPORT u8_t * get_eapol_header() const; + + /// This function returns pointer to the destination address of the Ethernet-packet. + EAP_FUNC_IMPORT u8_t * get_destination(); + + /// This function returns pointer to the source address of the Ethernet-packet. + EAP_FUNC_IMPORT u8_t * get_source(); + + /// This function resets the EAPOL-header. + /// The type parameter is the type of Ethernet-packet. + /// The buffer_length parameter is the length of the EAPOL-header and the following data buffer. + EAP_FUNC_IMPORT void reset_header(const eapol_ethernet_type_e type, const u16_t buffer_length); + + // + //-------------------------------------------------- +}; // class eapol_ethernet_header_wr_c + + + +#endif //#if !defined(_EAP_ETHERNET_HEADER_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_handle_tlv_message_data.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_handle_tlv_message_data.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,326 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_CREATE_TLV_MESSAGE_DATA_H_) +#define _EAP_CREATE_TLV_MESSAGE_DATA_H_ + +#include "eap_am_types.h" +#include "eap_tools.h" +#include "eap_array.h" +#include "eap_tlv_message_data.h" +#include "eap_expanded_type.h" + + +enum eapol_tlv_message_type_e +{ + eapol_tlv_message_type_none = 0, + eapol_tlv_message_type_array = 1, + eapol_tlv_message_type_boolean = 2, + eapol_tlv_message_type_eap_protocol_layer = 3, + eapol_tlv_message_type_eap_state_notification = 4, + eapol_tlv_message_type_eap_status = 5, + eapol_tlv_message_type_eap_type = 6, + eapol_tlv_message_type_eapol_key_802_11_authentication_mode = 7, + eapol_tlv_message_type_eapol_key_authentication_type = 8, + eapol_tlv_message_type_eapol_key_type = 9, + eapol_tlv_message_type_eapol_tkip_mic_failure_type = 10, + eapol_tlv_message_type_eapol_wlan_authentication_state = 11, + eapol_tlv_message_type_error = 12, + eapol_tlv_message_type_function = 13, + eapol_tlv_message_type_network_id = 14, + eapol_tlv_message_type_network_key = 15, + eapol_tlv_message_type_protected_setup_credential = 16, + eapol_tlv_message_type_RSNA_cipher = 17, + eapol_tlv_message_type_session_key = 18, + eapol_tlv_message_type_u8_t = 19, + eapol_tlv_message_type_u16_t = 20, + eapol_tlv_message_type_u32_t = 21, + eapol_tlv_message_type_u64_t = 22, + eapol_tlv_message_type_variable_data = 23, +}; + + +enum eapol_tlv_message_type_function_e +{ + eapol_tlv_message_type_function_none = 0, + eapol_tlv_message_type_function_check_pmksa_cache = 1, + eapol_tlv_message_type_function_start_authentication = 2, + eapol_tlv_message_type_function_complete_association = 3, + eapol_tlv_message_type_function_disassociation = 4, + eapol_tlv_message_type_function_start_preauthentication = 5, + eapol_tlv_message_type_function_start_reassociation = 6, + eapol_tlv_message_type_function_complete_reassociation = 7, + eapol_tlv_message_type_function_start_WPXM_reassociation = 8, + eapol_tlv_message_type_function_complete_WPXM_reassociation = 9, + eapol_tlv_message_type_function_packet_process = 10, + eapol_tlv_message_type_function_tkip_mic_failure = 11, + eapol_tlv_message_type_function_eap_acknowledge = 12, + eapol_tlv_message_type_function_update_header_offset = 13, + eapol_tlv_message_type_function_complete_check_pmksa_cache = 14, + eapol_tlv_message_type_function_packet_send = 15, + eapol_tlv_message_type_function_associate = 16, + eapol_tlv_message_type_function_disassociate = 17, + eapol_tlv_message_type_function_packet_data_session_key = 18, + eapol_tlv_message_type_function_state_notification = 19, + eapol_tlv_message_type_function_reassociate = 20, + eapol_tlv_message_type_function_update_wlan_database_reference_values = 21, + eapol_tlv_message_type_function_complete_start_WPXM_reassociation = 22, + eapol_tlv_message_type_function_new_protected_setup_credentials = 23, + eapol_tlv_message_type_function_illegal_value, // Keep this the last value. +}; + + +enum eapol_message_payload_index_e +{ + eapol_message_payload_index_function = 0, + eapol_message_payload_index_first_parameter = 1, +}; + + +/** @file */ + +class eap_variable_data_c; +class eap_am_network_id_c; +class eap_buf_chain_wr_c; +class eapol_session_key_c; +class abs_eap_state_notification_c; +class eap_state_notification_c; +class network_key_and_index_c; +class simple_config_credential_c; + +//---------------------------------------------------------------------------- + + +/// This class defines functions to add and parse message data composed +/// of Attribute-Value Pairs (See eap_tlv_header_c) to/from eap_tlv_message_data_c object. +class EAP_EXPORT eapol_handle_tlv_message_data_c +: public eap_tlv_message_data_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eapol_handle_tlv_message_data_c class does nothing. + */ + EAP_FUNC_IMPORT virtual ~eapol_handle_tlv_message_data_c(); + + /** + * The constructor of the eapol_handle_tlv_message_data_c class simply initializes the attributes. + */ + EAP_FUNC_IMPORT eapol_handle_tlv_message_data_c( + abs_eap_am_tools_c * const tools); + + /** + * This function should increase reference count. + */ + EAP_FUNC_IMPORT void object_increase_reference_count(); + + /** + * This function should first decrease reference count + * and second return the remaining reference count. + * Reference count must not be decreased when it is zero. + */ + EAP_FUNC_IMPORT u32_t object_decrease_reference_count(); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + //- - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT u32_t get_payload_size( + const eap_am_network_id_c * const network_id) const; + + EAP_FUNC_IMPORT u32_t get_payload_size( + const abs_eap_state_notification_c * const state) const; + + EAP_FUNC_IMPORT u32_t get_payload_size( + const eapol_session_key_c * const session_key) const; + +#if defined(USE_EAP_SIMPLE_CONFIG) + + EAP_FUNC_IMPORT u32_t get_payload_size( + network_key_and_index_c * key) const; + + EAP_FUNC_IMPORT u32_t get_payload_size( + EAP_TEMPLATE_CONST eap_array_c * network_keys) const; + + EAP_FUNC_IMPORT u32_t get_payload_size( + simple_config_credential_c * const credential) const; + + EAP_FUNC_IMPORT u32_t get_payload_size( + EAP_TEMPLATE_CONST eap_array_c * const credential_array) const; + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + //- - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT eap_status_e add_structured_parameter_header( + const eapol_tlv_message_type_e type, + const u32_t length); + + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const eapol_tlv_message_type_e type, + const u32_t integer); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const u64_t long_integer); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const u32_t integer); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const u16_t integer); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const u8_t byte_integer); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const bool boolean); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const eap_status_e status); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const eapol_tlv_message_type_function_e function); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const eap_variable_data_c * const variable_data); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const eap_am_network_id_c * const network_id); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const eap_buf_chain_wr_c * const packet_buffer); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const eapol_session_key_c * const session_key); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const abs_eap_state_notification_c * const state); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const eap_type_value_e eap_type); + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + const eap_general_header_base_c * const packet_data); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const credential_header, + simple_config_credential_c * const credential); + +#if defined(USE_EAP_SIMPLE_CONFIG) + + EAP_FUNC_IMPORT eap_status_e add_parameter_data( + EAP_TEMPLATE_CONST eap_array_c * const credential_array); + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + //- - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const integer_header, + u64_t * const value); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const integer_header, + u32_t * const value); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const integer_header, + u16_t * const value); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const integer_header, + u8_t * const value); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const function_header, + eapol_tlv_message_type_function_e * const function); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const network_id_header, + eap_am_network_id_c * const new_network_id); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const variable_data_header, + eap_variable_data_c * const variable_data); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const session_key_header, + eapol_session_key_c * const session_key); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const state_header, + eap_state_notification_c * * const state); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const eap_type_header, + eap_type_value_e * const eap_type); + +#if defined(USE_EAP_SIMPLE_CONFIG) + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const network_key_header, + network_key_and_index_c * const network_key); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const network_keys_array_header, + eap_array_c * const network_keys_array); + + EAP_FUNC_IMPORT eap_status_e get_parameter_data( + const eap_tlv_header_c * const credential_array_header, + eap_array_c * const credential_array); + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + //- - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT eap_const_string get_type_string(const eapol_tlv_message_type_e type); + + EAP_FUNC_IMPORT eap_const_string get_function_string(const eapol_tlv_message_type_function_e function); + + // + //-------------------------------------------------- +}; // class eapol_handle_tlv_message_data_c + + +//-------------------------------------------------- + +#endif //#if !defined(_EAP_CREATE_TLV_MESSAGE_DATA_H_) + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,240 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_HEADER_H_) +#define _EAPOL_HEADER_H_ + + +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "eap_header.h" +#include "eap_general_header_base.h" +#include "eapol_key_types.h" + +/** @file */ + +/** + * Enumeration of EAPOL Protocol Version. + */ +enum eapol_protocol_version_e +{ + eapol_protocol_version_none = 0, ///< This is internal value for no version case. + eapol_protocol_version_1 = 1, ///< This is the original Protocol Version. + eapol_protocol_version_2 = 2, ///< This is the new Protocol Version defined in new IEEE P802.1X. +}; + +/** + * Enumeration of EAPOL packet type. + */ +enum eapol_packet_type_e +{ + eapol_packet_type_eap = 0, ///< This the EAP-Packet. + eapol_packet_type_start = 1, ///< This is EAPOL-Start. + eapol_packet_type_logoff = 2, ///< This is EAPOL-Logoff. + eapol_packet_type_key = 3, ///< This is EAPOL-Key. + eapol_packet_type_enc_asf_alert = 4, ///< This is EAPOL-Encapsulated-ASF-Alert. + eapol_packet_type_SAE_KE = 5, ///< This is internal SAE testing. + eapol_packet_type_SAE_EAP = 6, ///< This is internal SAE testing. + eapol_packet_type_SAE_START = 7, ///< This is internal SAE testing. + eapol_packet_type_SAE_LOGOFF = 8, ///< This is internal SAE testing. + eapol_packet_type_no_type = 0xff, ///< This is internal value for no type case. +}; + + +/** + * This is base class of EAPOL header. + * @code + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Prot. Version | Packet Type | Data Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Data ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ +class EAP_EXPORT eapol_header_base_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + /** + * This enumeration defines the offsets of the EAPOL-header fields. + */ + enum offsets + { + m_version_offset = 0ul, ///< This is the offset of the version field. + m_packet_type_offset = m_version_offset+sizeof(u8_t), ///< This is the offset of the packet type field. + m_data_length_offset = m_packet_type_offset+sizeof(u8_t), ///< This is the offset of the data length field. + m_data_offset = m_data_length_offset+sizeof(u16_t), ///< This is the offset of the data field. + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing special. + EAP_FUNC_IMPORT virtual ~eapol_header_base_c(); + + /// Constructor does nothing special. + /// The tools parameter is pointer to tools object. + /// The header_buffer parameter is pointer to buffer of EAPOL-packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT eapol_header_base_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + /// This function returns the Protocol Version field of EAPOL header. + EAP_FUNC_IMPORT eapol_protocol_version_e get_version() const; + + /// This function returns the packet type field of EAPOL header. + EAP_FUNC_IMPORT eapol_packet_type_e get_packet_type() const; + + /// This function returns the data length of the EAPOL-packet. + EAP_FUNC_IMPORT u16_t get_data_length() const; + + /// This function returns the header length of the EAPOL-packet. + EAP_FUNC_IMPORT static u32_t get_header_length(); + + /// This function returns pointer to the data of the EAPOL-packet. + EAP_FUNC_IMPORT u8_t * get_data(const u32_t data_length) const; + + /// This function sets the Protocol Version field of the EAPOL-header. + EAP_FUNC_IMPORT void set_version(const eapol_protocol_version_e p_version); + + /// This function sets the packet type field of the EAPOL-header. + EAP_FUNC_IMPORT void set_packet_type(const eapol_packet_type_e p_packet_type); + + /// This function sets the data length field of the EAPOL-header. + EAP_FUNC_IMPORT void set_data_length(const u16_t p_data_length); + + /// This function returns debug string of the type of the EAPOL-packet. + EAP_FUNC_IMPORT eap_const_string get_type_string() const; + + /// This function checks the validity of EAPOL-header. + EAP_FUNC_IMPORT eap_status_e check_header() const; + + // + //-------------------------------------------------- +}; // class eapol_header_base_c + + + + +/// This is read only EAPOL header. +/// @{ This class can be removed. eapol_header_base_c could be used instead. } +class EAP_EXPORT eapol_header_rd_c +: public eapol_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing special. + EAP_FUNC_IMPORT virtual ~eapol_header_rd_c(); + + /// Constructor does nothing special. + /// The tools parameter is pointer to tools object. + /// The header_buffer parameter is pointer to buffer of EAPOL-packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT eapol_header_rd_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length); + + /// This function returns pointer to the header of the EAP-packet included in the EAPOL-packet. + EAP_FUNC_IMPORT u8_t * get_eap_header() const; + + // + //-------------------------------------------------- +}; // class eapol_header_rd_c + + + + +/// This is read and write EAPOL header. +/// @{ This class can be removed. eapol_header_base_c could be used instead. } +class EAP_EXPORT eapol_header_wr_c +: public eapol_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing special. + EAP_FUNC_IMPORT virtual ~eapol_header_wr_c(); + + /// Constructor does nothing special. + /// The tools parameter is pointer to tools object. + /// The header_buffer parameter is pointer to buffer of EAPOL-packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT eapol_header_wr_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length); + + /// This function returns pointer to the header of the EAP-packet included in the EAPOL-packet. + EAP_FUNC_IMPORT u8_t * get_eap_header(); + + /// This function resets the EAPOL-header. + /// The buffer_length parameter is the length of the EAPOL-header and the following data buffer. + EAP_FUNC_IMPORT void reset_header(u16_t buffer_length); + + // + //-------------------------------------------------- +}; // class eapol_header_wr_c + + +#endif //#if !defined(_EAPOL_HEADER_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_key_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_key_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_KEY_HEADER_H_) +#define _EAPOL_KEY_HEADER_H_ + +#include "eapol_header.h" +#include "eap_general_header_base.h" + + +/// Enumeration of EAPOL-Key descriptor type field. +enum eapol_key_descriptor_type_e +{ + eapol_key_descriptor_type_none = 0, + eapol_key_descriptor_type_RC4 = 1, + eapol_key_descriptor_type_RSNA = 2, ///< @{ Check RSNA Descriptor Type value. 802.1X should define this value. This is our assuption based on traces. } + eapol_key_descriptor_type_WPA = 0xfe, ///< WPA uses this value. +}; + + +#endif //#if !defined(_EAPOL_KEY_H_) + +//------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_key_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_key_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,981 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_KEY_STATE_H_) +#define _EAPOL_KEY_STATE_H_ + + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eapol_rsna_key_data_header.h" +#include "eapol_rsna_key_header.h" +#include "eap_am_network_id.h" +#include "eapol_key_types.h" + +class abs_eapol_core_c; +class abs_eapol_key_state_c; +class eapol_rsna_key_data_payloads_c; +class eap_core_retransmission_c; + + +#if defined(EAPOL_KEY_TEST_PRIVATE_FUNCTION) +#define EAP_KEY_TEST_PUBLIC_FUNCTION public: +#define EAP_KEY_TEST_PRIVATE_FUNCTION private: +#else +#define EAP_KEY_TEST_PUBLIC_FUNCTION +#define EAP_KEY_TEST_PRIVATE_FUNCTION +#endif // #if defined(EAPOL_KEY_TEST_PRIVATE_FUNCTION) + +/** @file */ + +/** + * This is the timer ID used with abs_eap_am_tools_c::set_timer() and abs_eap_am_tools_c::cancel_timer(). + */ +enum eapol_key_state_timer_id_e +{ + EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID, ///< See EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_TIMEOUT. + EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID, ///< See EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT. + EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID, ///< See EAPOL_KEY_STATE_TIMER_PMK_CACHING_TIMEOUT. + EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID, ///< See EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT. + EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID, ///< See EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT. + EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID, ///< See EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT. +}; + +/** + * These are the default timeout values. + */ +enum eapol_key_state_timer_timeout_value_e +{ + EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_TIMEOUT = 20000ul, // milli seconds + EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT = 2000ul, // milli seconds + EAPOL_KEY_STATE_RETRANSMISSION_COUNTER = 3ul, + EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT = 43200000ul, // milli seconds = 12 hours + EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT = 500ul, // milli seconds + EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT = 0ul, // milli seconds, this is for testing, zero means in test case group key is updated immediately. + EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT = 100ul, // milli seconds before client initializes 4-Way Handshake. + EAPOL_KEY_STATE_TIMER_WPXM_CACHE_TIMEOUT = 1000ul, // milli seconds, This is short timeout to remove WPXM SA. +}; + + +const u8_t EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL[] = "Pairwise key expansion"; +const u32_t EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL_LENGTH = (sizeof(EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL) - 1ul); // Terminating null is not included. + +const u8_t EAPOL_RSNA_PMK_NAME_LABEL[] = "PMK Name"; +const u32_t EAPOL_RSNA_PMK_NAME_LABEL_LENGTH = (sizeof(EAPOL_RSNA_PMK_NAME_LABEL) - 1ul); // Terminating null is not included. + +enum eapol_key_wpxm_constant_e +{ + eapol_key_constant_wpxm_initial_wpxc_counter_value = 1, +}; + + +//-------------------------------------------------------------------------------------------------- + + +/// Class eapol_key_state_c +/** + * This class stores the EAPOL-Key state. + */ +class EAP_EXPORT eapol_key_state_c +: public abs_eap_base_timer_c +{ + +public: + //-------------------------------------------------- + + //-------------------------------------------------- +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is back pointer to object which created this object. + /// Packets are sent to the partner. + abs_eapol_key_state_c * const m_key_state_partner; + + /// This is back pointer to object which created eapol_core_c object. + /// eapol_key_state_c object sent packets to this object. + abs_eapol_core_c * const m_eapol_partner; + + eap_am_network_id_c m_send_network_id; + + /// Authenticator RSN IE. Authenticator sends this in Beacon or Probe message. + eap_variable_data_c m_authenticator_RSNA_IE; + + /// If a second RSN IE is provided in the message, the Supplicant shall use + // the unicast cipher suite specified in the second RSN IE or deauthenticate. + eap_variable_data_c m_unicast_cipher_suite_RSNA_IE; + + /// Supplicant RSN IE. Supplicant sends this in (re)association request message. + eap_variable_data_c m_supplicant_RSNA_IE; + + /// Received Pairwise Master Key ID (PMKID). Authenticator sends this in 4-Way Handshake message 1. + eap_variable_data_c m_received_PMKID; + + /// This is Supplicant's MAC address. This is given from MAC layer when EAPOL-Key state is initialized. + eap_variable_data_c m_supplicant_MAC_address; + + /// This is Authenticator's MAC address. This is given from MAC layer when EAPOL-Key state is initialized. + eap_variable_data_c m_authenticator_MAC_address; + + /// This is Athenticator Nonce. + eap_variable_data_c m_ANonce; + + /// This is Supplicant Nonce. + eap_variable_data_c m_SNonce; + + /// This is EAPOL-Key IV. + eap_variable_data_c m_EAPOL_key_IV; + + /// This is the Pairwise Master Key (PMK 802.11i or WPXK3 WPXM) derived from a successful authentication. + eap_variable_data_c m_pairwise_PMK_WPXK3; + + /// Pairwise Master Key ID (PMKID). Derived with function: + /// PMKID = HMAC-SHA1-128(PMK, "PMK Name" || Authenticator-MAC-Addr || Supplicant-MAC-Addr). + eap_variable_data_c m_PMKID; + + /// Pairwise Transient Key (PTK). + /// PTK = PRF-X(PMK, "Pairwise key expansion", Min(AA,SA) || Max(AA, SA) || Min(ANonce,SNonce) || Max(ANonce,SNonce)). + eap_variable_data_c m_transient_PTK; + + /// EAPOL-Key Confirmation Key (KCK). + /// KCK = L(PTK, 0, 128). + eap_variable_data_c m_confirmation_KCK; + + /// EAPOL-Key Encryption Key (KEK). + /// KEK = L(PTK, 128, 128). + eap_variable_data_c m_encryption_KEK; + + /// Temporal Key (TK). + /// In TKIP: TK = L(PTK, 256, 256). + /// In CCMP: TK = L(PTK, 256, 128). + eap_variable_data_c m_temporal_TK; + + /// Group Temporal Key (GTK). + /// In TKIP: 256 bits. + /// In CCMP: 128 bits. + /// In WEP 40: 40 bits. + /// In WEP 104: 104 bits. + eap_variable_data_c m_group_GTK; + +#if defined(EAP_USE_WPXM) + eap_variable_data_c m_WPXM_WPXK1; + eap_variable_data_c m_WPXM_WPXK2; + + u32_t m_WPXM_WPXC; +#endif //#if defined(EAP_USE_WPXM) + + bool m_received_802_1x_keys[eapol_key_type_last_type]; + + u8_t m_group_GTK_ID; + + bool m_group_GTK_Tx_bit; + + u32_t m_eapol_header_offset; + + u32_t m_MTU; + + u32_t m_trailer_length; + + /// Re-transmission is used to test protocols. + /// This stores the information to resent a message. This is used for testing purposes. + eap_core_retransmission_c *m_retransmission; + + /// Re-transmission is used to test protocols. + /// This is the time after resent a message. This is used for testing purposes. + u32_t m_retransmission_time; + + /// Re-transmission is used to test protocols. + /// This is the maximum count of retransmission of one message. This is used for testing purposes. + u32_t m_retransmission_counter; + + /// This is the maximum time EAPOL-Key Handshake could succeed. + /// EAPOl-Key Handshake is terminated after this time elapses. + u32_t m_handshake_timeout; + + +#if defined(EAP_USE_WPXM) + + /// This is the maximum time WPXM reassociation could succeed. + /// WPXM reassociation is terminated after this time elapses. + u32_t m_wpxm_reassociate_timeout; + + /// This is used in test server. WPXM can be configured to to use RSNA or WPA Key descriptor. + eapol_key_descriptor_type_e m_EAPOL_WPXM_key_descriptor_type; + +#endif //#if defined(EAP_USE_WPXM) + + /// This is the authentication type. One of RSNA, WPA or 802.1X. + eapol_key_authentication_type_e m_authentication_type; + + /// This is the selected pairwise cipher. + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e m_eapol_pairwise_cipher; + + /// This is the selected group cipher. + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e m_eapol_group_cipher; + + /// This is the state of EAPOL-Key Handshake. + eapol_key_state_e m_eapol_key_state; + + /// This is the the current running handshake type. + eapol_key_handshake_type_e m_eapol_key_handshake_type; + + /// This used in EAPOL key MIC failure tests. Activation requires USE_EAPOL_KEY_TEST_FAILURES compiler flag. + eapol_key_state_e m_create_key_failure; + + u32_t m_pmksa_caching_timeout; + + /// This is Key Reply Counter. + u64_t m_key_reply_counter; + + /// This is Key Reply Counter for requests that client sends. + u64_t m_client_send_key_reply_counter; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This flag indicates that this object is marked to removed asynchronously. + /// The very same object could be taken use before the removing timer elapses. + bool m_marked_removed; + + bool m_shutdown_was_called; + + /// This flag tells whether broken 4-Way Handshake message 1 without PMKID is allowed (true) or dropped (false). + /// Default value id false. + /// Use configuration option EAPOL_key_state_allow_missing_PMKID_in_message_1 to change this value. + bool m_allow_missing_PMKID_in_message_1; + + /// This flag tells whether broken 4-Way Handshake message 1 without PMKID is created in server (true) or not (false). + /// Default value id false. + /// Use configuration option EAPOL_key_state_skip_PMKID_key_data_in_message_1 to change this value. + bool m_skip_PMKID_key_data_in_message_1; + + /// This flag tells whether broken 4-Way Handshake message 1 with non zero MIC or non zero reserved is allowed (true) or dropped (false). + /// Default value id false. + /// Use configuration option EAPOL_key_state_allow_non_zero_mic_in_message_1 to change this value. + bool m_allow_non_zero_mic_and_reserved_in_message_1; + + /// This flag tells the EAPOL must indicate PMKID to lower layers (true) or not (false). + /// The configuration option is EAPOL_key_state_indicate_pmkid_to_lower_layer. + bool m_indicate_pmkid_to_lower_layer; + + /// This flag tells the handshake timeout is already active (true) or not (false). + bool m_handshake_timeout_set; + + /// This flag activates group key update test (true) or not (false). + /// The configuration option is EAPOL_key_state_TEST_group_key_update. + bool m_server_TEST_group_key_update; + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + bool m_is_associated; +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + // - - - - - - - - - - - - - - - - - - - - - - - - + + enum eapol_key_state_constants_e + { + eapol_key_state_mppe_key_length_leap = 16ul, // LEAP gives only 16 bytes of key material + eapol_key_state_mppe_key_length = 32ul, + EAPOL_RSNA_PMK_LENGTH_BYTES = 32ul, + EAPOL_RSNA_NONCE_LENGTH_BYTES = 32ul, + EAPOL_RSNA_4_WAY_HANDSHAKE_MESSAGE_1_KEY_DATA_LENGTH_BYTES = eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_HEADER_LENGTH + + eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE, // sizeof(Key Data Encapsulation header) 6 + sizeof(PMKID) 16 + EAPOL_RSNA_RC4_KEY_STREAM_DISCARD_LENGTH = 256ul, + EAPOL_RSNA_TKIP_PTK_LENGTH_BITS = 512ul, + EAPOL_RSNA_CCMP_PTK_LENGTH_BITS = 384ul, + EAPOL_RSNA_KCK_LENGTH_BYTES = 16ul, + EAPOL_RSNA_KEK_LENGTH_BYTES = 16ul, + EAPOL_RSNA_TK_LENGTH_BYTES = 32ul, + EAPOL_RSNA_TKIP_TK_LENGTH_BYTES = 32ul, + EAPOL_RSNA_CCMP_TK_LENGTH_BYTES = 16ul, + EAPOL_RSNA_KCK_OFFSET_BYTES = 0ul, + EAPOL_RSNA_KEK_OFFSET_BYTES = EAPOL_RSNA_KCK_OFFSET_BYTES + EAPOL_RSNA_KCK_LENGTH_BYTES, + EAPOL_RSNA_TK_OFFSET_BYTES = EAPOL_RSNA_KEK_OFFSET_BYTES + EAPOL_RSNA_KEK_LENGTH_BYTES, + }; + + + EAP_FUNC_IMPORT eap_status_e trace_eapol_key_message( + const i8_t * const prefix, + eapol_RSNA_key_header_c * const eapol_key_message); + + eap_status_e trace_eapol_rsna_key_data_payload( + const bool is_RSNA, + const bool is_WPXM, + const eapol_key_descriptor_type_e eapol_key_descriptor_type, + const i8_t * const prefix, + const eapol_rsna_key_data_header_c * const key_data_payload, + const u32_t buffer_length); + +#if defined(USE_EAP_TRACE) + + #define TRACE_EAPOL_KEY_MESSAGE(prefix, eapol_key_message) \ + trace_eapol_key_message(prefix, eapol_key_message) + + #define EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD(is_RSNA, is_WPXM, eapol_key_descriptor_type, prefix, key_data_payload, buffer_length) \ + trace_eapol_rsna_key_data_payload(is_RSNA, is_WPXM, eapol_key_descriptor_type, prefix, key_data_payload, buffer_length) + +#else + + #define TRACE_EAPOL_KEY_MESSAGE(prefix, eapol_key_message) + + #define EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD(is_RSNA, is_WPXM, eapol_key_descriptor_type, prefix, key_data_payload, buffer_length) + +#endif //#if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS) + + + eap_status_e handshake_failure_notification(); + + eap_status_e set_mac_addresses( + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT eap_status_e save_parameters( + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const authenticator_RSNA_IE, + const eap_variable_data_c * const supplicant_RSNA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher); + + eap_status_e packet_data_session_key( + eap_variable_data_c * const key, ///< Here is the key. + const eapol_key_type_e key_type, ///< This the type of the key. + const u32_t key_index, ///< This is the index of the key. + const bool key_tx_bit, ///< This is the TX bit of the key. + const u8_t * const key_RSC, ///< This is the RSC counter + const u32_t key_RSC_size ///< This is the size of RSC counter + ); + + EAP_FUNC_IMPORT eap_status_e check_is_aes_key_wrap_padding( + const eapol_RSNA_key_descriptor_type_e current_key_data_type, + eapol_rsna_key_data_header_c * const key_data_payload, + const u32_t key_data_max_length + ); + + EAP_FUNC_IMPORT eap_status_e parse_generic_key_data_payload( + const eapol_key_descriptor_type_e key_descriptor_type, + const eapol_RSNA_key_descriptor_type_e current_key_data_payload, + eapol_rsna_key_data_header_c * const key_data_payload, + u32_t * const key_data_max_length, + eapol_rsna_key_data_payloads_c * const p_rsna_key_data_payloads, + const eapol_key_state_e expected_key_message); + + EAP_FUNC_IMPORT eap_status_e parse_key_data( + const eapol_key_descriptor_type_e key_descriptor_type, + const eapol_rsna_key_data_header_c * const p_payload, + u32_t * const buffer_length, + eapol_rsna_key_data_payloads_c * const p_rsna_key_data_payloads, + const eapol_key_state_e expected_key_message, + const eapol_RSNA_key_header_c::key_descriptor_version_e key_descriptor_version); + + EAP_FUNC_IMPORT eap_status_e rsna_prf( + const eap_variable_data_c * const key_K, + const eap_variable_data_c * const label_A, + const eap_variable_data_c * const input_B, + const u32_t output_length, + eap_variable_data_c * const output + ); + + EAP_FUNC_IMPORT eap_status_e select_minimum( + const eap_variable_data_c * const input_a, + const eap_variable_data_c * const input_b, + const eap_variable_data_c ** const minimum, + const eap_variable_data_c ** const maximum); + + + EAP_FUNC_IMPORT eap_status_e create_PMKID(); + + eap_status_e set_reassociation_parameters( + const eap_variable_data_c * const pairwise_PMK_WPXK3, + const eap_variable_data_c * const PMKID, + const eap_variable_data_c * const transient_PTK, + const eap_variable_data_c * const confirmation_KCK, + const eap_variable_data_c * const encryption_KEK, + const eap_variable_data_c * const temporal_TK, + const eap_variable_data_c * const WPXM_WPXK1, + const eap_variable_data_c * const WPXM_WPXK2, + const u32_t WPXM_WPXC, + const eapol_key_handshake_type_e eapol_key_handshake_type, + const eapol_key_authentication_type_e authentication_type + ); + + eap_status_e send_RC4_eapol_key_message( + const eapol_RC4_key_flags_e flags); + + void send_error_notification(const eap_status_e error); + + eap_status_e save_keys_for_test_use( + const eap_variable_data_c * const confirmation_KCK, + const eap_variable_data_c * const encryption_KEK, + const eap_variable_data_c * const temporal_TK, + const u32_t WPXM_WPXC); + +EAP_KEY_TEST_PUBLIC_FUNCTION + + + EAP_FUNC_IMPORT eap_status_e derive_PTK(); + + +EAP_KEY_TEST_PRIVATE_FUNCTION + + + EAP_FUNC_IMPORT eap_status_e derive_WPXM_WPXK1_WPXK2(); + + EAP_FUNC_IMPORT eap_status_e derive_WPXM_PTK(const u32_t WPXM_WPXC); + + EAP_FUNC_IMPORT eap_status_e verify_field_is_zero( + const u8_t * const field, + const u32_t field_length); + + EAP_FUNC_IMPORT eap_status_e encrypt_key_data( + eapol_RSNA_key_header_c * const eapol_key_message); + + EAP_FUNC_IMPORT eap_status_e decrypt_key_data( + eapol_RSNA_key_header_c * const eapol_key_message); + + + EAP_FUNC_IMPORT eap_status_e create_key_mic( + eapol_RSNA_key_header_c * const eapol_key_message, + const eap_variable_data_c * const confirmation_key); + + EAP_FUNC_IMPORT eap_status_e verify_key_mic( + eapol_RSNA_key_header_c * const eapol_key_message, + const eap_variable_data_c * const confirmation_key); + + + EAP_FUNC_IMPORT eap_status_e create_nonce( + eap_variable_data_c * const nonce, + const u32_t nonce_length); + + EAP_FUNC_IMPORT eap_status_e initialize_4_way_handshake( + const eap_am_network_id_c * const receive_network_id, + const eapol_protocol_version_e received_eapol_version); + + EAP_FUNC_IMPORT eap_status_e create_4_way_handshake_message_1( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type); + + EAP_FUNC_IMPORT eap_status_e create_4_way_handshake_message_2( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const u64_t received_key_replay_counter, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type); + + EAP_FUNC_IMPORT eap_status_e create_4_way_handshake_message_3( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type); + + EAP_FUNC_IMPORT eap_status_e create_4_way_handshake_message_4( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const u64_t received_key_replay_counter, + const bool received_secure_bit, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type); + + EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_2_payloads( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length); + + EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_3_payloads_a( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length, + bool * const group_key_received); + + EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_3_payloads_b( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length, + const bool group_key_received); + + EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_0( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length); + + EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_1( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length); + + EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_2( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length); + + EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_3( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length); + + EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message_4( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length); + + + EAP_FUNC_IMPORT eap_status_e start_group_key_handshake( + const eap_am_network_id_c * const receive_network_id, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type); + + EAP_FUNC_IMPORT eap_status_e process_group_key_handshake_message_0( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length); + + EAP_FUNC_IMPORT eap_status_e process_group_key_handshake_message_1( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length); + + EAP_FUNC_IMPORT eap_status_e process_group_key_handshake_message_2( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length); + + + EAP_FUNC_IMPORT eap_status_e create_eapol_key_handshake_message_0( + const bool true_when_4_way_handshake, ///< With false initiates Group Key Handshake. + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const u64_t received_key_replay_counter, + const eapol_protocol_version_e received_eapol_version); + + EAP_FUNC_IMPORT eap_status_e create_group_key_handshake_message_1( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type); + + EAP_FUNC_IMPORT eap_status_e create_group_key_handshake_message_2( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const u64_t received_key_replay_counter, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type); + + + EAP_FUNC_IMPORT eap_status_e process_4_way_handshake_message( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length); + + EAP_FUNC_IMPORT eap_status_e process_group_key_handshake_message( + const eap_am_network_id_c * const receive_network_id, + eapol_RSNA_key_header_c * const eapol_key_message, + const u32_t packet_length); + + EAP_FUNC_IMPORT eap_status_e process_RSNA_key_descriptor( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length); + + EAP_FUNC_IMPORT eap_status_e process_RC4_key_descriptor( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length); + + // This is documented in abs_eap_stack_interface_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + + // + EAP_FUNC_IMPORT eap_variable_data_c * get_authenticator_RSNA_IE(); + + // + EAP_FUNC_IMPORT eap_variable_data_c * get_unicast_cipher_suite_RSNA_IE(); + + // + EAP_FUNC_IMPORT eap_variable_data_c * get_supplicant_RSNA_IE(); + + // + EAP_FUNC_IMPORT eap_variable_data_c * get_received_PMKID(); + + // + EAP_FUNC_IMPORT eap_variable_data_c * get_supplicant_MAC_address(); + + // + EAP_FUNC_IMPORT eap_variable_data_c * get_authenticator_MAC_address(); + + // + EAP_FUNC_IMPORT u64_t get_key_reply_counter(); + + // + EAP_FUNC_IMPORT void increase_key_reply_counter(); + + // + EAP_FUNC_IMPORT void set_key_reply_counter( + const u64_t reply_counter); + + // + EAP_FUNC_IMPORT u64_t get_client_send_key_reply_counter(); + + // + EAP_FUNC_IMPORT void increase_client_send_key_reply_counter(); + + // + EAP_FUNC_IMPORT void set_client_send_key_reply_counter( + const u64_t reply_counter); + + // + EAP_FUNC_IMPORT eap_variable_data_c * get_ANonce(); + + // + EAP_FUNC_IMPORT eap_variable_data_c * get_SNonce(); + + // + EAP_FUNC_IMPORT eap_variable_data_c * get_confirmation_KCK(); + + // + EAP_FUNC_IMPORT eap_variable_data_c * get_encryption_KEK(); + + // + EAP_FUNC_IMPORT void set_eapol_key_state(const eapol_key_state_e state); + + // + EAP_FUNC_IMPORT eapol_key_state_e get_eapol_key_state() const; + + EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_eapol_key_state(); + + // + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + // + EAP_FUNC_IMPORT eap_status_e resend_packet( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + // + EAP_FUNC_IMPORT eap_status_e cancel_retransmission(); + + + // + EAP_FUNC_IMPORT eap_status_e cancel_handshake_timeout(); + + // + EAP_FUNC_IMPORT eap_status_e init_handshake_timeout( + const u32_t timeout); + + + // + eap_status_e cancel_reassociate_timeout(); + + // + eap_status_e init_reassociate_timeout( + const u32_t timeout); + + + eap_status_e cancel_4_way_handshake_start_timeout(); + + eap_status_e init_4_way_handshake_start_timeout(); + + // + EAP_FUNC_IMPORT eap_status_e cancel_pmksa_caching_timeout(); + + // + EAP_FUNC_IMPORT eap_status_e init_retransmission( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const eap_code_value_e eap_code, + const u8_t eap_identifier, + const eap_type_value_e eap_type + ); + + EAP_FUNC_IMPORT eap_status_e cancel_group_key_update_timeout(); + + EAP_FUNC_IMPORT eap_status_e init_group_key_update_timeout( + const u32_t timeout); + + // + EAP_FUNC_IMPORT eap_status_e create_tkip_mic_failure_message( + eap_buf_chain_wr_c * const sent_packet, + const u32_t eapol_header_offset, + u32_t * const data_length, + u32_t * const buffer_length, + const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type, + const eapol_protocol_version_e received_eapol_version); + + + EAP_FUNC_IMPORT bool get_is_RSNA(); + + EAP_FUNC_IMPORT bool get_is_WPA(); + + EAP_FUNC_IMPORT bool get_is_WPXM(); + + + EAP_FUNC_IMPORT eap_status_e add_RSN_GTK_payload( + const eapol_RSNA_key_header_c * const eapol_key_message, + eap_variable_data_c * const group_GTK, + u32_t * const eapol_data_length); + + EAP_FUNC_IMPORT eap_status_e add_RSN_IE_payload( + const eapol_RSNA_key_header_c * const eapol_key_message, + eap_variable_data_c * const RSNA_IE, + u32_t * const eapol_data_length); + + EAP_FUNC_IMPORT eap_status_e get_key_length( + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e cipher, + u16_t * const key_length); + + EAP_FUNC_IMPORT eap_status_e send_RC4_eapol_key_messages(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~eapol_key_state_c(); + + // + EAP_FUNC_IMPORT eapol_key_state_c( + abs_eap_am_tools_c * const tools, + abs_eapol_key_state_c * const key_state_partner, + abs_eapol_core_c * const eapol_partner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const authenticator_RSNA_IE, + const eap_variable_data_c * const supplicant_RSNA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher, + const eap_variable_data_c * const pre_shared_key); + + // + EAP_FUNC_IMPORT eapol_key_state_c( + abs_eap_am_tools_c * const tools, + abs_eapol_key_state_c * const key_state_partner, + abs_eapol_core_c * const eapol_partner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type); + + + EAP_FUNC_IMPORT eap_status_e initialize( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const authenticator_RSNA_IE, + const eap_variable_data_c * const supplicant_RSNA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher, + const eap_variable_data_c * const pre_shared_key); + +#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + EAP_FUNC_IMPORT eap_status_e initialize( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type); + +#endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + EAP_FUNC_IMPORT eapol_key_state_c *copy(const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT bool get_is_encryption_on(); + + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + EAP_FUNC_IMPORT bool get_is_associated(); + +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + + // + EAP_FUNC_IMPORT eap_status_e started_eap_authentication(); + + /** + * This function checks whether cached PMKSA have correct cipher suite. + */ + EAP_FUNC_IMPORT eap_status_e check_pmksa_cache( + const eapol_key_authentication_type_e selected_eapol_key_authentication_type, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite); + + EAP_FUNC_IMPORT eap_status_e initialize_preauthentication( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type); + + EAP_FUNC_IMPORT eap_status_e read_reassociation_parameters( + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + const eapol_key_authentication_type_e authentication_type, + eap_variable_data_c * const PMKID, + const eap_variable_data_c * const received_WPA_ie, + const eap_variable_data_c * const sent_WPA_ie); + + EAP_FUNC_IMPORT eap_status_e complete_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const received_WPA_IE, // WLM must give only the WPA IE to EAPOL + const eap_variable_data_c * const sent_WPA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite); + + EAP_FUNC_IMPORT eap_status_e start_WPXM_reassociation( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + eap_variable_data_c * const send_reassociation_request_ie); + + EAP_FUNC_IMPORT eap_status_e complete_WPXM_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const received_reassociation_ie); + + EAP_FUNC_IMPORT eap_status_e configure(); + + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT eap_status_e set_WPXM_parameters( + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT eap_status_e set_s_nonce( + const eap_variable_data_c * const s_nonce); + + EAP_FUNC_IMPORT eap_status_e set_pairwise_PMK( + const eap_variable_data_c * const key, + const eap_am_network_id_c * const send_network_id); + + EAP_FUNC_IMPORT eap_status_e allow_4_way_handshake(); + + EAP_FUNC_IMPORT eap_status_e start_4_way_handshake( + const eap_am_network_id_c * const receive_network_id); + + // + EAP_FUNC_IMPORT eap_status_e process_eapol_key_frame( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length); + + // This is documented in abs_eap_stack_interface_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * The object_increase_reference_count() function increases the reference count. + */ + EAP_FUNC_IMPORT void object_increase_reference_count(); + + /** + * The object_decrease_reference_count () function decreases + * the reference count and returns the remaining value. + * The EAP type is removed after there is no references to it. + */ + EAP_FUNC_IMPORT u32_t object_decrease_reference_count(); + + // See abs_eap_base_timer_c::timer_expired(). + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data); + + // See abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data); + + /** + * Gets flag whether this session is marked removed. + * Session is removed later if it is not reused. + */ + EAP_FUNC_IMPORT bool get_marked_removed(); + + /** + * Marks this session removed. + * Session is removed later if it is not reused. + */ + EAP_FUNC_IMPORT void set_marked_removed(); + + /** + * Marks this session not removed. + * Session is not removed it is reused. + */ + EAP_FUNC_IMPORT void unset_marked_removed(); + + /** + * This function resets object partially. + * Member attributes needed in reassociation are left untouched. + */ + EAP_FUNC_IMPORT eap_status_e reset_cached_pmksa(); + + /** + * This function resets the full state of object to same as + * state was after the configure() function call. + * If object reset succeeds this function must return eap_status_ok. + * If object reset fails this function must return corresponding error status. + * @return This function returns the status of reset operation. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + EAP_FUNC_IMPORT eap_status_e tkip_mic_failure( + const bool fatal_failure_when_true, + const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type); + + // + EAP_FUNC_IMPORT eap_status_e init_pmksa_caching_timeout(); + + // + EAP_FUNC_IMPORT eap_status_e cancel_authentication_session(); + + //-------------------------------------------------- +}; // class eapol_key_state_c + + +//-------------------------------------------------- + +#endif //#if !defined(_EAPOL_KEY_STATE_H_) + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_key_state_string.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_key_state_string.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_KEY_STATE_STRING_H_) +#define _EAPOL_KEY_STATE_STRING_H_ + + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eapol_rsna_key_data_header.h" +#include "eapol_rsna_key_header.h" +#include "eap_am_network_id.h" +#include "eapol_key_types.h" + +//-------------------------------------------------- + + +/// This class includes the debug strings of the tls_cipher_suites_e, tls_certificate_type_e and tls_compression_method_e. +class EAP_EXPORT eapol_key_state_string_c +{ +public: + + EAP_FUNC_IMPORT virtual ~eapol_key_state_string_c(); + + EAP_FUNC_IMPORT eapol_key_state_string_c(); + + /** + * Function returns string of eapol_key_state_e. + * @param state is the queried string. + */ + EAP_FUNC_IMPORT eap_const_string get_eapol_key_state_string( + const eapol_key_state_e state) const; + + /** + * Function returns string of eapol_key_handshake_type_e. + * @param state is the queried string. + */ + EAP_FUNC_IMPORT eap_const_string get_eapol_key_handshake_type_string( + const eapol_key_handshake_type_e handshake_type) const; + + /** + * Function returns string of eapol_key_handshake_type_e. + * @param state is the queried string. + */ + EAP_FUNC_IMPORT eap_const_string get_eapol_key_authentication_type_string( + const eapol_key_authentication_type_e authentication_type) const; + + /** + * Function returns string of eapol_key_descriptor_type_e. + * @param state is the queried string. + */ + eap_const_string get_eapol_key_descriptor_type_string( + const eapol_key_descriptor_type_e key_descriptor_type) const; + +}; + +//-------------------------------------------------- + +#endif //#if !defined(_EAPOL_KEY_STATE_STRING_H_) + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_key_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_key_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,432 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_EAPOL_KEY_TYPES_H_) +#define _EAPOL_KEY_TYPES_H_ + +#include "eap_configuration_field.h" + +//-------------------------------------------------------------------------------------------------- + +enum eapol_wpa_psk_constants_e +{ + EAPOL_WPA_PSK_LENGTH_BYTES = 32ul, +}; + +/** + * Enumeration of EAPOL ethernet type. + */ +enum eapol_ethernet_type_e +{ + eapol_ethernet_type_none = 0, + eapol_ethernet_type_pae = 0x888e, ///< Ethernet type Port Access Entity (PAE) + eapol_ethernet_type_preauthentication = 0x88c7, ///< Ethernet type Preauthentication +#if defined(USE_WAPI_CORE) + eapol_ethernet_type_wapi = 0x88b4, ///< Ethernet type WAPI +#endif //#if defined(USE_WAPI_CORE) +}; + +/** + * This is enumeration of key types. + * NOTE, do not change the values, these are used in interface. + * These values are used in for loop. + */ +enum eapol_key_type_e +{ + eapol_key_type_broadcast = 0, + eapol_key_type_unicast = 1, +#if defined(EAP_USE_WPXM) + eapol_key_type_wpxm_wpxk1 = 2, + eapol_key_type_wpxm_wpxk2 = 3, +#endif //#if defined(EAP_USE_WPXM) + eapol_key_type_pmkid = 4, + eapol_key_type_last_type, ///< Keep this the last one. +}; + +/// Enumeration of RC4 Key flag field. +/// NOTE, do not change the values, these are used in interface. +enum eapol_RC4_key_flags_e +{ + eapol_RC4_key_flag_broadcast = 0, + eapol_RC4_key_flag_unicast = 1, + eapol_RC4_key_flag_none = 0xff +}; + + +/// NOTE, do not change the values, these are used in interface. +enum eapol_wlan_authentication_state_e +{ + eapol_wlan_authentication_state_none = 0, ///< Initial value. + eapol_wlan_authentication_state_association_ok = 1, ///< Successfull association. + eapol_wlan_authentication_state_this_ap_failed = 2, ///< Still other authentication could be tested. + eapol_wlan_authentication_state_failed_completely = 3, ///< No more options to try. + eapol_wlan_authentication_state_802_11_auth_algorithm_not_supported = 4, + eapol_wlan_authentication_state_authenticating = 5, ///< This is temporary build fix, do not use this anymore. Instead use eapol_wlan_authentication_state_eap_authentication_running or eapol_wlan_authentication_state_4_way_handshake_running. @{ remove after integrated with WLAN engine.} + eapol_wlan_authentication_state_eap_authentication_running = 6, + eapol_wlan_authentication_state_no_response = 7, + eapol_wlan_authentication_state_4_way_handshake_running = 8, + eapol_wlan_authentication_state_authentication_successfull = 9, + eapol_wlan_authentication_state_authentication_cancelled = 10, // When user cancels the password prompt. + eapol_wlan_authentication_state_immediate_reconnect = 11, ///< This was a provisioning of credentials. Immediately reconnect so the credentials can be used. +#if defined(USE_WAPI_CORE) + eapol_wlan_authentication_state_wapi_authentication_running = 12, +#endif //#if defined(USE_WAPI_CORE) +}; + +/** + * This is enumeration of authentication types. + * NOTE, do not change the values, these are used in interface. + */ +enum eapol_key_authentication_type_e +{ + eapol_key_authentication_type_none = 0, + eapol_key_authentication_type_RSNA_EAP = 1, ///< Authentication is RSNA 802.11i EAP-authentication, 4-Way, Group Key and STAKey Handshakes. + eapol_key_authentication_type_RSNA_PSK = 2, ///< Authentication is RNSA 802.11i PSK (pre shared key), 4-Way and Group Key Handshakes. + eapol_key_authentication_type_WPA_EAP = 3, ///< Authentication is WPA EAP-authentication, 4-Way and Group Key Handshakes. + eapol_key_authentication_type_WPA_PSK = 4, ///< Authentication is WPA PSK (pre shared key), 4-Way and Group Key Handshakes. + eapol_key_authentication_type_802_1X = 5, ///< Authentication is dynamic WEP (802.1X). EAP-authentication with simple EAPOL RC4 key message. + eapol_key_authentication_type_WPXM = 6, ///< Authentication is WPXM. + eapol_key_authentication_type_WFA_SC = 7, ///< Authentication is Wi-Fi Alliance Simple Configure. +#if defined(USE_WAPI_CORE) + eapol_key_authentication_type_WAI_PSK = 8, ///< Authentication is WAI PSK. + eapol_key_authentication_type_WAI_certificate = 9, ///< Authentication is WAI certificate. +#endif //#if defined(USE_WAPI_CORE) +}; + +/** + * This is enumeration of 802.11 authentication modes. + * NOTE, do not change the values, these are used in interface. + */ +enum eapol_key_802_11_authentication_mode_e +{ + eapol_key_802_11_authentication_mode_none = 0, + eapol_key_802_11_authentication_mode_open = 1, ///< Authentication is 802.11 open authentication. + eapol_key_802_11_authentication_mode_shared = 2, ///< Authentication is 802.11 shared authentication. + eapol_key_802_11_authentication_mode_leap = 3, ///< Authentication is LEAP-authentication. +}; + +/** + * This is enumeration of EAPOL handshake types. + * NOTE, do not change the values, these are used in interface. + */ +enum eapol_key_handshake_type_e +{ + eapol_key_handshake_type_none = 0, + eapol_key_handshake_type_4_way_handshake = 1, + eapol_key_handshake_type_group_key_handshake = 2, + eapol_key_handshake_type_STAKey_handshake = 3, + eapol_key_handshake_type_802_11i_handshake = 4, + eapol_key_handshake_type_dynamic_WEP = 5, +#if defined(EAP_USE_WPXM) + eapol_key_handshake_type_WPXM_reassociation = 6, +#endif //#if defined(EAP_USE_WPXM) +#if defined(USE_WAPI_CORE) + eapol_key_handshake_type_wai_handshake = 7, +#endif //#if defined(USE_WAPI_CORE) +}; + +/** + * This is enumeration of EAPOL states. + * NOTE, do not change the values, these are used in interface. + */ +enum eapol_key_state_e +{ + eapol_key_state_none = 0, + + eapol_key_state_preauthenticated = 1, + + eapol_key_state_eap_authentication_running = 2, + + eapol_key_state_wait_4_way_handshake_start = 3, + eapol_key_state_wait_4_way_handshake_message_1 = 4, + eapol_key_state_wait_4_way_handshake_message_2 = 5, + eapol_key_state_wait_4_way_handshake_message_3 = 6, + eapol_key_state_wait_4_way_handshake_message_4 = 7, + eapol_key_state_4_way_handshake_running = 8, + eapol_key_state_4_way_handshake_failed = 9, + eapol_key_state_4_way_handshake_successfull = 10, + + eapol_key_state_wait_group_key_handshake_message_1 = 11, + eapol_key_state_wait_group_key_handshake_message_2 = 12, + eapol_key_state_group_key_handshake_failed = 13, + eapol_key_state_group_key_handshake_successfull = 14, + + eapol_key_state_wait_rc4_key_message = 15, + + eapol_key_state_802_11i_authentication_terminated_unsuccessfull = 16, + eapol_key_state_802_11i_authentication_finished_successfull = 17, + + eapol_key_state_reassociation_failed = 18, + +#if defined(EAP_USE_WPXM) + eapol_key_state_wpxm_reassociation_finished_successfull = 19, +#endif //#if defined(EAP_USE_WPXM) + +#if defined(USE_WAPI_CORE) + eapol_key_state_wapi_authentication_terminated_unsuccessfull = 20, + eapol_key_state_wapi_authentication_finished_successfull = 21, + eapol_key_state_wapi_authentication_running = 22, +#endif //#if defined(USE_WAPI_CORE) + +}; + +/** + * This is enumeration of authentication server. + * NOTE, do not change the values, these are used in interface. + */ +enum eapol_authentication_server_state_e +{ + eapol_authentication_server_state_none = 0, + eapol_authentication_server_state_authentication_successfull = 1, +}; + +//-------------------------------------------------------------------------------------------------- + +/** + * @defgroup EAPOL_key_state_config_options Configuration options of EAPOL Key State. + * The following configuration options are read through abs_eap_base_type_c::read_configure() function. + * @{ + */ + +/** + * This is u32_t configuration option. + * This is the maximum count EAPOL key state Authenticator resents EAPOL-Key message again. + * This is used in simulator testing. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_state_retransmission_counter, + "EAPOL_key_state_retransmission_counter", + eap_configure_type_u32_t, + false); + +/** + * This is u32_t configuration option. + * This is the time after EAPOL ket state Authenticator resents message again. + * Time is in milli seconds. + * This is used in simulator testing. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_state_retransmission_time, + "EAPOL_key_state_retransmission_time", + eap_configure_type_u32_t, + false); + +/** + * This is u32_t configuration option. + * This is the maximum time EAPOL-Key Handshake could succeed. + * EAPOL-Key Handshake is terminated after this time elapses. + * Time is in milli seconds. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_state_handshake_timeout, + "EAPOL_key_state_handshake_timeout", + eap_configure_type_u32_t, + false); + +#if defined(EAP_USE_WPXM) +/** + * This is u32_t configuration option. + * This is the maximum time WPXM reassociation could succeed. + * WPXM reassociation is terminated after this time elapses. + * Time is in milli seconds. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_state_wpxm_reassociate_timeout, + "EAPOL_key_state_wpxm_reassociate_timeout", + eap_configure_type_u32_t, + false); +#endif //#if defined(EAP_USE_WPXM) + +/** + * This is u32_t configuration option. + * This is the maximum time EAPOL-Key PMKSA is cached. + * Time is in milli seconds. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_state_pmksa_caching_timeout, + "EAPOL_key_state_pmksa_caching_timeout", + eap_configure_type_u32_t, + false); + +/** + * This string configuration option value selects the test authentication and key management. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_authentication_type, + "EAPOL_key_authentication_type", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_authentication_type_config_value_RSNA_EAP, + "RSNA_EAP", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_authentication_type_config_value_RSNA_PSK, + "RSNA_PSK", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_authentication_type_config_value_WPA_EAP, + "WPA_EAP", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_authentication_type_config_value_WPA_PSK, + "WPA_PSK", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_authentication_type_config_value_dynamic_WEP, + "dynamic_WEP", + eap_configure_type_string, + false); + +#if defined(EAP_USE_WPXM) +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_authentication_type_config_value_WPXM, + "WPXM", + eap_configure_type_string, + false); +#endif //#if defined(EAP_USE_WPXM) + +#if defined(EAP_USE_WPXM) +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_WPXM_type, + "EAPOL_WPXM_type", + eap_configure_type_string, + false); +#endif //#if defined(EAP_USE_WPXM) + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_authentication_type_config_value_WFA_SC, + "WFA_SC", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_authentication_type_config_value_WAI_PSK, + "WAI_PSK", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_authentication_type_config_value_WAI_certificate, + "WAI_certificate", + eap_configure_type_string, + false); + + +/** + * This string configuration option value selects the test pairwise cipher. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_pairwise_cipher, + "EAPOL_key_pairwise_cipher", + eap_configure_type_string, + false); + +/** + * This string configuration option value selects the test group cipher. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_group_cipher, + "EAPOL_key_group_cipher", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_cipher_CCMP, + "CCMP", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_cipher_TKIP, + "TKIP", + eap_configure_type_string, + false); + + +/** + * This is boolean configuration option. + * This flag tells whether broken 4-Way Handshake message 1 without PMKID is allowed (true) or dropped (false). + * Default value id false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_state_allow_missing_PMKID_in_message_1, + "EAPOL_key_state_allow_missing_PMKID_in_message_1", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag tells whether broken 4-Way Handshake message 1 without PMKID is created (true) or not (false). + * Default value id false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_state_skip_PMKID_key_data_in_message_1, + "EAPOL_key_state_skip_PMKID_key_data_in_message_1", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag activates group key update test (true) or not (false). + * Default value id false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_state_TEST_group_key_update, + "EAPOL_key_state_TEST_group_key_update", + eap_configure_type_boolean, + false); + + +/** + * This is boolean configuration option. + * This flag tells whether broken 4-Way Handshake message 1 with non zero MIC is allowed (true) or dropped (false). + * Default value id false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_state_allow_non_zero_mic_in_message_1, + "EAPOL_key_state_allow_non_zero_mic_in_message_1", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag tells the EAPOL must indicate PMKID to lower layers (true) or not (false). + * Default value id false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAPOL_key_state_indicate_pmkid_to_lower_layer, + "EAPOL_key_state_indicate_pmkid_to_lower_layer", + eap_configure_type_boolean, + false); + +/** @} */ // End of group EAPOK_key_state_config_options. + +//-------------------------------------------------------------------------------------------------- + +#endif //#if !defined(_EAPOL_KEY_TYPES_) diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_message_wlan_authentication.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_message_wlan_authentication.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,251 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(EAPOL_MESSAGE_WLAN_AUTHENTICATION_H) +#define EAPOL_MESSAGE_WLAN_AUTHENTICATION_H + + +#include "eapol_wlan_authentication.h" +#include "eapol_ethernet_header.h" +#include "eap_file_config.h" +//#include +#include "abs_eapol_wlan_database_reference_if.h" +#include "abs_eapol_message_wlan_authentication.h" +#include "eapol_handle_tlv_message_data.h" + +/** @file */ + +class eap_tlv_header_c; + +/// This class is the common part of EAPOL message interface. +/// This class implements the message creation and parsing function. +class eapol_message_wlan_authentication_c +: public abs_eapol_wlan_authentication_c +, public abs_eap_base_timer_c +, public abs_eapol_wlan_database_reference_if_c +{ + +private: + + /// This is pointer to the tools class. + abs_eap_am_tools_c * m_am_tools; + + /// This is pointer to the WLAN authentication implementation. + eapol_wlan_authentication_c * m_wauth; + + /// Pointer to the lower layer in the stack + abs_eapol_message_wlan_authentication_c * m_partner; + + eap_variable_data_c m_wlan_database_reference; + + u32_t m_header_offset; + u32_t m_MTU; + u32_t m_trailer_length; + + wlan_eap_if_send_status_e m_error_code; + + eapol_tlv_message_type_function_e m_error_function; + + bool m_use_asyncronous_test; + + bool m_is_valid; + + // ---------------------------------------------------------------------- + + EAP_FUNC_IMPORT eap_status_e check_pmksa_cache( + EAP_TEMPLATE_CONST eap_array_c * const tlv_blocks); + + EAP_FUNC_IMPORT eap_status_e start_authentication( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e complete_association( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e disassociation( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e start_preauthentication( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e start_reassociation( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e complete_reassociation( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e start_WPXM_reassociation( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e complete_WPXM_reassociation( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e packet_process( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e tkip_mic_failure( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e update_header_offset( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e update_wlan_database_reference_values( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e send_error_message( + const eap_status_e status, + const eapol_tlv_message_type_function_e function); + + EAP_FUNC_IMPORT eap_status_e process_message_type_error( + EAP_TEMPLATE_CONST eap_array_c * const parameters); + + EAP_FUNC_IMPORT eap_status_e process_message(eapol_handle_tlv_message_data_c * const message); + + EAP_FUNC_IMPORT eap_status_e send_message(eapol_handle_tlv_message_data_c * const message); + + // ---------------------------------------------------------------------- + +public: + + EAP_FUNC_IMPORT ~eapol_message_wlan_authentication_c(); + + EAP_FUNC_IMPORT eapol_message_wlan_authentication_c( + abs_eap_am_tools_c * const tools, + abs_eapol_message_wlan_authentication_c * const partner); + + + /// This function configures the object and sets the initial values + /// of header offset, MTU and trailer length. + /// Look at the abs_eap_base_type_c::get_header_offset() + /// for description of header_offset, MTU and trailer_length. + EAP_FUNC_IMPORT eap_status_e configure( + const u32_t header_offset, + const u32_t MTU, + const u32_t trailer_length); + + // Look at abs_eap_stack_interface_c::shutdown(). + EAP_FUNC_IMPORT eap_status_e shutdown(); + + // Look at abs_eap_stack_interface_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + + + // ------------------------------------------------------ + // The following functions are from abs_eap_base_timer_c. + + // Look at abs_eap_base_timer_c::timer_expired(). + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, + void *data); + + // Look at abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, + void *data); + + // The previous functions are from abs_eap_base_timer_c. + // ------------------------------------------------------ + + + // ---------------------------------------------------------------- + // The following functions are from abs_eapol_wlan_authentication_c. + + // Look at abs_eapol_wlan_authentication_c::packet_send(). + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + // Look at abs_eapol_wlan_authentication_c::get_header_offset(). + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + // Look at abs_eapol_wlan_authentication_c::associate(). + EAP_FUNC_IMPORT eap_status_e associate( + eapol_key_802_11_authentication_mode_e authentication_mode); + + // Look at abs_eapol_wlan_authentication_c::disassociate(). + EAP_FUNC_IMPORT eap_status_e disassociate( + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + const bool self_disassociation); + + // Look at abs_eapol_wlan_authentication_c::packet_data_session_key(). + EAP_FUNC_IMPORT eap_status_e packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key); + + // Look at abs_eapol_wlan_authentication_c::state_notification(). + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state); + + // Look at abs_eapol_wlan_authentication_c::add_rogue_ap(). + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + // Look at abs_eapol_wlan_authentication_c::reassociate(). + EAP_FUNC_IMPORT eap_status_e reassociate( + const eap_am_network_id_c * const send_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const PMKID); + + // The previous functions are from abs_eapol_wlan_authentication_c. + // ---------------------------------------------------------------- + + + // ---------------------------------------------------------------------- + // The following function is from abs_eapol_wlan_database_reference_if_c. + + // Look at abs_eapol_wlan_database_reference_if_c::get_wlan_database_reference_values(). + EAP_FUNC_IMPORT eap_status_e get_wlan_database_reference_values( + eap_variable_data_c * const reference) const; + + // The previous function is from abs_eapol_wlan_database_reference_if_c. + // ---------------------------------------------------------------------- + + + /// Function receives the data message from lower layer. + /// Data is formatted to Attribute-Value Pairs. + /// Look at eap_tlv_header_c and eap_tlv_message_data_c. + EAP_FUNC_IMPORT wlan_eap_if_send_status_e process_data(const void * const data, const u32_t length); + + // ---------------------------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + + EAP_FUNC_IMPORT eap_status_e save_simple_config_session( + const simple_config_state_e state, + EAP_TEMPLATE_CONST eap_array_c * const credential_array, + const eap_variable_data_c * const new_password, + const simple_config_Device_Password_ID_e Device_Password_ID, + const simple_config_payloads_c * const other_configuration); + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + // ---------------------------------------------------------------------- +}; + +#endif //#if !defined(EAPOL_MESSAGE_WLAN_AUTHENTICATION_H) + + +//-------------------------------------------------- diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_rc4_key_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_rc4_key_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,201 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_RC4_KEY_HEADER_H_) +#define _EAPOL_RC4_KEY_HEADER_H_ + +#include "eapol_header.h" +#include "eapol_key_header.h" +#include "eap_general_header_base.h" + + +//------------------------------------------------------ + + +enum eapol_RC4_key_header_constants_e +{ + EAPOL_RC4_KEY_IV_LENGTH = 16ul, + EAPOL_RC4_KEY_REPLAY_COUNTER_LENGTH = 8ul, + EAPOL_RC4_KEY_SIGNATURE_LENGTH = 16ul, + SIZE_OF_EMPTY_EAPOL_RC4_KEY_FRAME = 48ul, + SIZE_OF_EMPTY_EAPOL_RC4_KEY_BODY = 44ul, ///< <- This is without version, packet type and packet body length fields. +}; + + +/// This is base class of EAPOL RC4 key header. +/** + * This defined in rfc3580.txt. + * See chapter RC4 EAPOL-Key Frame. + * @code + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+ + * | EAPOL Version | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | EAPOL Type | EAPOL Packet Body Length | Descriptor Ty.| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | RC4 Key Length | RC4 Reply Counter 8 octets | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -+ + * | | + * +- -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | RC4 Key IV 16 octets | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -+ + * | | + * +- -+ + * | | + * +- -+ + * | | + * +- -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | RC4 Key Index | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -+ + * | RC4 Key Signature 16 octets | + * +- -+ + * | | + * +- -+ + * | | + * +- +-+-+-+-+-+-+-+-+ + * | | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -+ + * | RC4 Key n octets | + * +- -+ + * | n = (Packet Body Length) - SIZE_OF_EMPTY_EAPOL_KEY_HEADER | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ +class EAP_EXPORT eapol_RC4_key_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + enum bit_masks_e + { + m_flag_mask_key_flag = 0x80, + }; + + enum bit_shifts_e + { + m_flag_shift_key_flag = 0x07, + }; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + enum offsets_e + { + m_offset_eapol_version = 0ul, + m_offset_eapol_type = m_offset_eapol_version + sizeof(u8_t), + m_offset_eapol_packet_body_length = m_offset_eapol_type + sizeof(u8_t), + m_offset_key_descriptor_type = m_offset_eapol_packet_body_length + sizeof(u16_t), + m_offset_key_length = m_offset_key_descriptor_type + sizeof(u8_t), + m_offset_replay_counter = m_offset_key_length + sizeof(u16_t), + m_offset_key_IV = m_offset_replay_counter + EAPOL_RC4_KEY_REPLAY_COUNTER_LENGTH, + m_offset_key_index = m_offset_key_IV + EAPOL_RC4_KEY_IV_LENGTH, + m_offset_key_signature = m_offset_key_index + sizeof(u8_t), + m_offset_data = m_offset_key_signature + EAPOL_RC4_KEY_SIGNATURE_LENGTH, + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + enum eapol_RC4_key_header_constants_e + { + EAPOL_RC4_EAPOL_KEY_MAXIMUM_SIZE = 0xffff, + }; + + + // + EAP_FUNC_IMPORT virtual ~eapol_RC4_key_header_c(); + + // + EAP_FUNC_IMPORT eapol_RC4_key_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT eapol_protocol_version_e get_eapol_protocol_version() const; + + EAP_FUNC_IMPORT eapol_packet_type_e get_eapol_packet_type() const; + + EAP_FUNC_IMPORT u16_t get_eapol_packet_body_length() const; + + EAP_FUNC_IMPORT eapol_key_descriptor_type_e get_key_descriptor_type() const; + + EAP_FUNC_IMPORT u16_t get_key_length() const; + + EAP_FUNC_IMPORT u8_t *get_replay_counter(); + + EAP_FUNC_IMPORT u8_t *get_key_IV(); + + EAP_FUNC_IMPORT eapol_RC4_key_flags_e get_key_flag() const; + + EAP_FUNC_IMPORT u8_t get_key_index() const; + + EAP_FUNC_IMPORT u8_t *get_key_signature() const; + + EAP_FUNC_IMPORT static u16_t get_header_length(); + + EAP_FUNC_IMPORT u8_t * get_key() const; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT eap_status_e set_eapol_protocol_version(eapol_protocol_version_e version); + + EAP_FUNC_IMPORT eap_status_e set_eapol_packet_type(eapol_packet_type_e type); + + EAP_FUNC_IMPORT eap_status_e set_eapol_packet_body_length(u16_t eapol_length); + + EAP_FUNC_IMPORT eap_status_e set_key_descriptor_type(eapol_key_descriptor_type_e eapol_key_descriptor_type); + + EAP_FUNC_IMPORT eap_status_e set_key_length(u16_t length); + + EAP_FUNC_IMPORT eap_status_e set_key_flag(eapol_RC4_key_flags_e flags); + + EAP_FUNC_IMPORT eap_status_e set_key_index(u8_t index); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT void zero_key_signature( + abs_eap_am_tools_c * const m_am_tools + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT eap_status_e check_header() const; + + // + //-------------------------------------------------- +}; // class eapol_RC4_key_header_c + + +#endif //#if !defined(_EAPOL_KEY_H_) + +//------------------------------------------------------ +//------------------------------------------------------ +//------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_rsna_key_data_gtk_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_rsna_key_data_gtk_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,142 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_RSNA_KEY_DATA_GTK_HEADER_H_) +#define _EAPOL_RSNA_KEY_DATA_GTK_HEADER_H_ + +#include "eapol_header.h" +#include "eap_general_header_base.h" +#include "eapol_key_header.h" + + +//------------------------------------------------------ + +/// This is base class of EAPOL RSNA key data GTK header. +/** + * @code + * 0 1 2 3 4 5 6 7 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Key ID | Tx | Reserved | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Reserved | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | GTK (Length -6) Octets | + * +- -+ + * | | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * @endcode + */ +class EAP_EXPORT eapol_rsna_key_data_gtk_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + enum eapol_rsna_key_data_gtk_header_constants_e + { + EAPOL_RSNA_KEY_DATA_FLAGS_FIELD_SIZE = sizeof(u8_t), + EAPOL_RSNA_KEY_DATA_RESERVED_FIELD_SIZE = sizeof(u8_t), + EAPOL_RSNA_KEY_DATA_INVALID_GTK_INDEX = 0xff, + }; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + enum offsets_e + { + m_offset_flags = 0ul, + m_offset_reserved = m_offset_flags + EAPOL_RSNA_KEY_DATA_FLAGS_FIELD_SIZE, + m_offset_gtk = m_offset_reserved + EAPOL_RSNA_KEY_DATA_RESERVED_FIELD_SIZE, + }; + + enum eapol_rsna_key_data_gtk_header_masks_e + { + EAPOL_RSNA_KEY_DATA_GTK_INDEX_MASK = 0x03, + EAPOL_RSNA_KEY_DATA_TX_MASK = 0x04, + EAPOL_RSNA_KEY_DATA_RESERVED_MASK = 0xf8, + }; + + enum eapol_rsna_key_data_gtk_header_shift_e + { + EAPOL_RSNA_KEY_DATA_GTK_INDEX_SHIFT = 0x00, + EAPOL_RSNA_KEY_DATA_TX_SHIFT = 0x02, + EAPOL_RSNA_KEY_DATA_RESERVED_SHIFT = 0x03, + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eapol_rsna_key_data_gtk_header_c(); + + // + eapol_rsna_key_data_gtk_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length); + + u8_t get_key_index() const; + + bool get_tx_bit() const; + + u8_t * get_gtk_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + /** + * This function returns pointer to the GTK. + * @param contignuous_bytes is the length of queried data in bytes. + */ + u8_t * get_gtk(const u32_t contignuous_bytes) const; + + static u16_t get_header_length(); + + + eap_status_e set_key_index(const u32_t index); + + eap_status_e set_tx(const bool tx); + + eap_status_e set_reserved_flag(const u32_t reserved); + + eap_status_e set_reserved_field(const u32_t reserved); + + eap_status_e check_header() const; + + eap_status_e reset_header(); + + // + //-------------------------------------------------- +}; // class eapol_rsna_key_data_gtk_header_c + + +#endif //#if !defined(_EAPOL_RSNA_KEY_DATA_HEADER_H_) + +//------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_rsna_key_data_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_rsna_key_data_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,214 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_RSNA_KEY_DATA_HEADER_H_) +#define _EAPOL_RSNA_KEY_DATA_HEADER_H_ + +#include "eapol_header.h" +#include "eap_general_header_base.h" +#include "eapol_key_header.h" + + +//------------------------------------------------------ + +enum eapol_RSNA_key_descriptor_type_e +{ + eapol_RSNA_key_data_type_none = 0x00, + eapol_RSNA_key_data_type_RSN_IE = 0x30, + eapol_RSNA_key_data_type_RSN_key_data = 0xdd, + eapol_RSNA_key_data_type_WPA_IE = 0xdd, +#if defined(EAP_USE_WPXM) + eapol_RSNA_key_data_type_WPXM_reassoc_IE = 0x9c, +#endif //#if defined(EAP_USE_WPXM) +}; + +enum eapol_RSNA_key_payload_type_e +{ + eapol_RSNA_key_payload_type_reserved = 0x00, + eapol_RSNA_key_payload_type_group_key_and_id = 0x01, + eapol_RSNA_key_payload_type_sta_key = 0x02, + eapol_RSNA_key_payload_type_mac_address = 0x03, + eapol_RSNA_key_payload_type_pmkid = 0x04, + eapol_RSNA_key_payload_type_none = 0xff, +}; + +enum eapol_RSNA_key_data_oui_e +{ + eapol_RSNA_key_data_oui_IEEE = 0x00000fac, +}; + +/** + * This is the default trace mask for EAPOL Key Data. + */ +const u32_t TRACE_FLAGS_EAPOL_KEY_DATA_ERROR = eap_am_tools_c::eap_trace_mask_error; + + +/// This is base class of EAPOL RSNA key data header. +/** + * RSN IE have identical first two bytes, Type and Length fields. + * @code + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type = 0xdd | Length | OUI 3 octets ...| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ... OUI | Data Type | Data (Length - 4) octets ... : + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ +class EAP_EXPORT eapol_rsna_key_data_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This flag indicates whether the message is RSNA (true) or WPA (false). + bool m_is_RSNA_when_true; + + /// This flag indicates whether the message is WPXM (true) or other (false). + /// The other cases are separated with m_is_RSNA_when_true flag. + bool m_is_WPXM_when_true; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + enum eapol_RSNA_key_data_header_constants_e + { + EAPOL_RSNA_KEY_DATA_TYPE_FIELD_SIZE = sizeof(u8_t), + EAPOL_RSNA_KEY_DATA_LENGTH_FIELD_SIZE = sizeof(u8_t), + EAPOL_RSNA_KEY_DATA_OUI_FIELD_SIZE = 3ul*sizeof(u8_t), + EAPOL_RSNA_KEY_PAYLOAD_TYPE_FIELD_SIZE = sizeof(u8_t), + EAPOL_RSNA_KEY_DATA_LENGTH_FIELD_MINIMUM_SIZE = 4ul, + EAPOL_RSNA_KEY_ID_AND_GROUP_KEY_MINIMUM_SIZE = 2ul, + EAPOL_RSNA_KEY_ID_AND_GROUP_KEY_HEADER_SIZE = 2ul, + EAPOL_RSNA_STAKEY_MINIMUM_SIZE = 1ul, + EAPOL_RSNA_PMKID_MINIMUM_SIZE = 1ul, + EAPOL_RSNA_IE_MINIMUM_SIZE = 4ul, + }; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + enum offsets_e + { + m_offset_type = 0ul, + m_offset_length = m_offset_type + EAPOL_RSNA_KEY_DATA_TYPE_FIELD_SIZE, + m_offset_oui = m_offset_length + EAPOL_RSNA_KEY_DATA_LENGTH_FIELD_SIZE, + m_offset_key_data_payload_type = m_offset_oui + EAPOL_RSNA_KEY_DATA_OUI_FIELD_SIZE, + m_offset_key_data_payload = m_offset_key_data_payload_type + EAPOL_RSNA_KEY_PAYLOAD_TYPE_FIELD_SIZE, + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + enum eapol_RSNA_key_data_header_constants_part_2_e + { + EAPOL_RSNA_KEY_HEADER_LENGTH = m_offset_key_data_payload, + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eapol_rsna_key_data_header_c(); + + // + eapol_rsna_key_data_header_c( + abs_eap_am_tools_c * const tools, + const bool is_RSNA_when_true, + const bool is_WPXM_when_true, + void * const header_begin, + const u32_t header_buffer_length); + + eapol_RSNA_key_descriptor_type_e get_descriptor_type() const; + + u32_t get_header_and_body_length() const; + + u8_t get_length() const; + + u32_t get_oui() const; + + eapol_RSNA_key_payload_type_e get_payload_type() const; + + u32_t get_key_data_payload_length() const; + + /** + * This function returns pointer to the offset of Data of Key Data. + * @param offset is the offset of queried data in bytes. + * @param contignuous_bytes is the length of queried data in bytes. + */ + u8_t * get_key_data_payload_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + /** + * This function returns pointer to the Data of Key Data. + * @param contignuous_bytes is the length of queried data in bytes. + */ + u8_t * get_key_data_payload(const u32_t contignuous_bytes) const; + + /** + * This function return pointer to the next eapol_rsna_key_data_header_c in the same buffer. + */ + u8_t * get_next_header() const; + + static u16_t get_header_length(); + + eap_status_e set_type(const eapol_RSNA_key_descriptor_type_e type); + + eap_status_e set_length(const u8_t length); + + eap_status_e set_oui(const u32_t oui); + + eap_status_e set_payload_type(const eapol_RSNA_key_payload_type_e type); + + eap_status_e check_header() const; + + eap_status_e reset_header(); + + /** + * This function returns debug strings of the EAPOL Descriptor type. + */ + eap_const_string get_descriptor_type_string() const; + + /** + * This function returns debug strings of the EAPOL Key Data type. + */ + eap_const_string get_payload_type_string() const; + + // + //-------------------------------------------------- +}; // class eapol_rsna_key_data_header_c + + +#endif //#if !defined(_EAPOL_KEY_H_) + +//------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_rsna_key_data_payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_rsna_key_data_payloads.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,175 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_RSNA_KEY_DATA_PAYLOADS_H_) +#define _EAPOL_RSNA_KEY_DATA_PAYLOADS_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eapol_rsna_key_data_header.h" +#include "eap_array.h" + + + +class EAP_EXPORT eapol_rsna_variable_data_c +: public eap_variable_data_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + eapol_rsna_key_data_header_c m_original_header; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~eapol_rsna_variable_data_c(); + + EAP_FUNC_IMPORT eapol_rsna_variable_data_c( + abs_eap_am_tools_c * const tools, + const bool is_RSNA_when_true, + const bool is_WPXM_when_true); + + EAP_FUNC_IMPORT const eapol_rsna_key_data_header_c * get_original_header() const; + + EAP_FUNC_IMPORT eap_status_e set_buffer( + const eapol_rsna_key_data_header_c * const original_header, + u8_t *buffer, + const u32_t buffer_length, + const bool free_buffer, + const bool is_writable); + + //-------------------------------------------------- +}; // class eapol_rsna_variable_data_c + + +//-------------------------------------------------- + + +// +class EAP_EXPORT eapol_rsna_key_data_payloads_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + + /// This includes reference to Group Transient Key (GTK) if such payloads is included to EAPOL Key Data. + eapol_rsna_variable_data_c m_group_key; + + /// This is KeyID if such payloads is included to EAPOL Key Data. + u8_t m_group_key_id; + + /// This is Tx bit if such payloads is included to EAPOL Key Data. + bool m_group_key_tx_bit; + + + /// This includes reference to STAKey if such payloads is included to EAPOL Key Data. + eapol_rsna_variable_data_c m_STAKey; + + /// This includes reference to Pairwise Master Key ID (PMKID) if such payloads is included to EAPOL Key Data. + eapol_rsna_variable_data_c m_PMKID; + + /// This plain reference to information elements if such payloads is included to EAPOL Key Data. + /// Here could be included one or more RSN IEs. + eap_array_c m_RSN_IE; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + + enum eapol_rsna_key_data_payload_status_e + { + eapol_rsna_key_data_payload_status_optional, + eapol_rsna_key_data_payload_status_must_be, + eapol_rsna_key_data_payload_status_must_not_be + }; + + + EAP_FUNC_IMPORT virtual ~eapol_rsna_key_data_payloads_c(); + + EAP_FUNC_IMPORT eapol_rsna_key_data_payloads_c( + abs_eap_am_tools_c * const tools, + const bool is_RSNA_when_true, + const bool is_WPXM_when_true); + + EAP_FUNC_IMPORT bool check_one_payload( + const eapol_rsna_key_data_payload_status_e status, + const eapol_rsna_variable_data_c * const payload); + + EAP_FUNC_IMPORT bool check_one_payload( + const eapol_rsna_key_data_payload_status_e status, + const eap_array_c * const payload); + + /** This function checks the correct set of payloads are included in the message. + * NOTE do not change the order of parameters. + * Add new payload type to the last of the parameter list. + */ + EAP_FUNC_IMPORT bool check_payloads( + const eapol_rsna_key_data_payload_status_e key_id_and_group_key, + const eapol_rsna_key_data_payload_status_e sta_key, + const eapol_rsna_key_data_payload_status_e pmkid, + const eapol_rsna_key_data_payload_status_e one_or_more_RSN_IE + ); + + u8_t get_group_key_id(); + + bool get_group_key_tx(); + + eapol_rsna_variable_data_c * get_group_key(); + + eapol_rsna_variable_data_c * get_STAKey(); + + eapol_rsna_variable_data_c * get_PMKID(); + + eap_array_c * get_RSN_IE(); + + bool get_is_valid() const; + + + void set_group_key_id(const u8_t key_index); + + void set_group_key_tx(const bool key_tx_bit); + + //-------------------------------------------------- +}; // class eapol_rsna_key_data_payloads_c + + +#endif //#if !defined(_EAPOL_RSNA_KEY_DATA_PAYLOADS_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_rsna_key_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_rsna_key_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,517 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_RSNA_KEY_HEADER_H_) +#define _EAPOL_RSNA_KEY_HEADER_H_ + +#include "eapol_header.h" +#include "eap_general_header_base.h" +#include "eapol_key_header.h" +#include "eapol_key_types.h" +#include "eap_am_export.h" + + +//------------------------------------------------------ + +/// This is base class of EAPOL RSNA key header. +/** + * @code + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+ + * | EAPOL Version | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | EAPOL Type | EAPOL Packet Body Length | Descriptor Ty.| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key Information | Key Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key Replay Counter 8 octets | + * +- -+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key Nonce 32 octets | + * +- -+ + * : : + * +- -+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | EAPOL-Key IV 16 octets | + * +- -+ + * : : + * +- -+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key RSC 8 octets | + * +- -+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | STA MAC Address 6 octets | + * +- -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key MIC 16 octets | + * +- -+ + * : : + * +- -+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key Data Length (n) 2 octets | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key Data n octets | + * +- -+ + * : : + * +- -+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ +class EAP_EXPORT eapol_RSNA_key_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This flag indicates whether the message is RSNA (true) or WPA (false). + bool m_is_RSNA_when_true; + + /// This flag indicates whether the message is WPXM (true) or not (false). + bool m_is_WPXM_when_true; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is enumeration of Key Information bit masks. + enum key_information_bit_masks_e + { + m_key_information_mask_key_descriptor_version = 0x0007, ///< 3 bits wide + m_key_information_mask_key_type = 0x0008, ///< 1 bits wide + m_key_information_mask_reserved_a_RSNA = 0x0030, ///< 2 bits wide, this is RSNA specific. + m_key_information_mask_key_index_WPA = 0x0030, ///< 2 bits wide, this is WPA specific. + m_key_information_mask_install = 0x0040, ///< 1 bit wide + m_key_information_mask_key_ack = 0x0080, ///< 1 bit wide + m_key_information_mask_key_MIC = 0x0100, ///< 1 bit wide + m_key_information_mask_secure = 0x0200, ///< 1 bit wide + m_key_information_mask_error = 0x0400, ///< 1 bit wide + m_key_information_mask_request = 0x0800, ///< 1 bit wide + m_key_information_mask_encrypted_key_data_RSNA = 0x1000, ///< 1 bit wide, this is RSNA specific. + m_key_information_mask_reserved_b_RSNA = 0xe000, ///< 3 bits wide, this is RSNA specific. + m_key_information_mask_reserved_b_WPA = 0xf000, ///< 4 bits wide, this is WPA specific. + }; + + /// This is enumeration of Key Information bit masks. + enum key_information_bit_shifts_e + { + m_key_information_mask_key_descriptor_version_shift = 0, + m_key_information_mask_key_type_shift = 3, + m_key_information_mask_reserved_a_shift_RSNA = 4, // this is RSNA specific. + m_key_information_mask_key_index_shift_WPA = 4, // this is WPA specific. + m_key_information_mask_install_shift = 6, + m_key_information_mask_key_ack_shift = 7, + m_key_information_mask_key_MIC_shift = 8, + m_key_information_mask_secure_shift = 9, + m_key_information_mask_error_shift = 10, + m_key_information_mask_request_shift = 11, + m_key_information_mask_encrypted_key_data_shift_RSNA = 12, // this is RSNA specific. + m_key_information_mask_reserved_b_shift_WPA = 12, // this is WPA specific. + m_key_information_mask_reserved_b_shift_RSNA = 13, // this is RSNA specific. + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// This function sets the Key Information field. + EAP_FUNC_IMPORT eap_status_e set_key_information(const u16_t info); + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + enum key_descriptor_version_e + { + m_key_descriptor_version_none = 0, + m_key_descriptor_version_1 = 1, + m_key_descriptor_version_2 = 2, + }; + + enum eapol_RSNA_key_header_constants_e + { + EAPOL_RSNA_KEY_EAPOL_VERSION_SIZE = 1ul, + EAPOL_RSNA_KEY_EAPOL_TYPE_SIZE = 1ul, + EAPOL_RSNA_KEY_EAPOL_BODY_LENGTH_SIZE = 2ul, + + EAPOL_RSNA_KEY_DESCRIPTOR_TYPE_SIZE = 1ul, + EAPOL_RSNA_KEY_KEY_INFORMATION_SIZE = 2ul, + EAPOL_RSNA_KEY_KEY_LENGTH_SIZE = 2ul, + EAPOL_RSNA_KEY_REPLY_COUNTER_SIZE = 8ul, + EAPOL_RSNA_KEY_NONCE_SIZE = 32ul, + EAPOL_RSNA_EAPOL_KEY_IV_SIZE = 16ul, + EAPOL_RSNA_KEY_RSC_SIZE = 8ul, + EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE = 6ul, + EAPOL_RSNA_KEY_RESERVED_SIZE = 2ul, + EAPOL_RSNA_KEY_MIC_SIZE = 16ul, + EAPOL_RSNA_KEY_DATA_LENGTH_SIZE = 2ul, + + EAPOL_RSNA_KEY_DATA_PMKID_SIZE = 16ul, + EAPOL_RSNA_KEY_DATA_MAXIMUM_RSN_IE_SIZE = 257ul, + + EAPOL_RSNA_EAPOL_KEY_MAXIMUM_SIZE = 0xffff, + }; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + enum offsets_e + { + m_offset_eapol_version = 0ul, + m_offset_eapol_type = m_offset_eapol_version + EAPOL_RSNA_KEY_EAPOL_VERSION_SIZE, + m_offset_eapol_packet_body_length = m_offset_eapol_type + EAPOL_RSNA_KEY_EAPOL_TYPE_SIZE, + m_offset_key_descriptor_type = m_offset_eapol_packet_body_length + EAPOL_RSNA_KEY_EAPOL_BODY_LENGTH_SIZE, + m_offset_key_information = m_offset_key_descriptor_type + EAPOL_RSNA_KEY_DESCRIPTOR_TYPE_SIZE, + m_offset_key_length = m_offset_key_information + EAPOL_RSNA_KEY_KEY_INFORMATION_SIZE, + m_offset_key_replay_counter = m_offset_key_length + EAPOL_RSNA_KEY_KEY_LENGTH_SIZE, + m_offset_key_NONCE = m_offset_key_replay_counter + EAPOL_RSNA_KEY_REPLY_COUNTER_SIZE, + m_offset_EAPOL_key_IV = m_offset_key_NONCE + EAPOL_RSNA_KEY_NONCE_SIZE, + m_offset_key_RSC = m_offset_EAPOL_key_IV + EAPOL_RSNA_EAPOL_KEY_IV_SIZE, + m_offset_key_STA_MAC_address = m_offset_key_RSC + EAPOL_RSNA_KEY_RSC_SIZE, + m_offset_key_reserved = m_offset_key_STA_MAC_address + EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE, + m_offset_key_MIC = m_offset_key_reserved + EAPOL_RSNA_KEY_RESERVED_SIZE, + m_offset_key_data_length = m_offset_key_MIC + EAPOL_RSNA_KEY_MIC_SIZE, + m_offset_key_data = m_offset_key_data_length + EAPOL_RSNA_KEY_DATA_LENGTH_SIZE, + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + enum eapol_network_type_e + { + eapol_network_type_none, + eapol_network_type_RSN, + eapol_network_type_WPA, + }; + + enum eapol_RSNA_cipher_e + { + eapol_RSNA_cipher_none, + eapol_RSNA_cipher_CCMP, + eapol_RSNA_cipher_TKIP, + eapol_RSNA_cipher_WEP_40, + eapol_RSNA_cipher_WEP_104, + eapol_RSNA_cipher_SMS4, + }; + + enum eapol_RSNA_cipher_key_length_e + { + eapol_RSNA_cipher_key_length_none = 0ul, + eapol_RSNA_cipher_key_length_CCMP = 16ul, + eapol_RSNA_cipher_key_length_TKIP = 32ul, + eapol_RSNA_cipher_key_length_WEP_40 = 5ul, + eapol_RSNA_cipher_key_length_WEP_104 = 13ul, + }; + + enum eapol_tkip_mic_failure_type_e + { + eapol_tkip_mic_failure_type_group_key, + eapol_tkip_mic_failure_type_pairwise_key, + }; + + enum eapol_RSNA_key_type_e + { + eapol_RSNA_key_type_none, + eapol_RSNA_key_type_EAPOL_Key_Confirmation_Key, + eapol_RSNA_key_type_EAPOL_Key_Encryption_Key, + eapol_RSNA_key_type_Pairwise_Transient_Key, + eapol_RSNA_key_type_RN, + }; + + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~eapol_RSNA_key_header_c(); + + // + EAP_FUNC_IMPORT eapol_RSNA_key_header_c( + abs_eap_am_tools_c * const tools, + const bool is_RSNA_when_true, + const bool is_WPXM_when_true, + void * const header_begin, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT eapol_protocol_version_e get_eapol_protocol_version() const; + + EAP_FUNC_IMPORT eapol_packet_type_e get_eapol_packet_type() const; + + /// Function returns pcket body field of EAPOL packet. This field is two octets in length, + /// taken to represent an unsigned binary number. The value of this field defines the length + /// in octets of the Packet Body field. Value of 0 indicates that there is no Packet Body field present. + EAP_FUNC_IMPORT u16_t get_eapol_packet_body_length() const; + + /// This function returns whole length of the EAPOL packet. + /// This includes EAPOL header and packet body. + EAP_FUNC_IMPORT u16_t get_eapol_packet_length() const; + + EAP_FUNC_IMPORT eapol_key_descriptor_type_e get_key_descriptor_type() const; + + /// Gets the Key Information field. + EAP_FUNC_IMPORT u16_t get_key_information() const; + + /** + * This function returns the Key Descriptor Version bits of Key Information field. + */ + EAP_FUNC_IMPORT eapol_RSNA_key_header_c::key_descriptor_version_e get_key_information_key_descriptor_version() const; + + /** + * This function returns the Key Type bit of Key Information field. + */ + EAP_FUNC_IMPORT bool get_key_information_key_type() const; + + /** + * This function returns the Reserved A bits (higher ones) of Key Information field. + * This is RSNA specific. + */ + EAP_FUNC_IMPORT u8_t get_key_information_reserved_a() const; + + /** + * This function returns the key index bits (higher ones) of Key Information field. + * This is WPA specific. + */ + EAP_FUNC_IMPORT u8_t get_key_information_key_index() const; + + /** + * This function returns the Install bit of Key Information field. + */ + EAP_FUNC_IMPORT bool get_key_information_install() const; + + /** + * This function returns the Key Ack bit of Key Information field. + */ + EAP_FUNC_IMPORT bool get_key_information_key_ack() const; + + /** + * This function returns the Key MIC bit of Key Information field. + */ + EAP_FUNC_IMPORT bool get_key_information_key_MIC() const; + + /** + * This function returns the Secure bit of Key Information field. + */ + EAP_FUNC_IMPORT bool get_key_information_secure() const; + + /** + * This function returns the Error bit of Key Information field. + */ + EAP_FUNC_IMPORT bool get_key_information_error() const; + + /** + * This function returns the Request bit of Key Information field. + */ + EAP_FUNC_IMPORT bool get_key_information_request() const; + + /** + * This function returns the Encrypted Key Data bit of Key Information field. + */ + EAP_FUNC_IMPORT bool get_key_information_encrypted_key_data() const; + + + /** + * This function returns the Reserved B bits (lower ones) of Key Information field. + */ + EAP_FUNC_IMPORT u8_t get_key_information_reserved_b() const; + + /** + * This function returns the Key Length field of the EAPOL-Key descriptor. + */ + EAP_FUNC_IMPORT u16_t get_key_length() const; + + /** + * This function returns the Key Reply Counter field of the EAPOL-Key descriptor. + */ + EAP_FUNC_IMPORT u64_t get_key_replay_counter() const; + + EAP_FUNC_IMPORT u8_t * get_key_NONCE() const; + + EAP_FUNC_IMPORT u8_t * get_EAPOL_key_IV() const; + + EAP_FUNC_IMPORT u8_t * get_key_RSC() const; + + EAP_FUNC_IMPORT u8_t * get_key_STA_MAC_address() const; + + EAP_FUNC_IMPORT u8_t * get_key_reserved() const; + + EAP_FUNC_IMPORT u8_t * get_key_MIC() const; + + /** + * This function returns the Key Data Length field of the EAPOL-Key descriptor. + */ + EAP_FUNC_IMPORT u16_t get_key_data_length() const; + + EAP_FUNC_IMPORT u8_t * get_key_data(const u32_t key_length) const; + + EAP_FUNC_IMPORT u8_t * get_key_data_offset(const u32_t offset, const u32_t key_length) const; + + EAP_FUNC_IMPORT static u16_t get_header_length(); + + EAP_FUNC_IMPORT eap_status_e set_eapol_protocol_version(const eapol_protocol_version_e version); + + EAP_FUNC_IMPORT eap_status_e set_eapol_packet_type(const eapol_packet_type_e type); + + EAP_FUNC_IMPORT eap_status_e set_eapol_packet_body_length(const u32_t eapol_length); + + EAP_FUNC_IMPORT eap_status_e set_key_descriptor_type(const eapol_key_descriptor_type_e eapol_key_descriptor_type); + + /** + * This function sets the selected bits on. + */ + EAP_FUNC_IMPORT u16_t set_bits_on( + u16_t key_information, + const u16_t set_bits, + const u32_t mask, + const u32_t shift); + + /** + * This function sets the Key Descriptor Version bits of Key Information field. + */ + EAP_FUNC_IMPORT eap_status_e set_key_information_key_descriptor_version(const u8_t version); + + /** + * This function sets the Key Type bit of Key Information field. + */ + EAP_FUNC_IMPORT eap_status_e set_key_information_key_type(const bool key_type_bit_on_when_true); + + /** + * This function returns the key index bits (higher ones) of Key Information field. + * This is WPA specific. + */ + EAP_FUNC_IMPORT eap_status_e set_key_information_key_index(const u8_t key_index); + + /** + * This function sets the Install bit of Key Information field. + */ + EAP_FUNC_IMPORT eap_status_e set_key_information_install(const bool install_bit_on_when_true); + + /** + * This function sets the Key Ack bit of Key Information field. + */ + EAP_FUNC_IMPORT eap_status_e set_key_information_key_ack(const bool key_ack_bit_on_when_true); + + /** + * This function sets the Key MIC bit of Key Information field. + */ + EAP_FUNC_IMPORT eap_status_e set_key_information_key_MIC(const bool key_MIC_bit_on_when_true); + + /** + * This function sets the Secure bit of Key Information field. + */ + EAP_FUNC_IMPORT eap_status_e set_key_information_secure(const bool secure_bit_on_when_true); + + /** + * This function sets the Error bit of Key Information field. + */ + EAP_FUNC_IMPORT eap_status_e set_key_information_error(const bool error_bit_on_when_true); + + /** + * This function sets the Request bit of Key Information field. + */ + EAP_FUNC_IMPORT eap_status_e set_key_information_request(const bool request_bit_is_on_when_true); + + /** + * This function sets the Encrypted Key Data bit of Key Information field. + */ + EAP_FUNC_IMPORT eap_status_e set_key_information_encrypted_key_data(const bool encrypted_key_data_bit_is_on_when_true); + + /** + * This function sets the Key Length field of the EAPOL-Key descriptor. + */ + EAP_FUNC_IMPORT eap_status_e set_key_length(const u16_t length); + + /** + * This function sets the Key Reply Counter field of the EAPOL-Key descriptor. + */ + EAP_FUNC_IMPORT eap_status_e set_key_replay_counter(const u64_t reply_counter); + + /** + * This function sets the Key Data Length field of the EAPOL-Key descriptor. + */ + EAP_FUNC_IMPORT eap_status_e set_key_data_length(const u16_t key_data_length); + + /** + * This function zeroes the EAPOL header and EAPOL-Key descriptor header. + */ + EAP_FUNC_IMPORT eap_status_e zero_EAPOL_header_and_Key_descriptor( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT eap_status_e zero_key_MIC( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT eap_status_e zero_key_NONCE( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT eap_status_e zero_EAPOL_key_IV( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT eap_status_e zero_key_RSC( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT eap_status_e zero_key_STA_MAC_address( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT eap_status_e zero_key_reserved( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT eap_status_e check_header() const; + + EAP_FUNC_IMPORT eap_status_e reset_header( + const u8_t key_index, + const eapol_key_authentication_type_e authentication_type, + const eapol_RSNA_cipher_e eapol_pairwise_cipher, + const u64_t key_reply_counter, + const bool key_type_bit_on_when_true, + const bool install_bit_on_when_true, + const bool key_ack_bit_on_when_true, + const bool key_MIC_bit_on_when_true, + const bool secure_bit_on_when_true, + const bool error_bit_on_when_true, + const bool requst_bit_on_when_true, + const bool STAKey_bit_on_when_true, + const bool encrypted_key_data_bit_on_when_true, + const eapol_protocol_version_e received_eapol_version, + const eapol_key_descriptor_type_e received_key_descriptor_type); + + // + //-------------------------------------------------- +}; // class eapol_RC4_key_header_c + + +#endif //#if !defined(_EAPOL_KEY_H_) + +//------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_session_key.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_session_key.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_SESSION_KEY_H_) +#define _EAPOL_SESSION_KEY_H_ + +#include "eap_variable_data.h" +#include "eapol_key_types.h" +#include "eap_am_export.h" + + +/// A eapol_session_key_c class. +/// This is used for session key encapsulation. +class EAP_EXPORT eapol_session_key_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; ///< This is pointer to the tools class. @see abs_eap_am_tools_c. + + eap_variable_data_c m_key; ///< Here is the key. + + eap_variable_data_c m_sequence_number; ///< Here is the current sequence number for GTK. NOTE m_key_type should be GTK. + + eapol_key_type_e m_key_type; ///< This the type of the key. + + u32_t m_key_index; ///< This is the index of the key. + + bool m_key_tx_bit; ///< This is the TX bit of the key. + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eapol_session_key_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eapol_session_key_c(); + + /** + * The constructor of the eapol_session_key_c class does nothing special. + */ + EAP_FUNC_IMPORT eapol_session_key_c( + abs_eap_am_tools_c * const tools, + eap_variable_data_c * const key, ///< Here is the key. + const eapol_key_type_e key_type, ///< This the type of the key. + const u32_t key_index, ///< This is the index of the key. + const bool key_tx_bit, ///< This is the TX bit of the key. + const u8_t * const key_RSC, ///< This is the RSC counter + const u32_t key_RSC_size ///< This is the size of RSC counter + ); + + /** + * The constructor of the eapol_session_key_c class does nothing special. + */ + EAP_FUNC_IMPORT eapol_session_key_c( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT const eap_variable_data_c * get_key() const; + + EAP_FUNC_IMPORT const eap_variable_data_c * get_sequence_number() const; + + EAP_FUNC_IMPORT eapol_key_type_e get_key_type() const; + + EAP_FUNC_IMPORT u32_t get_key_index() const; + + EAP_FUNC_IMPORT bool get_key_tx_bit() const; + + EAP_FUNC_IMPORT bool get_is_valid() const; + + + EAP_FUNC_IMPORT eap_status_e set_key(const eap_variable_data_c * const key); + + EAP_FUNC_IMPORT eap_status_e set_sequence_number(eap_variable_data_c * const sequence_number); + + EAP_FUNC_IMPORT void set_key_type(const eapol_key_type_e key_type); + + EAP_FUNC_IMPORT void set_key_index(const u32_t key_index); + + EAP_FUNC_IMPORT void set_key_tx_bit(const bool key_tx_bit); + + EAP_FUNC_IMPORT static eap_const_string get_eapol_key_type_string( + const eapol_key_type_e key_type); + + //-------------------------------------------------- +}; // class eapol_session_key_c + +#endif //#if !defined(_EAPOL_SESSION_KEY_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_test_stack_if.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_test_stack_if.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_TEST_STACK_IF_H_) +#define _EAPOL_TEST_STACK_IF_H_ + +#include "eap_header.h" +#include "eap_array.h" + + +class EAP_EXPORT eapol_test_stack_if_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eapol_test_stack_if_c() + { + } + + // + eapol_test_stack_if_c() + { + } + + virtual eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) = 0; + + virtual u32_t get_wrong_send_packet_index() = 0; + + virtual void reset_authentication_can_succeed() = 0; + + virtual void set_authentication_can_succeed() = 0; + + virtual void restore_authentication_can_succeed() = 0; + + virtual void set_authentication_must_not_succeed( + const u32_t wrong_packet_index, + const u32_t packet_index, + const void * const wrong_packet_stack) = 0; + + //-------------------------------------------------- +}; // class eapol_test_stack_if_c + +#endif //#if !defined(_EAPOL_TEST_STACK_IF_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_wlan_authentication.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_wlan_authentication.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,397 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_WLAN_AUTHENTICATION_H_) +#define _EAPOL_WLAN_AUTHENTICATION_H_ + +// INCLUDES +#include "eapol_am_wlan_authentication.h" +#include "abs_eapol_am_wlan_authentication.h" +#include "abs_ethernet_core.h" +#include "abs_eapol_wlan_authentication.h" +#include "eapol_key_types.h" +#include "eap_type_selection.h" +#include "eap_array.h" +#include "eapol_key_state.h" +#include "eapol_test_stack_if.h" + +#if defined(USE_EAP_SIMPLE_CONFIG) +#include "abs_eap_configuration_if.h" +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +// FORWARD DECLARATIONS +class ethernet_core_c; +class eap_am_tools_symbian_c; +class eap_file_config_c; + + +// CLASS DECLARATION +class EAP_EXPORT eapol_wlan_authentication_c +: public abs_eapol_am_wlan_authentication_c +, public abs_ethernet_core_c +, public abs_eap_base_timer_c +#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) +, public eapol_test_stack_if_c +#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) +#if defined(USE_EAP_SIMPLE_CONFIG) +, public abs_eap_configuration_if_c +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) +{ +public: + + EAP_FUNC_IMPORT static eapol_wlan_authentication_c * new_eapol_wlan_authentication( + abs_eap_am_tools_c * const tools, + abs_eapol_wlan_authentication_c * const partner, + const bool is_client_when_true, + const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference); + + EAP_FUNC_IMPORT eapol_wlan_authentication_c( + abs_eap_am_tools_c * const tools, + abs_eapol_wlan_authentication_c * const partner, + eapol_am_wlan_authentication_c * const am_wauth, ///< eapol_wlan_authentication_c must always delete the am_wauth object. + const bool is_client_when_true); + +#if defined(EXPORT_DESTRUCTORS) + EAP_FUNC_IMPORT virtual ~eapol_wlan_authentication_c(); // For GCC compilation +#else + virtual ~eapol_wlan_authentication_c(); // For RVCT compilation +#endif + + + /////////////////////////////////////////////////////////////// + /* These are called from WLM */ + + /** + * This function checks whether PMKSA is cached to each eap_am_network_id_c object. + * Function removes eap_am_network_id_c object from bssid_sta_receive_network_ids if there are + * no cached PMKSA for removes eap_am_network_id_c object. + * All eap_am_network_id_c objects that exist in bssid_sta_receive_network_ids + * after function returns have PMKSA cached and read_reassociation_parameters() can be called + * with those eap_am_network_id_c objects. + */ + EAP_FUNC_IMPORT eap_status_e check_pmksa_cache( + eap_array_c * const bssid_sta_receive_network_ids, + const eapol_key_authentication_type_e selected_eapol_key_authentication_type, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite); + + EAP_FUNC_IMPORT eap_status_e start_authentication( + const eap_variable_data_c * const SSID, + const eapol_key_authentication_type_e selected_eapol_key_authentication_type, + const eap_variable_data_c * const wpa_preshared_key, + const bool WPA_override_enabled +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + , + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + ); + + EAP_FUNC_IMPORT eap_status_e complete_association( + const eapol_wlan_authentication_state_e association_result, + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + const eap_variable_data_c * const received_WPA_IE, // WLM must give only the WPA IE to EAPOL + const eap_variable_data_c * const sent_WPA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite + ); + + EAP_FUNC_IMPORT eap_status_e disassociation( + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ); + + EAP_FUNC_IMPORT eap_status_e start_preauthentication( + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ); + + EAP_FUNC_IMPORT eap_status_e start_reassociation( + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address. + const eapol_key_authentication_type_e selected_eapol_key_authentication_type ///< In WPXM this must be the same in old and new APs, other connections can change authentication type. + ); + + EAP_FUNC_IMPORT eap_status_e complete_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eap_variable_data_c * const received_WPA_IE, // WLM must give only the WPA IE to EAPOL + const eap_variable_data_c * const sent_WPA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite); + + EAP_FUNC_IMPORT eap_status_e start_WPXM_reassociation( + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address. + eap_variable_data_c * const send_reassociation_request_ie, + const eap_variable_data_c * const received_WPA_ie, + const eap_variable_data_c * const sent_WPA_ie); + + EAP_FUNC_IMPORT eap_status_e complete_WPXM_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eap_variable_data_c * const received_reassociation_ie); + + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + eap_general_header_base_c * const packet_data, + const u32_t packet_length + ); + + EAP_FUNC_IMPORT eap_status_e tkip_mic_failure( + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + const bool fatal_failure_when_true, + const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type + ); + + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ); + + ///////////////////////////////////////// + /* These are called from ethernet_core */ + + /** + * Sends packet to lower layers + */ + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, ///< source includes local address, destination includes remote address. + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + /** + * Loads an EAP type plug-in. + * @param type Type to be loaded. + * @param partner Pointer to the partner class for the EAP type. + * @param eap_type The pointer for the loaded type should be set here. + * @param is_client_when_true Indicates whether the loaded EAP type should be client or server. + * @param receive_network_id Network address. + */ + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ); + + EAP_FUNC_IMPORT eap_status_e unload_module(const eap_type_value_e type); + + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT void increment_authentication_counter(); + + EAP_FUNC_IMPORT u32_t get_authentication_counter(); + + EAP_FUNC_IMPORT bool get_is_client(); + + /** + * This does the initial configuration of the class. + */ + EAP_FUNC_IMPORT eap_status_e configure(); + + EAP_FUNC_IMPORT eap_status_e shutdown(); + + /** + * Reads a configuration parameter value from the database. + * In Symbian this function is only a TRAP wrapper for read_configure_L. + */ + EAP_FUNC_IMPORT eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // See abs_eap_base_type_c::state_notification(). + EAP_FUNC_IMPORT void state_notification(const abs_eap_state_notification_c * const state); + + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + /** + * Forwards the keys to lower layer (= WLM). + */ + EAP_FUNC_IMPORT eap_status_e packet_data_session_key( + const eap_am_network_id_c * const send_network_id, ///< source includes local address, destination includes remote address. + const eapol_session_key_c * const key); + + EAP_FUNC_IMPORT eap_status_e timer_expired(const u32_t id, void *data); + + EAP_FUNC_IMPORT eap_status_e timer_delete_data(const u32_t id, void *data); + + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + EAP_FUNC_IMPORT u32_t get_current_eap_index(); + + EAP_FUNC_IMPORT void set_current_eap_index(u32_t eap_index); + + +#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + /// These are called by testing application. + EAP_FUNC_IMPORT u32_t get_wrong_send_packet_index(); + + EAP_FUNC_IMPORT void reset_authentication_can_succeed(); + + EAP_FUNC_IMPORT void set_authentication_can_succeed(); + + EAP_FUNC_IMPORT void restore_authentication_can_succeed(); + + EAP_FUNC_IMPORT void set_authentication_must_not_succeed( + const u32_t wrong_packet_index, + const u32_t packet_index, + const void * const wrong_packet_stack); +#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION) + +#if defined(USE_EAP_SIMPLE_CONFIG) + EAP_FUNC_IMPORT eap_status_e save_simple_config_session( + const simple_config_state_e state, + EAP_TEMPLATE_CONST eap_array_c * const credential_array, + const eap_variable_data_c * const new_password, + const simple_config_Device_Password_ID_e Device_Password_ID, + const simple_config_payloads_c * const other_configuration); +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +private: + + EAP_FUNC_IMPORT eap_status_e eapol_indication( + const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address. + const eapol_wlan_authentication_state_e notification); + + EAP_FUNC_IMPORT eap_status_e create_upper_stack(); + + eap_status_e disassociation_mutex_must_be_reserved( + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ); + + eap_status_e cancel_all_authentication_sessions(); + +private: + + + eap_status_e cancel_timer_this_ap_failed(); + + eap_status_e cancel_timer_failed_completely(); + + eap_status_e cancel_timer_no_response(); + + eap_status_e cancel_timer_authentication_cancelled(); + + + + /// Pointer to the lower layer in the stack + abs_eapol_wlan_authentication_c * m_partner; + + /// Pointer to the AM of WAUTH. + eapol_am_wlan_authentication_c * m_am_wauth; + + /// Pointer to the upper layer in the stack + ethernet_core_c * m_ethernet_core; + + /// Pointer to the tools class + abs_eap_am_tools_c * m_am_tools; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_array_c m_selected_eap_types; + + eap_variable_data_c m_wpa_preshared_key_hash; + + eapol_key_authentication_type_e m_authentication_type; + + eapol_key_802_11_authentication_mode_e m_802_11_authentication_mode; + + eap_variable_data_c m_received_WPA_IE; // WLM must give only the WPA IE to EAPOL + + eap_variable_data_c m_sent_WPA_IE; + + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e m_group_key_cipher_suite; + + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e m_pairwise_key_cipher_suite; + + u32_t m_current_eap_index; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t m_authentication_counter; + + u32_t m_successful_authentications; + + u32_t m_failed_authentications; + + bool m_is_valid; + + bool m_is_client; + + bool m_shutdown_was_called; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_ERROR_TESTS) + bool m_randomly_drop_packets; + + u32_t m_randomly_drop_packets_probability; + + u32_t m_error_probability; + + u32_t m_generate_multiple_error_packets; + + u32_t m_packet_index; + + bool m_enable_random_errors; + + bool m_manipulate_ethernet_header; + + bool m_send_original_packet_first; +#endif //#if defined(USE_EAP_ERROR_TESTS) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + //-------------------------------------------------- +}; // class eapol_wlan_authentication_c + +#endif //#if !defined(_EAPOL_WLAN_AUTHENTICATION_H_) + +//-------------------------------------------------- + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_wlan_database_reference.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_wlan_database_reference.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_EAPOL_WLAN_DATABASE_REFERENCE_H_) +#define _EAPOL_WLAN_DATABASE_REFERENCE_H_ + +//-------------------------------------------------- + +#include "eap_am_export.h" +#include "eap_am_types.h" +#include "eap_status.h" + +class abs_eap_am_tools_c; + + +struct eapol_wlan_database_reference_values_s +{ + u32_t m_database_index_type; + + u32_t m_database_index; +}; + + + + +#endif //#if !defined(_EAPOL_WLAN_DATABASE_REFERENCE_H_) + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/eapol_wlan_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/eapol_wlan_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_WLAN_STATE_H_) +#define _EAPOL_WLAN_STATE_H_ + +#include "eap_type_selection.h" +#include "eap_array.h" +#include "eapol_key_state.h" + +//-------------------------------------------------- + +class abs_eap_am_tools_c; + + +/// wlan_state_c class stores information of one supported EAP-type. +class EAP_EXPORT eapol_wlan_state_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + bool m_is_valid; + + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eapol_wlan_state_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eapol_wlan_state_c(); + + /** + * The constructor of the eapol_wlan_state_c class does nothing special. + */ + EAP_FUNC_IMPORT eapol_wlan_state_c( + abs_eap_am_tools_c * const tools); + + /** + * The get_is_valid() function returns the status of the object. + * @return True indicates the object is initialized. + */ + EAP_FUNC_IMPORT bool get_is_valid() const; + +}; // class eapol_wlan_state_c + + +#endif //#if !defined(_EAPOL_WLAN_STATE_H_) + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/ethernet_core.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/ethernet_core.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,312 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ETHERNET_CORE_H_) +#define _ETHERNET_CORE_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_ethernet_core.h" +#include "abs_eapol_core.h" +#include "eapol_core.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_core_map.h" +#include "abs_eap_stack_interface.h" +#include "eapol_rsna_key_header.h" + + +/// This class defines the ethernet protocol layer. +class EAP_EXPORT ethernet_core_c +: public abs_eapol_core_c +, public abs_eap_stack_interface_c +{ +private: + //-------------------------------------------------- + + abs_ethernet_core_c *m_partner; + + eapol_core_c *m_eapol_core; + + abs_eap_am_tools_c * const m_am_tools; + + bool m_is_client; + + bool m_is_valid; + + bool m_shutdown_was_called; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~ethernet_core_c(); + + // + EAP_FUNC_IMPORT ethernet_core_c( + abs_eap_am_tools_c * const m_am_tools, + abs_ethernet_core_c * const partner, + const bool is_client_when_true); + + EAP_FUNC_IMPORT eap_status_e cancel_all_authentication_sessions(); + + // + EAP_FUNC_IMPORT eap_base_type_c * load_type(const eap_type_value_e type); + + // This is documented in abs_eap_stack_interface_c::packet_process(). + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length); + + // + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + // + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + // + EAP_FUNC_IMPORT eap_status_e eap_acknowledge(const eap_am_network_id_c * const receive_network_id); + + // + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + // + EAP_FUNC_IMPORT eap_status_e unload_module(const eap_type_value_e type); + + /** + * This function checks whether PMKSA is cached to each eap_am_network_id_c object. + * Function removes eap_am_network_id_c object from bssid_sta_receive_network_ids if there are + * no cached PMKSA for removes eap_am_network_id_c object. + * All eap_am_network_id_c objects that exist in bssid_sta_receive_network_ids + * after function returns have PMKSA cached and read_reassociation_parameters() can be called + * with those eap_am_network_id_c objects. + */ + EAP_FUNC_IMPORT eap_status_e check_pmksa_cache( + eap_array_c * const bssid_sta_receive_network_ids, + const eapol_key_authentication_type_e selected_eapol_key_authentication_type, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite); + + /** + * This function removes PMKSA from cache. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. + * MAC address of Supplicant should be in destination address. + */ + EAP_FUNC_IMPORT eap_status_e remove_pmksa_from_cache( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function starts the EAP-authentication. + * The first parameter includes the network addresses of the protocol + * over the EAP-packets are transmitted. + * The type attribute of the eap_am_network_id_c object MUST be set + * eapol_ethernet_type_e::eapol_ethernet_type_pae. + * Value eapol_ethernet_type_e::eapol_ethernet_type_pae starts normal EA-authentication. + * The second parameter is_client_when_true tells whether this stack + * is client (true) or server (false). + */ + EAP_FUNC_IMPORT eap_status_e start_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true); + + /** + * This function starts the preauthentication. + * The first parameter includes the network addresses of the protocol + * over the EAP-packets are transmitted. + * The type attribute of the eap_am_network_id_c object MUST be set + * eapol_ethernet_type_e::eapol_ethernet_type_preauthentication. + * Value eapol_ethernet_type_e::eapol_ethernet_type_preauthentication is used 802.11i preauthentication. + * The adaptation module calls the start_preauthentication() function + * when preauthentication is needed with another AP. + */ + EAP_FUNC_IMPORT eap_status_e start_preauthentication( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type); + + EAP_FUNC_IMPORT eap_status_e read_reassociation_parameters( + const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. + const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address. + const eapol_key_authentication_type_e authentication_type, + eap_variable_data_c * const PMKID, + const eap_variable_data_c * const received_WPA_ie, + const eap_variable_data_c * const sent_WPA_ie); + + EAP_FUNC_IMPORT eap_status_e start_reassociation( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const PMKID); + + EAP_FUNC_IMPORT eap_status_e complete_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const received_WPA_IE, // WLM must give only the WPA IE to EAPOL + const eap_variable_data_c * const sent_WPA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite); + + EAP_FUNC_IMPORT eap_status_e start_WPXM_reassociation( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + eap_variable_data_c * const send_reassociation_request_ie); + + EAP_FUNC_IMPORT eap_status_e complete_WPXM_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const received_reassociation_ie); + + EAP_FUNC_IMPORT eap_status_e send_logoff( + const eap_am_network_id_c * const receive_network_id); + + // This is documented in abs_eap_stack_interface_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + + // This is documented in abs_eap_stack_interface_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + // This is documented in abs_eap_stack_interface_c::configure(). + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is documented in abs_eap_stack_interface_c::shutdown(). + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT eap_status_e packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key); + + EAP_FUNC_IMPORT eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // See abs_eap_base_type_c::state_notification(). + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state); + + + // + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + // + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + // + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + // See abs_eap_core_c::get_eap_type_list(). + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + +#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + /** + * Function creates a state for later use. This is for optimazing 4-Way Handshake. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. MAC address of + * Supplicant should be in destination address. + * @param authentication_type is the selected authentication type. + */ + EAP_FUNC_IMPORT eap_status_e create_state( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type + ); +#endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + +#if defined(USE_EAPOL_KEY_STATE) + /** + * This function need to be called when client STA (re)associates to AP. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. MAC address of Supplicant should be in destination address. + * @param authenticator_RSNA_IE is RSN IE of authenticator. Authenticator sends this in Beacon or Probe message. + * @param supplicant_RSNA_IE is RSN IE of supplicant. Supplicant sends this in (re)association request message. + * @param eapol_pairwise_cipher is the selected pairwise cipher. + * @param eapol_group_cipher is the selected group cipher. + */ + EAP_FUNC_IMPORT eap_status_e association( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const authenticator_RSNA_IE, + const eap_variable_data_c * const supplicant_RSNA_IE, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, + const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher, + const eap_variable_data_c * const pre_shared_key); +#endif //#if defined(USE_EAPOL_KEY_STATE) + +#if defined(USE_EAPOL_KEY_STATE) + /** + * This function need to be called when client STA disassociates from AP. + * @param receive_network_id carries the MAC addresses. + * MAC address of Authenticator should be in source address. MAC address of Supplicant should be in destination address. + */ + EAP_FUNC_IMPORT eap_status_e disassociation( + const eap_am_network_id_c * const receive_network_id + ); +#endif //#if defined(USE_EAPOL_KEY_STATE) + + /// @see abs_eap_core_c::add_rogue_ap(). + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + EAP_FUNC_IMPORT eap_status_e tkip_mic_failure( + const eap_am_network_id_c * const receive_network_id, + const bool fatal_failure_when_true, + const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type); + + //-------------------------------------------------- +}; // class ethernet_core_c + +#endif //#if !defined(_ETHERNET_CORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/isakmp_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/isakmp_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,442 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ISAKMP_HEADER_H_) +#define _ISAKMP_HEADER_H_ + +#include "eap_am_memory.h" +#include "sae_cookie.h" + + +enum isakmp_version_value_e +{ + isakmp_version_none = 0, + isakmp_version_current = ((1 << 4) | (0)), +}; + +enum isakmp_exchange_type_value_e +{ + isakmp_exchange_type = 240, // This is in private area. +}; + +enum isakmp_payload_type_e +{ + isakmp_payload_NONE = 0, + isakmp_payload_sa = 1, + isakmp_payload_proposal = 2, + isakmp_payload_transform = 3, + isakmp_payload_key_exchange = 4, + isakmp_payload_identification = 5, + isakmp_payload_certificate = 6, + isakmp_payload_certificate_request = 7, + isakmp_payload_mac = 8, + isakmp_payload_signature = 9, + isakmp_payload_nonce = 10, + isakmp_payload_notification = 11, + isakmp_payload_delete = 12, + isakmp_payload_vendor_id = 13, + isakmp_payload_EAP = 103, // Found from draft-ietf-ipsra-pic-01.txt. + isakmp_payload_legacy_mac = 128, // NOTE this is in private area. +}; + + +enum isakmp_attribute_type_e +{ + isakmp_attribute_Encryption_Algorithm = 1, // B + isakmp_attribute_Hash_Algorithm = 2, // B + isakmp_attribute_Authentication_Method = 3, // B + isakmp_attribute_Group_Description = 4, // B + isakmp_attribute_Group_Type = 5, // B + isakmp_attribute_Group_Prime_Irreducible_Polynomial = 6, // V + isakmp_attribute_Group_Generator_One = 7, // V + isakmp_attribute_Group_Generator_Two = 8, // V + isakmp_attribute_Group_Curve_A = 9, // V + isakmp_attribute_Group_Curve_B = 10, // V + isakmp_attribute_Life_Type = 11, // B + isakmp_attribute_Life_Duration = 12, // V + isakmp_attribute_PRF = 13, // B + isakmp_attribute_Key_Length = 14, // B + isakmp_attribute_Field_Size = 15, // B + isakmp_attribute_Group_Order = 16, // V +}; + +const u32_t ISAKMP_COOKIE_LENGTH = 8u; + + +// +class isakmp_generic_payload_header_c +{ +private: + //-------------------------------------------------- + + u8_t m_next_payload; + u8_t m_reserved; + u16_t m_length; + // m_length-sizeof(isakmp_generic_payload_header_c) data octets follows isakmp_generic_payload_header_c. + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + ~isakmp_generic_payload_header_c() + { + } + + // + isakmp_generic_payload_header_c() + { + } + + const isakmp_payload_type_e get_next_payload() const + { + return (isakmp_payload_type_e)m_next_payload; + } + + const u8_t get_reserved() const + { + return m_reserved; + } + + u16_t get_data_length() const + { + if (eap_ntohs(m_length) > static_cast(sizeof(isakmp_generic_payload_header_c)) + return eap_ntohs(m_length)-(u16_t)sizeof(isakmp_generic_payload_header_c); + else + return 0; + } + + u16_t get_header_length() const + { + return sizeof(isakmp_generic_payload_header_c); + } + + u8_t * get_data(abs_eap_am_tools_c * const m_am_tools, const u32_t contignuous_bytes) const + { + if (get_data_length() >= contignuous_bytes + && contignuous_bytes > 0) + { + return reinterpret_cast(this+1); // Data begins after the header. + } + else + { + EAP_ASSERT_ALWAYS(get_data_length() > 0u); + } + return 0; + } + + isakmp_generic_payload_header_c * const get_next_header() const + { + return reinterpret_cast((reinterpret_cast(this+1))+get_data_length()); + } + + void set_next_payload(abs_eap_am_tools_c * const m_am_tools, const isakmp_payload_type_e p_next_payload) + { + EAP_ASSERT_ALWAYS(p_next_payload == (isakmp_payload_type_e)((u8_t)p_next_payload)); + m_next_payload = static_cast(p_next_payload; + } + + void set_reserved(const u8_t p_reserved) + { + m_reserved = p_reserved; + } + + void set_data_length(const u16_t p_data_length) + { + m_length = eap_htons(p_data_length+sizeof(isakmp_generic_payload_header_c)); + } + + void reset_header(abs_eap_am_tools_c * const m_am_tools, const u16_t buffer_length) + { + set_next_payload(m_am_tools, isakmp_payload_NONE); + set_reserved(0u); + set_data_length(buffer_length); + } + + // + //-------------------------------------------------- +}; // class isakmp_generic_payload_header_c + + + +// +class isakmp_attribute_header_c +{ +private: + //-------------------------------------------------- + + u16_t m_type; + u16_t m_value_or_length; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + ~isakmp_attribute_header_c() + { + } + + // + isakmp_attribute_header_c() + { + } + + const isakmp_attribute_type_e get_type() const + { + return (isakmp_attribute_type_e)(m_type && 0x7FFF); + } + + const u16_t get_value() const + { + return m_value_or_length; + } + + + bool is_type_fixed() const + { + if ((m_type & 0x8000) != 0) + { + return true; + } + return false; + } + + void set_type_fixed(const isakmp_attribute_type_e p_type) + { + m_type = p_type | 0x8000; + } + + void set_type_variable(const isakmp_attribute_type_e p_type) + { + m_type = p_type | 0x0000; + } + + void set_value_or_length(const u16_t p_value) + { + m_value_or_length = p_value; + } + + // + //-------------------------------------------------- +}; // class isakmp_attribute_header_c + + +const u8_t isakmp_flag_server = (1 << 3); +const u8_t isakmp_mask_server = (~(1 << 3)); + + +// +class isakmp_header_c +{ +private: + //-------------------------------------------------- + + sae_cookie_c m_source_cookie; // m_initiator. + sae_cookie_c m_destination_cookie; // m_responder. + u8_t m_next_payload; + u8_t m_version; + u8_t m_exchange_type; + u8_t m_flags; + u32_t m_sequence_number; //m_message_id. + u32_t m_length; + // m_length-sizeof(isakmp_header_c) data octets follows isakmp_header_c. + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + ~isakmp_header_c() + { + } + + // + isakmp_header_c() + { + } + + const isakmp_payload_type_e get_next_payload() const + { + return (isakmp_payload_type_e)m_next_payload; + } + + const isakmp_version_value_e get_version() const + { + return (const isakmp_version_value_e)m_version; + } + + const u8_t get_exchange_type() const + { + return m_exchange_type; + } + + const u8_t get_flags() const + { + return m_flags; + } + + const u32_t get_sequence_number() + { + return eap_ntohl(m_sequence_number); + } + + u32_t get_data_length() const + { + if (eap_ntohl(m_length) > (u32_t)sizeof(isakmp_header_c)) + return eap_ntohl(m_length)-(u32_t)sizeof(isakmp_header_c); + else + return 0; + } + + u32_t get_header_length() const + { + return sizeof(isakmp_header_c); + } + + sae_cookie_c *get_source_cookie() + { + return &m_source_cookie; + } + + sae_cookie_c *get_destination_cookie() + { + return &m_destination_cookie; + } + + u8_t * get_data_offset(abs_eap_am_tools_c * const m_am_tools, const u32_t offset, const u32_t contignuous_bytes) const + { + u32_t data_length = get_data_length(); + if (data_length >= offset+contignuous_bytes + && contignuous_bytes > 0u) + { + return ((reinterpret_cast(this+1))+offset); // Data begins after the header. + } + else + { + EAP_ASSERT_ALWAYS(get_data_length() > 0u); + } + return 0; + } + + + u8_t * get_data(abs_eap_am_tools_c * const m_am_tools, const u32_t contignuous_bytes) const + { + return get_data_offset(m_am_tools, 0u, contignuous_bytes); + } + + + void set_next_payload(const isakmp_payload_type_e p_next_payload) + { + m_next_payload = static_cast(p_next_payload; + } + + void set_version(const isakmp_version_value_e p_version) + { + m_version = static_cast(p_version; + } + + void set_exchange_type(const u8_t p_exchange_type) + { + m_exchange_type = p_exchange_type; + } + + void set_flags(const u8_t p_flags) + { + m_flags = p_flags; + } + + void set_sequence_number(const u32_t sequence_number) + { + m_sequence_number = eap_htonl(sequence_number); + } + + void set_data_length(const u32_t p_data_length) + { + m_length = eap_htonl(p_data_length+sizeof(isakmp_header_c)); + } + + void reset_header(const u32_t buffer_length, + const bool is_client_when_true) + { + set_next_payload(isakmp_payload_NONE); + set_version(isakmp_version_current); + set_exchange_type(isakmp_exchange_type); + if (is_client_when_true == true) + { + set_flags(0u); + } + else + { + set_flags(isakmp_flag_server); + } + set_sequence_number(0u); + set_data_length(buffer_length-sizeof(isakmp_header_c)); + get_source_cookie()->reset_cookie(); + get_destination_cookie()->reset_cookie(); + } + + eap_status_e check_header(const bool is_client_when_true) + { + if (get_version() != isakmp_version_current) + { + return eap_status_wrong_isakmp_header_version; + } + else if (get_exchange_type() != isakmp_exchange_type) + { + return eap_status_wrong_isakmp_exchange_type; + } + else if (is_client_when_true == false + && get_flags() != 0u) + { + return eap_status_wrong_isakmp_flags; + } + else if (is_client_when_true == true + && get_flags() != isakmp_flag_server) + { + return eap_status_wrong_isakmp_flags; + } + return eap_status_ok; + } + + // + //-------------------------------------------------- +}; // class isakmp_header_c + + +#endif //#if !defined(_ISAKMP_HEADER_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/isakmp_payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/isakmp_payloads.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,252 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ISAKMP_RESULT_H_) +#define _ISAKMP_RESULT_H_ + +#include "eap_variable_data.h" + +class isakmp_generic_payload_header_c; + + +class isakmp_fixed_data_c +{ +private: + //-------------------------------------------------- + + bool m_is_valid; + const isakmp_generic_payload_header_c * m_original_header; + u16_t m_type; + u16_t m_data; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~isakmp_fixed_data_c() + { + } + + // + isakmp_fixed_data_c() + : m_is_valid(false) + { + } + + bool get_is_valid() const + { + return m_is_valid; + } + + const isakmp_generic_payload_header_c * const get_original_header() + { + return m_original_header; + } + + const u16_t get_type(abs_eap_am_tools_c * const m_am_tools) const + { + if (m_is_valid == true) + { + return m_type; + } + else + { + EAP_ASSERT_ALWAYS(m_is_valid == true); + return 0u; + } + } + + const u16_t get_data(abs_eap_am_tools_c * const m_am_tools) const + { + if (m_is_valid == true) + { + return m_data; + } + else + { + EAP_ASSERT_ALWAYS(m_is_valid == true); + return 0u; + } + } + + void set_data(const isakmp_generic_payload_header_c * const original_header, + const u16_t type, const u16_t data) + { + m_is_valid = true; + m_original_header = original_header; + m_type = type & 0x7FFF; // Mask out the AF bit. + m_data = data; + } + + //-------------------------------------------------- +}; // class isakmp_fixed_data_c + + +class isakmp_variable_data_c +: public eap_variable_data_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + const isakmp_generic_payload_header_c * m_original_header; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~isakmp_variable_data_c() + { + } + + // + isakmp_variable_data_c(abs_eap_am_tools_c * const tools) + : eap_variable_data_c(tools) + , m_am_tools(tools) + , m_original_header(0) + { + } + + const isakmp_generic_payload_header_c * const get_original_header() + { + return m_original_header; + } + + void set_buffer(const isakmp_generic_payload_header_c * const original_header, + u8_t *buffer, const u32_t buffer_length, + const bool free_buffer, const bool is_writable) + { + m_original_header = original_header; + eap_variable_data_c::set_buffer(buffer, buffer_length, free_buffer, is_writable); + } + + //-------------------------------------------------- +}; // class isakmp_variable_data_c + + +//-------------------------------------------------- + + +// +class isakmp_payloads_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + const u32_t m_received_sequence_number; + + isakmp_fixed_data_c m_encryption_algorithm_offer; + + isakmp_variable_data_c m_dh_public_key; + + isakmp_variable_data_c m_nonce; + + isakmp_variable_data_c m_MAC; + + isakmp_variable_data_c m_L_MAC; + + isakmp_variable_data_c m_EAP_BLOB; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~isakmp_payloads_c() + { + } + + // + isakmp_payloads_c( + abs_eap_am_tools_c * const tools + , const u32_t received_sequence_number) + : m_am_tools(tools) + , m_received_sequence_number(received_sequence_number) + , m_dh_public_key(tools) + , m_nonce(tools) + , m_MAC(tools) + , m_L_MAC(tools) + , m_EAP_BLOB(tools) + { + } + + const u32_t get_received_sequence_number() + { + return m_received_sequence_number; + } + + isakmp_fixed_data_c * const get_encryption_algorithm_offer() + { + return reinterpret_cast(&m_encryption_algorithm_offer); + } + + isakmp_variable_data_c * const get_dh_public_key() + { + return reinterpret_cast(&m_dh_public_key); + } + + isakmp_variable_data_c * const get_NONCE() + { + return reinterpret_cast(&m_nonce); + } + + isakmp_variable_data_c * const get_MAC() + { + return reinterpret_cast(&m_MAC); + } + + isakmp_variable_data_c * const get_L_MAC() + { + return reinterpret_cast(&m_L_MAC); + } + + isakmp_variable_data_c * const get_EAP_BLOB() + { + return reinterpret_cast(&m_EAP_BLOB); + } + + //-------------------------------------------------- +}; // class isakmp_payloads_c + + +#endif //#if !defined(_ISAKMP_RESULT_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/sae_cookie.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/sae_cookie.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,100 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_SAE_COOKIE_H_) +#define _SAE_COOKIE_H_ + + +#include "eap_am_memory.h" + + +const u32_t SAE_COOKIE_LENGTH = 8u; + + +class sae_cookie_c +{ +private: + u8_t m_bytes[SAE_COOKIE_LENGTH]; +public: + + sae_cookie_c() + { + } + + ~sae_cookie_c() + { + } + + const u8_t * get_data() const + { + return reinterpret_cast(m_bytes); + } + + u32_t get_data_length() const + { + return sizeof(m_bytes); + } + + void set_bytes(abs_eap_am_tools_c * const m_am_tools, const u8_t * const p_bytes, const u32_t length) + { + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + EAP_ASSERT_ALWAYS(length == SAE_COOKIE_LENGTH); + + for (u32_t ind = 0u; ind < length; ind++) + { + m_bytes[ind] = p_bytes[ind]; + } + } + + void set_cookie(abs_eap_am_tools_c * const m_am_tools, const sae_cookie_c * const cookie) + { + set_bytes(m_am_tools, cookie->get_data(), cookie->get_data_length()); + } + + void reset_cookie() + { + for (u32_t ind = 0u; ind < SAE_COOKIE_LENGTH; ind++) + { + m_bytes[ind] = 0; + } + } + + sae_cookie_c * const copy(abs_eap_am_tools_c * const m_am_tools) const + { + sae_cookie_c * const new_cookie = new sae_cookie_c(); + if (new_cookie == 0) + { + return 0; + } + new_cookie->set_bytes(m_am_tools, get_data(), get_data_length()); + return new_cookie; + } +}; + + + +//-------------------------------------------------- + +#endif //#if !defined(_SAE_COOKIE_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/include/wlan_eap_if_send_status.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/include/wlan_eap_if_send_status.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_WLAN_EAP_IF_SEND_STATUS_H_) +#define _WLAN_EAP_IF_SEND_STATUS_H_ + +//-------------------------------------------------- + +#include "eap_am_export.h" +#include "eap_am_types.h" +#include "eap_status.h" + +/** @file */ + +/** + * This enumeration defines the return values of abs_eapol_message_wlan_authentication_c::send_data() function. + */ +enum wlan_eap_if_send_status_e +{ + wlan_eap_if_send_status_ok, + wlan_eap_if_send_status_pending_request, + wlan_eap_if_send_status_allocation_error, + wlan_eap_if_send_status_illegal_parameter, + wlan_eap_if_send_status_process_general_error, + wlan_eap_if_send_status_not_found, + wlan_eap_if_send_status_success, + wlan_eap_if_send_status_drop_packet_quietly, +}; + + +/// This class is converts the status values between wlan_eap_if_send_status_e and eap_status_e. +class EAP_EXPORT_INTERFACE wlan_eap_if_send_status_conversion_c +{ + +public: + + EAP_FUNC_IMPORT_INTERFACE static wlan_eap_if_send_status_e convert(const eap_status_e status); + + EAP_FUNC_IMPORT_INTERFACE static eap_status_e convert(const wlan_eap_if_send_status_e status); + +}; // class abs_eapol_message_wlan_authentication_c + + +#endif //#if !defined(_WLAN_EAP_IF_SEND_STATUS_H_) + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/core/aka_tools/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/core/aka_tools/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,20 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_aka_tools + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/type/aka/core/eap_type_aka_payloads.cpp \ + $(WLAN_COMMON)/type/aka/core/eap_type_aka_authentication_vector.cpp \ + $(WLAN_COMMON)/type/aka/core/eap_type_aka_header.cpp \ + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_testing_tools.$(LIB) \ + -lstdc++ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,7167 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 67 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_type_aka.h" +#include "eap_type_aka_header.h" +#include "eap_type_aka_payloads.h" +#include "abs_eap_am_type_aka.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" +#include "abs_eap_am_mutex.h" +#include "eap_automatic_variable.h" +#include "eap_sort.h" +#include "eap_buffer.h" +#include "eap_config.h" + + +//-------------------------------------------------- + +/** @file */ + +// +EAP_FUNC_EXPORT eap_type_aka_c::~eap_type_aka_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::~eap_type_aka_c(): this = 0x%08x => 0x%08x\n"), + this, + dynamic_cast(this))); + + EAP_ASSERT(m_shutdown_was_called == true); + + if (m_free_am_type_aka == true + && m_am_type_aka != 0) + { + delete m_am_type_aka; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +// +EAP_FUNC_EXPORT eap_type_aka_c::eap_type_aka_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + eap_am_type_aka_c * const am_type_aka, + const bool free_am_type_aka, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) + : eap_base_type_c(tools, partner) + , m_am_tools(tools) + , m_am_type_aka(am_type_aka) + , m_checkcode(tools) + , m_checkcode_update_count(0UL) + , m_received_checkcode(tools) + , m_checkcode_saved_message(tools) + , m_all_payloads(tools) + , m_nonce_mt_file(tools) + , m_manual_username(tools) + , m_manual_realm(tools) + , m_automatic_realm(tools) + , m_automatic_realm_read(false) + , m_aka_header_offset(0u) + , m_MTU(0u) + , m_trailer_length(0u) + , m_length_of_mnc(EAP_TYPE_AKA_DEFAULT_MNC_LENGTH_3_BYTES) + , m_authentication_type(AKA_AUTHENTICATION_TYPE_NONE) + , m_identity_type(AKA_IDENTITY_TYPE_NONE) + , m_client_error_code(eap_aka_client_error_code_none) + , m_aka_notification_code(eap_aka_notification_none) + , m_failure_message_delay_time(EAP_TYPE_AKA_TIMER_TIMEOUT_VALUE_DELAY_FAILURE_MESSAGE_SENT) + , m_is_valid(false) + , m_is_client(is_client_when_true) + , m_wait_eap_success_packet(true) + , m_check_identifier_of_eap_identity_response(false) + , m_free_am_type_aka(free_am_type_aka) + , m_client_responds_retransmitted_packets(false) + , m_aka_test_version(false) + , m_aka_randomly_refuse_eap_identity(false) + , m_check_nai_realm(false) + , m_fail_reauthentication_counter_check(false) + , m_accept_eap_identity_response(true) + , m_use_random_identity_on_eap_identity_response(false) + , m_shutdown_was_called(false) + , m_reset_was_called(false) + , m_use_pseudonym_identity(true) + , m_use_reauthentication_identity(true) + , m_erroneus_packet_received(false) + , m_aka_notification_packet_received(false) + , m_use_manual_username(false) + , m_use_manual_realm(false) + , m_randomly_fail_successfull_authentication(false) + , m_allow_use_result_indication(true) + , m_use_result_indication(false) + , m_state(eap_type_aka_state_none) + , m_saved_previous_state(eap_type_aka_state_none) + , m_send_network_id(tools) + , m_nonce_s(tools) + , m_IV(tools) + , m_saved_EAP_packet(tools) + , m_XKEY(tools) + , m_K_encr(tools) + , m_K_aut(tools) + , m_master_session_key(tools, eap_type_aka) + , m_IMSI(tools) + , m_pseudonym(tools) + , m_reauthentication_identity(tools) + , m_identity(tools) + , m_NAI(tools) + , m_RAND(tools) + , m_AUTN(tools) + , m_RES(tools) + , m_2_digit_mnc_map_of_mcc_of_imsi_array(tools) + , m_uma_automatic_realm_prefix(tools) + , m_use_uma_profile(false) + , m_authentication_vector(0) + , m_reauthentication_counter(0u) + , m_include_identity_to_aka_identity_response(aka_payload_NONE) + , m_aka_identity_response_includes_identity(aka_payload_NONE) + , m_failure_message_received(false) + , m_authentication_finished_successfully(false) + , m_last_eap_identifier(0) + , m_use_eap_expanded_type(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::eap_type_aka_c(): this = 0x%08x => 0x%08x, ") + EAPL("partner 0x%08x, type partner 0x%08x, compiled %s %s\n"), + this, + dynamic_cast(this), + partner, + get_type_partner(), + __DATE__, + __TIME__)); + + if (m_am_type_aka == 0) + { + // Something wrong with AM. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + m_am_type_aka->set_am_partner(this); + + if (m_checkcode.get_is_valid() == false + || m_received_checkcode.get_is_valid() == false + || m_checkcode_saved_message.get_is_valid() == false + || m_nonce_mt_file.get_is_valid() == false + || m_manual_username.get_is_valid() == false + || m_manual_realm.get_is_valid() == false + || m_send_network_id.get_is_valid() == false + || m_nonce_s.get_is_valid() == false + || m_IV.get_is_valid() == false + || m_saved_EAP_packet.get_is_valid() == false + || m_XKEY.get_is_valid() == false + || m_K_encr.get_is_valid() == false + || m_K_aut.get_is_valid() == false + || m_master_session_key.get_is_valid() == false + || m_IMSI.get_is_valid() == false + || m_pseudonym.get_is_valid() == false + || m_reauthentication_identity.get_is_valid() == false + || m_identity.get_is_valid() == false + || m_NAI.get_is_valid() == false + || m_RAND.get_is_valid() == false + || m_AUTN.get_is_valid() == false + || m_RES.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + eap_status_e status = checkcode_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + initialize_state(eap_type_aka_state_pending_kc_sres_query, false, false, + aka_subtype_Notification, + aka_subtype_Challenge, // Re-transmitted EAP-Request/AKA/Challenge is allowed. + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_pending_authentication_vector_query, false, false, + aka_subtype_Notification, + aka_subtype_Identity, // Note EAP-Response/AKA/Identity message is allowed here, eap_type_aka_c::handle_aka_identity_response_message() will drop EAP-Response/AKA/Identity message quietly. + aka_subtype_Client_Error, + aka_subtype_Challenge, // Re-transmitted EAP-Response/AKA/Challenge is allowed. + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_aka_identity_request, false, false, + aka_subtype_Notification, + aka_subtype_Identity, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_pseydonym_waiting_for_aka_identity_request, false, false, + aka_subtype_Notification, + aka_subtype_Identity, + aka_subtype_Re_authentication, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_imsi_waiting_for_aka_identity_request, false, false, + aka_subtype_Notification, + aka_subtype_Identity, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_aka_identity_response, true, false, + aka_subtype_Notification, + aka_subtype_Identity, + aka_subtype_Client_Error, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_notification_request_success, false, true, + aka_subtype_Notification, + aka_subtype_Challenge, + aka_subtype_Re_authentication, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_notification_response_failure, true, false, + aka_subtype_Notification, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_notification_response_success, true, false, + aka_subtype_Notification, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity, true, false, + aka_subtype_Notification, + aka_subtype_Identity, + aka_subtype_Client_Error, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_aka_identity_response_with_at_full_auth_identity, true, false, + aka_subtype_Notification, + aka_subtype_Identity, + aka_subtype_Client_Error, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity, true, false, + aka_subtype_Notification, + aka_subtype_Identity, + aka_subtype_Client_Error, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_analyse_aka_identity_request, false, false, + aka_subtype_Notification, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_challenge_request, false, false, + aka_subtype_Notification, + aka_subtype_Challenge, + aka_subtype_Identity, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_challenge_response, false, false, + aka_subtype_Notification, + aka_subtype_Challenge, + aka_subtype_Identity, + aka_subtype_Client_Error, + aka_subtype_Synchronization_Failure); + + initialize_state(eap_type_aka_state_waiting_for_reauth_request, false, false, + aka_subtype_Notification, + aka_subtype_Re_authentication, + aka_subtype_Identity, + aka_subtype_Challenge, // This is allowed because, server could start full authentication. + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_reauth_response, false, false, + aka_subtype_Notification, + aka_subtype_Re_authentication, + aka_subtype_Identity, + aka_subtype_Client_Error, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_success, false, false, + aka_subtype_Notification, + aka_subtype_Challenge, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_waiting_for_success, false, false, + aka_subtype_Notification, + aka_subtype_Challenge, + aka_subtype_Re_authentication, + aka_subtype_NONE, + aka_subtype_NONE); + + initialize_state(eap_type_aka_state_failure, false, false, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE, + aka_subtype_NONE); + + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + status = m_send_network_id.set_copy_of_network_id(&send_network_id); + + if (status != eap_status_ok + || m_send_network_id.get_is_valid_data() == false) + { + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//----------------------------------------------- + +// +void eap_type_aka_c::initialize_state( + const eap_type_aka_state_variable_e state, + const bool must_be_initiator, + const bool must_be_responder, + const aka_subtype_e type0, + const aka_subtype_e type1, + const aka_subtype_e type2, + const aka_subtype_e type3, + const aka_subtype_e type4) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_parameters[(state)].init_state(must_be_initiator, must_be_responder, + type0, type1, type2, type3, type4); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_aka_c::random_selection() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + crypto_random_c rand(m_am_tools); + + if (rand.get_is_valid() == false) + { + return false; + } + + return (rand.get_rand_integer(0, 1) != 0); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::checkcode_init() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_checkcode_update_count = 0UL; + + m_received_checkcode.reset(); + + m_checkcode_saved_message.reset(); + + m_all_payloads.reset(); + + eap_status_e status = m_checkcode.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_aka_c::compare_payload_first_is_less( + const aka_payload_AT_type_e * const first, + const aka_payload_AT_type_e * const second, + abs_eap_am_tools_c * const /* m_am_tools */) +{ + return *first < *second; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::checkcode_verify_payloads( + aka_payloads_c * const p_aka_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (p_aka_payloads != 0 + && p_aka_payloads->get_all_payloads()->get_is_valid_data() == true) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" CHECKCODE plain payload array"), + p_aka_payloads->get_all_payloads()->get_data(p_aka_payloads->get_all_payloads()->get_data_length()), + p_aka_payloads->get_all_payloads()->get_data_length())); + + // This will sort the payload array of type aka_payload_AT_type_e in increasing order. + // Comparing this payload array to previous payload arrays is then easy task. + eap_status_e status = eap_sort_array( + reinterpret_cast( + p_aka_payloads->get_all_payloads()->get_data( + p_aka_payloads->get_all_payloads()->get_data_length())), + p_aka_payloads->get_all_payloads()->get_data_length()/sizeof(aka_payload_AT_type_e), + compare_payload_first_is_less, + m_am_tools); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CHECKCODE sorted payload array"), + p_aka_payloads->get_all_payloads()->get_data(p_aka_payloads->get_all_payloads()->get_data_length()), + p_aka_payloads->get_all_payloads()->get_data_length())); + + for (u32_t ind = 0ul; ind < m_all_payloads.get_object_count(); ind++) + { + eap_variable_data_c * const payloads = m_all_payloads.get_object(ind); + if (payloads != 0) + { + if (payloads->compare(p_aka_payloads->get_all_payloads()) == 0) + { + // Message with these payloads have been seen already. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("WARNING: message with these payloads have been seen already.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_already_exists); + } + } + } + + // Save this payload array. + eap_variable_data_c * copy_attributes = p_aka_payloads->get_all_payloads()->copy(); + if (copy_attributes == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_all_payloads.add_object(copy_attributes, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::checkcode_save_message_client( + const void * const data, + const u32_t data_length, + aka_payloads_c * const p_aka_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (p_aka_payloads != 0) + { + // Client received a message. + + status = checkcode_verify_payloads(p_aka_payloads); + if (status == eap_status_ok) + { + // This is a new received message with new payloads. + status = checkcode_update_saved_message(); + + } + else + { + // Received message is duplicate. + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CHECKCODE saved data client"), + data, + data_length)); + + status = m_checkcode_saved_message.set_copy_of_buffer( + data, + data_length); + } + else + { + // Client sends a response message. + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CHECKCODE saved data client"), + data, + data_length)); + + status = m_checkcode_saved_message.add_data( + data, + data_length); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::checkcode_save_message_server( + const void * const data, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CHECKCODE saved data server"), + data, + data_length)); + + eap_status_e status = m_checkcode_saved_message.set_copy_of_buffer( + data, + data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::checkcode_update_saved_message() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; + + if (m_checkcode_saved_message.get_is_valid_data() == true + && m_checkcode_saved_message.get_data_length() > 0UL) + { + status = checkcode_update( + m_checkcode_saved_message.get_data(m_checkcode_saved_message.get_data_length()), + m_checkcode_saved_message.get_data_length()); + + m_checkcode_saved_message.reset(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::checkcode_update( + const void * const data, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CHECKCODE data"), + data, + data_length)); + + ++m_checkcode_update_count; + + eap_status_e status = m_checkcode.hash_update( + data, + data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::checkcode_final( + eap_variable_data_c * const digest) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = checkcode_update_saved_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t digest_length = m_checkcode.get_digest_length(); + + status = digest->init(digest_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + digest->set_is_valid(); + digest->set_data_length(digest_length); + + if (m_checkcode_update_count == 0UL) + { + // No AKA-Identity messages were sent. + digest->set_data_length(0UL); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + // Create a copy of crypto_sha1_c object. + // This will save the HASH for later use. + abs_crypto_hash_algorithm_c * const copy_checkcode = m_checkcode.copy(); + eap_automatic_variable_c automatic_copy_checkcode(m_am_tools, copy_checkcode); + + if (copy_checkcode == 0 + || copy_checkcode->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = copy_checkcode->hash_final( + digest->get_data(digest_length), + &digest_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::checkcode_verify( + const eap_variable_data_c * const received_digest) +{ + // Verify AT_CHECKCODE. + eap_variable_data_c checkcode_digest(m_am_tools); + + if (checkcode_digest.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = checkcode_final( + &checkcode_digest); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if ((m_checkcode_update_count != 0 && received_digest->get_data_length() == 0) + || (m_checkcode_update_count == 0 && received_digest->get_data_length() != 0) + || checkcode_digest.compare(received_digest) != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_AKA: %s, eap_type_aka_c::checkcode_verify(): CHECKCODE failed, m_checkcode_update_count %d, state %s\n"), + (m_is_client == true) ? "client": "server", + m_checkcode_update_count, + get_state_string())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" local digest"), + checkcode_digest.get_data(checkcode_digest.get_data_length()), + checkcode_digest.get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("received digest"), + received_digest->get_data(received_digest->get_data_length()), + received_digest->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, eap_type_aka_c::checkcode_verify(): CHECKCODE OK, state %s\n"), + (m_is_client == true) ? "client": "server", + get_state_string())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_final_notification() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_is_valid == true) + { + if (get_authentication_finished_successfully() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_AKA: %s, authentication FAILED, state %s\n"), + (m_is_client == true) ? "client": "server", + get_state_string())); + + if (m_aka_notification_code != eap_aka_notification_none) + { + // We have received EAP-Request/AKA notification, we pass the received code to the adaptation module. + (void) m_am_type_aka->handle_aka_notification(m_aka_notification_code); + } + + set_state(eap_type_aka_state_failure); + + // Notifies the lower level of unsuccessfull authentication. + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_type_aka, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + get_last_eap_identifier(), + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + state_notification(¬ification); + + // Indicate AKA AM authentication finish. + m_am_type_aka->authentication_finished(false, m_authentication_type, m_identity_type); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::add_variable_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_variable_data_c * const data_payload, + const aka_payload_AT_type_e data_payload_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + u16_t data_length = 0u; + + if (data_payload != 0) + { + if (data_payload->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + + if (data_payload->get_data_length() > aka_payload_AT_header_c::get_max_payload_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + data_length = static_cast(data_payload->get_data_length()); + } + else + { + // No data. + data_length = 0u; + } + + aka_payload_AT_header_c gp_data( + m_am_tools, + aka->get_data_offset(*aka_data_offset, *aka_data_free), + *aka_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + gp_data.reset_header(data_length); + + if (data_length > 0u) + { + u8_t *payload_buffer = gp_data.get_data(data_length); + + if (payload_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + payload_buffer, + data_payload->get_data(data_payload->get_data_length()), + data_payload->get_data_length()); + } + + gp_data.set_data_length(data_length); + + status = eap_status_ok; + + + gp_data.set_current_payload(data_payload_type); + + update_payload_indexes( + aka_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + aka_data_offset, + aka_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::add_RES_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_variable_data_c * const RES, + const aka_payload_AT_type_e data_payload_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + u16_t data_length = 0u; + + if (RES != 0) + { + if (RES->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + + if (RES->get_data_length() > aka_payload_AT_header_c::get_max_payload_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + data_length = static_cast(RES->get_data_length()); + } + else + { + // No data. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u16_t padding_zero_count = 0u; + // Add padding zero octets + if ((data_length % 4u) != 0) + { + padding_zero_count = 4u - (data_length % 4u); + } + + if (RES->get_data_length()+padding_zero_count + > aka_payload_AT_header_c::get_max_payload_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (RES->get_data_length()+padding_zero_count > *packet_buffer_free) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + aka_payload_AT_header_c gp_data( + m_am_tools, + aka->get_data_offset(*aka_data_offset, *aka_data_free), + *aka_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + gp_data.reset_header(data_length+padding_zero_count); + + { + u8_t *payload_buffer = gp_data.get_data(data_length+padding_zero_count); + + if (payload_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + payload_buffer, + RES->get_data(data_length), + data_length); + + if (padding_zero_count > 0u) + { + m_am_tools->memset( + payload_buffer+data_length, + 0, + padding_zero_count); + } + } + + // Note the reserved field includes the actual length of RES in bits in network order. + // It is always multiple of 8 bits. + gp_data.set_reserved(static_cast(data_length*8ul)); + + gp_data.set_data_length(data_length+padding_zero_count); + + status = eap_status_ok; + + + gp_data.set_current_payload(data_payload_type); + + update_payload_indexes( + aka_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + aka_data_offset, + aka_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::add_AUTS_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_variable_data_c * const AUTS, + const aka_payload_AT_type_e data_payload_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + u16_t data_length = 0u; + + if (AUTS != 0) + { + if (AUTS->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + + if (AUTS->get_data_length() > aka_payload_AT_header_c::get_max_payload_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (AUTS->get_data_length() >= 2ul) + { + // NOTE first 2 bytes are in reserved field. + data_length = static_cast(AUTS->get_data_length() - 2ul); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + } + else + { + // No data. + data_length = 0u; + } + + aka_payload_AT_header_c gp_data( + m_am_tools, + aka->get_data_offset(*aka_data_offset, *aka_data_free), + *aka_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + gp_data.reset_header(data_length); + + if (data_length > 0u) + { + u8_t *payload_buffer = gp_data.get_reserved_pointer(AUTS->get_data_length()); + + if (payload_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // The first 2 bytes are in reserved field. + m_am_tools->memmove( + payload_buffer, + AUTS->get_data(AUTS->get_data_length()), + AUTS->get_data_length()); + } + + gp_data.set_data_length(data_length); + + status = eap_status_ok; + + + gp_data.set_current_payload(data_payload_type); + + update_payload_indexes( + aka_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + aka_data_offset, + aka_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// Note the specification of IMSI payload is not same as pseudonym. +// IMSI and pseudonym specifications should be integrated. +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::add_pseudonym_or_imsi_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_variable_data_c * const pseudonym_or_imsi, + const aka_payload_AT_type_e data_payload_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (pseudonym_or_imsi->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + + u32_t padding_zero_count = 0u; + // Add padding zero octets + if ((pseudonym_or_imsi->get_data_length() % 4u) != 0) + { + padding_zero_count = 4u - (pseudonym_or_imsi->get_data_length() % 4u); + } + + if (pseudonym_or_imsi->get_data_length()+padding_zero_count + > aka_payload_AT_header_c::get_max_payload_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (pseudonym_or_imsi->get_data_length()+padding_zero_count > *packet_buffer_free) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + aka_payload_AT_header_c gp_data( + m_am_tools, + aka->get_data_offset( + *aka_data_offset, + *aka_data_free), + *aka_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + gp_data.reset_header(static_cast(pseudonym_or_imsi->get_data_length()+padding_zero_count)); + + u8_t *payload_buffer = gp_data.get_data(pseudonym_or_imsi->get_data_length()+padding_zero_count); + + if (payload_buffer == 0 + || pseudonym_or_imsi->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_am_tools->memmove( + payload_buffer, + pseudonym_or_imsi->get_data(pseudonym_or_imsi->get_data_length()), + pseudonym_or_imsi->get_data_length()); + + if (padding_zero_count > 0u) + { + m_am_tools->memset( + payload_buffer+(pseudonym_or_imsi->get_data_length()), + 0, + padding_zero_count); + } + + // Note the reserved field includes the actual length of pseudonym in network order. + // This must be less or equal to the length field. + gp_data.set_reserved(static_cast(pseudonym_or_imsi->get_data_length())); + + gp_data.set_data_length(static_cast(pseudonym_or_imsi->get_data_length()+padding_zero_count)); + + status = eap_status_ok; + + gp_data.set_current_payload(data_payload_type); + + update_payload_indexes( + aka_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + aka_data_offset, + aka_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::add_notification_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_aka_notification_codes_e notification_code) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + aka_payload_AT_header_c gp_data( + m_am_tools, + aka->get_data_offset( + *aka_data_offset, + *aka_data_free), + *aka_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gp_data.reset_header(0u); + + // Note the reserved field includes the notificatio code in network order. + gp_data.set_reserved(static_cast(notification_code)); + + gp_data.set_data_length(0u); + + status = eap_status_ok; + + gp_data.set_current_payload(aka_payload_AT_NOTIFICATION); + + update_payload_indexes( + aka_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + aka_data_offset, + aka_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::add_client_error_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_aka_client_error_code_e client_error_code) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + aka_payload_AT_header_c gp_data( + m_am_tools, + aka->get_data_offset( + *aka_data_offset, + *aka_data_free), + *aka_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gp_data.reset_header(0u); + + // Note the reserved field includes the client error code in network order. + // This must be less or equal to the length field. + gp_data.set_reserved(static_cast(client_error_code)); + + gp_data.set_data_length(0u); + + status = eap_status_ok; + + gp_data.set_current_payload(aka_payload_AT_CLIENT_ERROR_CODE); + + update_payload_indexes( + aka_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + aka_data_offset, + aka_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::add_counter_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + u16_t counter) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + aka_payload_AT_header_c gp_data( + m_am_tools, + aka->get_data_offset( + *aka_data_offset, + *aka_data_free), + *aka_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gp_data.reset_header(0u); + + // Note the reserved field includes the counter value in network order. + gp_data.set_reserved(counter); + + gp_data.set_data_length(0u); + + status = eap_status_ok; + + gp_data.set_current_payload(aka_payload_AT_COUNTER); + + update_payload_indexes( + aka_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + aka_data_offset, + aka_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::add_simple_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const aka_payload_AT_type_e data_payload_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + aka_payload_AT_header_c gp_data( + m_am_tools, + aka->get_data_offset( + *aka_data_offset, + *aka_data_free), + *aka_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gp_data.reset_header(0u); + + gp_data.set_reserved(0u); + + gp_data.set_data_length(0u); + + status = eap_status_ok; + + gp_data.set_current_payload(data_payload_type); + + update_payload_indexes( + aka_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + aka_data_offset, + aka_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::parse_generic_payload( + const aka_payload_AT_type_e current_payload, + const aka_payload_AT_header_c * const payload, + aka_payloads_c * const p_aka_payloads, + const aka_subtype_e /*subtype*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_AKA_TRACE_PAYLOAD("Parsing payload", payload); + + if ((payload->get_payload_length() % static_cast(AKA_PAYLOAD_LENGTH_ALIGN)) != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x not aligned to 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), + payload->get_payload_length(), AKA_PAYLOAD_LENGTH_ALIGN)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_status_e status(eap_status_process_general_error); + + + status = p_aka_payloads->get_all_payloads()->add_data( + ¤t_payload, + sizeof(current_payload)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (current_payload == aka_payload_AT_NONCE_S) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_NONCE_S | Length = 5 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | NONCE_S | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_reserved() != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() != EAP_TYPE_AKA_NONCE_MT_SIZE) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(EAP_TYPE_AKA_NONCE_MT_SIZE)); + + if (buffer == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + status = p_aka_payloads->get_NONCE_S()->set_buffer( + payload, buffer, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_RAND) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_RAND | Length | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | RAND ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_reserved() != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() < EAP_TYPE_AKA_MINIMUM_RAND_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x. Too few RAND bytes 0x%04x, 0x%04x bytes required.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_data_length(), + EAP_TYPE_AKA_MINIMUM_RAND_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_enough_challenges); + } + + u8_t * n_rands = static_cast(payload->get_data(payload->get_data_length())); + if (n_rands == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_aka_payloads->get_RAND()->set_buffer( + payload, n_rands, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_AUTN) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_AUTN | Length | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AUTN ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_reserved() != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() < EAP_TYPE_AKA_MINIMUM_AUTN_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x. Too few AUTN bytes 0x%04x, 0x%04x bytes required.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_data_length(), + EAP_TYPE_AKA_MINIMUM_AUTN_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_enough_challenges); + } + + u8_t * AUTN = static_cast(payload->get_data(payload->get_data_length())); + if (AUTN == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_aka_payloads->get_AUTN()->set_buffer( + payload, AUTN, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_AUTS) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_AUTS | Length | AUTS ... | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | ... AUTS ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // NOTE first 2 bytes are in reserved field. + if (payload->get_data_length()+2ul != EAP_TYPE_AKA_AUTS_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x. Too few AUTN bytes 0x%04x, 0x%04x bytes required.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_data_length(), + EAP_TYPE_AKA_MINIMUM_AUTN_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_enough_challenges); + } + + u8_t * AUTS = static_cast(payload->get_reserved_pointer(payload->get_data_length())); + if (AUTS == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // NOTE first 2 bytes are in reserved field. + status = p_aka_payloads->get_AUTS()->set_buffer( + payload, AUTS, payload->get_data_length()+2ul, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_RES) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_RES | Length | RES Length in bits | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | RES ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // Reserved field includes the length of RES in bits. It is always multiple of 8 bits. + u32_t RES_length = payload->get_reserved() / 8ul; + + if (RES_length == 0u + || RES_length > payload->get_data_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() < EAP_TYPE_AKA_MINIMUM_RES_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x. Too few RES bytes 0x%04x, 0x%04x bytes required.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_data_length(), + EAP_TYPE_AKA_MINIMUM_RES_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_enough_challenges); + } + + u8_t * RES = static_cast(payload->get_data(RES_length)); + if (RES == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_aka_payloads->get_RES()->set_buffer( + payload, RES, RES_length, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_PADDING) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_PADDING | Length | Padding... | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + u8_t * padding = 0; + + // Note two first octets of padding are the reserved field. It must be zero. + if (payload->get_reserved() != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // NOTE padding data length could be zero. + if (payload->get_data_length() != 0u) + { + padding = static_cast(payload->get_data(payload->get_data_length())); + } + + status = p_aka_payloads->get_padding_payload()->set_buffer( + payload, padding, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_NEXT_PSEUDONYM) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_NEXT...YM | Length | Actual Pseudonym Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | Pseudonym | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // Note the reserved field includes the actual length of pseudonym. + // This must be less or equal to the length field. + u16_t pseudonym_length = payload->get_reserved(); + if (pseudonym_length == 0u + || pseudonym_length > payload->get_data_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, pseudonym length field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * pseudonym = static_cast(payload->get_data(pseudonym_length)); + if (pseudonym == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_aka_payloads->get_NEXT_PSEUDONYM()->set_buffer( + payload, pseudonym, pseudonym_length, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_NEXT_REAUTH_ID) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_NEXT...ID | Length | Actual Identity Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | Reauthentication identity | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // Note the reserved field includes the actual length of reauthentication identity. + // This must be less or equal to the length field. + u16_t next_reauth_id_length = payload->get_reserved(); + if (next_reauth_id_length == 0u + || next_reauth_id_length > payload->get_data_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reauthentication identity length field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * next_reauth_id = static_cast(payload->get_data(next_reauth_id_length)); + if (next_reauth_id == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_aka_payloads->get_NEXT_REAUTH_ID()->set_buffer( + payload, next_reauth_id, next_reauth_id_length, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_RESULT_IND) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_RESULT_IND | Length = 1 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved %d.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_reserved())); + + status = p_aka_payloads->get_RESULT_IND()->set_buffer( + payload, 0, 0u, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_NOTIFICATION) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_NOTIFICATION| Length = 1 | Notification Code | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note the reserved field includes the notification code (client error code). + eap_aka_notification_codes_e notification_code = static_cast(payload->get_reserved()); + EAP_UNREFERENCED_PARAMETER(notification_code); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, notification code %d.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_reserved())); + + status = p_aka_payloads->get_NOTIFICATION()->set_buffer( + payload, 0, 0u, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_COUNTER) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_COUNTER | Length = 1 | Counter | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, counter %d.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_reserved())); + + status = p_aka_payloads->get_COUNTER()->set_buffer( + payload, 0, 0u, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_COUNTER_TOO_SMALL) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_COUNTER_TOO.| Length = 1 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved %d.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_reserved())); + + status = p_aka_payloads->get_COUNTER_TOO_SMALL()->set_buffer( + payload, 0, 0u, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_MAC) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_MAC | Length = 5 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | MAC | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_reserved() != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() != EAP_TYPE_AKA_MAC_SIZE) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(EAP_TYPE_AKA_MAC_SIZE)); + + if (buffer == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_aka_payloads->get_MAC()->set_buffer( + payload, buffer, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_IV) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_IV | Length = 5 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | Initialization Vector (optional) | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_reserved() != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (payload->get_data_length() != aes.get_block_size()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(payload->get_data_length())); + + if (buffer == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + status = p_aka_payloads->get_IV()->set_buffer( + payload, buffer, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_ENCR_DATA) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_ENCR_DATA | Length | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | Encrypted Data (optional) | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_reserved() != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() < 8u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(payload->get_data_length())); + + if (buffer == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_aka_payloads->get_ENCR_DATA()->set_buffer( + payload, buffer, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_PERMANENT_ID_REQ) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_PERM..._REQ | Length = 1 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_aka_payloads->get_PERMANENT_ID_REQ()->set_buffer( + payload, 0, 0, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_FULLAUTH_ID_REQ) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_FULL..._REQ | Length = 1 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_aka_payloads->get_FULLAUTH_ID_REQ()->set_buffer( + payload, 0, 0, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_ANY_ID_REQ) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_ANY..._REQ | Length = 1 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_aka_payloads->get_ANY_ID_REQ()->set_buffer( + payload, 0, 0, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_IDENTITY) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_IDENTITY | Length | Actual Identity Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // . Current Identity (optional) . + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + u16_t identity_length = payload->get_reserved(); + + if (payload->get_data_length() == 0 + || identity_length > payload->get_data_length() + || identity_length < 1u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, identity_length 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * identity_data + = static_cast(payload->get_data(payload->get_data_length())); + + if (identity_data == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (identity_length < payload->get_data_length()) + { + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Includes padding bytes. Those must be zero. + eap_status_e status = cbc_aes.check_padding_bytes( + identity_data+identity_length, + payload->get_data_length()-identity_length, + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // We assume the prefix byte is included. + status = p_aka_payloads->get_IDENTITY_payload()->set_buffer( + payload, identity_data, identity_length, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_CLIENT_ERROR_CODE) + { + // The format of the AT_CLIENT_ERROR_CODE attribute is shown below. + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_CLIENT_ERR..| Length = 1 | Client Error Code | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // Note the reserved field includes the client error code. + + if (payload->get_data_length() != EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_aka_client_error_code_e client_error_code = static_cast(payload->get_reserved()); + + if (client_error_code > eap_aka_client_error_code_maximum_value) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, illegal AKA client error code %d.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), client_error_code)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, client_error_code %d.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + client_error_code)); + + status = p_aka_payloads->get_CLIENT_ERROR_CODE()->set_buffer( + payload, 0, 0u, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == aka_payload_AT_CHECKCODE) + { + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_CHECKCODE | Length | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | Checkcode (0 or 20 bytes) | + // | | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_reserved() != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() != 0UL + && payload->get_data_length() != EAP_TYPE_AKA_MAXIMUM_CHECKCODE_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x. Illegal CHECKCODE bytes 0x%04x, 0 or 0x%04x bytes required.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_data_length(), + EAP_TYPE_AKA_MAXIMUM_CHECKCODE_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_enough_challenges); + } + + + u8_t * CHECKCODE = 0; + + if (payload->get_data_length() != 0) + { + CHECKCODE = static_cast(payload->get_data(payload->get_data_length())); + if (CHECKCODE == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + + status = p_aka_payloads->get_CHECKCODE()->set_buffer( + payload, CHECKCODE, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (128 <= current_payload && current_payload <= 255) + { + // Unknown skippable attribute. + // Silently ignore this payload. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("IGNORED: eap_type_aka_c::parse_generic_payload(): Ignored skippable attribute %d=0x%04x.\n"), + current_payload, + current_payload)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + // Unknown non-skippable attribute. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_generic_payload(): Unknown non-skippable attribute %d=0x%04x.\n"), + current_payload, + current_payload)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unsupported_gsmsim_payload); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::analyse_aka_packet( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (m_is_client == true) + { + // Client + + if (received_aka->get_subtype() == aka_subtype_Identity) + { + status = handle_aka_identity_request_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (received_aka->get_subtype() == aka_subtype_Challenge) + { + status = handle_challenge_request_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (received_aka->get_subtype() == aka_subtype_Notification) + { + status = handle_aka_notification_request_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (received_aka->get_subtype() == aka_subtype_Re_authentication) + { + status = handle_reauthentication_request_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else + { + // Unknown message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::analyse_aka_packet(): ") + EAPL("Unknown message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Server + + if (received_aka->get_subtype() == aka_subtype_Identity) + { + status = handle_aka_identity_response_message( + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (received_aka->get_subtype() == aka_subtype_Synchronization_Failure) + { + status = handle_synchronization_failure_response_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (received_aka->get_subtype() == aka_subtype_Challenge) + { + status = handle_challenge_response_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (received_aka->get_subtype() == aka_subtype_Notification) + { + status = handle_notification_response_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (received_aka->get_subtype() == aka_subtype_Re_authentication) + { + status = handle_reauthentication_response_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (received_aka->get_subtype() == aka_subtype_Client_Error) + { + status = handle_client_error_response_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else + { + // Unknown message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::analyse_aka_packet(): ") + EAPL("Unknown message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::parse_aka_payload( + const aka_payload_AT_header_c * const p_payload, + u32_t * const buffer_length, + aka_payloads_c * const p_aka_payloads, + const aka_subtype_e subtype) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + aka_payload_AT_header_c payload( + m_am_tools, + p_payload->get_header_buffer(*buffer_length), + *buffer_length); // Const correctness is gone. + + aka_payload_AT_type_e current_payload = payload.get_current_payload(); + + eap_status_e status = eap_status_header_corrupted; + + if (payload.get_is_valid() == true + && current_payload != aka_payload_NONE) + { + if (*buffer_length < payload.get_header_length()+payload.get_data_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_aka_payload(0x%08x): current payload 0x%04x=%s, data length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload, + payload.get_payload_AT_string(), + payload.get_data_length(), + *buffer_length)); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_aka_payload(): AKA-payload header is corrupted.\n"))); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload, p_aka_payloads, subtype); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT_ALWAYS(*buffer_length >= payload.get_header_length()+payload.get_data_length()); + *buffer_length -= payload.get_header_length()+payload.get_data_length(); + + while(*buffer_length >= payload.get_header_length() + && payload.get_is_valid() == true + && payload.get_header_buffer_length() >= (payload.get_header_length()+payload.get_data_length())) + { + payload.set_header_buffer( + payload.get_next_header(), + payload.get_header_buffer_length()-(payload.get_header_length()+payload.get_data_length())); + if (payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + current_payload = payload.get_current_payload(); + + if (*buffer_length < payload.get_header_length()+payload.get_data_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_aka_payload(0x%08x): current payload 0x%04x=%s, data length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload, + payload.get_payload_AT_string(), + payload.get_data_length(), + *buffer_length)); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_aka_payload(): AKA-payload header is corrupted.\n"))); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload, p_aka_payloads, subtype); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT_ALWAYS(*buffer_length >= payload.get_header_length()+payload.get_data_length()); + *buffer_length -= payload.get_header_length()+payload.get_data_length(); + } + } + + if (*buffer_length != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_aka_payload(): ") + EAPL("AKA-header is corrupted. Buffer length and payload length does not match. %lu illegal bytes.\n"), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::parse_aka_packet( + aka_header_c * const aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (aka->get_length() < aka->get_header_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_aka_packet(): ") + EAPL("AKA-header is corrupted. Buffer length and payload ") + EAPL("length does not match. AKA-header length %lu < minimum AKA-header length %lu.\n"), + aka->get_length(), + aka->get_header_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (aka->get_length() > aka_packet_length) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_aka_packet(): ") + EAPL("AKA-header is corrupted. Buffer length and payload ") + EAPL("length does not match. AKA-header length %lu > packet length %lu\n"), + aka->get_length(), + aka_packet_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u32_t buffer_length = aka->get_length() - aka->get_header_length(); + + if (buffer_length == 0u) + { + // No payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + + aka_payload_AT_header_c payload( + m_am_tools, + aka->get_data(buffer_length), + buffer_length); + + if (payload.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: No aka_payload_AT_header_c.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + eap_status_e status = parse_aka_payload( + &payload, + &buffer_length, + p_aka_payloads, + aka->get_subtype()); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (buffer_length != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::parse_aka_packet(): ") + EAPL("AKA-header is corrupted. Buffer length and payload ") + EAPL("length does not match. Illegal byte count %lu\n"), + buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_aka_packet( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_length, + aka_payloads_c * const p_aka_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = check_valid_state(received_aka->get_subtype()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = parse_aka_packet(received_aka, aka_length, p_aka_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = analyse_aka_packet( + receive_network_id, + received_aka, + aka_length, + p_aka_payloads); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +#if defined(USE_EAP_TRACE) + +// +EAP_FUNC_EXPORT void eap_type_aka_c::packet_trace( + eap_const_string prefix, + const eap_am_network_id_c * const /* receive_network_id */, + eap_header_wr_c * const eap_packet, + const u32_t /* eap_packet_length */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(prefix); + + if (eap_packet->get_length() > eap_header_base_c::get_header_length() + && eap_packet->get_type() == eap_type_aka) + { + aka_header_c aka_eap( + m_am_tools, + eap_packet->get_header_buffer(eap_packet->get_header_buffer_length()), + eap_packet->get_header_buffer_length()); + + EAP_UNREFERENCED_PARAMETER(aka_eap); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s EAP_type_AKA: %s, code=0x%02x=%s, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x=%s, subtype=0x%02x=%s\n"), + prefix, + (m_is_client == true) ? "client": "server", + aka_eap.get_code(), + aka_eap.get_code_string(), + aka_eap.get_identifier(), + aka_eap.get_length(), + convert_eap_type_to_u32_t(aka_eap.get_type()), + aka_eap.get_eap_type_string(), + aka_eap.get_subtype(), + aka_eap.get_subtype_string())); + + EAP_TRACE_DEBUG(m_am_tools, eap_am_tools_c::eap_trace_mask_eap_messages, + (EAPL("\n\t%s\n\tcode = 0x%02x = %s\n\tidentifier = 0x%02x") + EAPL("\n\tlength = 0x%04x = %lu\n\ttype = 0x%08x = %s\n\tsubtype = 0x%02x = %s\n"), + (m_is_client == true) ? "client": "server", + aka_eap.get_code(), + aka_eap.get_code_string(), + aka_eap.get_identifier(), + aka_eap.get_length(), + aka_eap.get_length(), + convert_eap_type_to_u32_t(aka_eap.get_type()), + aka_eap.get_eap_type_string(), + aka_eap.get_subtype(), + aka_eap.get_subtype_string())); + } + else if (eap_packet->get_length() > eap_header_base_c::get_header_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s EAP_type_AKA: %s, code=0x%02x=%s, identifier=0x%02x, length=0x%04x, type=0x%08x=%s\n"), + prefix, + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + convert_eap_type_to_u32_t(eap_packet->get_type()), + eap_packet->get_type_string())); + + EAP_TRACE_DEBUG( + m_am_tools, + eap_am_tools_c::eap_trace_mask_eap_messages, + (EAPL("\n\t%s\n\tcode = 0x%02x = %s\n\tidentifier = 0x%02x\n\tlength = 0x%04x = %lu\n\ttype = 0x%08x = %s\n"), + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + eap_packet->get_length(), + convert_eap_type_to_u32_t(eap_packet->get_type()), + eap_packet->get_type_string())); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s EAP_type_AKA: %s, code=0x%02x=%s, identifier=0x%02x, length=0x%04x\n"), + prefix, + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + eap_am_tools_c::eap_trace_mask_eap_messages, + (EAPL("\n\t%s\n\tcode = 0x%02x = %s\n\tidentifier = 0x%02x\n\tlength = 0x%04x = %lu\n"), + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + eap_packet->get_length())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +#endif //#if defined(USE_EAP_TRACE) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_aka_c::get_nai_realm() +{ + return &m_manual_realm; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_aka_c::update_buffer_indexes( + const u32_t maximum_buffer_size, + const u32_t payload_size, + u32_t * const buffer_offset, + u32_t * const buffer_free) +{ + EAP_UNREFERENCED_PARAMETER(maximum_buffer_size); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length); + EAP_ASSERT_ALWAYS(*buffer_free >= payload_size); + EAP_ASSERT_ALWAYS(m_aka_header_offset+m_MTU == *buffer_offset + *buffer_free); + + *buffer_free -= payload_size; + *buffer_offset += payload_size; + + EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length); + EAP_ASSERT_ALWAYS(*buffer_offset <= m_aka_header_offset+m_MTU); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_aka_c::update_payload_indexes( + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + const u32_t payload_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_offset, + u32_t * const buffer_free) +{ + EAP_UNREFERENCED_PARAMETER(eap_header_size); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT_ALWAYS(*buffer_offset == m_aka_header_offset + eap_header_size + *data_offset); + EAP_ASSERT_ALWAYS(*buffer_free == *data_free); + EAP_ASSERT_ALWAYS(*data_free >= payload_size); + + *data_free -= payload_size; + *data_offset += payload_size; + + update_buffer_indexes( + maximum_buffer_size, + payload_size, + buffer_offset, + buffer_free); + + EAP_ASSERT_ALWAYS(*buffer_offset == m_aka_header_offset + eap_header_size + *data_offset); + EAP_ASSERT_ALWAYS(*buffer_free == *data_free); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_type_aka_c::get_is_client() +{ + return m_is_client; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_aka_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_type_aka_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_aka_c::state_notification( + const abs_eap_state_notification_c * const state + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::state_notification(): get_type_partner() 0x%08x\n"), + get_type_partner())); + + get_type_partner()->state_notification(state); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::finish_successful_authentication( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::finish_successful_authentication().\n"))); + + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (get_master_session_key()->get_is_valid_data() == false + || get_master_session_key()->get_data_length() == 0u) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + eap_status_e status = get_type_partner()->packet_data_crypto_keys( + &send_network_id, + get_master_session_key()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_authentication_type == AKA_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + // Re-authentication counter is increased only on successfull re-authentication. + // In order to use re-authentication, the client and the server need to + // update re-authentication counter value. + status = m_am_type_aka->increase_reauth_counter(); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + set_authentication_finished_successfully(); + set_state(eap_type_aka_state_success); + + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_type_aka, + eap_state_none, + eap_state_authentication_finished_successfully, + get_last_eap_identifier(), + true); + state_notification(¬ification); + + // Indicate AKA AM authentication finish. + m_am_type_aka->authentication_finished(true, m_authentication_type, m_identity_type); + + + if (m_authentication_type == AKA_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, re-authentication EAP-SUCCESS, ") + EAPL("re-authentication identity\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_authentication_type == AKA_AUTHENTICATION_TYPE_FULL_AUTH) + { + if (m_identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, full authentication EAP-SUCCESS, ") + EAPL("pseudonym identity\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_IMSI_ID) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, full authentication EAP-SUCCESS, ") + EAPL("IMSI identity\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, full authentication EAP-SUCCESS, ") + EAPL("Re-auth identity\n"), + (m_is_client == true) ? "client": "server")); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS|TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: EAP_type_AKA: %s, unknown authentication EAP-SUCCESS, ") + EAPL("unknown identity\n"), + (m_is_client == true) ? "client": "server")); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS|TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: EAP_type_AKA: %s, unknown authentication EAP-SUCCESS, ") + EAPL("unknown identity\n"), + (m_is_client == true) ? "client": "server")); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + + cancel_error_message_delay_timer(); + + cancel_notification_message_delay_timer(); + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::packet_process(): receive_network_id=0x%08x is invalid.\n"), + receive_network_id)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (received_eap == 0 + || received_eap->get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::packet_process(): received_eap 0x%08x is invalid.\n"), + received_eap)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_AKA_PACKET_TRACE( + EAPL("->"), + receive_network_id, + received_eap, + eap_packet_length); + + if (eap_packet_length < received_eap->get_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::packet_process(): ") + EAPL("eap_packet_length=0x%04x < received_eap->get_length()=0x%04x.\n"), + eap_packet_length, received_eap->get_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (received_eap->get_length() < eap_header_base_c::get_header_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::packet_process(): received_eap->get_length() ") + EAPL("< eap_header_base_c::get_header_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + + // NOTE: by disabling these calls throughput increases about 18%. + // Disabling also decreases random seeds. + m_am_tools->get_crypto()->add_rand_seed( + received_eap->get_header_buffer(eap_packet_length), + eap_packet_length); + m_am_tools->get_crypto()->add_rand_seed_hw_ticks(); + + eap_status_e status = eap_status_process_general_error; + + if ((m_is_client == true + && received_eap->get_code() == eap_code_request) + || (m_is_client == false + && received_eap->get_code() == eap_code_response)) + { + if (received_eap->get_type() == eap_type_identity + || received_eap->get_type() == eap_type_aka) + { + if (received_eap->get_type() == eap_type_identity + && received_eap->get_code() == eap_code_request + && received_eap->get_length() <= eap_header_base_c::get_header_length()) + { + status = eap_status_header_corrupted; + } + else if (received_eap->get_type() == eap_type_identity + && received_eap->get_code() == eap_code_response + && received_eap->get_length() <= eap_header_base_c::get_header_length()) + { + status = eap_status_header_corrupted; + } + else if (received_eap->get_type() == eap_type_aka + && received_eap->get_length() < received_eap->get_header_length()) + { + status = eap_status_header_corrupted; + } + else + { + aka_header_c aka_header( + m_am_tools, + received_eap->get_header_buffer(received_eap->get_header_buffer_length()), + received_eap->get_header_buffer_length()); + + if (aka_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = aka_packet_process( + receive_network_id, + &aka_header, + eap_packet_length, + m_is_client); + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_drop_packet_quietly + && status != eap_status_pending_request) + { + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: %s=%d eap_type_aka_c::aka_packet_process() failed\n"), + status_string.get_status_string(status), status)); + + if (m_is_client == true) + { + status = initialize_error_message( + status); + } + else + { + status = initialize_notification_message(); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(received_eap, false); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (received_eap->get_type() == eap_type_notification) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP type notification: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, type=0x%08x\n"), + received_eap->get_code(), + received_eap->get_identifier(), + received_eap->get_length(), + convert_eap_type_to_u32_t(received_eap->get_type()))); + + status = eap_status_illegal_eap_type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP type unknown: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, type=0x%08x\n"), + received_eap->get_code(), + received_eap->get_identifier(), + received_eap->get_length(), + convert_eap_type_to_u32_t(received_eap->get_type()))); + + status = eap_status_illegal_eap_type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (m_is_client == true + && (received_eap->get_code() == eap_code_success + || received_eap->get_code() == eap_code_failure)) + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (received_eap->get_code() == eap_code_success) + { + if (get_state() == eap_type_aka_state_waiting_for_success) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(received_eap, false); + + if (m_wait_eap_success_packet == false) + { + /** + * @{ Check right functionality. + * Here we return eap_status_ok, eap_status_success was returned after successfull + * EAP-Request/AKA/Challenge. This may change after EAP, 802.1X and 802.11i specifications are ready. } + */ + status = eap_status_ok; + } + else + { + status = finish_successful_authentication( + receive_network_id); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP-Success: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, state %d=%s, is client %d\n"), + received_eap->get_code(), + received_eap->get_identifier(), + received_eap->get_length(), + get_state(), + get_state_string(), + (m_is_client == true))); + status = eap_status_drop_packet_quietly; + } + } + else if (received_eap->get_code() == eap_code_failure) + { + // EAP is quite sloppy protocol. + // Somebody just send a EAP-failure message and authentication is terminated. + + // Save received failure. We do not change our state yet. + // The real correct EAP message could be received later if this failure was + // send by nasty attacker. + set_failure_message_received(); + // We handle the EAP-Request/Failure message after a timeout. + + status = eap_status_ok; + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP code unknown: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, is client %d\n"), + received_eap->get_code(), received_eap->get_identifier(), + received_eap->get_length(), (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP code unknown: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, is client %d\n"), + received_eap->get_code(), received_eap->get_identifier(), + received_eap->get_length(), (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::new_handler( + const eap_am_network_id_c * const /* receive_network_id */, + const bool is_client_when_true) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::new_handler(): Creating new handler 0x%08x.\n"), + this)); + + // We do not have handler yet and the message is identity EAP-message. + // A new handler is needed. + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + m_is_client = is_client_when_true; + + if (is_client_when_true == true) + { + set_state(eap_type_aka_state_waiting_for_identity_request); + } + else if (is_client_when_true == false) + { + set_state(eap_type_aka_state_waiting_for_identity_response); + } + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::aka_packet_process(0x%08x): New handler created.\n"), + this)); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" own address"), + m_send_network_id.get_source_id()->get_data(m_send_network_id.get_source_id()->get_data_length()), + m_send_network_id.get_source_id()->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("peer address"), + m_send_network_id.get_destination_id()->get_data(m_send_network_id.get_destination_id()->get_data_length()), + m_send_network_id.get_destination_id()->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::aka_packet_process( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + const bool is_client_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): ") + EAPL("receive_network_id=0x%08x is invalid.\n"), + receive_network_id)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (received_aka == 0 + || received_aka->get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): ") + EAPL("received_aka 0x%08x is invalid.\n"), + received_aka)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (aka_packet_length < received_aka->get_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): ") + EAPL("aka_packet_length < received_aka->get_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (received_aka->get_type() == eap_type_aka) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::aka_packet_process(), AKA subtype %d=%s\n"), + received_aka->get_subtype(), received_aka->get_subtype_string())); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::aka_packet_process(), EAP-type 0x%08x=%s\n"), + convert_eap_type_to_u32_t(received_aka->get_type()), + received_aka->get_eap_type_string())); + } + + eap_status_e status = eap_status_process_general_error; + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (get_state() == eap_type_aka_state_none) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::aka_packet_process(): No handler found.\n"))); + + if (is_client_when_true == false + && received_aka->get_type() == eap_type_identity) + { + // The EAP-identity is plain EAP-packet without additional fields.. + eap_header_rd_c eap_header( + m_am_tools, + received_aka->get_header_buffer(received_aka->get_header_buffer_length()), + received_aka->get_header_buffer_length()); + + EAP_UNREFERENCED_PARAMETER(eap_header); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("received: EAP-identity"), + eap_header.get_type_data(eap_header.get_type_data_length()), + eap_header.get_type_data_length())); + + status = new_handler( + receive_network_id, + is_client_when_true); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): new_handler() failed, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (is_client_when_true == true + && received_aka->get_code() == eap_code_request) + { + if (received_aka->get_length() < received_aka->get_header_length()) + { + status = eap_status_process_illegal_packet_error; + eap_status_string_c status_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: %s=%d eap_type_aka_c::aka_packet_process(): corrupted AKA-header.\n"), + status_string.get_status_string(status), status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Here we create a handler and set state to eap_type_aka_state_waiting_for_aka_identity_request + // if first EAP-Request is EAP-Request/AKA/Identity. + if (received_aka->get_subtype() == aka_subtype_Identity) + { + eap_header_rd_c eap_header( + m_am_tools, + received_aka->get_header_buffer(received_aka->get_header_buffer_length()), + received_aka->get_header_buffer_length()); + + EAP_UNREFERENCED_PARAMETER(eap_header); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("received: EAP-Request/AKA/Identity"), + eap_header.get_type_data(eap_header.get_type_data_length()), + eap_header.get_type_data_length())); + + status = new_handler( + receive_network_id, + is_client_when_true); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): new_handler() failed, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + set_state(eap_type_aka_state_waiting_for_aka_identity_request); + } + else if (received_aka->get_subtype() == aka_subtype_Challenge) + { + eap_header_rd_c eap_header( + m_am_tools, + received_aka->get_header_buffer(received_aka->get_header_buffer_length()), + received_aka->get_header_buffer_length()); + + EAP_UNREFERENCED_PARAMETER(eap_header); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("received: EAP-Request/AKA/Challenge"), + eap_header.get_type_data(eap_header.get_type_data_length()), + eap_header.get_type_data_length())); + + // We must query the previous sent EAP-Identity from EAP_Core. + // The EAP_Core saves the sent EAP-Identity when the EAP-Identity is + // sent to the network. + // Previous EAP-type was NOT this instance. EAP-Identity was queried from other instance. + status = get_type_partner()->get_saved_eap_identity(get_identity()); + if (status != eap_status_ok) + { + // We do not have the identity server accepted anymore. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): ") + EAPL("Cannot create new handler because EAP-Identity is missing. This EAP-packet is dropped.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + status = get_NAI()->set_copy_of_buffer(get_identity()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(AKA_IDENTITY_TYPE_IMSI_ID); + + status = new_handler( + receive_network_id, + is_client_when_true); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): new_handler() failed, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + set_state(eap_type_aka_state_waiting_for_challenge_request); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): ") + EAPL("Only EAP-Request/AKA/Identity message in EAP-AKA client ") + EAPL("causes creation of new handler. This EAP-packet is dropped.\n"))); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_AKA_ERROR, (EAPL("ERROR: received: source"), + receive_network_id->get_source(), + receive_network_id->get_source_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_AKA_ERROR, (EAPL("ERROR: received: destination"), + receive_network_id->get_destination(), + receive_network_id->get_destination_length())); + + if (received_aka->get_type() == eap_type_aka) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x, subtype=0x%02x, client %d\n"), + received_aka->get_code(), + received_aka->get_identifier(), + received_aka->get_length(), + convert_eap_type_to_u32_t(received_aka->get_type()), + received_aka->get_subtype(), + is_client_when_true)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x, client %d\n"), + received_aka->get_code(), + received_aka->get_identifier(), + received_aka->get_length(), + convert_eap_type_to_u32_t(received_aka->get_type()), + is_client_when_true)); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): ") + EAPL("Only EAP-identity message in server causes creation ") + EAPL("of new handler. This EAP-packet is dropped.\n"))); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_AKA_ERROR, (EAPL("ERROR: received: source"), + receive_network_id->get_source(), + receive_network_id->get_source_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_AKA_ERROR, (EAPL("ERROR: received: destination"), + receive_network_id->get_destination(), + receive_network_id->get_destination_length())); + + if (received_aka->get_type() == eap_type_aka) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x, subtype=0x%02x, client %d\n"), + received_aka->get_code(), + received_aka->get_identifier(), + received_aka->get_length(), + convert_eap_type_to_u32_t(received_aka->get_type()), + received_aka->get_subtype(), + is_client_when_true)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x, client %d\n"), + received_aka->get_code(), + received_aka->get_identifier(), + received_aka->get_length(), + convert_eap_type_to_u32_t(received_aka->get_type()), + is_client_when_true)); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::aka_packet_process(): state %d=%s\n"), + get_state(), + get_state_string())); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("received: AKA packet"), + received_aka->get_header_buffer( + received_aka->get_header_buffer_length()), + received_aka->get_header_buffer_length())); + + if (received_aka->get_type() == eap_type_identity) + { + if (is_client_when_true == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): ") + EAPL("EAP-Request/Identity is not handled here anymore.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + status = eap_status_process_general_error; + } + else if (is_client_when_true == false) + { + eap_header_rd_c eap_header( + m_am_tools, + received_aka->get_header_buffer(received_aka->get_header_buffer_length()), + received_aka->get_header_buffer_length()); + + const eap_type_aka_state_variable_e saved_state = get_state(); + + EAP_UNREFERENCED_PARAMETER(saved_state); + + status = handle_identity_response_message( + &eap_header, + aka_packet_length + ); + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_drop_packet_quietly) + { + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: %s=%d eap_type_aka_c::aka_packet_process(): ") + EAPL("handle_identity_response_message().\n"), + status_string.get_status_string(status), status)); + } + + if (status == eap_status_ok) + { + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_type_aka, + eap_state_none, + eap_state_identity_response_received, + get_last_eap_identifier(), + false); + state_notification(¬ification); + } + } + + if (status == eap_status_ok + || status == eap_status_success) + { + // Ok, good EAP message received. + if (m_is_client == true) + { + unset_failure_message_received(); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): ") + EAPL("handle_identity_response_message() failed, status %d.\n"), + status)); + } + + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (aka_packet_length < received_aka->get_header_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): ") + EAPL("aka_packet_length < aka_header_c::get_header_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = received_aka->check_header(); + if (status != eap_status_ok) + { + eap_status_string_c status_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: %s=%d eap_type_aka_c::aka_packet_process(): corrupted AKA-header.\n"), + status_string.get_status_string(status), status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("received: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + received_aka->get_subtype_string(), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + aka_payloads_c * const l_aka_payloads = new aka_payloads_c(m_am_tools); + eap_automatic_variable_c l_aka_payloads_automatic(m_am_tools, l_aka_payloads); + + if (l_aka_payloads == 0 + || l_aka_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = handle_aka_packet( + receive_network_id, + received_aka, + aka_packet_length, + l_aka_payloads); + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_drop_packet_quietly + && status != eap_status_pending_request) + { + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: %s=%d eap_type_aka_c::aka_packet_process(): handle_aka_packet().\n"), + status_string.get_status_string(status), status)); + } + + if (status == eap_status_ok + || status == eap_status_success + || status == eap_status_pending_request) + { + // Ok, good EAP message received. + if (m_is_client == true) + { + unset_failure_message_received(); + } + } + + if (status == eap_status_ok) + { + // Do nothing special. + } + else if (status == eap_status_drop_packet_quietly) + { + // We will drop this message quietly. + } + else if (status != eap_status_ok) + { + // EAP-Failure will be sent from shutdown(). + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::cancel_error_message_delay_timer() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = cancel_timer( + this, + EAP_TYPE_AKA_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID); + + m_erroneus_packet_received = false; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID cancelled.\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::set_error_message_delay_timer() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = set_timer( + this, + EAP_TYPE_AKA_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID, + 0, + m_failure_message_delay_time); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID set.\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::cancel_notification_message_delay_timer() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = cancel_timer( + this, + EAP_TYPE_AKA_TIMER_DELAY_NOTIFICATION_MESSAGE_ID); + + m_erroneus_packet_received = false; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID cancelled.\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::set_notification_message_delay_timer() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = set_timer( + this, + EAP_TYPE_AKA_TIMER_DELAY_NOTIFICATION_MESSAGE_ID, + 0, + m_failure_message_delay_time); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID set.\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_error_packet() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_error_packet(): ") + EAPL("erroneus_packet_received %d, m_client_error_code %d\n"), + m_erroneus_packet_received, + m_client_error_code)); + + if (m_erroneus_packet_received == true) + { + set_state(eap_type_aka_state_failure); + + if (m_is_client == true) + { + // Client will send EAP-Response/AKA/Client-Error. + status = send_aka_client_error_response(); + } + else + { + // Server will send EAP-Failure. + // Notifies the lower level of unsuccessfull authentication. + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_type_aka, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + get_last_eap_identifier(), + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + state_notification(¬ification); + + status = eap_status_ok; + } + } + else + { + // One erroneous packet is already received. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("WARNING: eap_type_aka_c::handle_error_packet(): one erroneus packet already received. This is ignored.\n"))); + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::initialize_error_message( + const eap_status_e error_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::initialize_error_message(): erroneus_packet_received %d, error_status %s\n"), + m_erroneus_packet_received, + status_string.get_status_string(error_status))); + + if (m_erroneus_packet_received == false) + { + // Only the first erroneus packet is recorded. + m_erroneus_packet_received = true; + + if (m_is_client == true) + { + // Client will send EAP-Response/AKA/Client-Error. + switch(error_status) + { + case eap_status_no_matching_protocol_version: + m_client_error_code = eap_aka_client_error_code_unsupported_version; + break; + case eap_status_not_enough_challenges: + m_client_error_code = eap_aka_client_error_code_insufficient_number_of_challenges; + break; + case eap_status_not_fresh_challenges: + m_client_error_code = eap_aka_client_error_code_rands_are_not_fresh; + break; + default: + m_client_error_code = eap_aka_client_error_code_unable_to_process_packet; + break; + }; + } + else + { + // Server will send EAP-Failure. + } + + if (m_failure_message_delay_time > 0ul) + { + // First try set delay timer. + status = set_error_message_delay_timer(); + if (status != eap_status_ok) + { + // ERROR: Process error packet immediately. + status = handle_error_packet(); + } + } + else + { + // Process error packet immediately. + status = handle_error_packet(); + } + } + else + { + // Error packet is already processed. + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_notification_packet() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_notification_packet(): aka_notification_packet_received %d\n"), + m_aka_notification_packet_received)); + + if (m_aka_notification_packet_received == true) + { + bool add_at_counter_attribute = false; + if (m_authentication_type == AKA_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + add_at_counter_attribute = true; + } + + if (m_is_client == true) + { + // Client will send EAP-Response/AKA/Notification. + if (get_aka_notification_code_F_bit(m_aka_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + set_state(eap_type_aka_state_failure); + } + + status = send_aka_notification_response( + m_aka_notification_code, + add_at_counter_attribute); + } + else + { + set_state(eap_type_aka_state_waiting_for_notification_response_failure); + + // Server will send EAP-Request/AKA/Notification. + status = send_aka_notification_request( + m_aka_notification_code, + add_at_counter_attribute); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_notification_packet(): one AKA/Notification packet already received. This is ignored.\n"))); + + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::initialize_notification_message() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (m_aka_notification_packet_received == false) + { + // Only the first AKA notification packet is recorded. + m_aka_notification_packet_received = true; + + if (m_is_client == true) + { + // Client will send empty EAP-Response/AKA/Notification. + } + else + { + // Server will send EAP-Request/AKA/Notification. + if (m_aka_notification_code == eap_aka_notification_none) + { + m_aka_notification_code = eap_aka_notification_no_F_P_set_general_failure; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::initialize_notification_message(0x%08x), notification_code = 0x%04x, F bit %d, P bit %d.\n"), + this, + m_aka_notification_code, + get_aka_notification_code_F_bit(m_aka_notification_code), + get_aka_notification_code_P_bit(m_aka_notification_code))); + } + + if (m_failure_message_delay_time > 0ul) + { + // First try set delay timer. + status = set_notification_message_delay_timer(); + if (status != eap_status_ok) + { + // ERROR: Process AKA notification packet immediately. + status = handle_notification_packet(); + } + } + else + { + // Process AKA notification packet immediately. + status = handle_notification_packet(); + } + } + else + { + // AKA notification packet is already processed. + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_type_aka_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + u32_t offset = get_type_partner()->get_header_offset(MTU, trailer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return offset; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::extra_message_authentication_code_bytes( + const aka_subtype_e subtype, + const eap_code_value_e code, + crypto_hmac_c *hmac_sha1) +{ + if (code == eap_code_request) + { + } + else if (code == eap_code_response) + { + if (subtype == aka_subtype_Re_authentication) + { + eap_status_e status = hmac_sha1->hmac_update( + get_NONCE_S()->get_data(get_NONCE_S()->get_data_length()), + get_NONCE_S()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_AKA_ERROR, (EAPL("ERROR: extra_message_authentication_code_bytes(): unsupported EAP-Code %d.\n"), + code)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::create_message_authentication_code( + eap_type_aka_MAC_attributes_c *MAC_attributes, + const aka_subtype_e subtype, + const eap_code_value_e code, + const eap_variable_data_c * const authentication_key +) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (MAC_attributes == 0 + || authentication_key == 0 + || authentication_key->get_is_valid_data() == false + || MAC_attributes->get_data() == 0 + || MAC_attributes->get_data_length() == 0u + || MAC_attributes->get_MAC() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("authentication_key"), + authentication_key->get_data(authentication_key->get_data_length()), + authentication_key->get_data_length())); + + eap_status_e status = eap_status_process_general_error; + +#if defined(USE_EAP_TRACE) + { + eap_variable_data_c buffer(m_am_tools); + + if (buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = buffer.set_buffer_length(2048); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = buffer.set_buffer_length(buffer.get_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const tmpbuffer = buffer.get_data(buffer.get_data_length()); + if (tmpbuffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t offset = 0; + + m_am_tools->memmove(tmpbuffer+offset, + (MAC_attributes->get_data()), + MAC_attributes->get_data_length()); + offset += MAC_attributes->get_data_length(); + + if (code == eap_code_request) + { + } + else if (code == eap_code_response) + { + if (subtype == aka_subtype_Re_authentication) + { + m_am_tools->memmove(tmpbuffer+offset, + get_NONCE_S()->get_data(get_NONCE_S()->get_data_length()), + get_NONCE_S()->get_data_length()); + offset += get_NONCE_S()->get_data_length(); + } + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_AKA_ERROR, (EAPL("ERROR: extra_message_authentication_code_bytes(): unsupported EAP-Code %d.\n"), + code)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("create_message_authentication_code(): MAC calculated over the following bytes:\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("MAC data"), + tmpbuffer, + offset)); + } +#endif // #if defined(USE_EAP_TRACE) + + + crypto_sha1_c sha1(m_am_tools); + crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false); + + if (hmac_sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (hmac_sha1.hmac_set_key( + authentication_key + ) != eap_status_ok) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_AKA_ERROR, (EAPL("ERROR: create_message_authentication_code(): set_key() failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = hmac_sha1.hmac_update( + MAC_attributes->get_data(), + MAC_attributes->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = extra_message_authentication_code_bytes(subtype, code, &hmac_sha1); + if (status != eap_status_ok) + { + eap_status_string_c status_string; + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_AKA_ERROR, (EAPL("ERROR: %s=%d create_message_authentication_code(): extra_message_authentication_code_bytes().\n"), + status_string.get_status_string(status), status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + u32_t length = 0u; + + status = hmac_sha1.hmac_128_final( + MAC_attributes->get_MAC(), + &length); + if (status != eap_status_ok + || length != EAP_TYPE_AKA_MAC_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT(length == EAP_TYPE_AKA_MAC_SIZE); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("MAC:\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("MAC"), + MAC_attributes->get_MAC(), + length)); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::check_message_authentication_code( + const eap_variable_data_c * const authentication_key, + aka_payloads_c * const p_aka_payloads, + const aka_header_c * const aka_packet, + const u32_t aka_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (authentication_key == 0 + || authentication_key->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + if (p_aka_payloads->get_MAC() == 0 + || p_aka_payloads->get_MAC()->get_payload_included() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + if (aka_packet == 0 + || aka_packet_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("authentication_key"), + authentication_key->get_data(authentication_key->get_data_length()), + authentication_key->get_data_length())); + + crypto_sha1_c sha1(m_am_tools); + crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false); + + if (hmac_sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (hmac_sha1.hmac_set_key( + authentication_key + ) != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u8_t saved_MAC[EAP_TYPE_AKA_MAC_SIZE]; + + m_am_tools->memmove( + saved_MAC, + p_aka_payloads->get_MAC()->get_data(p_aka_payloads->get_MAC()->get_data_length()), + p_aka_payloads->get_MAC()->get_data_length()); + + m_am_tools->memset( + p_aka_payloads->get_MAC()->get_data(p_aka_payloads->get_MAC()->get_data_length()), + 0, + p_aka_payloads->get_MAC()->get_data_length()); + + + eap_status_e status = hmac_sha1.hmac_update( + aka_packet->get_header_buffer(aka_packet_length), + aka_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = extra_message_authentication_code_bytes( + aka_packet->get_subtype(), + aka_packet->get_code(), + &hmac_sha1); + if (status != eap_status_ok) + { + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: %s=%d check_message_authentication_code(): extra_message_authentication_code_bytes().\n"), + status_string.get_status_string(status), status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + + eap_variable_data_c *end_of_authentication = 0; + if (p_aka_payloads->get_MAC()->get_payload_included() == true) + { + end_of_authentication = p_aka_payloads->get_MAC()->get_payload_buffer(); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + + u32_t length = 0u; + + eap_variable_data_c tmp_MAC(m_am_tools); + + if (tmp_MAC.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tmp_MAC.init(EAP_TYPE_AKA_MAC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + tmp_MAC.set_is_valid(); + tmp_MAC.set_data_length(EAP_TYPE_AKA_MAC_SIZE); + + u8_t * const mac_data = tmp_MAC.get_data_offset(0u, EAP_TYPE_AKA_MAC_SIZE); + if (mac_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = hmac_sha1.hmac_128_final( + mac_data, + &length); + if (status != eap_status_ok + || length != EAP_TYPE_AKA_MAC_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT(length == EAP_TYPE_AKA_MAC_SIZE); + + + +#if defined(USE_EAP_TRACE) + { + eap_variable_data_c buffer(m_am_tools); + + if (buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = buffer.set_buffer_length(2048); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = buffer.set_buffer_length(buffer.get_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const tmpbuffer = buffer.get_data(buffer.get_data_length()); + if (tmpbuffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t offset = 0; + + m_am_tools->memmove(tmpbuffer+offset, + aka_packet->get_header_buffer(aka_packet_length), + aka_packet_length); + offset += aka_packet_length; + + if (aka_packet->get_code() == eap_code_request) + { + } + else if (aka_packet->get_code() == eap_code_response) + { + if (aka_packet->get_subtype() == aka_subtype_Re_authentication) + { + m_am_tools->memmove(tmpbuffer+offset, + get_NONCE_S()->get_data(get_NONCE_S()->get_data_length()), + get_NONCE_S()->get_data_length()); + offset += get_NONCE_S()->get_data_length(); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: extra_message_authentication_code_bytes(): unsupported EAP-Code %d.\n"), + aka_packet->get_code())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("check_message_authentication_code(): MAC calculated over the following bytes:\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("MAC data"), + tmpbuffer, + offset)); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("MAC:\n"))); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("MAC"), + tmp_MAC.get_data(tmp_MAC.get_data_length()), + tmp_MAC.get_data_length())); + } +#endif // #if defined(USE_EAP_TRACE) + + + if (length != end_of_authentication->get_data_length() + || tmp_MAC.get_data_length() + != end_of_authentication->get_data_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO|TRACE_FLAGS_AKA_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: MAC differs.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + if (m_am_tools->memcmp( + tmp_MAC.get_data(tmp_MAC.get_data_length()), + saved_MAC, + tmp_MAC.get_data_length()) != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO|TRACE_FLAGS_AKA_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: MAC differs.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("MAC OK.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::timer_expired( + const u32_t id, void *data) +{ + EAP_UNREFERENCED_PARAMETER(id); + EAP_UNREFERENCED_PARAMETER(data); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_type_aka_c::timer_expired(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + + eap_status_e status = eap_status_process_general_error; + + if (id == EAP_TYPE_AKA_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID elapsed.\n"), + (m_is_client == true) ? "client": "server")); + + if (get_state() == eap_type_aka_state_failure) + { + // Athentication is already failed. + + // We set the session timeout to zero. + // This will terminate this session immediately. + status = get_type_partner()->set_session_timeout(0ul); + } + else + { + status = handle_error_packet(); + } + } + else if (id == EAP_TYPE_AKA_TIMER_DELAY_NOTIFICATION_MESSAGE_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID elapsed.\n"), + (m_is_client == true) ? "client": "server")); + + status = handle_notification_packet(); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::timer_delete_data( + const u32_t id, void *data) +{ + EAP_UNREFERENCED_PARAMETER(id); + EAP_UNREFERENCED_PARAMETER(data); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_type_aka_c::timer_delete_data(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + + if (id == EAP_TYPE_AKA_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID delete data.\n"), + (m_is_client == true) ? "client": "server")); + } + else if (id == EAP_TYPE_AKA_TIMER_DELAY_NOTIFICATION_MESSAGE_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID delete data.\n"), + (m_is_client == true) ? "client": "server")); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::packet_send().\n"))); + + eap_header_wr_c eap( + m_am_tools, + sent_packet->get_data_offset( + header_offset, data_length), + data_length); + if (eap.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + EAP_AKA_PACKET_TRACE( + EAPL("<-"), + network_id, + &eap, + data_length); + + eap_status_e status = get_type_partner()->packet_send( + network_id, + sent_packet, + header_offset, + data_length, + buffer_length + ); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE this will be read from AM of AKA EAP-type. + const eap_status_e status = m_am_type_aka->type_configure_read(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE this will be written to AM of AKA EAP-type. + const eap_status_e status = m_am_type_aka->type_configure_write(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in eap_base_type_c::configure(). +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::configure(): this = 0x%08x => 0x%08x\n"), + this, + dynamic_cast(this))); + + eap_status_e status(eap_status_process_general_error); + + + // This must be configured first. + status = m_am_type_aka->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + //---------------------------------------------------------- + + { + eap_variable_data_c error_message_delay_time(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_failure_message_delay_time.get_field(), + &error_message_delay_time); + if (status == eap_status_ok + && error_message_delay_time.get_is_valid_data() == true + && error_message_delay_time.get_data_length() == sizeof(u32_t) + && error_message_delay_time.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + m_failure_message_delay_time = *reinterpret_cast( + error_message_delay_time.get_data(sizeof(u32_t))); + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_manual_realm(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_use_manual_realm.get_field(), + &use_manual_realm); + if (status == eap_status_ok + && use_manual_realm.get_is_valid_data() == true + && use_manual_realm.get_data_length() == sizeof(u32_t)) + { + u32_t *flag = reinterpret_cast( + use_manual_realm.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_use_manual_realm = false; + } + else + { + m_use_manual_realm = true; + } + } + } + } + + //---------------------------------------------------------- + + { + status = read_configure( + cf_str_EAP_AKA_manual_realm.get_field(), + get_nai_realm()); + if (status == eap_status_ok + && get_nai_realm()->get_is_valid_data() == true) + { + // OK NAI realm is configured. + } + else + { + // No configured NAI realm. + // We will use automatic realm "wlan.mnc456.mcc123.3gppnetwork.org" as a realm. + // Look at eap_type_aka_c::generate_nai(). + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c wait_eap_success_packet(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_wait_eap_success_packet.get_field(), + &wait_eap_success_packet); + + if (status == eap_status_ok + && wait_eap_success_packet.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast( + wait_eap_success_packet.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_wait_eap_success_packet = false; + } + else + { + m_wait_eap_success_packet = true; + } + } + } + + if (get_type_partner()->get_is_tunneled_eap() == true) + { + // Inside the PEAP we must wait EAP-Success to fullfill the state machine of PEAP. + m_wait_eap_success_packet = true; + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c check_identifier_of_eap_identity_response(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_check_identifier_of_eap_identity_response.get_field(), + &check_identifier_of_eap_identity_response); + + if (status == eap_status_ok + && check_identifier_of_eap_identity_response.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast( + check_identifier_of_eap_identity_response.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_check_identifier_of_eap_identity_response = false; + } + else + { + m_check_identifier_of_eap_identity_response = true; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_AKA_check_nai_realm(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_check_nai_realm.get_field(), + &EAP_AKA_check_nai_realm); + if (status == eap_status_ok + && EAP_AKA_check_nai_realm.get_is_valid_data() == true) + { + u32_t *check_nai_realm = reinterpret_cast( + EAP_AKA_check_nai_realm.get_data(sizeof(u32_t))); + if (check_nai_realm != 0 + && *check_nai_realm != 0) + { + m_check_nai_realm = true; + } + } + } + + //---------------------------------------------------------- + + { + status = read_configure( + cf_str_EAP_AKA_nonce_mt_file.get_field(), + &m_nonce_mt_file); + if (status == eap_status_ok + && m_nonce_mt_file.get_is_valid_data() == true + && m_nonce_mt_file.get_data_length() != 0 + && m_nonce_mt_file.get_data(m_nonce_mt_file.get_data_length()) != 0) + { + // This is optional value. + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_AKA_client_responds_retransmitted_packets(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_client_responds_retransmitted_packets.get_field(), + &EAP_AKA_client_responds_retransmitted_packets); + if (status == eap_status_ok + && EAP_AKA_client_responds_retransmitted_packets.get_is_valid_data() == true + && EAP_AKA_client_responds_retransmitted_packets.get_data_length() == sizeof(u32_t) + && EAP_AKA_client_responds_retransmitted_packets.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + EAP_AKA_client_responds_retransmitted_packets.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_client_responds_retransmitted_packets = false; + } + else + { + m_client_responds_retransmitted_packets = true; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c test_version(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_test_version.get_field(), + &test_version); + if (status == eap_status_ok + && test_version.get_is_valid_data() == true + && test_version.get_data_length() == sizeof(u32_t) + && test_version.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(test_version.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_aka_test_version = false; + } + else + { + m_aka_test_version = true; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c randomly_refuse_eap_identity(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_randomly_refuse_eap_identity.get_field(), + &randomly_refuse_eap_identity); + if (status == eap_status_ok + && randomly_refuse_eap_identity.get_is_valid_data() == true + && randomly_refuse_eap_identity.get_data_length() == sizeof(u32_t) + && randomly_refuse_eap_identity.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + randomly_refuse_eap_identity.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_aka_randomly_refuse_eap_identity = false; + } + else + { + m_aka_randomly_refuse_eap_identity = true; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_manual_username(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_use_manual_username.get_field(), + &use_manual_username); + if (status == eap_status_ok + && use_manual_username.get_is_valid_data() == true) + { + u32_t *use_manual_username_flag = reinterpret_cast( + use_manual_username.get_data(sizeof(u32_t))); + if (use_manual_username_flag != 0 + && *use_manual_username_flag != 0) + { + m_use_manual_username = true; + } + } + } + + //---------------------------------------------------------- + + if (m_use_manual_username == true) + { + status = read_configure( + cf_str_EAP_AKA_manual_username.get_field(), + &m_manual_username); + if (status == eap_status_ok + && m_manual_username.get_is_valid_data() == true) + { + // This is optional value. + } + else + { + // No username defined. + m_use_manual_username = false; + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c fail_re_authentication_counter_check(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_fail_re_authentication_counter_check.get_field(), + &fail_re_authentication_counter_check); + if (status == eap_status_ok + && fail_re_authentication_counter_check.get_is_valid_data() == true + && fail_re_authentication_counter_check.get_data_length() == sizeof(u32_t) + && fail_re_authentication_counter_check.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + fail_re_authentication_counter_check.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_fail_reauthentication_counter_check = false; + } + else + { + m_fail_reauthentication_counter_check = true; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c accept_eap_identity_response(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_accept_eap_identity_response.get_field(), + &accept_eap_identity_response); + if (status == eap_status_ok + && accept_eap_identity_response.get_is_valid_data() == true + && accept_eap_identity_response.get_data_length() == sizeof(u32_t) + && accept_eap_identity_response.get_data( + accept_eap_identity_response.get_data_length()) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + accept_eap_identity_response.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag != 0) + { + m_accept_eap_identity_response = true; + } + else if (*flag == 0) + { + m_accept_eap_identity_response = false; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_random_identity_on_eap_identity_response(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_use_random_identity_on_eap_identity_response.get_field(), + &use_random_identity_on_eap_identity_response); + if (status == eap_status_ok + && use_random_identity_on_eap_identity_response.get_is_valid_data() == true + && use_random_identity_on_eap_identity_response.get_data_length() == sizeof(u32_t) + && use_random_identity_on_eap_identity_response.get_data( + use_random_identity_on_eap_identity_response.get_data_length()) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + use_random_identity_on_eap_identity_response.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag != 0) + { + m_use_random_identity_on_eap_identity_response = true; + } + else if (*flag == 0) + { + m_use_random_identity_on_eap_identity_response = false; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_pseudonym_identity(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_use_pseudonym_identity.get_field(), + &use_pseudonym_identity); + if (status == eap_status_ok + && use_pseudonym_identity.get_is_valid_data() == true + && use_pseudonym_identity.get_data_length() == sizeof(u32_t) + && use_pseudonym_identity.get_data(use_pseudonym_identity.get_data_length()) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(use_pseudonym_identity.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag != 0) + { + m_use_pseudonym_identity = true; + } + else if (*flag == 0) + { + m_use_pseudonym_identity = false; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_reauthentication_identity(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_use_reauthentication_identity.get_field(), + &use_reauthentication_identity); + if (status == eap_status_ok + && use_reauthentication_identity.get_is_valid_data() == true + && use_reauthentication_identity.get_data_length() == sizeof(u32_t) + && use_reauthentication_identity.get_data( + use_reauthentication_identity.get_data_length()) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + use_reauthentication_identity.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag != 0) + { + m_use_reauthentication_identity = true; + } + else if (*flag == 0) + { + m_use_reauthentication_identity = false; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c randomly_fail_successfull_authentication(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_randomly_fail_successfull_authentication.get_field(), + &randomly_fail_successfull_authentication); + if (status == eap_status_ok + && randomly_fail_successfull_authentication.get_is_valid_data() == true + && randomly_fail_successfull_authentication.get_data_length() == sizeof(u32_t) + && randomly_fail_successfull_authentication.get_data( + randomly_fail_successfull_authentication.get_data_length()) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + randomly_fail_successfull_authentication.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag != 0) + { + m_randomly_fail_successfull_authentication = true; + } + else + { + m_randomly_fail_successfull_authentication = false; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c allow_use_result_indication(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_allow_use_result_indication.get_field(), + &allow_use_result_indication); + if (status == eap_status_ok + && allow_use_result_indication.get_is_valid_data() == true + && allow_use_result_indication.get_data_length() == sizeof(u32_t) + && allow_use_result_indication.get_data( + allow_use_result_indication.get_data_length()) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + allow_use_result_indication.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag != 0) + { + m_allow_use_result_indication = true; + } + else + { + m_allow_use_result_indication = false; + } + } + } + } + + if (m_is_client == false) + { + eap_variable_data_c server_allow_use_result_indication(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_server_allow_use_result_indication.get_field(), + &server_allow_use_result_indication); + if (status == eap_status_ok + && server_allow_use_result_indication.get_is_valid_data() == true + && server_allow_use_result_indication.get_data_length() == sizeof(u32_t) + && server_allow_use_result_indication.get_data( + server_allow_use_result_indication.get_data_length()) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + server_allow_use_result_indication.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag != 0) + { + m_allow_use_result_indication = true; + } + else + { + m_allow_use_result_indication = false; + } + } + } + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_EXPANDED_TYPES) + { + eap_variable_data_c use_eap_expanded_type(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_AKA_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + + if (status != eap_status_ok) + { + status = read_configure( + cf_str_EAP_CORE_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + } + + if (status == eap_status_ok + && use_eap_expanded_type.get_data_length() == sizeof(u32_t) + && use_eap_expanded_type.get_data() != 0) + { + u32_t *flag = reinterpret_cast(use_eap_expanded_type.get_data(use_eap_expanded_type.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_use_eap_expanded_type = true; + } + else + { + m_use_eap_expanded_type = false; + } + } + } + } +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + //---------------------------------------------------------- + + { + (void) read_configure( + cf_str_EAP_AKA_2_digit_mnc_map_of_mcc_of_imsi_array.get_field(), + &m_2_digit_mnc_map_of_mcc_of_imsi_array); + // This is optional value. + } + + { + eap_variable_data_c use_uma_profile(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_AKA_UMA_profile.get_field(), + &use_uma_profile); + if (status == eap_status_ok + && use_uma_profile.get_is_valid_data() == true + && use_uma_profile.get_data_length() == sizeof(u32_t)) + { + u32_t *flag = reinterpret_cast(use_uma_profile.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_use_uma_profile = false; + } + else + { + m_use_uma_profile = true; + } + } + } + } + + if (m_use_uma_profile == true) + { + (void) read_configure( + cf_str_EAP_AKA_UMA_realm_prefix.get_field(), + &m_uma_automatic_realm_prefix); + // m_uma_automatic_realm_prefix is optional. + + // In the UMA we must wait EAP-Success to fullfill the state machine of mVPN. + m_wait_eap_success_packet = true; + } + else + { + eap_variable_data_c wait_eap_success_packet(m_am_tools); + + status = read_configure( + cf_str_EAP_AKA_wait_eap_success_packet.get_field(), + &wait_eap_success_packet); + + if (status == eap_status_ok + && wait_eap_success_packet.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast(wait_eap_success_packet.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_wait_eap_success_packet = false; + } + else + { + m_wait_eap_success_packet = true; + } + } + } + + if (get_type_partner()->get_is_tunneled_eap() == true) + { + // Inside the PEAP we must wait EAP-Success to fullfill the state machine of PEAP. + m_wait_eap_success_packet = true; + } + } + + //---------------------------------------------------------- + + m_aka_header_offset = get_type_partner()->get_header_offset( + &m_MTU, &m_trailer_length); + + if (m_aka_header_offset+m_MTU+m_trailer_length > EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH) + { + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + >= (m_aka_header_offset+m_trailer_length)); + + m_MTU = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH - (m_aka_header_offset+m_trailer_length); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// This is commented in eap_base_type_c::shutdown(). +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::shutdown(): this = 0x%08x => 0x%08x\n"), + this, + dynamic_cast(this))); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + cancel_error_message_delay_timer(); + cancel_notification_message_delay_timer(); + + if (m_am_type_aka != 0) + { + // We must cancel the pending query. + if (get_state() == eap_type_aka_state_pending_identity_query) + { + (void) m_am_type_aka->cancel_AKA_IMSI_or_pseudonym_or_reauthentication_id_query(); + } + else if (get_state() == eap_type_aka_state_pending_kc_sres_query) + { + (void) m_am_type_aka->cancel_AKA_RES_query(); + } + else if (get_state() == eap_type_aka_state_pending_pseudonym_decode_query) + { + (void) m_am_type_aka->cancel_imsi_from_username_query(); + } + else if (get_state() == eap_type_aka_state_pending_authentication_vector_query) + { + (void) m_am_type_aka->cancel_AKA_authentication_vector_query(); + } + + send_final_notification(); + } + + reset(); + + eap_status_e status(eap_status_ok); + if (m_am_type_aka != 0) + { + status = m_am_type_aka->shutdown(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This function is to allow reuse of this object. +// The whole object state must be reset. +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("AKA: %s: function: eap_type_aka_c::reset(): this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + eap_status_e status = eap_status_not_supported; + + m_reset_was_called = true; + + m_use_result_indication = false; + m_authentication_type = AKA_AUTHENTICATION_TYPE_NONE; + set_identity_type(AKA_IDENTITY_TYPE_NONE); + + + { + cancel_error_message_delay_timer(); + m_client_error_code = eap_aka_client_error_code_none; + m_erroneus_packet_received = false; + + cancel_notification_message_delay_timer(); + m_aka_notification_code = eap_aka_notification_none; + m_aka_notification_packet_received = false; + + if (m_authentication_vector != 0) + { + delete m_authentication_vector; + m_authentication_vector = 0; + } + + m_state = eap_type_aka_state_none; + + m_nonce_s.reset(); + m_IV.get_payload_buffer()->reset(); + m_saved_EAP_packet.reset(); + m_XKEY.reset(); + m_K_encr.reset(); + m_K_aut.reset(); + m_master_session_key.reset(); + m_automatic_realm.reset(); + m_automatic_realm_read = false; + m_IMSI.reset(); + m_pseudonym.reset(); + m_reauthentication_identity.reset(); + m_identity.reset(); + m_NAI.reset(); + m_RAND.reset(); + m_AUTN.reset(); + m_RES.reset(); + } + + status = checkcode_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_am_type_aka->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = get_type_partner()->set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = get_type_partner()->cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = get_type_partner()->cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_type_aka_state_variable_parameters_c * eap_type_aka_c::get_state_variable() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (get_state() < eap_type_aka_state_last_value) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &(m_parameters[get_state()]); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::check_valid_state(aka_subtype_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + const eap_type_aka_state_variable_parameters_c * const state_variable = get_state_variable(); + + if (state_variable == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_gsmsim_state); + } + + if (state_variable->check_initiator(!get_is_client()) == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::check_valid_state(): Initiator type %d is wrong in eap_type_aka_state_variable_e %d=%s.\n"), + get_is_client(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_gsmsim_state); + } + + if (state_variable->check_valid_types(type) == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::check_valid_state(): aka_subtype_e %d is wrong in eap_type_aka_state_variable_e %d=%s.\n"), + type, + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_subtype); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::store_identity( + const eap_variable_data_c * const IMSI_or_pseudonym, + const bool IMSI_is_used) +{ + eap_status_e status = get_identity()->init(IMSI_or_pseudonym->get_data_length()+1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + get_identity()->set_is_valid(); + + if (IMSI_is_used == true) + { + // Note the first octet is reserved for IMSI prefix. + status = get_identity()->set_copy_of_buffer(AKA_IMSI_PREFIX_CHARACTER, 1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = get_identity()->add_data(IMSI_or_pseudonym); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +/// not used: expansion_0 = prf(key, seed | 0) +/// not used: expansion_i = prf(key, expansion_i-1 | seed | i), where i = 1, 2... + +/// The following is from "DIGITAL SIGNATURE STANDARD (DSS)" FIPS PUB 186-2: +/// Let x be the signer's private key. The following may be used to generate m values of x: +/// Step 1. Choose a new, secret value for the seed-key, XKEY. +/// Step 2. In hexadecimal notation let +/// t = 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0. +/// This is the initial value for H0 || H1 || H2 || H3 || H4 in the SHS. +/// Step 3. For j = 0 to m - 1 do +/// a. XSEEDj = optional user input. +/// b. XVAL = (XKEY + XSEEDj) mod 2^b. +/// c. xj = G(t,XVAL) mod q. +/// d. XKEY = (1 + XKEY + xj) mod 2^b. +/// +/// Within AKA the following parameters are used: +/// 160-bit XKEY and XVAL values are used, so b = 160. +/// XKEY = SHA1(n*Kc| NONCE_MT) +/// The optional user input values (XSEED_j) are set to zero. +/// xj = G(t, XVAL) + +/// Random generator become as follows: +/// Step 1. Choose a new, secret value for the seed-key, XKEY. +/// Step 2. In hexadecimal notation let +/// t = 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0. +/// This is the initial value for H0 || H1 || H2 || H3 || H4 in the SHS. +/// Step 3. For j = 0 to m - 1 do +/// c. xj = G(t,XKEY). +/// d. XKEY = (1 + XKEY + xj) mod 2^b. + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::data_exp( + const u32_t data_length, + eap_variable_data_c * const expansion, + const eap_variable_data_c * const key, + const eap_variable_data_c * const seed) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_UNREFERENCED_PARAMETER(seed); + + u32_t count = data_length/EAP_TYPE_AKA_KEYMAT_SIZE; + if ((data_length % EAP_TYPE_AKA_KEYMAT_SIZE) != 0) + { + ++count; + } + + status = expansion->init(count*EAP_TYPE_AKA_KEYMAT_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + expansion->set_is_valid(); + + status = expansion->set_data_length(count*EAP_TYPE_AKA_KEYMAT_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_am_tools->get_crypto()->dss_pseudo_random( + expansion->get_data(expansion->get_data_length()), + expansion->get_data_length(), + key->get_data(key->get_data_length()), + key->get_data_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::generate_shared_secred_keys( + const u32_t key_length, + const eap_variable_data_c * const CK, + const eap_variable_data_c * const IK, + eap_variable_data_c * const XKEY, + eap_variable_data_c * const K_encr, + eap_variable_data_c * const K_aut, + eap_variable_data_c * const master_session_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("generate_shared_secred_keys():\n"))); + + if (get_NAI()->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("full auth NAI"), + get_NAI()->get_data(get_NAI()->get_data_length()), + get_NAI()->get_data_length())); + + if (IK->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("IK"), + IK->get_data(IK->get_data_length()), + IK->get_data_length())); + + if (CK->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("CK"), + CK->get_data(CK->get_data_length()), + CK->get_data_length())); + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + // XKEY = SHA1(NAI | IK | CK) + + crypto_sha1_c sha1(m_am_tools); + + if (sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (sha1.hash_init() != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: generate_shared_secred_keys(): init() failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = sha1.hash_update( + get_NAI()->get_data(get_NAI()->get_data_length()), + get_NAI()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + IK->get_data(IK->get_data_length()), + IK->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + CK->get_data(CK->get_data_length()), + CK->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = XKEY->init(key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + XKEY->set_is_valid(); + XKEY->set_data_length(key_length); + + u32_t md_length = key_length; + + status = sha1.hash_final( + XKEY->get_data_offset(0u, key_length), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT_ALWAYS(md_length == key_length); + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_shared_secred_keys(): XKEY\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL(" XKEY"), + XKEY->get_data(XKEY->get_data_length()), + XKEY->get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aes_key_length = m_am_tools->get_crypto()->aes_key_length(); + u32_t data_length = aes_key_length + EAP_TYPE_AKA_MAC_SIZE + EAP_TYPE_AKA_MASTER_SESSION_KEY_SIZE; + + eap_variable_data_c expansion(m_am_tools); + eap_variable_data_c seed(m_am_tools); + + if (expansion.get_is_valid() == false + || seed.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = seed.add_data(get_NAI()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = data_exp( + data_length, + &expansion, + XKEY, + &seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_shared_secred_keys(): expansion\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("expansion"), + expansion.get_data(expansion.get_data_length()), + expansion.get_data_length())); + + u8_t *data = expansion.get_data_offset(0u, data_length); + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + const u8_t * const data_begin = data; + + EAP_UNREFERENCED_PARAMETER(data_begin); + + // K_encr, K_aut and master_session_key + + status = K_encr->set_copy_of_buffer(data, aes_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + data += aes_key_length; + EAP_ASSERT_ALWAYS(static_cast(data-data_begin) <= data_length); + + status = K_aut->set_copy_of_buffer(data, EAP_TYPE_AKA_MAC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + data += EAP_TYPE_AKA_MAC_SIZE; + EAP_ASSERT_ALWAYS(static_cast(data-data_begin) <= data_length); + + status = master_session_key->set_copy_of_buffer(data, EAP_TYPE_AKA_MASTER_SESSION_KEY_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + data += EAP_TYPE_AKA_MASTER_SESSION_KEY_SIZE; + EAP_ASSERT_ALWAYS(static_cast(data-data_begin) <= data_length); + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_shared_secred_keys(): K_encr\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL(" K_encr"), + K_encr->get_data(K_encr->get_data_length()), + K_encr->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_shared_secred_keys(): K_aut\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL(" K_aut"), + K_aut->get_data(K_aut->get_data_length()), + K_aut->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_shared_secred_keys(): master_session_key\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL(" MSK+EMSK"), + master_session_key->get_data(master_session_key->get_data_length()), + master_session_key->get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::generate_reauth_shared_secred_keys( + const u32_t key_length, + const eap_variable_data_c * const orig_XKEY, + const u32_t reauth_counter, + const eap_variable_data_c * const reauth_identity, + const eap_variable_data_c * const reauth_nonce_s, + eap_variable_data_c * const master_session_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + u16_t counter = eap_htons(static_cast(reauth_counter)); + + eap_variable_data_c reauth_XKEY(m_am_tools); + + if (reauth_XKEY.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("generate_reauth_shared_secred_keys():\n"))); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("reauth NAI"), + reauth_identity->get_data(reauth_identity->get_data_length()), + reauth_identity->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("reauth_counter"), + &counter, + sizeof(counter))); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("NONCE_S"), + reauth_nonce_s->get_data(reauth_nonce_s->get_data_length()), + reauth_nonce_s->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("orig_XKEY"), + orig_XKEY->get_data(orig_XKEY->get_data_length()), + orig_XKEY->get_data_length())); + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + // XKEY = SHA1(Identity|counter|NONCE_S|original XKEY) + + crypto_sha1_c sha1(m_am_tools); + + if (sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (sha1.hash_init() != eap_status_ok) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_AKA_ERROR, (EAPL("ERROR: generate_reauth_shared_secred_keys(): init() failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = sha1.hash_update( + reauth_identity->get_data(reauth_identity->get_data_length()), + reauth_identity->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + &counter, + sizeof(counter)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + reauth_nonce_s->get_data(reauth_nonce_s->get_data_length()), + reauth_nonce_s->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + orig_XKEY->get_data(orig_XKEY->get_data_length()), + orig_XKEY->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = reauth_XKEY.init(key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + reauth_XKEY.set_is_valid(); + reauth_XKEY.set_data_length(key_length); + + u32_t md_length = key_length; + + status = sha1.hash_final( + reauth_XKEY.get_data_offset(0u, key_length), + &md_length); + + EAP_ASSERT_ALWAYS(md_length == key_length); + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_reauth_shared_secred_keys(): reauth_XKEY\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("reauth_XKEY"), + reauth_XKEY.get_data(reauth_XKEY.get_data_length()), + reauth_XKEY.get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aes_key_length = m_am_tools->get_crypto()->aes_key_length(); + u32_t data_length = aes_key_length + EAP_TYPE_AKA_MAC_SIZE + EAP_TYPE_AKA_MASTER_SESSION_KEY_SIZE; + + eap_variable_data_c expansion(m_am_tools); + eap_variable_data_c seed(m_am_tools); + + if (expansion.get_is_valid() == false + || seed.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = seed.add_data(get_NAI()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = data_exp( + data_length, + &expansion, + &reauth_XKEY, + &seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("generate_reauth_shared_secred_keys(): expansion\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("expansion"), + expansion.get_data(expansion.get_data_length()), + expansion.get_data_length())); + + u8_t *data = expansion.get_data_offset(0u, data_length); + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + const u8_t * const data_begin = data; + + EAP_UNREFERENCED_PARAMETER(data_begin); + + // Only master_session_key is used in re-authentication. + + status = master_session_key->set_copy_of_buffer(data, EAP_TYPE_AKA_MASTER_SESSION_KEY_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + data += EAP_TYPE_AKA_MASTER_SESSION_KEY_SIZE; + EAP_ASSERT_ALWAYS(static_cast(data-data_begin) <= data_length); + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_reauth_shared_secred_keys(): master_session_key\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL(" MSK+EMSK"), + master_session_key->get_data(master_session_key->get_data_length()), + master_session_key->get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_type_aka_c::delete_unused_keys() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_aka_c::get_identity_string(const eap_type_aka_identity_type identity_type) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(identity_type, AKA_IDENTITY_TYPE_NONE) + else EAP_IF_RETURN_STRING(identity_type, AKA_IDENTITY_TYPE_IMSI_ID) + else EAP_IF_RETURN_STRING(identity_type, AKA_IDENTITY_TYPE_PSEUDONYM_ID) + else EAP_IF_RETURN_STRING(identity_type, AKA_IDENTITY_TYPE_RE_AUTH_ID) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(identity_type); + return EAPL("Unknown AKA identity"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_aka_c::get_state_string(eap_type_aka_state_variable_e state) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_identity_request) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_pending_identity_query) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_aka_identity_request) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_imsi_waiting_for_aka_identity_request) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_pseydonym_waiting_for_aka_identity_request) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_analyse_aka_identity_request) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_challenge_request) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_analyses_challenge_request) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_pending_kc_sres_query) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_success) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_reauth_request) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_analyses_reauthentication_request) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_pending_pseudonym_decode_query) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_identity_response) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_aka_identity_response_with_at_full_auth_identity) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_aka_identity_response) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_challenge_response) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_pending_authentication_vector_query) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_analyses_challenge_response) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_analyses_aka_identity_response) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_notification_request_success) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_notification_response_failure) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_notification_response_success) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_waiting_for_reauth_response) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_analyses_reauthentication_response) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_success) + else EAP_IF_RETURN_STRING(state, eap_type_aka_state_failure) + else +#else +EAP_UNREFERENCED_PARAMETER(state); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown AKA state"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_aka_c::get_state_string() const +{ + return get_state_string(m_state); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_aka_c::get_saved_previous_state_string() const +{ + return get_state_string(m_saved_previous_state); +} + +//-------------------------------------------------- + +bool eap_type_aka_c::get_aka_notification_code_F_bit(const eap_aka_notification_codes_e notification_code) +{ + return ((notification_code & aka_notification_code_bit_f) != 0); +} + +//-------------------------------------------------- + +bool eap_type_aka_c::get_aka_notification_code_P_bit(const eap_aka_notification_codes_e notification_code) +{ + return ((notification_code & aka_notification_code_bit_p) != 0); +} + +//-------------------------------------------------- + +void eap_type_aka_c::object_increase_reference_count() +{ +} + +//-------------------------------------------------- + +u32_t eap_type_aka_c::object_decrease_reference_count() +{ + return 0u; +} + +//-------------------------------------------------- + +void eap_type_aka_c::set_authentication_vector(eap_type_aka_authentication_vector_c * const authentication_vector) +{ + if (m_authentication_vector != 0) + { + delete m_authentication_vector; + m_authentication_vector = 0; + } + m_authentication_vector = authentication_vector; +} + +//-------------------------------------------------- + +void eap_type_aka_c::set_reauthentication_counter(const u32_t reauthentication_counter) +{ + m_reauthentication_counter = reauthentication_counter; +} + +//-------------------------------------------------- + +u32_t eap_type_aka_c::get_reauthentication_counter() +{ + return m_reauthentication_counter; +} + +//-------------------------------------------------- + +eap_type_aka_authentication_vector_c * eap_type_aka_c::get_authentication_vector() +{ + return m_authentication_vector; +} + +//-------------------------------------------------- + +const eap_variable_data_c * eap_type_aka_c::get_RAND() const +{ + return &m_RAND; +} + +//-------------------------------------------------- + +eap_status_e eap_type_aka_c::set_RAND(const eap_variable_data_c * const RAND) +{ + return m_RAND.set_copy_of_buffer(RAND); +} + +//-------------------------------------------------- + +const eap_variable_data_c * eap_type_aka_c::get_AUTN() const +{ + return &m_AUTN; +} + +//-------------------------------------------------- + +eap_status_e eap_type_aka_c::set_AUTN(const eap_variable_data_c * const AUTN) +{ + return m_AUTN.set_copy_of_buffer(AUTN); +} + +//-------------------------------------------------- + +void eap_type_aka_c::set_last_eap_identifier(const u8_t last_eap_identifier) +{ + m_last_eap_identifier = last_eap_identifier; +} + +//-------------------------------------------------- + +u8_t eap_type_aka_c::get_last_eap_identifier() +{ + return m_last_eap_identifier; +} + +//-------------------------------------------------- + +void eap_type_aka_c::set_include_identity_to_aka_identity_response(const aka_payload_AT_type_e id_type_required) +{ + m_include_identity_to_aka_identity_response = id_type_required; +} + +//-------------------------------------------------- + +aka_payload_AT_type_e eap_type_aka_c::get_include_identity_to_aka_identity_response() +{ + return m_include_identity_to_aka_identity_response; +} + +//-------------------------------------------------- + +void eap_type_aka_c::set_aka_identity_response_includes_identity(const aka_payload_AT_type_e id_type_required) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_AKA: %s: eap_type_aka_c::set_aka_identity_response_includes_identity(): %d=%s\n"), + (m_is_client == true ? "client": "server"), + id_type_required, + aka_payload_AT_header_c::get_payload_AT_string(id_type_required))); + + m_aka_identity_response_includes_identity = id_type_required; +} + +//-------------------------------------------------- + +aka_payload_AT_type_e eap_type_aka_c::get_aka_identity_response_includes_identity() +{ + return m_aka_identity_response_includes_identity; +} + +//-------------------------------------------------- + +void eap_type_aka_c::set_failure_message_received() +{ + m_failure_message_received = true; +} + +//-------------------------------------------------- + +void eap_type_aka_c::unset_failure_message_received() +{ + m_failure_message_received = false; +} + +//-------------------------------------------------- + +bool eap_type_aka_c::get_failure_message_received() +{ + return m_failure_message_received; +} + +//-------------------------------------------------- + +eap_type_aka_state_variable_e eap_type_aka_c::get_state() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_state; +} + +//-------------------------------------------------- + +eap_type_aka_state_variable_e eap_type_aka_c::get_saved_previous_state() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_saved_previous_state; +} + +//-------------------------------------------------- + +void eap_type_aka_c::save_current_state() +{ + m_saved_previous_state = m_state; +} + +//-------------------------------------------------- + +void eap_type_aka_c::restore_saved_previous_state() +{ + set_state(m_saved_previous_state); +} + +//-------------------------------------------------- + +eap_am_network_id_c * eap_type_aka_c::get_send_network_id() +{ + return &m_send_network_id; +} + +//-------------------------------------------------- + +void eap_type_aka_c::set_authentication_finished_successfully() +{ + m_authentication_finished_successfully = true; +} + +//-------------------------------------------------- + +bool eap_type_aka_c::get_authentication_finished_successfully() +{ + return m_authentication_finished_successfully; +} + +//-------------------------------------------------- + +void eap_type_aka_c::set_state(eap_type_aka_state_variable_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_type_aka_state_variable_e previous_state = m_state; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::set_state(): old state %d=%s\n"), + get_state(), + get_state_string())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::set_state(): new state %d=%s\n"), + state, + get_state_string(state))); + + m_state = state; + + eap_type_aka_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap_type, + eap_type_aka, + previous_state, + state, + m_last_eap_identifier, + false); + state_notification(¬ification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +eap_variable_data_c * eap_type_aka_c::get_NONCE_S() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_nonce_s; +} + +//-------------------------------------------------- + +eap_variable_data_c * eap_type_aka_c::get_IMSI() +{ + return &m_IMSI; +} + +//-------------------------------------------------- + +eap_variable_data_c * eap_type_aka_c::get_identity() +{ + return &m_identity; +} + +//-------------------------------------------------- + +eap_variable_data_c * eap_type_aka_c::get_NAI() +{ + return &m_NAI; +} + +//-------------------------------------------------- + +eap_variable_data_c * eap_type_aka_c::get_RES() +{ + return &m_RES; +} + +//-------------------------------------------------- + +eap_variable_data_c * eap_type_aka_c::get_pseudonym() +{ + return &m_pseudonym; +} + +//-------------------------------------------------- + +eap_variable_data_c * eap_type_aka_c::get_reauthentication_identity() +{ + return &m_reauthentication_identity; +} + +//-------------------------------------------------- + +aka_variable_data_c * eap_type_aka_c::get_IV() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_IV; +} + +//-------------------------------------------------- + +eap_variable_data_c * eap_type_aka_c::get_saved_EAP_packet() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_saved_EAP_packet; +} + +//-------------------------------------------------- + +eap_variable_data_c * eap_type_aka_c::get_XKEY() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_XKEY; +} + +//-------------------------------------------------- + +eap_variable_data_c * eap_type_aka_c::get_K_encr() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_K_encr; +} + +//-------------------------------------------------- + +eap_variable_data_c * eap_type_aka_c::get_K_aut() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_K_aut; +} + +//-------------------------------------------------- + +eap_master_session_key_c * eap_type_aka_c::get_master_session_key() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_master_session_key; +} + +//-------------------------------------------------- + +eap_status_e eap_type_aka_c::store_last_encryption_iv(const eap_variable_data_c * const encryption_IV) +{ + return m_IV.get_payload_buffer()->set_copy_of_buffer(encryption_IV); +} + +//-------------------------------------------------- + +void eap_type_aka_c::set_identity_type(eap_type_aka_identity_type type) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("GSMSIM: %s: eap_type_aka_c::set_identity_type(): %d=%s\n"), + (m_is_client == true ? "client": "server"), + type, + get_identity_string(type))); + + m_identity_type = type; +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +eap_type_aka_MAC_attributes_c::~eap_type_aka_MAC_attributes_c() +{ +} + +//-------------------------------------------------- + +eap_type_aka_MAC_attributes_c::eap_type_aka_MAC_attributes_c() + : m_MAC(0) + , m_MAC_size(0) + , m_data(0) + , m_data_length(0u) +{ +} + +//-------------------------------------------------- + +eap_type_aka_MAC_attributes_c::eap_type_aka_MAC_attributes_c( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length) + : m_MAC(MAC) + , m_MAC_size(MAC_size) + , m_data(EAP_data) + , m_data_length(EAP_data_length) +{ +} + +//-------------------------------------------------- + +void eap_type_aka_MAC_attributes_c::init( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length) +{ + m_MAC = (MAC); + m_MAC_size = (MAC_size); + m_data = (EAP_data); + m_data_length = (EAP_data_length); +} + +//-------------------------------------------------- + +u8_t * eap_type_aka_MAC_attributes_c::get_MAC() const +{ + return m_MAC; +} + +//-------------------------------------------------- + +void eap_type_aka_MAC_attributes_c::set_MAC(u8_t * MAC) +{ + m_MAC = MAC; +} + +//-------------------------------------------------- + +u32_t eap_type_aka_MAC_attributes_c::get_MAC_size() const +{ + return m_MAC_size; +} + +//-------------------------------------------------- + +eap_type_aka_MAC_attributes_c * eap_type_aka_MAC_attributes_c::copy() const +{ + return new eap_type_aka_MAC_attributes_c( + m_MAC, + m_MAC_size, + m_data, + m_data_length); +} + +//-------------------------------------------------- + +u8_t * eap_type_aka_MAC_attributes_c::get_data() const +{ + return m_data; +} + +//-------------------------------------------------- + +u32_t eap_type_aka_MAC_attributes_c::get_data_length() +{ + return m_data_length; +} + +//-------------------------------------------------- + +void eap_type_aka_MAC_attributes_c::set_data(u8_t * const data) +{ + m_data = data; +} + + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_authentication_vector.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_authentication_vector.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,204 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 65 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_type_aka_authentication_vector.h" +#include "eap_am_tools.h" + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_aka_authentication_vector_c::~eap_type_aka_authentication_vector_c() +{ +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_aka_authentication_vector_c::eap_type_aka_authentication_vector_c( + abs_eap_am_tools_c * const tools + ) + : m_am_tools(tools) + , m_RAND(tools) + , m_AUTN(tools) + , m_RES(tools) + , m_CK(tools) + , m_IK(tools) + , m_AUTS(tools) + , m_vector_status(eap_status_process_general_error) + , m_is_valid(true) +{ +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_aka_authentication_vector_c::get_RAND() const +{ + return const_cast(&m_RAND); +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_aka_authentication_vector_c::get_AUTN() const +{ + return const_cast(&m_AUTN); +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_aka_authentication_vector_c::get_RES() const +{ + return const_cast(&m_RES); +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_aka_authentication_vector_c::get_CK() const +{ + return const_cast(&m_CK); +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_aka_authentication_vector_c::get_IK() const +{ + return const_cast(&m_IK); +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_aka_authentication_vector_c::get_AUTS() const +{ + return const_cast(&m_AUTS); +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_aka_authentication_vector_c * eap_type_aka_authentication_vector_c::copy() const +{ + eap_type_aka_authentication_vector_c * vector = new eap_type_aka_authentication_vector_c(m_am_tools); + if (vector == 0) + { + return 0; + } + + eap_status_e status = eap_status_process_general_error; + + if (get_RAND()->get_is_valid_data() == true) + { + status = vector->get_RAND()->set_copy_of_buffer(get_RAND()); + if (status != eap_status_ok) + { + vector->reset(); + delete vector; + return 0; + } + } + + if (get_AUTN()->get_is_valid_data() == true) + { + status = vector->get_AUTN()->set_copy_of_buffer(get_AUTN()); + if (status != eap_status_ok) + { + vector->reset(); + delete vector; + return 0; + } + } + + if (get_RES()->get_is_valid_data() == true) + { + status = vector->get_RES()->set_copy_of_buffer(get_RES()); + if (status != eap_status_ok) + { + vector->reset(); + delete vector; + return 0; + } + } + + if (get_CK()->get_is_valid_data() == true) + { + status = vector->get_CK()->set_copy_of_buffer(get_CK()); + if (status != eap_status_ok) + { + vector->reset(); + delete vector; + return 0; + } + } + + if (get_IK()->get_is_valid_data() == true) + { + status = vector->get_IK()->set_copy_of_buffer(get_IK()); + if (status != eap_status_ok) + { + vector->reset(); + delete vector; + return 0; + } + } + + return vector; +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_type_aka_authentication_vector_c::reset() +{ + m_RAND.reset(); + m_AUTN.reset(); + m_RES.reset(); + m_CK.reset(); + m_IK.reset(); +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_type_aka_authentication_vector_c::set_vector_status(eap_status_e vector_status) +{ + m_vector_status = vector_status; +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_authentication_vector_c::get_vector_status() const +{ + return EAP_STATUS_RETURN(m_am_tools, m_vector_status); +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_aka_authentication_vector_c::get_is_valid() const +{ + return m_is_valid; +} + +//------------------------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_client.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_client.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,6041 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 66 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_type_aka.h" +#include "eap_type_aka_header.h" +#include "eap_type_aka_payloads.h" +#include "abs_eap_am_type_aka.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" +#include "abs_eap_am_mutex.h" +#include "eap_automatic_variable.h" +#include "eap_buffer.h" + + +//-------------------------------------------------- + +/** @file */ + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::generate_nai( + eap_variable_data_c * const new_nai, + const bool use_manual_default_realm, + const eap_variable_data_c * const nai_realm, + const eap_variable_data_c * const id_IMSI_or_pseudonym, + const bool id_is_imsi, + const eap_variable_data_c * const IMSI, + const eap_variable_data_c * const automatic_realm, + const u32_t length_of_mnc) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (id_IMSI_or_pseudonym == 0 + || id_IMSI_or_pseudonym->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_status_e status = eap_status_not_supported; + + status = new_nai->init(id_IMSI_or_pseudonym->get_data_length()+1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + new_nai->set_is_valid(); + + eap_variable_data_c local_username(m_am_tools); + if (local_username.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = local_username.set_buffer_length(id_IMSI_or_pseudonym->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + local_username.set_data_length(id_IMSI_or_pseudonym->get_data_length()); + + m_am_tools->memmove( + local_username.get_data(id_IMSI_or_pseudonym->get_data_length()), + id_IMSI_or_pseudonym->get_data(id_IMSI_or_pseudonym->get_data_length()), + id_IMSI_or_pseudonym->get_data_length()); + + new_nai->set_data_length(0u); + + if (id_is_imsi == true) + { + // Note the first octet is reserved for IMSI prefix. + status = new_nai->add_data(AKA_IMSI_PREFIX_CHARACTER, 1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // This could be IMSI or pseudonym. + status = new_nai->add_data(&local_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (use_manual_default_realm == true + && nai_realm != 0 + && nai_realm->get_is_valid_data() == true) + { + if (nai_realm->get_data_length() > 0ul) + { + status = new_nai->add_data(AKA_AT_CHARACTER, 1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = new_nai->add_data(nai_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (IMSI != 0 + && IMSI->get_is_valid_data() == true + && IMSI->get_data_length() >= EAP_TYPE_AKA_MINIMUM_IMSI_LENGTH) + { + // We must use automatic realm (Example: "wlan.mnc456.mcc123.3gppnetwork.org"). + + status = new_nai->add_data(AKA_AT_CHARACTER, 1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (automatic_realm != 0 + && automatic_realm->get_is_valid_data() == true) + { + status = new_nai->add_data(automatic_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = new_nai->add_data(AKA_OWLAN_ORG_PREFIX_STRING, AKA_OWLAN_ORG_PREFIX_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(AKA_OWLAN_DOT_STRING, AKA_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(AKA_OWLAN_MNC_STRING, AKA_OWLAN_MNC_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // MNC part. + if (length_of_mnc == EAP_TYPE_AKA_MNC_LENGTH_2_BYTES) + { + // Add zero digit. + u8_t zero = '0'; + status = new_nai->add_data(&zero, sizeof(zero)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + status = new_nai->add_data(IMSI->get_data_offset(EAP_TYPE_AKA_MNC_OFFSET, length_of_mnc), length_of_mnc); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(AKA_OWLAN_DOT_STRING, AKA_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(AKA_OWLAN_MCC_STRING, AKA_OWLAN_MCC_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // MCC part is in index 0 and it is 3 bytes long. + status = new_nai->add_data(IMSI->get_data_offset(EAP_TYPE_AKA_MCC_OFFSET, EAP_TYPE_AKA_MCC_LENGTH), EAP_TYPE_AKA_MCC_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(AKA_OWLAN_DOT_STRING, AKA_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(AKA_OWLAN_ORG_STRING, AKA_OWLAN_ORG_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("new_nai"), + new_nai->get_data(new_nai->get_data_length()), + new_nai->get_data_length())); + + if (new_nai->get_data_length() < sizeof(u8_t)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::query_AKA_IMSI_or_pseudonym_or_reauthentication_id( + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const length_of_mnc, + const bool /*must_be_synchronous*/, + const aka_payload_AT_type_e required_identity, + const eap_type_aka_complete_e required_completion, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + save_current_state(); + set_state(eap_type_aka_state_pending_identity_query); + + status = m_am_type_aka->query_AKA_IMSI_or_pseudonym_or_reauthentication_id( + IMSI, + pseudonym_identity, + reauthentication_identity, + automatic_realm, + length_of_mnc, + required_identity, + required_completion, + received_eap_identifier); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok + && status != eap_status_success) + { + // This is an error case. + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_ok) + { + if (m_use_pseudonym_identity == false) + { + // We do not want use pseudonym identity. + pseudonym_identity->reset(); + } + + if (m_use_reauthentication_identity == false) + { + // We do not want use re-authentication identity. + reauthentication_identity->reset(); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::query_AKA_RES( + eap_type_aka_authentication_vector_c * const authentication_vector + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + status = set_RAND(authentication_vector->get_RAND()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_AUTN(authentication_vector->get_AUTN()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(eap_type_aka_state_pending_kc_sres_query); + + status = m_am_type_aka->query_AKA_RES(authentication_vector); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_AKA_RES_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_AKA_RES_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok + && status != eap_status_success) + { + // This is a error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +u32_t eap_type_aka_c::get_mnc_length(const u32_t mcc) +{ + u32_t * const mcc_array = reinterpret_cast(m_2_digit_mnc_map_of_mcc_of_imsi_array.get_data( + m_2_digit_mnc_map_of_mcc_of_imsi_array.get_data_length())); + + u32_t count = m_2_digit_mnc_map_of_mcc_of_imsi_array.get_data_length() / sizeof(u32_t); + + for (u32_t ind = 0ul; ind < count; ind++) + { + if (mcc == mcc_array[ind]) + { + return EAP_TYPE_AKA_MNC_LENGTH_2_BYTES; + } + } + + return EAP_TYPE_AKA_DEFAULT_MNC_LENGTH_3_BYTES; +} + +//-------------------------------------------------- + +eap_status_e eap_type_aka_c::create_uma_realm( + eap_variable_data_c * const automatic_realm, + const eap_variable_data_c * const IMSI, + const u32_t length_of_mnc) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + // Create special automatic realm for UMA. + automatic_realm->reset(); + + if (m_use_uma_profile == true) + { + // Create special automatic realm for UMA. + automatic_realm->reset(); + + if (m_uma_automatic_realm_prefix.get_is_valid_data() == true) + { + status = automatic_realm->add_data(&m_uma_automatic_realm_prefix); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (automatic_realm->get_data_length() > 0ul) + { + status = automatic_realm->add_data(AKA_OWLAN_DOT_STRING, AKA_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = automatic_realm->add_data(AKA_OWLAN_MNC_STRING, AKA_OWLAN_MNC_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // MNC part. + if (length_of_mnc == EAP_TYPE_AKA_MNC_LENGTH_2_BYTES) + { + // Add zero digit. + u8_t zero = '0'; + status = automatic_realm->add_data(&zero, sizeof(zero)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + status = automatic_realm->add_data(IMSI->get_data_offset(EAP_TYPE_AKA_MNC_OFFSET, length_of_mnc), length_of_mnc); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = automatic_realm->add_data(AKA_OWLAN_DOT_STRING, AKA_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = automatic_realm->add_data(AKA_OWLAN_MCC_STRING, AKA_OWLAN_MCC_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // MCC part is in index 0 and it is 3 bytes long. + status = automatic_realm->add_data(IMSI->get_data_offset(EAP_TYPE_AKA_MCC_OFFSET, EAP_TYPE_AKA_MCC_LENGTH), EAP_TYPE_AKA_MCC_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = automatic_realm->add_data(AKA_OWLAN_DOT_STRING, AKA_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = automatic_realm->add_data(AKA_OWLAN_ORG_STRING, AKA_OWLAN_ORG_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query( + const eap_variable_data_c * const IMSI, + const eap_variable_data_c * const p_pseudonym_identity, + const eap_variable_data_c * const p_reauthentication_identity, + const eap_variable_data_c * const p_automatic_realm, ///< If this is not used, do not add any data to this parameter. + const u32_t length_of_mnc, + const eap_type_aka_complete_e required_completion, + const u8_t received_eap_identifier, + const eap_status_e completion_status +) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (completion_status != eap_status_ok + || IMSI == 0 + || p_pseudonym_identity == 0 + || p_reauthentication_identity == 0) + { + set_state(eap_type_aka_state_failure); + + // The eap_status_process_general_error error value is more important + // than return value of set_session_timeout(). + (void) get_type_partner()->set_session_timeout(0ul); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + const eap_variable_data_c * local_pseudonym_identity = p_pseudonym_identity; + const eap_variable_data_c * local_reauthentication_identity = p_reauthentication_identity; + + if (m_use_pseudonym_identity == false) + { + // We do not want use pseudonym identity. + local_pseudonym_identity = 0; + } + + if (m_use_reauthentication_identity == false) + { + // We do not want use re-authentication identity. + local_reauthentication_identity = 0; + } + + if (get_state() != eap_type_aka_state_pending_identity_query) + { + // Authentication is terminated or state is wrong. Cannot continue. + set_state(eap_type_aka_state_failure); + + // The eap_status_handler_does_not_exists_error error value is more important + // than return value of set_session_timeout(). + (void) get_type_partner()->set_session_timeout(0ul); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c local_automatic_realm(m_am_tools); + + if (p_automatic_realm == 0 + || p_automatic_realm->get_is_valid_data() == false) + { + { + // Here we read the length of the MNC. + const u8_t * const MCC = IMSI->get_data_offset(EAP_TYPE_AKA_MCC_OFFSET, EAP_TYPE_AKA_MCC_LENGTH); + if (MCC == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t MCC_value(0ul); + + status = m_am_tools->number_string_to_u32( + MCC, + 3ul, + &MCC_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_length_of_mnc = get_mnc_length(MCC_value); + } + + status = create_uma_realm(&local_automatic_realm, IMSI, m_length_of_mnc); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (local_automatic_realm.get_is_valid_data() == true) + { + status = m_automatic_realm.set_copy_of_buffer(&local_automatic_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + status = local_automatic_realm.set_copy_of_buffer(p_automatic_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_length_of_mnc = length_of_mnc; + + status = m_automatic_realm.set_copy_of_buffer(p_automatic_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + m_automatic_realm_read = true; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + if (required_completion == eap_type_aka_complete_query_eap_identity) + { + status = handle_eap_identity_query( + get_send_network_id(), + 0, + get_last_eap_identifier(), + IMSI, + local_pseudonym_identity, + local_reauthentication_identity, + &local_automatic_realm, + m_length_of_mnc, + false); + if (status != eap_status_ok + && status != eap_status_completed_request) + { + restore_saved_previous_state(); + } + } + else if (required_completion == eap_type_aka_complete_aka_identity_request) + { + if (local_reauthentication_identity != 0 + && local_reauthentication_identity->get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query reauthentication_identity\n"))); + + status = get_reauthentication_identity()->set_copy_of_buffer(local_reauthentication_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(get_reauthentication_identity(), false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (local_pseudonym_identity != 0 + && local_pseudonym_identity->get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query pseudonym\n"))); + + get_reauthentication_identity()->reset(); + status = get_pseudonym()->set_copy_of_buffer(local_pseudonym_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(get_pseudonym(), false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (IMSI->get_is_valid_data() == true + && IMSI->get_data_length() >= EAP_TYPE_AKA_MINIMUM_IMSI_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query IMSI\n"))); + + get_reauthentication_identity()->reset(); + get_pseudonym()->reset(); + status = get_IMSI()->set_copy_of_buffer(IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(get_IMSI(), true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + save_current_state(); + set_state(eap_type_aka_state_analyse_aka_identity_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query(0x%08x).\n"), + this)); + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + get_send_network_id()->get_destination_id(), + get_send_network_id()->get_source_id(), + get_send_network_id()->get_type()); + + status = send_aka_identity_response_message( + &receive_network_id, + received_eap_identifier, + get_include_identity_to_aka_identity_response(), + &local_automatic_realm); + + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::complete_AKA_RES_query( + const eap_type_aka_authentication_vector_c * const authentication_vector, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (completion_status != eap_status_ok + || authentication_vector == 0 + || authentication_vector->get_is_valid() == false) + { + if (completion_status == eap_status_not_fresh_challenges) + { + (void) initialize_error_message(completion_status); + + restore_saved_previous_state(); + } + else + { + set_state(eap_type_aka_state_failure); + + // The eap_status_process_general_error error value is more important + // than return value of set_session_timeout(). + (void) get_type_partner()->set_session_timeout(0ul); + } + + return EAP_STATUS_RETURN(m_am_tools, completion_status); + } + + if (get_state() != eap_type_aka_state_pending_kc_sres_query) + { + // Authentication is terminated or state is wrong. Cannot continue. + set_state(eap_type_aka_state_failure); + + // The eap_status_handler_does_not_exists_error error value is more important + // than return value of set_session_timeout(). + (void) get_type_partner()->set_session_timeout(0ul); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = process_AKA_kc_sres( + authentication_vector); + + if (status != eap_status_ok + && status != eap_status_success) + { + (void) initialize_error_message(status); + + restore_saved_previous_state(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::process_AKA_kc_sres( + const eap_type_aka_authentication_vector_c * const authentication_vector) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + eap_variable_data_c MAC_RAND(m_am_tools); + if (MAC_RAND.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (get_state() != eap_type_aka_state_pending_kc_sres_query + || authentication_vector == 0 + || authentication_vector->get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (get_identity() == 0 + || get_identity()->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("RAND"), + authentication_vector->get_RAND()->get_data(authentication_vector->get_RAND()->get_data_length()), + authentication_vector->get_RAND()->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AUTN"), + authentication_vector->get_AUTN()->get_data(authentication_vector->get_AUTN()->get_data_length()), + authentication_vector->get_AUTN()->get_data_length())); + + if (authentication_vector->get_vector_status() == eap_status_ok) + { + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("RES"), + authentication_vector->get_RES()->get_data(authentication_vector->get_RES()->get_data_length()), + authentication_vector->get_RES()->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CK"), + authentication_vector->get_CK()->get_data(authentication_vector->get_CK()->get_data_length()), + authentication_vector->get_CK()->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IK"), + authentication_vector->get_IK()->get_data(authentication_vector->get_IK()->get_data_length()), + authentication_vector->get_IK()->get_data_length())); + } + else if (authentication_vector->get_vector_status() == eap_status_syncronization_failure) + { + // ERROR: send EAP-Response/AKA-Synchronization-Failure + status = send_aka_synchronization_failure_response_message( + authentication_vector); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // ERROR: send EAP-Response/AKA-Authentication-Reject + status = send_aka_authentication_reject_response_message( + authentication_vector); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, authentication_vector->get_vector_status()); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("identity"), + get_identity()->get_data(get_identity()->get_data_length()), + get_identity()->get_data_length())); + + status = get_RES()->set_copy_of_buffer(authentication_vector->get_RES()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c XKEY(m_am_tools); + eap_variable_data_c K_encr(m_am_tools); + eap_variable_data_c K_aut(m_am_tools); + eap_variable_data_c master_session_key(m_am_tools); + + if (XKEY.get_is_valid() == false + || K_encr.get_is_valid() == false + || K_aut.get_is_valid() == false + || master_session_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = generate_shared_secred_keys( + EAP_TYPE_AKA_KEYMAT_SIZE, + authentication_vector->get_CK(), + authentication_vector->get_IK(), + &XKEY, + &K_encr, + &K_aut, + &master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (get_saved_EAP_packet()->get_is_valid_data() == true) + { + aka_payloads_c * const l_aka_payloads = new aka_payloads_c(m_am_tools); + eap_automatic_variable_c l_aka_payloads_automatic(m_am_tools, l_aka_payloads); + + if (l_aka_payloads == 0 + || l_aka_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + aka_header_c saved_EAP_packet( + m_am_tools, + get_saved_EAP_packet()->get_data(get_saved_EAP_packet()->get_data_length()), + get_saved_EAP_packet()->get_data_length()); + + if (saved_EAP_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_aka_packet( + &saved_EAP_packet, + get_saved_EAP_packet()->get_data_length(), + l_aka_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = check_message_authentication_code( + &K_aut, + l_aka_payloads, + &saved_EAP_packet, + saved_EAP_packet.get_length()); + if (status != eap_status_ok) + { + (void) initialize_error_message(status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_received_checkcode.get_is_valid_data() == true) + { + // Verify AT_CHECKCODE. + status = checkcode_verify( + &m_received_checkcode); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // Decrypt and parse encrypted payload. + if (l_aka_payloads->get_IV()->get_payload_included() == true + || l_aka_payloads->get_ENCR_DATA()->get_payload_included() == true) + { + if (l_aka_payloads->get_IV()->get_payload_included() == true + && l_aka_payloads->get_ENCR_DATA()->get_payload_included() == true + && l_aka_payloads->get_MAC()->get_payload_included() == true) + { + status = decrypt_DATA_payload( + l_aka_payloads, + &K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = handle_DATA_payload( + aka_subtype_Challenge, + l_aka_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // All of these must be included + // or none of these must be included. + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + else + { + // No encrypted payload. + // AKA AM should remove re-authentication identity from favourite place. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::process_AKA_kc_sres(0x%08x): Resets re-authentication identity from database.\n"), + this)); + + status = m_am_type_aka->store_reauthentication_id( + &m_send_network_id, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + get_reauthentication_identity()->reset(); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_type_aka_authentication_vector_c * const copy_authentication_vector = authentication_vector->copy(); + if (copy_authentication_vector == 0 + || copy_authentication_vector->get_is_valid() == false) + { + delete copy_authentication_vector; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_authentication_vector(copy_authentication_vector); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = send_challenge_response_message( + &K_aut); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Store keys. + status = get_XKEY()->set_copy_of_buffer(&XKEY); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = get_K_encr()->set_copy_of_buffer(&K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = get_K_aut()->set_copy_of_buffer(&K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = get_master_session_key()->set_copy_of_buffer(&master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_aka->store_reauth_parameters( + &XKEY, + &K_aut, + &K_encr, + EAP_TYPE_AKA_INITIAL_REAUTH_COUNTER); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Authentication was successful. + if (m_use_result_indication == true) + { + // This version waits result indication. + if (m_authentication_type == AKA_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, re-authentication OK, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_authentication_type == AKA_AUTHENTICATION_TYPE_FULL_AUTH) + { + if (m_identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, full authentication OK, pseudonym identity, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_IMSI_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, full authentication OK, IMSI identity, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, full authentication OK, Re-auth identity, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_AKA_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_AKA: %s, full authentication OK, unknown identity\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_AKA_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_AKA: %s, unknown authentication OK, unknown identity\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + set_state(eap_type_aka_state_waiting_for_notification_request_success); + } + else if (m_wait_eap_success_packet == false) + { + // This version does not wait EAP-Success message. + if (get_send_network_id()->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + get_send_network_id()->get_destination_id(), + get_send_network_id()->get_source_id(), + get_send_network_id()->get_type()); + + // This version does not wait EAP-Success message. + status = finish_successful_authentication( + &receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // This version waits the EAP-Success message. + + if (m_authentication_type == AKA_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, re-authentication OK, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_authentication_type == AKA_AUTHENTICATION_TYPE_FULL_AUTH) + { + if (m_identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, full authentication OK, pseudonym identity, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_IMSI_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, full authentication OK, IMSI identity, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, full authentication OK, Re-auth identity, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_AKA_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_AKA: %s, full authentication OK, unknown identity, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_AKA_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_AKA: %s, unknown authentication OK, unknown identity, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + set_state(eap_type_aka_state_waiting_for_success); + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_aka_identity_response_message( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier, + const aka_payload_AT_type_e include_identity_to_aka_identity_response, + const eap_variable_data_c * const automatic_realm) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + EAPL("aka_subtype_Identity"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + eap_buf_chain_wr_c aka_initial_reply( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (aka_initial_reply.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means AKA does process every re-transmitted EAP-Request. + aka_initial_reply.set_do_packet_retransmission(false); + } + + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH >= (m_aka_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_aka_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_aka_header_offset+m_MTU; + } + + aka_header_c aka_response( + m_am_tools, + aka_initial_reply.get_data_offset( + m_aka_header_offset, + (packet_buffer_free-m_aka_header_offset)), + (packet_buffer_free-m_aka_header_offset)); + + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + aka_response.reset_header( + packet_buffer_free-m_aka_header_offset, + m_use_eap_expanded_type); + aka_response.set_length( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_code(eap_code_response); + aka_response.set_identifier(received_eap_identifier); + aka_response.set_type( + eap_type_aka, + m_use_eap_expanded_type); + + aka_response.set_subtype(aka_subtype_Identity); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_response_message(0x%08x): include_identity_to_start_response %d=%s.\n"), + this, + include_identity_to_aka_identity_response, + aka_payload_AT_header_c::get_payload_AT_string(include_identity_to_aka_identity_response))); + + update_buffer_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + m_aka_header_offset+aka_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aka_data_free = packet_buffer_free; + u32_t aka_data_offset = 0u; + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID) + { + // Re-authentication identity MUST be removed after first use. + // EAP-AKA AM should remove re-authentication identity from favourite place. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_response_message(0x%08x): Resets re-authentication identity from database.\n"), + this)); + + status = m_am_type_aka->store_reauthentication_id( + &m_send_network_id, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Do not reset the local copy of re-authentocation identity. + } + + + if (include_identity_to_aka_identity_response == aka_payload_AT_PERMANENT_ID_REQ) + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(AKA_IDENTITY_TYPE_IMSI_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_response_message(0x%08x): Selects full authentication and IMSI identity.\n"), + this)); + } + else if (include_identity_to_aka_identity_response == aka_payload_AT_FULLAUTH_ID_REQ) + { + eap_variable_data_c * const pseudonym = get_pseudonym(); + + if (pseudonym->get_is_valid_data() == true) + { + // We have pseudonym. + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(AKA_IDENTITY_TYPE_PSEUDONYM_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_response_message(0x%08x): Selects full authentication and pseudonym identity.\n"), + this)); + } + else // if (pseudonym->get_is_valid() == false) + { + // Because no pseudonym is available we must use IMSI. + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(AKA_IDENTITY_TYPE_IMSI_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_response_message(0x%08x): Selects full authentication and IMSI identity.\n"), + this)); + } + } + else if (include_identity_to_aka_identity_response == aka_payload_AT_ANY_ID_REQ) + { + eap_variable_data_c * const reauthentication_identity = get_reauthentication_identity(); + eap_variable_data_c * const pseudonym = get_pseudonym(); + + if (reauthentication_identity->get_is_valid_data() == true) + { + // We have reauthentication identity. Re-authentication identity is NAI. + m_authentication_type = AKA_AUTHENTICATION_TYPE_REAUTHENTICATION; + set_identity_type(AKA_IDENTITY_TYPE_RE_AUTH_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_response_message(0x%08x): Selects fast re-authentication and re-authentication identity.\n"), + this)); + } + else if (pseudonym->get_is_valid_data() == true) + { + // We have pseudonym. + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(AKA_IDENTITY_TYPE_PSEUDONYM_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_response_message(0x%08x): Selects full authentication and pseudonym identity.\n"), + this)); + } + else if (get_IMSI()->get_is_valid_data() == true) + { + // Because no pseudonym is available we must use IMSI. + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(AKA_IDENTITY_TYPE_IMSI_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_response_message(0x%08x): Selects full authentication and IMSI identity.\n"), + this)); + } + else + { + // ERROR, no identity available. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + + + if (include_identity_to_aka_identity_response != aka_payload_NONE) + { + if (m_identity_type == AKA_IDENTITY_TYPE_IMSI_ID) + { + eap_variable_data_c NAI(m_am_tools); + if (NAI.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = NAI.init(1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + NAI.set_is_valid(); + + status = generate_nai( + &NAI, + m_use_manual_realm, + get_nai_realm(), + get_IMSI(), + true, + get_IMSI(), + automatic_realm, + m_length_of_mnc); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_pseudonym_or_imsi_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &NAI, + aka_payload_AT_IDENTITY); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save used NAI. + status = get_NAI()->set_copy_of_buffer(&NAI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_response_message(): Client sends IMSI identity.\n"))); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID) + { + eap_variable_data_c * const pseudonym = get_pseudonym(); + + if (pseudonym->get_is_valid_data() == true) + { + // We have pseudonym. + + eap_variable_data_c NAI(m_am_tools); + if (NAI.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = NAI.init(1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + NAI.set_is_valid(); + + status = generate_nai( + &NAI, + m_use_manual_realm, + get_nai_realm(), + pseudonym, + false, + get_IMSI(), + automatic_realm, + m_length_of_mnc); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_pseudonym_or_imsi_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &NAI, + aka_payload_AT_IDENTITY); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save used NAI. + status = get_NAI()->set_copy_of_buffer(&NAI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_response_message(): Client sends pseudonym identity.\n"))); + } + else // if (pseudonym->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + else if (m_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID) + { + eap_variable_data_c * const reauthentication_identity = get_reauthentication_identity(); + + if (reauthentication_identity->get_is_valid_data() == true) + { + // We have reauthentication identity. Re-authentication identity is NAI. + status = add_pseudonym_or_imsi_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + reauthentication_identity, + aka_payload_AT_IDENTITY); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save used NAI. + status = get_NAI()->set_copy_of_buffer(reauthentication_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_response_message(): Client sends re-authentication identity.\n"))); + } + else + { + // ERROR, no identity available. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + aka_initial_reply.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = checkcode_save_message_client( + aka_response.get_header_buffer( + aka_response.get_header_length() + +aka_response.get_data_length()), + aka_response.get_header_length() + +aka_response.get_data_length(), + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = packet_send( + &send_network_id, + &aka_initial_reply, + m_aka_header_offset, + aka_response.get_header_length()+aka_response.get_data_length(), + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + if (m_authentication_type == AKA_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + set_state(eap_type_aka_state_waiting_for_reauth_request); + } + else + { + set_state(eap_type_aka_state_waiting_for_challenge_request); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_aka_synchronization_failure_response_message( + const eap_type_aka_authentication_vector_c * const authentication_vector + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + EAPL("send_synchronization_failure_response_message"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + eap_buf_chain_wr_c eap_notification_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_notification_packet.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means AKA does process every re-transmitted EAP-Request. + eap_notification_packet.set_do_packet_retransmission(false); + } + + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH >= (m_aka_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_aka_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_aka_header_offset+m_MTU; + } + + aka_header_c aka_response( + m_am_tools, + eap_notification_packet.get_data_offset( + m_aka_header_offset, + (packet_buffer_free-m_aka_header_offset)), + (packet_buffer_free-m_aka_header_offset)); + + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + aka_response.reset_header( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_length( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_code(eap_code_response); + aka_response.set_identifier(static_cast(get_last_eap_identifier())); + aka_response.set_type( + eap_type_aka, + m_use_eap_expanded_type); + aka_response.set_subtype(aka_subtype_Synchronization_Failure); + + + update_buffer_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + m_aka_header_offset+aka_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aka_data_free = packet_buffer_free; + u32_t aka_data_offset = 0u; + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c orig_K_aut(m_am_tools); + if (orig_K_aut.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_AUTS_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + authentication_vector->get_AUTS(), + aka_payload_AT_AUTS); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_aka_synchronization_failure_response_message(): aka_subtype_Synchronization_Failure packet"), + aka_response.get_header_buffer(aka_response.get_length()), + aka_response.get_length())); + + status = packet_send( + get_send_network_id(), + &eap_notification_packet, + m_aka_header_offset, + aka_response.get_length(), + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + set_state(eap_type_aka_state_waiting_for_challenge_request); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_aka_authentication_reject_response_message( + const eap_type_aka_authentication_vector_c * const /*authentication_vector*/ + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + EAPL("send_authentication_reject_response_message"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + eap_buf_chain_wr_c eap_notification_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_notification_packet.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means AKA does process every re-transmitted EAP-Request. + eap_notification_packet.set_do_packet_retransmission(false); + } + + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH >= (m_aka_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_aka_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_aka_header_offset+m_MTU; + } + + aka_header_c aka_response( + m_am_tools, + eap_notification_packet.get_data_offset( + m_aka_header_offset, + (packet_buffer_free-m_aka_header_offset)), + (packet_buffer_free-m_aka_header_offset)); + + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + aka_response.reset_header( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_length( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_code(eap_code_response); + aka_response.set_identifier(static_cast(get_last_eap_identifier())); + aka_response.set_type( + eap_type_aka, + m_use_eap_expanded_type); + aka_response.set_subtype(aka_subtype_Authentication_Reject); + + + update_buffer_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + m_aka_header_offset+aka_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aka_data_offset = 0u; + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_aka_authentication_reject_response_message: aka_subtype_Authentication_Reject packet"), + aka_response.get_header_buffer(aka_response.get_length()), + aka_response.get_length())); + + status = packet_send( + get_send_network_id(), + &eap_notification_packet, + m_aka_header_offset, + aka_response.get_length(), + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_aka_notification_response( + const eap_aka_notification_codes_e notification_code, + const bool add_at_counter_attribute) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + EAPL("send_aka_notification_response"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + eap_buf_chain_wr_c eap_notification_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_notification_packet.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means AKA does process every re-transmitted EAP-Request. + eap_notification_packet.set_do_packet_retransmission(false); + } + + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH >= (m_aka_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_aka_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_aka_header_offset+m_MTU; + } + + aka_header_c aka_response( + m_am_tools, + eap_notification_packet.get_data_offset( + m_aka_header_offset, + (packet_buffer_free-m_aka_header_offset)), + (packet_buffer_free-m_aka_header_offset)); + + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + aka_response.reset_header( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_length( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_code(eap_code_response); + aka_response.set_identifier(static_cast(get_last_eap_identifier())); + aka_response.set_type( + eap_type_aka, + m_use_eap_expanded_type); + aka_response.set_subtype(aka_subtype_Notification); + + + update_buffer_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + m_aka_header_offset+aka_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aka_data_free = packet_buffer_free; + u32_t aka_data_offset = 0u; + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c * K_aut = 0; + + eap_variable_data_c orig_K_aut(m_am_tools); + if (orig_K_aut.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (get_aka_notification_code_P_bit(notification_code) == false) + { + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_aka_MAC_attributes_c MAC_attributes; + + if (add_at_counter_attribute == true) + { + // If EAP-Request/AKA/Notification is used on fast a re-authentication + // exchange, and if the P bit in AT_NOTIFICATION is set to zero, then + // AT_COUNTER is used for replay protection. In this case, the + // AT_ENCR_DATA and AT_IV attributes MUST be included, and the + // encapsulated plaintext attributes MUST include the AT_COUNTER + // attribute. The counter value included in AT_COUNTER MUST be the same + // as in the EAP-Request/AKA/Re-authentication packet on the same fast + // re-authentication exchange. + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + + if (orig_XKEY.get_is_valid() == false + || orig_K_encr.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t reauth_counter = 0u; + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_aka->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + K_aut = &orig_K_aut; + + // - - - - - - - - - - - - + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_type_aka->generate_encryption_IV( + get_IV()->get_payload_buffer(), + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + get_IV()->get_payload_buffer(), + aka_payload_AT_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // Encrypted data. + { + aka_payload_AT_header_c gp_encrypted_data( + m_am_tools, + aka_response.get_data_offset( + aka_data_offset, + aka_data_free), + aka_data_free); + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Initialize the length of encrypted data to maximum length. + // Later this will be set to correct length. + gp_encrypted_data.reset_header(aka_payload_AT_header_c::get_max_payload_data_length()); + gp_encrypted_data.set_current_payload(aka_payload_AT_ENCR_DATA); + + update_payload_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + gp_encrypted_data.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_offset, + &packet_buffer_free); + + u32_t encrypted_data_offset_begin = packet_buffer_offset; + + // - - - - - - - - - - - - + + status = add_counter_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + static_cast(reauth_counter)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_padding_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + (packet_buffer_offset - encrypted_data_offset_begin) // Length of the plain text. + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + gp_encrypted_data.set_data_length( + static_cast(packet_buffer_offset - encrypted_data_offset_begin)); + + // - - - - - - - - - - - - + + status = encrypt_DATA_payload( + gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), + gp_encrypted_data.get_data_length(), + get_IV()->get_payload_buffer(), + &orig_K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); + } + + } + else + { + K_aut = get_K_aut(); + } // if (add_counter_payload == true) + + // - - - - - - - - - - - - + + // Add AT_MAC attribute. + status = add_mac_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + aka_response.get_header_buffer(aka_response.get_length()), + aka_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + aka_response.get_subtype(), + aka_response.get_code(), + K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_aka_notification_response: aka_subtype_Notification packet"), + aka_response.get_header_buffer(aka_response.get_length()), + aka_response.get_length())); + + status = packet_send( + get_send_network_id(), + &eap_notification_packet, + m_aka_header_offset, + aka_response.get_length(), + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_aka_client_error_response() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + EAPL("send_aka_client_error_response"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + eap_buf_chain_wr_c eap_client_error_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_client_error_packet.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means AKA does process every re-transmitted EAP-Request. + eap_client_error_packet.set_do_packet_retransmission(false); + } + + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH >= (m_aka_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_aka_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_aka_header_offset+m_MTU; + } + + aka_header_c aka_response( + m_am_tools, + eap_client_error_packet.get_data_offset( + m_aka_header_offset, + (packet_buffer_free-m_aka_header_offset)), + (packet_buffer_free-m_aka_header_offset)); + + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + aka_response.reset_header( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_length( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_code(eap_code_response); + aka_response.set_identifier(static_cast(get_last_eap_identifier())); + aka_response.set_type( + eap_type_aka, + m_use_eap_expanded_type); + aka_response.set_subtype(aka_subtype_Client_Error); + + + update_buffer_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + m_aka_header_offset+aka_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aka_data_free = packet_buffer_free; + u32_t aka_data_offset = 0u; + + eap_status_e status = add_client_error_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + m_client_error_code); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + eap_client_error_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_client_error_packet.set_data_length(packet_buffer_offset); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" send: EAP-Response/Client-Error packet"), + aka_response.get_header_buffer(aka_response.get_length()), + aka_response.get_length())); + + status = packet_send( + get_send_network_id(), + &eap_client_error_packet, + m_aka_header_offset, + aka_response.get_length(), + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_challenge_response_message( + eap_variable_data_c * const K_aut) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + EAPL("aka_subtype_Challenge"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + + eap_variable_data_c checkcode_digest(m_am_tools); + if (checkcode_digest.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_status_process_general_error; + + status = checkcode_final( + &checkcode_digest); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_buf_chain_wr_c aka_initial_reply( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (aka_initial_reply.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means AKA does process every re-transmitted EAP-Request. + aka_initial_reply.set_do_packet_retransmission(false); + } + + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH >= (m_aka_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_aka_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_aka_header_offset+m_MTU; + } + + aka_header_c aka_response( + m_am_tools, + aka_initial_reply.get_data_offset( + m_aka_header_offset, + (packet_buffer_free-m_aka_header_offset)), + (packet_buffer_free-m_aka_header_offset)); + + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + aka_response.reset_header( + packet_buffer_free, + m_use_eap_expanded_type); + aka_response.set_length( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_code(eap_code_response); + aka_response.set_identifier(get_last_eap_identifier()); + aka_response.set_type( + eap_type_aka, + m_use_eap_expanded_type); + aka_response.set_subtype(aka_subtype_Challenge); + + update_buffer_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + m_aka_header_offset+aka_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_type_aka_c::send_challenge_response_message(0x%08x).\n"), + this)); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aka_data_free = packet_buffer_free; + u32_t aka_data_offset = 0u; + + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_aka_MAC_attributes_c MAC_attributes; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_use_result_indication == true) + { + // We support use of protected success indications. + status = add_simple_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + aka_payload_AT_RESULT_IND); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &checkcode_digest, + aka_payload_AT_CHECKCODE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_RES_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + get_authentication_vector()->get_RES(), + aka_payload_AT_RES); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_mac_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + aka_initial_reply.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + aka_response.get_header_buffer(aka_response.get_length()), + aka_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + aka_response.get_subtype(), + aka_response.get_code(), + K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + aka_initial_reply.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = packet_send( + get_send_network_id(), + &aka_initial_reply, + m_aka_header_offset, + aka_response.get_header_length()+aka_response.get_data_length(), + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_reauthentication_response_message( + const eap_variable_data_c * const orig_XKEY, + const eap_variable_data_c * const orig_K_aut, + const eap_variable_data_c * const orig_K_encr, + const eap_variable_data_c * const reauth_username, + const eap_variable_data_c * const reauth_nonce_s, + const u16_t reauth_counter, + const u8_t eap_identifier, + const bool include_at_counter_too_small) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: handler 0x%08x, AKA-subtype %10s, %s, state %2d=%s\n"), + this, + EAPL("aka_subtype_Re_authentication"), + EAPL("client"), + get_state(), + get_state_string() + )); + + + eap_variable_data_c checkcode_digest(m_am_tools); + if (checkcode_digest.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_status_process_general_error; + + status = checkcode_final( + &checkcode_digest); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_buf_chain_wr_c request_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (request_packet.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means AKA does process every re-transmitted EAP-Request. + request_packet.set_do_packet_retransmission(false); + } + + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH >= (m_aka_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_aka_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_aka_header_offset+m_MTU; + } + + aka_header_c aka_response( + m_am_tools, + request_packet.get_data_offset( + m_aka_header_offset, + (packet_buffer_free-m_aka_header_offset)), + (packet_buffer_free-m_aka_header_offset)); + + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_reauthentication_response_message: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + aka_response.reset_header( + packet_buffer_free-m_aka_header_offset, + m_use_eap_expanded_type); + aka_response.set_length( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_code(eap_code_response); + aka_response.set_identifier(eap_identifier); + aka_response.set_type( + eap_type_aka, + m_use_eap_expanded_type); + aka_response.set_subtype(aka_subtype_Re_authentication); + + update_buffer_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + m_aka_header_offset+aka_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_reauthentication_response_message(0x%08x).\n"), + this)); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aka_data_free = packet_buffer_free; + u32_t aka_data_offset = 0u; + + eap_variable_data_c master_session_key(m_am_tools); + if (master_session_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = generate_reauth_shared_secred_keys( + EAP_TYPE_AKA_KEYMAT_SIZE, + orig_XKEY, + reauth_counter, + reauth_username, + reauth_nonce_s, + &master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + if (m_use_result_indication == true) + { + // We support use of protected success indications. + status = add_simple_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + aka_payload_AT_RESULT_IND); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &checkcode_digest, + aka_payload_AT_CHECKCODE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_type_aka->generate_encryption_IV( + get_IV()->get_payload_buffer(), + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + get_IV()->get_payload_buffer(), + aka_payload_AT_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_aka_MAC_attributes_c MAC_attributes; + + // Encrypted data. + { + aka_payload_AT_header_c gp_encrypted_data( + m_am_tools, + aka_response.get_data_offset( + aka_data_offset, + aka_data_free), + aka_data_free); + if (gp_encrypted_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Initialize the length of encrypted data to maximum length. + // Later this will be set to correct length. + gp_encrypted_data.reset_header(aka_payload_AT_header_c::get_max_payload_data_length()); + gp_encrypted_data.set_current_payload(aka_payload_AT_ENCR_DATA); + + update_payload_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + gp_encrypted_data.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_offset, + &packet_buffer_free); + + u32_t encrypted_data_offset_begin = packet_buffer_offset; + + + // - - - - - - - - - - - - + + if (include_at_counter_too_small == true) + { + status = add_simple_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + aka_payload_AT_COUNTER_TOO_SMALL); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + status = add_counter_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + reauth_counter); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_padding_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + (packet_buffer_offset - encrypted_data_offset_begin) // Length of the plain text. + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + gp_encrypted_data.set_data_length( + static_cast(packet_buffer_offset - encrypted_data_offset_begin)); + + // - - - - - - - - - - - - + + status = encrypt_DATA_payload( + gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), + gp_encrypted_data.get_data_length(), + get_IV()->get_payload_buffer(), + orig_K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); + } + + + + // - - - - - - - - - - - - + + status = add_mac_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + request_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + aka_response.get_header_buffer(aka_response.get_length()), + aka_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + aka_response.get_subtype(), + aka_response.get_code(), + orig_K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + request_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_reauthentication_request_message()\n"))); + + status = packet_send( + get_send_network_id(), + &request_packet, + m_aka_header_offset, + aka_response.get_header_length()+aka_response.get_data_length(), + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + if (include_at_counter_too_small == false) + { + status = get_master_session_key()->set_copy_of_buffer(&master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (include_at_counter_too_small == true) + { + // The full authentication must follow. + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::decrypt_DATA_payload( + aka_payloads_c * const p_aka_payloads, + const eap_variable_data_c * const encryption_key + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t aes_key_length = aes.get_key_length(); + if (encryption_key->get_data_length() < aes_key_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + if (p_aka_payloads->get_ENCR_DATA()->get_data_length() == 0 + || (p_aka_payloads->get_ENCR_DATA()->get_data_length() % aes_key_length) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + if (p_aka_payloads->get_IV()->get_payload_included() == false + || p_aka_payloads->get_IV()->get_data_length() == 0u + || encryption_key->get_is_valid_data() == false + || encryption_key->get_data_length() == 0u) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + if (p_aka_payloads->get_ENCR_DATA()->get_payload_included() == false + || p_aka_payloads->get_ENCR_DATA()->get_data_length() == 0u) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + + + status = cbc_aes.set_decryption_key( + p_aka_payloads->get_IV()->get_data(p_aka_payloads->get_IV()->get_data_length()), + p_aka_payloads->get_IV()->get_data_length(), + encryption_key->get_data(encryption_key->get_data_length()), + aes_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = cbc_aes.decrypt_data( + p_aka_payloads->get_ENCR_DATA()->get_data(p_aka_payloads->get_ENCR_DATA()->get_data_length()), + p_aka_payloads->get_ENCR_DATA()->get_data_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_DATA_payload( + const aka_subtype_e subtype, + aka_payloads_c * const p_aka_payloads + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (p_aka_payloads->get_ENCR_DATA() == 0 + || p_aka_payloads->get_ENCR_DATA()->get_data_length() == 0u) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t state_payload_buffer_length = p_aka_payloads->get_ENCR_DATA()->get_data_length(); + const aka_payload_AT_header_c gp_data_payload( + m_am_tools, + p_aka_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), + state_payload_buffer_length); + + if (gp_data_payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_aka_payload( + &gp_data_payload, + &state_payload_buffer_length, + p_aka_payloads, + subtype); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (p_aka_payloads->get_NEXT_PSEUDONYM()->get_payload_included() == true) + { + if (p_aka_payloads->get_padding_payload()->get_payload_included() == true + && p_aka_payloads->get_padding_payload()->get_data_length() > 0u) + { + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Check the padding bytes. + // Must be filled with zero (0x00) bytes. + status = cbc_aes.check_padding_bytes( + p_aka_payloads->get_padding_payload()->get_data(p_aka_payloads->get_padding_payload()->get_data_length()), + p_aka_payloads->get_padding_payload()->get_data_length(), + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // AKA AM could store pseudonym to favourite place. + status = m_am_type_aka->store_pseudonym_id( + get_send_network_id(), + p_aka_payloads->get_NEXT_PSEUDONYM()->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (p_aka_payloads->get_NEXT_REAUTH_ID()->get_payload_included() == true) + { + if (p_aka_payloads->get_padding_payload()->get_payload_included() == true + && p_aka_payloads->get_padding_payload()->get_data_length() > 0u) + { + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Check the padding bytes. + // Must be filled with zero (0x00) bytes. + status = cbc_aes.check_padding_bytes( + p_aka_payloads->get_padding_payload()->get_data(p_aka_payloads->get_padding_payload()->get_data_length()), + p_aka_payloads->get_padding_payload()->get_data_length(), + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // AKA AM could store pseudonym to favourite place. + status = m_am_type_aka->store_reauthentication_id( + get_send_network_id(), + p_aka_payloads->get_NEXT_REAUTH_ID()->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // AKA AM should remove pseudonym from favourite place. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_DATA_payload(0x%08x): Resets re-authentication identity from database.\n"), + this)); + + status = m_am_type_aka->store_reauthentication_id( + get_send_network_id(), + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + get_reauthentication_identity()->reset(); + } + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_aka_identity_request_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t /* aka_packet_length */, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + if (get_state() == eap_type_aka_state_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_pseydonym_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_imsi_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_waiting_for_challenge_request + || get_state() == eap_type_aka_state_waiting_for_reauth_request) + { + // This could be first or retransmission request. + + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_not_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_not_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_optional, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_optional, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_optional, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_must_not_be, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_must_not_be // CHECKCODE + ) == true + ) + { + // NOTE, this message is unauthenticated. Anybody could sent this message. + + aka_payload_AT_type_e include_identity_to_aka_identity_response = aka_payload_NONE; + + + if ( get_state() == eap_type_aka_state_imsi_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_waiting_for_challenge_request + || get_state() == eap_type_aka_state_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_pseydonym_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_waiting_for_reauth_request) + { + if ((p_aka_payloads->get_PERMANENT_ID_REQ()->get_payload_included() == true + && p_aka_payloads->get_FULLAUTH_ID_REQ()->get_payload_included() == true) + || (p_aka_payloads->get_PERMANENT_ID_REQ()->get_payload_included() == true + && p_aka_payloads->get_ANY_ID_REQ()->get_payload_included() == true) + || (p_aka_payloads->get_FULLAUTH_ID_REQ()->get_payload_included() == true + && p_aka_payloads->get_ANY_ID_REQ()->get_payload_included() == true)) + { + // Only one of these is allowed. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_request_message(0x%08x), illegal payloads.\n"), + this)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (p_aka_payloads->get_PERMANENT_ID_REQ()->get_payload_included() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message ") + EAPL("aka_payload_AT_PERMANENT_ID_REQ\n"))); + // Note, this is optional, included only when pseudonym decode failed in server. + include_identity_to_aka_identity_response = aka_payload_AT_PERMANENT_ID_REQ; + } + else if (p_aka_payloads->get_FULLAUTH_ID_REQ()->get_payload_included() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message ") + EAPL("aka_payload_AT_FULLAUTH_ID_REQ\n"))); + // Note, this is optional, included only when reauthentication identity decode failed in server. + include_identity_to_aka_identity_response = aka_payload_AT_FULLAUTH_ID_REQ; + } + else if (p_aka_payloads->get_ANY_ID_REQ()->get_payload_included() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message ") + EAPL("aka_payload_AT_ANY_ID_REQ\n"))); + // Note, this is optional, included only when server have no identity of client. + include_identity_to_aka_identity_response = aka_payload_AT_ANY_ID_REQ; + } + } + + set_include_identity_to_aka_identity_response(include_identity_to_aka_identity_response); + + if (include_identity_to_aka_identity_response == aka_payload_NONE + && (get_identity() == 0 + || get_identity()->get_is_valid_data() == false)) + { + // We must query the previous sent EAP-Identity from EAP_Core. + // The EAP_Core saves the sent EAP-Identity when the EAP-Identity is + // sent to the network. + // Previous EAP-type was NOT this instance. EAP-Identity was queried from other instance. + status = get_type_partner()->get_saved_eap_identity(get_identity()); + if (status != eap_status_ok) + { + // We do not have the identity server accepted anymore. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_NAI()->set_copy_of_buffer(get_identity()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + status = checkcode_save_message_client( + received_aka->get_header_buffer( + received_aka->get_header_length() + +received_aka->get_data_length()), + received_aka->get_header_length() + +received_aka->get_data_length(), + p_aka_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (include_identity_to_aka_identity_response == aka_payload_AT_ANY_ID_REQ + && (get_reauthentication_identity()->get_is_valid_data() == false + && get_pseudonym()->get_is_valid_data() == false + && get_IMSI()->get_is_valid_data() == false + && m_automatic_realm_read == false)) + { + eap_variable_data_c IMSI(m_am_tools); + eap_variable_data_c pseudonym(m_am_tools); + eap_variable_data_c reauthentication_identity(m_am_tools); + + if (IMSI.get_is_valid() == false + || pseudonym.get_is_valid() == false + || reauthentication_identity.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message ") + EAPL("aka_payload_AT_ANY_ID_REQ\n"))); + + status = query_AKA_IMSI_or_pseudonym_or_reauthentication_id( + &IMSI, + &pseudonym, + &reauthentication_identity, + &m_automatic_realm, + &m_length_of_mnc, + false, + include_identity_to_aka_identity_response, + eap_type_aka_complete_aka_identity_request, + received_aka->get_identifier()); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message(): ") + EAPL("completed returns eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok) + { + // This is the error case. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message(): ") + EAPL("error returns eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (reauthentication_identity.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message ") + EAPL("reauthentication_identity\n"))); + + status = get_reauthentication_identity()->set_copy_of_buffer(&reauthentication_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(get_reauthentication_identity(), false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (pseudonym.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message pseudonym\n"))); + + get_reauthentication_identity()->reset(); + status = get_pseudonym()->set_copy_of_buffer(&pseudonym); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(get_pseudonym(), false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (IMSI.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message IMSI\n"))); + + get_reauthentication_identity()->reset(); + get_pseudonym()->reset(); + status = get_IMSI()->set_copy_of_buffer(&IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(get_IMSI(), true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (include_identity_to_aka_identity_response == aka_payload_AT_FULLAUTH_ID_REQ + && (get_pseudonym()->get_is_valid_data() == false + && get_IMSI()->get_is_valid_data() == false + && m_automatic_realm_read == false)) + { + eap_variable_data_c IMSI(m_am_tools); + eap_variable_data_c pseudonym(m_am_tools); + eap_variable_data_c reauthentication_identity(m_am_tools); + + if (IMSI.get_is_valid() == false + || pseudonym.get_is_valid() == false + || reauthentication_identity.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message ") + EAPL("aka_payload_AT_FULLAUTH_ID_REQ\n"))); + + status = query_AKA_IMSI_or_pseudonym_or_reauthentication_id( + &IMSI, + &pseudonym, + &reauthentication_identity, + &m_automatic_realm, + &m_length_of_mnc, + false, + include_identity_to_aka_identity_response, + eap_type_aka_complete_aka_identity_request, + received_aka->get_identifier()); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message(): ") + EAPL("completed returns eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok) + { + // This is the error case. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message(): ") + EAPL("error returns eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (pseudonym.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message pseudonym\n"))); + + get_reauthentication_identity()->reset(); + status = get_pseudonym()->set_copy_of_buffer(&pseudonym); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(get_pseudonym(), false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (IMSI.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message IMSI\n"))); + + get_reauthentication_identity()->reset(); + get_pseudonym()->reset(); + status = get_IMSI()->set_copy_of_buffer(&IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(get_IMSI(), true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (include_identity_to_aka_identity_response == aka_payload_AT_PERMANENT_ID_REQ + && get_IMSI()->get_is_valid_data() == false + && m_automatic_realm_read == false) + { + eap_variable_data_c IMSI(m_am_tools); + eap_variable_data_c pseudonym(m_am_tools); + eap_variable_data_c reauthentication_identity(m_am_tools); + + if (IMSI.get_is_valid() == false + || pseudonym.get_is_valid() == false + || reauthentication_identity.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message ") + EAPL("aka_payload_AT_PERMANENT_ID_REQ\n"))); + + status = query_AKA_IMSI_or_pseudonym_or_reauthentication_id( + &IMSI, + &pseudonym, + &reauthentication_identity, + &m_automatic_realm, + &m_length_of_mnc, + false, + include_identity_to_aka_identity_response, + eap_type_aka_complete_aka_identity_request, + received_aka->get_identifier()); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message(): ") + EAPL("completed returns eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok) + { + // This is the error case. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message(): ") + EAPL("error returns eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (IMSI.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message IMSI\n"))); + + get_reauthentication_identity()->reset(); + get_pseudonym()->reset(); + status = get_IMSI()->set_copy_of_buffer(&IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(get_IMSI(), true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + save_current_state(); + set_state(eap_type_aka_state_analyse_aka_identity_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_request_message(0x%08x).\n"), + this)); + + status = send_aka_identity_response_message( + receive_network_id, + received_aka->get_identifier(), + include_identity_to_aka_identity_response, + &m_automatic_realm); + + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_request_message(1): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_aka_notification_request_message_reauthentication( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t /*aka_packet_length*/, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + EAPL("handle_aka_notification_request_message_reauthentication"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + // The second most significant bit of the notification code is called + // the Phase bit (P bit). It specifies at which phase of the EAP-AKA + // exchange the notification can be used. + if (get_aka_notification_code_P_bit(m_aka_notification_code) == false + && (get_state() == eap_type_aka_state_waiting_for_success + || get_state() == eap_type_aka_state_success + || get_state() == eap_type_aka_state_waiting_for_notification_request_success) + ) + { + // If the P bit is set to zero, + // the notification can only be used after a successful EAP/AKA/ + // Challenge round in full authentication or a successful EAP/AKA/ + // Re-authentication round in reautentication. A re-authentication round + // is considered successful only if the peer has successfully verified + // AT_MAC and AT_COUNTER attributes, and does not include the + // AT_COUNTER_TOO_SMALL attribute in EAP-Response/AKA/Re-authentication. + + // The AT_MAC attribute MUST beincluded if the P bit of the notification + // code in AT_NOTIFICATION is set to zero, and MUST NOT be included in + // cases when the P bit is set to one. The P bit is discussed in Section + // 4.4. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_must_not_be, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_must_not_be // CHECKCODE + ) == true + ) + { + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_aut(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + + if (orig_XKEY.get_is_valid() == false + || orig_K_aut.get_is_valid() == false + || orig_K_encr.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t reauth_counter = 0u; + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_aka->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = check_message_authentication_code( + &orig_K_aut, + p_aka_payloads, + received_aka, + received_aka->get_length()); + if (status != eap_status_ok) + { + (void) initialize_error_message(status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + bool authentication_ok = true; + + // Decrypt and parse encrypted payload. + { + aka_payloads_c * const l_aka_payloads = new aka_payloads_c(m_am_tools); + eap_automatic_variable_c l_aka_payloads_automatic(m_am_tools, l_aka_payloads); + + if (l_aka_payloads == 0 + || l_aka_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = decrypt_DATA_payload( + p_aka_payloads, + &orig_K_encr); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t state_payload_buffer_length = p_aka_payloads->get_ENCR_DATA()->get_data_length(); + const aka_payload_AT_header_c gp_data_payload( + m_am_tools, + p_aka_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), + state_payload_buffer_length); + + status = parse_aka_payload( + &gp_data_payload, + &state_payload_buffer_length, + l_aka_payloads, + received_aka->get_subtype()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (l_aka_payloads->get_COUNTER()->get_payload_included() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u32_t counter = l_aka_payloads->get_COUNTER()->get_original_header()->get_reserved(); + + if (counter == reauth_counter) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_notification_request_message_reauthentication(): ") + EAPL("reauth counter %d OK, %d=%s.\n"), + reauth_counter, + get_state(), + get_state_string())); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_notification_request_message_reauthentication(): ") + EAPL("reauth counter %d wrong, should be %d, %d=%s.\n"), + counter, + reauth_counter, + get_state(), + get_state_string())); + + authentication_ok = false; + } + } + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (authentication_ok == false + || get_aka_notification_code_F_bit(m_aka_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + + set_state(eap_type_aka_state_failure); + + // This will terminate session immediately. + (void) get_type_partner()->set_session_timeout(0ul); + } + + + // EAP-Response/AKA-Notification must be send + // before finish_successful_authentication() call. + status = send_aka_notification_response( + m_aka_notification_code, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (authentication_ok == true + && get_aka_notification_code_F_bit(m_aka_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + if (m_aka_notification_code == eap_aka_notification_F_set_no_P_user_authenticated) + { + if (m_wait_eap_success_packet == false) + { + status = finish_successful_authentication( + receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // This version waits the EAP-Success message. + set_state(eap_type_aka_state_waiting_for_success); + status = eap_status_ok; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, re-authentication OK, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + } + } + + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_notification_request_message(1): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + else if (get_aka_notification_code_P_bit(m_aka_notification_code) == true + && (get_state() == eap_type_aka_state_waiting_for_identity_request + || get_state() == eap_type_aka_state_pending_identity_query + || get_state() == eap_type_aka_state_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_imsi_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_pseydonym_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_analyse_aka_identity_request + || get_state() == eap_type_aka_state_waiting_for_challenge_request + || get_state() == eap_type_aka_state_analyses_challenge_request + || get_state() == eap_type_aka_state_pending_kc_sres_query + || get_state() == eap_type_aka_state_waiting_for_reauth_request + || get_state() == eap_type_aka_state_analyses_reauthentication_request + || get_state() == eap_type_aka_state_waiting_for_success + || get_state() == eap_type_aka_state_success + || get_state() == eap_type_aka_state_waiting_for_notification_request_success + || get_state() == eap_type_aka_state_failure)) + { + // If the P bit is set to one, the notification can only by used before + // the EAP/AKA/Challenge round in full authentication, or before the + // EAP/AKA/Re-authentication round in reauthentication. + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_aka_notification_code_F_bit(m_aka_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + } + else //if (get_aka_notification_code_F_bit(m_aka_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + } + + status = initialize_notification_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_notification_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_aka_notification_request_message_full_authentication( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t /*aka_packet_length*/, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + EAPL("handle_aka_notification_request_message_full_authentication"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + // The second most significant bit of the notification code is called + // the Phase bit (P bit). It specifies at which phase of the EAP-AKA + // exchange the notification can be used. + if (get_aka_notification_code_P_bit(m_aka_notification_code) == false + && (get_state() == eap_type_aka_state_waiting_for_success + || get_state() == eap_type_aka_state_success + || get_state() == eap_type_aka_state_waiting_for_notification_request_success) + ) + { + // If the P bit is set to zero, + // the notification can only be used after a successful EAP/AKA/ + // Challenge round in full authentication or a successful EAP/AKA/ + // Re-authentication round in reautentication. A re-authentication round + // is considered successful only if the peer has successfully verified + // AT_MAC and AT_COUNTER attributes, and does not include the + // AT_COUNTER_TOO_SMALL attribute in EAP-Response/AKA/Re-authentication. + + // The AT_MAC attribute MUST beincluded if the P bit of the notification + // code in AT_NOTIFICATION is set to zero, and MUST NOT be included in + // cases when the P bit is set to one. The P bit is discussed in Section + // 4.4. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_not_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_optional, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_must_not_be // CHECKCODE + ) == true + ) + { + status = check_message_authentication_code( + get_K_aut(), + p_aka_payloads, + received_aka, + received_aka->get_length()); + if (status != eap_status_ok) + { + (void) initialize_error_message(status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_use_result_indication == false + && m_aka_notification_code == eap_aka_notification_F_set_no_P_user_authenticated) + { + // ERROR: We did not require result indication and server send it to us. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_aka_notification_code_F_bit(m_aka_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + + set_state(eap_type_aka_state_failure); + + // This will terminate session immediately. + (void) get_type_partner()->set_session_timeout(0ul); + } + else //if (get_aka_notification_code_F_bit(m_aka_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + if (m_aka_notification_code == eap_aka_notification_F_set_no_P_user_authenticated) + { + if (m_wait_eap_success_packet == false) + { + status = finish_successful_authentication( + receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // This version waits the EAP-Success message. + set_state(eap_type_aka_state_waiting_for_success); + status = eap_status_ok; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, full-authentication OK, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + } + } + + status = send_aka_notification_response( + m_aka_notification_code, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_notification_request_message(1): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + else if (get_aka_notification_code_P_bit(m_aka_notification_code) == true + && (get_state() == eap_type_aka_state_waiting_for_identity_request + || get_state() == eap_type_aka_state_pending_identity_query + || get_state() == eap_type_aka_state_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_imsi_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_pseydonym_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_analyse_aka_identity_request + || get_state() == eap_type_aka_state_waiting_for_challenge_request + || get_state() == eap_type_aka_state_analyses_challenge_request + || get_state() == eap_type_aka_state_pending_kc_sres_query + || get_state() == eap_type_aka_state_waiting_for_reauth_request + || get_state() == eap_type_aka_state_analyses_reauthentication_request + || get_state() == eap_type_aka_state_waiting_for_success + || get_state() == eap_type_aka_state_success + || get_state() == eap_type_aka_state_waiting_for_notification_request_success + || get_state() == eap_type_aka_state_failure)) + { + // If the P bit is set to one, the notification can only by used before + // the EAP/AKA/Challenge round in full authentication, or before the + // EAP/AKA/Re-authentication round in reauthentication. + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_aka_notification_code_F_bit(m_aka_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + } + else //if (get_aka_notification_code_F_bit(m_aka_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + } + + status = initialize_notification_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_notification_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_aka_notification_request_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_UNREFERENCED_PARAMETER(received_aka); + EAP_UNREFERENCED_PARAMETER(aka_packet_length); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + + if (get_state() == eap_type_aka_state_waiting_for_identity_request + || get_state() == eap_type_aka_state_pending_identity_query + || get_state() == eap_type_aka_state_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_imsi_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_pseydonym_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_analyse_aka_identity_request + || get_state() == eap_type_aka_state_waiting_for_challenge_request + || get_state() == eap_type_aka_state_analyses_challenge_request + || get_state() == eap_type_aka_state_pending_kc_sres_query + || get_state() == eap_type_aka_state_waiting_for_notification_request_success + || get_state() == eap_type_aka_state_waiting_for_success + || get_state() == eap_type_aka_state_waiting_for_reauth_request + || get_state() == eap_type_aka_state_analyses_reauthentication_request + || get_state() == eap_type_aka_state_success + || get_state() == eap_type_aka_state_failure + ) + { + // This could be first or retransmission request. + + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_optional, // MAC + aka_payloads_c::eap_aka_payload_status_optional, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_optional, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_optional, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_must_not_be // CHECKCODE + ) == true + ) + { + // NOTE, this message is unauthenticated. Anybody could sent this message. + + // We store the received notification code. This will be handled after session timeouts. + m_aka_notification_code = + static_cast( + p_aka_payloads->get_NOTIFICATION()->get_original_header()->get_reserved()); + + save_current_state(); + + set_last_eap_identifier(received_aka->get_identifier()); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_notification_request_message(0x%08x), ") + EAPL("notification_code = 0x%04x, F bit %d, P bit %d, state %d=%s.\n"), + this, + m_aka_notification_code, + get_aka_notification_code_F_bit(m_aka_notification_code), + get_aka_notification_code_P_bit(m_aka_notification_code), + get_state(), + get_state_string())); + + if (m_authentication_type == AKA_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + status = handle_aka_notification_request_message_reauthentication( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = handle_aka_notification_request_message_full_authentication( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_notification_request_message(1): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_notification_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_challenge_request_message( + const eap_am_network_id_c * const /* receive_network_id */, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + if (get_state() == eap_type_aka_state_waiting_for_challenge_request + || get_state() == eap_type_aka_state_waiting_for_reauth_request // Server could start full authentication. + || (get_state() == eap_type_aka_state_waiting_for_success && m_use_result_indication == false) + || (get_state() == eap_type_aka_state_waiting_for_notification_request_success && m_use_result_indication == true)) + { + // This could be first or retransmission request. + + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_be, // MAC + aka_payloads_c::eap_aka_payload_status_optional, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_optional, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_optional, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_optional // CHECKCODE + ) == true + ) + { + if (p_aka_payloads->get_RESULT_IND()->get_payload_included() == true) + { + m_use_result_indication = m_allow_use_result_indication; + } + else + { + m_use_result_indication = false; + } + + if (p_aka_payloads->get_IV()->get_payload_included() == true + || p_aka_payloads->get_ENCR_DATA()->get_payload_included() == true) + { + if (p_aka_payloads->get_IV()->get_payload_included() == true + && p_aka_payloads->get_ENCR_DATA()->get_payload_included() == true) + { + // OK + } + else + { + // All of these must be included + // or none of these must be included. + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + + // The whole EAP packet must copied. + // The MAC is checked later after n*Kc and n*SRES is get from AKA. + status = get_saved_EAP_packet()->set_copy_of_buffer( + received_aka->get_header_buffer(aka_packet_length), + aka_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (p_aka_payloads->get_CHECKCODE()->get_payload_included() == true) + { + // Save AT_CHECKCODE. + status = m_received_checkcode.set_copy_of_buffer( + p_aka_payloads->get_CHECKCODE()->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (get_state() == eap_type_aka_state_waiting_for_reauth_request) + { + // Server started a full authentication. + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + } + + set_last_eap_identifier(received_aka->get_identifier()); + + save_current_state(); + set_state(eap_type_aka_state_analyses_challenge_request); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c CK(m_am_tools); + eap_variable_data_c IK(m_am_tools); + eap_variable_data_c RES(m_am_tools); + + if (CK.get_is_valid() == false + || IK.get_is_valid() == false + || RES.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_type_aka_authentication_vector_c authentication_vector(m_am_tools); + + if (authentication_vector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = authentication_vector.get_RAND()->set_copy_of_buffer( + p_aka_payloads->get_RAND()->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = authentication_vector.get_AUTN()->set_copy_of_buffer( + p_aka_payloads->get_AUTN()->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = query_AKA_RES( + &authentication_vector); + if (status == eap_status_pending_request) + { + // Request will be completed later using complete_AKA_RES_query() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status == eap_status_completed_request) + { + // Request was already completed by AM using complete_AKA_RES_query() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status == eap_status_success) + { + // eap_status_success means the authentication was successful. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_ok) + { + // The query_AKA_RES() function call is synchronous. + // We must call process_AKA_kc_sres(). + } + else + { + // This is an error case. + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // eap_status_ok status value means n_kc and n_sres were read but not processed. + // Next we must call process_AKA_kc_sres(). + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = process_AKA_kc_sres( + &authentication_vector); + + if (status != eap_status_ok + && status != eap_status_success) + { + (void) initialize_error_message(status); + + restore_saved_previous_state(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_challenge_request_message(6): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (get_state() == eap_type_aka_state_pending_kc_sres_query) + { + // This is re-transmitted EAP-Request/AKA/Challenge. + // We dischard it quietly. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_aka_c::handle_challenge_request_message(): ") + EAPL("Re-transmitted message %d=%s dropped in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else + { + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_challenge_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_reauthentication_request_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + if (get_state() == eap_type_aka_state_waiting_for_reauth_request + || (get_state() == eap_type_aka_state_waiting_for_success && m_use_result_indication == false) + || (get_state() == eap_type_aka_state_waiting_for_notification_request_success && m_use_result_indication == true)) + { + // This could be first or retransmission request. + + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_optional, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_optional // CHECKCODE + ) == true + ) + { + + set_last_eap_identifier(received_aka->get_identifier()); + + save_current_state(); + set_state(eap_type_aka_state_analyses_reauthentication_request); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_aut(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + + if (orig_XKEY.get_is_valid() == false + || orig_K_aut.get_is_valid() == false + || orig_K_encr.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t reauth_counter = 0u; + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_aka->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = check_message_authentication_code( + &orig_K_aut, + p_aka_payloads, + received_aka, + aka_packet_length); + if (status != eap_status_ok) + { + (void) initialize_error_message(status); + + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (p_aka_payloads->get_CHECKCODE()->get_payload_included() == true) + { + // Verify AT_CHECKCODE. + status = checkcode_verify( + p_aka_payloads->get_CHECKCODE()->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (p_aka_payloads->get_RESULT_IND()->get_payload_included() == true) + { + m_use_result_indication = m_allow_use_result_indication; + } + else + { + m_use_result_indication = false; + } + + // Decrypt and parse encrypted payload. + if (p_aka_payloads->get_IV()->get_payload_included() == true + || p_aka_payloads->get_ENCR_DATA()->get_payload_included() == true) + { + if (p_aka_payloads->get_IV()->get_payload_included() == true + && p_aka_payloads->get_ENCR_DATA()->get_payload_included() == true + && p_aka_payloads->get_MAC()->get_payload_included() == true) + { + aka_payloads_c * const l_aka_payloads = new aka_payloads_c(m_am_tools); + eap_automatic_variable_c l_aka_payloads_automatic(m_am_tools, l_aka_payloads); + + if (l_aka_payloads == 0 + || l_aka_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + bool include_at_counter_too_small = false; + + status = decrypt_DATA_payload( + p_aka_payloads, + &orig_K_encr); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t state_payload_buffer_length = p_aka_payloads->get_ENCR_DATA()->get_data_length(); + const aka_payload_AT_header_c gp_data_payload( + m_am_tools, + p_aka_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), + state_payload_buffer_length); + + status = parse_aka_payload( + &gp_data_payload, + &state_payload_buffer_length, + l_aka_payloads, + received_aka->get_subtype()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (l_aka_payloads->get_COUNTER()->get_payload_included() == false + || l_aka_payloads->get_NONCE_S()->get_payload_included() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u32_t counter = l_aka_payloads->get_COUNTER()->get_original_header()->get_reserved(); + + if (m_aka_test_version == true + && m_fail_reauthentication_counter_check == true) + { + --counter; + } + + if (get_saved_previous_state() == eap_type_aka_state_waiting_for_reauth_request) + { + if (counter < reauth_counter) + { + // When the client detects that the + // counter value is not fresh, it includes the AT_COUNTER_TOO_SMALL + // attribute in EAP-Response/AKA/Re-authentication. This attribute + // doesn't contain any data but it is a request for the server to + // initiate full authentication. In this case, the client MUST ignore + // the contents of the server's AT_NEXT_REAUTH_ID attribute. + include_at_counter_too_small = true; + l_aka_payloads->get_NEXT_REAUTH_ID()->reset(); + } + } + else if (get_saved_previous_state() == eap_type_aka_state_waiting_for_success + || get_state() == eap_type_aka_state_waiting_for_notification_request_success) + { + // This is retransmission request. + if (counter+1ul < reauth_counter) + { + // When the client detects that the + // counter value is not fresh, it includes the AT_COUNTER_TOO_SMALL + // attribute in EAP-Response/AKA/Re-authentication. This attribute + // doesn't contain any data but it is a request for the server to + // initiate full authentication. In this case, the client MUST ignore + // the contents of the server's AT_NEXT_REAUTH_ID attribute. + include_at_counter_too_small = true; + l_aka_payloads->get_NEXT_REAUTH_ID()->reset(); + } + } + + if (l_aka_payloads->get_NEXT_REAUTH_ID()->get_payload_included() == true) + { + // Save next re-authentication identity. + // AKA AM could store pseudonym to favourite place. + status = m_am_type_aka->store_reauthentication_id( + get_send_network_id(), + l_aka_payloads->get_NEXT_REAUTH_ID()->get_payload_buffer()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // AKA AM should remove re-authentiction ID from favourite place. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_reauthentication_request_message(0x%08x): Resets re-authentication identity from database.\n"), + this)); + + status = m_am_type_aka->store_reauthentication_id( + get_send_network_id(), + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + get_reauthentication_identity()->reset(); + } + + status = get_NONCE_S()->set_copy_of_buffer( + l_aka_payloads->get_NONCE_S()->get_payload_buffer()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_reauthentication_response_message( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + get_NAI(), + l_aka_payloads->get_NONCE_S()->get_payload_buffer(), + static_cast(counter), + received_aka->get_identifier(), + include_at_counter_too_small); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // OK, server re-authenticates correcly. + + if (include_at_counter_too_small == true) + { + // Re-authentication failed. + // We will expect full authentication. + set_state(eap_type_aka_state_waiting_for_aka_identity_request); + status = eap_status_ok; + } + else + { + // Authentication was successful. + if (m_use_result_indication == true) + { + // This version waits the result indication. + set_state(eap_type_aka_state_waiting_for_notification_request_success); + status = eap_status_ok; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, re-authentication OK, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_wait_eap_success_packet == false) + { + // This version does not wait EAP-Success message. + status = finish_successful_authentication( + receive_network_id); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // This version waits the EAP-Success message. + set_state(eap_type_aka_state_waiting_for_success); + status = eap_status_ok; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, re-authentication OK, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // All of these must be included + // or none of these must be included. + restore_saved_previous_state(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + else + { + // Not correct AKA-payloads are included. + restore_saved_previous_state(); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_reauthentication_request_message(6): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_reauthentication_request_message(6): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_reauthentication_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +// +eap_status_e eap_type_aka_c::handle_eap_identity_query( + const eap_am_network_id_c * const send_network_id, + eap_variable_data_c * const p_identity, + const u8_t eap_identifier, + const eap_variable_data_c * const IMSI, + const eap_variable_data_c * const pseudonym, + const eap_variable_data_c * const reauthentication_identity, + const eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + const u32_t length_of_mnc, + const bool must_be_synchronous) +{ + const eap_variable_data_c *current_identity = 0; + + eap_variable_data_c manual_identity(m_am_tools); + + if (manual_identity.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + bool IMSI_is_used = false; + bool reauth_id_is_used = false; + eap_status_e status = eap_status_process_general_error; + + if (get_state() != eap_type_aka_state_pending_identity_query) + { + // Authentication is state is wrong. Cannot continue. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_gsmsim_state); + } + + if (must_be_synchronous == true + && p_identity == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (IMSI == 0 + || IMSI->get_is_valid_data() == false + || IMSI->get_data_length() < EAP_TYPE_AKA_MINIMUM_IMSI_LENGTH) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + + // We must save queried re-authentication and pseudonym identity. + if (reauthentication_identity != 0 + && reauthentication_identity->get_is_valid_data() == true) + { + status = get_reauthentication_identity()->set_copy_of_buffer(reauthentication_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (pseudonym != 0 + && pseudonym->get_is_valid_data() == true) + { + status = get_pseudonym()->set_copy_of_buffer(pseudonym); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + if (m_use_manual_username == true + && m_manual_username.get_is_valid_data() == true + && m_use_manual_realm == true + && m_manual_realm.get_is_valid_data() == true) + { + // Here manual username could be zero or more bytes in length. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_eap_identity_query(): Client sends manual username and realm.\n"))); + + status = manual_identity.set_copy_of_buffer(&m_manual_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + current_identity = &manual_identity; + IMSI_is_used = false; + } + else if (m_use_manual_username == true + && m_manual_username.get_is_valid_data() == true + && m_use_manual_realm == false) + { + // We will send manual username with automatic realm. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_eap_identity_query(): Client sends manual username and automatic realm.\n"))); + + status = manual_identity.set_copy_of_buffer(&m_manual_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + current_identity = &manual_identity; + IMSI_is_used = false; + } + else if (reauthentication_identity != 0 + && reauthentication_identity->get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_eap_identity_query(): Client sends re-authentication identity.\n"))); + + current_identity = reauthentication_identity; + IMSI_is_used = false; + reauth_id_is_used = true; + + status = get_reauthentication_identity()->set_copy_of_buffer(reauthentication_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (pseudonym != 0 + && pseudonym->get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_eap_identity_query(): Client sends pseudonym username.\n"))); + + current_identity = pseudonym; + IMSI_is_used = false; + + status = get_pseudonym()->set_copy_of_buffer(pseudonym); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (m_use_random_identity_on_eap_identity_response == true) + { + // Generate random username. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_eap_identity_query(): Client sends random username.\n"))); + + const u32_t EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH = 16; + + eap_variable_data_c random_username(m_am_tools); + eap_variable_data_c random_bytes(m_am_tools); + + if (random_username.get_is_valid() == false + || random_bytes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = random_bytes.init(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + random_bytes.set_is_valid(); + random_bytes.set_data_length(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH); + + status = m_am_tools->get_crypto()->get_rand_bytes( + random_bytes.get_data(random_bytes.get_data_length()), + random_bytes.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Change first byte to 'r' to make it different than the default IMSI prefix '1'. + // This will cause the first identity char 'S' after ascii armor conversion. + *random_bytes.get_data(1ul) = static_cast('r'); + + const u32_t EAP_AKA_RANDOM_IDENTITY_BUFFER_LENGTH + = 3ul+(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH+1u)*4u/3u; + + status = random_username.init(EAP_AKA_RANDOM_IDENTITY_BUFFER_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + random_username.set_is_valid(); + random_username.set_data_length(EAP_AKA_RANDOM_IDENTITY_BUFFER_LENGTH); + + u32_t random_identity_length = random_username.get_data_length(); + + status = m_am_tools->convert_bytes_to_ascii_armor( + random_bytes.get_data_offset(0u, random_bytes.get_data_length()), + random_bytes.get_data_length(), + random_username.get_data_offset(0u, random_username.get_data_length()), + &random_identity_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + random_username.set_data_length(random_identity_length); + + status = manual_identity.set_copy_of_buffer(&random_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + current_identity = &manual_identity; + IMSI_is_used = false; + } + else if (IMSI != 0 + && IMSI->get_is_valid_data() == true + && IMSI->get_data_length() >= EAP_TYPE_AKA_MINIMUM_IMSI_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_eap_identity_query(): Client sends IMSI username.\n"))); + + current_identity = IMSI; + IMSI_is_used = true; + } + + if (current_identity != 0) + { + status = get_IMSI()->set_copy_of_buffer(IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(current_identity, IMSI_is_used); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("current_identity"), + current_identity->get_data(current_identity->get_data_length()), + current_identity->get_data_length())); + + eap_variable_data_c NAI(m_am_tools); + + if (NAI.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (reauth_id_is_used == true) + { + // Re-authentication identity is NAI. + status = NAI.set_copy_of_buffer(current_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = generate_nai( + &NAI, + m_use_manual_realm, + get_nai_realm(), + current_identity, + IMSI_is_used, + get_IMSI(), + automatic_realm, + length_of_mnc); + } + + if (status == eap_status_ok) + { + status = get_NAI()->set_copy_of_buffer(&NAI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (must_be_synchronous == false) + { + status = get_type_partner()->complete_eap_identity_query( + send_network_id, + get_NAI(), + eap_identifier); + if (status == eap_status_ok) + { + if (p_identity != 0) + { + status = p_identity->set_copy_of_buffer(get_NAI()); + } + + if (status == eap_status_ok) + { + status = eap_status_completed_request; + } + } + } + else + { + status = p_identity->set_copy_of_buffer(get_NAI()); + } + + if (status == eap_status_ok + || status == eap_status_completed_request) + { + if (m_use_random_identity_on_eap_identity_response == true) + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_NONE; + set_identity_type(AKA_IDENTITY_TYPE_NONE); + set_state(eap_type_aka_state_waiting_for_aka_identity_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_eap_identity_query(0x%08x): Selects none.\n"), + this)); + } + else if (reauthentication_identity != 0 + && reauthentication_identity->get_is_valid_data() == true) + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_REAUTHENTICATION; + set_identity_type(AKA_IDENTITY_TYPE_RE_AUTH_ID); + set_state(eap_type_aka_state_waiting_for_reauth_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_eap_identity_query(0x%08x): Selects fast re-authentication and re-authentication identity.\n"), + this)); + } + else if (pseudonym != 0 + && pseudonym->get_is_valid_data() == true) + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(AKA_IDENTITY_TYPE_PSEUDONYM_ID); + set_state(eap_type_aka_state_waiting_for_challenge_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_eap_identity_query(0x%08x): Selects full authentication and pseudonym identity.\n"), + this)); + } + else + { + if (m_use_manual_username == true) + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_NONE; + set_identity_type(AKA_IDENTITY_TYPE_NONE); + set_state(eap_type_aka_state_waiting_for_aka_identity_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_eap_identity_query(0x%08x): Selects none.\n"), + this)); + } + else + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(AKA_IDENTITY_TYPE_IMSI_ID); + set_state(eap_type_aka_state_waiting_for_challenge_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_eap_identity_query(0x%08x): Selects full authentication and IMSI identity.\n"), + this)); + } + } + } + } + } + else + { + status = eap_status_illegal_nai; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eap_type_aka_c::query_eap_identity( + const bool must_be_synchronous, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_variable_data_c IMSI(m_am_tools); + eap_variable_data_c pseudonym(m_am_tools); + eap_variable_data_c reauthentication_identity(m_am_tools); + + if (IMSI.get_is_valid() == false + || pseudonym.get_is_valid() == false + || reauthentication_identity.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + eap_status_e status = eap_status_process_general_error; + + if (get_state() == eap_type_aka_state_none) + { + status = new_handler( + receive_network_id, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::query_eap_identity(): eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + if (get_state() == eap_type_aka_state_waiting_for_identity_request + || (m_aka_test_version == true + && get_state() == eap_type_aka_state_success)) // This one is for testing purposes. + { + set_last_eap_identifier(eap_identifier); + + eap_variable_data_c automatic_realm(m_am_tools); + if (automatic_realm.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = query_AKA_IMSI_or_pseudonym_or_reauthentication_id( + &IMSI, + &pseudonym, + &reauthentication_identity, + &automatic_realm, + &m_length_of_mnc, + must_be_synchronous, + aka_payload_AT_ANY_ID_REQ, + eap_type_aka_complete_query_eap_identity, + eap_identifier); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::query_eap_identity(): ") + EAPL("completed returns eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok) + { + // This is the error case. + restore_saved_previous_state(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::query_eap_identity(): ") + EAPL("error returns eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // status == eap_status_ok + { + status = handle_eap_identity_query( + &send_network_id, + identity, + eap_identifier, + &IMSI, + &pseudonym, + &reauthentication_identity, + &automatic_realm, + m_length_of_mnc, + must_be_synchronous); + + if (status != eap_status_ok + && status != eap_status_completed_request) + { + restore_saved_previous_state(); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::query_eap_identity(): handle_eap_identity_query() ") + EAPL("returns eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (get_state() == eap_type_aka_state_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_pseydonym_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_imsi_waiting_for_aka_identity_request + || get_state() == eap_type_aka_state_waiting_for_reauth_request) + { + // This is re-transmission request. We do not change our state. + // Just send EAP-Identity again. + if (get_NAI()->get_is_valid_data() == true) + { + status = identity->set_copy_of_buffer(get_NAI()); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::query_eap_identity(): handle_eap_identity_query() ") + EAPL("returns eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::query_eap_identity(): ") + EAPL("EAP-Request/Identity cannot be completed, identity (NAI) ") + EAPL("is missing. in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (get_state() == eap_type_aka_state_pending_identity_query) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::query_eap_identity(): ignores re-transmitted query_eap_identity()") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); + } + + + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("WARNING: eap_type_aka_c::query_eap_identity(): ") + EAPL("Wrong message EAP-Request/Identity in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::set_initial_eap_identifier( + const eap_am_network_id_c * const receive_network_id, + const u8_t initial_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = new_handler( + receive_network_id, + false); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::aka_packet_process(): ") + EAPL("new_handler() failed, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_last_eap_identifier(static_cast(initial_identifier-1u)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::eap_acknowledge( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + if (get_state() == eap_type_aka_state_waiting_for_success + && m_wait_eap_success_packet == true) + { + status = finish_successful_authentication( + receive_network_id); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ignored eap_acknowledge(): state %d=%s, is client %d\n"), + get_state(), + get_state_string(), + (m_is_client == true))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(_DEBUG) && defined(USE_EAP_AKA_TEST_VECTORS) + #include "read_rand_and_triplets.h" +#endif //#if defined(_DEBUG) && defined(USE_EAP_AKA_TEST_VECTORS) + + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::generate_nonce( + const u32_t nonce_size, + eap_variable_data_c * const nonce) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = nonce->init(nonce_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + nonce->set_is_valid(); + nonce->set_data_length(nonce_size); + +#if defined(_DEBUG) && defined(USE_EAP_AKA_TEST_VECTORS) + if (m_nonce_mt_file.get_is_valid() == true) + { + status = read_rand_from_file(m_am_tools, &m_nonce_mt_file, nonce); + if (status != eap_status_ok) + { + status = m_am_tools->get_crypto()->get_rand_bytes( + nonce->get_data(nonce->get_data_length()), + nonce->get_data_length()); + } + } + else +#endif //#if defined(_DEBUG) && defined(USE_EAP_AKA_TEST_VECTORS) + { + status = m_am_tools->get_crypto()->get_rand_bytes( + nonce->get_data(nonce->get_data_length()), + nonce->get_data_length()); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,477 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 68 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_tools.h" +#include "eap_header.h" +#include "eap_header_string.h" +#include "eap_type_aka_header.h" + +/** @file */ + + +// +EAP_FUNC_EXPORT aka_payload_AT_header_c::~aka_payload_AT_header_c() +{ +} + +// +EAP_FUNC_EXPORT aka_payload_AT_header_c::aka_payload_AT_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT aka_payload_AT_type_e aka_payload_AT_header_c::get_current_payload() const +{ + const u8_t * const payload_data = get_header_offset(m_type_offset, sizeof(u8_t)); + if (payload_data != 0) + { + return static_cast(*payload_data); + } + else + { + return aka_payload_NONE; + } +} + +EAP_FUNC_EXPORT u16_t aka_payload_AT_header_c::get_payload_length() const +{ + const u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u8_t)); + if (length_data != 0) + { + return static_cast(*length_data * 4u); + } + else + { + return 0ul; + } +} + +EAP_FUNC_EXPORT u16_t aka_payload_AT_header_c::get_reserved() const +{ + const u8_t * const reserved = get_header_offset(m_reserved_offset, sizeof(u16_t)); + if (reserved != 0) + { + return eap_read_u16_t_network_order(reserved, sizeof(u16_t)); + } + else + { + // this is illegal reserved field value. + return 0xffff; + } +} + +EAP_FUNC_EXPORT u8_t * aka_payload_AT_header_c::get_reserved_pointer(const u32_t contignuous_bytes) const +{ + const u32_t required_data_bytes = contignuous_bytes - 2ul; + + if (get_data_length() >= required_data_bytes + && required_data_bytes > 0) + { + u8_t * const reserved = get_header_offset(m_reserved_offset, contignuous_bytes); + return reserved; + } + else + { + EAP_ASSERT( + get_data_length() >= required_data_bytes + && required_data_bytes > 0); + } + return 0; +} + +EAP_FUNC_EXPORT u32_t aka_payload_AT_header_c::get_data_length() const +{ + if (get_payload_length() > get_header_length()) + return static_cast(get_payload_length()-get_header_length()); + else + return 0; +} + +EAP_FUNC_EXPORT u16_t aka_payload_AT_header_c::get_header_length() +{ + return m_data_offset; +} + +EAP_FUNC_EXPORT u16_t aka_payload_AT_header_c::get_max_payload_data_length() +{ + return static_cast((0xff*4u-get_header_length())); +} + +EAP_FUNC_EXPORT u8_t * aka_payload_AT_header_c::get_data(const u32_t contignuous_bytes) const +{ + if (get_data_length() >= contignuous_bytes + && contignuous_bytes > 0) + { + return get_header_offset(m_data_offset, contignuous_bytes); // Data begins after the header. + } + else + { + EAP_ASSERT( + get_data_length() >= contignuous_bytes + && contignuous_bytes > 0); + } + return 0; +} + +EAP_FUNC_EXPORT u8_t * aka_payload_AT_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + if (get_header_buffer_length()-get_header_length() >= offset+contignuous_bytes + && contignuous_bytes > 0) + { + u8_t * const data = get_header_offset(m_data_offset, contignuous_bytes); + if (data != 0) + { + return data+offset; // Data begins after the header. + } + else + { + return 0; + } + } + else + { + EAP_ASSERT( + get_data_length() >= offset+contignuous_bytes + && contignuous_bytes > 0); + } + return 0; +} + +EAP_FUNC_EXPORT u8_t * aka_payload_AT_header_c::get_next_header() const +{ + if (get_header_buffer_length() >= get_data_length()+2ul*get_header_length()) + { + return get_data_offset(get_data_length(), get_header_length()); + } + else + { + return 0; + } +} + +// Mostly this is zero. +// With some attributes this is used for special purposes. +EAP_FUNC_EXPORT void aka_payload_AT_header_c::set_reserved(const u16_t reserved) +{ + u8_t *reserved_data = get_header_offset(m_reserved_offset, sizeof(u16_t)); + + EAP_ASSERT(reserved_data != 0); + + reserved_data[0] = static_cast(((reserved & 0xff00) >> 8)); + reserved_data[1] = static_cast((reserved & 0x00ff)); +} + +EAP_FUNC_EXPORT void aka_payload_AT_header_c::set_current_payload(const aka_payload_AT_type_e p_current_payload) +{ + EAP_ASSERT_ALWAYS(p_current_payload == static_cast(static_cast(p_current_payload))); + + u8_t * const payload_type = get_header_offset(m_type_offset, sizeof(u8_t)); + + EAP_ASSERT(payload_type != 0); + + *payload_type = static_cast(p_current_payload); +} + +EAP_FUNC_EXPORT void aka_payload_AT_header_c::set_data_length(const u16_t p_data_length) +{ + u32_t total_length = p_data_length+aka_payload_AT_header_c::get_header_length(); + u32_t remaider = total_length % 4u; + + EAP_ASSERT(remaider == 0); + EAP_ASSERT((total_length / 4u) <= 0xff); + + EAP_UNREFERENCED_PARAMETER(remaider); + + u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u8_t)); + + EAP_ASSERT(length_data != 0); + + *length_data = static_cast(total_length/4u); +} + +EAP_FUNC_EXPORT void aka_payload_AT_header_c::reset_header(const u16_t data_length) +{ + set_reserved(0u); + set_current_payload(aka_payload_NONE); + set_data_length(data_length); +} + +EAP_FUNC_EXPORT eap_const_string aka_payload_AT_header_c::get_payload_AT_string(const aka_payload_AT_type_e payload_type) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(payload_type, aka_payload_NONE) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_RAND) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_AUTN) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_RES) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_AUTS) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_PADDING) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_PERMANENT_ID_REQ) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_MAC) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_NOTIFICATION) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_ANY_ID_REQ) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_IDENTITY) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_FULLAUTH_ID_REQ) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_COUNTER) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_COUNTER_TOO_SMALL) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_NONCE_S) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_CLIENT_ERROR_CODE) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_IV) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_ENCR_DATA) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_NEXT_PSEUDONYM) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_NEXT_REAUTH_ID) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_RESULT_IND) + else EAP_IF_RETURN_STRING(payload_type, aka_payload_AT_CHECKCODE) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(payload_type); + return EAPL("Unknown AKA payload AT"); + } +} + +EAP_FUNC_EXPORT eap_const_string aka_payload_AT_header_c::get_payload_AT_string() const +{ + return get_payload_AT_string(get_current_payload()); +} + +EAP_FUNC_EXPORT eap_status_e aka_payload_AT_header_c::check_header() const +{ + if (get_reserved() != 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + + +// +EAP_FUNC_EXPORT aka_header_c::~aka_header_c() +{ +} + +// +EAP_FUNC_EXPORT aka_header_c::aka_header_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length) + : eap_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT aka_subtype_e aka_header_c::get_subtype() const +{ + u32_t subtype_offset(get_sub_type_offset()); + + const u8_t * const subtype_data = get_header_offset(subtype_offset, sizeof(u8_t)); + if (subtype_data != 0) + { + return static_cast(*subtype_data); + } + else + { + return aka_subtype_NONE; + } +} + +EAP_FUNC_EXPORT u16_t aka_header_c::get_data_length() const +{ + if (get_length() > static_cast(get_header_length())) + { + return static_cast(get_length()-static_cast(get_header_length())); + } + else + { + return 0; + } +} + +EAP_FUNC_EXPORT u32_t aka_header_c::get_sub_type_offset() const +{ + return eap_header_base_c::get_header_length() + eap_header_base_c::get_type_field_length() + m_subtype_delta_offset; +} + +EAP_FUNC_EXPORT u32_t aka_header_c::get_header_length() const +{ + return get_sub_type_offset() + m_data_delta_offset; +} + +EAP_FUNC_EXPORT u8_t * aka_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + u32_t data_length = get_data_length(); + + if (data_length >= offset+contignuous_bytes + && contignuous_bytes > 0u) + { + return (get_header_offset(get_header_length(), contignuous_bytes)+offset); // Data begins after the header. + } + else + { + EAP_ASSERT(get_data_length() > 0u); + } + return 0; +} + + +EAP_FUNC_EXPORT u8_t * aka_header_c::get_data(const u32_t contignuous_bytes) const +{ + return get_data_offset(0u, contignuous_bytes); +} + + +EAP_FUNC_EXPORT u16_t aka_header_c::get_reserved() const +{ + u32_t reserved_offset(get_sub_type_offset()+m_reserved_delta_offset); + + u8_t * const reserved_data = get_header_offset(reserved_offset, sizeof(u16_t)); + if (reserved_data != 0) + { + return eap_read_u16_t_network_order(reserved_data, sizeof(u16_t)); + } + else + { + // This is illegal reserved data value. + return 0xffff; + } +} + + +EAP_FUNC_EXPORT eap_status_e aka_header_c::check_header() const +{ + if (get_type() != eap_type_aka) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (get_reserved() != static_cast(0ul)) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +EAP_FUNC_EXPORT eap_const_string aka_header_c::get_subtype_string() const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + const aka_subtype_e packet_type = get_subtype(); + + EAP_IF_RETURN_STRING(packet_type, aka_subtype_NONE) + else EAP_IF_RETURN_STRING(packet_type, aka_subtype_Synchronization_Failure) + else EAP_IF_RETURN_STRING(packet_type, aka_subtype_Authentication_Reject) + else EAP_IF_RETURN_STRING(packet_type, aka_subtype_Identity) + else EAP_IF_RETURN_STRING(packet_type, aka_subtype_Challenge) + else EAP_IF_RETURN_STRING(packet_type, aka_subtype_Notification) + else EAP_IF_RETURN_STRING(packet_type, aka_subtype_Re_authentication) + else EAP_IF_RETURN_STRING(packet_type, aka_subtype_Client_Error) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown AKA-type"); + } +} + +EAP_FUNC_EXPORT eap_const_string aka_header_c::get_code_string() const +{ + return eap_header_string_c::get_eap_code_string(get_code()); +} + +EAP_FUNC_EXPORT eap_const_string aka_header_c::get_eap_type_string() const +{ + if (get_length() <= eap_header_base_c::get_header_length()) + { + return EAPL("No EAP-type"); + } + + return eap_header_string_c::get_eap_type_string(get_type()); +} + +EAP_FUNC_EXPORT void aka_header_c::set_reserved(const u16_t reserved) +{ + u32_t reserved_offset(get_sub_type_offset()+m_reserved_delta_offset); + u8_t *reserved_data = get_header_offset(reserved_offset, sizeof(u16_t)); + + EAP_ASSERT(reserved_data != 0); + + reserved_data[0] = static_cast((reserved & 0xff00) >> 8); + reserved_data[1] = static_cast(reserved & 0x00ff); +} + +EAP_FUNC_EXPORT void aka_header_c::set_subtype(const aka_subtype_e p_subtype) +{ + u32_t subtype_offset(get_sub_type_offset()); + u8_t * const subtype_data = get_header_offset(subtype_offset, sizeof(u8_t)); + + EAP_ASSERT(subtype_data != 0); + + *subtype_data = static_cast(p_subtype); +} + +EAP_FUNC_EXPORT void aka_header_c::set_data_length( + const u32_t p_data_length, + const bool expanded_type_when_true) +{ + EAP_ASSERT_ALWAYS(p_data_length+get_header_length() <= 0xffff); + + set_length( + static_cast(p_data_length+get_header_length()), + expanded_type_when_true); +} + +EAP_FUNC_EXPORT void aka_header_c::reset_header( + const u32_t buffer_length, + const bool expanded_type_when_true) +{ + eap_header_base_c::set_length( + static_cast(buffer_length), + expanded_type_when_true); + + set_code(eap_code_none); + + set_identifier(0u); + + set_type( + eap_type_aka, + expanded_type_when_true); // AKA = 18 + + set_subtype(aka_subtype_NONE); + set_reserved(0u); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_payloads.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_payloads.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,356 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 69 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_type_aka_payloads.h" +#include "abs_eap_am_tools.h" +#include "eap_tools.h" + + +EAP_FUNC_EXPORT aka_fixed_data_c::~aka_fixed_data_c() +{ +} + +EAP_FUNC_EXPORT aka_fixed_data_c::aka_fixed_data_c( + abs_eap_am_tools_c * const tools) + : m_is_valid(false) + , m_original_header(tools, 0, 0) + , m_type(0) + , m_data(0) +{ +} + +EAP_FUNC_EXPORT bool aka_fixed_data_c::get_is_valid() const +{ + return m_is_valid; +} + +EAP_FUNC_EXPORT const aka_payload_AT_header_c * aka_fixed_data_c::get_original_header() +{ + return &m_original_header; +} + +EAP_FUNC_EXPORT u16_t aka_fixed_data_c::get_type(abs_eap_am_tools_c * const m_am_tools) const +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + if (m_is_valid == true) + { + return m_type; + } + else + { + EAP_ASSERT_ALWAYS(m_is_valid == true); + return 0u; + } +} + +EAP_FUNC_EXPORT u16_t aka_fixed_data_c::get_data(abs_eap_am_tools_c * const m_am_tools) const +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + if (m_is_valid == true) + { + return m_data; + } + else + { + EAP_ASSERT_ALWAYS(m_is_valid == true); + return 0u; + } +} + +EAP_FUNC_EXPORT void aka_fixed_data_c::set_data(const aka_payload_AT_header_c * const original_header, + const u16_t type, const u16_t data) +{ + m_is_valid = true; + m_original_header.set_header_buffer( + original_header->get_header_buffer(original_header->get_header_buffer_length()), + original_header->get_header_buffer_length()); + m_type = static_cast(type & 0x7FFF); // Mask out the AF bit. + m_data = data; +} + + + +EAP_FUNC_EXPORT aka_variable_data_c::~aka_variable_data_c() +{ +} + +EAP_FUNC_EXPORT aka_variable_data_c::aka_variable_data_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_data(tools) + , m_original_header(tools, 0, 0) + , m_payload_included(false) +{ +} + +EAP_FUNC_EXPORT eap_status_e aka_variable_data_c::reset() +{ + m_payload_included = false; + m_original_header.reset_header(0ul); + return m_data.reset(); +} + +EAP_FUNC_EXPORT const aka_payload_AT_header_c * aka_variable_data_c::get_original_header() const +{ + return &m_original_header; +} + +EAP_FUNC_EXPORT eap_status_e aka_variable_data_c::set_buffer(const aka_payload_AT_header_c * const original_header, + u8_t *buffer, const u32_t buffer_length, + const bool free_buffer, const bool is_writable) +{ + m_original_header.set_header_buffer( + original_header->get_header_buffer(original_header->get_header_buffer_length()), + original_header->get_header_buffer_length()); + if (m_original_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_status_e status = m_data.set_buffer(buffer, buffer_length, free_buffer, is_writable); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_payload_included = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +EAP_FUNC_EXPORT bool aka_variable_data_c::get_payload_included() const +{ + return m_payload_included; +} + +EAP_FUNC_EXPORT u32_t aka_variable_data_c::get_data_length() const +{ + return m_data.get_data_length(); +} + +EAP_FUNC_EXPORT u8_t * aka_variable_data_c::get_data(const u32_t data_length) const +{ + return m_data.get_data(data_length); +} + +EAP_FUNC_EXPORT eap_variable_data_c * aka_variable_data_c::get_payload_buffer() +{ + return &m_data; +} + +EAP_FUNC_EXPORT bool aka_variable_data_c::get_is_valid() const +{ + return m_data.get_is_valid(); +} + + +EAP_FUNC_EXPORT aka_payloads_c::~aka_payloads_c() +{ +} + +EAP_FUNC_EXPORT aka_payloads_c::aka_payloads_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_all_payloads(tools) + , m_nonce_s(tools) + , m_MAC(tools) + , m_ENCR_DATA(tools) + , m_IDENTITY_payload(tools) + , m_padding_payload(tools) + , m_RAND(tools) + , m_AUTN(tools) + , m_AUTS(tools) + , m_RES(tools) + , m_PERMANENT_ID_REQ(tools) + , m_FULLAUTH_ID_REQ(tools) + , m_ANY_ID_REQ(tools) + , m_IV(tools) + , m_NEXT_PSEUDONYM(tools) + , m_NEXT_REAUTH_ID(tools) + , m_NOTIFICATION(tools) + , m_COUNTER(tools) + , m_COUNTER_TOO_SMALL(tools) + , m_CLIENT_ERROR_CODE(tools) + , m_RESULT_IND(tools) + , m_CHECKCODE(tools) + , m_unknown_payload(aka_payload_NONE) + , m_includes_other_version_than_1(false) + , m_is_valid(false) +{ + if (m_all_payloads.get_is_valid() == false + || m_nonce_s.get_is_valid() == false + || m_MAC.get_is_valid() == false + || m_ENCR_DATA.get_is_valid() == false + || m_IDENTITY_payload.get_is_valid() == false + || m_padding_payload.get_is_valid() == false + || m_RAND.get_is_valid() == false + || m_AUTN.get_is_valid() == false + || m_AUTS.get_is_valid() == false + || m_RES.get_is_valid() == false + || m_PERMANENT_ID_REQ.get_is_valid() == false + || m_FULLAUTH_ID_REQ.get_is_valid() == false + || m_ANY_ID_REQ.get_is_valid() == false + || m_IV.get_is_valid() == false + || m_NEXT_PSEUDONYM.get_is_valid() == false + || m_NEXT_REAUTH_ID.get_is_valid() == false + || m_NOTIFICATION.get_is_valid() == false + || m_COUNTER.get_is_valid() == false + || m_COUNTER_TOO_SMALL.get_is_valid() == false + || m_CLIENT_ERROR_CODE.get_is_valid() == false + || m_RESULT_IND.get_is_valid() == false + || m_CHECKCODE.get_is_valid() == false + ) + { + return; + } + + m_is_valid = true; +} + +EAP_FUNC_EXPORT bool aka_payloads_c::check_one_payload( + const eap_aka_payload_status_e status, + const aka_variable_data_c * const payload) +{ + if (status == eap_aka_payload_status_optional) + { + return true; + } + else if (status == eap_aka_payload_status_must_not_be + && payload->get_payload_included() == false) + { + return true; + } + else if (status == eap_aka_payload_status_must_be + && payload->get_payload_included() == true) + { + return true; + } + else + { + return false; + } +} + +EAP_FUNC_EXPORT bool aka_payloads_c::check_payloads( + const eap_aka_payload_status_e nonce_s, + const eap_aka_payload_status_e MAC, + const eap_aka_payload_status_e ENCR_DATA, + const eap_aka_payload_status_e IDENTITY, + const eap_aka_payload_status_e padding, + const eap_aka_payload_status_e n_RANDs, + const eap_aka_payload_status_e AUTN, + const eap_aka_payload_status_e AUTS, + const eap_aka_payload_status_e RES, + const eap_aka_payload_status_e PERMANENT_ID_REQ, + const eap_aka_payload_status_e FULLAUTH_ID_REQ, + const eap_aka_payload_status_e ANY_ID_REQ, + const eap_aka_payload_status_e IV, + const eap_aka_payload_status_e NEXT_PSEUDONYM, + const eap_aka_payload_status_e NEXT_REAUTH_ID, + const eap_aka_payload_status_e NOTIFICATION, + const eap_aka_payload_status_e COUNTER, + const eap_aka_payload_status_e COUNTER_TOO_SMALL, + const eap_aka_payload_status_e CLIENT_ERROR_CODE, + const eap_aka_payload_status_e RESULT_IND, + const eap_aka_payload_status_e CHECKCODE + ) +{ + if (/*check_one_payload(nonce_mt, get_NONCE_MT()) == true + && */ + check_one_payload(nonce_s, get_NONCE_S()) == true + && check_one_payload(MAC, get_MAC()) == true + && check_one_payload(ENCR_DATA, get_ENCR_DATA()) == true + && check_one_payload(IDENTITY, get_IDENTITY_payload()) == true + && check_one_payload(padding, get_padding_payload()) == true + && check_one_payload(n_RANDs, get_RAND()) == true + && check_one_payload(AUTN, get_AUTN()) == true + && check_one_payload(AUTS, get_AUTS()) == true + && check_one_payload(RES, get_RES()) == true + && check_one_payload(PERMANENT_ID_REQ, get_PERMANENT_ID_REQ()) == true + && check_one_payload(FULLAUTH_ID_REQ, get_FULLAUTH_ID_REQ()) == true + && check_one_payload(ANY_ID_REQ, get_ANY_ID_REQ()) == true + && check_one_payload(IV, get_IV()) == true + && check_one_payload(NEXT_PSEUDONYM, get_NEXT_PSEUDONYM()) == true + && check_one_payload(NEXT_REAUTH_ID, get_NEXT_REAUTH_ID()) == true + && check_one_payload(NOTIFICATION, get_NOTIFICATION()) == true + && check_one_payload(COUNTER, get_COUNTER()) == true + && check_one_payload(COUNTER_TOO_SMALL, get_COUNTER_TOO_SMALL()) == true + && check_one_payload(CLIENT_ERROR_CODE, get_CLIENT_ERROR_CODE()) == true + && check_one_payload(RESULT_IND, get_RESULT_IND()) == true + && check_one_payload(CHECKCODE, get_CHECKCODE()) == true + ) + { + return true; + } + else + { + return false; + } +} + + +EAP_FUNC_EXPORT void aka_payloads_c::set_includes_unknown_attribute(const aka_payload_AT_type_e unknown_payload) +{ + if (m_unknown_payload == aka_payload_NONE) + { + // Only the first one is recorded. + m_unknown_payload = unknown_payload; + } +} + +EAP_FUNC_EXPORT aka_payload_AT_type_e aka_payloads_c::get_includes_unknown_attribute() +{ + return m_unknown_payload; +} + +EAP_FUNC_EXPORT void aka_payloads_c::set_includes_other_version_than_1(const bool includes_other_version_than_1) +{ + m_includes_other_version_than_1 = includes_other_version_than_1; +} + +EAP_FUNC_EXPORT bool aka_payloads_c::get_includes_other_version_than_1() +{ + return m_includes_other_version_than_1; +} + +EAP_FUNC_EXPORT bool aka_payloads_c::get_is_valid() const +{ + return m_is_valid; +} + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_server.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_server.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,5209 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 70 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_type_aka.h" +#include "eap_type_aka_header.h" +#include "eap_type_aka_payloads.h" +#include "abs_eap_am_type_aka.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" +#include "eap_automatic_variable.h" +#include "eap_buffer.h" + + +//-------------------------------------------------- + +/** @file */ + +//-------------------------------------------------- + + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::add_mac_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + u8_t ** const MAC_data, + u32_t * const MAC_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + aka_payload_AT_header_c gp_MAC( + m_am_tools, + aka->get_data_offset( + *aka_data_offset, *aka_data_free), + *aka_data_free); + + if (gp_MAC.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u32_t eap_type_aka_mac_size = EAP_TYPE_AKA_MAC_SIZE; + + gp_MAC.reset_header(static_cast(eap_type_aka_mac_size)); + gp_MAC.set_data_length(static_cast(eap_type_aka_mac_size)); + gp_MAC.set_current_payload(aka_payload_AT_MAC); + + *MAC_data = gp_MAC.get_data(eap_type_aka_mac_size); + if (*MAC_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + *MAC_data_length = eap_type_aka_mac_size; + + m_am_tools->memset(*MAC_data, 0, eap_type_aka_mac_size); + + // MAC is calculated later using call create_message_authentication_code(). + + update_payload_indexes( + aka_buffer_length, + eap_header_size, + gp_MAC.get_header_length()+gp_MAC.get_data_length(), + aka_data_offset, + aka_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_MAC); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::add_padding_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const u32_t plaintext_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + aka_payload_AT_header_c gp_padding( + m_am_tools, + aka->get_data_offset( + *aka_data_offset, *aka_data_free), + *aka_data_free); + + if (gp_padding.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if ((plaintext_length % cbc_aes.get_block_size()) == 0ul) + { + // We do not need padding, because plaintext length is multiple of + // block size. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + u32_t cbc_aes_data_length = cbc_aes.aligned_data_length(plaintext_length); + u32_t padding_bytes_length = 0u; + + if (cbc_aes_data_length + > plaintext_length+aka_payload_AT_header_c::get_header_length()) + { + // Fill with zero (0x00) bytes. + padding_bytes_length + = cbc_aes_data_length + - (plaintext_length + +aka_payload_AT_header_c::get_header_length()); + } + + u32_t padding_payload_length + = aka_payload_AT_header_c::get_header_length() + +padding_bytes_length; + + if ((padding_payload_length % EAP_TYPE_AKA_PADDING_MODULUS) != 0) + { + // ERROR + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + if (padding_payload_length > EAP_TYPE_AKA_PADDING_MAX_VALUE) + { + padding_payload_length = 0ul; + padding_bytes_length = 0ul; + } + + // Note the reserved field is the begin of padding. + // The reserved field is set zero in reset_header() function. + gp_padding.reset_header(static_cast(padding_payload_length)); + gp_padding.set_data_length(static_cast(padding_bytes_length)); + gp_padding.set_current_payload(aka_payload_AT_PADDING); + + if (padding_bytes_length > 0ul) + { + u8_t *padding = gp_padding.get_data(padding_bytes_length); + if (padding == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + cbc_aes.add_padding_bytes( + padding, + padding_bytes_length, + 0ul); + } + + update_payload_indexes( + aka_buffer_length, + eap_header_size, + gp_padding.get_header_length()+gp_padding.get_data_length(), + aka_data_offset, + aka_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_AKA_TRACE_PAYLOAD("Padding payload added", &gp_padding); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::encrypt_DATA_payload( + u8_t * const data, + const u32_t cbc_aes_data_length, + const eap_variable_data_c * const IV, + const eap_variable_data_c * const encryption_key + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (data == 0 + || cbc_aes_data_length == 0 + || IV == 0 + || IV->get_is_valid_data() == false + || encryption_key == 0 + || encryption_key->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t aes_key_length = aes.get_key_length(); + if (encryption_key->get_data_length() < aes_key_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + status = cbc_aes.set_encryption_key( + IV->get_data(IV->get_data_length()), + IV->get_data_length(), + encryption_key->get_data(encryption_key->get_data_length()), + aes_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = cbc_aes.encrypt_data( + data, + cbc_aes_data_length); + + store_last_encryption_iv(cbc_aes.get_tmp_IV()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_reauthentication_request_message( + const eap_variable_data_c * const username, + const bool pseudonym_decode_failed, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(pseudonym_decode_failed); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: handler 0x%08x, AKA-subtype %10s, %s, state %2d=%s\n"), + this, + EAPL("aka_subtype_Re_authentication"), + EAPL("server"), + get_state(), + get_state_string() + )); + + + eap_variable_data_c checkcode_digest(m_am_tools); + + if (checkcode_digest.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_status_process_general_error; + + status = checkcode_final( + &checkcode_digest); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_buf_chain_wr_c request_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (request_packet.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means AKA does process every re-transmitted EAP-Request. + request_packet.set_do_packet_retransmission(false); + } + + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH >= (m_aka_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_aka_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_aka_header_offset+m_MTU; + } + + aka_header_c aka_response( + m_am_tools, + request_packet.get_data_offset( + m_aka_header_offset, + (packet_buffer_free-m_aka_header_offset)), + (packet_buffer_free-m_aka_header_offset)); + + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_reauthentication_request_message: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + aka_response.reset_header( + packet_buffer_free-m_aka_header_offset, + m_use_eap_expanded_type); + aka_response.set_length( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_code(eap_code_request); + aka_response.set_identifier(eap_identifier); + aka_response.set_type( + eap_type_aka, + m_use_eap_expanded_type); + aka_response.set_subtype(aka_subtype_Re_authentication); + + update_buffer_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + m_aka_header_offset+aka_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_reauthentication_request_message(0x%08x).\n"), + this)); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aka_data_free = packet_buffer_free; + u32_t aka_data_offset = 0u; + + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_aut(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + + if (orig_XKEY.get_is_valid() == false + || orig_K_aut.get_is_valid() == false + || orig_K_encr.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t reauth_counter = 0u; + + eap_variable_data_c reauth_nonce_s(m_am_tools); + + if (reauth_nonce_s.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_aka->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = generate_nonce(EAP_TYPE_AKA_NONCE_MT_SIZE, &reauth_nonce_s); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_NONCE_S()->set_copy_of_buffer(&reauth_nonce_s); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c master_session_key(m_am_tools); + + if (master_session_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = generate_reauth_shared_secred_keys( + EAP_TYPE_AKA_KEYMAT_SIZE, + &orig_XKEY, + reauth_counter, + username, + &reauth_nonce_s, + &master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + m_use_result_indication = m_allow_use_result_indication; + + if (m_use_result_indication == true) + { + // We support use of protected success indications. + status = add_simple_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + aka_payload_AT_RESULT_IND); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &checkcode_digest, + aka_payload_AT_CHECKCODE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_type_aka->generate_encryption_IV( + get_IV()->get_payload_buffer(), + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + get_IV()->get_payload_buffer(), + aka_payload_AT_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_aka_MAC_attributes_c MAC_attributes; + + // Encrypted data. + { + aka_payload_AT_header_c gp_encrypted_data( + m_am_tools, + aka_response.get_data_offset( + aka_data_offset, + aka_data_free), + aka_data_free); + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Initialize the length of encrypted data to maximum length. + // Later this will be set to correct length. + gp_encrypted_data.reset_header(aka_payload_AT_header_c::get_max_payload_data_length()); + gp_encrypted_data.set_current_payload(aka_payload_AT_ENCR_DATA); + + update_payload_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + gp_encrypted_data.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_offset, + &packet_buffer_free); + + u32_t encrypted_data_offset_begin = packet_buffer_offset; + + // - - - - - - - - - - - - + + status = add_counter_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + static_cast(reauth_counter)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &reauth_nonce_s, + aka_payload_AT_NONCE_S); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = m_am_type_aka->generate_reauthentication_id( + get_send_network_id(), + get_IMSI(), + get_reauthentication_identity(), + EAP_TYPE_AKA_MAX_NAI_LENGTH); + if (status == eap_status_ok) + { + status = add_pseudonym_or_imsi_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + get_reauthentication_identity(), + aka_payload_AT_NEXT_REAUTH_ID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + status = add_padding_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + (packet_buffer_offset - encrypted_data_offset_begin) // Length of the plain text. + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + gp_encrypted_data.set_data_length( + static_cast(packet_buffer_offset - encrypted_data_offset_begin)); + + // - - - - - - - - - - - - + + status = encrypt_DATA_payload( + gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), + gp_encrypted_data.get_data_length(), + get_IV()->get_payload_buffer(), + &orig_K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); + } + + // - - - - - - - - - - - - + + status = add_mac_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + request_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + aka_response.get_header_buffer(aka_response.get_length()), + aka_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + aka_response.get_subtype(), + aka_response.get_code(), + &orig_K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + request_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_reauthentication_request_message()\n"))); + + status = packet_send( + get_send_network_id(), + &request_packet, + m_aka_header_offset, + aka_response.get_header_length()+aka_response.get_data_length(), + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + status = get_master_session_key()->set_copy_of_buffer(&master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + set_state(eap_type_aka_state_waiting_for_reauth_response); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_aka_identity_request_message( + const bool pseudonym_decode_failed, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: handler 0x%08x, %s, AKA-subtype %10s, %s, state %2d=%s\n"), + this, + EAPL("initiator"), + EAPL("aka_subtype_Identity"), + EAPL("server"), + get_state(), + get_state_string() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_request_message(): ") + EAPL("requested identity payload is %d=%s, state %d=%s, pseudonym decode %d.\n"), + get_aka_identity_response_includes_identity(), + aka_payload_AT_header_c::get_payload_AT_string(get_aka_identity_response_includes_identity()), + get_state(), + get_state_string(), + pseudonym_decode_failed)); + + eap_status_e status = eap_status_process_general_error; + + eap_buf_chain_wr_c request_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (request_packet.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means AKA does process every re-transmitted EAP-Request. + request_packet.set_do_packet_retransmission(false); + } + + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH >= (m_aka_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_aka_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_aka_header_offset+m_MTU; + } + + aka_header_c aka_response( + m_am_tools, + request_packet.get_data_offset( + m_aka_header_offset, + (packet_buffer_free-m_aka_header_offset)), + (packet_buffer_free-m_aka_header_offset)); + + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_aka_identity_request_message: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + aka_response.reset_header( + packet_buffer_free-m_aka_header_offset, + m_use_eap_expanded_type); + aka_response.set_length( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_code(eap_code_request); + aka_response.set_identifier(eap_identifier); + aka_response.set_type( + eap_type_aka, + m_use_eap_expanded_type); + aka_response.set_subtype(aka_subtype_Identity); + + update_buffer_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + m_aka_header_offset+aka_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_request_message(0x%08x).\n"), + this)); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aka_data_free = packet_buffer_free; + u32_t aka_data_offset = 0u; + + if (pseudonym_decode_failed == true) + { + aka_payload_AT_type_e next_identity_request = aka_payload_NONE; + eap_type_aka_state_variable_e next_state = eap_type_aka_state_failure; + + if (get_identity()->get_is_valid_data() == true) + { + if (get_aka_identity_response_includes_identity() == aka_payload_AT_FULLAUTH_ID_REQ) + { + next_identity_request = aka_payload_AT_FULLAUTH_ID_REQ; + next_state = eap_type_aka_state_waiting_for_aka_identity_response_with_at_full_auth_identity; + } + else if (get_aka_identity_response_includes_identity() == aka_payload_AT_PERMANENT_ID_REQ) + { + next_identity_request = aka_payload_AT_PERMANENT_ID_REQ; + next_state = eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity; + } + else if (get_aka_identity_response_includes_identity() == aka_payload_AT_ANY_ID_REQ) + { + next_identity_request = aka_payload_AT_ANY_ID_REQ; + next_state = eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity; + } + else + { + // We drop this message because no real identity is received from client. + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_AKA_ERROR, (EAPL("ERROR: send_aka_identity_request_message: no real identity received.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + else + { + next_identity_request = aka_payload_AT_ANY_ID_REQ; + next_state = eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity; + } + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + 0, + next_identity_request); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(next_state); + } + else + { + set_state(eap_type_aka_state_waiting_for_aka_identity_response); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + request_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + status = checkcode_save_message_server( + aka_response.get_header_buffer( + aka_response.get_header_length() + +aka_response.get_data_length()), + aka_response.get_header_length() + +aka_response.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_aka_identity_request_message()\n"))); + + status = packet_send( + get_send_network_id(), + &request_packet, + m_aka_header_offset, + aka_response.get_header_length()+aka_response.get_data_length(), + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_challenge_request_message( + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + EAPL("aka_subtype_Challenge"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + eap_variable_data_c checkcode_digest(m_am_tools); + + if (checkcode_digest.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_status_process_general_error; + + status = checkcode_final( + &checkcode_digest); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_buf_chain_wr_c aka_initial_reply( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (aka_initial_reply.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means AKA does process every re-transmitted EAP-Request. + aka_initial_reply.set_do_packet_retransmission(false); + } + + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH >= (m_aka_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_aka_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_aka_header_offset+m_MTU; + } + + aka_header_c aka_response( + m_am_tools, + aka_initial_reply.get_data_offset( + m_aka_header_offset, + (packet_buffer_free-m_aka_header_offset)), + (packet_buffer_free-m_aka_header_offset)); + + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + aka_response.reset_header( + packet_buffer_free-m_aka_header_offset, + m_use_eap_expanded_type); + aka_response.set_length( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_code(eap_code_request); + aka_response.set_identifier(eap_identifier); + aka_response.set_type( + eap_type_aka, + m_use_eap_expanded_type); + + aka_response.set_subtype(aka_subtype_Challenge); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::send_challenge_request_message(0x%08x).\n"), + this)); + + update_buffer_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + m_aka_header_offset+aka_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aka_data_free = packet_buffer_free; + u32_t aka_data_offset = 0u; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + if (get_authentication_vector()->get_RAND()->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (get_authentication_vector()->get_AUTN()->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (get_authentication_vector()->get_RES()->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (get_authentication_vector()->get_CK()->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (get_authentication_vector()->get_IK()->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + + + if (get_identity()->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (get_IMSI()->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("RAND"), + get_authentication_vector()->get_RAND()->get_data( + get_authentication_vector()->get_RAND()->get_data_length()), + get_authentication_vector()->get_RAND()->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AUTN"), + get_authentication_vector()->get_AUTN()->get_data( + get_authentication_vector()->get_AUTN()->get_data_length()), + get_authentication_vector()->get_AUTN()->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("RES"), + get_authentication_vector()->get_RES()->get_data( + get_authentication_vector()->get_RES()->get_data_length()), + get_authentication_vector()->get_RES()->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CK"), + get_authentication_vector()->get_CK()->get_data( + get_authentication_vector()->get_CK()->get_data_length()), + get_authentication_vector()->get_CK()->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IK"), + get_authentication_vector()->get_IK()->get_data( + get_authentication_vector()->get_IK()->get_data_length()), + get_authentication_vector()->get_IK()->get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("identity"), + get_identity()->get_data(get_identity()->get_data_length()), + get_identity()->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IMSI"), + get_IMSI()->get_data(get_IMSI()->get_data_length()), + get_IMSI()->get_data_length())); + + eap_variable_data_c XKEY(m_am_tools); + eap_variable_data_c K_encr(m_am_tools); + eap_variable_data_c K_aut(m_am_tools); + eap_variable_data_c master_session_key(m_am_tools); + + if (XKEY.get_is_valid() == false + || K_encr.get_is_valid() == false + || K_aut.get_is_valid() == false + || master_session_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = generate_shared_secred_keys( + EAP_TYPE_AKA_KEYMAT_SIZE, + get_authentication_vector()->get_CK(), + get_authentication_vector()->get_IK(), + &XKEY, + &K_encr, + &K_aut, + &master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + m_use_result_indication = m_allow_use_result_indication; + + if (m_use_result_indication == true) + { + // We support use of protected success indications. + status = add_simple_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + aka_payload_AT_RESULT_IND); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &checkcode_digest, + aka_payload_AT_CHECKCODE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + get_authentication_vector()->get_RAND(), + aka_payload_AT_RAND); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + get_authentication_vector()->get_AUTN(), + aka_payload_AT_AUTN); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_aka_MAC_attributes_c MAC_attributes; + + if (m_use_pseudonym_identity == true + || m_use_reauthentication_identity == true) + { + u32_t saved_aka_data_offset = aka_data_offset; + u32_t saved_aka_data_free = aka_data_free; + u32_t saved_packet_buffer_offset = packet_buffer_offset; + u32_t saved_packet_buffer_free = packet_buffer_free; + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_type_aka->generate_encryption_IV( + get_IV()->get_payload_buffer(), + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + get_IV()->get_payload_buffer(), + aka_payload_AT_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // Encrypted data. + { + aka_payload_AT_header_c gp_encrypted_data( + m_am_tools, + aka_response.get_data_offset( + aka_data_offset, + aka_data_free), + aka_data_free); + if (gp_encrypted_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Initialize the length of encrypted data to maximum length. + // Later this will be set to correct length. + gp_encrypted_data.reset_header(aka_payload_AT_header_c::get_max_payload_data_length()); + gp_encrypted_data.set_current_payload(aka_payload_AT_ENCR_DATA); + + update_payload_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + gp_encrypted_data.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_offset, + &packet_buffer_free); + + u32_t encrypted_data_offset_begin = packet_buffer_offset; + + // - - - - - - - - - - - - + + if (m_use_pseudonym_identity == true) + { + status = m_am_type_aka->generate_pseudonym_id( + get_send_network_id(), + get_IMSI(), + get_pseudonym(), + EAP_TYPE_AKA_MAX_NAI_LENGTH); + if (status == eap_status_ok) + { + status = add_pseudonym_or_imsi_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + get_pseudonym(), + aka_payload_AT_NEXT_PSEUDONYM); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + // - - - - - - - - - - - - + + if (m_use_reauthentication_identity == true) + { + status = m_am_type_aka->generate_reauthentication_id( + get_send_network_id(), + get_IMSI(), + get_reauthentication_identity(), + EAP_TYPE_AKA_MAX_NAI_LENGTH); + if (status == eap_status_ok) + { + status = add_pseudonym_or_imsi_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + get_reauthentication_identity(), + aka_payload_AT_NEXT_REAUTH_ID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + // - - - - - - - - - - - - + + u32_t plain_text_length = packet_buffer_offset - encrypted_data_offset_begin; + + if (plain_text_length > 0ul) + { + status = add_padding_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + plain_text_length // Length of the plain text. + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Re calculate after adding the padding. + plain_text_length = packet_buffer_offset - encrypted_data_offset_begin; + + gp_encrypted_data.set_data_length( + static_cast(plain_text_length)); + + // - - - - - - - - - - - - + + status = encrypt_DATA_payload( + gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), + gp_encrypted_data.get_data_length(), + get_IV()->get_payload_buffer(), + &K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); + } + else + { + // No encrypted data, remove AT_ENCR_DATA header. + aka_data_offset = saved_aka_data_offset; + aka_data_free = saved_aka_data_free; + packet_buffer_offset = saved_packet_buffer_offset; + packet_buffer_free = saved_packet_buffer_free; + } + } + } + + // - - - - - - - - - - - - + + status = add_mac_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + aka_initial_reply.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + aka_response.get_header_buffer(aka_response.get_length()), + aka_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + aka_response.get_subtype(), + aka_response.get_code(), + &K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + aka_initial_reply.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = packet_send( + get_send_network_id(), + &aka_initial_reply, + m_aka_header_offset, + aka_response.get_header_length()+aka_response.get_data_length(), + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + // Store keys. + status = get_XKEY()->set_copy_of_buffer(&XKEY); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = get_K_encr()->set_copy_of_buffer(&K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = get_K_aut()->set_copy_of_buffer(&K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = get_master_session_key()->set_copy_of_buffer(&master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::send_aka_notification_request( + const eap_aka_notification_codes_e notification_code, + const bool add_at_counter_attribute) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s, notification_code = %d\n"), + this, + EAPL("send_aka_notification_request"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string(), + notification_code + )); + + eap_buf_chain_wr_c eap_notification_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_notification_packet.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means AKA does process every re-transmitted EAP-Request. + eap_notification_packet.set_do_packet_retransmission(false); + } + + EAP_ASSERT_ALWAYS(EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH >= (m_aka_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_aka_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_aka_header_offset+m_MTU; + } + + aka_header_c aka_response( + m_am_tools, + eap_notification_packet.get_data_offset( + m_aka_header_offset, + (packet_buffer_free-m_aka_header_offset)), + (packet_buffer_free-m_aka_header_offset)); + + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + set_last_eap_identifier(static_cast(get_last_eap_identifier()+1u)); + + aka_response.reset_header( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_length( + static_cast(packet_buffer_free-m_aka_header_offset), + m_use_eap_expanded_type); + aka_response.set_code(eap_code_request); + aka_response.set_identifier(get_last_eap_identifier()); + aka_response.set_type( + eap_type_aka, + m_use_eap_expanded_type); + aka_response.set_subtype(aka_subtype_Notification); + + + update_buffer_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + m_aka_header_offset+aka_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aka_data_free = packet_buffer_free; + u32_t aka_data_offset = 0u; + + eap_status_e status = add_notification_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + notification_code); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_variable_data_c * K_aut = 0; + + eap_variable_data_c orig_K_aut(m_am_tools); + + if (orig_K_aut.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (get_aka_notification_code_P_bit(notification_code) == false) + { + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_aka_MAC_attributes_c MAC_attributes; + + if (add_at_counter_attribute == true) + { + // If EAP-Request/AKA/Notification is used on fast a re-authentication + // exchange, and if the P bit in AT_NOTIFICATION is set to zero, then + // AT_COUNTER is used for replay protection. In this case, the + // AT_ENCR_DATA and AT_IV attributes MUST be included, and the + // encapsulated plaintext attributes MUST include the AT_COUNTER + // attribute. The counter value included in AT_COUNTER MUST be the same + // as in the EAP-Request/AKA/Re-authentication packet on the same fast + // re-authentication exchange. + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + + if (orig_XKEY.get_is_valid() == false + || orig_K_encr.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t reauth_counter = 0u; + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_aka->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + K_aut = &orig_K_aut; + + // - - - - - - - - - - - - + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_type_aka->generate_encryption_IV( + get_IV()->get_payload_buffer(), + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = add_variable_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + get_IV()->get_payload_buffer(), + aka_payload_AT_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // Encrypted data. + { + aka_payload_AT_header_c gp_encrypted_data( + m_am_tools, + aka_response.get_data_offset( + aka_data_offset, + aka_data_free), + aka_data_free); + if (aka_response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Initialize the length of encrypted data to maximum length. + // Later this will be set to correct length. + gp_encrypted_data.reset_header(aka_payload_AT_header_c::get_max_payload_data_length()); + gp_encrypted_data.set_current_payload(aka_payload_AT_ENCR_DATA); + + update_payload_indexes( + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + gp_encrypted_data.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_offset, + &packet_buffer_free); + + u32_t encrypted_data_offset_begin = packet_buffer_offset; + + // - - - - - - - - - - - - + + status = add_counter_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + static_cast(reauth_counter)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_padding_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + (packet_buffer_offset - encrypted_data_offset_begin) // Length of the plain text. + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + gp_encrypted_data.set_data_length( + static_cast(packet_buffer_offset - encrypted_data_offset_begin)); + + // - - - - - - - - - - - - + + status = encrypt_DATA_payload( + gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), + gp_encrypted_data.get_data_length(), + get_IV()->get_payload_buffer(), + &orig_K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_AKA_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); + } + + } + else + { + K_aut = get_K_aut(); + } // if (add_counter_payload == true) + + // - - - - - - - - - - - - + + // Add AT_MAC attribute. + status = add_mac_payload( + &aka_response, + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH, + aka_response.get_header_length(), + &aka_data_offset, + &aka_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + aka_response.get_header_buffer(aka_response.get_length()), + aka_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + aka_response.get_subtype(), + aka_response.get_code(), + K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + else + { + aka_response.set_data_length( + aka_data_offset, + m_use_eap_expanded_type); + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_aka_header_offset+aka_response.get_header_length()+aka_response.get_data_length() + == packet_buffer_offset); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_aka_notification_request: aka_subtype_Notification packet"), + aka_response.get_header_buffer(aka_response.get_length()), + aka_response.get_length())); + + status = packet_send( + get_send_network_id(), + &eap_notification_packet, + m_aka_header_offset, + aka_response.get_length(), + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::query_AKA_authentication_vector( + const u8_t next_eap_identifier, + eap_type_aka_identity_type * const identity_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_type_aka_authentication_vector_c authentication_vector(m_am_tools); + + set_state(eap_type_aka_state_pending_authentication_vector_query); + + eap_status_e status = m_am_type_aka->query_AKA_authentication_vector( + get_identity(), // This is username part from payload AT_IDENTITY. + next_eap_identifier, + get_IMSI(), // This is the real IMSI. If this is uninitialized get_identity() must be initialized, imsi will be initialized after this call is complete. + &authentication_vector, + identity_type); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_AKA_authentication_vector_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This query was already completed by complete_AKA_authentication_vector_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok) + { + // Some error occurred. + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_authentication_vector(authentication_vector.copy()); + if (get_authentication_vector() == 0 + || get_authentication_vector()->get_is_valid() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::complete_AKA_authentication_vector_query( + eap_type_aka_authentication_vector_c * const authentication_vector, + const eap_variable_data_c * const IMSI, + const eap_aka_authentication_vector_status_e authentication_vector_status, + const eap_type_aka_identity_type identity_type, + const eap_status_e completion_status, + const u8_t next_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::complete_AKA_authentication_vector_query(): ") + EAPL("EAP-identity is %d=%s, identity payload was %d=%s, state %d=%s.\n"), + identity_type, + get_identity_string(identity_type), + get_aka_identity_response_includes_identity(), + aka_payload_AT_header_c::get_payload_AT_string(get_aka_identity_response_includes_identity()), + get_state(), + get_state_string())); + + if (completion_status != eap_status_ok + || authentication_vector == 0) + { + set_state(eap_type_aka_state_failure); + + // The eap_status_process_general_error error value is more important + // than return value of set_session_timeout(). + (void) get_type_partner()->set_session_timeout(0ul); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + + if (get_state() != eap_type_aka_state_pending_authentication_vector_query) + { + // Authentication is terminated or state is wrong. Cannot continue. + set_state(eap_type_aka_state_failure); + + // The eap_status_handler_does_not_exists_error error value is more important + // than return value of set_session_timeout(). + (void) get_type_partner()->set_session_timeout(0ul); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + + eap_status_e status = eap_status_process_general_error; + + if (m_identity_type != AKA_IDENTITY_TYPE_RE_AUTH_ID) + { + set_identity_type(identity_type); + } + + if (m_identity_type == AKA_IDENTITY_TYPE_IMSI_ID + && IMSI->get_is_valid_data() == true) + { + status = m_IMSI.set_copy_of_buffer(IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (authentication_vector_status == eap_aka_authentication_vector_status_ok) + { + // First check the identity type is correct. + if ((m_identity_type == AKA_IDENTITY_TYPE_IMSI_ID + && (get_aka_identity_response_includes_identity() == aka_payload_AT_PERMANENT_ID_REQ + || get_aka_identity_response_includes_identity() == aka_payload_AT_FULLAUTH_ID_REQ + || get_aka_identity_response_includes_identity() == aka_payload_AT_ANY_ID_REQ)) + || (m_identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID + && (get_aka_identity_response_includes_identity() == aka_payload_AT_FULLAUTH_ID_REQ + || get_aka_identity_response_includes_identity() == aka_payload_AT_ANY_ID_REQ)) + || (m_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID + && get_aka_identity_response_includes_identity() == aka_payload_AT_ANY_ID_REQ) + || get_aka_identity_response_includes_identity() == aka_payload_NONE) + { + // OK, correct identity received. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::complete_AKA_authentication_vector_query(): OK\n"))); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::complete_AKA_authentication_vector_query(): ") + EAPL("EAP-identity is wrong, state %d=%s.\n"), + get_state(), get_state_string())); + + if (get_aka_identity_response_includes_identity() == aka_payload_AT_PERMANENT_ID_REQ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::complete_AKA_authentication_vector_query(): ") + EAPL("permanent identity was required, %d=%s was get.\n"), + m_identity_type, + get_identity_string(m_identity_type))); + } + else if (get_aka_identity_response_includes_identity() == aka_payload_AT_FULLAUTH_ID_REQ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::complete_AKA_authentication_vector_query(): ") + EAPL("full authentication identity was required, %d=%s was get.\n"), + m_identity_type, + get_identity_string(m_identity_type))); + } + else if (get_aka_identity_response_includes_identity() == aka_payload_AT_ANY_ID_REQ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::complete_AKA_authentication_vector_query(): ") + EAPL("any identity was required, %d=%s was get.\n"), + m_identity_type, + get_identity_string(m_identity_type))); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::complete_AKA_authentication_vector_query(): ") + EAPL("no special identity was required, %d=%s was get.\n"), + m_identity_type, + get_identity_string(m_identity_type))); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR, wrong identity"), + get_NAI()->get_data(get_NAI()->get_data_length()), + get_NAI()->get_data_length())); + + restore_saved_previous_state(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + if (get_IMSI()->get_is_valid_data() == false + && IMSI != get_IMSI()) + { + // We must copy queried IMSI. + status = get_IMSI()->set_copy_of_buffer(IMSI); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + set_authentication_vector(authentication_vector->copy()); + if (get_authentication_vector() == 0 + || get_authentication_vector()->get_is_valid() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = send_challenge_request_message( + next_eap_identifier); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_last_eap_identifier(next_eap_identifier); + set_state(eap_type_aka_state_waiting_for_challenge_response); + } + else + { + // Error occurred in tripler query. + // We must send EAP-Notification message. + // + + // eap_aka_notification_no_F_no_P_users_calls_are_barred and eap_aka_notification_no_F_no_P_user_has_not_subscribed_to_the_requested_service cannot be used because P bit is not set. + + m_aka_notification_code = eap_aka_notification_no_F_P_set_general_failure; + + status = initialize_notification_message(); + + set_last_eap_identifier(static_cast(get_last_eap_identifier()+1u)); + + set_state(eap_type_aka_state_waiting_for_notification_response_failure); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_aka_c::randomly_refuse_eap_identity() +{ + bool skip_query_imsi_from_username = false; + + if (m_aka_test_version == true + && m_aka_randomly_refuse_eap_identity == true) + { + crypto_random_c rand(m_am_tools); + + if (rand.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; + } + + u32_t random_guard; + + eap_status_e status = rand.get_rand_bytes( + reinterpret_cast(&random_guard), + sizeof(random_guard)); + if (status != eap_status_ok) + { + return false; + } + + if ((random_guard % 2) == 0) + { + // Note, this is just for testing. + skip_query_imsi_from_username = true; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: eap_type_aka_c::randomly_refuse_eap_identity(): ") + EAPL("randomly fails EAP-Identity.\n"))); + } + } + + return skip_query_imsi_from_username; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_identity_response_message( + eap_header_rd_c * const eap_header, + const u32_t aka_packet_length) +{ + eap_status_e status = eap_status_process_general_error; + + if (get_state() == eap_type_aka_state_waiting_for_identity_response + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_full_auth_identity + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity + // In test version new authentication could start from this state. + || (m_aka_test_version == true + && get_state() == eap_type_aka_state_success) // This one is for testing purposes. + ) + { + // OK correct state. + } + else + { + // Wrong state, dischard packet. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_identity_response_message(): ") + EAPL("EAP-Response/Identity received in wrong state %d=%s. This EAP-packet is dropped.\n"), + get_state(), get_state_string())); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: erroneous EAP packet: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, type=0x%08x, client %d\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + convert_eap_type_to_u32_t(eap_header->get_type()), + get_is_client())); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (m_check_identifier_of_eap_identity_response == true) + { + if (get_state() == eap_type_aka_state_waiting_for_identity_response + && eap_header->get_identifier() != get_last_eap_identifier()) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + else if ((get_state() == eap_type_aka_state_waiting_for_aka_identity_response + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_full_auth_identity + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity + ) + && eap_header->get_identifier() != get_last_eap_identifier()-1u) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + eap_header->get_identifier(), + get_last_eap_identifier()-1u, + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + // In test version new authentication could start from this state. + else if (m_aka_test_version == true + && get_state() == eap_type_aka_state_success) // This one is for testing purposes. + { + // NOTE here we can not check the EAP-identifier. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_aka_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is not checked in eap_type_aka_state_variable_e %d=%s.\n"), + eap_header->get_identifier(), + get_state(), + get_state_string())); + } + } + + { + // This could be first or retransmission request. + + if (eap_header->get_type_data_length() > aka_packet_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + status = parse_identity( + eap_header->get_type_data( + eap_header->get_type_data_length()), + eap_header->get_type_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("AKA received EAP-identity NAI"), + get_NAI()->get_data(get_NAI()->get_data_length()), + get_NAI()->get_data_length())); + + u8_t next_eap_identifier = static_cast(eap_header->get_identifier()+1u); + + if (get_state() == eap_type_aka_state_waiting_for_aka_identity_response + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_full_auth_identity + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity + ) + { + // This is retransmission, so the EAP-identifier is not increased. + next_eap_identifier = get_last_eap_identifier(); + } + // In test version new authentication could start from this state. + else if (m_aka_test_version == true + && get_state() == eap_type_aka_state_success) // This one is for testing purposes. + { + // NOTE here we can not check the EAP-identifier. + next_eap_identifier = static_cast(eap_header->get_identifier()+1u); + set_state(eap_type_aka_state_waiting_for_identity_response); + get_IMSI()->reset(); + } + + save_current_state(); + set_state(eap_type_aka_state_pending_pseudonym_decode_query); + + eap_type_aka_identity_type identity_type = AKA_IDENTITY_TYPE_NONE; + + if (m_accept_eap_identity_response == true) + { + if (randomly_refuse_eap_identity() == false) + { + status = m_am_type_aka->query_imsi_from_username( + next_eap_identifier, + get_send_network_id(), + get_identity(), + get_IMSI(), + &identity_type, + eap_type_aka_complete_handle_imsi_from_username); + } + else + { + status = eap_status_illegal_eap_identity; + } + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_imsi_from_username() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_imsi_from_username() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status != eap_status_ok) + { + // Identity decoding failed. + // We must query IMSI of client. + + if (m_use_manual_username == true) + { + // We reset the illegal identity. + // EAP-AKA/request/start will query identity. + get_identity()->reset(); + } + } + else // status == eap_status_ok + { + // The query_imsi_from_username() function call was synchronous. + // We must call send_aka_identity_request_message(). + } + } + + + { + status = handle_imsi_from_username( + next_eap_identifier, + get_send_network_id(), + get_identity(), + get_IMSI(), + identity_type); + if (status != eap_status_ok) + { + // ERROR in handle_imsi_from_username(). + // This will return error status of handle_imsi_from_username() call. + } + else + { + // OK handle_imsi_from_username(). + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + const eap_variable_data_c * const imsi, ///< The result is stored to imsi parameter. + const eap_type_aka_identity_type received_identity_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(username); + EAP_UNREFERENCED_PARAMETER(network_id); + + EAP_ASSERT(received_identity_type == AKA_IDENTITY_TYPE_IMSI_ID + || received_identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID + || received_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID + || received_identity_type == AKA_IDENTITY_TYPE_NONE); + + if (get_state() != eap_type_aka_state_pending_pseudonym_decode_query) + { + // State is wrong. Cannot continue. + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_gsmsim_state); + } + + eap_status_e status = eap_status_process_general_error; + bool pseudonym_decode_failed = true; + + //eap_type_aka_identity_type local_identity_type = identity_type; + set_identity_type(received_identity_type); + + if (imsi != 0 + && imsi->get_is_valid_data() == true) + { + pseudonym_decode_failed = false; + status = get_IMSI()->set_copy_of_buffer(imsi); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (received_identity_type == AKA_IDENTITY_TYPE_NONE) + { + set_identity_type(AKA_IDENTITY_TYPE_IMSI_ID); + } + } + else + { + get_IMSI()->reset(); + } + + if (received_identity_type == AKA_IDENTITY_TYPE_IMSI_ID) + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(received_identity_type); + set_aka_identity_response_includes_identity(aka_payload_AT_ANY_ID_REQ); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: IMSI\n"))); + } + else if (received_identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID) + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(received_identity_type); + set_aka_identity_response_includes_identity(aka_payload_AT_ANY_ID_REQ); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: pseudonym\n"))); + } + else if (received_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID) + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_REAUTHENTICATION; + set_identity_type(received_identity_type); + set_aka_identity_response_includes_identity(aka_payload_AT_ANY_ID_REQ); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: re-authentication\n"))); + } + else + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_NONE; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: other\n"))); + } + + + if (m_authentication_type == AKA_AUTHENTICATION_TYPE_FULL_AUTH + && (m_identity_type == AKA_IDENTITY_TYPE_IMSI_ID + && (get_saved_previous_state() == eap_type_aka_state_waiting_for_identity_response + || get_saved_previous_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity + || get_saved_previous_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_full_auth_identity + || get_saved_previous_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity + || get_saved_previous_state() == eap_type_aka_state_waiting_for_aka_identity_response)) + || (m_identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID + && (get_saved_previous_state() == eap_type_aka_state_waiting_for_identity_response + || get_saved_previous_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity + || get_saved_previous_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity + || get_saved_previous_state() == eap_type_aka_state_waiting_for_aka_identity_response)) + ) + { + eap_type_aka_identity_type local_identity_type = m_identity_type; + + eap_status_e local_status = query_AKA_authentication_vector(next_eap_identifier, &local_identity_type); + if (local_status == eap_status_pending_request) + { + // Request will be completed later with complete_AKA_authentication_vector_query() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (local_status == eap_status_completed_request) + { + // Request was already completed with complete_AKA_authentication_vector_query() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (local_status != eap_status_ok) + { + // This is an error case. + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + else //if (local_status == eap_status_ok) + { + // The query_AKA_authentication_vector() function call is synchronous. + // We must call send_challenge_request_message(). + } + + const u8_t local_eap_identifier = static_cast(get_last_eap_identifier()+1u); + + local_status = send_challenge_request_message( + local_eap_identifier); + if (local_status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + + set_last_eap_identifier(local_eap_identifier); + set_state(eap_type_aka_state_waiting_for_challenge_response); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID + && (get_saved_previous_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity + || get_saved_previous_state() == eap_type_aka_state_waiting_for_identity_response + || get_saved_previous_state() == eap_type_aka_state_waiting_for_aka_identity_response)) + { + // Here we need to send EAP-Request/Re-authentication + status = send_reauthentication_request_message( + get_NAI(), + pseudonym_decode_failed, + next_eap_identifier); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_NONE + && get_saved_previous_state() == eap_type_aka_state_waiting_for_identity_response) + { + set_aka_identity_response_includes_identity(aka_payload_AT_ANY_ID_REQ); + + status = send_aka_identity_request_message( + pseudonym_decode_failed, + next_eap_identifier); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_imsi_from_username(): ") + EAPL("EAP-Identity type 0x%02x is wrong in eap_type_aka_state_variable_e %d=%s.\n"), + m_identity_type, + get_saved_previous_state(), + get_saved_previous_state_string())); + + status = eap_status_illegal_eap_identity; + } + + if (status != eap_status_ok) + { + restore_saved_previous_state(); + } + else + { + set_last_eap_identifier(next_eap_identifier); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::complete_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + const eap_variable_data_c * const imsi, ///< The result is stored to imsi parameter. + const eap_type_aka_identity_type identity_type, + const eap_status_e completion_status, + const eap_type_aka_complete_e completion_action) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::complete_imsi_from_username(): ") + EAPL("EAP-identity is %d=%s, identity payload was %d=%s, state %d=%s.\n"), + identity_type, + get_identity_string(identity_type), + get_aka_identity_response_includes_identity(), + aka_payload_AT_header_c::get_payload_AT_string(get_aka_identity_response_includes_identity()), + get_state(), + get_state_string())); + + EAP_UNREFERENCED_PARAMETER(username); + EAP_UNREFERENCED_PARAMETER(network_id); + + if (get_state() == eap_type_aka_state_none) + { + // The eap_status_handler_does_not_exists_error error value is more important + // than return value of set_session_timeout(). + (void) get_type_partner()->set_session_timeout(0ul); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + + if (completion_status != eap_status_ok) + { + set_state(eap_type_aka_state_failure); + + // The completion_status error value is more important + // than return value of set_session_timeout(). + (void) get_type_partner()->set_session_timeout(0ul); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, completion_status); + } + + eap_status_e status = eap_status_not_supported; + + if (completion_action == eap_type_aka_complete_handle_imsi_from_username) + { + status = handle_imsi_from_username( + next_eap_identifier, + network_id, + username, + imsi, ///< The result is stored to imsi parameter. + identity_type); + + status = eap_status_completed_request; + } + else if (completion_action == eap_type_aka_complete_handle_aka_identity_response_message_completion) + { + // NOTE the identity_payload_was_included parameter is + // true in this completion. + status = handle_aka_identity_response_message_completion( + next_eap_identifier, + completion_status, + identity_type, + true); + + status = eap_status_completed_request; + } + else + { + // Unknown completion. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::complete_imsi_from_username(): ") + EAPL("Unknown eap_type_aka_complete_e %d in eap_type_aka_state_variable_e %d=%s.\n"), + completion_action, + get_saved_previous_state(), + get_saved_previous_state_string())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::check_synchronization_failure_response_message( + const eap_am_network_id_c * const /* receive_network_id */, + aka_header_c * const /*received_aka*/, + const u32_t /*aka_packet_length*/, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_not_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_not_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_must_not_be, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_must_not_be // CHECKCODE + ) == true + ) + { + const u8_t next_eap_identifier = static_cast(get_last_eap_identifier()+1u); + + save_current_state(); + set_state(eap_type_aka_state_pending_re_syncronization_query); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_type_aka_authentication_vector_c authentication_vector(m_am_tools); + + status = authentication_vector.get_AUTS()->set_copy_of_buffer( + p_aka_payloads->get_AUTS()->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = authentication_vector.get_RAND()->set_copy_of_buffer(get_authentication_vector()->get_RAND()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_am_type_aka->query_re_syncronization( + next_eap_identifier, + &authentication_vector); + if (status == eap_status_pending_request) + { + // Request will be completed later using complete_re_syncronization_query() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status == eap_status_completed_request) + { + // Request was already completed by AM using complete_re_syncronization_query() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status == eap_status_success) + { + // eap_status_success means the authentication was successful. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_ok) + { + // The query_re_syncronization() function call is synchronous. + // We must call process_re_syncronization(). + } + else + { + // This is an error case. + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // eap_status_ok status value means n_kc and n_sres were read but not processed. + // Next we must call process_re_syncronization(). + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = process_re_syncronization( + next_eap_identifier, + &authentication_vector); + + if (status != eap_status_ok + && status != eap_status_success) + { + restore_saved_previous_state(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_challenge_request_message(6): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::complete_re_syncronization_query( + const u8_t next_eap_identifier, + const eap_type_aka_authentication_vector_c * const authentication_vector) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (get_state() != eap_type_aka_state_pending_re_syncronization_query + || authentication_vector == 0 + || authentication_vector->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + status = process_re_syncronization( + next_eap_identifier, + authentication_vector); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::process_re_syncronization( + const u8_t next_eap_identifier, + const eap_type_aka_authentication_vector_c * const authentication_vector) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (get_state() != eap_type_aka_state_pending_re_syncronization_query + || authentication_vector == 0 + || authentication_vector->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + set_authentication_vector(authentication_vector->copy()); + if (get_authentication_vector() == 0 + || get_authentication_vector()->get_is_valid() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = send_challenge_request_message( + next_eap_identifier); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_last_eap_identifier(next_eap_identifier); + set_state(eap_type_aka_state_waiting_for_challenge_response); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_synchronization_failure_response_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + if (get_state() == eap_type_aka_state_waiting_for_challenge_response) + { + // This could be first or retransmission request. + if (received_aka->get_identifier() != get_last_eap_identifier()) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_synchronization_failure_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_identifier(), + get_last_eap_identifier(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + status = check_synchronization_failure_response_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (get_state() == eap_type_aka_state_success) + { + if (received_aka->get_identifier() != get_last_eap_identifier()-1u) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_synchronization_failure_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_identifier(), + get_last_eap_identifier()-1u, + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + status = check_synchronization_failure_response_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (get_state() == eap_type_aka_state_pending_re_syncronization_query) + { + // This is re-transmitted EAP-Response/AKA/Challenge. + // We dischard it quietly. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_aka_c::handle_challenge_response_message(): ") + EAPL("Re-transmitted message %d=%s dropped in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else + { + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_challenge_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_aka_identity_response_message_completion( + const u8_t next_eap_identifier, + const eap_status_e identity_status, + eap_type_aka_identity_type received_identity_type, + const bool identity_payload_was_included) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_response_message_completion(): ") + EAPL("received_identity_type %d=%s, identity payload was %d=%s, state %d=%s.\n"), + received_identity_type, + get_identity_string(received_identity_type), + get_aka_identity_response_includes_identity(), + aka_payload_AT_header_c::get_payload_AT_string(get_aka_identity_response_includes_identity()), + get_state(), + get_state_string())); + + if (get_state() == eap_type_aka_state_none) + { + // Authentication is terminated or state is wrong. Cannot continue. + + // The eap_status_handler_does_not_exists_error error value is more important + // than return value of set_session_timeout(). + (void) get_type_partner()->set_session_timeout(0ul); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + + if (identity_payload_was_included == true) + { + if (identity_status != eap_status_ok + || received_identity_type == AKA_IDENTITY_TYPE_NONE) + { + // We did not get valid identity. + set_identity_type(AKA_IDENTITY_TYPE_NONE); + if (get_aka_identity_response_includes_identity() == aka_payload_AT_ANY_ID_REQ) + { + set_aka_identity_response_includes_identity(aka_payload_AT_FULLAUTH_ID_REQ); + } + else // if (get_aka_identity_response_includes_identity() == aka_payload_AT_FULLAUTH_ID_REQ) + { + set_aka_identity_response_includes_identity(aka_payload_AT_PERMANENT_ID_REQ); + } + } + else + { + // We receive an identity. + set_identity_type(received_identity_type); + } + + if (m_identity_type == AKA_IDENTITY_TYPE_IMSI_ID) + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: IMSI\n"))); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID) + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: pseudonym\n"))); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID) + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_REAUTHENTICATION; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: re-authentication\n"))); + } + else + { + m_authentication_type = AKA_AUTHENTICATION_TYPE_NONE; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: other\n"))); + } + } + else + { + // No AT_IDENTITY payload. + // We may have identity already. + if (get_identity()->get_is_valid_data() == true + && m_authentication_type != AKA_AUTHENTICATION_TYPE_NONE + && m_identity_type != AKA_IDENTITY_TYPE_NONE) + { + // OK identity is known. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_response_message_completion(): ") + EAPL("Known m_identity_type %d=%s, identity payload was %d=%s, state %d=%s.\n"), + m_identity_type, + get_identity_string(m_identity_type), + get_aka_identity_response_includes_identity(), + aka_payload_AT_header_c::get_payload_AT_string(get_aka_identity_response_includes_identity()), + get_state(), + get_state_string())); + } + else + { + // ERROR no accepted identity. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_response_message_completion(5): ") + EAPL("No correct AKA-identity were received in eap_type_gsmsim_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + + save_current_state(); + + u8_t local_eap_identifier = 0u; + + if (get_saved_previous_state() == eap_type_aka_state_waiting_for_challenge_response) + { + // Do not increase EAP-Identifier, this was re-transmission. + local_eap_identifier = get_last_eap_identifier(); + } + else + { + local_eap_identifier = static_cast(get_last_eap_identifier()+1u); + } + + if (m_identity_type == AKA_IDENTITY_TYPE_NONE) + { + eap_status_e local_status = send_aka_identity_request_message( + true, + local_eap_identifier); + if (local_status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + set_last_eap_identifier(local_eap_identifier); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_IMSI_ID + || m_identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID + || (m_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID + && m_authentication_type == AKA_AUTHENTICATION_TYPE_FULL_AUTH)) + { + eap_type_aka_identity_type local_identity_type = m_identity_type; + + eap_status_e local_status = query_AKA_authentication_vector( + next_eap_identifier, + &local_identity_type); + if (local_status == eap_status_pending_request) + { + // Request will be completed later with complete_AKA_authentication_vector_query() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (local_status == eap_status_completed_request) + { + // Request was already completed with complete_AKA_authentication_vector_query() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (local_status != eap_status_ok) + { + // This is an error case. + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + else //if (local_status == eap_status_ok) + { + // The query_AKA_authentication_vector() function call is synchronous. + // We must call send_challenge_request_message(). + } + + local_status = send_challenge_request_message( + local_eap_identifier); + if (local_status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + + set_last_eap_identifier(local_eap_identifier); + set_state(eap_type_aka_state_waiting_for_challenge_response); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + else if (m_identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID + && m_authentication_type == AKA_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + // Here we need to send EAP-Request/Re-authentication + eap_status_e local_status = send_reauthentication_request_message( + get_NAI(), + false, + local_eap_identifier); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + else + { + // Unnown identity type, do nothing. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_aka_identity_response_message( + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_aka_identity_response_message(): ") + EAPL("m_identity_type %d=%s, identity payload was %d=%s, state %d=%s.\n"), + m_identity_type, + get_identity_string(m_identity_type), + get_aka_identity_response_includes_identity(), + aka_payload_AT_header_c::get_payload_AT_string(get_aka_identity_response_includes_identity()), + get_state(), + get_state_string())); + + if (aka_packet_length < received_aka->get_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_response_message(): ") + EAPL("aka_packet_length < received_aka->get_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (get_state() == eap_type_aka_state_waiting_for_aka_identity_response + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_full_auth_identity + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity + || get_state() == eap_type_aka_state_waiting_for_challenge_response + ) + { + if (get_state() == eap_type_aka_state_waiting_for_aka_identity_response + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_full_auth_identity + || get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity + ) + { + if (received_aka->get_identifier() != get_last_eap_identifier()) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_identifier(), + get_last_eap_identifier(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + else // if (get_state() == eap_type_aka_state_waiting_for_challenge_response) + { + // This might be retransmission response. + if (received_aka->get_identifier() != get_last_eap_identifier()-1u) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_identifier(), + get_last_eap_identifier()-1u, + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + + + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_not_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_not_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_optional, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_must_not_be, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_must_not_be // CHECKCODE + ) == true + ) + { + if (get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity) + { + if (p_aka_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + // OK, NAI identity is included. + // Identity must be IMSI. query_AKA_authentication_vector() must decode identity. + + set_aka_identity_response_includes_identity(aka_payload_AT_PERMANENT_ID_REQ); + } + else + { + // AT_IDENTITY is missing. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_response_message(0x%08x), ") + EAPL("AT_IDENTITY is missing in state %s.\n"), + this, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_full_auth_identity) + { + if (p_aka_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + // OK, NAI identity is included. + // Identity must be IMSI or pseudonym identity. query_AKA_authentication_vector() must decode identity. + + set_aka_identity_response_includes_identity(aka_payload_AT_FULLAUTH_ID_REQ); + } + else + { + // AT_IDENTITY is missing. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_response_message(0x%08x), ") + EAPL("AT_IDENTITY is missing in state %s.\n"), + this, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (get_state() == eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity) + { + if (p_aka_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + // OK, NAI identity is included. + // Identity must be IMSI, pseudonym or re-authentication identity. query_AKA_authentication_vector() must decode identity. + + set_aka_identity_response_includes_identity(aka_payload_AT_ANY_ID_REQ); + } + else + { + // AT_IDENTITY is missing. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_response_message(0x%08x), ") + EAPL("AT_IDENTITY is missing in state %s.\n"), + this, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (get_state() == eap_type_aka_state_waiting_for_challenge_response) + { + // This is re-transmission. + if (p_aka_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + if (get_aka_identity_response_includes_identity() == aka_payload_AT_PERMANENT_ID_REQ + || get_aka_identity_response_includes_identity() == aka_payload_AT_FULLAUTH_ID_REQ + || get_aka_identity_response_includes_identity() == aka_payload_AT_ANY_ID_REQ) + { + // OK, NAI identity is included. + } + else + { + // Illegal IDENTITY is included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_response_message(0x%08x), ") + EAPL("illegal AT_IDENTITY included in state %s.\n"), + this, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + } + else + { + if (p_aka_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + // Illegal IDENTITY is included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_response_message(0x%08x), ") + EAPL("illegal AT_IDENTITY included in state %s.\n"), + this, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + + + status = checkcode_update_saved_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = checkcode_update( + received_aka->get_header_buffer( + received_aka->get_header_length() + +received_aka->get_data_length()), + received_aka->get_header_length() + +received_aka->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_type_aka_identity_type identity_type = AKA_IDENTITY_TYPE_NONE; + bool identity_payload_was_included = false; + const u8_t next_eap_identifier = static_cast(received_aka->get_identifier()+1u); + + if (p_aka_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + status = parse_identity( + p_aka_payloads->get_IDENTITY_payload()->get_data(p_aka_payloads->get_IDENTITY_payload()->get_data_length()), + p_aka_payloads->get_IDENTITY_payload()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + identity_payload_was_included = true; + + // We must ask AM module whether the identity is IMSI, pseudonym or re-authentication identity. + // If we have re-authentication identity we must send re-authentication query. + + if (randomly_refuse_eap_identity() == false) + { + status = m_am_type_aka->query_imsi_from_username( + next_eap_identifier, + get_send_network_id(), + get_identity(), + get_IMSI(), + &identity_type, + eap_type_aka_complete_handle_aka_identity_response_message_completion); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_imsi_from_username() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_imsi_from_username() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status != eap_status_ok) + { + // ERROR in query_imsi_from_username(). + // This will return error status of query_imsi_from_username() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // status == eap_status_ok + { + // The query_imsi_from_username() function call was synchronous. + // We must call send_aka_identity_request_message(). + } + } + else + { + status = eap_status_illegal_eap_identity; + } + } + + + status = handle_aka_identity_response_message_completion( + next_eap_identifier, + status, + identity_type, + identity_payload_was_included); + + + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_response_message(4): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (get_state() == eap_type_aka_state_pending_authentication_vector_query) + { + // This is retransmission of EAP-Response/AKA/Start. + // Triplet query is already initialized. + // We will drop this message quietly. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_aka_c::handle_aka_identity_response_message(5): ") + EAPL("Retransmission of EAP-Response/AKA/Start in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else + { + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_aka_identity_response_message(): ") + EAPL("Wrong message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_notification_response_message_reauthentication( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t /*aka_packet_length*/, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + EAPL("handle_notification_response_message_reauthentication"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + // The second most significant bit of the notification code is called + // the Phase bit (P bit). It specifies at which phase of the EAP-AKA + // exchange the notification can be used. + if (get_aka_notification_code_P_bit(m_aka_notification_code) == false) + { + // If the P bit is set to zero, + // the notification can only be used after a successful EAP/AKA/ + // Challenge round in full authentication or a successful EAP/AKA/ + // Re-authentication round in reautentication. A re-authentication round + // is considered successful only if the peer has successfully verified + // AT_MAC and AT_COUNTER attributes, and does not include the + // AT_COUNTER_TOO_SMALL attribute in EAP-Response/AKA/Re-authentication. + + // The AT_MAC attribute MUST beincluded if the P bit of the notification + // code in AT_NOTIFICATION is set to zero, and MUST NOT be included in + // cases when the P bit is set to one. The P bit is discussed in Section + // 4.4. + + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_must_not_be, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_must_not_be // CHECKCODE + ) == true + ) + { + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_aut(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + + if (orig_XKEY.get_is_valid() == false + || orig_K_aut.get_is_valid() == false + || orig_K_encr.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t reauth_counter = 0u; + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_aka->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = check_message_authentication_code( + &orig_K_aut, + p_aka_payloads, + received_aka, + received_aka->get_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + bool authentication_ok = true; + + // Decrypt and parse encrypted payload. + { + aka_payloads_c * const l_aka_payloads = new aka_payloads_c(m_am_tools); + eap_automatic_variable_c l_aka_payloads_automatic(m_am_tools, l_aka_payloads); + + if (l_aka_payloads == 0 + || l_aka_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = decrypt_DATA_payload( + p_aka_payloads, + &orig_K_encr); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t state_payload_buffer_length = p_aka_payloads->get_ENCR_DATA()->get_data_length(); + const aka_payload_AT_header_c gp_data_payload( + m_am_tools, + p_aka_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), + state_payload_buffer_length); + + status = parse_aka_payload( + &gp_data_payload, + &state_payload_buffer_length, + l_aka_payloads, + received_aka->get_subtype()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (l_aka_payloads->get_COUNTER()->get_payload_included() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u32_t counter = l_aka_payloads->get_COUNTER()->get_original_header()->get_reserved(); + + if (counter == reauth_counter) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_notification_response_message_reauthentication(): ") + EAPL("reauth counter %d OK, %d=%s.\n"), + reauth_counter, + get_state(), + get_state_string())); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_notification_response_message_reauthentication(): ") + EAPL("reauth counter %d wrong, should be %d, %d=%s.\n"), + counter, + reauth_counter, + get_state(), + get_state_string())); + + authentication_ok = false; + } + } + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (authentication_ok == false + || get_aka_notification_code_F_bit(m_aka_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + + set_last_eap_identifier(static_cast(get_last_eap_identifier()+1u)); + set_state(eap_type_aka_state_failure); + + // This will terminate session immediately. + (void) get_type_partner()->set_session_timeout(0UL); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else //if (get_aka_notification_code_F_bit(m_aka_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + if (m_aka_notification_code == eap_aka_notification_F_set_no_P_user_authenticated) + { + status = finish_successful_authentication( + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_notification_response_message_reauthentication(): ") + EAPL("Not correct AKA-payloads are included ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else //if (get_aka_notification_code_P_bit(m_aka_notification_code) == true) + { + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_not_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_not_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_must_not_be, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_must_not_be // CHECKCODE + ) == true + ) + { + // If the P bit is set to one, the notification can only by used before + // the EAP/AKA/Challenge round in full authentication, or before the + // EAP/AKA/Re-authentication round in reauthentication. + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_aka_notification_code_F_bit(m_aka_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + } + else //if (get_aka_notification_code_F_bit(m_aka_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + } + + status = initialize_error_message( + eap_status_process_general_error); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_notification_response_message_reauthentication(): ") + EAPL("Not correct AKA-payloads are included ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_notification_response_message_full_authentication( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t /*aka_packet_length*/, + aka_payloads_c * const p_aka_payloads) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: handler 0x%08x, AKA-type %10s, %s, state %2d=%s\n"), + this, + EAPL("handle_notification_response_message_full_authentication"), + (get_is_client()) ? EAPL("client") : EAPL("server"), + get_state(), + get_state_string() + )); + + // The second most significant bit of the notification code is called + // the Phase bit (P bit). It specifies at which phase of the EAP-AKA + // exchange the notification can be used. + if (get_aka_notification_code_P_bit(m_aka_notification_code) == false) + { + // If the P bit is set to zero, + // the notification can only be used after a successful EAP/AKA/ + // Challenge round in full authentication or a successful EAP/AKA/ + // Re-authentication round in reautentication. A re-authentication round + // is considered successful only if the peer has successfully verified + // AT_MAC and AT_COUNTER attributes, and does not include the + // AT_COUNTER_TOO_SMALL attribute in EAP-Response/AKA/Re-authentication. + + // The AT_MAC attribute MUST beincluded if the P bit of the notification + // code in AT_NOTIFICATION is set to zero, and MUST NOT be included in + // cases when the P bit is set to one. The P bit is discussed in Section + // 4.4. + + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_not_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_must_not_be, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_must_not_be // CHECKCODE + ) == true + ) + { + eap_status_e status = check_message_authentication_code( + get_K_aut(), + p_aka_payloads, + received_aka, + received_aka->get_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_aka_notification_code_F_bit(m_aka_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + + set_last_eap_identifier(static_cast(get_last_eap_identifier()+1u)); + set_state(eap_type_aka_state_failure); + + // This will terminate session immediately. + (void) get_type_partner()->set_session_timeout(0UL); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else //if (get_aka_notification_code_F_bit(m_aka_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + if (m_aka_notification_code == eap_aka_notification_F_set_no_P_user_authenticated) + { + status = finish_successful_authentication( + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_notification_response_message_full_authentication(): ") + EAPL("Not correct AKA-payloads are included ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else //if (get_aka_notification_code_P_bit(m_aka_notification_code) == true) + { + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_not_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_not_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_must_not_be, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_must_not_be // CHECKCODE + ) == true + ) + { + // If the P bit is set to one, the notification can only by used before + // the EAP/AKA/Challenge round in full authentication, or before the + // EAP/AKA/Re-authentication round in reauthentication. + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_aka_notification_code_F_bit(m_aka_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + } + else //if (get_aka_notification_code_F_bit(m_aka_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + } + + eap_status_e status = initialize_error_message( + eap_status_process_general_error); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_notification_response_message_full_authentication(): ") + EAPL("Not correct AKA-payloads are included ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_notification_response_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + if (aka_packet_length < received_aka->get_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_notification_response_message(): ") + EAPL("aka_packet_length < received_aka->get_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + eap_status_e status = eap_status_process_general_error; + + if (get_state() == eap_type_aka_state_waiting_for_notification_response_success + || get_state() == eap_type_aka_state_waiting_for_notification_response_failure) + { + // NOTE, this message is unauthenticated. Anybody could sent this message. + + if (received_aka->get_identifier() != get_last_eap_identifier()) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_notification_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_identifier(), get_last_eap_identifier(), + get_state(), get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + + if (m_authentication_type == AKA_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + status = handle_notification_response_message_reauthentication( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = handle_notification_response_message_full_authentication( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_notification_response_message(): ") + EAPL("Wrong message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::check_challenge_response_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_not_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_optional, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_optional // CHECKCODE + ) == true + ) + { + save_current_state(); + set_state(eap_type_aka_state_analyses_challenge_response); + + status = get_saved_EAP_packet()->set_buffer( + received_aka->get_header_buffer(aka_packet_length), + aka_packet_length, + false, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = check_message_authentication_code( + get_K_aut(), + p_aka_payloads, + received_aka, + aka_packet_length); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (p_aka_payloads->get_CHECKCODE()->get_payload_included() == true) + { + // Verify AT_CHECKCODE. + status = checkcode_verify( + p_aka_payloads->get_CHECKCODE()->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (status == eap_status_ok) + { + // Ok, client successfully authenticated. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Authentication OK.\n"))); + + if (m_use_result_indication == false + && p_aka_payloads->get_RESULT_IND()->get_payload_included() == true) + { + // ERROR: We did not send AT_RESULT_IND and client responds with it. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + else if (m_use_result_indication == true + && p_aka_payloads->get_RESULT_IND()->get_payload_included() == false) + { + // Client does not expect result indication. + m_use_result_indication = false; + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (get_master_session_key()->get_is_valid_data() == false + || get_master_session_key()->get_data_length() == 0u) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_aka->store_reauth_parameters( + get_XKEY(), + get_K_aut(), + get_K_encr(), + EAP_TYPE_AKA_INITIAL_REAUTH_COUNTER); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_use_result_indication == true) + { + // Send EAP-Request/AKA/Notification. + m_aka_notification_code = eap_aka_notification_F_set_no_P_user_authenticated; + + status = send_aka_notification_request( + m_aka_notification_code, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(eap_type_aka_state_waiting_for_notification_response_success); + } + else + { + if (m_randomly_fail_successfull_authentication == true + && random_selection() == true) + { + // This is for testing. + m_aka_notification_code = eap_aka_notification_no_F_no_P_general_failure; + + status = initialize_notification_message(); + } + else + { + // Note the EAP-Identifier of EAP-Success must be the same as + // EAP-Identifier in the last EAP-Request - EAP-Response roundtrip. + status = finish_successful_authentication( + receive_network_id); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_challenge_response_message(6): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_challenge_response_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + if (get_state() == eap_type_aka_state_waiting_for_challenge_response) + { + if (received_aka->get_identifier() != get_last_eap_identifier()) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_challenge_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_identifier(), get_last_eap_identifier(), + get_state(), get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + status = check_challenge_response_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (get_state() == eap_type_aka_state_success) + { + if (received_aka->get_identifier() != get_last_eap_identifier()-1u) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_challenge_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_identifier(), + get_last_eap_identifier()-1u, + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + status = check_challenge_response_message( + receive_network_id, + received_aka, + aka_packet_length, + p_aka_payloads); + } + else if (get_state() == eap_type_aka_state_pending_authentication_vector_query) + { + // This is re-transmitted EAP-Response/AKA/Challenge. + // We dischard it quietly. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_aka_c::handle_challenge_response_message(): ") + EAPL("Re-transmitted message %d=%s dropped in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else + { + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_challenge_response_message(): ") + EAPL("Wrong message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_reauthentication_response_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_aka_c::handle_reauthentication_response_message(): %s, m_identity_type %d=%s, identity payload was %d=%s.\n"), + (m_is_client == true ? "client": "server"), + m_identity_type, + get_identity_string(m_identity_type), + get_aka_identity_response_includes_identity(), + aka_payload_AT_header_c::get_payload_AT_string(get_aka_identity_response_includes_identity()))); + + if (get_state() == eap_type_aka_state_waiting_for_reauth_response) + { + // This could be first or retransmission request. + + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_not_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_optional, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_optional // CHECKCODE + ) == true + ) + { + + set_last_eap_identifier(received_aka->get_identifier()); + + save_current_state(); + set_state(eap_type_aka_state_analyses_reauthentication_response); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_aut(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + + if (orig_XKEY.get_is_valid() == false + || orig_K_aut.get_is_valid() == false + || orig_K_encr.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t reauth_counter = 0u; + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_aka->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = check_message_authentication_code( + &orig_K_aut, + p_aka_payloads, + received_aka, + aka_packet_length); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: Re-authentication failed: %s, state %s\n"), + status_string.get_status_string(status), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (p_aka_payloads->get_CHECKCODE()->get_payload_included() == true) + { + // Verify AT_CHECKCODE. + status = checkcode_verify( + p_aka_payloads->get_CHECKCODE()->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // Decrypt and parse encrypted payload. + if (p_aka_payloads->get_IV()->get_payload_included() == true + || p_aka_payloads->get_ENCR_DATA()->get_payload_included() == true) + { + if (p_aka_payloads->get_IV()->get_payload_included() == true + && p_aka_payloads->get_ENCR_DATA()->get_payload_included() == true + && p_aka_payloads->get_MAC()->get_payload_included() == true) + { + if (m_use_result_indication == false + && p_aka_payloads->get_RESULT_IND()->get_payload_included() == true) + { + // ERROR: We did not send AT_RESULT_IND and client responds with it. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + else if (m_use_result_indication == true + && p_aka_payloads->get_RESULT_IND()->get_payload_included() == false) + { + // Client does not expect result indication. + m_use_result_indication = false; + } + + aka_payloads_c * const l_aka_payloads = new aka_payloads_c(m_am_tools); + eap_automatic_variable_c l_aka_payloads_automatic(m_am_tools, l_aka_payloads); + + if (l_aka_payloads == 0 + || l_aka_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = decrypt_DATA_payload( + p_aka_payloads, + &orig_K_encr); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t state_payload_buffer_length = p_aka_payloads->get_ENCR_DATA()->get_data_length(); + + const aka_payload_AT_header_c gp_data_payload( + m_am_tools, + p_aka_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), + state_payload_buffer_length); + + if (gp_data_payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_aka_payload( + &gp_data_payload, + &state_payload_buffer_length, + l_aka_payloads, + received_aka->get_subtype()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (l_aka_payloads->get_COUNTER_TOO_SMALL()->get_payload_included() == true) + { + // When the client detects that the + // counter value is not fresh, it includes the AT_COUNTER_TOO_SMALL + // attribute in EAP-Response/AKA/Re-authentication. This attribute + // doesn't contain any data but it is a request for the server to + // initiate full authentication. + + // The full authentication must follow. + m_authentication_type = AKA_AUTHENTICATION_TYPE_FULL_AUTH; + set_aka_identity_response_includes_identity(aka_payload_NONE); + + bool pseudonym_decode_failed = false; + + if (get_identity()->get_is_valid_data() == false + || (m_identity_type != AKA_IDENTITY_TYPE_IMSI_ID + && m_identity_type != AKA_IDENTITY_TYPE_PSEUDONYM_ID + && m_identity_type != AKA_IDENTITY_TYPE_RE_AUTH_ID)) + { + // We do not have any identity of the client. + set_aka_identity_response_includes_identity(aka_payload_AT_FULLAUTH_ID_REQ); + set_identity_type(AKA_IDENTITY_TYPE_NONE); + (void) get_identity()->reset(); + pseudonym_decode_failed = true; + } + + status = send_aka_identity_request_message( + pseudonym_decode_failed, + static_cast(received_aka->get_identifier()+1u)); + if (status == eap_status_ok) + { + set_last_eap_identifier(static_cast(received_aka->get_identifier()+1u)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (l_aka_payloads->get_COUNTER()->get_payload_included() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u32_t counter = l_aka_payloads->get_COUNTER()->get_original_header()->get_reserved(); + + if (counter != reauth_counter) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // OK, client re-authenticates corretly. + + if (m_use_result_indication == true) + { + // Send EAP-Request/AKA/Notification. + m_aka_notification_code = eap_aka_notification_F_set_no_P_user_authenticated; + + status = send_aka_notification_request( + m_aka_notification_code, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(eap_type_aka_state_waiting_for_notification_response_success); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_AKA: %s, re-authentication OK, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else + { + if (m_randomly_fail_successfull_authentication == true + && random_selection() == true) + { + // This is for testing. + m_aka_notification_code = eap_aka_notification_no_F_no_P_general_failure; + + status = initialize_notification_message(); + } + else + { + // Note the EAP-Identifier of EAP-Success must be the same as + // EAP-Identifier in the last EAP-Request - EAP-Response roundtrip. + status = finish_successful_authentication( + receive_network_id); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // All of these must be included + // or none of these must be included. + restore_saved_previous_state(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + else + { + // Not correct AKA-payloads are included. + restore_saved_previous_state(); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_reauthentication_response_message(6): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_reauthentication_response_message(6): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_reauthentication_response_message(): ") + EAPL("Wrong message %d=%s in eap_type_aka_state_variable_e %d=%s.\n"), + received_aka->get_subtype(), + received_aka->get_subtype_string(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::handle_client_error_response_message( + const eap_am_network_id_c * const /* receive_network_id */, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads) +{ + EAP_UNREFERENCED_PARAMETER(aka_packet_length); + EAP_UNREFERENCED_PARAMETER(received_aka); + + eap_status_e status = eap_status_process_general_error; + + // This could be first, retransmission request + // or some nasty attacker to make denial of service. + + // Checks the payloads existence. + if (p_aka_payloads->check_payloads( + aka_payloads_c::eap_aka_payload_status_must_not_be, // nonce_s + aka_payloads_c::eap_aka_payload_status_must_not_be, // MAC + aka_payloads_c::eap_aka_payload_status_must_not_be, // ENCR_DATA + aka_payloads_c::eap_aka_payload_status_must_not_be, // IDENTITY + aka_payloads_c::eap_aka_payload_status_must_not_be, // padding + aka_payloads_c::eap_aka_payload_status_must_not_be, // n_RANDs + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTN + aka_payloads_c::eap_aka_payload_status_must_not_be, // AUTS + aka_payloads_c::eap_aka_payload_status_must_not_be, // RES + aka_payloads_c::eap_aka_payload_status_must_not_be, // PERMANENT_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // FULLAUTH_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // ANY_ID_REQ + aka_payloads_c::eap_aka_payload_status_must_not_be, // IV + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_PSEUDONYM + aka_payloads_c::eap_aka_payload_status_must_not_be, // NEXT_REAUTH_ID + aka_payloads_c::eap_aka_payload_status_must_not_be, // NOTIFICATION + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER + aka_payloads_c::eap_aka_payload_status_must_not_be, // COUNTER_TOO_SMALL + aka_payloads_c::eap_aka_payload_status_must_be, // CLIENT_ERROR_CODE + aka_payloads_c::eap_aka_payload_status_must_not_be, // RESULT_IND + aka_payloads_c::eap_aka_payload_status_must_not_be // CHECKCODE + ) == true + ) + { + eap_status_e client_status = eap_status_process_general_error; + + /** @{ Add some use for the Client Error Code. } */ + eap_aka_client_error_code_e client_error_code + = static_cast(p_aka_payloads->get_CLIENT_ERROR_CODE() + ->get_original_header()->get_reserved()); + + EAP_UNREFERENCED_PARAMETER(client_error_code); + + status = initialize_error_message( + client_status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct AKA-payloads are included. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: eap_type_aka_c::handle_client_error_response_message(): ") + EAPL("Not correct AKA-payloads are included in eap_type_aka_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::check_NAI( + const u8_t * const identity, + const u32_t identity_length, + const u8_t * const at_character) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + bool includes_at = false; + bool includes_dot = false; + u32_t username_length = 0u; + u32_t realm_length = 0u; + + for (u32_t ind = 0; ind < identity_length; ind++) + { + const u8_t character = identity[ind]; + + if (includes_at == false) + { + if (character != AKA_NAI_AT_BYTE) + { + ++username_length; + } + } + else + { + ++realm_length; + } + + + if ('0' <= character && character <= '9') + { + // OK. + } + else if ('a' <= character && character <= 'z') + { + // OK. + } + else if ('A' <= character && character <= 'Z') + { + // OK. + } + else if (character == AKA_NAI_AT_BYTE) + { + if (includes_at == false) + { + includes_at = true; + } + else + { + // Second at ('@'). + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Illegal NAI, includes second at \'@\' character."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + else if (character == '.') + { + if (includes_at == true) + { + // OK. + includes_dot = true; + } + else + { + // dot ('.') within username + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Illegal NAI, dot \'.\' within username."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + else if (character == '<' + || character == '>' + || character == '(' + || character == ')' + || character == '[' + || character == ']' + || character == '\\' + || character == '.' + || character == ',' + || character == ';' + || character == ':' + || character == AKA_NAI_AT_BYTE + || character == ' ' // space + || character <= 0x1f // Ctrl + || character >= 0x7f) // extented characters + { + // Illegal character. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_AKA_ERROR, + (EAPL("ERROR: Illegal NAI, includes illegal character 0x%02x=%c.\n"), + character, + character)); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Illegal NAI, includes illegal character."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + else + { + // All other ascii values are OK. + } + } + + // Note the username could be zero length. + if ((realm_length == 1u && includes_at == true) // one at ('@') is illegal. + || (realm_length == 2u && includes_at == true && includes_dot == true)) // one at ('@') and one dot is illegal. + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, (EAPL("Illegal NAI."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + + if (m_check_nai_realm == true) + { + if (at_character == 0 + && realm_length == 0 + && get_nai_realm()->get_data_length() == 0) + { + // OK, no realm. + } + else if (at_character == 0 + || realm_length != get_nai_realm()->get_data_length() + || m_am_tools->memcmp( + at_character+1u, + get_nai_realm()->get_data(get_nai_realm()->get_data_length()), + get_nai_realm()->get_data_length()) != 0) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Illegal NAI, realm unknown."), + identity, + identity_length)); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("NAI should be"), + get_nai_realm()->get_data(get_nai_realm()->get_data_length()), + get_nai_realm()->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_aka_c::parse_identity( + const u8_t * const identity, + const u32_t identity_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + if (identity_length < 1u) + { + status = get_identity()->init(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_NAI()->init(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + const u8_t *at_character = reinterpret_cast(m_am_tools->memchr( + identity, + AKA_AT_CHARACTER[0], + identity_length)); + + // NOTE, at_character could be NULL. Realm is optional. + + status = check_NAI(identity, identity_length, at_character); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_process_general_error; + + u32_t username_length = identity_length; + if (at_character != 0) + { + username_length = static_cast(at_character-identity); + } + + status = get_identity()->set_copy_of_buffer( + identity, // Note we do store whole IMSI or pseudonym including possible prefix. + username_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_NAI()->set_copy_of_buffer(identity, identity_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_state.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_state.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,109 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 71 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_type_aka_header.h" +#include "eap_type_aka_types.h" +#include "eap_type_aka_payloads.h" +//#include "abs_eap_type_aka_state.h" +#include "abs_eap_base_timer.h" +#include "eap_type_aka_state.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_type_aka_state_variable_parameters_c::~eap_type_aka_state_variable_parameters_c() +{ +} + +EAP_FUNC_EXPORT eap_type_aka_state_variable_parameters_c::eap_type_aka_state_variable_parameters_c() + : m_must_be_initiator(false) + , m_must_be_responder(false) + , m_dummy_1_for_alignment(0) + , m_dummy_2_for_alignment(0) +{ + u32_t ind = 0; + for (ind = 0; ind < AKA_STATE_MAX_TYPES; ind++) + { + m_valid_types[ind] = aka_subtype_NONE; + } +} + + +EAP_FUNC_EXPORT bool eap_type_aka_state_variable_parameters_c::check_valid_types(aka_subtype_e type) const +{ + for (u32_t ind = 0u; ind < AKA_STATE_MAX_TYPES; ind++) + { + if (type == m_valid_types[ind]) + { + return true; + } + } + return false; +} + +EAP_FUNC_EXPORT bool eap_type_aka_state_variable_parameters_c::check_initiator(const bool is_initiator) const +{ + if (m_must_be_initiator == true && is_initiator == false + || m_must_be_responder == true && is_initiator == true) + { + return false; + } + return true; +} + +EAP_FUNC_EXPORT void eap_type_aka_state_variable_parameters_c::init_state( + const bool must_be_initiator, + const bool must_be_responder, + const aka_subtype_e type0, + const aka_subtype_e type1, + const aka_subtype_e type2, + const aka_subtype_e type3, + const aka_subtype_e type4) +{ + m_must_be_initiator = (must_be_initiator); + m_must_be_responder = (must_be_responder); + m_valid_types[0] = (type0); + m_valid_types[1] = (type1); + m_valid_types[2] = (type2); + m_valid_types[3] = (type3); + m_valid_types[4] = (type4); +} + + +//----------------------------------------------- + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_state_notification.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/core/eap_type_aka_state_notification.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,123 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 72 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_type_aka_state_notification.h" +#include "eap_type_aka_types.h" +#include "eap_tools.h" +#include "eap_type_aka.h" + + +EAP_FUNC_EXPORT eap_type_aka_state_notification_c::~eap_type_aka_state_notification_c() +{ +} + +EAP_FUNC_EXPORT eap_type_aka_state_notification_c::eap_type_aka_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e type, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + protocol, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + + +#if defined(USE_EAP_EXPANDED_TYPES) + +EAP_FUNC_EXPORT eap_type_aka_state_notification_c::eap_type_aka_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e type, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + eap_type, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + +EAP_FUNC_EXPORT eap_type_aka_state_notification_c::eap_type_aka_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e type, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + eap_type, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/core/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/core/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,28 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_aka + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/type/aka/core/eap_type_aka.cpp \ + $(WLAN_COMMON)/type/aka/core/eap_type_aka_authentication_vector.cpp \ + $(WLAN_COMMON)/type/aka/core/eap_type_aka_client.cpp \ + $(WLAN_COMMON)/type/aka/core/eap_type_aka_header.cpp \ + $(WLAN_COMMON)/type/aka/core/eap_type_aka_payloads.cpp \ + $(WLAN_COMMON)/type/aka/core/eap_type_aka_server.cpp \ + $(WLAN_COMMON)/type/aka/core/eap_type_aka_state.cpp \ + $(WLAN_COMMON)/type/aka/core/eap_type_aka_state_notification.cpp \ + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_aka_simulator.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_testing_tools.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_aka_tools.$(LIB) \ + -lstdc++ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/include/abs_eap_type_aka_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/include/abs_eap_type_aka_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,147 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#error Do not use anymore. + +#if !defined(_ABS_AKA_STATE_H_) +#define _ABS_AKA_STATE_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_buffer.h" +#include "eap_base_type.h" +#include "eap_config.h" +#include "eap_type_aka_types.h" + + +/// This class declares the functions eap_type_aka_state_c +/// requires from the partner class. +class EAP_EXPORT abs_eap_type_aka_state_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Constructor does nothing. + */ + virtual ~abs_eap_type_aka_state_c() + { + } + + /** + * Desstructor does nothing. + */ + abs_eap_type_aka_state_c() + { + } + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @see abs_eap_base_type_c::get_header_offset(). + */ + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + //-------------------------------------------------- +}; // class abs_eap_type_aka_state_c + + + +#endif //#if !defined(_ABS_AKA_STATE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1961 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_AKA_CORE_H_) +#define _AKA_CORE_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_type_aka_header.h" +#include "eap_type_aka_types.h" +#include "eap_type_aka_payloads.h" +#include "eap_type_aka_state.h" +#include "eap_type_aka_initialized.h" +#include "abs_eap_base_timer.h" +#include "abs_eap_am_type_aka.h" +#include "eap_am_type_aka.h" +#include "eap_crypto_api.h" +#include "eap_master_session_key.h" + + +//-------------------------------------------------- + + +/// This class is implementation of AKA EAP-type. +class EAP_EXPORT eap_type_aka_c +: public abs_eap_am_type_aka_c +, public abs_eap_base_timer_c +, public eap_base_type_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to adaptation module of AKA EAP type. + eap_am_type_aka_c * const m_am_type_aka; + + + /// HASH over all AKA-Identity messages. + crypto_sha1_c m_checkcode; + + u32_t m_checkcode_update_count; + + eap_variable_data_c m_received_checkcode; + + eap_variable_data_c m_checkcode_saved_message; + + eap_array_c m_all_payloads; + + + eap_variable_data_c m_nonce_mt_file; + + eap_variable_data_c m_manual_username; + + eap_variable_data_c m_manual_realm; + + /// This is the automatic realm generated in AM of EAP-SIM. + /// Note this could be invalid data when automatic realm is not used. + /// The m_automatic_realm_read flag tells whether m_automatic_realm is read from AM of EAP-SIM. + eap_variable_data_c m_automatic_realm; + + /// This flag tells whether automatic realm is read from AM of EAP-SIM. + /// Note the data of m_automatic_realm could be invalid data when it is not used. + bool m_automatic_realm_read; + + /// This is offset in bytes of the EAP-type header in the packet buffer. + /// Offset is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_aka_header_offset; + + /// This is maximum transfer unit in bytes. + /// MTU is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_MTU; + + /// This is length of the trailer in bytes. + /// Trailer length is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_trailer_length; + + u32_t m_length_of_mnc; + + /// This stores the current authentication type. + /// Look at the m_identity_type too. + eap_aka_authentication_type_e m_authentication_type; + + /// This stores the current identity type. + /// NOTE there is one stupid case where m_identity_type is AKA_IDENTITY_TYPE_RE_AUTH_ID + /// and m_authentication_type is AKA_AUTHENTICATION_TYPE_FULL_AUTH. + /// Look at the Chapter "Fast Re-authentication Procedure when Counter is Too Small" + /// in the EAP-SIM specification. + /// Because of that illogical specification we need separate + /// attributes for authentication type and identity type. + eap_type_aka_identity_type m_identity_type; + + /// This is the first client error. + eap_aka_client_error_code_e m_client_error_code; + + /// This is saved AKA notificatoin code. + /// If this value is eap_aka_notification_none, no notification is stored. + eap_aka_notification_codes_e m_aka_notification_code; + + u32_t m_failure_message_delay_time; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + /// True value of this flag indicates the EAP-Success packet must be received + /// in successfull authentication of clien. + /// This value is configured with EAP_AKA_wait_eap_success_packet. + bool m_wait_eap_success_packet; + + /// True value of this flag indicates the identifier of the EAP-Response/Identity must be checked. + /// This is not possible cases where identifier of the EAP-Request/Identity is generated by other network entities. + bool m_check_identifier_of_eap_identity_response; + + + /// True value means m_am_type_aka is allocated within eap_type_aka_c + /// and m_am_type_aka must be freed in destructor. + bool m_free_am_type_aka; + + /// True value means client responds to all re-transmitted EAP-AKA packets. + /// False value means client does not respond to any re-transmitted EAP-AKA packets. + bool m_client_responds_retransmitted_packets; + + /// True value means this is a test version of AKA. + bool m_aka_test_version; + + /// True value means server refuses EAP-identity randomly. + /// False value means does not refuse EAP-identity randomly. + /// NOTE EAP_AKA_test_version option must be true also. + bool m_aka_randomly_refuse_eap_identity; + + /// This flag forces check of NAI realm. Realm must be the same as given in EAP_AKA_manual_realm configuration option. + /// Default value is false, check is not done by default. + bool m_check_nai_realm; + + /// This is for testing purposes. True value will cause failed test of re-authentication counter. + bool m_fail_reauthentication_counter_check; + + /// True value of this flag allows acception of EAP-Response/Identity. + /// False value does not accept EAP-Response/Identity. Instead identity is queried + /// in EAP-Request/AKA/Start with AT_ANY_ID_REQ attribute. + bool m_accept_eap_identity_response; + + /// True value of this flag returns random + /// identity on EAP-Response/Identity. + /// False value returns real identity + /// (IMSI, pseudonym or re-authentication identity). + bool m_use_random_identity_on_eap_identity_response; + + /// This flag is set true when shutdown() function is called. + bool m_shutdown_was_called; + + /// This flag is set true when reset() function is called. + /// This flag prevent multiple subsequent calls of rset() function. + bool m_reset_was_called; + + /// This flag tells whether the pseudonym identity could be used (true) or not (false). + bool m_use_pseudonym_identity; + + /// This flag tells whether the re-authentication identity could be used (true) or not (false). + bool m_use_reauthentication_identity; + + /// This is set true when erroneus packet is received. + bool m_erroneus_packet_received; + + /// This is set true when AKA notification packet is received. + bool m_aka_notification_packet_received; + + /// This flag allows use of Windows RAS identity in EAP-Identity/Response. + /// EAP-Request/Start will include identity query attribute. + bool m_use_manual_username; + + /// Default value is false. That will cause use of automatic realm. + /// If this is true then + /// cf_str_EAP_AKA_manual_realm is used as the realm. + bool m_use_manual_realm; + + bool m_randomly_fail_successfull_authentication; + + bool m_allow_use_result_indication; + + bool m_use_result_indication; + + //-------------------------------------------------- + //-------------------------------------------------- + + /// This attribute stores the valid AKA states (eap_type_aka_state_variable_e). + /// Each eap_type_aka_state_variable_parameters_c includes the valid + /// AKA messages within the state. + eap_type_aka_state_variable_parameters_c m_parameters[eap_type_aka_state_last_value]; + + /// This is the current state. + eap_type_aka_state_variable_e m_state; + + /// This is the saved previous state. On error case this is the state where continue. + eap_type_aka_state_variable_e m_saved_previous_state; + + /// This is network identity of the sent packet from this handler. + eap_am_network_id_c m_send_network_id; + + /// This is the NONCE_S. Server generates NONCE_S and sends it to client + /// within the EAP-Request/AKA/Re-authentication message. + eap_variable_data_c m_nonce_s; + + // - - - - - - - - - - - - - - - - - - - - + + /// Server sends IV to client within EAP-Request/AKA/Challenge message. + /// The AT_IV payload is optional. + aka_variable_data_c m_IV; + + /// EAP-Request/AKA/Challenge message must be saved until n*Kc and n*SRES are get from AKA. + eap_variable_data_c m_saved_EAP_packet; + + // - - - - - - - - - - - - - - - - - - - - + + /// XKEY = SHA1(n*Kc| NONCE_MT) + eap_variable_data_c m_XKEY; + + /// K_encr is the first 16 octets of generated Key_block:s. + eap_variable_data_c m_K_encr; + + /// K_aut is the 16 octets after K_encr of generated Key_block:s. + eap_variable_data_c m_K_aut; + + /// m_master_session_key is the 20 octets after m_K_aut of generated Key_block:s. + eap_master_session_key_c m_master_session_key; + + // - - - - - - - - - - - - - - - - - - - - + + /// This is the real IMSI. + eap_variable_data_c m_IMSI; + + /// This is the pseudonym for IMSI. This is used only if server supports use of pseudonym. + eap_variable_data_c m_pseudonym; + + /// This is the reauthentication identity. This is used only if server supports use of reauthentication identity. + eap_variable_data_c m_reauthentication_identity; + + /// This is identity used in authentication. This is real IMSI or pseudonym. + /// Pseudonym is used only if server supports use of pseudonym. + eap_variable_data_c m_identity; + + /// This is the NAI. Format is "username@realm". + eap_variable_data_c m_NAI; + + eap_variable_data_c m_RAND; + + eap_variable_data_c m_AUTN; + + eap_variable_data_c m_RES; + + eap_variable_data_c m_2_digit_mnc_map_of_mcc_of_imsi_array; + + eap_variable_data_c m_uma_automatic_realm_prefix; + + bool m_use_uma_profile; + + /// Here is stored the received authentication vector. + eap_type_aka_authentication_vector_c *m_authentication_vector; + + u32_t m_reauthentication_counter; + + aka_payload_AT_type_e m_include_identity_to_aka_identity_response; + + /// Identity of this type is included in start response. + aka_payload_AT_type_e m_aka_identity_response_includes_identity; + + /// This flag indicates whether the EAP-Failure was received. + /// On successfull authentication bogus EAP-Failure is ignored. + bool m_failure_message_received; + /// This flag indicated whether the authentication was successfull (true). + bool m_authentication_finished_successfully; + + /// This variable stores the last used EAP-Identifier. + /// Client will always send EAP-Response with this identifier. + /// Server will always send EAP-Request with this identifier increased by one. + /// Server increase this identifier after successfull packet send. + u8_t m_last_eap_identifier; + + bool m_use_eap_expanded_type; + + //-------------------------------------------------- + //-------------------------------------------------- + + /** + * This function initializes the allowed messages within one specific state. + */ + EAP_FUNC_IMPORT void initialize_state( + const eap_type_aka_state_variable_e state, + const bool must_be_initiator, + const bool must_be_responder, + const aka_subtype_e type0, + const aka_subtype_e type1, + const aka_subtype_e type2, + const aka_subtype_e type3, + const aka_subtype_e type4); + + /** + * This function expands key and seed data to key_length of expansion. + * expansion_0 = prf(key, seed | 0) + * expansion_i = prf(key, expansion_i-1 | seed | i), where i = 1, 2... + */ + EAP_FUNC_IMPORT eap_status_e data_exp( + const u32_t key_length, + eap_variable_data_c * const expansion, + const eap_variable_data_c * const key, + const eap_variable_data_c * const seed); + + /** + * This function returns the eap_type_aka_state_variable_parameters_c object of current state. + */ + EAP_FUNC_IMPORT const eap_type_aka_state_variable_parameters_c * get_state_variable(); + + + //-------------------------------------------------- + //-------------------------------------------------- + + /** + * This function generates a new NAI from domain and IMSI. + */ + EAP_FUNC_IMPORT eap_status_e generate_nai( + eap_variable_data_c * const new_nai, ///< This is the new generated NAI. + const bool use_manual_default_realm, ///< When true uses realm parameter, when false generates automatic realm. + const eap_variable_data_c * const realm, ///< This is the domain part of the NAI. + const eap_variable_data_c * const id_IMSI_or_pseydonym, ///< This is IMSI or pseudonym. + const bool id_is_imsi, ///< This parameter tells whether id_IMSI_or_pseydonym is IMSI (true) or pseudonym (false). + const eap_variable_data_c * const IMSI, ///< This parameter must be IMSI always. + const eap_variable_data_c * const automatic_realm, + const u32_t length_of_mnc + ); + + /** + * This function adds generic attribute payload to AKA message. + * @param aka is pointer to EAP header including AKA fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also aka_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in AKA EAP packet. + * It is the value of AKA sub-type data. + * @param data_free is the remaining free AKA data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param data_payload is the new payload to be added. + * @param data_payload_type is the attribute payload type to be added. + * + * See also eap_type_aka_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT type | Payload Length| Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Any variable length payload | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_variable_payload( + aka_header_c * const aka, + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_free, + u32_t * const buffer_offset, + const eap_variable_data_c * const data_payload, + const aka_payload_AT_type_e data_payload_type); + + /** + * This function adds AUTS attribute payload to AKA message. + * @param aka is pointer to EAP header including AKA fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also aka_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in AKA EAP packet. + * It is the value of AKA sub-type data. + * @param data_free is the remaining free AKA data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param data_payload is the new payload to be added. + * @param data_payload_type is the attribute payload type to be added. + * + * See also eap_type_aka_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT type | Payload Length| AUTS ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ... AUTS | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_AUTS_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_variable_data_c * const data_payload, + const aka_payload_AT_type_e data_payload_type); + + /** + * This function adds RES attribute payload to AKA message. + * @param aka is pointer to EAP header including AKA fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also aka_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in AKA EAP packet. + * It is the value of AKA sub-type data. + * @param data_free is the remaining free AKA data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param RES is the RES payload to be added. + * @param data_payload_type is the attribute payload type to be added. + * + * See also eap_type_aka_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT_RES | Length | RES Length in bits | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | RES ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_RES_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_variable_data_c * const RES, + const aka_payload_AT_type_e data_payload_type); + + /** + * This function adds IMSI or pseudonym attribute payload to AKA message. + * @param aka is pointer to EAP header including AKA fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also aka_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in AKA EAP packet. + * It is the value of AKA sub-type data. + * @param data_free is the remaining free AKA data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param pseudonym_or_imsi is the IMSI or pseudonym payload to be added. + * @param data_payload_type is the attribute payload type to be added. + * + * See also eap_type_aka_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT_ | Length | Actual Pseudonym Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Pseudonym or IMSI | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_pseudonym_or_imsi_payload( + aka_header_c * const aka, + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_free, + u32_t * const buffer_offset, + const eap_variable_data_c * const pseudonym_or_imsi, + const aka_payload_AT_type_e data_payload_type); + + + /** + * This function adds selected version attribute payload to AKA message. + * @param aka is pointer to EAP header including AKA fields. + * @param aka_buffer_length is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also aka_header_c and eap_header_base_c. + * @param aka_data_offset is the offset of inserted payloads in AKA EAP packet. + * It is the value of AKA sub-type data. + * @param aka_data_free is the remaining free AKA data buffer size. + * @param packet_buffer_free is the remaining free packet buffer size. + * @param packet_buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param counter is the re-authentication counter. + * + * See also eap_type_aka_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |AT_COUNTER | Length = 1 | Counter | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_counter_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + u16_t counter); + + + /** + * This function adds akaple attribute payload to AKA message. + * @param aka is pointer to EAP header including AKA fields. + * @param aka_buffer_length is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also aka_header_c and eap_header_base_c. + * @param aka_data_offset is the offset of inserted payloads in AKA EAP packet. + * It is the value of AKA sub-type data. + * @param aka_data_free is the remaining free AKA data buffer size. + * @param packet_buffer_free is the remaining free packet buffer size. + * @param packet_buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param data_payload_type is the type of akaple payload. + * + * See also eap_type_aka_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |AT_XXX | Length = 1 | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_simple_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const aka_payload_AT_type_e data_payload_type); + + /** + * This function adds Notification attribute payload to AKA message. + * @param aka is pointer to EAP header including AKA fields. + * @param aka_buffer_length is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also aka_header_c and eap_header_base_c. + * @param aka_data_offset is the offset of inserted payloads in AKA EAP packet. + * It is the value of AKA sub-type data. + * @param aka_data_free is the remaining free AKA data buffer size. + * @param packet_buffer_free is the remaining free packet buffer size. + * @param packet_buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * + * See also eap_type_aka_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |AT_NOTIFICATION| Length = 1 | Notification Code | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_notification_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_aka_notification_codes_e notification_code); + + /** + * This function adds AT_CLIENT_ERROR_CODE attribute payload to AKA message. + * @param aka is pointer to EAP header including AKA fields. + * @param aka_buffer_length is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also aka_header_c and eap_header_base_c. + * @param aka_data_offset is the offset of inserted payloads in AKA EAP packet. + * It is the value of AKA sub-type data. + * @param aka_data_free is the remaining free AKA data buffer size. + * @param packet_buffer_free is the remaining free packet buffer size. + * @param packet_buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param client_error_code is the error code to be sent. + * + * See also eap_type_aka_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |AT_CLIENT_ERR..| Length = 1 | Client Error Code | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_client_error_payload( + aka_header_c * const aka, + const u32_t aka_buffer_length, + const u32_t eap_header_size, + u32_t * const aka_data_offset, + u32_t * const aka_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_aka_client_error_code_e client_error_code); + + /** + * This function adds message authentication code (MAC) attribute payload to AKA message. + * This MAC is written later in the create_message_authentication_code() function. + * MAC includes the whole EAP message. + * @param aka is pointer to EAP header including AKA fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also aka_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in AKA EAP packet. + * It is the value of AKA sub-type data. + * @param data_free is the remaining free AKA data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param MAC_data is the start of the message authentication code (MAC) to be written. + * @param MAC_data_length is the length of the message authentication code (MAC) to be written. + * + * See also eap_type_aka_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT_MAC | Length | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MAC | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_mac_payload( + aka_header_c * const aka, + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_free, + u32_t * const buffer_offset, + u8_t ** const MAC_data, + u32_t * const MAC_data_length); + + /** + * This function adds message authentication code (MAC) attribute payload to AKA message. + * This MAC is written later in the create_message_authentication_code() function. + * @param aka is pointer to EAP header including AKA fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also aka_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in AKA EAP packet. + * It is the value of AKA sub-type data. + * @param data_free is the remaining free AKA data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param plaintext_length is the length of the plain text. Padding length is calculated from this. + * + * See also eap_type_aka_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT_PADDING | Length | Padding set to zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Zero or more padding octets. Padding octet is 0x00. | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_padding_payload( + aka_header_c * const aka_packet, + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_free, + u32_t * const buffer_offset, + const u32_t plaintext_length); + + /** + * This function verifies the message authentication code (MAC) is correct. + * @see add_mac_payload(). + */ + EAP_FUNC_IMPORT eap_status_e check_message_authentication_code( + const eap_variable_data_c * const authentication_key, + aka_payloads_c * const p_aka_payloads, ///< This is pointer to all payloads of the received EAP packet. + const aka_header_c * const aka_packet, + const u32_t aka_packet_length); + + /** + * This function handles the received AKA EAP packet. + * + * First is checked the valid massage is received in valid state. + * See also check_valid_state(). + * + * Second is parsed the payloads and checked syntax of the received AKA EAP packet. + * See also parse_aka_packet(). + * + * Third is analysed the AKA EAP packet. This includes the payload and values of each payload. + * See also analyse_aka_packet(). + */ + EAP_FUNC_IMPORT eap_status_e handle_aka_packet( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + aka_header_c * const aka, ///< This is pointer to EAP header including AKA fields. + const u32_t aka_length, ///< This is length of received AKA EAP packet. + aka_payloads_c * const p_aka_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + /** + * This function analyses the received AKA EAP packet. + * Each sub-type is handled in separate function. + * @see Client messages are handled in handle_aka_identity_request_message() and handle_challenge_request_message(). + * @see Server messages are handled in handle_aka_identity_response_message() and handle_challenge_response_message(). + */ + EAP_FUNC_IMPORT eap_status_e analyse_aka_packet( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + aka_header_c * const received_aka, ///< This is pointer to EAP header including AKA fields. + const u32_t aka_packet_length, ///< This is length of received AKA EAP packet. + aka_payloads_c * const p_aka_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + /** + * This function parses the payloads starting from specified payload (p_payload). + * Function parses all payloads from the buffer. + * Payloads are stored to p_aka_payloads. + * @return If the length of the buffer and sum of the length of all payloads does not match + * function returns eap_status_header_corrupted. + * Also error is returned when illegal payload attribute is recognised. + */ + EAP_FUNC_IMPORT eap_status_e parse_aka_payload( + const aka_payload_AT_header_c * const p_payload, ///< This is the start of the buffer and the first parsed payload. + u32_t * const buffer_length, ///< This is the length of the buffer. This must match with the length of all payloads. + aka_payloads_c * const p_aka_payloads, ///< This is pointer to all payloads of the received EAP packet. + const aka_subtype_e subtype + ); + + /** + * This function parses all payloads of the whole AKA EAP packet. + * Payloads are stored to p_aka_payloads. + * @see parse_aka_payload(). + */ + EAP_FUNC_IMPORT eap_status_e parse_aka_packet( + aka_header_c * const aka, ///< This is pointer to EAP header including AKA fields. + const u32_t aka_packet_length, ///< This is length of received AKA EAP packet. + aka_payloads_c * const p_aka_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + /** + * This function parses each payload attributes. + * @return If payload attribute is illegal function returns eap_status_header_corrupted. + * If payload attribute is unknown function returns eap_status_unsupported_aka_payload. + */ + EAP_FUNC_IMPORT eap_status_e parse_generic_payload( + const aka_payload_AT_type_e current_payload, ///< This is the type of current payload attribute. + const aka_payload_AT_header_c * const payload, ///< This is the current parsed payload. + aka_payloads_c * const p_aka_payloads, ///< This is pointer to all payloads of the received EAP packet. + const aka_subtype_e subtype); + + /** + * This function sends the EAP-Request/AKA/Re-authentication message. + */ + EAP_FUNC_IMPORT eap_status_e send_reauthentication_request_message( + const eap_variable_data_c * const username, + const bool pseudonym_decode_failed, + const u8_t eap_identifier); + + /** + * This function sends the EAP-Request/AKA/Start message. + */ + EAP_FUNC_IMPORT eap_status_e send_aka_identity_request_message( + const bool pseudonym_decode_failed, ///< This identifies whether the pseudonym decode was failed (true). We must send a IMSI request. + const u8_t eap_identifier ///< This is the EAP-Identifier used with this message. + ); + + /** + * This function sends the EAP-Response/AKA/Start message. + */ + EAP_FUNC_IMPORT eap_status_e send_aka_identity_response_message( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. NOTE received. + const u8_t received_eap_identifier, ///< This is the EAP-identifier of the received EAP-request message. + const aka_payload_AT_type_e include_identity_to_aka_identity_response, ///< This is the queried identity type. + const eap_variable_data_c * const automatic_realm + ); + + /** + * This function sends the EAP-Response/AKA/Notification message. + */ + EAP_FUNC_IMPORT eap_status_e send_aka_notification_response( + const eap_aka_notification_codes_e notification_code, + const bool add_at_counter_attribute + ); + + /** + * This function sends the EAP-Response/AKA/Client-Error message. + */ + EAP_FUNC_IMPORT eap_status_e send_aka_client_error_response(); + + /** + * This function sends the EAP-Request/AKA/Challenge message. + */ + EAP_FUNC_IMPORT eap_status_e send_challenge_request_message( + const u8_t eap_identifier ///< This is the EAP-Identifier used with this message. + ); + + /** + * This function sends the EAP-Response/AKA/Challenge message. + */ + EAP_FUNC_IMPORT eap_status_e send_challenge_response_message( + eap_variable_data_c * const K_aut); + + EAP_FUNC_IMPORT eap_status_e send_reauthentication_response_message( + const eap_variable_data_c * const orig_XKEY, + const eap_variable_data_c * const orig_K_aut, + const eap_variable_data_c * const orig_K_encr, + const eap_variable_data_c * const reauth_username, + const eap_variable_data_c * const reauth_nonce_s, + const u16_t reauth_counter, + const u8_t eap_identifier, + const bool include_at_counter_too_small); + + /** + * This function sends the EAP-Request/AKA/Notification message. + * Message includes the localizable notification string. + */ + EAP_FUNC_IMPORT eap_status_e send_aka_notification_request( + const eap_aka_notification_codes_e notification_code, + const bool add_at_counter_attribute + ); + + EAP_FUNC_IMPORT eap_status_e send_aka_synchronization_failure_response_message( + const eap_type_aka_authentication_vector_c * const authentication_vector + ); + + EAP_FUNC_IMPORT eap_status_e send_aka_authentication_reject_response_message( + const eap_type_aka_authentication_vector_c * const authentication_vector + ); + + /** + * This function encrypts the payload. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_DATA_payload( + u8_t * const EAP_data, ///< This is pointer to the begin of the encrypted payload. + const u32_t cbc_aes_data_length, ///< This is the length of the encrypted payload. This must be aligned to AES block length. + const eap_variable_data_c * const IV, + const eap_variable_data_c * const encryption_key + ); + + /** + * This function decrypts the payload. + * p_aka_payloads->get_ENCR_DATA() points to the decrypted payload. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_DATA_payload( + aka_payloads_c * const p_aka_payloads, ///< This is pointer to all payloads of the received EAP packet. + const eap_variable_data_c * const encryption_key + ); + + /** + * This function handles the received DATA payload attribute. + * The received encrypte payload have been decrypted before thiscall. + * p_aka_payloads->get_ENCR_DATA() includes decrypted DATA payload. + */ + EAP_FUNC_IMPORT eap_status_e handle_DATA_payload( + const aka_subtype_e subtype, + aka_payloads_c * const p_aka_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + //-------------------------------------------------- + + /** + * This function generate a new NONCE of nonce_size octets length. + */ + EAP_FUNC_IMPORT eap_status_e generate_nonce( + const u32_t nonce_size, + eap_variable_data_c * const nonce); + + /** + * This function returns the domain name. + */ + EAP_FUNC_IMPORT eap_variable_data_c * get_nai_realm(); + + /** + * This is the situation before the update_buffer_indexes() call. + * @code + * + * |<---------buffer_offset-------->|<----------buffer_free----------------->| + * | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * This is the situation after the update_buffer_indexes() call. + * @code + * + * |<-----------------buffer_offset--------------------->|<---buffer_free--->| + * | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * Note maximum_buffer_size could be larger than (m_aka_header_offset + m_MTU + m_trailer_length). + */ + EAP_FUNC_IMPORT void update_buffer_indexes( + const u32_t maximum_buffer_size, + const u32_t payload_size, + u32_t * const buffer_offset, + u32_t * const buffer_free); + + /** + * This is the situation before the update_payload_indexes() call. + * @code + * + * |<---------buffer_offset-------->|<----------buffer_free----------------->| + * | | | + * | |<-data_offset->|<--------data_free--------------------->| + * | | | | + * | | |<---payload_size--->| | + * | | | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * This is the situation after the update_payload_indexes() call. + * @code + * + * |<-----------------buffer_offset--------------------->|<---buffer_free--->| + * | | | + * | |<----------data_offset------------->|<----data_free---->| + * | | | | + * | | |<---payload_size--->| | + * | | | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * Note maximum_buffer_size could be larger than (m_aka_header_offset + m_MTU + m_trailer_length). + */ + EAP_FUNC_IMPORT void update_payload_indexes( + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + const u32_t payload_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_offset, + u32_t * const buffer_free); + + /** + * This function queries the IMSI or saved pseudonym. IMSI is queried always. The optional + * pseudonym is returned if it has been received and it has been stored to AKA AM. + * This function could be synchronous or asynchronous. Parameter must_be_synchronous could be + * used if only synchronous call is accepted. + * + * @return Successful syncronous call returns eap_status_ok. + * The process_AKA_IMSI() function must be called immediately. + * + * @return Successful asynchronous call returns eap_status_ok. + * This means call was indeed synchronous. + * The process_AKA_IMSI() function must be called immediately. + * + * @return Pending asynchronous call returns eap_status_pending_request. + * AM will complete this call later by complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + * + * @return Immediately comleted asynchronous call returns eap_status_completed_request. + * AM already called the complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query(). + * + * @return Other return values are errors. + */ + EAP_FUNC_IMPORT eap_status_e query_AKA_IMSI_or_pseudonym_or_reauthentication_id( + eap_variable_data_c * const IMSI, ///< Pointer to IMSI. Buffer for IMSI is allocated during the call. + eap_variable_data_c * const pseudonym_identity, ///< Pointer to pseudonym. Buffer for pseudonym is allocated during the call. + eap_variable_data_c * const reauthentication_identity, ///< Pointer to reauthentication_identity. Buffer for reauthentication_identity is allocated during the call. + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const length_of_mnc, + const bool must_be_synchronous, ///< True value indicates only synchronous call is accepted. + const aka_payload_AT_type_e required_identity, ///< This parameter indicated the type of identity required. + const eap_type_aka_complete_e required_completion, ///< This parameter tells the required completion after this call is completed, if this is asyncronous. Use this value with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + const u8_t received_eap_identifier ///< This is the EAP-identifier of the received EAP-request message. Use this value with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + ); + + /** + * This function queries KC and SRES. Each of them could include multiple concatenated items. + * This function could be synchronous or asynchronous. + * + * @return Successful call returns eap_status_ok. + * This means call was indeed synchronous. + * The process_AKA_kc_sres() function must be called immediately. + * + * @return Pending asynchronous call returns eap_status_pending_request. + * AM will complete this call later by complete_AKA_RES_query() call. + * + * @return Immediately comleted asynchronous call returns eap_status_completed_request. + * AM already called the complete_AKA_RES_query(). + * + * @return Other return values are errors. + */ + EAP_FUNC_IMPORT eap_status_e query_AKA_RES( + eap_type_aka_authentication_vector_c * const authentication_vector + ); + + /** + * This function queries the authentication_vector. + * This function could be synchronous or asynchronous. + * + * @return Successful call returns eap_status_ok. + * This means call was indeed synchronous. + * The send_challenge_request_message() function must be called immediately. + * + * @return Pending asynchronous call returns eap_status_pending_request. + * AM will complete this call later by complete_AKA_authentication_vector_query() call. + * + * @return Immediately comleted asynchronous call returns eap_status_completed_request. + * AM already called the complete_AKA_authentication_vector_query(). + * + * @return Other return values are errors. + */ + EAP_FUNC_IMPORT eap_status_e query_AKA_authentication_vector( + const u8_t next_eap_identifier, + eap_type_aka_identity_type * const identity_type + ); + + /** + * This function creates local copy of MAC_RAND and checks the received one match with local MAC_RAND. + * After succesfull MAC_RAND check function parses the AKA payloads from saved AKA EAP packet. + * This is because of the process_AKA_kc_sres() function could be called asynchronously and + * the received AKA EAP packet is stored to get_saved_EAP_packet(). + * Also encrypted payload (l_aka_payloads.get_ENCR_DATA()) is handled here. + * This is the first place where we have the K_encr (get_K_encr()) available. + * The decrpted DATA payload is handled immediately in handle_DATA_payload() function. + * Then function calculates MAC_SRES and sends EAP-Response/AKA/Challenge. + */ + EAP_FUNC_IMPORT eap_status_e process_AKA_kc_sres( + const eap_type_aka_authentication_vector_c * const authentication_vector + ); + + /** + * This function selects whether to use pseudonym or IMSI. + * Function creates NAI and EAP-Response/Identity message. + * Message is sent immediately. + */ + EAP_FUNC_IMPORT eap_status_e process_AKA_IMSI( + const eap_variable_data_c * const IMSI, ///< This is the IMSI. + const eap_variable_data_c * const pseudonym ///< This is the pseudonym. + ); + + + /** + * This function calculates the MAC_SRES. + */ + EAP_FUNC_IMPORT eap_status_e calculate_MAC_SRES( + eap_variable_data_c * const MAC_SRES, ///< This is the calculated MAC_SRES. + const eap_variable_data_c * const n_kc, ///< This includes concatenated n KC. + const eap_variable_data_c * const n_sres ///< This includes concatenated n SRES. + ); + + /** + * This function reads the identity payload. Identity is stored to get_identity(). + */ + EAP_FUNC_IMPORT eap_status_e parse_identity( + const u8_t * const identity, ///< This is pointer to received EAP-Identity buffer. + const u32_t identity_length ///< This is length of received EAP-Identity buffer. + ); + + + EAP_FUNC_IMPORT eap_status_e handle_eap_identity_query( + const eap_am_network_id_c * const send_network_id, + eap_variable_data_c * const identity, + const u8_t eap_identifier, + const eap_variable_data_c * const IMSI, + const eap_variable_data_c * const pseudonym, + const eap_variable_data_c * const reauthentication_identity, + const eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + const u32_t length_of_mnc, + const bool must_be_synchronous + ); + + /** + * This function handles the received EAP-Response/Identity message. + * First function parses the identity. + * Function queries the AM (query_imsi_from_username()) whether the pseudonym + * is known or should it query peer the IMSI. + * Currently the query_imsi_from_username() is synchronous call. + * The send_aka_identity_request_message() function will send the EAP-Request/AKA/Start message. + */ + EAP_FUNC_IMPORT eap_status_e handle_identity_response_message( + eap_header_rd_c * const eap_header, ///< This is the received EAP-Identity packet, pointer points to the header. + const u32_t aka_packet_length ///< This is length of received AKA EAP packet. + ); + + /** + * This function handles the received EAP-Request/AKA/Start message. + * Function checks the valid payloads and calls send_aka_identity_response_message() that sends EAP-Response/AKA/Start message. + */ + EAP_FUNC_IMPORT eap_status_e handle_aka_identity_request_message( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + aka_header_c * const received_aka, ///< This is pointer to EAP header including AKA fields. + const u32_t aka_packet_length, ///< This is length of received AKA EAP packet. + aka_payloads_c * const p_aka_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + EAP_FUNC_IMPORT eap_status_e handle_aka_notification_request_message_reauthentication( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + EAP_FUNC_IMPORT eap_status_e handle_aka_notification_request_message_full_authentication( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + /** + * This function handles the received EAP-Request/AKA/Notification message. + * Function checks the valid payloads and calls send_notification_response_message() that sends EAP-Response/AKA/Notification message. + */ + EAP_FUNC_IMPORT eap_status_e handle_aka_notification_request_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + /** + * This function handles the received EAP-Request/AKA/Challenge message. + * Function checks the valid payloads. The whole EAP-Request/AKA/Challenge message is + * saved to get_saved_EAP_packet() if there is encrypted payload. + * This is because the MAC could be checked and payload dercypted later + * after n*Kc and n*SRES is get from AKA. + * Function calls query_AKA_RES(). The query_AKA_kc_sres() function + * is completed using complete_AKA_RES_query() function. The complete_AKA_RES_query() + * function will call process_AKA_kc_sres(). + */ + EAP_FUNC_IMPORT eap_status_e handle_challenge_request_message( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + aka_header_c * const received_aka, ///< This is pointer to EAP header including AKA fields. + const u32_t aka_packet_length, ///< This is length of received AKA EAP packet. + aka_payloads_c * const p_aka_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + /** + * This function handles the received EAP-Request/AKA/Re-authentication message. + * Function checks the valid payloads. The whole EAP-Request/AKA/Challenge message is + * saved to get_saved_EAP_packet() if there is encrypted payload. + * This is because the MAC could be checked and payload dercypted later + * after n*Kc and n*SRES is get from AKA. + * Function calls query_AKA_RES(). The query_AKA_RES() function + * is completed using complete_AKA_RES_query() function. The complete_AKA_RES_query() + * function will call process_AKA_kc_sres(). + */ + EAP_FUNC_IMPORT eap_status_e handle_reauthentication_request_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + EAP_FUNC_IMPORT eap_status_e check_challenge_response_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + /** + * This function handles the received EAP-Response/AKA/Start message. + * Function checks the valid payloads. If IMSI is included it is copied to get_IMSI(). + * Also the included NONCE_MT is copied to get_NONCE_MT(). + * Function calls the query_AKA_authentication_vector() of AM to get fresh authentication_vector. + * The query_AKA_authentication_vector() function is completed by AM using complete_AKA_authentication_vector_query() function. + */ + EAP_FUNC_IMPORT eap_status_e handle_aka_identity_response_message( + aka_header_c * const received_aka, ///< This is pointer to EAP header including AKA fields. + const u32_t aka_packet_length, ///< This is length of received AKA EAP packet. + aka_payloads_c * const p_aka_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + EAP_FUNC_IMPORT eap_status_e handle_notification_response_message_reauthentication( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + EAP_FUNC_IMPORT eap_status_e handle_notification_response_message_full_authentication( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + /** + * This function handles the received EAP-Response/AKA/Notification message. + * Function checks the valid payloads. + */ + EAP_FUNC_IMPORT eap_status_e handle_notification_response_message( + const eap_am_network_id_c * const receive_network_id, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + /** + * This function handles the received EAP-Response/AKA/Challenge message. + * Function checks the valid payloads. The analyse_MAC_SRES_payload() function is + * called to check MAC_SRES. If it returns eap_status_success the authentication was succesfull + * and this function calls the send_eap_success() to send EAP-Success message. + */ + EAP_FUNC_IMPORT eap_status_e handle_challenge_response_message( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + aka_header_c * const received_aka, ///< This is pointer to EAP header including AKA fields. + const u32_t aka_packet_length, ///< This is length of received AKA EAP packet. + aka_payloads_c * const p_aka_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + EAP_FUNC_IMPORT eap_status_e handle_reauthentication_response_message( + const eap_am_network_id_c * const /* receive_network_id */, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + EAP_FUNC_IMPORT eap_status_e handle_client_error_response_message( + const eap_am_network_id_c * const /* receive_network_id */, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + /** + * This function sends and traces all messages. + */ + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + /** + * This function chechs NAI. + */ + EAP_FUNC_IMPORT eap_status_e check_NAI( + const u8_t * const identity, + const u32_t identity_length, + const u8_t * const at_character); + + +#if defined(USE_EAP_TRACE) + + /** + * This function traces the EAP packet. + */ + EAP_FUNC_IMPORT void packet_trace( + eap_const_string prefix, + const eap_am_network_id_c * const receive_network_id, + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length); + + #define EAP_AKA_PACKET_TRACE(prefix, receive_network_id, received_eap, eap_packet_length) \ + packet_trace((prefix), (receive_network_id), (received_eap), (eap_packet_length)) + +#else + + #define EAP_AKA_PACKET_TRACE(prefix, receive_network_id, received_eap, eap_packet_length) + +#endif //#if defined(_DEBUG) + + + /** + * This function finishes the successfull authentication. + * Generated keys are offered to lower layer. + * Connection handle is initialised. + */ + EAP_FUNC_IMPORT eap_status_e finish_successful_authentication( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function sends a notification of possible failed authentication + * to lower layer. + */ + EAP_FUNC_IMPORT eap_status_e send_final_notification(); + + EAP_FUNC_IMPORT eap_status_e new_handler( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true); + + EAP_FUNC_IMPORT bool randomly_refuse_eap_identity(); + + /** + * This function processes the AKA packets. + */ + EAP_FUNC_IMPORT eap_status_e aka_packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + aka_header_c * const received_aka, ///< This is pointer to EAP header including AKA fields. + const u32_t aka_packet_length, ///< This is length of received AKA EAP packet. + const bool is_client_when_true ///< Indicates whether this is client (true) or server (false). + ); + + EAP_FUNC_IMPORT eap_status_e cancel_error_message_delay_timer(); + + EAP_FUNC_IMPORT eap_status_e set_error_message_delay_timer(); + + EAP_FUNC_IMPORT eap_status_e handle_error_packet(); + + /** + * This function initializes the error message. + */ + EAP_FUNC_IMPORT eap_status_e initialize_error_message( + const eap_status_e error_status + ); + + EAP_FUNC_IMPORT eap_status_e check_synchronization_failure_response_message( + const eap_am_network_id_c * const /* receive_network_id */, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + EAP_FUNC_IMPORT eap_status_e complete_re_syncronization_query( + const u8_t next_eap_identifier, + const eap_type_aka_authentication_vector_c * const authentication_vector); + + EAP_FUNC_IMPORT eap_status_e process_re_syncronization( + const u8_t next_eap_identifier, + const eap_type_aka_authentication_vector_c * const authentication_vector); + + EAP_FUNC_IMPORT eap_status_e handle_synchronization_failure_response_message( + const eap_am_network_id_c * const /* receive_network_id */, + aka_header_c * const received_aka, + const u32_t aka_packet_length, + aka_payloads_c * const p_aka_payloads); + + EAP_FUNC_IMPORT eap_status_e handle_aka_identity_response_message_completion( + const u8_t next_eap_identifier, + const eap_status_e identity_status, + const eap_type_aka_identity_type identity_type, + const bool identity_payload_was_included); + + EAP_FUNC_IMPORT eap_status_e initialize_notification_message(); + + EAP_FUNC_IMPORT eap_status_e cancel_notification_message_delay_timer(); + + EAP_FUNC_IMPORT eap_status_e set_notification_message_delay_timer(); + + EAP_FUNC_IMPORT eap_status_e handle_notification_packet(); + + bool get_aka_notification_code_F_bit(const eap_aka_notification_codes_e notification_code); + + bool get_aka_notification_code_P_bit(const eap_aka_notification_codes_e notification_code); + + EAP_FUNC_IMPORT bool random_selection(); + + + EAP_FUNC_IMPORT eap_status_e checkcode_init(); + + EAP_FUNC_IMPORT static bool compare_payload_first_is_less( + const aka_payload_AT_type_e * const first, + const aka_payload_AT_type_e * const second, + abs_eap_am_tools_c * const m_am_tools); + + EAP_FUNC_IMPORT eap_status_e checkcode_verify_payloads( + aka_payloads_c * const p_aka_payloads); + + EAP_FUNC_IMPORT eap_status_e checkcode_save_message_client( + const void * const data, + const u32_t data_length, + aka_payloads_c * const p_aka_payloads); + + EAP_FUNC_IMPORT eap_status_e checkcode_save_message_server( + const void * const data, + const u32_t data_length); + + EAP_FUNC_IMPORT eap_status_e checkcode_update_saved_message(); + + EAP_FUNC_IMPORT eap_status_e checkcode_update( + const void * const data, + const u32_t data_length); + + EAP_FUNC_IMPORT eap_status_e checkcode_final( + eap_variable_data_c * const digest); + + EAP_FUNC_IMPORT eap_status_e checkcode_verify( + const eap_variable_data_c * const received_digest); + + /** + * This function stores identity. + */ + EAP_FUNC_IMPORT eap_status_e store_identity( + const eap_variable_data_c * const IMSI_or_pseudonym, + const bool IMSI_is_used); + + /** + * eap_core_map_c class increases reference count each time reference to stored object is get. + * Here is always just one state for one session so no references are used. + */ + void object_increase_reference_count(); + + /** + * eap_core_map_c class increases reference count each time reference to stored object is get. + * Here is always just one state for one session so no references are used. + */ + u32_t object_decrease_reference_count(); + + /** + * This function stores pointer to the received authentication vector. + */ + void set_authentication_vector(eap_type_aka_authentication_vector_c * const authentication_vector); + + + void set_reauthentication_counter(const u32_t reauthentication_counter); + + u32_t get_reauthentication_counter(); + + + /** + * This function returns pointer to the stored authentication_vector. + */ + eap_type_aka_authentication_vector_c * get_authentication_vector(); + + const eap_variable_data_c * get_RAND() const; + + eap_status_e set_RAND(const eap_variable_data_c * const RAND); + + const eap_variable_data_c * get_AUTN() const; + + eap_status_e set_AUTN(const eap_variable_data_c * const AUTN); + + /** + * This function stores the last EAP-Identifier. + */ + void set_last_eap_identifier(const u8_t last_eap_identifier); + + /** + * This function returns the last stored EAP-Identifier. + */ + u8_t get_last_eap_identifier(); + + + void set_include_identity_to_aka_identity_response(const aka_payload_AT_type_e id_type_required); + + aka_payload_AT_type_e get_include_identity_to_aka_identity_response(); + + + void set_aka_identity_response_includes_identity(const aka_payload_AT_type_e id_type_required); + + aka_payload_AT_type_e get_aka_identity_response_includes_identity(); + + /** + * This function sets the m_failure_message_received flag true. + */ + void set_failure_message_received(); + + /** + * This function sets the m_failure_message_received flag false. + */ + void unset_failure_message_received(); + + /** + * This function returns the m_failure_message_received flag. + */ + bool get_failure_message_received(); + + /** + * This function returns the current state. + */ + eap_type_aka_state_variable_e get_state(); + + /** + * This function returns the saved previous state. + */ + eap_type_aka_state_variable_e get_saved_previous_state(); + + /** + * This function saves the current m_state to m_saved_previous_state. + * The saved state is restored in error case. + */ + void save_current_state(); + + /** + * This function restores the saved state. + */ + void restore_saved_previous_state(); + + /** + * This function returns the send network identity of this session. + */ + eap_am_network_id_c * get_send_network_id(); + + /** + * This function checks the received AKA subtype is valid in current state. + * This is used for quick check. + */ + EAP_FUNC_IMPORT eap_status_e check_valid_state(aka_subtype_e type); + + /** + * This function sets the m_authentication_finished_successfully flag true. + */ + void set_authentication_finished_successfully(); + + /** + * This function returns the m_authentication_finished_successfully flag. + */ + bool get_authentication_finished_successfully(); + + /** + * This function sets the new state and notifies the lower layer of this change. + */ + void set_state(eap_type_aka_state_variable_e state); + + //-------------------------------------------------- + + /** + * This function generates K_encr, K_aut and master_session_key. + */ + EAP_FUNC_IMPORT eap_status_e generate_shared_secred_keys( + const u32_t key_length, + const eap_variable_data_c * const CK, + const eap_variable_data_c * const IK, + eap_variable_data_c * const XKEY, + eap_variable_data_c * const K_encr, + eap_variable_data_c * const K_aut, + eap_variable_data_c * const master_session_key); + + + //-------------------------------------------------- + + /** + * This function generates K_encr, K_aut and master_session_key. + */ + EAP_FUNC_IMPORT eap_status_e generate_reauth_shared_secred_keys( + const u32_t key_length, + const eap_variable_data_c * const orig_XKEY, + const u32_t reauth_counter, + const eap_variable_data_c * const reauth_identity, + const eap_variable_data_c * const reauth_nonce_s, + eap_variable_data_c * const master_session_key); + + //-------------------------------------------------- + + /** + * This function returns m_nonce_S. + */ + eap_variable_data_c * get_NONCE_S(); + + //-------------------------------------------------- + + /** + * This function returns m_IMSI. + */ + eap_variable_data_c * get_IMSI(); + + //-------------------------------------------------- + + /** + * This function returns m_username. + */ + eap_variable_data_c * get_identity(); + + //-------------------------------------------------- + + /** + * This function returns m_NAI. + */ + eap_variable_data_c * get_NAI(); + + //-------------------------------------------------- + + /** + * This function returns m_n_sres. + */ + eap_variable_data_c * get_RES(); + + //-------------------------------------------------- + + /** + * This function returns m_pseudonym. + */ + eap_variable_data_c * get_pseudonym(); + + //-------------------------------------------------- + + /** + * This function returns m_reauthentication_identity. + */ + eap_variable_data_c * get_reauthentication_identity(); + + //-------------------------------------------------- + + /** + * This function returns m_IV. + */ + aka_variable_data_c * get_IV(); + + /** + * This function returns m_saved_EAP_packet. + */ + eap_variable_data_c * get_saved_EAP_packet(); + + //-------------------------------------------------- + + /** + * This function returns m_XKEY. + */ + eap_variable_data_c * get_XKEY(); + + /** + * This function returns m_K_encr. + */ + eap_variable_data_c * get_K_encr(); + + /** + * This function returns m_K_aut. + */ + eap_variable_data_c * get_K_aut(); + + /** + * This function returns m_master_session_key. + */ + eap_master_session_key_c * get_master_session_key(); + + /** + * This function stores the last encryption IV. In CBC-mode previous encrypted block is + * used as a IV of next block. + */ + eap_status_e store_last_encryption_iv(const eap_variable_data_c * const encryption_IV); + + /** + * Currently this does nothing and this is not called anywhere. + */ + EAP_FUNC_IMPORT void delete_unused_keys(); + + + /** + * This function returns string of the current state. This is for trace purposes. + */ + EAP_FUNC_IMPORT eap_const_string get_state_string() const; + + /** + * This function returns string of the current state. This is for trace purposes. + */ + EAP_FUNC_IMPORT eap_const_string get_saved_previous_state_string() const; + + /** + * This function initializes a timer to sends the EAP-Request/Failure message. + */ + EAP_FUNC_IMPORT eap_status_e initialize_eap_failure_timer(); + + /** + * This function cancels a timer to sends the EAP-Request/Failure message. + */ + EAP_FUNC_IMPORT eap_status_e cancel_eap_failure_timer(); + + /** + * This function initializes a timer to sends the EAP-Response/Notification message. + */ + EAP_FUNC_IMPORT eap_status_e initialize_eap_notification_timer(); + + /** + * This function cancels a timer to sends the EAP-Response/Notification message. + */ + EAP_FUNC_IMPORT eap_status_e cancel_eap_notification_timer(); + + /** + * This function initializes a timer to sends the EAP-Response/Failure message. + */ + EAP_FUNC_IMPORT eap_status_e initialize_failure_message_received_timer(); + + /** + * This function cancels a timer to sends the EAP-Response/Failure message. + */ + EAP_FUNC_IMPORT eap_status_e cancel_failure_message_received_timer(); + + u32_t get_mnc_length(const u32_t mcc); + + eap_status_e create_uma_realm( + eap_variable_data_c * const automatic_realm, + const eap_variable_data_c * const IMSI, + const u32_t length_of_mnc); + + void set_identity_type(eap_type_aka_identity_type type); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor cancels all timers and deletes member attributes. + */ + EAP_FUNC_IMPORT virtual ~eap_type_aka_c(); + + /** + * Constructor initializes all member attributes. + */ + EAP_FUNC_IMPORT eap_type_aka_c( + abs_eap_am_tools_c * const tools, ///< This is pointer to the tools AM of current platform. + abs_eap_base_type_c * const partner, ///< This is back pointer to object which created this object. + eap_am_type_aka_c * const am_type_aka, ///< This is pointer to adaptation module of AKA EAP type. + const bool free_am_type_aka, ///< True value means m_am_type_aka is allocated within eap_type_aka_c and m_am_type_aka must be freed in destructor. + const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false). + const eap_am_network_id_c * const receive_network_id); + + /** + * This function tells if the object is a client or a server.. + */ + EAP_FUNC_IMPORT bool get_is_client(); + + // This is commented in abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query(). + EAP_FUNC_IMPORT eap_status_e complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query( + const eap_variable_data_c * const IMSI, ///< This is the IMSI. + const eap_variable_data_c * const pseudonym, ///< This is the pseudonym. + const eap_variable_data_c * const reauthentication_identity, ///< This is the re-authentication identity. + const eap_variable_data_c * const automatic_realm, + const u32_t length_of_mnc, + const eap_type_aka_complete_e required_completion, ///< This parameter tells the required completion + const u8_t received_eap_identifier, ///< This parameter is the EAP-identifier of EAP-request + const eap_status_e completion_status + ); + + // This is commented in abs_eap_am_type_aka_c::complete_AKA_authentication_vector_query(). + EAP_FUNC_IMPORT eap_status_e complete_AKA_authentication_vector_query( + eap_type_aka_authentication_vector_c * const authentication_vector, ///< authentication_vector includes all AKA parametrs used in this authentication session. + const eap_variable_data_c * const IMSI, ///< IMSI may be queried during query_AKA_authentication_vector() function call. It must be copied to state. + const eap_aka_authentication_vector_status_e authentication_vector_status, ///< This is the status of the failed authentication_vector query. + const eap_type_aka_identity_type type, ///< This is type of the identity. + const eap_status_e completion_status, + const u8_t next_eap_identifier + ); + + // This is commented in abs_eap_am_type_aka_c::complete_AKA_RES_query(). + EAP_FUNC_IMPORT eap_status_e complete_AKA_RES_query( + const eap_type_aka_authentication_vector_c * const authentication_vector, + const eap_status_e completion_status + ); + + /** Client calls this function. + * This function IMSI and username to AKA EAP type. + */ + EAP_FUNC_IMPORT eap_status_e handle_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + const eap_variable_data_c * const imsi, ///< The result is stored to imsi parameter. + const eap_type_aka_identity_type identity_type); + + // This is commented in abs_eap_am_type_aka_c::complete_imsi_from_username(). + EAP_FUNC_IMPORT eap_status_e complete_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + const eap_variable_data_c * const imsi, ///< The result is stored to imsi parameter. + const eap_type_aka_identity_type type, + const eap_status_e completion_status, + const eap_type_aka_complete_e completion_action); + + /** + * The partner class calls this function when EAP/AKA packet is received. + * see also eap_base_type_c::packet_process(). + */ + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + /** + * This function obtains header offset, MTU and trailer length. + * See also abs_eap_base_type_c::get_header_offset(). + */ + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length + ); + + /** + * This function creates a message authentication code (MAC) + */ + EAP_FUNC_IMPORT eap_status_e create_message_authentication_code( + eap_type_aka_MAC_attributes_c *MAC_attributes, ///< This includes required parameters. + const aka_subtype_e subtype, + const eap_code_value_e code, + const eap_variable_data_c * const authentication_key + ); + + /** + * This function adds addiditional data to MAC calculation. + */ + EAP_FUNC_IMPORT eap_status_e extra_message_authentication_code_bytes( + const aka_subtype_e subtype, + const eap_code_value_e code, + crypto_hmac_c *hmac_sha1); + + // This is commented in abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data + ); + + // This is commented in abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data + ); + + // This is commented in eap_base_type_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + + // This is commented in eap_base_type_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + // This is commented in eap_base_type_c::configure(). + /** + * EAP-type AKA reads configuration. + */ + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is commented in eap_base_type_c::shutdown(). + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + EAP_FUNC_IMPORT eap_status_e shutdown(); + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ); + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ); + + // See abs_eap_base_type_c::state_notification(). + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state + ); + + // This is commented in eap_base_type_c::query_eap_identity(). + EAP_FUNC_IMPORT eap_status_e query_eap_identity( + const bool must_be_synchronous, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier); + + // This is commented in eap_base_type_c::set_initial_eap_identifier(). + EAP_FUNC_IMPORT eap_status_e set_initial_eap_identifier( + const eap_am_network_id_c * const receive_network_id, + const u8_t initial_identifier); + + // This is commented in eap_base_type_c::eap_acknowledge(). + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function must reset the state of object to same as + * state was after the configure() function call. + * If object reset succeeds this function must return eap_status_ok. + * If object reset fails this function must return corresponding error status. + * @return This function returns the status of reset operation. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + // + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + // + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + EAP_FUNC_IMPORT static eap_const_string get_identity_string(const eap_type_aka_identity_type identity_type); + + /** + * This function returns string of the state. This is for trace purposes. + * NOTE this is static member function. + */ + EAP_FUNC_IMPORT static eap_const_string get_state_string(eap_type_aka_state_variable_e state); + + //-------------------------------------------------- + +}; // class eap_type_aka_c + +#endif //#if !defined(_AKA_CORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_authentication_vector.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_authentication_vector.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TYPE_AKA_AUTHENTICATION_VECTOR_H_) +#define _EAP_TYPE_AKA_AUTHENTICATION_VECTOR_H_ + +//#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_variable_data.h" + +//----------------------------------------------- + +class EAP_EXPORT eap_type_aka_authentication_vector_c +{ +private: + + abs_eap_am_tools_c * m_am_tools; + + eap_variable_data_c m_RAND; + eap_variable_data_c m_AUTN; + eap_variable_data_c m_RES; + eap_variable_data_c m_CK; + eap_variable_data_c m_IK; + eap_variable_data_c m_AUTS; + + eap_status_e m_vector_status; + + bool m_is_valid; + +public: + + EAP_FUNC_IMPORT virtual ~eap_type_aka_authentication_vector_c(); + + EAP_FUNC_IMPORT eap_type_aka_authentication_vector_c( + abs_eap_am_tools_c * const tools + ); + + EAP_FUNC_IMPORT eap_variable_data_c * get_RAND() const; + + EAP_FUNC_IMPORT eap_variable_data_c * get_AUTN() const; + + EAP_FUNC_IMPORT eap_variable_data_c * get_RES() const; + + EAP_FUNC_IMPORT eap_variable_data_c * get_CK() const; + + EAP_FUNC_IMPORT eap_variable_data_c * get_IK() const; + + EAP_FUNC_IMPORT eap_variable_data_c * get_AUTS() const; + + EAP_FUNC_IMPORT eap_type_aka_authentication_vector_c * copy() const; + + EAP_FUNC_IMPORT void reset(); + + EAP_FUNC_IMPORT void set_vector_status(eap_status_e vector_status); + + EAP_FUNC_IMPORT eap_status_e get_vector_status() const; + + EAP_FUNC_IMPORT bool get_is_valid() const; +}; + + +#endif //#if !defined(_EAP_TYPE_AKA_AUTHENTICATION_VECTOR_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,277 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_AKA_HEADER_H_) +#define _AKA_HEADER_H_ + +#include "eap_tools.h" +#include "eap_header.h" +#include "eap_header_string.h" + +/** @file */ + +const u32_t AKA_FIRST_SEQUENCE = 1u; +const u32_t AKA_PAYLOAD_LENGTH_ALIGN = 4u; +const u32_t EAP_AKA_PAYLOAD_ZERO_DATA_LENGTH = 0u; +const u8_t AKA_NAI_AT_BYTE = '@'; + + +enum aka_subtype_e +{ + aka_subtype_NONE = 0, + aka_subtype_Challenge = 1, + aka_subtype_Authentication_Reject = 2, + aka_subtype_Synchronization_Failure = 4, + aka_subtype_Identity = 5, + aka_subtype_Notification = 12, + aka_subtype_Re_authentication = 13, + aka_subtype_Client_Error = 14, +}; + +enum aka_payload_AT_type_e +{ + aka_payload_NONE = 0, + + aka_payload_AT_RAND = 1, + aka_payload_AT_AUTN = 2, + aka_payload_AT_RES = 3, + aka_payload_AT_AUTS = 4, + aka_payload_AT_PADDING = 6, + aka_payload_AT_PERMANENT_ID_REQ = 10, + aka_payload_AT_MAC = 11, + aka_payload_AT_NOTIFICATION = 12, + aka_payload_AT_ANY_ID_REQ = 13, + aka_payload_AT_IDENTITY = 14, + aka_payload_AT_FULLAUTH_ID_REQ = 17, + aka_payload_AT_COUNTER = 19, + aka_payload_AT_COUNTER_TOO_SMALL = 20, + aka_payload_AT_NONCE_S = 21, + aka_payload_AT_CLIENT_ERROR_CODE = 22, + + aka_payload_AT_IV = 129, + aka_payload_AT_ENCR_DATA = 130, + aka_payload_AT_NEXT_PSEUDONYM = 132, + aka_payload_AT_NEXT_REAUTH_ID = 133, + aka_payload_AT_CHECKCODE = 134, + aka_payload_AT_RESULT_IND = 135, +}; + +enum eap_aka_client_error_code_e +{ + eap_aka_client_error_code_unable_to_process_packet = 0, + eap_aka_client_error_code_unsupported_version = 1, + eap_aka_client_error_code_insufficient_number_of_challenges = 2, + eap_aka_client_error_code_rands_are_not_fresh = 3, + eap_aka_client_error_code_maximum_value = eap_aka_client_error_code_rands_are_not_fresh, + eap_aka_client_error_code_none = 0xff, +}; + +//---------------------------------------------------------------------------- + + +/// This class defines the attribute payload header of AKA EAP-type. +/** + * Here is a figure of attribute payload header of AKA EAP-type. + * Attribute payload data is (m_length*4)-sizeof(aka_payload_AT_header_c) data octets that follows aka_payload_AT_header_c. + * @code + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Length | Value ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Attribute payload data ... + * +-+-+-+-+-+-+-+-+-+-+- + * @endcode + * + */ +class EAP_EXPORT aka_payload_AT_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + enum offsets + { + m_type_offset = 0ul, + m_length_offset = m_type_offset+sizeof(u8_t), + m_reserved_offset = m_length_offset+sizeof(u8_t), + m_data_offset = m_reserved_offset+sizeof(u16_t), + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~aka_payload_AT_header_c(); + + // + EAP_FUNC_IMPORT aka_payload_AT_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT aka_payload_AT_type_e get_current_payload() const; + + EAP_FUNC_IMPORT u16_t get_payload_length() const; + + EAP_FUNC_IMPORT u16_t get_reserved() const; + + EAP_FUNC_IMPORT u8_t * get_reserved_pointer(const u32_t contignuous_bytes) const; + + EAP_FUNC_IMPORT u32_t get_data_length() const; + + EAP_FUNC_IMPORT static u16_t get_header_length(); + + EAP_FUNC_IMPORT static u16_t get_max_payload_data_length(); + + EAP_FUNC_IMPORT u8_t * get_data(const u32_t contignuous_bytes) const; + + EAP_FUNC_IMPORT u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + EAP_FUNC_IMPORT u8_t * get_next_header() const; + + // Mostly this is zero. + // With some attributes this is used for special purposes. + EAP_FUNC_IMPORT void set_reserved(const u16_t reserved); + + EAP_FUNC_IMPORT void set_current_payload(const aka_payload_AT_type_e p_current_payload); + + EAP_FUNC_IMPORT void set_data_length(const u16_t p_data_length); + + EAP_FUNC_IMPORT void reset_header(const u16_t data_length); + + EAP_FUNC_IMPORT static eap_const_string get_payload_AT_string(const aka_payload_AT_type_e payload_type); + + EAP_FUNC_IMPORT eap_const_string get_payload_AT_string() const; + + EAP_FUNC_IMPORT eap_status_e check_header() const; + + // + //-------------------------------------------------- +}; // class aka_payload_AT_header_c + + + +//---------------------------------------------------------------------------- + + +/// This class defines header of AKA EAP-type. +/** + * Here is a figure of header of AKA EAP-type. + * Subtype-Data is m_length-sizeof(aka_header_c) data octets that follows aka_header_c. + * @code + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Code | Identifier | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type=18 | Subtype | Reserved = 0 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Subtype-Data... + * +-+-+-+-+-+-+-+-+-+-+- + * @endcode + * + */ +class EAP_EXPORT aka_header_c +: public eap_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + enum delta_offsets + { + m_subtype_delta_offset = 0ul, // This is offset from the end of the type field. NOTE type field could be extented 8 bytes in length. + m_reserved_delta_offset = m_subtype_delta_offset+sizeof(u8_t), + m_data_delta_offset = m_reserved_delta_offset+sizeof(u16_t), + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~aka_header_c(); + + // + EAP_FUNC_IMPORT aka_header_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT aka_subtype_e get_subtype() const; + + EAP_FUNC_IMPORT u16_t get_data_length() const; + + /// This returns the length of EAP-header, EAP-type, subtype and reserved fields. + EAP_FUNC_IMPORT u32_t get_header_length() const; + + EAP_FUNC_IMPORT u32_t get_sub_type_offset() const; + + EAP_FUNC_IMPORT u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + + EAP_FUNC_IMPORT u8_t * get_data(const u32_t contignuous_bytes) const; + + + EAP_FUNC_IMPORT u16_t get_reserved() const; + + + EAP_FUNC_IMPORT eap_status_e check_header() const; + + EAP_FUNC_IMPORT eap_const_string get_subtype_string() const; + + EAP_FUNC_IMPORT eap_const_string get_code_string() const; + + EAP_FUNC_IMPORT eap_const_string get_eap_type_string() const; + + EAP_FUNC_IMPORT void set_reserved(const u16_t reserved); + + EAP_FUNC_IMPORT void set_subtype(const aka_subtype_e p_subtype); + + EAP_FUNC_IMPORT void set_data_length( + const u32_t p_data_length, + const bool expanded_type_when_true); + + EAP_FUNC_IMPORT void reset_header( + const u32_t buffer_length, + const bool expanded_type_when_true); + + // + //-------------------------------------------------- +}; // class aka_header_c + +//-------------------------------------------------- + +#endif //#if !defined(_AKA_HEADER_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_initialized.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_initialized.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_AKA_INITIALIZED_H_) +#define _AKA_INITIALIZED_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_type_aka_header.h" +#include "eap_type_aka_types.h" +#include "eap_type_aka_payloads.h" +#include "abs_eap_am_tools.h" + + +const u32_t AKA_MAX_OFFER_COUNT = 3; + + +class EAP_EXPORT eap_type_aka_initialized_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + u32_t m_counter; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_type_aka_initialized_c() + { + } + + // + eap_type_aka_initialized_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_counter(1u) + { + } + + u32_t counter() + { + return m_counter; + } + + void increment() + { + ++m_counter; + } + + //-------------------------------------------------- + + void reset() + { + m_counter = 0u; + } + + //-------------------------------------------------- + +}; + + +#endif //#if !defined(_AKA_INITIALIZED_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_payloads.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,367 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_AKA_RESULT_H_) +#define _AKA_RESULT_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_type_aka_header.h" + + + +class EAP_EXPORT aka_fixed_data_c +{ +private: + //-------------------------------------------------- + + bool m_is_valid; + aka_payload_AT_header_c m_original_header; + u16_t m_type; + u16_t m_data; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~aka_fixed_data_c(); + + EAP_FUNC_IMPORT aka_fixed_data_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT bool get_is_valid() const; + + EAP_FUNC_IMPORT const aka_payload_AT_header_c * get_original_header(); + + EAP_FUNC_IMPORT u16_t get_type(abs_eap_am_tools_c * const m_am_tools) const; + + EAP_FUNC_IMPORT u16_t get_data(abs_eap_am_tools_c * const m_am_tools) const; + + EAP_FUNC_IMPORT void set_data( + const aka_payload_AT_header_c * const original_header, + const u16_t type, const u16_t data); + + //-------------------------------------------------- +}; // class aka_fixed_data_c + + +class EAP_EXPORT aka_variable_data_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + eap_variable_data_c m_data; + + aka_payload_AT_header_c m_original_header; + + bool m_payload_included; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~aka_variable_data_c(); + + EAP_FUNC_IMPORT aka_variable_data_c(abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT const aka_payload_AT_header_c * get_original_header() const; + + EAP_FUNC_IMPORT eap_status_e set_buffer( + const aka_payload_AT_header_c * const original_header, + u8_t *buffer, + const u32_t buffer_length, + const bool free_buffer, + const bool is_writable); + + EAP_FUNC_IMPORT bool get_payload_included() const; + + EAP_FUNC_IMPORT u32_t get_data_length() const; + + EAP_FUNC_IMPORT u8_t * get_data(const u32_t data_length) const; + + EAP_FUNC_IMPORT eap_variable_data_c * get_payload_buffer(); + + EAP_FUNC_IMPORT bool get_is_valid() const; + + EAP_FUNC_IMPORT eap_status_e reset(); + + //-------------------------------------------------- +}; // class aka_variable_data_c + + +//-------------------------------------------------- + + +// +class EAP_EXPORT aka_payloads_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + eap_variable_data_c m_all_payloads; + + aka_variable_data_c m_nonce_s; + + aka_variable_data_c m_MAC; + + aka_variable_data_c m_ENCR_DATA; + + aka_variable_data_c m_IDENTITY_payload; + + aka_variable_data_c m_padding_payload; + + aka_variable_data_c m_RAND; + + aka_variable_data_c m_AUTN; + + aka_variable_data_c m_AUTS; + + aka_variable_data_c m_RES; + + aka_variable_data_c m_PERMANENT_ID_REQ; + + aka_variable_data_c m_FULLAUTH_ID_REQ; + + aka_variable_data_c m_ANY_ID_REQ; + + aka_variable_data_c m_IV; + + aka_variable_data_c m_NEXT_PSEUDONYM; + + aka_variable_data_c m_NEXT_REAUTH_ID; + + aka_variable_data_c m_NOTIFICATION; + + aka_variable_data_c m_COUNTER; + + aka_variable_data_c m_COUNTER_TOO_SMALL; + + aka_variable_data_c m_CLIENT_ERROR_CODE; + + aka_variable_data_c m_RESULT_IND; + + aka_variable_data_c m_CHECKCODE; + + aka_payload_AT_type_e m_unknown_payload; + + bool m_includes_other_version_than_1; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + + enum eap_aka_payload_status_e + { + eap_aka_payload_status_optional, + eap_aka_payload_status_must_be, + eap_aka_payload_status_must_not_be + }; + + + EAP_FUNC_IMPORT virtual ~aka_payloads_c(); + + EAP_FUNC_IMPORT aka_payloads_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT bool check_one_payload( + const eap_aka_payload_status_e status, + const aka_variable_data_c * const payload); + + /** This function checks the correct set of payloads are included in the message. + * NOTE do not change the order of parameters. + * Add new payload type to the last of the parameter list. + */ + EAP_FUNC_IMPORT bool check_payloads( + const eap_aka_payload_status_e nonce_s, + const eap_aka_payload_status_e MAC, + const eap_aka_payload_status_e ENCR_DATA, + const eap_aka_payload_status_e IDENTITY, + const eap_aka_payload_status_e padding, + const eap_aka_payload_status_e n_RANDs, + const eap_aka_payload_status_e AUTN, + const eap_aka_payload_status_e AUTS, + const eap_aka_payload_status_e RES, + const eap_aka_payload_status_e PERMANENT_ID_REQ, + const eap_aka_payload_status_e FULLAUTH_ID_REQ, + const eap_aka_payload_status_e ANY_ID_REQ, + const eap_aka_payload_status_e IV, + const eap_aka_payload_status_e NEXT_PSEUDONYM, + const eap_aka_payload_status_e NEXT_REAUTH_ID, + const eap_aka_payload_status_e NOTIFICATION, + const eap_aka_payload_status_e COUNTER, + const eap_aka_payload_status_e COUNTER_TOO_SMALL, + const eap_aka_payload_status_e CLIENT_ERROR_CODE, + const eap_aka_payload_status_e RESULT_IND, + const eap_aka_payload_status_e CHECKCODE + ); + + eap_variable_data_c * const get_all_payloads() + { + return static_cast(&m_all_payloads); + } + + aka_variable_data_c * const get_NONCE_S() + { + return static_cast(&m_nonce_s); + } + + aka_variable_data_c * const get_MAC() + { + return static_cast(&m_MAC); + } + + aka_variable_data_c * const get_ENCR_DATA() + { + return static_cast(&m_ENCR_DATA); + } + + aka_variable_data_c * const get_IDENTITY_payload() + { + return static_cast(&m_IDENTITY_payload); + } + + aka_variable_data_c * const get_padding_payload() + { + return static_cast(&m_padding_payload); + } + + aka_variable_data_c * const get_RAND() + { + return static_cast(&m_RAND); + } + + aka_variable_data_c * const get_AUTN() + { + return static_cast(&m_AUTN); + } + + aka_variable_data_c * const get_AUTS() + { + return static_cast(&m_AUTS); + } + + aka_variable_data_c * const get_RES() + { + return static_cast(&m_RES); + } + + aka_variable_data_c * const get_PERMANENT_ID_REQ() + { + return static_cast(&m_PERMANENT_ID_REQ); + } + + aka_variable_data_c * const get_FULLAUTH_ID_REQ() + { + return static_cast(&m_FULLAUTH_ID_REQ); + } + + aka_variable_data_c * const get_ANY_ID_REQ() + { + return static_cast(&m_ANY_ID_REQ); + } + + aka_variable_data_c * const get_IV() + { + return static_cast(&m_IV); + } + + aka_variable_data_c * const get_NEXT_PSEUDONYM() + { + return static_cast(&m_NEXT_PSEUDONYM); + } + + aka_variable_data_c * const get_NEXT_REAUTH_ID() + { + return static_cast(&m_NEXT_REAUTH_ID); + } + + aka_variable_data_c * const get_NOTIFICATION() + { + return static_cast(&m_NOTIFICATION); + } + + aka_variable_data_c * const get_RESULT_IND() + { + return static_cast(&m_RESULT_IND); + } + + aka_variable_data_c * const get_CHECKCODE() + { + return static_cast(&m_CHECKCODE); + } + + aka_variable_data_c * const get_CLIENT_ERROR_CODE() + { + return static_cast(&m_CLIENT_ERROR_CODE); + } + + aka_variable_data_c * const get_COUNTER() + { + return static_cast(&m_COUNTER); + } + + aka_variable_data_c * const get_COUNTER_TOO_SMALL() + { + return static_cast(&m_COUNTER_TOO_SMALL); + } + + + void set_includes_unknown_attribute(const aka_payload_AT_type_e unknown_payload); + + aka_payload_AT_type_e get_includes_unknown_attribute(); + + + void set_includes_other_version_than_1(const bool includes_other_version_than_1); + + bool get_includes_other_version_than_1(); + + + bool get_is_valid() const; + + //-------------------------------------------------- +}; // class aka_payloads_c + + +#endif //#if !defined(_AKA_RESULT_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,105 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_AKA_STATE_H_) +#define _AKA_STATE_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_type_aka_header.h" +#include "eap_type_aka_types.h" +#include "eap_type_aka_payloads.h" +#include "abs_eap_base_timer.h" +#include "eap_type_aka_authentication_vector.h" +#include "eap_type_aka_state_notification.h" +#include "eap_am_network_id.h" + + +const u32_t AKA_STATE_MAX_TYPES = 5; + + +//----------------------------------------------- + +/// This class stores the valid AKA messages (aka_subtype_e) +/// within a one state (eap_type_aka_state_variable_e). +class EAP_EXPORT eap_type_aka_state_variable_parameters_c +{ +private: + + /// Array includes valid AKA messages (aka_subtype_e). + aka_subtype_e m_valid_types[AKA_STATE_MAX_TYPES]; + + /// The handler of this state must be initiator (server, authenticator). + bool m_must_be_initiator; + + /// The handler of this state must be responsed (client, peer). + bool m_must_be_responder; + + bool m_dummy_1_for_alignment; + + bool m_dummy_2_for_alignment; + +public: + + /** + * Destructor does nothing. + */ + EAP_FUNC_IMPORT virtual ~eap_type_aka_state_variable_parameters_c(); + + /** + * Constructor initializes attributes with default values. + */ + EAP_FUNC_IMPORT eap_type_aka_state_variable_parameters_c(); + + /** + * This function checks the AKA message is valid in this state. + */ + EAP_FUNC_IMPORT bool check_valid_types(aka_subtype_e type) const; + + /** + * This function checks the initiator is valid in this state. + */ + EAP_FUNC_IMPORT bool check_initiator(const bool is_initiator) const; + + /** + * This function initializes this state to allow three AKA message types. + */ + EAP_FUNC_IMPORT void init_state( + const bool must_be_initiator, + const bool must_be_responder, + const aka_subtype_e type0, + const aka_subtype_e type1, + const aka_subtype_e type2, + const aka_subtype_e type3, + const aka_subtype_e type4 + ); +}; + + +//----------------------------------------------- + +#endif //#if !defined(_AKA_STATE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_state_notification.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_state_notification.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,105 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AKA_STATE_NOTIFICATION_H_) +#define _EAP_AKA_STATE_NOTIFICATION_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_protocol_layer.h" +#include "eap_state_notification.h" + + +/// A eap_type_aka_state_notification_c class. +/// This is used for debugging and protocol testing. +class EAP_EXPORT eap_type_aka_state_notification_c +: public eap_state_notification_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_type_aka_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_type_aka_state_notification_c(); + + /** + * The constructor of the eap_type_aka_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT eap_type_aka_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + +#if defined(USE_EAP_EXPANDED_TYPES) + + EAP_FUNC_IMPORT eap_type_aka_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + + EAP_FUNC_IMPORT eap_type_aka_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + + + //-------------------------------------------------- +}; // class eap_type_aka_state_notification_c + +#endif //#if !defined(_EAP_AKA_STATE_NOTIFICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/aka/include/eap_type_aka_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,782 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_AKA_TYPES_H_) +#define _AKA_TYPES_H_ + +#include "eap_type_aka_header.h" +#include "eap_type_all_types.h" +#include "eap_configuration_field.h" + +/** @file eap_type_aka_types.h + * @brief This file defines the constants of the AKA EAP type. + */ + +/** + * This is the internal state of the AKA EAP type. + */ +enum eap_type_aka_state_variable_e +{ + eap_type_aka_state_none , ///< State state_none + + eap_type_aka_state_waiting_for_identity_request , ///< Client state waiting_for_identity_request + eap_type_aka_state_pending_identity_query , ///< Client state pending_identity_query + eap_type_aka_state_waiting_for_aka_identity_request , ///< Client state imsi_waiting_for_aka_identity_request + eap_type_aka_state_imsi_waiting_for_aka_identity_request , ///< Client state imsi_waiting_for_aka_identity_request + eap_type_aka_state_pseydonym_waiting_for_aka_identity_request , ///< Client state pseydonym_waiting_for_aka_identity_request + eap_type_aka_state_analyse_aka_identity_request , ///< Client state analyse_aka_identity_request + eap_type_aka_state_waiting_for_challenge_request , ///< Client state waiting_for_challenge_request + eap_type_aka_state_analyses_challenge_request , ///< Client state analyses_challenge_request + eap_type_aka_state_pending_kc_sres_query , ///< Client state pending_kc_sres_query + eap_type_aka_state_waiting_for_notification_request_success , ///< Client state waiting_for_notification_request_success + eap_type_aka_state_waiting_for_success , ///< Client state waiting_for_success + eap_type_aka_state_waiting_for_reauth_request , ///< Client state waiting_for_reauth_request + eap_type_aka_state_analyses_reauthentication_request , ///< Client state analyses_reauthentication_request + + eap_type_aka_state_pending_pseudonym_decode_query , ///< Server state pending_pseudonym_decode_query + eap_type_aka_state_waiting_for_identity_response , ///< Server state waiting_for_identity_response + eap_type_aka_state_waiting_for_aka_identity_response_with_at_permanent_identity , ///< Server state waiting_for_aka_identity_response_with_at_permanen_identity + eap_type_aka_state_waiting_for_aka_identity_response_with_at_full_auth_identity , ///< Server state waiting_for_aka_identity_response_with_at_identity + eap_type_aka_state_waiting_for_aka_identity_response_with_at_any_identity , ///< Server state waiting_for_aka_identity_response_with_at_identity + eap_type_aka_state_waiting_for_aka_identity_response , ///< Server state waiting_for_aka_identity_response + eap_type_aka_state_pending_re_syncronization_query , ///< Server state pending_re_syncronization_query + eap_type_aka_state_waiting_for_challenge_response , ///< Server state waiting_for_challenge_response + eap_type_aka_state_pending_authentication_vector_query , ///< Server state pending_authentication_vector_query + eap_type_aka_state_analyses_challenge_response , ///< Server state analyses_challenge_response + eap_type_aka_state_analyses_aka_identity_response , ///< Server state analyses_aka_identity_response + eap_type_aka_state_waiting_for_notification_response_failure , ///< Server state waiting_for_notification_response, authentication failed + eap_type_aka_state_waiting_for_notification_response_success , ///< Server state waiting_for_notification_response, authentication success + eap_type_aka_state_waiting_for_reauth_response , ///< Server state waiting_for_reauth_response + eap_type_aka_state_analyses_reauthentication_response , ///< Server state analyses_reauthentication_response + + eap_type_aka_state_success , ///< State state_success + eap_type_aka_state_failure , ///< State state_failure + + eap_type_aka_state_last_value ///< Keep this enum the last one. +}; + + +/** + * This is the required completion after a asyncronous call. + */ +enum eap_type_aka_complete_e +{ + eap_type_aka_complete_none, ///< No completion required + eap_type_aka_complete_aka_identity_request, ///< AKA start request must be completed + eap_type_aka_complete_query_eap_identity, ///< AKA EAP-identity query must be completed + eap_type_aka_complete_handle_imsi_from_username, + eap_type_aka_complete_handle_aka_identity_response_message_completion, +}; + + +/** + * This is the status of the authentication_vector. + */ +enum eap_aka_authentication_vector_status_e +{ + eap_aka_authentication_vector_status_ok = 0, + eap_aka_authentication_vector_status_no_roaming_agreement = 1024, ///< No roaming agreement. + eap_aka_authentication_vector_status_users_calls_are_barred = 1026, ///< User's calls are barred. + eap_aka_authentication_vector_status_user_has_not_subscribed_to_the_requested_service = 1031, ///< User has not subrcibed to the requested service. +}; + + +enum eap_aka_notification_codes_e +{ + eap_aka_notification_no_F_no_P_general_failure = 0, ///< General failure. (implies failure, used after successful authentication) + eap_aka_notification_no_F_P_set_general_failure = 16384, ///< General failure. (implies failure, used before authentication) + eap_aka_notification_F_set_no_P_user_authenticated = 32768, ///< User has been successfully authenticated. (does not imply failure, used after successful authentication). The usage of this code is discussed in Section 4.4.2. + eap_aka_notification_no_F_no_P_users_calls_are_barred = 1026, ///< User has been temporarily denied access to the requested service. (Implies failure, used after successful authentication) + eap_aka_notification_no_F_no_P_user_has_not_subscribed_to_the_requested_service = 1031, ///< User has not subscribed to the requested service (implies failure, used after successful authentication) + eap_aka_notification_none = 0xffff, ///< No code. +}; + + +enum aka_notification_code_bits_e +{ + aka_notification_code_bit_f = 0x8000, + aka_notification_code_bit_p = 0x4000, + aka_notification_code_value = 0x3FFF, +}; + + +/** See eap_aka_authentication_vector_status_e. */ +const u8_t EAP_AKA_NOTIFICATION_NO_ROAMING_AGREEMENT[] + = "1024 Visited network does not have a roaming agreement with user's home operator"; +/** See eap_aka_authentication_vector_status_e. */ +const u8_t EAP_AKA_NOTIFICATION_USERS_CALLS_ARE_BARRED[] + = "1026 User's calls are barred"; +/** See eap_aka_authentication_vector_status_e. */ +const u8_t EAP_AKA_NOTIFICATION_USER_HAS_NOT_SUBSCRIBED_TO_THE_REQUESTED_SERVICE[] + = "1031 User has not subscribed to the requested service"; + +/** + * This is the type of the AKA identity. + */ +enum eap_type_aka_identity_type +{ + AKA_IDENTITY_TYPE_NONE, + AKA_IDENTITY_TYPE_IMSI_ID, + AKA_IDENTITY_TYPE_PSEUDONYM_ID, + AKA_IDENTITY_TYPE_RE_AUTH_ID, +}; + +enum eap_aka_authentication_type_e +{ + AKA_AUTHENTICATION_TYPE_NONE, + AKA_AUTHENTICATION_TYPE_FULL_AUTH, + AKA_AUTHENTICATION_TYPE_REAUTHENTICATION, +}; + +const u8_t AKA_IMSI_PREFIX_CHARACTER[] = "0"; + +const u32_t TRACE_FLAGS_AKA_ERROR = eap_am_tools_c::eap_trace_mask_error; + +const u8_t AKA_AT_CHARACTER[] = "@"; + +const u8_t AKA_OWLAN_ORG_PREFIX_STRING[] = "wlan"; +const u32_t AKA_OWLAN_ORG_PREFIX_STRING_LENGTH = sizeof(AKA_OWLAN_ORG_PREFIX_STRING)-1ul; + +const u8_t AKA_UMA_PREFIX_STRING[] = "uma"; +const u32_t AKA_UMA_PREFIX_STRING_LENGTH = sizeof(AKA_UMA_PREFIX_STRING)-1ul; + +const u8_t AKA_OWLAN_MNC_STRING[] = "mnc"; +const u32_t AKA_OWLAN_MNC_STRING_LENGTH = sizeof(AKA_OWLAN_MNC_STRING)-1ul; + +const u8_t AKA_OWLAN_DOT_STRING[] = "."; +const u32_t AKA_OWLAN_DOT_STRING_LENGTH = sizeof(AKA_OWLAN_DOT_STRING)-1ul; + +const u8_t AKA_OWLAN_MCC_STRING[] = "mcc"; +const u32_t AKA_OWLAN_MCC_STRING_LENGTH = sizeof(AKA_OWLAN_MCC_STRING)-1ul; + +const u8_t AKA_OWLAN_ORG_STRING[] = "3gppnetwork.org"; +const u32_t AKA_OWLAN_ORG_STRING_LENGTH = sizeof(AKA_OWLAN_ORG_STRING)-1ul; + + +enum eap_type_aka_constants_e +{ + EAP_TYPE_AKA_NONCE_MT_SIZE = 16ul, ///< bytes = 128 bits + EAP_TYPE_AKA_MAC_SIZE = 16ul, ///< bytes = 128 bits + EAP_TYPE_AKA_KEYMAT_SIZE = 20ul, ///< bytes = 160 bits + EAP_TYPE_AKA_MASTER_SESSION_KEY_SIZE = 4u*32ul, ///< bytes + EAP_TYPE_AKA_MAX_NAI_LENGTH = 255ul, ///< bytes + EAP_TYPE_AKA_MAX_USER_NAI_LENGTH = 255ul, ///< bytes + EAP_TYPE_AKA_DEFAULT_MINIMUM_RAND_COUNT = 2ul, ///< count + EAP_TYPE_AKA_LOCAL_PACKET_BUFFER_LENGTH = 512ul, ///< This is the size of the local send buffer. + EAP_TYPE_AKA_PADDING_MODULUS = 4ul, ///< Padding length is always mudulus of 4. + EAP_TYPE_AKA_PADDING_MAX_VALUE = 12ul, ///< Maximum padding length is 12 bytes. + EAP_TYPE_AKA_MINIMUM_RAND_LENGTH = 16ul, + EAP_TYPE_AKA_MINIMUM_AUTN_LENGTH = 16ul, + EAP_TYPE_AKA_AUTS_LENGTH = 14ul, + EAP_TYPE_AKA_CK_LENGTH = 16ul, + EAP_TYPE_AKA_IK_LENGTH = 16ul, + EAP_TYPE_AKA_MINIMUM_RES_LENGTH = 4ul, + EAP_TYPE_AKA_MAXIMUM_CHECKCODE_LENGTH = 20ul, + EAP_TYPE_AKA_INITIAL_REAUTH_COUNTER = 1ul, + EAP_TYPE_AKA_DEFAULT_MNC_LENGTH_3_BYTES = 3ul, + EAP_TYPE_AKA_MNC_LENGTH_2_BYTES = 2ul, + EAP_TYPE_AKA_MNC_OFFSET = 3ul, + EAP_TYPE_AKA_MCC_LENGTH = 3ul, + EAP_TYPE_AKA_MCC_OFFSET = 0ul, + EAP_TYPE_AKA_MINIMUM_IMSI_LENGTH = EAP_TYPE_AKA_MCC_LENGTH+EAP_TYPE_AKA_MNC_LENGTH_2_BYTES+1, +}; + +enum eap_type_aka_timer_id_e +{ + EAP_TYPE_AKA_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID, + EAP_TYPE_AKA_TIMER_DELAY_NOTIFICATION_MESSAGE_ID, +}; + +enum eap_type_aka_timer_timeout_value_e +{ + EAP_TYPE_AKA_TIMER_TIMEOUT_VALUE_DELAY_FAILURE_MESSAGE_SENT = 0ul, ///< This is the default value. Zero means error message is handled immediately. +}; + +enum eap_type_aka_stored_e +{ + eap_type_aka_stored_none, + eap_type_aka_stored_reauth_xkey, + eap_type_aka_stored_reauth_k_aut, + eap_type_aka_stored_reauth_k_encr, + eap_type_aka_stored_pseudonym_identity, + eap_type_aka_stored_reauth_identity, + eap_type_aka_stored_pseudonym_key, + eap_type_aka_stored_pseudonym_mac_key, + eap_type_aka_stored_prev_pseudonym_key, + eap_type_aka_stored_prev_pseudonym_mac_key, + eap_type_aka_stored_pseudonym_key_index, + eap_type_aka_stored_pseudonym_key_use_count, + eap_type_aka_stored_pseudonym_use_count, + eap_type_aka_stored_reauth_use_count, + eap_type_aka_stored_saved_reauth_counter, + eap_type_aka_stored_sqn, +}; + + +/** + * @defgroup AKA_config_options Configuration options of AKA. + * The following configuration options are read through abs_eap_base_type_c::read_configure() function. + * @{ + */ + +/** + * This u32_t configuration option is timeout in milli seconds before erroneous message is processed. + * This is useful in protocol testing or if some delay is needed in final application. + * Default value is 0. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_failure_message_delay_time, + "EAP_AKA_failure_message_delay_time", + eap_configure_type_u32_t, + false); + +/** + * This boolean configuration option specifies whether the username should + * be generated automatically. + * Default value is 0. That will cause use of automatic username. If this is 1 + * then cf_str_EAP_AKA_manual_username is used as the username. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_use_manual_username, + "EAP_AKA_use_manual_username", + eap_configure_type_boolean, + false); + +/** + * This string configuration option is the username part of EAP-type AKA identity. + * Default value is empty string. That will cause use of automatic username. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_manual_username, + "EAP_AKA_manual_username", + eap_configure_type_string, + false); + +/** + * This boolean configuration option specifies whether the realm should + * be generated automatically. + * Default value is 0. That will cause use of automatic realm. If this is 1 + * then cf_str_EAP_AKA_manual_realm is used as the realm. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_use_manual_realm, + "EAP_AKA_use_manual_realm", + eap_configure_type_boolean, + false); + +/** + * This string configuration option is the realm part of EAP-type AKA identity. + * Default value is empty string. That will cause use of automatic realm. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_manual_realm, + "EAP_AKA_manual_realm", + eap_configure_type_string, + false); + +/** + * This is boolean configuration option. + * True value means on successfull authentication EAP-type AKA waits the EAP-Success message. + * False value means on successfull authentication EAP-type AKA does NOT wait the EAP-Success message. + * NOTE: True value is needed in Windows RAS. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_wait_eap_success_packet, + "EAP_AKA_wait_eap_success_packet", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means on EAP-type AKA must check identifier of EAP-Response/Identity message. + * False value means on EAP-type AKA does not check identifier of EAP-Response/Identity message. + * This is not possible in cases where identifier of the EAP-Request/Identity is generated by other network entities. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_check_identifier_of_eap_identity_response, + "EAP_AKA_check_identifier_of_eap_identity_response", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag activates NAI realm check. Default value is false. + * When active NAI realm muts be the same as realm given by EAP_AKA_manual_realm option. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_check_nai_realm, + "EAP_AKA_check_nai_realm", + eap_configure_type_boolean, + false); + +/** + * This is for testing. + * This string configuration option is the full path name of the nonce_mt file. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_nonce_mt_file, + "EAP_AKA_nonce_mt_file", + eap_configure_type_string, + false); + +/** + * This is for testing. + * This string configuration option is the full path name of the triplet file. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_authentication_vector_file, + "EAP_AKA_authentication_vector_file", + eap_configure_type_string, + false); + +/** + * This is for testing. + * This string configuration option is the full path name of the pseudonym file. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_pseudonym_file, + "EAP_AKA_pseudonym_file", + eap_configure_type_string, + false); + +/** + * This is for testing. + * This string configuration option is the full path name of the reauthentication file. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_reauthentication_file, + "EAP_AKA_reauthentication_file", + eap_configure_type_string, + false); + +/** + * This is for testing. + * This string configuration option is the full path name of the encryption IV file. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_encryption_iv_file, + "EAP_AKA_encryption_iv_file", + eap_configure_type_string, + false); + +/** + * This is boolean configuration option. + * True value means client of EAP-type AKA responds to every re-transmitted EAP-AKA request packets. + * False value means client of EAP-type AKA does not respond to any re-transmitted EAP-AKA request packets, + * instead the EAP layer does re-transmit the response. + * The default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_client_responds_retransmitted_packets, + "EAP_AKA_client_responds_retransmitted_packets", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is for testing. + * True value means test version of EAP-type AKA is used. + * Test version tries to make as many authentications as it is possible. + * False value means on real version of EAP-type AKA is used. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_test_version, + "EAP_AKA_test_version", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is for testing. + * True value means server refuses EAP-identity randomly. + * False value means does not refuse EAP-identity randomly. + * NOTE EAP_AKA_test_version option must be true also. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_randomly_refuse_eap_identity, + "EAP_AKA_randomly_refuse_eap_identity", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means on test of re-authentication counter of EAP-type AKA will fail always. + * NOTE EAP_AKA_test_version option must be true also. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_fail_re_authentication_counter_check, + "EAP_AKA_fail_re_authentication_counter_check", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value of this flag allows server accept the EAP-Response/Identity message. + * False value does not allow server accept the EAP-Response/Identity message. + * Instead server queries identity in EAP-Request/AKA/Start with AT_ANY_ID_REQ attribute. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_accept_eap_identity_response, + "EAP_AKA_accept_eap_identity_response", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value of this flag causes client return random + * identity on EAP-Response/Identity. + * False value causes client return real identity + * (IMSI, pseudonym or re-authentication identity) + * in EAP-Response/Identity. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_use_random_identity_on_eap_identity_response, + "EAP_AKA_use_random_identity_on_eap_identity_response", + eap_configure_type_boolean, + false); + +/** + * This is string configuration option. + * This option selects the AKA algorithm used in akaulation. + * Possible values are "nokia_test_network_xor" or "tls_prf_with_shared_secret". + * The default value is nokia_test_network_xor. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_simulator_aka_algorithm, + "EAP_AKA_simulator_aka_algorithm", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_simulator_aka_algorithm_config_value_nokia_test_network_xor, + "nokia_test_network_xor", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_simulator_aka_algorithm_config_value_tls_prf_with_shared_secret, + "tls_prf_with_shared_secret", + eap_configure_type_string, + false); + +/** + * This is hex data configuration option. + * This Ki is used in software-AKA (SW-AKA) implementation of MILENAGE algorithm. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_simulator_aka_k, + "EAP_AKA_simulator_aka_k", + eap_configure_type_hex_data, + false); + +/** + * This is hex data configuration option. + * This OP is used in software-AKA (SW-AKA) implementation of MILENAGE algorithm. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_simulator_aka_op, + "EAP_AKA_simulator_aka_op", + eap_configure_type_hex_data, + false); + +/** + * This is 16-bit hex data configuration option. + * This AMF is used in software-AKA (SW-AKA) implementation of MILENAGE algorithm. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_simulator_aka_amf, + "EAP_AKA_simulator_aka_amf", + eap_configure_type_hex_data, + false); + +/** + * This is boolean configuration option. + * This flag tells whether the random synchronization errors + * of MILENAGE algorithm must be done (true) or not (false). + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_simulator_aka_do_random_synchronization_errors, + "EAP_AKA_simulator_aka_do_random_synchronization_errors", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag tells whether the pseudonym identity could be used (true) or not (false). + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_use_pseudonym_identity, + "EAP_AKA_use_pseudonym_identity", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag tells whether the re-authentication identity could be used (true) or not (false). + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_use_reauthentication_identity, + "EAP_AKA_use_reauthentication_identity", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means queries to AM are completed asyncronous. + * False value means queries to AM are completed syncronous. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_do_asyncronous_completions, + "EAP_AKA_do_asyncronous_completions", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means authentication_vector queries to AM are failed randomly. + * False value means authentication_vector queries to AM are not failed. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_fail_AKA_authentication_vector_query_randomly, + "EAP_AKA_fail_AKA_authentication_vector_query_randomly", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means queries to AM are randomly completed asyncronous. + * False value means queries to AM are randomly completed syncronous. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_do_asyncronous_completions_randomly, + "EAP_AKA_do_asyncronous_completions_randomly", + eap_configure_type_boolean, + false); + + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means EAP-AKA server fails randomly successfull authentication. + * False value means EAP-AKA server does NOT fail randomly successfull authentication. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_randomly_fail_successfull_authentication, + "EAP_AKA_randomly_fail_successfull_authentication", + eap_configure_type_boolean, + false); + + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means EAP-AKA client and server allows result indications. + * False value means EAP-AKA client and server does NOT allow result indications. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_allow_use_result_indication, + "EAP_AKA_allow_use_result_indication", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. True value activates use of expanded EAP type field of 64-bits in length. + * False value forces to use the normal 8-bit EAP type field. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_use_eap_expanded_type, + "EAP_AKA_use_eap_expanded_type", + eap_configure_type_boolean, + false); + + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means EAP-AKA server allows result indications. + * False value means EAP-AKA server does NOT allow result indications. + * NOTE this option over rides cf_str_EAP_AKA_allow_use_result_indication + * in server. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_server_allow_use_result_indication, + "EAP_AKA_server_allow_use_result_indication", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag tells whether the UMA profile is used (true) or not (false). + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_UMA_profile, + "EAP_AKA_UMA_profile", + eap_configure_type_boolean, + false); + +/** + * This is string configuration option. + * The string is the prefix of automatic realm in the UMA profile. + * Note also the EAP_AKA_UMA_profile must be true before + * this option is used. + * Default value is empty. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_UMA_realm_prefix, + "EAP_AKA_UMA_realm_prefix", + eap_configure_type_string, + false); + +/** + * This u32_t array configuration option is includes those MCCs that uses 2 digit MNC. + * Default value is empty array. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_2_digit_mnc_map_of_mcc_of_imsi_array, + "EAP_AKA_GSMSIM_2_digit_mnc_map_of_mcc_of_imsi_array", + eap_configure_type_u32array, + false); + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means EAP-AKA server randomly skip pseudonym and fast-reauth identity generation. + * False value means EAP-AKA server does generate those identities. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_server_randomly_skip_identity_generation, + "EAP_AKA_server_randomly_skip_identity_generation", + eap_configure_type_boolean, + false); + +/** + * This u32_t configuration value specifies the maximum session validity time in seconds. + * Default value is 12 hours in seconds, which is 43200 seconds. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_AKA_max_session_validity_time, + "EAP_AKA_max_session_validity_time", + eap_configure_type_u32_t, + false); + +/** @} */ // End of group AKA_config_options. + +//-------------------------------------------------- + +/// Macro traces payload type and data. +#define EAP_AKA_TRACE_PAYLOAD(prefix, payload) \ + { \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("%s (0x%08x): current payload 0x%04x=%s, data length 0x%04x.\n"), \ + prefix, (payload)->get_header_buffer((payload)->get_payload_length()), (payload)->get_current_payload(), \ + (payload)->get_payload_AT_string(), (payload)->get_data_length())); \ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("payload"), \ + (payload)->get_header_buffer((payload)->get_payload_length()), \ + (payload)->get_payload_length())); \ + } + +//-------------------------------------------------- + + +/// These are the stored attributes for message authentication calculations. +class eap_type_aka_MAC_attributes_c +{ +private: + //-------------------------------------------------- + + u8_t * m_MAC; ///< This is the pointer to MAC. + u32_t m_MAC_size; ///< This is the size of the MAC. + u8_t *m_data; ///< This is the pointer to the authenticated data. + u32_t m_data_length; ///< This the length of the authenticated data. + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + virtual ~eap_type_aka_MAC_attributes_c(); + + eap_type_aka_MAC_attributes_c(); + + eap_type_aka_MAC_attributes_c( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length); + + void init( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length); + + u8_t * get_MAC() const; + + void set_MAC(u8_t * MAC); + + u32_t get_MAC_size() const; + + eap_type_aka_MAC_attributes_c * copy() const; + + u8_t * get_data() const; + + u32_t get_data_length(); + + void set_data(u8_t * const data); + + //-------------------------------------------------- +}; + + +#endif //#if !defined(_AKA_TYPES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/diameter/include/eap_diameter_avp_code.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/diameter/include/eap_diameter_avp_code.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,287 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_DIAMETER_AVP_CODE_H_) +#define _EAP_DIAMETER_AVP_CODE_H_ + + +#include "eap_am_assert.h" +#include "eap_am_tools.h" +#include "eap_tools.h" + + +/** @file */ + +/** + * Enumeration of the DIAMETER APV codes of IETF. + * These are defined in IANA, "RADIUS Types", + * http://www.iana.org/assignments/radius-types. + */ +enum eap_diameter_avp_code_of_ietf_e +{ + eap_diameter_avp_code_none = 0, + eap_diameter_avp_code_user_name = 1, + eap_diameter_avp_code_user_password = 2, + eap_diameter_avp_code_chap_password = 3, + eap_diameter_avp_code_nas_ip_address = 4, + eap_diameter_avp_code_nas_port = 5, + eap_diameter_avp_code_service_type = 6, + eap_diameter_avp_code_framed_protocol = 7, + eap_diameter_avp_code_framed_ip_address = 8, + eap_diameter_avp_code_framed_ip_netmask = 9, + eap_diameter_avp_code_framed_routing = 10, + eap_diameter_avp_code_filter_id = 11, + eap_diameter_avp_code_framed_mtu = 12, + eap_diameter_avp_code_framed_compression = 13, + eap_diameter_avp_code_login_ip_host = 14, + eap_diameter_avp_code_login_service = 15, + eap_diameter_avp_code_login_tcp_port = 16, + eap_diameter_avp_code_reply_message = 18, + eap_diameter_avp_code_callback_number = 19, + eap_diameter_avp_code_callback_id = 20, + eap_diameter_avp_code_framed_route = 22, + eap_diameter_avp_code_framed_ipx_network = 23, + eap_diameter_avp_code_state = 24, + eap_diameter_avp_code_class = 25, + eap_diameter_avp_code_vendor_specific = 26, + eap_diameter_avp_code_session_timeout = 27, + eap_diameter_avp_code_idle_timeout = 28, + eap_diameter_avp_code_termination_action = 29, + eap_diameter_avp_code_called_station_id = 30, + eap_diameter_avp_code_calling_station_id = 31, + eap_diameter_avp_code_nas_identifier = 32, + eap_diameter_avp_code_proxy_state = 33, + eap_diameter_avp_code_login_lat_service = 34, + eap_diameter_avp_code_login_lat_node = 35, + eap_diameter_avp_code_login_lat_group = 36, + eap_diameter_avp_code_framed_appletalk_link = 37, + eap_diameter_avp_code_framed_appletalk_network = 38, + eap_diameter_avp_code_framed_appletalk_zone = 39, + eap_diameter_avp_code_chap_challenge = 60, + eap_diameter_avp_code_nas_port_type = 61, + eap_diameter_avp_code_port_limit = 62, + eap_diameter_avp_code_login_lat_port = 63, + eap_diameter_avp_code_eap_message = 79, + eap_diameter_avp_code_message_authenticator = 80, +}; + + +/** + * These values are defined in "ASSIGNED NUMBERS", RFC 1700. + */ +enum eap_diameter_vendor_id_e +{ + eap_diameter_vendor_id_of_ietf = 0, + eap_diameter_vendor_id_of_microsoft = 311, +}; + + +/** + * These are defined in "Microsoft Vendor-specific RADIUS Attributes", RFC 2548. + */ +enum eap_diameter_vendor_codes_of_microsoft_e +{ + eap_diameter_vendor_code_of_microsoft_ms_chap_error_value = 2, + eap_diameter_vendor_code_of_microsoft_ms_chap_nt_enc_pw_value = 6, + eap_diameter_vendor_code_of_microsoft_ms_chap_challenge_value = 11, + eap_diameter_vendor_code_of_microsoft_ms_mppe_send_key_value = 16, + eap_diameter_vendor_code_of_microsoft_ms_mppe_recv_key_value = 17, + eap_diameter_vendor_code_of_microsoft_ms_chap2_response_value = 25, + eap_diameter_vendor_code_of_microsoft_ms_chap2_success_value = 26, + eap_diameter_vendor_code_of_microsoft_ms_chap2_cpw_value = 27, +}; + +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- + +class EAP_EXPORT eap_diameter_avp_code_c +{ + +public: + + EAP_FUNC_IMPORT ~eap_diameter_avp_code_c(); + + EAP_FUNC_IMPORT eap_diameter_avp_code_c(); + + EAP_FUNC_IMPORT eap_diameter_avp_code_c( + const eap_diameter_vendor_id_e vendor_id, + const u32_t vendor_code); + + EAP_FUNC_IMPORT eap_diameter_avp_code_c( + const eap_diameter_avp_code_of_ietf_e ietf_code); + + + EAP_FUNC_IMPORT static bool is_ietf_code(const eap_diameter_avp_code_c code); + + + EAP_FUNC_IMPORT eap_status_e get_code_data( + abs_eap_am_tools_c * const am_tools, + eap_diameter_avp_code_of_ietf_e * const code); + + EAP_FUNC_IMPORT eap_status_e get_code_data( + abs_eap_am_tools_c * const am_tools, + eap_diameter_avp_code_c * const code); + + + EAP_FUNC_IMPORT void set_code_values( + const eap_diameter_vendor_id_e vendor_id, + const u32_t vendor_code); + + EAP_FUNC_IMPORT eap_diameter_vendor_id_e get_vendor_id() const; + + EAP_FUNC_IMPORT u32_t get_vendor_code() const; + + + EAP_FUNC_IMPORT bool operator == (const eap_diameter_avp_code_of_ietf_e right_type_value) const; + + EAP_FUNC_IMPORT bool operator != (const eap_diameter_avp_code_of_ietf_e right_type_value) const; + + EAP_FUNC_IMPORT bool operator == (const eap_diameter_avp_code_c &right_type_value) const; + + EAP_FUNC_IMPORT bool operator != (const eap_diameter_avp_code_c &right_type_value) const; + + + EAP_FUNC_IMPORT eap_diameter_avp_code_c &operator = (const eap_diameter_avp_code_of_ietf_e right_type_value); + + EAP_FUNC_IMPORT eap_diameter_avp_code_c &operator = (const eap_diameter_avp_code_c &right_type_value); + + EAP_FUNC_IMPORT eap_diameter_avp_code_c *operator & (); + + + EAP_FUNC_IMPORT const eap_diameter_avp_code_c *operator & () const; + + +private: + + eap_diameter_vendor_id_e m_vendor_id; + u32_t m_vendor_code; +}; + +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- + +class EAP_EXPORT eap_static_diameter_vendor_code_c +{ +public: + + EAP_FUNC_IMPORT const eap_diameter_avp_code_c & get_code() const; + +public: + + eap_diameter_vendor_id_e m_vendor_id; + u32_t m_vendor_code; +}; + +#define EAP_DIAMETER_VENDOR_CODE(name, vendor_id, vendor_code) \ + static const eap_static_diameter_vendor_code_c name={vendor_id, vendor_code} + +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- + +EAP_C_FUNC_IMPORT u32_t convert_eap_diameter_avp_code_to_u32_t(eap_diameter_avp_code_c code); + +EAP_C_FUNC_IMPORT u64_t convert_eap_diameter_avp_code_to_u64_t(eap_diameter_avp_code_c code); + +//----------------------------------------------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +// EAP Diameter Vendor Codes. + +/** + * This is defined in "Microsoft Vendor-specific RADIUS Attributes", RFC 2548. + * Reference name is MS-CHAP-Error. + */ +EAP_DIAMETER_VENDOR_CODE( + eap_diameter_vendor_code_of_microsoft_ms_chap_error, + eap_diameter_vendor_id_of_microsoft, + eap_diameter_vendor_code_of_microsoft_ms_chap_error_value); + +/** + * This is defined in "Microsoft Vendor-specific RADIUS Attributes", RFC 2548. + * Reference name is MS-CHAP-NT-Enc-PW. + */ +EAP_DIAMETER_VENDOR_CODE( + eap_diameter_vendor_code_of_microsoft_ms_chap_nt_enc_pw, + eap_diameter_vendor_id_of_microsoft, + eap_diameter_vendor_code_of_microsoft_ms_chap_nt_enc_pw_value); + +/** + * This is defined in "Microsoft Vendor-specific RADIUS Attributes", RFC 2548. + * Reference name is MS-CHAP-Challenge. + */ +EAP_DIAMETER_VENDOR_CODE( + eap_diameter_vendor_code_of_microsoft_ms_chap_challenge, + eap_diameter_vendor_id_of_microsoft, + eap_diameter_vendor_code_of_microsoft_ms_chap_challenge_value); + + +EAP_DIAMETER_VENDOR_CODE( + eap_diameter_vendor_code_of_microsoft_ms_mppe_send_key, + eap_diameter_vendor_id_of_microsoft, + eap_diameter_vendor_code_of_microsoft_ms_mppe_send_key_value); + +EAP_DIAMETER_VENDOR_CODE( + eap_diameter_vendor_code_of_microsoft_ms_mppe_recv_key, + eap_diameter_vendor_id_of_microsoft, + eap_diameter_vendor_code_of_microsoft_ms_mppe_recv_key_value); + + +/** + * This is defined in "Microsoft Vendor-specific RADIUS Attributes", RFC 2548. + * Reference name is MS-CHAP2-Response. + */ +EAP_DIAMETER_VENDOR_CODE( + eap_diameter_vendor_code_of_microsoft_ms_chap2_response, + eap_diameter_vendor_id_of_microsoft, + eap_diameter_vendor_code_of_microsoft_ms_chap2_response_value); + +/** + * This is defined in "Microsoft Vendor-specific RADIUS Attributes", RFC 2548. + * Reference name is MS-CHAP2-Success. + */ +EAP_DIAMETER_VENDOR_CODE( + eap_diameter_vendor_code_of_microsoft_ms_chap2_success, + eap_diameter_vendor_id_of_microsoft, + eap_diameter_vendor_code_of_microsoft_ms_chap2_success_value); + +/** + * This is defined in "Microsoft Vendor-specific RADIUS Attributes", RFC 2548. + * Reference name is MS-CHAP2-CPW. + */ +EAP_DIAMETER_VENDOR_CODE( + eap_diameter_vendor_code_of_microsoft_ms_chap2_cpw, + eap_diameter_vendor_id_of_microsoft, + eap_diameter_vendor_code_of_microsoft_ms_chap2_cpw_value); + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- + +#endif //#if !defined(_EAP_DIAMETER_AVP_CODE_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/diameter/include/eap_diameter_avp_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/diameter/include/eap_diameter_avp_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,255 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_DIAMETER_AVP_HEADER_H_) +#define _EAP_DIAMETER_AVP_HEADER_H_ + +#include "eap_tools.h" +#include "eap_general_header_base.h" +#include "eap_diameter_avp_code.h" + +/** @file */ + +const u32_t TRACE_FLAGS_DIAMETER_ERROR = eap_am_tools_c::eap_trace_mask_error; + +//---------------------------------------------------------------------------- + + +/// This class defines header of Attribute-Value Pairs. +/** + * Here is a figure of header of Attribute-Value Pairs. + * Value data follows eap_diameter_avp_header_c. + * @code + * AVP-header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AVP Code | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |V|M|r r r r r r| AVP Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Vendor-ID (optional) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Data .... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + * + * @code + * The fields of this header are: + * 32-bits AVP Code; This is a AVP Code. + * 1-bit flag vendor specific (V); Whether this AVP is vendor specific (1) + * 1-bit flag mandatory (M); Whether support of the AVP is required (1). + * 6-bits reserved bits; Unused bits must be zero. + * 24-bits value AVP Length; This is a length field, the length (in bytes) of the AVP header and data. + * 32-bits Vendor-ID; This is a optional Vendor-ID. The flag vendor specific (V) must be set too. + * @endcode + * + * See draft-funk-eap-ttls-v0-00.txt. + */ +class EAP_EXPORT eap_diameter_avp_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is enumeration of bit masks. + enum bit_masks + { + m_flag_mask_vendor_specific_avp = 0x80, + m_flag_mask_mandatory_avp = 0x40, + m_flag_mask_reserved_avp = 0x3f, + }; + + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + /// This is enumeration of offsets to data fields. + enum offsets + { + m_avp_code_offset = 0ul, ///< This is offset to AVP Code 32-bit field. + m_flags_offset = m_avp_code_offset+sizeof(u32_t), ///< This is offset to flags 8-bit field. + m_length_offset = m_flags_offset+sizeof(u8_t), ///< This is offset to length 24-bit field. + m_vendor_id_or_data_offset = m_length_offset+(3ul*sizeof(u8_t)), ///< This is offset to vendor_specific id of data field. + m_data_with_vendor_id_offset = m_vendor_id_or_data_offset+sizeof(u32_t), ///< This is offset to data field. + }; + + /// This is enumeration of sizes of data fields. + enum avp_sizes + { + EAP_DIAMETER_AVP_MINIMUM_HEADER_LENGTH = m_vendor_id_or_data_offset, + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_diameter_avp_header_c class does nothing. + */ + virtual ~eap_diameter_avp_header_c(); + + /** + * The constructor of the eap_diameter_avp_header_c class simply initializes the attributes. + */ + eap_diameter_avp_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length); + + /** + * This function returns lengthof required padding. + */ + u32_t get_padding_length() const; + + + /** + * This function returns the AVP Code. + */ + eap_diameter_avp_code_c get_avp_code() const; + + /** + * This function returns the AVP vendor specific flag. + */ + bool get_avp_flag_vendor_specific() const; + + /** + * This function returns the AVP mandatory flag. + */ + bool get_avp_flag_mandatory_avp() const; + + /** + * This function returns the AVP reserved flags. + */ + u8_t get_avp_flags_reserved() const; + + /** + * This function returns the length of AVP (header+data). + */ + u32_t get_length() const; + + /** + * This function returns the length of AVP data. + */ + u32_t get_data_length() const; + + /** + * This function returns the header length of AVP. + */ + static u32_t get_header_length(const bool include_vendor_specific); + + /** + * This function returns the header length of AVP. + */ + u32_t get_header_length() const; + + /** + * This function returns pointer to the offset of data of AVP. + * @param offset is the offset of queried data in bytes. + * @param contignuous_bytes is the length of queried data in bytes. + */ + u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + + /** + * This function returns pointer to the offset of data of AVP. + * @param contignuous_bytes is the length of queried data in bytes. + */ + u8_t * get_data(const u32_t contignuous_bytes) const; + + + /** + * This function return pointer to the next AVP header in the same buffer. + */ + u8_t * get_next_header() const; + + + /** + * This function checks the header is valid. + */ + eap_status_e check_header() const; + + /** + * This function returns debug strings of the AVP Code. + */ + eap_const_string get_avp_code_string() const; + + /** + * This function sets the AVP Code. + */ + eap_status_e set_avp_code(const eap_diameter_avp_code_c code); + + /** + * This function sets the AVP vendor specific flag. + */ + eap_status_e set_avp_flag_vendor_specific(const bool vendor_specific); + + /** + * This function sets the AVP mandatory flag. + */ + eap_status_e set_avp_flag_mandatory_avp(const bool mandatory); + + /** + * This function sets the AVP mandatory flag. + */ + eap_status_e set_avp_flags_reserved(); + + /** + * This function sets the AVP data length. + */ + eap_status_e set_data_length(const u32_t p_length); + + /** + * This function resets the AVP header. + */ + eap_status_e reset_header(const u16_t data_length); + + // + //-------------------------------------------------- +}; // class eap_diameter_avp_header_c + + +//-------------------------------------------------- + +/// Macro traces payload type and data. +#define EAP_DIAMETER_TRACE_PAYLOAD(prefix, payload) \ + { \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("%s (0x%08x): AVP code 0x%08x:0x%08x=%s, data length 0x%04x.\n"), \ + prefix, (payload)->get_header_buffer((payload)->get_length()), \ + (payload)->get_avp_code().get_vendor_id(), (payload)->get_avp_code().get_vendor_code(), \ + (payload)->get_avp_code_string(), (payload)->get_data_length())); \ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("payload"), (payload)->get_header_buffer((payload)->get_length()), \ + (payload)->get_length())); \ + } + +//-------------------------------------------------- + +#endif //#if !defined(_EAP_DIAMETER_AVP_HEADER_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/diameter/include/eap_diameter_payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/diameter/include/eap_diameter_payloads.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,184 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_DIAMETER_RESULT_H_) +#define _EAP_DIAMETER_RESULT_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_diameter_avp_header.h" +#include "eap_diameter_avp_code.h" +#include "eap_core_map.h" +#include "eap_array.h" + + +class EAP_EXPORT eap_diameter_variable_data_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + eap_variable_data_c m_data; + + eap_diameter_avp_code_c m_payload_code; + + bool m_is_mandatory; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~eap_diameter_variable_data_c(); + + EAP_FUNC_IMPORT eap_diameter_variable_data_c(abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT eap_status_e set_buffer( + const eap_diameter_avp_code_c current_payload_code, + const bool is_mandatory, + const u8_t * const buffer, + const u32_t buffer_length, + const bool free_buffer, + const bool is_writable); + + EAP_FUNC_IMPORT eap_status_e add_data( + const u8_t * const buffer, + const u32_t buffer_length); + + EAP_FUNC_IMPORT u32_t get_data_length() const; + + EAP_FUNC_IMPORT u8_t * get_data(const u32_t data_length) const; + + EAP_FUNC_IMPORT eap_variable_data_c * get_payload_buffer(); + + EAP_FUNC_IMPORT eap_diameter_avp_code_c get_payload_code() const; + + EAP_FUNC_IMPORT bool get_is_mandatory() const; + + EAP_FUNC_IMPORT void set_payload_code(const eap_diameter_avp_code_c code); + + EAP_FUNC_IMPORT eap_diameter_variable_data_c * copy() const; + + EAP_FUNC_IMPORT void object_increase_reference_count(); + + //-------------------------------------------------- +}; // class eap_diameter_variable_data_c + + +//-------------------------------------------------- + + +// +class EAP_EXPORT eap_diameter_payloads_c +: public abs_eap_core_map_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + /// This stores the eap_diameter_variable_data_c objects using eap_variable_data selector. + eap_core_map_c m_payload_map; + + /// This stores the same eap_diameter_variable_data_c objects to array. + /// This is to speed the sequential check of all payloads. + eap_array_c m_read_payloads; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~eap_diameter_payloads_c(); + + EAP_FUNC_IMPORT eap_diameter_payloads_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT eap_diameter_variable_data_c * get_payload( + const eap_diameter_avp_code_c current_payload); + + EAP_FUNC_IMPORT eap_status_e add_payload( + const eap_diameter_avp_code_c current_payload, + const bool is_mandatory, + const u8_t * const data, + const u32_t data_length, + const bool free_buffer, + const bool is_writable, + const bool fragments_allowed); + + /** + * This function parses the payloads starting from specified payload (p_payload). + * Function parses all payloads from the buffer. + * Payloads are stored to p_radius_payloads. + * @return If the length of the buffer and sum of the length of all payloads does not match + * function returns eap_status_header_corrupted. + * Also error is returned when illegal payload attribute is recognised. + */ + EAP_FUNC_IMPORT eap_status_e parse_diameter_payloads( + const eap_diameter_avp_header_c * const p_payload, ///< This is the start of the buffer and the first parsed payload. + u32_t * const buffer_length ///< This is the length of the buffer. This must match with the length of all payloads. + ); + + /** + * This function parses each payload attributes. + * @return If payload attribute is illegal function returns eap_status_header_corrupted. + * If payload attribute is unknown function returns eap_status_unsupported_payload. + */ + EAP_FUNC_IMPORT eap_status_e parse_generic_payload( + const eap_diameter_avp_code_c current_payload, ///< This is the type of current payload attribute. + const eap_diameter_avp_header_c * const payload ///< This is the current parsed payload. + ); + + /** + * This function checks all mandatory AVPs are used. + */ + EAP_FUNC_IMPORT eap_status_e check_mandatory_payloads( + EAP_TEMPLATE_CONST eap_array_c * const used_payloads); + + /** + * This function checks all required AVPs are received. + */ + EAP_FUNC_IMPORT eap_status_e check_payloads_existense( + EAP_TEMPLATE_CONST eap_array_c * const needed_payloads); + + EAP_FUNC_IMPORT bool get_is_valid() const; + + EAP_FUNC_IMPORT eap_status_e reset(); + + //-------------------------------------------------- +}; // class eap_diameter_payloads_c + + +#endif //#if !defined(_EAP_DIAMETER_RESULT_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/diameter/src/eap_diameter_avp_code.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/diameter/src/eap_diameter_avp_code.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,254 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 573 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_diameter_avp_code.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_diameter_avp_code_c::~eap_diameter_avp_code_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_diameter_avp_code_c::eap_diameter_avp_code_c() +{ + m_vendor_id = eap_diameter_vendor_id_of_ietf; + m_vendor_code = static_cast(eap_diameter_avp_code_none); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_diameter_avp_code_c::eap_diameter_avp_code_c( + const eap_diameter_vendor_id_e vendor_id, + const u32_t vendor_type) +{ + m_vendor_id = vendor_id; + m_vendor_code = vendor_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_diameter_avp_code_c::eap_diameter_avp_code_c( + const eap_diameter_avp_code_of_ietf_e type) +{ + m_vendor_id = eap_diameter_vendor_id_of_ietf; + m_vendor_code = static_cast(type); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_diameter_avp_code_c::is_ietf_code(const eap_diameter_avp_code_c avp_code) +{ + return (avp_code.get_vendor_id() == eap_diameter_vendor_id_of_ietf); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_diameter_avp_code_c::get_code_data( + abs_eap_am_tools_c * const am_tools, + eap_diameter_avp_code_of_ietf_e * const type) +{ + if (type == 0) + { + EAP_UNREFERENCED_PARAMETER(am_tools); + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + + if (m_vendor_id == eap_diameter_vendor_id_of_ietf) + { + *type = static_cast(m_vendor_code); + } + else + { + // This is EAP type of other vendor than IETF. + // This cannot be denoted in eap_diameter_avp_code_of_ietf_e. + *type = static_cast(eap_diameter_avp_code_none); + } + + return EAP_STATUS_RETURN(am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_diameter_avp_code_c::get_code_data( + abs_eap_am_tools_c * const am_tools, + eap_diameter_avp_code_c * const type) +{ + if (type == 0) + { + EAP_UNREFERENCED_PARAMETER(am_tools); + return EAP_STATUS_RETURN(am_tools, eap_status_illegal_parameter); + } + + *type = *this; + + return EAP_STATUS_RETURN(am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_diameter_avp_code_c::set_code_values( + const eap_diameter_vendor_id_e vendor_id, + const u32_t vendor_type) +{ + m_vendor_id = vendor_id; + m_vendor_code = vendor_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_diameter_vendor_id_e eap_diameter_avp_code_c::get_vendor_id() const +{ + return m_vendor_id; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_diameter_avp_code_c::get_vendor_code() const +{ + return m_vendor_code; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_diameter_avp_code_c::operator == (const eap_diameter_avp_code_of_ietf_e right_type_value) const +{ + if (m_vendor_id != eap_diameter_vendor_id_of_ietf) + { + return false; + } + else if (m_vendor_code != static_cast(right_type_value)) + { + return false; + } + else + { + return true; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_diameter_avp_code_c::operator != (const eap_diameter_avp_code_of_ietf_e right_type_value) const +{ + return !(*this == right_type_value); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_diameter_avp_code_c::operator == (const eap_diameter_avp_code_c &right_type_value) const +{ + if (m_vendor_id != right_type_value.get_vendor_id()) + { + return false; + } + else if (m_vendor_code != right_type_value.get_vendor_code()) + { + return false; + } + else + { + return true; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_diameter_avp_code_c::operator != (const eap_diameter_avp_code_c &right_type_value) const +{ + return !(*this == right_type_value); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_diameter_avp_code_c &eap_diameter_avp_code_c::operator = (const eap_diameter_avp_code_of_ietf_e right_type_value) +{ + m_vendor_id = eap_diameter_vendor_id_of_ietf; ///< Here we use only 24 least significant bits. + m_vendor_code = static_cast(right_type_value); + + return *this; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_diameter_avp_code_c &eap_diameter_avp_code_c::operator = (const eap_diameter_avp_code_c &right_type_value) +{ + m_vendor_id = right_type_value.get_vendor_id(); ///< Here we use only 24 least significant bits. + m_vendor_code = right_type_value.get_vendor_code(); + + return *this; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_diameter_avp_code_c *eap_diameter_avp_code_c::operator & () +{ + return this; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_diameter_avp_code_c *eap_diameter_avp_code_c::operator & () const +{ + return this; +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_diameter_avp_code_c &eap_static_diameter_vendor_code_c::get_code() const +{ + return *reinterpret_cast(this); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_C_FUNC_EXPORT u32_t convert_eap_diameter_avp_code_to_u32_t(eap_diameter_avp_code_c code) +{ + // NOTE, this returns only 8 least significant bits of vendor type. + return static_cast(code.get_vendor_id() << sizeof(u8_t)*8ul + | (0xff & code.get_vendor_code())); +} + +EAP_C_FUNC_EXPORT u64_t convert_eap_diameter_avp_code_to_u64_t(eap_diameter_avp_code_c code) +{ + return static_cast(code.get_vendor_id()) << sizeof(u32_t)*8ul + | static_cast(code.get_vendor_code()); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/diameter/src/eap_diameter_avp_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/diameter/src/eap_diameter_avp_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,582 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 73 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_diameter_avp_header.h" + +/** @file */ + +//----------------------------------------------------------------------------- + +/** + * This function returns length of the required padding. + */ +u32_t eap_diameter_avp_header_c::get_padding_length() const +{ + // NOTE AVP is padded always to multiple of 4 octets. + u32_t avp_length = get_length(); + u32_t remainder = avp_length % 4ul; + if (remainder != 0ul) + { + return 4ul - remainder; + } + else + { + return 0; + } +} + +//----------------------------------------------------------------------------- + +/** + * The destructor of the eap_diameter_avp_header_c class does nothing. + */ +eap_diameter_avp_header_c::~eap_diameter_avp_header_c() +{ +} + +//----------------------------------------------------------------------------- + +/** + * The constructor of the eap_diameter_avp_header_c class simply initializes the attributes. + */ +eap_diameter_avp_header_c::eap_diameter_avp_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) +{ +} + +//----------------------------------------------------------------------------- + +/** + * This function returns the AVP Code. + */ +eap_diameter_avp_code_c eap_diameter_avp_header_c::get_avp_code() const +{ + const u8_t * const code_data = get_header_offset(m_avp_code_offset, sizeof(u32_t)); + if (code_data != 0) + { + const u32_t avp_code = eap_read_u32_t_network_order(code_data, sizeof(u32_t)); + + eap_diameter_vendor_id_e vendor_id(eap_diameter_vendor_id_of_ietf); + + if (get_avp_flag_vendor_specific() == true) + { + // We have vendor specific AVP code. + // This reads the vendor ID. + const u8_t * const vendor_id_data = get_header_offset(m_vendor_id_or_data_offset, sizeof(u32_t)); + if (vendor_id_data != 0) + { + vendor_id = static_cast(eap_read_u32_t_network_order(vendor_id_data, sizeof(u32_t))); + } + else + { + return eap_diameter_avp_code_none; + } + } + + eap_diameter_avp_code_c vendor_specific_code(vendor_id, avp_code); + + return vendor_specific_code; + } + else + { + return eap_diameter_avp_code_none; + } +} + +//----------------------------------------------------------------------------- + +/** + * This function returns the AVP vendor specific flag. + */ +bool eap_diameter_avp_header_c::get_avp_flag_vendor_specific() const +{ + const u8_t * const flags = get_header_offset(m_flags_offset, sizeof(u8_t)); + if (flags != 0) + { + if (((*flags) & m_flag_mask_vendor_specific_avp) != 0) + { + return true; + } + } + return false; +} + +//----------------------------------------------------------------------------- + +/** + * This function returns the AVP mandatory flag. + */ +bool eap_diameter_avp_header_c::get_avp_flag_mandatory_avp() const +{ + const u8_t * const flags = get_header_offset(m_flags_offset, sizeof(u8_t)); + if (flags != 0) + { + if (((*flags) & m_flag_mask_mandatory_avp) != 0) + { + return true; + } + } + return false; +} + +//----------------------------------------------------------------------------- + +/** + * This function returns the AVP reserved flags. + */ +u8_t eap_diameter_avp_header_c::get_avp_flags_reserved() const +{ + const u8_t * const flags = get_header_offset(m_flags_offset, sizeof(u8_t)); + if (flags != 0) + { + return static_cast((*flags) & m_flag_mask_reserved_avp); + } + + return 0xff; +} + +//----------------------------------------------------------------------------- + +/** + * This function returns the length of AVP (header+data). + */ +u32_t eap_diameter_avp_header_c::get_length() const +{ + return get_header_length() + get_data_length(); +} + +//----------------------------------------------------------------------------- + +/** + * This function returns the length of AVP data. + */ +u32_t eap_diameter_avp_header_c::get_data_length() const +{ + const u8_t * const length_data = get_header_offset(m_length_offset, 3ul*sizeof(u8_t)); + if (length_data != 0) + { + u32_t header_and_data_length = eap_read_u24_t_network_order(length_data, 3ul*sizeof(u8_t)); + if (header_and_data_length > get_header_length()) + { + return header_and_data_length - get_header_length(); + } + } + return 0ul; +} + +//----------------------------------------------------------------------------- + +/** + * This function returns the header length of AVP. + */ +u32_t eap_diameter_avp_header_c::get_header_length(const bool include_vendor_specific) +{ + if (include_vendor_specific == true) + { + return m_data_with_vendor_id_offset; + } + else + { + return m_vendor_id_or_data_offset; + } +} + +//----------------------------------------------------------------------------- + +/** + * This function returns the header length of AVP. + */ +u32_t eap_diameter_avp_header_c::get_header_length() const +{ + return get_header_length(get_avp_flag_vendor_specific()); +} + +//----------------------------------------------------------------------------- + +/** + * This function returns pointer to the offset of data of AVP. + * @param offset is the offset of queried data in bytes. + * @param contignuous_bytes is the length of queried data in bytes. + */ +u8_t * eap_diameter_avp_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + u32_t data_length = get_header_buffer_length() - get_header_length(); + + if (data_length >= offset+contignuous_bytes) + { + u8_t * data = 0; + + if (get_avp_flag_vendor_specific() == true) + { + data = get_header_offset(m_data_with_vendor_id_offset, offset+contignuous_bytes); + } + else + { + data = get_header_offset(m_vendor_id_or_data_offset, offset+contignuous_bytes); + } + + if (data != 0) + { + return &data[offset]; + } + else + { + return 0; + } + } + else + { + EAP_ASSERT_ALWAYS(data_length >= offset+contignuous_bytes); + } + return 0; +} + +//----------------------------------------------------------------------------- + +/** + * This function returns pointer to the offset of data of AVP. + * @param contignuous_bytes is the length of queried data in bytes. + */ +u8_t * eap_diameter_avp_header_c::get_data(const u32_t contignuous_bytes) const +{ + return get_data_offset(0u, contignuous_bytes); +} + +//----------------------------------------------------------------------------- + +/** + * This function return pointer to the next AVP header in the same buffer. + */ +u8_t * eap_diameter_avp_header_c::get_next_header() const +{ + // NOTE AVP is padded always to multiple of 4 octets. + u32_t data_length = get_header_buffer_length() - get_header_length(); + u32_t avp_data_length = get_data_length(); + u32_t padding_length = get_padding_length(); + u32_t required_length = avp_data_length+padding_length+EAP_DIAMETER_AVP_MINIMUM_HEADER_LENGTH; + + if (data_length >= required_length) + { + return get_data_offset(avp_data_length+padding_length, EAP_DIAMETER_AVP_MINIMUM_HEADER_LENGTH); + } + else + { + return 0; + } +} + +//----------------------------------------------------------------------------- + +/** + * This function checks the header is valid. + */ +eap_status_e eap_diameter_avp_header_c::check_header() const +{ + if (get_avp_code() != eap_diameter_avp_code_eap_message) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (get_avp_flags_reserved() != 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (get_avp_flag_vendor_specific() == true + && get_header_buffer_length() < m_data_with_vendor_id_offset) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + else if (get_avp_flag_vendor_specific() == false + && get_header_buffer_length() < m_vendor_id_or_data_offset) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//----------------------------------------------------------------------------- + +/** + * This function returns debug strings of the AVP Code. + */ +eap_const_string eap_diameter_avp_header_c::get_avp_code_string() const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + const eap_diameter_avp_code_c code = get_avp_code(); + + EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_none) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_user_name) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_user_password) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_chap_password) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_nas_ip_address) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_nas_port) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_service_type) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_framed_protocol) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_framed_ip_address) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_framed_ip_netmask) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_framed_routing) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_filter_id) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_framed_mtu) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_framed_compression) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_login_ip_host) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_login_service) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_login_tcp_port) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_reply_message) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_callback_number) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_callback_id) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_framed_route) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_framed_ipx_network) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_state) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_class) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_vendor_specific) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_session_timeout) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_idle_timeout) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_termination_action) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_called_station_id) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_calling_station_id) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_nas_identifier) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_proxy_state) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_login_lat_service) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_login_lat_node) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_login_lat_group) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_framed_appletalk_link) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_framed_appletalk_network) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_framed_appletalk_zone) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_chap_challenge) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_nas_port_type) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_port_limit) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_login_lat_port) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_eap_message) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_message_authenticator) + else EAP_IF_RETURN_STRING(code, eap_diameter_avp_code_eap_message) +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else EAP_IF_RETURN_STRING(code, eap_diameter_vendor_code_of_microsoft_ms_chap_error.get_code()) + else EAP_IF_RETURN_STRING(code, eap_diameter_vendor_code_of_microsoft_ms_chap_nt_enc_pw.get_code()) + else EAP_IF_RETURN_STRING(code, eap_diameter_vendor_code_of_microsoft_ms_chap_challenge.get_code()) + else EAP_IF_RETURN_STRING(code, eap_diameter_vendor_code_of_microsoft_ms_chap2_response.get_code()) + else EAP_IF_RETURN_STRING(code, eap_diameter_vendor_code_of_microsoft_ms_chap2_success.get_code()) + else EAP_IF_RETURN_STRING(code, eap_diameter_vendor_code_of_microsoft_ms_chap2_cpw.get_code()) +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown AVP code"); + } +} + +//----------------------------------------------------------------------------- + +/** + * This function sets the AVP Code. + */ +eap_status_e eap_diameter_avp_header_c::set_avp_code(const eap_diameter_avp_code_c code) +{ + eap_status_e status(eap_status_process_general_error); + + { + u8_t * const code_data = get_header_offset(m_avp_code_offset, sizeof(u32_t)); + + if (code_data == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = eap_write_u32_t_network_order( + code_data, + sizeof(u32_t), + code.get_vendor_code()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (code.get_vendor_id() != eap_diameter_vendor_id_of_ietf) + { + // We have vendor specific AVP code. + // This writes the vendor ID. + + status = set_avp_flag_vendor_specific(true); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const vendor_id_data = get_header_offset(m_vendor_id_or_data_offset, sizeof(u32_t)); + + if (vendor_id_data == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = eap_write_u32_t_network_order( + vendor_id_data, + sizeof(u32_t), + code.get_vendor_id()); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------------------- + +/** + * This function sets the AVP vendor specific flag. + */ +eap_status_e eap_diameter_avp_header_c::set_avp_flag_vendor_specific( + const bool vendor_specific) +{ + u8_t * const flags = get_header_offset(m_flags_offset, sizeof(u8_t)); + if (flags != 0) + { + if (vendor_specific == true) + { + *flags = static_cast((*flags) | m_flag_mask_vendor_specific_avp); + } + else + { + *flags = static_cast((*flags) & ~m_flag_mask_vendor_specific_avp); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); +} + +//----------------------------------------------------------------------------- + +/** + * This function sets the AVP mandatory flag. + */ +eap_status_e eap_diameter_avp_header_c::set_avp_flag_mandatory_avp(const bool mandatory) +{ + u8_t * const flags = get_header_offset(m_flags_offset, sizeof(u8_t)); + if (flags != 0) + { + if (mandatory == true) + { + *flags = static_cast((*flags) | m_flag_mask_mandatory_avp); + } + else + { + *flags = static_cast((*flags) & ~m_flag_mask_mandatory_avp); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); +} + +//----------------------------------------------------------------------------- + +/** + * This function sets the AVP mandatory flag. + */ +eap_status_e eap_diameter_avp_header_c::set_avp_flags_reserved() +{ + u8_t * const flags = get_header_offset(m_flags_offset, sizeof(u8_t)); + if (flags != 0) + { + *flags = static_cast(((*flags) & ~m_flag_mask_reserved_avp) | 0ul); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); +} + +//----------------------------------------------------------------------------- + +/** + * This function sets the AVP data length. + */ +eap_status_e eap_diameter_avp_header_c::set_data_length(const u32_t p_length) +{ + u8_t * const length_data = get_header_offset(m_length_offset, 3ul*sizeof(u8_t)); + if (length_data != 0) + { + return EAP_STATUS_RETURN( + m_am_tools, + eap_write_u24_t_network_order( + length_data, + 3ul*sizeof(u8_t), + p_length)); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); +} + +//----------------------------------------------------------------------------- + +/** + * This function resets the AVP header. + */ +eap_status_e eap_diameter_avp_header_c::reset_header(const u16_t data_length) +{ + eap_status_e status = set_avp_code(eap_diameter_avp_code_none); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_avp_flag_vendor_specific(false); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_avp_flag_mandatory_avp(false); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_avp_flags_reserved(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = set_data_length(data_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//----------------------------------------------------------------------------- +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/diameter/src/eap_diameter_payloads.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/diameter/src/eap_diameter_payloads.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,606 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 588 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_diameter_payloads.h" +#include "eap_diameter_avp_header.h" +#include "abs_eap_am_tools.h" +#include "eap_tools.h" +#include "eap_array_algorithms.h" + + +EAP_FUNC_EXPORT eap_diameter_variable_data_c::~eap_diameter_variable_data_c() +{ +} + +EAP_FUNC_EXPORT eap_diameter_variable_data_c::eap_diameter_variable_data_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_data(tools) + , m_payload_code(eap_diameter_avp_code_none) + , m_is_mandatory(false) +{ +} + +EAP_FUNC_EXPORT eap_status_e eap_diameter_variable_data_c::set_buffer( + const eap_diameter_avp_code_c current_payload, + const bool is_mandatory, + const u8_t * const buffer, + const u32_t buffer_length, + const bool free_buffer, + const bool is_writable) +{ + eap_status_e status = m_data.set_buffer( + buffer, + buffer_length, + free_buffer, + is_writable); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_payload_code = current_payload; + + m_is_mandatory = is_mandatory; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e eap_diameter_variable_data_c::add_data( + const u8_t * const buffer, + const u32_t buffer_length) +{ + eap_status_e status = m_data.add_data( + buffer, + buffer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT u32_t eap_diameter_variable_data_c::get_data_length() const +{ + return m_data.get_data_length(); +} + +EAP_FUNC_EXPORT u8_t * eap_diameter_variable_data_c::get_data( + const u32_t data_length) const +{ + return m_data.get_data(data_length); +} + +EAP_FUNC_EXPORT eap_variable_data_c * eap_diameter_variable_data_c::get_payload_buffer() +{ + return &m_data; +} + +EAP_FUNC_EXPORT eap_diameter_avp_code_c eap_diameter_variable_data_c::get_payload_code() const +{ + return m_payload_code; +} + +EAP_FUNC_EXPORT bool eap_diameter_variable_data_c::get_is_mandatory() const +{ + return m_is_mandatory; +} + +EAP_FUNC_EXPORT void eap_diameter_variable_data_c::set_payload_code( + const eap_diameter_avp_code_c code) +{ + m_payload_code = code; +} + +EAP_FUNC_EXPORT eap_diameter_variable_data_c * eap_diameter_variable_data_c::copy() const +{ + eap_diameter_variable_data_c * new_data = new eap_diameter_variable_data_c(m_am_tools); + + if (new_data != 0) + { + eap_status_e status = new_data->get_payload_buffer()->add_data(&m_data); + if (status != eap_status_ok) + { + delete new_data; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + new_data->set_payload_code(get_payload_code()); + } + + return new_data; +} + +EAP_FUNC_EXPORT void eap_diameter_variable_data_c::object_increase_reference_count() +{ +} + + + +EAP_FUNC_EXPORT eap_diameter_payloads_c::~eap_diameter_payloads_c() +{ +} + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +EAP_FUNC_EXPORT eap_diameter_payloads_c::eap_diameter_payloads_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_payload_map(tools, this) + , m_read_payloads(tools) + , m_is_valid(false) +{ + m_is_valid = true; +} + +EAP_FUNC_EXPORT eap_diameter_variable_data_c * eap_diameter_payloads_c::get_payload( + const eap_diameter_avp_code_c current_payload) +{ + eap_variable_data_c selector(m_am_tools); + + eap_status_e status = selector.set_buffer( + ¤t_payload, + sizeof(current_payload), + false, + false); + if (status != eap_status_ok) + { + return 0; + } + + eap_diameter_variable_data_c *payload = m_payload_map.get_handler(&selector); + + return payload; +} + + +EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::check_payloads_existense( + EAP_TEMPLATE_CONST eap_array_c * const needed_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + for (u32_t ind = 0ul; ind < needed_payloads->get_object_count(); ind++) + { + const eap_diameter_avp_code_c * const required_avp_code = needed_payloads->get_object(ind); + if (required_avp_code == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (get_payload(*required_avp_code) == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("not received AVP 0x%08x:0x%08x.\n"), + required_avp_code->get_vendor_id(), + required_avp_code->get_vendor_code())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::check_mandatory_payloads( + EAP_TEMPLATE_CONST eap_array_c * const used_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + for (u32_t ind = 0ul; ind < m_read_payloads.get_object_count(); ind++) + { + const eap_diameter_variable_data_c * const read_payload = m_read_payloads.get_object(ind); + if (read_payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (read_payload->get_is_mandatory() == true) + { + eap_diameter_avp_code_c code = read_payload->get_payload_code(); + + i32_t index = find_simple( + used_payloads, + &code, + m_am_tools); + if (index < 0ul) + { + // ERROR: not used mandatory AVP. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DIAMETER_ERROR, + (EAPL("ERROR: not used mandatory AVP 0x%08x:0x%08x.\n"), + code.get_vendor_id(), + code.get_vendor_code())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unsupported_payload); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::add_payload( + const eap_diameter_avp_code_c current_payload, + const bool is_mandatory, + const u8_t * const data, + const u32_t data_length, + const bool free_buffer, + const bool is_writable, + const bool fragments_allowed) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + eap_diameter_variable_data_c *payload = get_payload( + current_payload); + if (payload != 0) + { + if (fragments_allowed == true) + { + // Add fragment to the end of the existing payload. + status = payload->add_data(data, data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Cannot add fragment. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + else + { + eap_variable_data_c selector(m_am_tools); + + status = selector.set_buffer( + ¤t_payload, + sizeof(current_payload), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_diameter_variable_data_c *payload = new eap_diameter_variable_data_c( + m_am_tools); + if (payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payload->set_buffer( + current_payload, + is_mandatory, + data, + data_length, + free_buffer, + is_writable); + if (status != eap_status_ok) + { + delete payload; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_payload_map.add_handler(&selector, payload); + if (status != eap_status_ok) + { + delete payload; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Note the same payload object is added to m_read_payloads as to m_payload_map. + status = m_read_payloads.add_object(payload, false); + if (status != eap_status_ok) + { + // Note we do not delete payload here, because it has been added alredy to m_payload_map. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +EAP_FUNC_EXPORT bool eap_diameter_payloads_c::get_is_valid() const +{ + return m_is_valid; +} + + +//-------------------------------------------------- + +//eap_diameter_payloads_c +EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::parse_generic_payload( + const eap_diameter_avp_code_c payload_type, + const eap_diameter_avp_header_c * const payload) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_DIAMETER_TRACE_PAYLOAD("Parsing payload", payload); + + eap_status_e status(eap_status_process_general_error); + + /* + * AVP-header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AVP Code | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |V|M|r r r r r r| AVP Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Vendor-ID (optional) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Data .... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (payload->get_length() < payload->get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DIAMETER_ERROR, + (EAPL("ERROR: eap_diameter_payloads_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%08x:0x%08x=%s, required length 0x%08x, packet length too less 0x%08x.\n"), + payload, + payload_type.get_vendor_id(), + payload_type.get_vendor_code(), + payload->get_avp_code_string(), + payload->get_header_length(), + payload->get_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u32_t data_length = payload->get_data_length(); + + u8_t * const data + = static_cast(payload->get_data_offset(0ul, data_length)); + + if (data == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DIAMETER_ERROR, + (EAPL("ERROR: eap_diameter_payloads_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%08x:0x%08x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, + payload_type.get_vendor_id(), + payload_type.get_vendor_code(), + payload->get_avp_code_string(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = add_payload( + payload_type, + payload->get_avp_flag_mandatory_avp(), + data, + data_length, + false, + false, + true); // This can be fragmented. + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::parse_diameter_payloads( + const eap_diameter_avp_header_c * const p_payload, + u32_t * const buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_diameter_avp_header_c payload( + m_am_tools, + p_payload->get_header_buffer(*buffer_length), + *buffer_length); // Const correctness is gone. + + eap_diameter_avp_code_c current_payload = payload.get_avp_code(); + + eap_status_e status = eap_status_header_corrupted; + + if (payload.get_is_valid() == true + && current_payload != eap_diameter_avp_code_none) + { + if (*buffer_length < payload.get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DIAMETER_ERROR, + (EAPL("ERROR: eap_diameter_payloads_c::parse_diameter_payloads(0x%08x): ") + EAPL("current payload 0x%08x:0x%08x=%s, data length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload.get_vendor_id(), + current_payload.get_vendor_code(), + payload.get_avp_code_string(), + payload.get_data_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DIAMETER_ERROR, + (EAPL("ERROR: eap_diameter_payloads_c::parse_diameter_payloads(): ") + EAPL("DIAMETER-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t prev_avp_length = payload.get_length() + payload.get_padding_length(); + if (*buffer_length < prev_avp_length) + { + // We do have only the current payload. So not padding is included. + prev_avp_length = payload.get_length(); + } + + EAP_ASSERT_ALWAYS(*buffer_length >= prev_avp_length); + *buffer_length -= prev_avp_length; + + while(*buffer_length >= payload.get_header_length() + && payload.get_is_valid() == true + && payload.get_header_buffer_length() >= payload.get_length()) + { + payload.set_header_buffer( + payload.get_next_header(), + payload.get_header_buffer_length() - prev_avp_length); + if (payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + current_payload = payload.get_avp_code(); + + if (*buffer_length < payload.get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DIAMETER_ERROR, + (EAPL("ERROR: eap_diameter_payloads_c::parse_diameter_payloads(0x%08x): ") + EAPL("current payload 0x%08x:0x%08x=%s, payload data length 0x%04x, payload length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload.get_vendor_id(), + current_payload.get_vendor_code(), + payload.get_avp_code_string(), + payload.get_data_length(), + payload.get_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DIAMETER_ERROR, + (EAPL("ERROR: eap_diameter_payloads_c::parse_diameter_payloads(): ") + EAPL("DIAMETER-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + prev_avp_length = payload.get_length() + payload.get_padding_length(); + if (*buffer_length < prev_avp_length) + { + // We do have only the current payload. So not padding is included. + prev_avp_length = payload.get_length(); + } + + EAP_ASSERT_ALWAYS(*buffer_length >= prev_avp_length); + *buffer_length -= prev_avp_length; + } + } + + if (*buffer_length != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DIAMETER_ERROR, + (EAPL("ERROR: eap_diameter_payloads_c::parse_diameter_payloads(): ") + EAPL("DIAMETER-header is corrupted. Buffer length and payload ") + EAPL("length does not match. %lu illegal bytes.\n"), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_diameter_payloads_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_payload_map.reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_read_payloads.reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/diameter/src/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/diameter/src/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,30 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_gsmsim + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_client.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_payloads.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_server.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_state.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_state_notification.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_header.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_initialized.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_mac_attributes.cpp + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_gsmsim_simulator.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_testing_tools.$(LIB) \ + -lstdc++ + +# $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_dummy_sim.$(LIB) \ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/eap_type_all.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/eap_type_all.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,694 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 75 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_type_all.h" + +#if defined(USE_EAP_TYPE_GSMSIM) + #include "eap_type_gsmsim.h" + #include "eap_am_type_gsmsim.h" +#endif +#if defined(USE_AKA_EAP_TYPE) + #include "eap_type_aka.h" +#endif +#if defined(USE_MSCHAPV2_EAP_TYPE) + #include "eap_type_mschapv2.h" +#endif +#if defined(USE_SECURID_EAP_TYPE) + #include "eap_type_securid.h" +#endif +#if defined(USE_LEAP_EAP_TYPE) + #include "eap_type_leap.h" +#endif +#if defined(USE_TLS_EAP_TYPE) || defined(USE_PEAP_EAP_TYPE) + #include "eap_type_tls_peap.h" + #include "tls_base_record.h" + #include "tls_record.h" + #include "tls_application_eap_core.h" + #include "eap_am_type_tls_peap.h" + #include "tls_am_services.h" + #include "eap_core.h" +#endif +#if defined(USE_FAST_EAP_TYPE) + #include "eap_type_tls_peap.h" + #include "tls_base_record.h" + #include "tls_record.h" + #include "tls_application_eap_fast.h" + #include "eap_am_type_tls_peap.h" + #include "tls_am_services.h" + #include "eap_core.h" +#endif +#if defined(USE_SAESIM_EAP_TYPE) + #include "eap_type_saesim_core.h" +#endif +#if defined(USE_DUMMY_SIM_EAP_TYPE) + #include "eap_type_dummy_sim.h" +#endif +#if defined(USE_EAP_SIMPLE_CONFIG) + #include "simple_config_am_services.h" + #include "eap_am_type_simple_config.h" + #include "simple_config_base_record.h" + #include "simple_config_record.h" + #include "eap_type_simple_config.h" +#endif //#if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +// +EAP_C_FUNC_EXPORT eap_base_type_c * const new_eap_type( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const eap_type_value_e eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if) +{ + EAP_TRACE_BEGIN(tools, TRACE_FLAGS_DEFAULT); + eap_base_type_c *type = 0; + + if (tools == 0) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_type(): parameter tools is NULL.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + if (partner == 0) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_type(): parameter partner is NULL.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + if (receive_network_id == 0 + || receive_network_id->get_source() == 0 + || receive_network_id->get_destination() == 0) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_type(): parameter receive_network_id is NULL.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT_ANYWAY_TOOLS(tools); + return 0; + } + +#if defined(USE_EAP_TYPE_GSMSIM) + if (eap_type == eap_type_gsmsim) + { + eap_am_type_gsmsim_c * am_type_gsmsim = ::new_eap_am_type_gsmsim( + tools, + partner, + is_client_when_true, + receive_network_id); // Note this function is defined in the platform AM DLL. + if (am_type_gsmsim == 0 + || am_type_gsmsim->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_type(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + type = new eap_type_gsmsim_c( + tools, + partner, + am_type_gsmsim, + true, + is_client_when_true, + receive_network_id); + } + else +#endif //#if defined(USE_EAP_TYPE_GSMSIM) +#if defined(USE_AKA_EAP_TYPE) + if (eap_type == eap_type_aka) + { + eap_am_type_aka_c * am_type_aka = ::new_eap_am_type_aka( + tools, + partner, + is_client_when_true, + receive_network_id); // Note this function is defined in the platform AM DLL. + if (am_type_aka == 0 + || am_type_aka->get_is_valid() == false) + { + delete am_type_aka; + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_type(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + type = new eap_type_aka_c( + tools, + partner, + am_type_aka, + true, + is_client_when_true, + receive_network_id); + } + else +#endif //#if defined(USE_AKA_EAP_TYPE) +#if defined(USE_MSCHAPV2_EAP_TYPE) + if (eap_type == eap_type_mschapv2) + { + eap_am_type_mschapv2_c * am_type_mschapv2 + = ::new_eap_am_type_mschapv2( + tools, + partner, + receive_network_id); // Note this function is defined in the platform AM DLL. + if (am_type_mschapv2 == 0 + || am_type_mschapv2->get_is_valid() == false) + { + delete am_type_mschapv2; + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_type(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + type = new eap_type_mschapv2_c( + tools, + partner, + am_type_mschapv2, + true, + is_client_when_true, + receive_network_id); + } + else +#endif //#if defined(USE_MSCHAPV2_EAP_TYPE) +#if defined(USE_SECURID_EAP_TYPE) + if (eap_type == eap_type_generic_token_card) + { + eap_am_type_securid_c * am_type_securid + = ::new_eap_am_type_securid( + tools, + partner, + eap_type, + receive_network_id); // Note this function is defined in the platform AM DLL. + if (am_type_securid == 0 + || am_type_securid->get_is_valid() == false) + { + delete am_type_securid; + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_type(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + type = new eap_type_securid_c( + tools, + partner, + am_type_securid, + true, + eap_type, + is_client_when_true, + receive_network_id); + } + else +#endif //#if defined(USE_SECURID_EAP_TYPE) +#if defined(USE_LEAP_EAP_TYPE) + if (eap_type == eap_type_leap) + { + eap_am_type_leap_c * am_type_leap + = ::new_eap_am_type_leap( + tools, + partner, + is_client_when_true, + receive_network_id); // Note this function is defined in the platform AM DLL. + if (am_type_leap == 0 + || am_type_leap->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_type(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + type = new eap_type_leap_c( + tools, + partner, + am_type_leap, + true, + is_client_when_true, + receive_network_id); + } + else +#endif //#if defined(USE_LEAP_EAP_TYPE) +#if defined(USE_TLS_EAP_TYPE) + if (eap_type == eap_type_tls) + { + eap_am_type_tls_peap_c * am_type_tls_peap + = ::new_eap_am_type_tls_peap( + tools, + partner, + eap_type, + is_client_when_true, + receive_network_id); // Note this function is defined in the platform AM DLL. + if (am_type_tls_peap == 0 + || am_type_tls_peap->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_am_type_tls_peap(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + tls_base_record_c * const tls_record + = new tls_record_c( + tools, + am_type_tls_peap, + false, + 0, + false, + is_client_when_true, + eap_type, + receive_network_id); + if (tls_record == 0 + || tls_record->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_am_type_tls_peap(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + type = new eap_type_tls_peap_c( + tools, + partner, + am_type_tls_peap, + true, + tls_record, + true, + is_client_when_true, + eap_type, + receive_network_id); + } + else +#endif //#if defined(USE_TLS_EAP_TYPE) +#if defined(USE_PEAP_EAP_TYPE) + if (eap_type == eap_type_peap) + { + eap_am_type_tls_peap_c * am_type_tls_peap + = ::new_eap_am_type_tls_peap( + tools, + partner, + eap_type, + is_client_when_true, + receive_network_id); // Note this function is defined in the platform AM DLL. + if (am_type_tls_peap == 0 + || am_type_tls_peap->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_am_type_tls_peap(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + eap_core_c * const eap_core + = new eap_core_c( + tools, + 0, + is_client_when_true, + receive_network_id, + true); + if (eap_core == 0 + || eap_core->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new eap_core_c(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + tls_base_application_c * const application + = new tls_application_eap_core_c( + tools, + eap_core, + true, + is_client_when_true, + eap_type, + receive_network_id); + if (application == 0 + || application->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new tls_application_eap_core_c(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + tls_base_record_c * const tls_record + = new tls_record_c( + tools, + am_type_tls_peap, + false, + application, + true, + is_client_when_true, + eap_type, + receive_network_id); + if (tls_record == 0 + || tls_record->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_am_type_tls_peap(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + type = new eap_type_tls_peap_c( + tools, + partner, + am_type_tls_peap, + true, + tls_record, + true, + is_client_when_true, + eap_type, + receive_network_id); + } + else +#endif //#if defined(USE_PEAP_EAP_TYPE) +#if defined(USE_TTLS_EAP_TYPE) + if (eap_type == eap_type_ttls) + { + eap_am_type_tls_peap_c * am_type_tls_ttls + = ::new_eap_am_type_tls_peap( + tools, + partner, + eap_type, + is_client_when_true, + receive_network_id); // Note this function is defined in the platform AM DLL. + if (am_type_tls_ttls == 0 + || am_type_tls_ttls->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_am_type_tls_peap(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + eap_core_c * const eap_core + = new eap_core_c( + tools, + 0, + is_client_when_true, + receive_network_id, + true); + if (eap_core == 0 + || eap_core->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new eap_core_c(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + tls_base_application_c * const application + = new tls_application_eap_core_c( + tools, + eap_core, + true, + is_client_when_true, + eap_type, + receive_network_id); + if (application == 0 + || application->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new tls_application_eap_core_c(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + tls_base_record_c * const tls_record + = new tls_record_c( + tools, + am_type_tls_ttls, + false, + application, + true, + is_client_when_true, + eap_type, + receive_network_id); + if (tls_record == 0 + || tls_record->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_am_type_tls_peap(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + type = new eap_type_tls_peap_c( + tools, + partner, + am_type_tls_ttls, + true, + tls_record, + true, + is_client_when_true, + eap_type, + receive_network_id); + } + else +#endif //#if defined(USE_TTLS_EAP_TYPE) +#if defined(USE_SAESIM_EAP_TYPE) + if (eap_type == eap_type_saesim) + { + type = new eap_type_saesim_core_c(tools, partner, is_client_when_true); + } + else +#endif +#if defined(USE_DUMMY_SIM_EAP_TYPE) + if (eap_type == eap_type_sim) + { + type = new eap_type_dummy_sim_c(tools, partner, is_client_when_true); + } + else +#endif +#if defined(USE_EAP_EXPANDED_TYPES) +#if defined(USE_EAP_SIMPLE_CONFIG) + if (eap_type == eap_expanded_type_simple_config.get_type()) + { + eap_am_type_simple_config_c * am_type_simple_config + = ::new_eap_am_type_simple_config( + tools, + partner, + eap_type, + is_client_when_true, + receive_network_id, + configuration_if); // Note this function is defined in the platform AM DLL. + if (am_type_simple_config == 0 + || am_type_simple_config->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_am_type_simple_config(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + simple_config_base_record_c * const simple_config_record + = new simple_config_record_c( + tools, + am_type_simple_config, + false, + is_client_when_true, + receive_network_id); + if (simple_config_record == 0 + || simple_config_record->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: simple_config_record_c(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + type = new eap_type_simple_config_c( + tools, + partner, + am_type_simple_config, + true, + simple_config_record, + true, + is_client_when_true, + eap_type, + receive_network_id); + } + else +#endif //#if defined(USE_EAP_SIMPLE_CONFIG) +#endif //#if defined(USE_EAP_EXPANDED_TYPES) +#if defined(USE_FAST_EAP_TYPE) + if (eap_type == eap_type_fast) + { + eap_am_type_tls_peap_c * am_type_tls_peap + = ::new_eap_am_type_tls_peap( + tools, + partner, + eap_type, + is_client_when_true, + receive_network_id); // Note this function is defined in the platform AM DLL. + if (am_type_tls_peap == 0 + || am_type_tls_peap->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_am_type_tls_peap(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + eap_core_c * const eap_core + = new eap_core_c( + tools, + 0, + is_client_when_true, + receive_network_id, + true); + if (eap_core == 0 + || eap_core->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new eap_core_c(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + tls_base_application_c * const application + = new tls_application_eap_fast_c( + tools, + eap_core, + true, + is_client_when_true, + eap_type, + receive_network_id, + am_type_tls_peap); + if (application == 0 + || application->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new tls_application_eap_core_c(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + tls_base_record_c * const tls_record + = new tls_record_c( + tools, + am_type_tls_peap, + false, + application, + true, + is_client_when_true, + eap_type, + receive_network_id); + if (tls_record == 0 + || tls_record->get_is_valid() == false) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_am_type_tls_peap(): failed.\n"))); + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + type = new eap_type_tls_peap_c( + tools, + partner, + am_type_tls_peap, + true, + tls_record, + true, + is_client_when_true, + eap_type, + receive_network_id); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + EAP_TRACE_ERROR( + tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: new_eap_type(): EAP-type=0x%08x not supported in this module.\n"), + convert_eap_type_to_u32_t(eap_type))); + } + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return type; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,6838 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 77 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_type_gsmsim.h" +#include "eap_type_gsmsim_header.h" +#include "eap_type_gsmsim_payloads.h" +#include "eap_type_gsmsim_mac_attributes.h" +#include "abs_eap_am_type_gsmsim.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" +#include "abs_eap_am_mutex.h" +#include "eap_automatic_variable.h" +#include "eap_am_type_gsmsim.h" + + +//-------------------------------------------------- + +/** @file */ + +// +EAP_FUNC_EXPORT eap_type_gsmsim_c::~eap_type_gsmsim_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::~eap_type_gsmsim_c(): this = 0x%08x => 0x%08x\n"), + this, + dynamic_cast(this))); + + EAP_ASSERT(m_shutdown_was_called == true); + + if (m_free_am_type_gsmsim == true + && m_am_type_gsmsim != 0) + { + delete m_am_type_gsmsim; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +// +EAP_FUNC_EXPORT eap_type_gsmsim_c::eap_type_gsmsim_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + eap_am_type_gsmsim_c * const am_type_gsmsim, + const bool free_am_type_gsmsim, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) + : eap_base_type_c(tools, partner) + , m_am_tools(tools) + , m_state(eap_type_gsmsim_state_none) + , m_saved_previous_state(eap_type_gsmsim_state_none) + , m_send_network_id(m_am_tools) + , m_nonce_mt(m_am_tools) + , m_nonce_s(m_am_tools) + , m_IV(m_am_tools) + , m_saved_EAP_packet(m_am_tools) + , m_XKEY(m_am_tools) + , m_K_encr(m_am_tools) + , m_K_aut(m_am_tools) + , m_master_session_key(m_am_tools, eap_type_gsmsim) + , m_IMSI(m_am_tools) + , m_pseudonym(m_am_tools) + , m_reauthentication_identity(m_am_tools) + , m_automatic_realm(m_am_tools) + , m_automatic_realm_read(false) + , m_identity(m_am_tools) + , m_NAI(m_am_tools) + , m_n_rands(m_am_tools) + , m_n_sres(m_am_tools) + , m_gsmsim_version_list(m_am_tools) +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + , m_triplets(0) +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + , m_reauthentication_counter(0u) + , m_include_identity_to_start_response(gsmsim_payload_NONE) + , m_start_response_includes_identity(gsmsim_payload_NONE) + , m_failure_message_received(false) + , m_authentication_finished_successfully(false) + , m_last_eap_identifier(0) + , m_gsmsim_selected_version(GSMSIM_ILLEGAL_VERSION) + , m_2_digit_mnc_map_of_mcc_of_imsi_array(tools) + , m_uma_automatic_realm_prefix(tools) + , m_use_uma_profile(false) + , m_am_type_gsmsim(am_type_gsmsim) +#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + , m_nonce_mt_file(tools) +#endif //#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + , m_manual_username(tools) + , m_manual_realm(tools) + , m_gsmsim_header_offset(0u) + , m_MTU(0u) + , m_trailer_length(0u) + , m_minimum_rand_count(EAP_TYPE_GSMSIM_DEFAULT_MINIMUM_RAND_COUNT) + , m_length_of_mnc(EAP_TYPE_GSMSIM_DEFAULT_MNC_LENGTH_3_BYTES) + , m_authentication_type(GSMSIM_AUTHENTICATION_TYPE_NONE) + , m_identity_type(GSMSIM_IDENTITY_TYPE_NONE) + , m_client_error_code(eap_gsmsim_client_error_code_none) + , m_gsmsim_notification_code(eap_gsmsim_notification_none) + , m_failure_message_delay_time(EAP_TYPE_GSMSIM_TIMER_TIMEOUT_VALUE_DELAY_FAILURE_MESSAGE_SENT) + , m_is_valid(false) + , m_is_client(is_client_when_true) + , m_wait_eap_success_packet(true) + , m_check_identifier_of_eap_identity_response(false) + , m_free_am_type_gsmsim(free_am_type_gsmsim) +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + , m_client_responds_retransmitted_packets(false) +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + , m_gsmsim_test_version(false) + , m_gsmsim_randomly_refuse_eap_identity(false) + , m_check_nai_realm(false) + , m_fail_reauthentication_counter_check(false) + , m_accept_eap_identity_response(true) + , m_use_random_identity_on_eap_identity_response(false) + , m_shutdown_was_called(false) + , m_reset_was_called(false) + , m_do_rand_uniqueness_check(true) + , m_use_pseudonym_identity(true) + , m_use_reauthentication_identity(true) + , m_erroneus_packet_received(false) + , m_sim_notification_packet_received(false) + , m_use_manual_username(false) + , m_use_manual_realm(false) + , m_randomly_fail_successfull_authentication(false) + , m_allow_use_result_indication(true) + , m_use_result_indication(false) + , m_use_eap_expanded_type(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::eap_type_gsmsim_c(): this = 0x%08x => 0x%08x, ") + EAPL("partner 0x%08x, type partner 0x%08x, compiled %s %s\n"), + this, + dynamic_cast(this), + partner, + get_type_partner(), + __DATE__, + __TIME__)); + + // This is the only supported version. + m_supported_versions[0] = GSMSIM_VERSION_1; + + if (m_am_type_gsmsim == 0) + { + // Something wrong with AM. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + m_am_type_gsmsim->set_am_partner(this); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + + initialize_state(eap_type_gsmsim_state_pending_kc_sres_query, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Challenge, // Re-transmitted EAP-Request/SIM/Challenge is allowed. + gsmsim_subtype_NONE, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_pending_triplet_query, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Start, // Note EAP-Response/SIM/Start message is allowed here, eap_type_gsmsim_c::handle_start_response_message() will drop EAP-Response/SIM/Start message quietly. + gsmsim_subtype_Client_Error, + gsmsim_subtype_Challenge); // Re-transmitted EAP-Response/SIM/Challenge is allowed. + + initialize_state(eap_type_gsmsim_state_waiting_for_start_request, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Start, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_pseydonym_waiting_for_start_request, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Start, + gsmsim_subtype_Re_authentication, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_imsi_waiting_for_start_request, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Start, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_waiting_for_start_response, true, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Start, + gsmsim_subtype_Client_Error, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_waiting_for_notification_request_success, false, true, + gsmsim_subtype_Notification, + gsmsim_subtype_Challenge, + gsmsim_subtype_Re_authentication, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_waiting_for_notification_response_failure, true, false, + gsmsim_subtype_Notification, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_waiting_for_notification_response_success, true, false, + gsmsim_subtype_Notification, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity, true, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Start, + gsmsim_subtype_Client_Error, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity, true, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Start, + gsmsim_subtype_Client_Error, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity, true, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Start, + gsmsim_subtype_Client_Error, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_analyse_start_request, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_waiting_for_challenge_request, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Challenge, + gsmsim_subtype_Start, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_waiting_for_challenge_response, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Challenge, + gsmsim_subtype_Start, + gsmsim_subtype_Client_Error); + + initialize_state(eap_type_gsmsim_state_waiting_for_reauth_request, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Re_authentication, + gsmsim_subtype_Start, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_waiting_for_reauth_response, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Re_authentication, + gsmsim_subtype_Start, + gsmsim_subtype_Client_Error); + + initialize_state(eap_type_gsmsim_state_success, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Challenge, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_waiting_for_success, false, false, + gsmsim_subtype_Notification, + gsmsim_subtype_Challenge, + gsmsim_subtype_Re_authentication, + gsmsim_subtype_NONE); + + initialize_state(eap_type_gsmsim_state_failure, false, false, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE, + gsmsim_subtype_NONE); + +#endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + eap_status_e status = m_send_network_id.set_copy_of_network_id(&send_network_id); + + if (status != eap_status_ok + || m_send_network_id.get_is_valid_data() == false) + { + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//----------------------------------------------- + +#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + +// +void eap_type_gsmsim_c::initialize_state( + const eap_type_gsmsim_state_variable_e state, + const bool must_be_initiator, + const bool must_be_responder, + const gsmsim_subtype_e type0, + const gsmsim_subtype_e type1, + const gsmsim_subtype_e type2, + const gsmsim_subtype_e type3) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_parameters[(state)].init_state(must_be_initiator, must_be_responder, + type0, type1, type2, type3); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +#endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + +//-------------------------------------------------- + +/** + * This function stores the last encryption IV. In CBC-mode previous encrypted block is + * used as a IV of next block. + */ +eap_status_e eap_type_gsmsim_c::store_last_encryption_iv(const eap_variable_data_c * const encryption_IV) +{ + return m_IV.get_payload_buffer()->set_copy_of_buffer(encryption_IV); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_gsmsim_version eap_type_gsmsim_c::select_version( + const gsmsim_variable_data_c * const version_payload, + bool * const includes_other_version_than_1) +{ + u32_t version_payload_length = version_payload->get_original_header()->get_data_length(); + u32_t real_payload_length = version_payload->get_original_header()->get_reserved(); + eap_gsmsim_version selected_version = GSMSIM_ILLEGAL_VERSION; + + if (real_payload_length == 0 + || real_payload_length > version_payload_length) + { + return GSMSIM_ILLEGAL_VERSION; + } + + u32_t version_count = real_payload_length/sizeof(u16_t); + u16_t *payload_version_list = reinterpret_cast(version_payload->get_original_header()->get_data(real_payload_length)); + + for (u32_t ind = 0u; ind < version_count; ind++) + { + u8_t * const payload_version_network_order = reinterpret_cast(&(payload_version_list[ind])); + u16_t payload_version_host_order + = eap_read_u16_t_network_order(payload_version_network_order, sizeof(u16_t)); + if (payload_version_host_order == static_cast(GSMSIM_VERSION_1)) + { + selected_version = static_cast(payload_version_host_order); + } + else if (payload_version_host_order != static_cast(GSMSIM_VERSION_1)) + { + *includes_other_version_than_1 = true; + } + } + + return selected_version; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_gsmsim_c::get_identity_string(const eap_type_gsmsim_identity_type identity_type) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(identity_type, GSMSIM_IDENTITY_TYPE_NONE) + else EAP_IF_RETURN_STRING(identity_type, GSMSIM_IDENTITY_TYPE_IMSI_ID) + else EAP_IF_RETURN_STRING(identity_type, GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID) + else EAP_IF_RETURN_STRING(identity_type, GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(identity_type); + return EAPL("Unknown AKA identity"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_gsmsim_c::get_state_string(eap_type_gsmsim_state_variable_e state) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_identity_request) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_pending_identity_query) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_start_request) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_imsi_waiting_for_start_request) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_pseydonym_waiting_for_start_request) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyse_start_request) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_challenge_request) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyses_challenge_request) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_pending_kc_sres_query) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_success) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_reauth_request) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyses_reauthentication_request) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_pending_pseudonym_decode_query) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_identity_response) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_start_response) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_challenge_response) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_pending_triplet_query) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyses_challenge_response) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyses_start_response) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_notification_request_success) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_notification_response_failure) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_notification_response_success) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_reauth_response) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyses_reauthentication_response) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_success) + else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_failure) + else +#else +EAP_UNREFERENCED_PARAMETER(state); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown GSMSIM state"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_gsmsim_c::get_state_string() const +{ + return get_state_string(m_state); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_gsmsim_c::get_saved_previous_state_string() const +{ + return get_state_string(m_saved_previous_state); +} + +//-------------------------------------------------- + +/** + * This function sets the new state and notifies the lower layer of this change. + */ +void eap_type_gsmsim_c::set_state(eap_type_gsmsim_state_variable_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_type_gsmsim_state_variable_e previous_state = m_state; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::set_state(): old state %d=%s\n"), + m_state, + get_state_string())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::set_state(): new state %d=%s\n"), + state, + get_state_string(state))); + + m_state = state; + + eap_type_gsmsim_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap_type, + eap_type_gsmsim, + previous_state, + state, + m_last_eap_identifier, + false); + state_notification(¬ification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + +/** + * This function checks the valid states. + */ +bool eap_type_gsmsim_c::verify_states( + const eap_type_gsmsim_state_variable_e * const valid_states, + const u32_t count) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + for (u32_t ind = 0ul; ind < count; ind++) + { + if (m_state == valid_states[ind]) + { + return true; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; +} + +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + +//-------------------------------------------------- + +#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::check_valid_state(gsmsim_subtype_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + const eap_type_gsmsim_state_variable_parameters_c * const state_variable = get_state_variable(); + + if (state_variable == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_gsmsim_state); + } + + if (state_variable->check_initiator(!get_is_client()) == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_state_c::check_valid_state(): Initiator type %d is wrong in eap_type_gsmsim_state_variable_e %d=%s.\n"), + get_is_client(), m_state, get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_gsmsim_state); + } + + if (state_variable->check_valid_types(type) == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_state_c::check_valid_state(): gsmsim_subtype_e %d is wrong in eap_type_gsmsim_state_variable_e %d=%s.\n"), + type, m_state, get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_subtype); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + +//-------------------------------------------------- + +#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + +EAP_FUNC_EXPORT const eap_type_gsmsim_state_variable_parameters_c * eap_type_gsmsim_c::get_state_variable() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (m_state < eap_type_gsmsim_state_last_value) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &(m_parameters[m_state]); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } +} + +#endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + +//-------------------------------------------------- + +/** + * This function saves the current m_state to m_saved_previous_state. + * The saved state is restored in error case. + */ +void eap_type_gsmsim_c::save_current_state() +{ + m_saved_previous_state = m_state; +} + +//-------------------------------------------------- + +/** + * This function restores the saved state. + */ +void eap_type_gsmsim_c::restore_saved_previous_state() +{ + set_state(m_saved_previous_state); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::store_identity( + const eap_variable_data_c * const IMSI_or_pseudonym, + const bool IMSI_is_used) +{ + eap_status_e status = m_identity.init(IMSI_or_pseudonym->get_data_length()+1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_identity.set_is_valid(); + + if (IMSI_is_used == true) + { + // Note the first octet is reserved for IMSI prefix. + status = m_identity.set_copy_of_buffer(GSMSIM_IMSI_PREFIX_CHARACTER, 1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = m_identity.add_data(IMSI_or_pseudonym); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +/// not used: expansion_0 = prf(key, seed | 0) +/// not used: expansion_i = prf(key, expansion_i-1 | seed | i), where i = 1, 2... + +/// The following is from "DIGITAL SIGNATURE STANDARD (DSS)" FIPS PUB 186-2: +/// Let x be the signer's private key. The following may be used to generate m values of x: +/// Step 1. Choose a new, secret value for the seed-key, XKEY. +/// Step 2. In hexadecimal notation let +/// t = 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0. +/// This is the initial value for H0 || H1 || H2 || H3 || H4 in the SHS. +/// Step 3. For j = 0 to m - 1 do +/// a. XSEEDj = optional user input. +/// b. XVAL = (XKEY + XSEEDj) mod 2^b. +/// c. xj = G(t,XVAL) mod q. +/// d. XKEY = (1 + XKEY + xj) mod 2^b. +/// +/// Within GSMSIM the following parameters are used: +/// 160-bit XKEY and XVAL values are used, so b = 160. +/// XKEY = SHA1(n*Kc| NONCE_MT) +/// The optional user input values (XSEED_j) are set to zero. +/// xj = G(t, XVAL) + +/// Random generator become as follows: +/// Step 1. Choose a new, secret value for the seed-key, XKEY. +/// Step 2. In hexadecimal notation let +/// t = 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0. +/// This is the initial value for H0 || H1 || H2 || H3 || H4 in the SHS. +/// Step 3. For j = 0 to m - 1 do +/// c. xj = G(t,XKEY). +/// d. XKEY = (1 + XKEY + xj) mod 2^b. + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::data_exp( + const u32_t data_length, + eap_variable_data_c * const expansion, + const eap_variable_data_c * const key, + const eap_variable_data_c * const seed) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_UNREFERENCED_PARAMETER(seed); + + u32_t count = data_length/EAP_TYPE_GSMSIM_KEYMAT_SIZE; + if ((data_length % EAP_TYPE_GSMSIM_KEYMAT_SIZE) != 0) + { + ++count; + } + + status = expansion->init(count*EAP_TYPE_GSMSIM_KEYMAT_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + expansion->set_is_valid(); + expansion->set_data_length(count*EAP_TYPE_GSMSIM_KEYMAT_SIZE); + + status = m_am_tools->get_crypto()->dss_pseudo_random( + expansion->get_data(), + expansion->get_data_length(), + key->get_data(), + key->get_data_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::generate_shared_secred_keys( + const u32_t key_length, + const eap_variable_data_c * const n_Kc, + const eap_variable_data_c * const n_sres, + eap_variable_data_c * const XKEY, + eap_variable_data_c * const K_encr, + eap_variable_data_c * const K_aut, + eap_variable_data_c * const master_session_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(n_sres); + + u16_t selected_version = eap_htons(static_cast(m_gsmsim_selected_version)); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_shared_secred_keys():\n"))); + + if (m_NAI.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("full auth NAI"), + m_NAI.get_data(), + m_NAI.get_data_length())); + + if (n_Kc->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("n*Kc"), + n_Kc->get_data(), + n_Kc->get_data_length())); + + if (n_sres->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("n*SRES"), + n_sres->get_data(), + n_sres->get_data_length())); + + if (m_nonce_mt.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("NONCE MT"), + m_nonce_mt.get_data(), + m_nonce_mt.get_data_length())); + + if (m_gsmsim_version_list.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("version list"), + m_gsmsim_version_list.get_data(), + m_gsmsim_version_list.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("selected version"), + &selected_version, + sizeof(selected_version))); + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + // XKEY = SHA1(NAI | n*Kc | NONCE_MT | Version List | Selected Version) + + crypto_sha1_c sha1(m_am_tools); + + if (sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (sha1.hash_init() != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: generate_shared_secred_keys(): init() failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = sha1.hash_update( + m_NAI.get_data(), + m_NAI.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + n_Kc->get_data(), + n_Kc->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + m_nonce_mt.get_data(), + m_nonce_mt.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + m_gsmsim_version_list.get_data(), + m_gsmsim_version_list.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + reinterpret_cast(&selected_version), + sizeof(selected_version)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = XKEY->init(key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + XKEY->set_is_valid(); + XKEY->set_data_length(key_length); + + u32_t md_length = key_length; + + status = sha1.hash_final( + XKEY->get_data_offset(0u, key_length), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT_ALWAYS(md_length == key_length); + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_shared_secred_keys(): XKEY\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL(" XKEY"), + XKEY->get_data(), + XKEY->get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aes_key_length = m_am_tools->get_crypto()->aes_key_length(); + u32_t data_length = aes_key_length + EAP_TYPE_GSMSIM_MAC_SIZE + EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE; + + eap_variable_data_c expansion(m_am_tools); + eap_variable_data_c seed(m_am_tools); + + status = seed.add_data(&m_NAI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = data_exp( + data_length, + &expansion, + XKEY, + &seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_shared_secred_keys(): expansion\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("expansion"), + expansion.get_data(), + expansion.get_data_length())); + + u8_t *data = expansion.get_data_offset(0u, data_length); + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + const u8_t * const data_begin = data; + + EAP_UNREFERENCED_PARAMETER(data_begin); + + // K_encr, K_aut and master_session_key + + status = K_encr->set_copy_of_buffer(data, aes_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + data += aes_key_length; + EAP_ASSERT_ALWAYS(static_cast(data-data_begin) <= data_length); + + status = K_aut->set_copy_of_buffer(data, EAP_TYPE_GSMSIM_MAC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + data += EAP_TYPE_GSMSIM_MAC_SIZE; + EAP_ASSERT_ALWAYS(static_cast(data-data_begin) <= data_length); + + status = master_session_key->set_copy_of_buffer(data, EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + data += EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE; + EAP_ASSERT_ALWAYS(static_cast(data-data_begin) <= data_length); + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_shared_secred_keys(): K_encr\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL(" K_encr"), + K_encr->get_data(), + K_encr->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_shared_secred_keys(): K_aut\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL(" K_aut"), + K_aut->get_data(), + K_aut->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_shared_secred_keys(): master_session_key\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL(" MSK+EMSK"), + master_session_key->get_data(), + master_session_key->get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::generate_reauth_shared_secred_keys( + const u32_t key_length, + const eap_variable_data_c * const orig_XKEY, + const u32_t reauth_counter, + const eap_variable_data_c * const reauth_identity, + const eap_variable_data_c * const reauth_nonce_s, + eap_variable_data_c * const master_session_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + u16_t counter = eap_htons(static_cast(reauth_counter)); + eap_variable_data_c reauth_XKEY(m_am_tools); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("generate_reauth_shared_secred_keys():\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("reauth NAI"), + reauth_identity->get_data(), + reauth_identity->get_data_length())); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("reauth_counter"), + &counter, + sizeof(counter))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("NONCE_S"), + reauth_nonce_s->get_data(), + reauth_nonce_s->get_data_length())); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("orig_XKEY"), + orig_XKEY->get_data(), + orig_XKEY->get_data_length())); + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + // XKEY = SHA1(Identity|counter|NONCE_S|original XKEY) + + crypto_sha1_c sha1(m_am_tools); + + if (sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (sha1.hash_init() != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: generate_reauth_shared_secred_keys(): init() failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = sha1.hash_update( + reauth_identity->get_data(), + reauth_identity->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + &counter, + sizeof(counter)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + reauth_nonce_s->get_data(), + reauth_nonce_s->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + orig_XKEY->get_data(), + orig_XKEY->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = reauth_XKEY.init(key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + reauth_XKEY.set_is_valid(); + reauth_XKEY.set_data_length(key_length); + + u32_t md_length = key_length; + + status = sha1.hash_final( + reauth_XKEY.get_data_offset(0u, key_length), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT_ALWAYS(md_length == key_length); + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_reauth_shared_secred_keys(): reauth_XKEY\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("reauth_XKEY"), + reauth_XKEY.get_data(), + reauth_XKEY.get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t aes_key_length = m_am_tools->get_crypto()->aes_key_length(); + u32_t data_length = aes_key_length + EAP_TYPE_GSMSIM_MAC_SIZE + EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE; + + eap_variable_data_c expansion(m_am_tools); + eap_variable_data_c seed(m_am_tools); + + status = seed.add_data(&m_NAI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = data_exp( + data_length, + &expansion, + &reauth_XKEY, + &seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("generate_reauth_shared_secred_keys(): expansion\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("expansion"), + expansion.get_data(), + expansion.get_data_length())); + + u8_t *data = expansion.get_data_offset(0u, data_length); + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + const u8_t * const data_begin = data; + + EAP_UNREFERENCED_PARAMETER(data_begin); + + // Only master_session_key is used in re-authentication. + + status = master_session_key->set_copy_of_buffer(data, EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + data += EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE; + EAP_ASSERT_ALWAYS(static_cast(data-data_begin) <= data_length); + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("generate_reauth_shared_secred_keys(): master_session_key\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL(" MSK+EMSK"), + master_session_key->get_data(), + master_session_key->get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) +/** + * This function stores pointer to the received triplet array. + */ +void eap_type_gsmsim_c::set_triplets(eap_type_sim_triplet_array_c * const triplets) +{ + if (m_triplets != 0) + { + delete m_triplets; + m_triplets = 0; + } + m_triplets = triplets; +} +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::save_version( + const u16_t * const payload_version_list, + const u32_t version_count, + const eap_gsmsim_version selected_version) +{ + m_gsmsim_selected_version = selected_version; + + eap_status_e status = m_gsmsim_version_list.set_copy_of_buffer( + payload_version_list, + sizeof(payload_version_list[0])*version_count); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_gsmsim_c::random_selection() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + crypto_random_c rand(m_am_tools); + + if (rand.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; + } + + return (rand.get_rand_integer(0, 1) != 0); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_final_notification() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_is_valid == true) + { + if (m_is_client == true + && m_n_rands.get_is_valid_data() == true) + { + eap_status_e status = m_am_type_gsmsim->set_rand_is_used(&m_n_rands); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + } + + if (m_authentication_finished_successfully == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, authentication FAILED, state %s\n"), + (m_is_client == true) ? "client": "server", + get_state_string())); + + if (m_gsmsim_notification_code != eap_gsmsim_notification_none) + { + // We have received EAP-Request/SIM notification, we pass the received code to the adaptation module. + m_am_type_gsmsim->handle_gsmsim_notification(m_gsmsim_notification_code); + } + + set_state(eap_type_gsmsim_state_failure); + + // Notifies the lower level of unsuccessfull authentication. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_type_gsmsim, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + m_last_eap_identifier, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + state_notification(¬ification); + + // Indicate GSMSIM AM authentication finish. + m_am_type_gsmsim->authentication_finished(false, m_authentication_type, m_identity_type); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_padding_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const u32_t plaintext_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + gsmsim_payload_AT_header_c gp_padding( + m_am_tools, + gsmsim->get_data_offset( + *gsmsim_data_offset, *gsmsim_data_free), + *gsmsim_data_free); + + if (gp_padding.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t cbc_aes_data_length = cbc_aes.aligned_data_length(plaintext_length); + u32_t padding_bytes_length = 0u; + + if (cbc_aes_data_length > plaintext_length+gsmsim_payload_AT_header_c::get_header_length()) + { + // Fill with zero (0x00) bytes. + padding_bytes_length = cbc_aes_data_length - (plaintext_length+gsmsim_payload_AT_header_c::get_header_length()); + } + + u32_t padding_payload_length = gsmsim_payload_AT_header_c::get_header_length()+padding_bytes_length; + + if ((padding_payload_length % EAP_TYPE_GSMSIM_PADDING_MODULUS) != 0) + { + // ERROR + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + if (padding_payload_length > EAP_TYPE_GSMSIM_PADDING_MAX_VALUE) + { + padding_payload_length = 0ul; + padding_bytes_length = 0ul; + } + + // Note the reserved field is the begin of padding. + // The reserved field is set zero in reset_header() function. + gp_padding.reset_header(static_cast(padding_payload_length)); + gp_padding.set_data_length(static_cast(padding_bytes_length)); + gp_padding.set_current_payload(gsmsim_payload_AT_PADDING); + + if (padding_payload_length > 0u) + { + if (padding_bytes_length > 0ul) + { + u8_t *padding = gp_padding.get_data(padding_bytes_length); + if (padding == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + cbc_aes.add_padding_bytes( + padding, + padding_bytes_length, + 0ul); + } + + update_payload_indexes( + gsmsim_buffer_length, + eap_header_size, + gp_padding.get_header_length()+gp_padding.get_data_length(), + gsmsim_data_offset, + gsmsim_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_padding); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("GSMSIM: Padding payload not needed.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_variable_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_variable_data_c * const data_payload, + const gsmsim_payload_AT_type_e data_payload_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + u16_t data_length = 0u; + + if (data_payload != 0) + { + if (data_payload->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + + if (data_payload->get_data_length() > gsmsim_payload_AT_header_c::get_max_payload_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + data_length = static_cast(data_payload->get_data_length()); + } + else + { + // No data. + data_length = 0u; + } + + gsmsim_payload_AT_header_c gp_data( + m_am_tools, + gsmsim->get_data_offset(*gsmsim_data_offset, *gsmsim_data_free), + *gsmsim_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + gp_data.reset_header(data_length); + + if (data_length > 0u) + { + u8_t *payload_buffer = gp_data.get_data(data_length); + if (payload_buffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_am_tools->memmove( + payload_buffer, + data_payload->get_data(), + data_payload->get_data_length()); + } + + gp_data.set_data_length(data_length); + + status = eap_status_ok; + + + gp_data.set_current_payload(data_payload_type); + + update_payload_indexes( + gsmsim_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + gsmsim_data_offset, + gsmsim_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// Note the specification of IMSI payload is not same as pseudonym. +// IMSI and pseudonym specifications should be integrated. +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_pseudonym_or_imsi_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_variable_data_c * const pseudonym_or_imsi, + const gsmsim_payload_AT_type_e data_payload_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (pseudonym_or_imsi->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + + u32_t padding_zero_count = 0u; + // Add padding zero octets + if ((pseudonym_or_imsi->get_data_length() % 4u) != 0) + { + padding_zero_count = 4u - (pseudonym_or_imsi->get_data_length() % 4u); + } + + if (pseudonym_or_imsi->get_data_length()+padding_zero_count + > gsmsim_payload_AT_header_c::get_max_payload_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (pseudonym_or_imsi->get_data_length()+padding_zero_count > *packet_buffer_free) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + gsmsim_payload_AT_header_c gp_data( + m_am_tools, + gsmsim->get_data_offset( + *gsmsim_data_offset, + *gsmsim_data_free), + *gsmsim_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + gp_data.reset_header(static_cast(pseudonym_or_imsi->get_data_length()+padding_zero_count)); + + u8_t *payload_buffer = gp_data.get_data(pseudonym_or_imsi->get_data_length()+padding_zero_count); + + if (payload_buffer == 0 + || pseudonym_or_imsi->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_am_tools->memmove( + payload_buffer, + pseudonym_or_imsi->get_data(), + pseudonym_or_imsi->get_data_length()); + + if (padding_zero_count > 0u) + { + m_am_tools->memset( + payload_buffer+(pseudonym_or_imsi->get_data_length()), + 0, + padding_zero_count); + } + + // Note the reserved field includes the actual length of pseudonym in network order. + // This must be less or equal to the length field. + gp_data.set_reserved(static_cast(pseudonym_or_imsi->get_data_length())); + + gp_data.set_data_length(static_cast(pseudonym_or_imsi->get_data_length()+padding_zero_count)); + + status = eap_status_ok; + + gp_data.set_current_payload(data_payload_type); + + update_payload_indexes( + gsmsim_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + gsmsim_data_offset, + gsmsim_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_version_list( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_gsmsim_version *gsmsim_versions, + const u32_t gsmsim_versions_count, + const gsmsim_payload_AT_type_e data_payload_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + u32_t version_list_size = sizeof(u16_t)*gsmsim_versions_count; + u32_t padding_zero_count = 0u; + // Add padding zero octets + if ((version_list_size % 4u) != 0) + { + padding_zero_count = 4u - (version_list_size % 4u); + } + + if (version_list_size+padding_zero_count + > gsmsim_payload_AT_header_c::get_max_payload_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (version_list_size+padding_zero_count > *packet_buffer_free) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + gsmsim_payload_AT_header_c gp_data( + m_am_tools, + gsmsim->get_data_offset( + *gsmsim_data_offset, + *gsmsim_data_free), + *gsmsim_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gp_data.reset_header(static_cast(version_list_size+padding_zero_count)); + + u8_t *payload_buffer = gp_data.get_data(version_list_size+padding_zero_count); + + if (payload_buffer == 0 + || version_list_size == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u16_t *payload_version_list = reinterpret_cast(payload_buffer); + u32_t ind; + for (ind = 0u; ind < gsmsim_versions_count; ind++) + { + payload_version_list[ind] = eap_htons(static_cast(gsmsim_versions[ind])); + } + + if (padding_zero_count > 0u) + { + m_am_tools->memset( + payload_buffer+(version_list_size), + 0, + padding_zero_count); + } + + // Note the reserved field includes the actual length of version list in network order. + // This must be less or equal to the length field. + gp_data.set_reserved(static_cast(version_list_size)); + + gp_data.set_data_length(static_cast(version_list_size+padding_zero_count)); + + status = eap_status_ok; + + gp_data.set_current_payload(data_payload_type); + + update_payload_indexes( + gsmsim_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + gsmsim_data_offset, + gsmsim_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_notification_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_gsmsim_notification_codes_e notification_code) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + gsmsim_payload_AT_header_c gp_data( + m_am_tools, + gsmsim->get_data_offset( + *gsmsim_data_offset, + *gsmsim_data_free), + *gsmsim_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gp_data.reset_header(0u); + + // Note the reserved field includes the notificatio code in network order. + gp_data.set_reserved(static_cast(notification_code)); + + gp_data.set_data_length(0u); + + status = eap_status_ok; + + gp_data.set_current_payload(gsmsim_payload_AT_NOTIFICATION); + + update_payload_indexes( + gsmsim_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + gsmsim_data_offset, + gsmsim_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_client_error_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_gsmsim_client_error_code_e client_error_code) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + gsmsim_payload_AT_header_c gp_data( + m_am_tools, + gsmsim->get_data_offset( + *gsmsim_data_offset, + *gsmsim_data_free), + *gsmsim_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gp_data.reset_header(0u); + + // Note the reserved field includes the triplet status in network order. + // This must be less or equal to the length field. + gp_data.set_reserved(static_cast(client_error_code)); + + gp_data.set_data_length(0u); + + status = eap_status_ok; + + gp_data.set_current_payload(gsmsim_payload_AT_CLIENT_ERROR_CODE); + + update_payload_indexes( + gsmsim_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + gsmsim_data_offset, + gsmsim_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_version_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_gsmsim_version version) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + gsmsim_payload_AT_header_c gp_data( + m_am_tools, + gsmsim->get_data_offset( + *gsmsim_data_offset, + *gsmsim_data_free), + *gsmsim_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gp_data.reset_header(0u); + + // Note the reserved field includes the selected version in network order. + gp_data.set_reserved(static_cast(version)); + + gp_data.set_data_length(0u); + + status = eap_status_ok; + + gp_data.set_current_payload(gsmsim_payload_AT_SELECTED_VERSION); + + update_payload_indexes( + gsmsim_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + gsmsim_data_offset, + gsmsim_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_counter_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + u16_t counter) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + gsmsim_payload_AT_header_c gp_data( + m_am_tools, + gsmsim->get_data_offset( + *gsmsim_data_offset, + *gsmsim_data_free), + *gsmsim_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gp_data.reset_header(0u); + + // Note the reserved field includes the selected version in network order. + gp_data.set_reserved(counter); + + gp_data.set_data_length(0u); + + status = eap_status_ok; + + gp_data.set_current_payload(gsmsim_payload_AT_COUNTER); + + update_payload_indexes( + gsmsim_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + gsmsim_data_offset, + gsmsim_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_simple_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const gsmsim_payload_AT_type_e data_payload_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + gsmsim_payload_AT_header_c gp_data( + m_am_tools, + gsmsim->get_data_offset( + *gsmsim_data_offset, + *gsmsim_data_free), + *gsmsim_data_free); + + if (gp_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gp_data.reset_header(0u); + + gp_data.set_reserved(0u); + + gp_data.set_data_length(0u); + + status = eap_status_ok; + + gp_data.set_current_payload(data_payload_type); + + update_payload_indexes( + gsmsim_buffer_length, + eap_header_size, + gp_data.get_header_length()+gp_data.get_data_length(), + gsmsim_data_offset, + gsmsim_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::encrypt_DATA_payload( + u8_t * const data, + const u32_t cbc_aes_data_length, + const eap_variable_data_c * const IV, + const eap_variable_data_c * const encryption_key + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (data == 0 + || cbc_aes_data_length == 0 + || IV == 0 + || IV->get_is_valid_data() == false + || encryption_key == 0 + || encryption_key->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t aes_key_length = aes.get_key_length(); + if (encryption_key->get_data_length() < aes_key_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + status = cbc_aes.set_encryption_key( + IV->get_data(), + IV->get_data_length(), + encryption_key->get_data(), + aes_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = cbc_aes.encrypt_data( + data, + cbc_aes_data_length); + + store_last_encryption_iv(cbc_aes.get_tmp_IV()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_mac_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + u8_t ** const MAC_data, + u32_t * const MAC_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + gsmsim_payload_AT_header_c gp_MAC( + m_am_tools, + gsmsim->get_data_offset( + *gsmsim_data_offset, *gsmsim_data_free), + *gsmsim_data_free); + + if (gp_MAC.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u32_t eap_type_gsmsim_mac_size = EAP_TYPE_GSMSIM_MAC_SIZE; + + gp_MAC.reset_header(static_cast(eap_type_gsmsim_mac_size)); + gp_MAC.set_data_length(static_cast(eap_type_gsmsim_mac_size)); + gp_MAC.set_current_payload(gsmsim_payload_AT_MAC); + + *MAC_data = gp_MAC.get_data(eap_type_gsmsim_mac_size); + if (*MAC_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + *MAC_data_length = eap_type_gsmsim_mac_size; + + m_am_tools->memset(*MAC_data, 0, eap_type_gsmsim_mac_size); + + // MAC is calculated later using call create_message_authentication_code(). + + update_payload_indexes( + gsmsim_buffer_length, + eap_header_size, + gp_MAC.get_header_length()+gp_MAC.get_data_length(), + gsmsim_data_offset, + gsmsim_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_MAC); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::check_version_list( + const gsmsim_payload_AT_header_c * const payload, + const u16_t version_list_length, + u8_t *version_list, + bool * const includes_other_version_than_1) +{ + eap_status_e status(eap_status_process_general_error); + + if (payload->get_data_length() > version_list_length) + { + // Check padding bytes are zero. + const u8_t * const padding = &version_list[version_list_length]; + const u32_t padding_count = payload->get_data_length() - version_list_length; + + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = cbc_aes.check_padding_bytes( + padding, + padding_count, + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + // Illegal padding byte. + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + } + + gsmsim_variable_data_c tmp_version_list(m_am_tools); + + status = tmp_version_list.set_buffer( + payload, version_list, version_list_length, false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_gsmsim_version selected_version = select_version(&tmp_version_list, includes_other_version_than_1); + + if (selected_version == GSMSIM_ILLEGAL_VERSION) + { + // ERROR, no supported version. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::check_version_list(), illegal version list.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::parse_generic_payload( + const gsmsim_payload_AT_type_e current_payload, + const gsmsim_payload_AT_header_c * const payload, + gsmsim_payloads_c * const p_gsmsim_payloads, + const gsmsim_subtype_e subtype) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_GSMSIM_TRACE_PAYLOAD("Parsing payload", payload); + + if ((payload->get_payload_length() % static_cast(GSMSIM_PAYLOAD_LENGTH_ALIGN)) != 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x not aligned to 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), + payload->get_payload_length(), GSMSIM_PAYLOAD_LENGTH_ALIGN)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_status_e status(eap_status_process_general_error); + + if (current_payload == gsmsim_payload_AT_NONCE_MT) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_NONCE_MT | Length = 5 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | NONCE_MT | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_reserved() != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), + payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() != EAP_TYPE_GSMSIM_NONCE_MT_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), + payload->get_payload_length(), payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(EAP_TYPE_GSMSIM_NONCE_MT_SIZE)); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + status = p_gsmsim_payloads->get_NONCE_MT()->set_buffer( + payload, buffer, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_NONCE_S) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_NONCE_S | Length = 5 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | NONCE_S | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_reserved() != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() != EAP_TYPE_GSMSIM_NONCE_MT_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(EAP_TYPE_GSMSIM_NONCE_MT_SIZE)); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + status = p_gsmsim_payloads->get_NONCE_S()->set_buffer( + payload, buffer, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_RAND) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_RAND | Length | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | n*RAND ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_reserved() != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() < m_minimum_rand_count*SIM_RAND_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x. Too few RAND bytes 0x%04x, 0x%04x bytes required.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_data_length(), + m_minimum_rand_count*SIM_RAND_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_enough_challenges); + } + + if ((payload->get_data_length() % SIM_RAND_LENGTH) != 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, n*RAND length ") + EAPL("0x%04x is not multiple of one RAND length 0x%04x bytes.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_data_length(), + SIM_RAND_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + + u8_t * n_rands = static_cast(payload->get_data(payload->get_data_length())); + if (n_rands == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_gsmsim_payloads->get_n_RANDs()->set_buffer( + payload, n_rands, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_PADDING) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_PADDING | Length | Padding... | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + u8_t * padding = 0; + + // Note two first octets of padding are the reserved field. It must be zero. + if (payload->get_reserved() != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // NOTE padding data length could be zero. + if (payload->get_data_length() != 0u) + { + padding = static_cast(payload->get_data(payload->get_data_length())); + } + + status = p_gsmsim_payloads->get_padding_payload()->set_buffer( + payload, padding, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_NEXT_PSEUDONYM) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_NEXT...YM | Length | Actual Pseudonym Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | Pseudonym | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // Note the reserved field includes the actual length of pseudonym. + // This must be less or equal to the length field. + u16_t pseudonym_length = payload->get_reserved(); + if (pseudonym_length == 0u + || pseudonym_length > payload->get_data_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, pseudonym length field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * pseudonym = static_cast(payload->get_data(pseudonym_length)); + if (pseudonym == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_gsmsim_payloads->get_NEXT_PSEUDONYM()->set_buffer( + payload, pseudonym, pseudonym_length, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_NEXT_REAUTH_ID) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_NEXT...ID | Length | Actual Identity Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | Reauthentication identity | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // Note the reserved field includes the actual length of reauthentication identity. + // This must be less or equal to the length field. + u16_t next_reauth_id_length = payload->get_reserved(); + if (next_reauth_id_length == 0u + || next_reauth_id_length > payload->get_data_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reauthentication identity length field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * next_reauth_id = static_cast(payload->get_data(next_reauth_id_length)); + if (next_reauth_id == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_gsmsim_payloads->get_NEXT_REAUTH_ID()->set_buffer( + payload, next_reauth_id, next_reauth_id_length, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_RESULT_IND) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_RESULT_IND | Length = 1 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, notification code %d.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_reserved())); + + status = p_gsmsim_payloads->get_RESULT_IND()->set_buffer( + payload, 0, 0u, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_NOTIFICATION) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_NOTIFICATION| Length = 1 | Notification Code | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note the reserved field includes the notification code (triplet status). + eap_gsmsim_notification_codes_e notification_code = static_cast(payload->get_reserved()); + EAP_UNREFERENCED_PARAMETER(notification_code); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, notification code %d.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_reserved())); + + status = p_gsmsim_payloads->get_NOTIFICATION()->set_buffer( + payload, 0, 0u, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_COUNTER) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_COUNTER | Length = 1 | Counter | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_gsmsim_payloads->get_COUNTER()->set_buffer( + payload, 0, 0u, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_COUNTER_TOO_SMALL) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_COUNTER_TOO.| Length = 1 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved %d.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + payload->get_reserved())); + + status = p_gsmsim_payloads->get_COUNTER_TOO_SMALL()->set_buffer( + payload, 0, 0u, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_MAC) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_MAC | Length = 5 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | MAC | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_reserved() != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() != EAP_TYPE_GSMSIM_MAC_SIZE) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(EAP_TYPE_GSMSIM_MAC_SIZE)); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_gsmsim_payloads->get_MAC()->set_buffer( + payload, buffer, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_IV) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_IV | Length = 5 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | Initialization Vector (optional) | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_reserved() != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (payload->get_data_length() != aes.get_block_size()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(payload->get_data_length())); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + status = p_gsmsim_payloads->get_IV()->set_buffer( + payload, buffer, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_ENCR_DATA) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_ENCR_DATA | Length | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | Encrypted Data (optional) | + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_reserved() != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (payload->get_data_length() < 8u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(payload->get_data_length())); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_gsmsim_payloads->get_ENCR_DATA()->set_buffer( + payload, buffer, payload->get_data_length(), false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_PERMANENT_ID_REQ) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_PERM..._REQ | Length = 1 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_gsmsim_payloads->get_PERMANENT_ID_REQ()->set_buffer( + payload, 0, 0, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_FULLAUTH_ID_REQ) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_FULL..._REQ | Length = 1 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_gsmsim_payloads->get_FULLAUTH_ID_REQ()->set_buffer( + payload, 0, 0, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_ANY_ID_REQ) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_ANY..._REQ | Length = 1 | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = p_gsmsim_payloads->get_ANY_ID_REQ()->set_buffer( + payload, 0, 0, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_IDENTITY) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_IDENTITY | Length | Actual Identity Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // . Current Identity (optional) . + // | | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + u16_t identity_length = payload->get_reserved(); + + if (payload->get_data_length() == 0 + || identity_length > payload->get_data_length() + || identity_length < 1u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, identity_length 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * identity_data + = static_cast(payload->get_data(payload->get_data_length())); + + if (identity_data == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (identity_length < payload->get_data_length()) + { + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Includes padding bytes. Those must be zero. + eap_status_e status = cbc_aes.check_padding_bytes( + identity_data+identity_length, + payload->get_data_length()-identity_length, + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // We assume the prefix byte is included. + status = p_gsmsim_payloads->get_IDENTITY_payload()->set_buffer( + payload, identity_data, identity_length, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_VERSION_LIST) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_VERSION_L..| Length | Actual Version List Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Supported Version 1 | Padding | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // Note the reserved field includes the actual length of version list. + // This must be less or equal to the length field. + u16_t version_list_length = payload->get_reserved(); + if (version_list_length == 0u + || version_list_length > payload->get_data_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, version list length field incorrect 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * version_list = static_cast(payload->get_data(version_list_length)); + if (version_list == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + bool includes_other_version_than_1 = false; + + eap_status_e status = check_version_list(payload, version_list_length, version_list, &includes_other_version_than_1); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + p_gsmsim_payloads->set_includes_other_version_than_1(includes_other_version_than_1); + + status = p_gsmsim_payloads->get_VERSION_LIST()->set_buffer( + payload, version_list, version_list_length, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_SELECTED_VERSION) + { + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AT_SELECTED...| Length = 1 | Selected Version | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note the reserved field includes the selected version. + eap_gsmsim_version selected_version = static_cast(payload->get_reserved()); + + if (selected_version != GSMSIM_VERSION_1) // This is the only supported GSMSIM version. + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, illegal GSMSIM version %d.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), selected_version)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, selected_version %d.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + selected_version)); + + status = p_gsmsim_payloads->get_SELECTED_VERSION()->set_buffer( + payload, 0, 0u, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == gsmsim_payload_AT_CLIENT_ERROR_CODE) + { + // The format of the AT_CLIENT_ERROR_CODE attribute is shown below. + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |AT_CLIENT_ERR..| Length = 1 | Client Error Code | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // Note the reserved field includes the selected version. + + if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), + payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_gsmsim_client_error_code_e client_error_code = static_cast(payload->get_reserved()); + + if (client_error_code > eap_gsmsim_client_error_code_maximum_value) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, illegal GSMSIM version %d.\n"), + payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), client_error_code)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, client_error_code %d.\n"), + payload, + current_payload, + payload->get_payload_AT_string(), + payload->get_payload_length(), + client_error_code)); + + status = p_gsmsim_payloads->get_CLIENT_ERROR_CODE()->set_buffer( + payload, 0, 0u, false, false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (128 <= current_payload && current_payload <= 255) + { + // Unknown skippable attribute. + if (subtype == gsmsim_subtype_Start) + { + // EAP-Request/SIM/Start and EAP-Response/SIM/Start messages may + // include unknown non-skippable attributes if version list includes + // other than version 1. + p_gsmsim_payloads->set_includes_unknown_attribute(current_payload); + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("IGNORED: eap_type_gsmsim_c::parse_generic_payload(): Marked non-skippable attribute %d=0x%04x.\n"), + current_payload, + current_payload)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + // Silently ignore this payload. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("IGNORED: eap_type_gsmsim_c::parse_generic_payload(): Ignored skippable attribute %d=0x%04x.\n"), + current_payload, + current_payload)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + else + { + // Unknown non-skippable attribute. + if (subtype == gsmsim_subtype_Start) + { + // EAP-Request/SIM/Start and EAP-Response/SIM/Start messages may + // include unknown non-skippable attributes if version list includes + // other than version 1. + p_gsmsim_payloads->set_includes_unknown_attribute(current_payload); + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("IGNORED: eap_type_gsmsim_c::parse_generic_payload(): Marked non-skippable attribute %d=0x%04x.\n"), + current_payload, + current_payload)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(): Unknown non-skippable attribute %d=0x%04x.\n"), + current_payload, + current_payload)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unsupported_gsmsim_payload); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::analyse_gsmsim_packet( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (m_is_client == true) + { + // Client + + if (received_gsmsim->get_subtype() == gsmsim_subtype_Start) + { + status = handle_start_request_message( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + } + else if (received_gsmsim->get_subtype() == gsmsim_subtype_Challenge) + { + status = handle_challenge_request_message( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + } + else if (received_gsmsim->get_subtype() == gsmsim_subtype_Notification) + { + status = handle_gsmsim_notification_request_message( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + } + else if (received_gsmsim->get_subtype() == gsmsim_subtype_Re_authentication) + { + status = handle_reauthentication_request_message( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + } + else + { + // Unknown message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::analyse_gsmsim_packet(): ") + EAPL("Unknown message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Server + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + if (received_gsmsim->get_subtype() == gsmsim_subtype_Start) + { + status = handle_start_response_message( + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + } + else if (received_gsmsim->get_subtype() == gsmsim_subtype_Challenge) + { + status = handle_challenge_response_message( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + } + else if (received_gsmsim->get_subtype() == gsmsim_subtype_Notification) + { + status = handle_notification_response_message( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + } + else if (received_gsmsim->get_subtype() == gsmsim_subtype_Re_authentication) + { + status = handle_reauthentication_response_message( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + } + else if (received_gsmsim->get_subtype() == gsmsim_subtype_Client_Error) + { + status = handle_client_error_response_message( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + } + else +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + { + // Unknown message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::analyse_gsmsim_packet(): ") + EAPL("Unknown message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::parse_gsmsim_payload( + const gsmsim_payload_AT_header_c * const p_payload, + u32_t * const buffer_length, + gsmsim_payloads_c * const p_gsmsim_payloads, + const gsmsim_subtype_e subtype) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + gsmsim_payload_AT_header_c payload( + m_am_tools, + p_payload->get_header_buffer(*buffer_length), + *buffer_length); // Const correctness is gone. + + gsmsim_payload_AT_type_e current_payload = payload.get_current_payload(); + + eap_status_e status = eap_status_header_corrupted; + + if (payload.get_is_valid() == true + && current_payload != gsmsim_payload_NONE) + { + if (*buffer_length < payload.get_header_length()+payload.get_data_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_payload(0x%08x): current payload 0x%04x=%s, data length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload, + payload.get_payload_AT_string(), + payload.get_data_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_payload(): GSMSIM-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload, p_gsmsim_payloads, subtype); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT_ALWAYS(*buffer_length >= payload.get_header_length()+payload.get_data_length()); + *buffer_length -= payload.get_header_length()+payload.get_data_length(); + + while(*buffer_length >= payload.get_header_length() + && payload.get_is_valid() == true + && payload.get_header_buffer_length() >= (payload.get_header_length()+payload.get_data_length())) + { + payload.set_header_buffer( + payload.get_next_header(), + payload.get_header_buffer_length()-(payload.get_header_length()+payload.get_data_length())); + if (payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + current_payload = payload.get_current_payload(); + + if (*buffer_length < payload.get_header_length()+payload.get_data_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_payload(0x%08x): current payload 0x%04x=%s, data length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload, + payload.get_payload_AT_string(), + payload.get_data_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_payload(): GSMSIM-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload, p_gsmsim_payloads, subtype); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT_ALWAYS(*buffer_length >= payload.get_header_length()+payload.get_data_length()); + *buffer_length -= payload.get_header_length()+payload.get_data_length(); + } + } + + if (*buffer_length != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_payload(): ") + EAPL("GSMSIM-header is corrupted. Buffer length and payload length does not match. %lu illegal bytes.\n"), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::parse_gsmsim_packet( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (gsmsim->get_length() < gsmsim->get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_packet(): ") + EAPL("GSMSIM-header is corrupted. Buffer length and payload ") + EAPL("length does not match. GSMSIM-header length %lu < minimum GSMSIM-header length %lu.\n"), + gsmsim->get_length(), + gsmsim->get_header_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (gsmsim->get_length() > gsmsim_packet_length) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_packet(): ") + EAPL("GSMSIM-header is corrupted. Buffer length and payload ") + EAPL("length does not match. GSMSIM-header length %lu > packet length %lu\n"), + gsmsim->get_length(), + gsmsim_packet_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u32_t buffer_length = gsmsim->get_length() - gsmsim->get_header_length(); + + if (buffer_length == 0u) + { + // No payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + + gsmsim_payload_AT_header_c payload( + m_am_tools, + gsmsim->get_data(buffer_length), + buffer_length); + + if (payload.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: No gsmsim_payload_AT_header_c.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + eap_status_e status = parse_gsmsim_payload( + &payload, + &buffer_length, + p_gsmsim_payloads, + gsmsim->get_subtype()); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (buffer_length != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_packet(): ") + EAPL("GSMSIM-header is corrupted. Buffer length and payload ") + EAPL("length does not match. Illegal byte count %lu\n"), + buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_gsmsim_packet( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_header_corrupted); + +#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + + status = check_valid_state(received_gsmsim->get_subtype()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + + status = parse_gsmsim_packet(received_gsmsim, gsmsim_length, p_gsmsim_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = analyse_gsmsim_packet( + receive_network_id, + received_gsmsim, + gsmsim_length, + p_gsmsim_payloads); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +#if defined(USE_EAP_TRACE) + +// +EAP_FUNC_EXPORT void eap_type_gsmsim_c::packet_trace( + eap_const_string prefix, + const eap_am_network_id_c * const /* receive_network_id */, + eap_header_wr_c * const eap_packet, + const u32_t /* eap_packet_length */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(prefix); + + if (eap_packet->get_length() > eap_header_base_c::get_header_length() + && eap_packet->get_type() == eap_type_gsmsim) + { + gsmsim_header_c gsmsim_eap( + m_am_tools, + eap_packet->get_header_buffer(eap_packet->get_header_buffer_length()), + eap_packet->get_header_buffer_length()); + + gsmsim_eap.get_code(); // This is just to make some use in release version. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s EAP_type_GSMSIM: %s, (0x%08x), code=0x%02x=%s, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x=%s, subtype=0x%02x=%s\n"), + prefix, + (m_is_client == true) ? "client": "server", + this, + gsmsim_eap.get_code(), + gsmsim_eap.get_code_string(), + gsmsim_eap.get_identifier(), + gsmsim_eap.get_length(), + convert_eap_type_to_u32_t(gsmsim_eap.get_type()), + gsmsim_eap.get_eap_type_string(), + gsmsim_eap.get_subtype(), + gsmsim_eap.get_subtype_string())); + + EAP_TRACE_DEBUG(m_am_tools, eap_am_tools_c::eap_trace_mask_eap_messages, + (EAPL("\n\t%s\n\tcode = 0x%02x = %s\n\tidentifier = 0x%02x") + EAPL("\n\tlength = 0x%04x = %lu\n\ttype = 0x%08x = %s\n\tsubtype = 0x%02x = %s\n"), + (m_is_client == true) ? "client": "server", + gsmsim_eap.get_code(), + gsmsim_eap.get_code_string(), + gsmsim_eap.get_identifier(), + gsmsim_eap.get_length(), + gsmsim_eap.get_length(), + convert_eap_type_to_u32_t(gsmsim_eap.get_type()), + gsmsim_eap.get_eap_type_string(), + gsmsim_eap.get_subtype(), + gsmsim_eap.get_subtype_string())); + } + else if (eap_packet->get_length() > eap_header_base_c::get_header_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s EAP_type_GSMSIM: %s, (0x%08x), code=0x%02x=%s, identifier=0x%02x, length=0x%04x, type=0x%08x=%s\n"), + prefix, + (m_is_client == true) ? "client": "server", + this, + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + convert_eap_type_to_u32_t(eap_packet->get_type()), + eap_packet->get_type_string())); + + EAP_TRACE_DEBUG( + m_am_tools, + eap_am_tools_c::eap_trace_mask_eap_messages, + (EAPL("\n\t%s\n\tcode = 0x%02x = %s\n\tidentifier = 0x%02x\n\tlength = 0x%04x = %lu\n\ttype = 0x%08x = %s\n"), + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + eap_packet->get_length(), + convert_eap_type_to_u32_t(eap_packet->get_type()), + eap_packet->get_type_string())); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s EAP_type_GSMSIM: %s, (0x%08x), code=0x%02x=%s, identifier=0x%02x, length=0x%04x\n"), + prefix, + (m_is_client == true) ? "client": "server", + this, + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + eap_am_tools_c::eap_trace_mask_eap_messages, + (EAPL("\n\t%s\n\tcode = 0x%02x = %s\n\tidentifier = 0x%02x\n\tlength = 0x%04x = %lu\n"), + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + eap_packet->get_length())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +#endif //#if defined(USE_EAP_TRACE) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_gsmsim_c::get_nai_realm() +{ + return &m_manual_realm; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_gsmsim_c::update_buffer_indexes( + const u32_t maximum_buffer_size, + const u32_t payload_size, + u32_t * const buffer_offset, + u32_t * const buffer_free) +{ + EAP_UNREFERENCED_PARAMETER(maximum_buffer_size); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length); + EAP_ASSERT_ALWAYS(*buffer_free >= payload_size); + EAP_ASSERT_ALWAYS(m_gsmsim_header_offset+m_MTU == *buffer_offset + *buffer_free); + + *buffer_free -= payload_size; + *buffer_offset += payload_size; + + EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length); + EAP_ASSERT_ALWAYS(*buffer_offset <= m_gsmsim_header_offset+m_MTU); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_gsmsim_c::update_payload_indexes( + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + const u32_t payload_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_offset, + u32_t * const buffer_free) +{ + EAP_UNREFERENCED_PARAMETER(eap_header_size); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT_ALWAYS(*buffer_offset == m_gsmsim_header_offset + eap_header_size + *data_offset); + EAP_ASSERT_ALWAYS(*buffer_free == *data_free); + EAP_ASSERT_ALWAYS(*data_free >= payload_size); + + *data_free -= payload_size; + *data_offset += payload_size; + + update_buffer_indexes( + maximum_buffer_size, + payload_size, + buffer_offset, + buffer_free); + + EAP_ASSERT_ALWAYS(*buffer_offset == m_gsmsim_header_offset + eap_header_size + *data_offset); + EAP_ASSERT_ALWAYS(*buffer_free == *data_free); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_type_gsmsim_c::get_is_client() +{ + return m_is_client; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_gsmsim_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_type_gsmsim_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_gsmsim_c::state_notification( + const abs_eap_state_notification_c * const state + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::state_notification(): get_type_partner() 0x%08x\n"), + get_type_partner())); + + get_type_partner()->state_notification(state); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::finish_successful_authentication( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::finish_successful_authentication().\n"))); + + if (m_is_client + && m_n_rands.get_is_valid_data() == true) + { + if (m_do_rand_uniqueness_check == true) + { + eap_status_e status = m_am_type_gsmsim->set_rand_is_used( + &m_n_rands); + if (status != eap_status_ok) + { + // ERROR: write to database failed.. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + } + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (m_master_session_key.get_is_valid_data() == false + || m_master_session_key.get_data_length() == 0u) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + eap_status_e status = get_type_partner()->packet_data_crypto_keys( + &send_network_id, + &m_master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_authentication_finished_successfully = true; + set_state(eap_type_gsmsim_state_success); + + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_type_gsmsim, + eap_state_none, + eap_state_authentication_finished_successfully, + m_last_eap_identifier, + true); + state_notification(¬ification); + + // Indicate GSMSIM AM authentication finish. + m_am_type_gsmsim->authentication_finished(true, m_authentication_type, m_identity_type); + + + if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, re-authentication EAP-SUCCESS, ") + EAPL("re-authentication identity\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH) + { + if (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, full authentication EAP-SUCCESS, ") + EAPL("pseudonym identity\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, full authentication EAP-SUCCESS, ") + EAPL("IMSI identity\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, full authentication EAP-SUCCESS, ") + EAPL("Re-auth identity\n"), + (m_is_client == true) ? "client": "server")); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS|TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: EAP_type_GSMSIM: %s, unknown authentication EAP-SUCCESS, ") + EAPL("unknown identity\n"), + (m_is_client == true) ? "client": "server")); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS|TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: EAP_type_GSMSIM: %s, unknown authentication EAP-SUCCESS, ") + EAPL("unknown identity\n"), + (m_is_client == true) ? "client": "server")); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + + cancel_error_message_delay_timer(); + + cancel_notification_message_delay_timer(); + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::packet_process(): receive_network_id=0x%08x is invalid.\n"), + receive_network_id)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (received_eap == 0 + || received_eap->get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::packet_process(): received_eap 0x%08x is invalid.\n"), + received_eap)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_GSMSIM_PACKET_TRACE( + EAPL("->"), + receive_network_id, + received_eap, + eap_packet_length); + + if (eap_packet_length < received_eap->get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::packet_process(): ") + EAPL("eap_packet_length=0x%04x < received_eap->get_length()=0x%04x.\n"), + eap_packet_length, received_eap->get_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (received_eap->get_length() < eap_header_base_c::get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::packet_process(): received_eap->get_length() ") + EAPL("< eap_header_base_c::get_header_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + + // NOTE: by disabling these calls throughput increases about 18%. + // Disabling also decreases random seeds. + m_am_tools->get_crypto()->add_rand_seed( + received_eap->get_header_buffer(eap_packet_length), + eap_packet_length); + m_am_tools->get_crypto()->add_rand_seed_hw_ticks(); + + eap_status_e status = eap_status_process_general_error; + + if ((m_is_client == true + && received_eap->get_code() == eap_code_request) + || (m_is_client == false + && received_eap->get_code() == eap_code_response)) + { + if (received_eap->get_type() == eap_type_identity + || received_eap->get_type() == eap_type_gsmsim) + { + if (received_eap->get_type() == eap_type_identity + && received_eap->get_code() == eap_code_request + && received_eap->get_length() <= eap_header_base_c::get_header_length()) + { + status = eap_status_header_corrupted; + } + else if (received_eap->get_type() == eap_type_identity + && received_eap->get_code() == eap_code_response + && received_eap->get_length() <= eap_header_base_c::get_header_length()) + { + status = eap_status_header_corrupted; + } + else if (received_eap->get_type() == eap_type_gsmsim + && received_eap->get_length() < received_eap->get_header_length()) + { + status = eap_status_header_corrupted; + } + else + { + gsmsim_header_c gsmsim_header( + m_am_tools, + received_eap->get_header_buffer(received_eap->get_header_buffer_length()), + received_eap->get_header_buffer_length()); + + if (gsmsim_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = gsmsim_packet_process( + receive_network_id, + &gsmsim_header, + eap_packet_length, + m_is_client); + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_drop_packet_quietly + && status != eap_status_pending_request) + { + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: %s=%d eap_type_gsmsim_c::gsmsim_packet_process() failed\n"), + status_string.get_status_string(status), status)); + + if (m_is_client == true) + { + status = initialize_error_message( + status); + } + else + { + status = initialize_notification_message(); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(received_eap, false); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (received_eap->get_type() == eap_type_notification) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP type notification: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, type=0x%08x\n"), + received_eap->get_code(), + received_eap->get_identifier(), + received_eap->get_length(), + convert_eap_type_to_u32_t(received_eap->get_type()))); + + status = eap_status_illegal_eap_type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP type unknown: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, type=0x%08x\n"), + received_eap->get_code(), + received_eap->get_identifier(), + received_eap->get_length(), + convert_eap_type_to_u32_t(received_eap->get_type()))); + + status = eap_status_illegal_eap_type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (m_is_client == true + && (received_eap->get_code() == eap_code_success + || received_eap->get_code() == eap_code_failure)) + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (received_eap->get_code() == eap_code_success) + { + if (m_state == eap_type_gsmsim_state_waiting_for_success) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(received_eap, false); + + if (m_wait_eap_success_packet == false) + { + /** + * @{ Check right functionality. + * Here we return eap_status_ok, eap_status_success was returned after successfull + * EAP-Request/SIM/Challenge. This may change after EAP, 802.1X and 802.11i specifications are ready. } + */ + status = eap_status_ok; + } + else + { + status = finish_successful_authentication( + receive_network_id); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP-Success: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, state %d=%s, is client %d\n"), + received_eap->get_code(), + received_eap->get_identifier(), + received_eap->get_length(), + m_state, + get_state_string(), + (m_is_client == true))); + status = eap_status_drop_packet_quietly; + } + } + else if (received_eap->get_code() == eap_code_failure) + { + // EAP is quite sloppy protocol. + // Somebody just send a EAP-failure message and authentication is terminated. + + // Save received failure. We do not change our state yet. + // The real correct EAP message could be received later if this failure was + // send by nasty attacker. + m_failure_message_received = true; + // We handle the EAP-Request/Failure message after a timeout. + + status = eap_status_ok; + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP code unknown: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, is client %d\n"), + received_eap->get_code(), received_eap->get_identifier(), + received_eap->get_length(), (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP code unknown: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, is client %d\n"), + received_eap->get_code(), received_eap->get_identifier(), + received_eap->get_length(), (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::new_handler( + const eap_am_network_id_c * const /* receive_network_id */, + const bool is_client_when_true) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::new_handler(): Creating new handler 0x%08x.\n"), + this)); + + // We do not have handler yet and the message is identity EAP-message. + // A new handler is needed. + // Handler is selected using own address and peer address. + + m_is_client = is_client_when_true; + + if (is_client_when_true == true) + { + set_state(eap_type_gsmsim_state_waiting_for_identity_request); + } + else if (is_client_when_true == false) + { + set_state(eap_type_gsmsim_state_waiting_for_identity_response); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::aka_packet_process(0x%08x): New handler created.\n"), + this)); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" own address"), + m_send_network_id.get_source_id()->get_data(m_send_network_id.get_source_id()->get_data_length()), + m_send_network_id.get_source_id()->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("peer address"), + m_send_network_id.get_destination_id()->get_data(m_send_network_id.get_destination_id()->get_data_length()), + m_send_network_id.get_destination_id()->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::gsmsim_packet_process( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + const bool is_client_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("receive_network_id=0x%08x is invalid.\n"), + receive_network_id)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (received_gsmsim == 0 + || received_gsmsim->get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("received_gsmsim 0x%08x is invalid.\n"), + received_gsmsim)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (gsmsim_packet_length < received_gsmsim->get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("gsmsim_packet_length < received_gsmsim->get_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (received_gsmsim->get_type() == eap_type_gsmsim) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::gsmsim_packet_process(), GSMSIM subtype %d=%s\n"), + received_gsmsim->get_subtype(), received_gsmsim->get_subtype_string())); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::gsmsim_packet_process(), EAP-type 0x%08x=%s\n"), + convert_eap_type_to_u32_t(received_gsmsim->get_type()), + received_gsmsim->get_eap_type_string())); + } + + eap_status_e status = eap_status_process_general_error; + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (m_state == eap_type_gsmsim_state_none) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::gsmsim_packet_process(): No handler found.\n"))); + + if (is_client_when_true == false + && received_gsmsim->get_type() == eap_type_identity) + { + // The EAP-identity is plain EAP-packet without additional fields.. + eap_header_rd_c eap_header( + m_am_tools, + received_gsmsim->get_header_buffer( + received_gsmsim->get_header_buffer_length()), + received_gsmsim->get_header_buffer_length()); + + // This is just to make some use in release version. + eap_header.get_type_data_length(); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("received: EAP-identity"), + eap_header.get_type_data(eap_header.get_type_data_length()), + eap_header.get_type_data_length())); + + status = new_handler( + receive_network_id, + is_client_when_true); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("new_handler() failed, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (is_client_when_true == true + && received_gsmsim->get_code() == eap_code_request) + { + if (received_gsmsim->get_length() < received_gsmsim->get_header_length()) + { + status = eap_status_process_illegal_packet_error; + eap_status_string_c status_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: %s=%d eap_type_gsmsim_c::gsmsim_packet_process(): corrupted GSMSIM-header.\n"), + status_string.get_status_string(status), status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Here we create a handler and set state to + // eap_type_gsmsim_state_waiting_for_start_request + // if first EAP-Request is EAP-Request/SIM/Start. + if (received_gsmsim->get_subtype() == gsmsim_subtype_Start) + { + eap_header_rd_c eap_header( + m_am_tools, + received_gsmsim->get_header_buffer(received_gsmsim->get_header_buffer_length()), + received_gsmsim->get_header_buffer_length()); + + EAP_UNREFERENCED_PARAMETER(eap_header); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("received: EAP-Request/GSMSIM/Start"), + eap_header.get_type_data(eap_header.get_type_data_length()), + eap_header.get_type_data_length())); + + // We must query the previous sent EAP-Identity from EAP_Core. + // The EAP_Core saves the sent EAP-Identity when the EAP-Identity is + // sent to the network. + // Previous EAP-type was NOT this instance. EAP-Identity was queried from other instance. + status = get_type_partner()->get_saved_eap_identity(&m_identity); + if (status == eap_status_ok) + { + status = m_NAI.set_copy_of_buffer(&m_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(GSMSIM_IDENTITY_TYPE_IMSI_ID); + } + + status = new_handler( + receive_network_id, + is_client_when_true); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): new_handler() failed, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + set_state(eap_type_gsmsim_state_waiting_for_start_request); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("Only EAP-Request/SIM/Start message in EAP-SIM client ") + EAPL("causes creation of new handler. This EAP-packet is dropped.\n"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: received: source"), + receive_network_id->get_source(), + receive_network_id->get_source_length())); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: received: destination"), + receive_network_id->get_destination(), + receive_network_id->get_destination_length())); + + if (received_gsmsim->get_type() == eap_type_gsmsim) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x, subtype=0x%02x, client %d\n"), + received_gsmsim->get_code(), + received_gsmsim->get_identifier(), + received_gsmsim->get_length(), + convert_eap_type_to_u32_t(received_gsmsim->get_type()), + received_gsmsim->get_subtype(), + is_client_when_true)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x, client %d\n"), + received_gsmsim->get_code(), + received_gsmsim->get_identifier(), + received_gsmsim->get_length(), + convert_eap_type_to_u32_t(received_gsmsim->get_type()), + is_client_when_true)); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("Only EAP-identity message in server causes creation ") + EAPL("of new handler. This EAP-packet is dropped.\n"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: received: source"), + receive_network_id->get_source(), + receive_network_id->get_source_length())); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: received: destination"), + receive_network_id->get_destination(), + receive_network_id->get_destination_length())); + + if (received_gsmsim->get_type() == eap_type_gsmsim) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x, subtype=0x%02x, client %d\n"), + received_gsmsim->get_code(), + received_gsmsim->get_identifier(), + received_gsmsim->get_length(), + convert_eap_type_to_u32_t(received_gsmsim->get_type()), + received_gsmsim->get_subtype(), + is_client_when_true)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x, client %d\n"), + received_gsmsim->get_code(), + received_gsmsim->get_identifier(), + received_gsmsim->get_length(), + convert_eap_type_to_u32_t(received_gsmsim->get_type()), + is_client_when_true)); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::gsmsim_packet_process(): state %d=%s\n"), + m_state, + get_state_string())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("received: GSMSIM packet"), + received_gsmsim->get_header_buffer( + received_gsmsim->get_header_length()+received_gsmsim->get_data_length()), + received_gsmsim->get_header_length()+received_gsmsim->get_data_length())); + + if (received_gsmsim->get_type() == eap_type_identity) + { + if (is_client_when_true == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("EAP-Request/Identity is not handled here anymore.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + status = eap_status_process_general_error; + } +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + else if (is_client_when_true == false) + { + eap_header_rd_c eap_header( + m_am_tools, + received_gsmsim->get_header_buffer( + received_gsmsim->get_header_buffer_length()), + received_gsmsim->get_header_buffer_length()); + + const eap_type_gsmsim_state_variable_e saved_state = m_state; + + EAP_UNREFERENCED_PARAMETER(saved_state); + + status = handle_identity_response_message( + &eap_header, + gsmsim_packet_length); + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_drop_packet_quietly) + { + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: %s=%d eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("handle_identity_response_message().\n"), + status_string.get_status_string(status), status)); + } + + if (status == eap_status_ok) + { + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_type_gsmsim, + eap_state_none, + eap_state_identity_response_received, + m_last_eap_identifier, + false); + state_notification(¬ification); + } + } +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + if (status == eap_status_ok + || status == eap_status_success) + { + // Ok, good EAP message received. + if (m_is_client == true) + { + m_failure_message_received = false; + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("handle_identity_response_message() failed, status %d.\n"), + status)); + } + + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (gsmsim_packet_length < received_gsmsim->get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("gsmsim_packet_length < gsmsim_header_c::get_header_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = received_gsmsim->check_header(); + if (status != eap_status_ok) + { + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: %s=%d eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("corrupted GSMSIM-header.\n"), + status_string.get_status_string(status), status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("received: GSMSIM-type %10s, %s, state %2d=%s\n"), + received_gsmsim->get_subtype_string(), + (m_is_client) ? EAPL("client") : EAPL("server"), + m_state, + get_state_string() + )); + + gsmsim_payloads_c * const l_gsmsim_payloads = new gsmsim_payloads_c(m_am_tools); + eap_automatic_variable_c l_gsmsim_payloads_automatic( + m_am_tools, + l_gsmsim_payloads); + + if (l_gsmsim_payloads == 0 + || l_gsmsim_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = handle_gsmsim_packet( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + l_gsmsim_payloads); + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_drop_packet_quietly + && status != eap_status_pending_request) + { + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: %s=%d eap_type_gsmsim_c::gsmsim_packet_process(): ") + EAPL("handle_gsmsim_packet().\n"), + status_string.get_status_string(status), status)); + } + + if (status == eap_status_ok + || status == eap_status_success + || status == eap_status_pending_request) + { + // Ok, good EAP message received. + if (m_is_client == true) + { + m_failure_message_received = false; + } + } + + if (status == eap_status_ok) + { + // Do nothing special. + } + else if (status == eap_status_drop_packet_quietly) + { + // We will drop this message quietly. + } + else if (status != eap_status_ok) + { + // EAP-Failure will be sent from shutdown(). + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::cancel_error_message_delay_timer() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = cancel_timer( + this, + EAP_TYPE_GSMSIM_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID); + + m_erroneus_packet_received = false; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID cancelled.\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::set_error_message_delay_timer() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = set_timer( + this, + EAP_TYPE_GSMSIM_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID, + 0, + m_failure_message_delay_time); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID set.\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::cancel_notification_message_delay_timer() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = cancel_timer( + this, + EAP_TYPE_GSMSIM_TIMER_DELAY_NOTIFICATION_MESSAGE_ID); + + m_erroneus_packet_received = false; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID cancelled.\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::set_notification_message_delay_timer() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = set_timer( + this, + EAP_TYPE_GSMSIM_TIMER_DELAY_NOTIFICATION_MESSAGE_ID, + 0, + m_failure_message_delay_time); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID set.\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_error_packet() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_error_packet(): ") + EAPL("erroneus_packet_received %d, m_client_error_code %d\n"), + m_erroneus_packet_received, + m_client_error_code)); + + if (m_state == eap_type_gsmsim_state_none) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_erroneus_packet_received == true) + { + set_state(eap_type_gsmsim_state_failure); + + if (m_is_client == true) + { + // Client will send EAP-Response/SIM/Client-Error. + status = send_gsmsim_client_error_response(); + } + else + { + // Server will send EAP-Failure. + // Notifies the lower level of unsuccessfull authentication. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_type_gsmsim, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + m_last_eap_identifier, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + state_notification(¬ification); + + status = eap_status_ok; + } + } + else + { + // One erroneous packet is already received. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("WARNING: eap_type_gsmsim_c::handle_error_packet(): one erroneus packet already received. This is ignored.\n"))); + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::initialize_error_message( + const eap_status_e error_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::initialize_error_message(): erroneus_packet_received %d, error_status %s\n"), + m_erroneus_packet_received, + status_string.get_status_string(error_status))); + + if (m_erroneus_packet_received == false) + { + // Only the first erroneus packet is recorded. + m_erroneus_packet_received = true; + + if (m_is_client == true) + { + // Client will send EAP-Response/SIM/Client-Error. + switch(error_status) + { + case eap_status_no_matching_protocol_version: + m_client_error_code = eap_gsmsim_client_error_code_unsupported_version; + break; + case eap_status_not_enough_challenges: + m_client_error_code = eap_gsmsim_client_error_code_insufficient_number_of_challenges; + break; + case eap_status_not_fresh_challenges: + m_client_error_code = eap_gsmsim_client_error_code_rands_are_not_fresh; + break; + default: + m_client_error_code = eap_gsmsim_client_error_code_unable_to_process_packet; + break; + }; + } + else + { + // Server will send EAP-Failure. + } + + if (m_failure_message_delay_time > 0ul) + { + // First try set delay timer. + status = set_error_message_delay_timer(); + if (status != eap_status_ok) + { + // ERROR: Process error packet immediately. + status = handle_error_packet(); + } + } + else + { + // Process error packet immediately. + status = handle_error_packet(); + } + } + else + { + // Error packet is already processed. + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_notification_packet() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("eap_type_gsmsim_c::handle_notification_packet(): sim_notification_packet_received %d\n"), + m_sim_notification_packet_received)); + + if (m_state == eap_type_gsmsim_state_none) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_sim_notification_packet_received == true) + { + bool add_at_counter_attribute = false; + if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + add_at_counter_attribute = true; + } + + if (m_is_client == true) + { + // Client will send EAP-Response/SIM/Notification. + if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + set_state(eap_type_gsmsim_state_failure); + } + + status = send_gsmsim_notification_response( + m_gsmsim_notification_code, + add_at_counter_attribute); + } +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + else + { + set_state(eap_type_gsmsim_state_waiting_for_notification_response_failure); + + // Server will send EAP-Request/SIM/Notification. + status = send_gsmsim_notification_request( + m_gsmsim_notification_code, + add_at_counter_attribute); + } +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("eap_type_gsmsim_c::handle_notification_packet(): one SIM/Notification packet already received. This is ignored.\n"))); + + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::initialize_notification_message() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (m_state == eap_type_gsmsim_state_none) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_sim_notification_packet_received == false) + { + // Only the first SIM notification packet is recorded. + m_sim_notification_packet_received = true; + + if (m_is_client == true) + { + // Client will send empty EAP-Response/SIM/Notification. + } + else + { + // Server will send EAP-Request/SIM/Notification. + if (m_gsmsim_notification_code == eap_gsmsim_notification_none) + { + m_gsmsim_notification_code = eap_gsmsim_notification_no_F_P_set_general_failure; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::initialize_notification_message(0x%08x), notification_code = 0x%04x, F bit %d, P bit %d.\n"), + this, + m_gsmsim_notification_code, + get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code), + get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code))); + } + + if (m_failure_message_delay_time > 0ul) + { + // First try set delay timer. + status = set_notification_message_delay_timer(); + if (status != eap_status_ok) + { + // ERROR: Process SIM notification packet immediately. + status = handle_notification_packet(); + } + } + else + { + // Process SIM notification packet immediately. + status = handle_notification_packet(); + } + } + else + { + // SIM notification packet is already processed. + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_type_gsmsim_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + u32_t offset = get_type_partner()->get_header_offset(MTU, trailer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return offset; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::extra_message_authentication_code_bytes( + const gsmsim_subtype_e subtype, + const eap_code_value_e code, + crypto_hmac_c *hmac_sha1) +{ + eap_status_e status(eap_status_ok); + + if (code == eap_code_request) + { + if (subtype == gsmsim_subtype_Challenge) + { + status = hmac_sha1->hmac_update( + m_nonce_mt.get_data(), + m_nonce_mt.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (code == eap_code_response) + { + if (subtype == gsmsim_subtype_Challenge) + { + status = hmac_sha1->hmac_update( + m_n_sres.get_data(), + m_n_sres.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (subtype == gsmsim_subtype_Re_authentication) + { + status = hmac_sha1->hmac_update( + m_nonce_s.get_data(), + m_nonce_s.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_GSMSIM_ERROR, (EAPL("ERROR: extra_message_authentication_code_bytes(): unsupported EAP-Code %d.\n"), + code)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::create_message_authentication_code( + eap_type_gsmsim_MAC_attributes_c *MAC_attributes, + const gsmsim_subtype_e subtype, + const eap_code_value_e code, + const eap_variable_data_c * const authentication_key +) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (MAC_attributes == 0 + || authentication_key == 0 + || authentication_key->get_is_valid_data() == false + //|| MAC_attributes->get_handler() == 0 + || MAC_attributes->get_data() == 0 + || MAC_attributes->get_data_length() == 0u + || MAC_attributes->get_MAC() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("authentication_key"), + authentication_key->get_data(), + authentication_key->get_data_length())); + + eap_status_e status = eap_status_process_general_error; + +#if defined(USE_EAP_TRACE) + { + eap_variable_data_c buffer(m_am_tools); + + status = buffer.set_buffer_length(2048); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = buffer.set_buffer_length(buffer.get_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const tmpbuffer = buffer.get_data(); + if (tmpbuffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t offset = 0; + + m_am_tools->memmove(tmpbuffer+offset, + (MAC_attributes->get_data()), + MAC_attributes->get_data_length()); + offset += MAC_attributes->get_data_length(); + + if (code == eap_code_request) + { + if (subtype == gsmsim_subtype_Challenge) + { + m_am_tools->memmove(tmpbuffer+offset, + m_nonce_mt.get_data(), + m_nonce_mt.get_data_length()); + offset += m_nonce_mt.get_data_length(); + } + } + else if (code == eap_code_response) + { + if (subtype == gsmsim_subtype_Challenge) + { + m_am_tools->memmove(tmpbuffer+offset, + m_n_sres.get_data(), + m_n_sres.get_data_length()); + offset += m_n_sres.get_data_length(); + } + else if (subtype == gsmsim_subtype_Re_authentication) + { + m_am_tools->memmove(tmpbuffer+offset, + m_nonce_s.get_data(), + m_nonce_s.get_data_length()); + offset += m_nonce_s.get_data_length(); + } + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_GSMSIM_ERROR, (EAPL("ERROR: extra_message_authentication_code_bytes(): unsupported EAP-Code %d.\n"), + code)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("create_message_authentication_code(): MAC calculated over the following bytes:\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("MAC data"), + tmpbuffer, + offset)); + } +#endif // #if defined(USE_EAP_TRACE) + + + crypto_sha1_c sha1(m_am_tools); + crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false); + + if (hmac_sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (hmac_sha1.hmac_set_key( + authentication_key + ) != eap_status_ok) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_GSMSIM_ERROR, (EAPL("ERROR: create_message_authentication_code(): set_key() failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = hmac_sha1.hmac_update( + MAC_attributes->get_data(), + MAC_attributes->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = extra_message_authentication_code_bytes(subtype, code, &hmac_sha1); + if (status != eap_status_ok) + { + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: %s=%d create_message_authentication_code(): extra_message_authentication_code_bytes().\n"), + status_string.get_status_string(status), status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + u32_t length = 0u; + + status = hmac_sha1.hmac_128_final( + MAC_attributes->get_MAC(), + &length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT(length == EAP_TYPE_GSMSIM_MAC_SIZE); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("MAC:\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("MAC"), + MAC_attributes->get_MAC(), + length)); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::check_message_authentication_code( + const eap_variable_data_c * const authentication_key, + gsmsim_payloads_c * const p_gsmsim_payloads, + const gsmsim_header_c * const gsmsim_packet, + const u32_t gsmsim_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (authentication_key == 0 + || authentication_key->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + if (p_gsmsim_payloads->get_MAC() == 0 + || p_gsmsim_payloads->get_MAC()->get_payload_included() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + if (gsmsim_packet == 0 + || gsmsim_packet_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("authentication_key"), + authentication_key->get_data(), + authentication_key->get_data_length())); + + crypto_sha1_c sha1(m_am_tools); + crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false); + + if (hmac_sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (hmac_sha1.hmac_set_key( + authentication_key + ) != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u8_t saved_MAC[EAP_TYPE_GSMSIM_MAC_SIZE]; + + m_am_tools->memmove( + saved_MAC, + p_gsmsim_payloads->get_MAC()->get_data(p_gsmsim_payloads->get_MAC()->get_data_length()), + p_gsmsim_payloads->get_MAC()->get_data_length()); + + m_am_tools->memset( + p_gsmsim_payloads->get_MAC()->get_data(p_gsmsim_payloads->get_MAC()->get_data_length()), + 0, + p_gsmsim_payloads->get_MAC()->get_data_length()); + + + eap_status_e status = hmac_sha1.hmac_update( + gsmsim_packet->get_header_buffer(gsmsim_packet_length), + gsmsim_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = extra_message_authentication_code_bytes( + gsmsim_packet->get_subtype(), + gsmsim_packet->get_code(), + &hmac_sha1); + if (status != eap_status_ok) + { + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: %s=%d check_message_authentication_code(): extra_message_authentication_code_bytes().\n"), + status_string.get_status_string(status), status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + + eap_variable_data_c *end_of_authentication = 0; + if (p_gsmsim_payloads->get_MAC()->get_payload_included() == true) + { + end_of_authentication = p_gsmsim_payloads->get_MAC()->get_payload_buffer(); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + + u32_t length = 0u; + + eap_variable_data_c tmp_MAC(m_am_tools); + status = tmp_MAC.init(EAP_TYPE_GSMSIM_MAC_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + tmp_MAC.set_is_valid(); + tmp_MAC.set_data_length(EAP_TYPE_GSMSIM_MAC_SIZE); + + u8_t * const mac_data = tmp_MAC.get_data_offset(0u, EAP_TYPE_GSMSIM_MAC_SIZE); + if (mac_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = hmac_sha1.hmac_128_final( + mac_data, + &length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT(length == EAP_TYPE_GSMSIM_MAC_SIZE); + + + +#if defined(USE_EAP_TRACE) + { + eap_variable_data_c buffer(m_am_tools); + + status = buffer.set_buffer_length(2048); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = buffer.set_buffer_length(buffer.get_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const tmpbuffer = buffer.get_data(); + if (tmpbuffer == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t offset = 0; + + m_am_tools->memmove(tmpbuffer+offset, + gsmsim_packet->get_header_buffer(gsmsim_packet_length), + gsmsim_packet_length); + offset += gsmsim_packet_length; + + if (gsmsim_packet->get_code() == eap_code_request) + { + if (gsmsim_packet->get_subtype() == gsmsim_subtype_Challenge) + { + m_am_tools->memmove(tmpbuffer+offset, + m_nonce_mt.get_data(), + m_nonce_mt.get_data_length()); + offset += m_nonce_mt.get_data_length(); + } + } + else if (gsmsim_packet->get_code() == eap_code_response) + { + if (gsmsim_packet->get_subtype() == gsmsim_subtype_Challenge) + { + m_am_tools->memmove(tmpbuffer+offset, + m_n_sres.get_data(), + m_n_sres.get_data_length()); + offset += m_n_sres.get_data_length(); + } + else if (gsmsim_packet->get_subtype() == gsmsim_subtype_Re_authentication) + { + m_am_tools->memmove(tmpbuffer+offset, + m_nonce_s.get_data(), + m_nonce_s.get_data_length()); + offset += m_nonce_s.get_data_length(); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: extra_message_authentication_code_bytes(): unsupported EAP-Code %d.\n"), + gsmsim_packet->get_code())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("check_message_authentication_code(): MAC calculated over the following bytes:\n"))); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("MAC data"), + tmpbuffer, + offset)); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("MAC:\n"))); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("MAC"), + tmp_MAC.get_data(), + tmp_MAC.get_data_length())); + } +#endif // #if defined(USE_EAP_TRACE) + + + if (length != end_of_authentication->get_data_length() + || tmp_MAC.get_data_length() + != end_of_authentication->get_data_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO|TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: MAC differs.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + if (m_am_tools->memcmp( + tmp_MAC.get_data(), + saved_MAC, + tmp_MAC.get_data_length()) != 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO|TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: MAC differs.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("MAC OK.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::timer_expired( + const u32_t id, void *data) +{ + EAP_UNREFERENCED_PARAMETER(id); + EAP_UNREFERENCED_PARAMETER(data); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_type_gsmsim_c::timer_expired(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + + eap_status_e status = eap_status_process_general_error; + + if (id == EAP_TYPE_GSMSIM_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID elapsed.\n"), + (m_is_client == true) ? "client": "server")); + + if (m_state == eap_type_gsmsim_state_failure) + { + // Athentication is already failed. + + // We set the session timeout to zero. + // This will terminate this session immediately. + status = get_type_partner()->set_session_timeout(0ul); + } + else + { + status = handle_error_packet(); + } + } + else if (id == EAP_TYPE_GSMSIM_TIMER_DELAY_NOTIFICATION_MESSAGE_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID elapsed.\n"), + (m_is_client == true) ? "client": "server")); + + status = handle_notification_packet(); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::timer_delete_data( + const u32_t id, void *data) +{ + EAP_UNREFERENCED_PARAMETER(id); + EAP_UNREFERENCED_PARAMETER(data); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_type_gsmsim_c::timer_delete_data(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + + if (id == EAP_TYPE_GSMSIM_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID delete data.\n"), + (m_is_client == true) ? "client": "server")); + } + else if (id == EAP_TYPE_GSMSIM_TIMER_DELAY_NOTIFICATION_MESSAGE_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID delete data.\n"), + (m_is_client == true) ? "client": "server")); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::packet_send().\n"))); + + eap_header_wr_c eap( + m_am_tools, + sent_packet->get_data_offset( + header_offset, data_length), + data_length); + if (eap.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + EAP_GSMSIM_PACKET_TRACE( + EAPL("<-"), + network_id, + &eap, + data_length); + + eap_status_e status = get_type_partner()->packet_send( + network_id, + sent_packet, + header_offset, + data_length, + buffer_length + ); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE this will be read from AM of GSMSIM EAP-type. + const eap_status_e status = m_am_type_gsmsim->type_configure_read(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE this will be written to AM of GSMSIM EAP-type. + const eap_status_e status = m_am_type_gsmsim->type_configure_write(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in eap_base_type_c::configure(). +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::configure(): this = 0x%08x => 0x%08x\n"), + this, + dynamic_cast(this))); + + eap_status_e status(eap_status_process_general_error); + + + // This must be configured first. + status = m_am_type_gsmsim->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + //---------------------------------------------------------- + + { + eap_variable_data_c error_message_delay_time(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_failure_message_delay_time.get_field(), + &error_message_delay_time); + if (status == eap_status_ok + && error_message_delay_time.get_is_valid_data() == true + && error_message_delay_time.get_data_length() == sizeof(u32_t) + && error_message_delay_time.get_data() != 0) + { + // This is optional value. + m_failure_message_delay_time = *reinterpret_cast( + error_message_delay_time.get_data()); + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c minimum_rand_count(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_minimum_rand_count.get_field(), + &minimum_rand_count); + if (status == eap_status_ok + && minimum_rand_count.get_is_valid_data() == true + && minimum_rand_count.get_data_length() == sizeof(u32_t) + && minimum_rand_count.get_data() != 0) + { + // This is optional value. + m_minimum_rand_count = *reinterpret_cast( + minimum_rand_count.get_data()); + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_manual_realm(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_use_manual_realm.get_field(), + &use_manual_realm); + if (status == eap_status_ok + && use_manual_realm.get_is_valid_data() == true + && use_manual_realm.get_data_length() == sizeof(u32_t)) + { + u32_t *flag = reinterpret_cast(use_manual_realm.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_use_manual_realm = false; + } + else + { + m_use_manual_realm = true; + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_GSMSIM_use_manual_realm.get_field()->get_field())); + } + } + } + + //---------------------------------------------------------- + + { + status = read_configure( + cf_str_EAP_GSMSIM_manual_realm.get_field(), + get_nai_realm()); + if (status == eap_status_ok + && get_nai_realm()->get_is_valid_data() == true) + { + // OK NAI realm is configured. + } + else + { + // No configured NAI realm. + // We will use automatic realm "wlan.mnc456.mcc123.3gppnetwork.org" as a realm. + // Look at eap_type_gsmsim_c::generate_nai(). + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c check_identifier_of_eap_identity_response(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_check_identifier_of_eap_identity_response.get_field(), + &check_identifier_of_eap_identity_response); + + if (status == eap_status_ok + && check_identifier_of_eap_identity_response.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast( + check_identifier_of_eap_identity_response.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_check_identifier_of_eap_identity_response = false; + } + else + { + m_check_identifier_of_eap_identity_response = true; + } + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_GSMSIM_check_identifier_of_eap_identity_response + .get_field()->get_field())); + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_GSMSIM_check_nai_realm(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_check_nai_realm.get_field(), + &EAP_GSMSIM_check_nai_realm); + if (status == eap_status_ok + && EAP_GSMSIM_check_nai_realm.get_is_valid_data() == true) + { + u32_t *check_nai_realm = reinterpret_cast( + EAP_GSMSIM_check_nai_realm.get_data()); + if (check_nai_realm != 0 + && *check_nai_realm != 0) + { + m_check_nai_realm = true; + } + } + } + + //---------------------------------------------------------- + +#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + { + status = read_configure( + cf_str_EAP_GSMSIM_nonce_mt_file.get_field(), + &m_nonce_mt_file); + if (status == eap_status_ok + && m_nonce_mt_file.get_is_valid_data() == true + && m_nonce_mt_file.get_data_length() != 0 + && m_nonce_mt_file.get_data() != 0) + { + // This is optional value. + } + } +#endif //#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + + //---------------------------------------------------------- + +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + { + eap_variable_data_c EAP_GSMSIM_client_responds_retransmitted_packets(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_client_responds_retransmitted_packets.get_field(), + &EAP_GSMSIM_client_responds_retransmitted_packets); + if (status == eap_status_ok + && EAP_GSMSIM_client_responds_retransmitted_packets.get_is_valid_data() == true + && EAP_GSMSIM_client_responds_retransmitted_packets.get_data_length() == sizeof(u32_t) + && EAP_GSMSIM_client_responds_retransmitted_packets.get_data() != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + EAP_GSMSIM_client_responds_retransmitted_packets.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_client_responds_retransmitted_packets = false; + } + else + { + m_client_responds_retransmitted_packets = true; + } + } + } + } +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + + //---------------------------------------------------------- + + { + eap_variable_data_c test_version(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_test_version.get_field(), + &test_version); + if (status == eap_status_ok + && test_version.get_is_valid_data() == true + && test_version.get_data_length() == sizeof(u32_t) + && test_version.get_data() != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(test_version.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_gsmsim_test_version = false; + } + else + { + m_gsmsim_test_version = true; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c randomly_refuse_eap_identity(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_randomly_refuse_eap_identity.get_field(), + &randomly_refuse_eap_identity); + if (status == eap_status_ok + && randomly_refuse_eap_identity.get_is_valid_data() == true + && randomly_refuse_eap_identity.get_data_length() == sizeof(u32_t) + && randomly_refuse_eap_identity.get_data() != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(randomly_refuse_eap_identity.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_gsmsim_randomly_refuse_eap_identity = false; + } + else + { + m_gsmsim_randomly_refuse_eap_identity = true; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c do_rand_uniqueness_check(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_do_rand_uniqueness_check.get_field(), + &do_rand_uniqueness_check); + + if (status == eap_status_ok + && do_rand_uniqueness_check.get_is_valid_data() == true + && do_rand_uniqueness_check.get_data_length() == sizeof(u32_t)) + { + u32_t *flag = reinterpret_cast(do_rand_uniqueness_check.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_do_rand_uniqueness_check = false; + } + else + { + m_do_rand_uniqueness_check = true; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_manual_username(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_use_manual_username.get_field(), + &use_manual_username); + if (status == eap_status_ok + && use_manual_username.get_is_valid_data() == true + && use_manual_username.get_data_length() == sizeof(u32_t)) + { + u32_t *use_manual_username_flag = reinterpret_cast( + use_manual_username.get_data()); + if (use_manual_username_flag != 0 + && *use_manual_username_flag != 0) + { + m_use_manual_username = true; + } + } + } + + //---------------------------------------------------------- + + if (m_use_manual_username == true) + { + status = read_configure( + cf_str_EAP_GSMSIM_manual_username.get_field(), + &m_manual_username); + if (status == eap_status_ok + && m_manual_username.get_is_valid_data() == true) + { + // This is optional value. + } + else + { + // No username defined. + m_use_manual_username = false; + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c fail_re_authentication_counter_check(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_fail_re_authentication_counter_check.get_field(), + &fail_re_authentication_counter_check); + if (status == eap_status_ok + && fail_re_authentication_counter_check.get_is_valid_data() == true + && fail_re_authentication_counter_check.get_data_length() == sizeof(u32_t) + && fail_re_authentication_counter_check.get_data() != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + fail_re_authentication_counter_check.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_fail_reauthentication_counter_check = false; + } + else + { + m_fail_reauthentication_counter_check = true; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c accept_eap_identity_response(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_accept_eap_identity_response.get_field(), + &accept_eap_identity_response); + if (status == eap_status_ok + && accept_eap_identity_response.get_is_valid_data() == true + && accept_eap_identity_response.get_data_length() == sizeof(u32_t) + && accept_eap_identity_response.get_data() != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(accept_eap_identity_response.get_data()); + if (flag != 0) + { + if (*flag != 0) + { + m_accept_eap_identity_response = true; + } + else if (*flag == 0) + { + m_accept_eap_identity_response = false; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_random_identity_on_eap_identity_response(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_use_random_identity_on_eap_identity_response.get_field(), + &use_random_identity_on_eap_identity_response); + if (status == eap_status_ok + && use_random_identity_on_eap_identity_response.get_is_valid_data() == true + && use_random_identity_on_eap_identity_response.get_data_length() == sizeof(u32_t) + && use_random_identity_on_eap_identity_response.get_data() != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + use_random_identity_on_eap_identity_response.get_data()); + if (flag != 0) + { + if (*flag != 0) + { + m_use_random_identity_on_eap_identity_response = true; + } + else if (*flag == 0) + { + m_use_random_identity_on_eap_identity_response = false; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_pseudonym_identity(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_use_pseudonym_identity.get_field(), + &use_pseudonym_identity); + if (status == eap_status_ok + && use_pseudonym_identity.get_is_valid_data() == true + && use_pseudonym_identity.get_data_length() == sizeof(u32_t) + && use_pseudonym_identity.get_data() != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(use_pseudonym_identity.get_data()); + if (flag != 0) + { + if (*flag != 0) + { + m_use_pseudonym_identity = true; + } + else if (*flag == 0) + { + m_use_pseudonym_identity = false; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_reauthentication_identity(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_use_reauthentication_identity.get_field(), + &use_reauthentication_identity); + if (status == eap_status_ok + && use_reauthentication_identity.get_is_valid_data() == true + && use_reauthentication_identity.get_data_length() == sizeof(u32_t) + && use_reauthentication_identity.get_data() != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(use_reauthentication_identity.get_data()); + if (flag != 0) + { + if (*flag != 0) + { + m_use_reauthentication_identity = true; + } + else if (*flag == 0) + { + m_use_reauthentication_identity = false; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c randomly_fail_successfull_authentication(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_randomly_fail_successfull_authentication.get_field(), + &randomly_fail_successfull_authentication); + if (status == eap_status_ok + && randomly_fail_successfull_authentication.get_is_valid_data() == true + && randomly_fail_successfull_authentication.get_data_length() == sizeof(u32_t) + && randomly_fail_successfull_authentication.get_data() != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + randomly_fail_successfull_authentication.get_data()); + if (flag != 0) + { + if (*flag != 0) + { + m_randomly_fail_successfull_authentication = true; + } + else + { + m_randomly_fail_successfull_authentication = false; + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c allow_use_result_indication(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_allow_use_result_indication.get_field(), + &allow_use_result_indication); + if (status == eap_status_ok + && allow_use_result_indication.get_is_valid_data() == true + && allow_use_result_indication.get_data_length() == sizeof(u32_t) + && allow_use_result_indication.get_data() != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(allow_use_result_indication.get_data()); + if (flag != 0) + { + if (*flag != 0) + { + m_allow_use_result_indication = true; + } + else + { + m_allow_use_result_indication = false; + } + } + } + } + + if (m_is_client == false) + { + eap_variable_data_c server_allow_use_result_indication(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_server_allow_use_result_indication.get_field(), + &server_allow_use_result_indication); + if (status == eap_status_ok + && server_allow_use_result_indication.get_is_valid_data() == true + && server_allow_use_result_indication.get_data_length() == sizeof(u32_t) + && server_allow_use_result_indication.get_data() != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(server_allow_use_result_indication.get_data()); + if (flag != 0) + { + if (*flag != 0) + { + m_allow_use_result_indication = true; + } + else + { + m_allow_use_result_indication = false; + } + } + } + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_EXPANDED_TYPES) + { + eap_variable_data_c use_eap_expanded_type(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_GSMSIM_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + + if (status != eap_status_ok) + { + status = read_configure( + cf_str_EAP_CORE_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + } + + if (status == eap_status_ok + && use_eap_expanded_type.get_data_length() == sizeof(u32_t) + && use_eap_expanded_type.get_data() != 0) + { + u32_t *flag = reinterpret_cast(use_eap_expanded_type.get_data(use_eap_expanded_type.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_use_eap_expanded_type = true; + } + else + { + m_use_eap_expanded_type = false; + } + } + } + } +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + //---------------------------------------------------------- + + { + (void) read_configure( + cf_str_EAP_GSMSIM_2_digit_mnc_map_of_mcc_of_imsi_array.get_field(), + &m_2_digit_mnc_map_of_mcc_of_imsi_array); + // This is optional value. + } + + { + eap_variable_data_c use_uma_profile(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_GSMSIM_UMA_profile.get_field(), + &use_uma_profile); + if (status == eap_status_ok + && use_uma_profile.get_is_valid_data() == true + && use_uma_profile.get_data_length() == sizeof(u32_t)) + { + u32_t *flag = reinterpret_cast(use_uma_profile.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_use_uma_profile = false; + } + else + { + m_use_uma_profile = true; + } + } + } + } + + if (m_use_uma_profile == true) + { + (void) read_configure( + cf_str_EAP_GSMSIM_UMA_realm_prefix.get_field(), + &m_uma_automatic_realm_prefix); + // m_uma_automatic_realm_prefix is optional value. + + // In the UMA we must wait EAP-Success to fullfill the state machine of mVPN. + m_wait_eap_success_packet = true; + } + else + { + eap_variable_data_c wait_eap_success_packet(m_am_tools); + + status = read_configure( + cf_str_EAP_GSMSIM_wait_eap_success_packet.get_field(), + &wait_eap_success_packet); + + if (status == eap_status_ok + && wait_eap_success_packet.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast(wait_eap_success_packet.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_wait_eap_success_packet = false; + } + else + { + m_wait_eap_success_packet = true; + } + } + } + + if (get_type_partner()->get_is_tunneled_eap() == true) + { + // Inside the PEAP we must wait EAP-Success to fullfill the state machine of PEAP. + m_wait_eap_success_packet = true; + } + } + + //---------------------------------------------------------- + + m_gsmsim_header_offset = get_type_partner()->get_header_offset( + &m_MTU, &m_trailer_length); + + if (m_gsmsim_header_offset+m_MTU+m_trailer_length + > EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH) + { + EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH + >= (m_gsmsim_header_offset+m_trailer_length)); + + m_MTU = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH + - (m_gsmsim_header_offset+m_trailer_length); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// This is commented in eap_base_type_c::shutdown(). +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::shutdown(): this = 0x%08x => 0x%08x\n"), + this, + dynamic_cast(this))); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + cancel_error_message_delay_timer(); + cancel_notification_message_delay_timer(); + + if (m_state != eap_type_gsmsim_state_none) + { + // We must cancel the pending query. + if (m_state == eap_type_gsmsim_state_pending_identity_query) + { + m_am_type_gsmsim->cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query(); + } + else if (m_state == eap_type_gsmsim_state_pending_kc_sres_query) + { + m_am_type_gsmsim->cancel_SIM_kc_sres_query(); + } + else if (m_state == eap_type_gsmsim_state_pending_pseudonym_decode_query) + { + m_am_type_gsmsim->cancel_imsi_from_username_query(); + } +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + else if (m_state == eap_type_gsmsim_state_pending_triplet_query) + { + m_am_type_gsmsim->cancel_SIM_triplets_query(); + } +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + send_final_notification(); + } + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + if (m_triplets != 0) + { + delete m_triplets; + m_triplets = 0; + } +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + eap_status_e status(eap_status_ok); + if (m_am_type_gsmsim != 0) + { + status = m_am_type_gsmsim->shutdown(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This function is to allow reuse of this object. +// The whole object state must be reset. +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("GSMSIM: %s: function: eap_type_gsmsim_c::reset(): this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + eap_status_e status = eap_status_not_supported; + + m_reset_was_called = true; + + m_use_result_indication = false; + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_NONE; + set_identity_type(GSMSIM_IDENTITY_TYPE_NONE); + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + if (m_triplets != 0) + { + delete m_triplets; + m_triplets = 0; + } +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + m_state = eap_type_gsmsim_state_none; + m_saved_previous_state = eap_type_gsmsim_state_none; + m_gsmsim_selected_version = GSMSIM_ILLEGAL_VERSION; + m_nonce_mt.reset(); + m_nonce_s.reset(); + m_IV.get_payload_buffer()->reset(); + m_saved_EAP_packet.reset(); + m_XKEY.reset(); + m_K_encr.reset(); + m_K_aut.reset(); + m_master_session_key.reset(); + m_automatic_realm.reset(); + m_automatic_realm_read = false; + m_IMSI.reset(); + m_pseudonym.reset(); + m_reauthentication_identity.reset(); + m_identity.reset(); + m_NAI.reset(); + m_n_rands.reset(); + m_n_sres.reset(); + + { + cancel_error_message_delay_timer(); + m_client_error_code = eap_gsmsim_client_error_code_none; + m_erroneus_packet_received = false; + + cancel_notification_message_delay_timer(); + m_gsmsim_notification_code = eap_gsmsim_notification_none; + m_sim_notification_packet_received = false; + } + + status = m_am_type_gsmsim->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = get_type_partner()->set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = get_type_partner()->cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = get_type_partner()->cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_type_gsmsim_c::set_start_response_includes_identity(gsmsim_payload_AT_type_e type) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("GSMSIM: %s: eap_type_gsmsim_c::set_start_response_includes_identity(): %d=%s\n"), + (m_is_client == true ? "client": "server"), + type, + gsmsim_payload_AT_header_c::get_payload_AT_string(type))); + + m_start_response_includes_identity = type; +} + +//-------------------------------------------------- + +void eap_type_gsmsim_c::set_identity_type(eap_type_gsmsim_identity_type type) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("GSMSIM: %s: eap_type_gsmsim_c::set_identity_type(): %d=%s\n"), + (m_is_client == true ? "client": "server"), + type, + get_identity_string(type))); + + m_identity_type = type; +} + +//-------------------------------------------------- +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_client.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_client.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,5783 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 76 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_type_gsmsim.h" +#include "eap_type_gsmsim_header.h" +#include "eap_type_gsmsim_payloads.h" +#include "eap_type_gsmsim_mac_attributes.h" +#include "abs_eap_am_type_gsmsim.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" +#include "abs_eap_am_mutex.h" +#include "eap_automatic_variable.h" +#include "eap_type_gsmsim_header.h" +#include "eap_am_type_gsmsim.h" + + +//-------------------------------------------------- + +/** @file */ + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::generate_nai( + eap_variable_data_c * const new_nai, + const bool use_manual_default_realm, + const eap_variable_data_c * const nai_realm, + const eap_variable_data_c * const id_IMSI_or_pseudonym, + const bool id_is_imsi, + const eap_variable_data_c * const IMSI, + const eap_variable_data_c * const automatic_realm, + const u32_t length_of_mnc) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (id_IMSI_or_pseudonym == 0 + || id_IMSI_or_pseudonym->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_status_e status = eap_status_not_supported; + + status = new_nai->init(id_IMSI_or_pseudonym->get_data_length()+1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + new_nai->set_is_valid(); + + eap_variable_data_c local_username(m_am_tools); + status = local_username.set_buffer_length(id_IMSI_or_pseudonym->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + local_username.set_data_length(id_IMSI_or_pseudonym->get_data_length()); + + m_am_tools->memmove( + local_username.get_data(id_IMSI_or_pseudonym->get_data_length()), + id_IMSI_or_pseudonym->get_data(), + id_IMSI_or_pseudonym->get_data_length()); + + new_nai->set_data_length(0u); + + if (id_is_imsi == true) + { + // Note the first octet is reserved for IMSI prefix. + status = new_nai->add_data(GSMSIM_IMSI_PREFIX_CHARACTER, 1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // This could be IMSI or pseudonym. + status = new_nai->add_data(&local_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (use_manual_default_realm == true + && nai_realm != 0 + && nai_realm->get_is_valid_data() == true) + { + if (nai_realm->get_data_length() > 0ul) + { + status = new_nai->add_data(GSMSIM_AT_CHARACTER, 1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = new_nai->add_data(nai_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (IMSI != 0 + && IMSI->get_is_valid_data() == true + && IMSI->get_data_length() >= EAP_TYPE_GSMSIM_MINIMUM_IMSI_LENGTH) + { + status = new_nai->add_data(GSMSIM_AT_CHARACTER, 1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (automatic_realm != 0 + && automatic_realm->get_is_valid_data() == true) + { + // We must use automatic realm. + + status = new_nai->add_data(automatic_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // We must use automatic realm (Example: "wlan.mnc456.mcc123.3gppnetwork.org"). + + status = new_nai->add_data(GSMSIM_OWLAN_ORG_PREFIX_STRING, GSMSIM_OWLAN_ORG_PREFIX_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(GSMSIM_OWLAN_MNC_STRING, GSMSIM_OWLAN_MNC_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // MNC part. + if (length_of_mnc == EAP_TYPE_GSMSIM_MNC_LENGTH_2_BYTES) + { + // Add zero digit. + u8_t zero = '0'; + status = new_nai->add_data(&zero, sizeof(zero)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + status = new_nai->add_data(IMSI->get_data_offset(EAP_TYPE_GSMSIM_MNC_OFFSET, length_of_mnc), length_of_mnc); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(GSMSIM_OWLAN_MCC_STRING, GSMSIM_OWLAN_MCC_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // MCC part is in index 0 and it is 3 bytes long. + status = new_nai->add_data(IMSI->get_data_offset(EAP_TYPE_GSMSIM_MCC_OFFSET, EAP_TYPE_GSMSIM_MCC_LENGTH), EAP_TYPE_GSMSIM_MCC_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_nai->add_data(GSMSIM_OWLAN_ORG_STRING, GSMSIM_OWLAN_ORG_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("new_nai"), + new_nai->get_data(), + new_nai->get_data_length())); + + if (new_nai->get_data_length() < sizeof(u8_t)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const length_of_mnc, + const bool must_be_synchronous, + const gsmsim_payload_AT_type_e required_identity, + const eap_type_gsmsim_complete_e required_completion, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + save_current_state(); + set_state(eap_type_gsmsim_state_pending_identity_query); + + status = m_am_type_gsmsim->query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + must_be_synchronous, + IMSI, + pseudonym_identity, + reauthentication_identity, + automatic_realm, + length_of_mnc, + required_identity, + required_completion, + received_eap_identifier); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok + && status != eap_status_success) + { + // This is an error case. + restore_saved_previous_state(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_ok) + { + if (m_use_pseudonym_identity == false) + { + // We do not want use pseudonym identity. + pseudonym_identity->reset(); + } + + if (m_use_reauthentication_identity == false) + { + // We do not want use re-authentication identity. + reauthentication_identity->reset(); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::check_rands( + const eap_variable_data_c * const n_rands + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if ((n_rands->get_data_length() % SIM_RAND_LENGTH) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + + const u32_t rand_count = n_rands->get_data_length() / SIM_RAND_LENGTH; + + if (rand_count < m_minimum_rand_count) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_enough_challenges); + } + + u32_t ind = 0ul; + + for (ind = 0ul; ind+1ul < rand_count; ind++) + { + const u8_t * const rand_a = n_rands->get_data_offset(ind*SIM_RAND_LENGTH, SIM_RAND_LENGTH); + for (u32_t b_ind = ind+1ul; b_ind < rand_count; b_ind++) + { + const u8_t * const rand_b = n_rands->get_data_offset(b_ind*SIM_RAND_LENGTH, SIM_RAND_LENGTH); + if (rand_a == 0 + || rand_b == 0 + || m_am_tools->memcmp(rand_a, rand_b, SIM_RAND_LENGTH) == 0) + { + // ERROR: Two equal RANDs. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + } + } + + if (m_do_rand_uniqueness_check == true) + { + eap_status_e status = m_am_type_gsmsim->check_is_rand_unused(n_rands); + if (status != eap_status_ok) + { + // ERROR: RAND is used already. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_fresh_challenges); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::query_SIM_kc_sres( + const eap_variable_data_c * const n_rands, + eap_variable_data_c * const n_kc, + eap_variable_data_c * const n_sres + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + status = check_rands(n_rands); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_n_rands.set_copy_of_buffer(n_rands); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(eap_type_gsmsim_state_pending_kc_sres_query); + + status = m_am_type_gsmsim->query_SIM_kc_sres( + false, + n_rands, + n_kc, + n_sres); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_SIM_kc_sres() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_SIM_kc_sres() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok + && status != eap_status_success) + { + // This is a error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +u32_t eap_type_gsmsim_c::get_mnc_length(const u32_t mcc) +{ + u32_t * const mcc_array = reinterpret_cast(m_2_digit_mnc_map_of_mcc_of_imsi_array.get_data( + m_2_digit_mnc_map_of_mcc_of_imsi_array.get_data_length())); + + u32_t count = m_2_digit_mnc_map_of_mcc_of_imsi_array.get_data_length() / sizeof(u32_t); + + for (u32_t ind = 0ul; ind < count; ind++) + { + if (mcc == mcc_array[ind]) + { + return EAP_TYPE_GSMSIM_MNC_LENGTH_2_BYTES; + } + } + + return EAP_TYPE_GSMSIM_DEFAULT_MNC_LENGTH_3_BYTES; +} + +//-------------------------------------------------- + +eap_status_e eap_type_gsmsim_c::create_uma_realm( + eap_variable_data_c * const automatic_realm, + const eap_variable_data_c * const IMSI, + const u32_t length_of_mnc) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + // Create special automatic realm for UMA. + automatic_realm->reset(); + + if (m_use_uma_profile == true) + { + // Create special automatic realm for UMA. + automatic_realm->reset(); + + if (m_uma_automatic_realm_prefix.get_is_valid_data() == true) + { + status = automatic_realm->add_data(&m_uma_automatic_realm_prefix); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (automatic_realm->get_data_length() > 0ul) + { + status = automatic_realm->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = automatic_realm->add_data(GSMSIM_OWLAN_MNC_STRING, GSMSIM_OWLAN_MNC_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // MNC part. + if (length_of_mnc == EAP_TYPE_GSMSIM_MNC_LENGTH_2_BYTES) + { + // Add zero digit. + u8_t zero = '0'; + status = automatic_realm->add_data(&zero, sizeof(zero)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + status = automatic_realm->add_data(IMSI->get_data_offset(EAP_TYPE_GSMSIM_MNC_OFFSET, length_of_mnc), length_of_mnc); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = automatic_realm->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = automatic_realm->add_data(GSMSIM_OWLAN_MCC_STRING, GSMSIM_OWLAN_MCC_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // MCC part is in index 0 and it is 3 bytes long. + status = automatic_realm->add_data(IMSI->get_data_offset(EAP_TYPE_GSMSIM_MCC_OFFSET, EAP_TYPE_GSMSIM_MCC_LENGTH), EAP_TYPE_GSMSIM_MCC_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = automatic_realm->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = automatic_realm->add_data(GSMSIM_OWLAN_ORG_STRING, GSMSIM_OWLAN_ORG_STRING_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query( + const eap_variable_data_c * const IMSI, + const eap_variable_data_c * const p_pseudonym_identity, + const eap_variable_data_c * const p_reauthentication_identity, + const eap_variable_data_c * const p_automatic_realm, ///< This could be zero pointer if this is not used. + const u32_t length_of_mnc, + const eap_type_gsmsim_complete_e required_completion, + const u8_t received_eap_identifier, + const eap_status_e completion_status +) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (completion_status != eap_status_ok + || IMSI == 0 + || p_pseudonym_identity == 0 + || p_reauthentication_identity == 0) + { + set_state(eap_type_gsmsim_state_failure); + + // The eap_status_process_general_error error value is more important + // than return value of set_session_timeout(). + get_type_partner()->set_session_timeout(0ul); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + + const eap_variable_data_c * local_pseudonym_identity = p_pseudonym_identity; + const eap_variable_data_c * local_reauthentication_identity = p_reauthentication_identity; + + if (m_use_pseudonym_identity == false) + { + // We do not want use pseudonym identity. + local_pseudonym_identity = 0; + } + + if (m_use_reauthentication_identity == false) + { + // We do not want use re-authentication identity. + local_reauthentication_identity = 0; + } + + if (m_state != eap_type_gsmsim_state_pending_identity_query) + { + // Authentication is terminated or state is wrong. Cannot continue. + set_state(eap_type_gsmsim_state_failure); + + // The eap_status_handler_does_not_exists_error error value is more important + // than return value of set_session_timeout(). + get_type_partner()->set_session_timeout(0ul); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c local_automatic_realm(m_am_tools); + + if (p_automatic_realm == 0 + || p_automatic_realm->get_is_valid_data() == false) + { + { + // Here we read the length of the MNC. + const u8_t * const MCC = IMSI->get_data_offset(EAP_TYPE_GSMSIM_MCC_OFFSET, EAP_TYPE_GSMSIM_MCC_LENGTH); + if (MCC == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + u32_t MCC_value(0ul); + status = m_am_tools->number_string_to_u32( + MCC, + 3ul, + &MCC_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_length_of_mnc = get_mnc_length(MCC_value); + } + + status = create_uma_realm(&local_automatic_realm, IMSI, m_length_of_mnc); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (local_automatic_realm.get_is_valid() == true) + { + status = m_automatic_realm.set_copy_of_buffer(&local_automatic_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + status = local_automatic_realm.set_copy_of_buffer(p_automatic_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_automatic_realm.set_copy_of_buffer(p_automatic_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_length_of_mnc = length_of_mnc; + + } + + m_automatic_realm_read = true; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + if (required_completion == eap_type_gsmsim_complete_query_eap_identity) + { + status = handle_eap_identity_query( + &m_send_network_id, + 0, + m_last_eap_identifier, + IMSI, + local_pseudonym_identity, + local_reauthentication_identity, + &local_automatic_realm, + m_length_of_mnc, + false); + if (status != eap_status_ok + && status != eap_status_completed_request) + { + restore_saved_previous_state(); + } + } + else if (required_completion == eap_type_gsmsim_complete_start_request) + { + if (local_reauthentication_identity != 0 + && local_reauthentication_identity->get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query reauthentication_identity\n"))); + + status = m_reauthentication_identity.set_copy_of_buffer(local_reauthentication_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(&m_reauthentication_identity, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (local_pseudonym_identity != 0 + && local_pseudonym_identity->get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query pseudonym\n"))); + + m_reauthentication_identity.reset(); + status = m_pseudonym.set_copy_of_buffer(local_pseudonym_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(&m_pseudonym, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (IMSI->get_is_valid_data() == true + && IMSI->get_data_length() >= EAP_TYPE_GSMSIM_MINIMUM_IMSI_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query IMSI\n"))); + + m_reauthentication_identity.reset(); + m_pseudonym.reset(); + status = m_IMSI.set_copy_of_buffer(IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(&m_IMSI, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + save_current_state(); + set_state(eap_type_gsmsim_state_analyse_start_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query(0x%08x).\n"), + this)); + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + m_send_network_id.get_destination_id(), + m_send_network_id.get_source_id(), + m_send_network_id.get_type()); + + status = send_start_response_message( + &receive_network_id, + received_eap_identifier, + m_gsmsim_selected_version, + m_include_identity_to_start_response, + &local_automatic_realm, + m_length_of_mnc); + + if (status == eap_status_ok) + { + } + else + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::complete_SIM_kc_sres( + const eap_variable_data_c * const n_rand, + const eap_variable_data_c * const n_kc, + const eap_variable_data_c * const n_sres, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (completion_status != eap_status_ok + || n_rand == 0 + || n_kc == 0 + || n_sres == 0) + { + if (completion_status == eap_status_not_fresh_challenges) + { + (void) initialize_error_message(completion_status); + + restore_saved_previous_state(); + } + else + { + set_state(eap_type_gsmsim_state_failure); + + // The eap_status_process_general_error error value is more important + // than return value of set_session_timeout(). + get_type_partner()->set_session_timeout(0ul); + } + + return EAP_STATUS_RETURN(m_am_tools, completion_status); + } + + + if (m_state != eap_type_gsmsim_state_pending_kc_sres_query) + { + // Authentication is terminated or state is wrong. Cannot continue. + set_state(eap_type_gsmsim_state_failure); + + // The eap_status_handler_does_not_exists_error error value is more important + // than return value of set_session_timeout(). + get_type_partner()->set_session_timeout(0ul); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = process_SIM_kc_sres( + n_rand, + n_kc, + n_sres); + + if (status != eap_status_ok + && status != eap_status_success) + { + (void) initialize_error_message(status); + + restore_saved_previous_state(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::process_SIM_kc_sres( + const eap_variable_data_c * const n_rand, + const eap_variable_data_c * const n_kc, + const eap_variable_data_c * const n_sres) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + eap_variable_data_c MAC_RAND(m_am_tools); + + if (m_state != eap_type_gsmsim_state_pending_kc_sres_query + || n_rand == 0 + || n_kc == 0 + || n_sres == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_identity.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + if (m_nonce_mt.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("n*RAND"), + n_rand->get_data(), + n_rand->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("n*KC"), + n_kc->get_data(), + n_kc->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("n*SRES"), + n_sres->get_data(), + n_sres->get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("identity"), + m_identity.get_data(), + m_identity.get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("NONCE MT"), + m_nonce_mt.get_data(), + m_nonce_mt.get_data_length())); + + + status = m_n_sres.set_copy_of_buffer(n_sres); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c XKEY(m_am_tools); + eap_variable_data_c K_encr(m_am_tools); + eap_variable_data_c K_aut(m_am_tools); + eap_variable_data_c master_session_key(m_am_tools); + + status = generate_shared_secred_keys( + EAP_TYPE_GSMSIM_KEYMAT_SIZE, + n_kc, + n_sres, + &XKEY, + &K_encr, + &K_aut, + &master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_saved_EAP_packet.get_is_valid_data() == true) + { + gsmsim_payloads_c * const l_gsmsim_payloads = new gsmsim_payloads_c(m_am_tools); + eap_automatic_variable_c l_gsmsim_payloads_automatic(m_am_tools, l_gsmsim_payloads); + + if (l_gsmsim_payloads == 0 + || l_gsmsim_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + gsmsim_header_c saved_EAP_packet( + m_am_tools, + m_saved_EAP_packet.get_data(), + m_saved_EAP_packet.get_data_length()); + + if (saved_EAP_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_gsmsim_packet( + &saved_EAP_packet, + m_saved_EAP_packet.get_data_length(), + l_gsmsim_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = check_message_authentication_code( + &K_aut, + l_gsmsim_payloads, + &saved_EAP_packet, + saved_EAP_packet.get_length()); + if (status != eap_status_ok) + { + (void) initialize_error_message(status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Decrypt and parse encrypted payload. + if (l_gsmsim_payloads->get_IV()->get_payload_included() == true + || l_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true) + { + if (l_gsmsim_payloads->get_IV()->get_payload_included() == true + && l_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true + && l_gsmsim_payloads->get_MAC()->get_payload_included() == true) + { + status = decrypt_DATA_payload( + l_gsmsim_payloads, + &K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = handle_DATA_payload( + gsmsim_subtype_Challenge, + l_gsmsim_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // All of these must be included + // or none of these must be included. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + else + { + // No encrypted payload. + // GSMSIM AM should remove re-authentication identity from favourite place. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::process_SIM_kc_sres(0x%08x): Resets re-authentication identity from database.\n"), + this)); + + status = m_am_type_gsmsim->store_reauthentication_id( + &m_send_network_id, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_reauthentication_identity.reset(); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = send_challenge_response_message( + &K_aut); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Store keys. + status = m_XKEY.set_copy_of_buffer(&XKEY); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = m_K_encr.set_copy_of_buffer(&K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = m_K_aut.set_copy_of_buffer(&K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = m_master_session_key.set_copy_of_buffer(&master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_gsmsim->store_reauth_parameters( + &XKEY, + &K_aut, + &K_encr, + EAP_TYPE_GSMSIM_INITIAL_REAUTH_COUNTER); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Authentication was successful. + if (m_use_result_indication == true) + { + // This version waits result indication. + if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, re-authentication OK, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH) + { + if (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, full authentication OK, pseudonym identity, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, full authentication OK, IMSI identity, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, full authentication OK, Re-auth identity, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_GSMSIM: %s, full authentication OK, unknown identity\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_GSMSIM: %s, unknown authentication OK, unknown identity\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + set_state(eap_type_gsmsim_state_waiting_for_notification_request_success); + } + else if (m_wait_eap_success_packet == false) + { + // This version does not wait EAP-Success message. + if (m_send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + m_send_network_id.get_destination_id(), + m_send_network_id.get_source_id(), + m_send_network_id.get_type()); + + // This version does not wait EAP-Success message. + status = finish_successful_authentication( + &receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // This version waits the EAP-Success message. + + if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, re-authentication OK, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH) + { + if (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, full authentication OK, pseudonym identity, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, full authentication OK, IMSI identity, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, full authentication OK, Re-auth identity, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_GSMSIM: %s, full authentication OK, unknown identity, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_GSMSIM: %s, unknown authentication OK, unknown identity, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + set_state(eap_type_gsmsim_state_waiting_for_success); + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_start_response_message( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier, + const eap_gsmsim_version version, + const gsmsim_payload_AT_type_e include_identity_to_start_response, + const eap_variable_data_c * const automatic_realm, ///< This could be zero pointer if this is not used. + const u32_t /* length_of_mnc */ +) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: GSMSIM-type %10s, %s, state %2d=%s\n"), + EAPL("gsmsim_subtype_Start"), + (m_is_client) ? EAPL("client") : EAPL("server"), + m_state, + get_state_string() + )); + + eap_buf_chain_wr_c gsmsim_initial_reply( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (gsmsim_initial_reply.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means GSMSIM does process every re-transmitted EAP-Request. + gsmsim_initial_reply.set_do_packet_retransmission(false); + } +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + + EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_gsmsim_header_offset+m_MTU; + } + + gsmsim_header_c gsmsim_response( + m_am_tools, + gsmsim_initial_reply.get_data_offset( + m_gsmsim_header_offset, + (packet_buffer_free-m_gsmsim_header_offset)), + (packet_buffer_free-m_gsmsim_header_offset)); + + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + gsmsim_response.reset_header( + packet_buffer_free-m_gsmsim_header_offset, + m_use_eap_expanded_type); + gsmsim_response.set_length( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_code(eap_code_response); + gsmsim_response.set_identifier(received_eap_identifier); + gsmsim_response.set_type( + eap_type_gsmsim, + m_use_eap_expanded_type); + + gsmsim_response.set_subtype(gsmsim_subtype_Start); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): include_identity_to_start_response %d=%s.\n"), + this, + include_identity_to_start_response, + gsmsim_payload_AT_header_c::get_payload_AT_string(include_identity_to_start_response))); + + update_buffer_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + m_gsmsim_header_offset+gsmsim_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t gsmsim_data_free = packet_buffer_free; + u32_t gsmsim_data_offset = 0u; + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) + { + // Re-authentication identity MUST be removed after first use. + // GSMSIM AM should remove re-authentication identity from favourite place. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Resets re-authentication identity from database.\n"), + this)); + + status = m_am_type_gsmsim->store_reauthentication_id( + &m_send_network_id, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Do not reset the local copy of re-authentocation identity. + } + + if (include_identity_to_start_response == gsmsim_payload_AT_PERMANENT_ID_REQ) + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(GSMSIM_IDENTITY_TYPE_IMSI_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects full authentication and IMSI identity.\n"), + this)); + } + else if (include_identity_to_start_response == gsmsim_payload_AT_FULLAUTH_ID_REQ) + { + eap_variable_data_c * const pseudonym = &m_pseudonym; + + if (pseudonym->get_is_valid_data() == true) + { + // We have pseudonym. + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects full authentication and pseudonym identity.\n"), + this)); + } + else // if (pseudonym->get_is_valid() == false) + { + // Because no pseudonym is available we must use IMSI. + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(GSMSIM_IDENTITY_TYPE_IMSI_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects full authentication and IMSI identity.\n"), + this)); + } + } + else if (include_identity_to_start_response == gsmsim_payload_AT_ANY_ID_REQ) + { + eap_variable_data_c * const reauthentication_identity = &m_reauthentication_identity; + eap_variable_data_c * const pseudonym = &m_pseudonym; + + if (reauthentication_identity->get_is_valid_data() == true) + { + // We have reauthentication identity. Re-authentication identity is NAI. + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION; + set_identity_type(GSMSIM_IDENTITY_TYPE_RE_AUTH_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects fast re-authentication and re-authentication identity.\n"), + this)); + } + else if (pseudonym->get_is_valid_data() == true) + { + // We have pseudonym. + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects full authentication and pseudonym identity.\n"), + this)); + } + else if (m_IMSI.get_is_valid_data() == true) + { + // Because no pseudonym is available we must use IMSI. + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(GSMSIM_IDENTITY_TYPE_IMSI_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects full authentication and IMSI identity.\n"), + this)); + } + else + { + // ERROR, no identity available. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + + if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH) + { + status = add_variable_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &m_nonce_mt, + gsmsim_payload_AT_NONCE_MT); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_version_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + version); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + if (include_identity_to_start_response != gsmsim_payload_NONE) + { + if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID) + { + eap_variable_data_c NAI(m_am_tools); + status = NAI.init(1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + NAI.set_is_valid(); + + status = generate_nai( + &NAI, + m_use_manual_realm, + get_nai_realm(), + &m_IMSI, + true, + &m_IMSI, + automatic_realm, + m_length_of_mnc); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_pseudonym_or_imsi_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &NAI, + gsmsim_payload_AT_IDENTITY); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save used NAI. + status = m_NAI.set_copy_of_buffer(&NAI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_response_message(): Client sends IMSI identity.\n"))); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID) + { + eap_variable_data_c * const pseudonym = &m_pseudonym; + + if (pseudonym->get_is_valid_data() == true) + { + // We have pseudonym. + + eap_variable_data_c NAI(m_am_tools); + status = NAI.init(1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + NAI.set_is_valid(); + + status = generate_nai( + &NAI, + m_use_manual_realm, + get_nai_realm(), + pseudonym, + false, + &m_IMSI, + automatic_realm, + m_length_of_mnc); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_pseudonym_or_imsi_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &NAI, + gsmsim_payload_AT_IDENTITY); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save used NAI. + status = m_NAI.set_copy_of_buffer(&NAI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_response_message(): Client sends pseudonym identity.\n"))); + } + else // if (pseudonym->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) + { + eap_variable_data_c * const reauthentication_identity = &m_reauthentication_identity; + + if (reauthentication_identity->get_is_valid_data() == true) + { + // We have reauthentication identity. Re-authentication identity is NAI. + status = add_pseudonym_or_imsi_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + reauthentication_identity, + gsmsim_payload_AT_IDENTITY); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save used NAI. + status = m_NAI.set_copy_of_buffer(reauthentication_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_response_message(): Client sends re-authentication identity.\n"))); + } + else + { + // ERROR, no identity available. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + gsmsim_initial_reply.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = packet_send( + &send_network_id, + &gsmsim_initial_reply, + m_gsmsim_header_offset, + gsmsim_response.get_header_length()+gsmsim_response.get_data_length(), + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + // Now we have on-going re-authentication. + set_state(eap_type_gsmsim_state_waiting_for_reauth_request); + } + else + { + // Now we have on-going full-authentication. + set_state(eap_type_gsmsim_state_waiting_for_challenge_request); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_gsmsim_notification_response( + const eap_gsmsim_notification_codes_e notification_code, + const bool add_at_counter_attribute) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: GSMSIM-type %10s, %s, state %2d=%s\n"), + EAPL("send_gsmsim_notification_response"), + (m_is_client) ? EAPL("client") : EAPL("server"), + m_state, + get_state_string() + )); + + eap_buf_chain_wr_c eap_notification_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_notification_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means GSMSIM does process every re-transmitted EAP-Request. + eap_notification_packet.set_do_packet_retransmission(false); + } +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + + EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_gsmsim_header_offset+m_MTU; + } + + gsmsim_header_c gsmsim_response( + m_am_tools, + eap_notification_packet.get_data_offset( + m_gsmsim_header_offset, + (packet_buffer_free-m_gsmsim_header_offset)), + (packet_buffer_free-m_gsmsim_header_offset)); + + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + gsmsim_response.reset_header( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_length( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_code(eap_code_response); + gsmsim_response.set_identifier(static_cast(m_last_eap_identifier)); + gsmsim_response.set_type( + eap_type_gsmsim, + m_use_eap_expanded_type); + gsmsim_response.set_subtype(gsmsim_subtype_Notification); + + + update_buffer_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + m_gsmsim_header_offset+gsmsim_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t gsmsim_data_free = packet_buffer_free; + u32_t gsmsim_data_offset = 0u; + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c * K_aut = 0; + eap_variable_data_c orig_K_aut(m_am_tools); + + if (get_gsmsim_notification_code_P_bit(notification_code) == false) + { + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_gsmsim_MAC_attributes_c MAC_attributes; + + if (add_at_counter_attribute == true) + { + // If EAP-Request/SIM/Notification is used on fast a re-authentication + // exchange, and if the P bit in AT_NOTIFICATION is set to zero, then + // AT_COUNTER is used for replay protection. In this case, the + // AT_ENCR_DATA and AT_IV attributes MUST be included, and the + // encapsulated plaintext attributes MUST include the AT_COUNTER + // attribute. The counter value included in AT_COUNTER MUST be the same + // as in the EAP-Request/SIM/Re-authentication packet on the same fast + // re-authentication exchange. + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + u32_t reauth_counter = 0u; + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_gsmsim->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_gsmsim_notification_response(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + reauth_counter)); + + K_aut = &orig_K_aut; + + // - - - - - - - - - - - - + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_type_gsmsim->generate_encryption_IV( + m_IV.get_payload_buffer(), + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = add_variable_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + m_IV.get_payload_buffer(), + gsmsim_payload_AT_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // Encrypted data. + { + gsmsim_payload_AT_header_c gp_encrypted_data( + m_am_tools, + gsmsim_response.get_data_offset( + gsmsim_data_offset, + gsmsim_data_free), + gsmsim_data_free); + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Initialize the length of encrypted data to maximum length. + // Later this will be set to correct length. + gp_encrypted_data.reset_header(gsmsim_payload_AT_header_c::get_max_payload_data_length()); + gp_encrypted_data.set_current_payload(gsmsim_payload_AT_ENCR_DATA); + + update_payload_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + gp_encrypted_data.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_offset, + &packet_buffer_free); + + u32_t encrypted_data_offset_begin = packet_buffer_offset; + + // - - - - - - - - - - - - + + status = add_counter_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + static_cast(reauth_counter)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_padding_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + (packet_buffer_offset - encrypted_data_offset_begin) // Length of the plain text. + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + gp_encrypted_data.set_data_length( + static_cast(packet_buffer_offset - encrypted_data_offset_begin)); + + // - - - - - - - - - - - - + + status = encrypt_DATA_payload( + gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), + gp_encrypted_data.get_data_length(), + m_IV.get_payload_buffer(), + &orig_K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); + } + + } + else + { + K_aut = &m_K_aut; + } // if (add_counter_payload == true) + + // - - - - - - - - - - - - + + // Add AT_MAC attribute. + status = add_mac_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + gsmsim_response.get_header_buffer(gsmsim_response.get_length()), + gsmsim_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + gsmsim_response.get_subtype(), + gsmsim_response.get_code(), + K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" send: EAP-Response/Notification packet"), + gsmsim_response.get_header_buffer(gsmsim_response.get_length()), + gsmsim_response.get_length())); + + status = packet_send( + &m_send_network_id, + &eap_notification_packet, + m_gsmsim_header_offset, + gsmsim_response.get_length(), + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_gsmsim_client_error_response() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: send: GSMSIM-type %10s, %s, state %2d=%s, m_client_error_code %d\n"), + EAPL("send_gsmsim_client_error_response"), + (m_is_client) ? EAPL("client") : EAPL("server"), + m_state, + get_state_string(), + m_client_error_code + )); + + eap_buf_chain_wr_c eap_client_error_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_client_error_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means GSMSIM does process every re-transmitted EAP-Request. + eap_client_error_packet.set_do_packet_retransmission(false); + } +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + + EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_gsmsim_header_offset+m_MTU; + } + + gsmsim_header_c gsmsim_response( + m_am_tools, + eap_client_error_packet.get_data_offset( + m_gsmsim_header_offset, + (packet_buffer_free-m_gsmsim_header_offset)), + (packet_buffer_free-m_gsmsim_header_offset)); + + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + gsmsim_response.reset_header( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_length( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_code(eap_code_response); + gsmsim_response.set_identifier(static_cast(m_last_eap_identifier)); + gsmsim_response.set_type( + eap_type_gsmsim, + m_use_eap_expanded_type); + gsmsim_response.set_subtype(gsmsim_subtype_Client_Error); + + + update_buffer_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + m_gsmsim_header_offset+gsmsim_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t gsmsim_data_free = packet_buffer_free; + u32_t gsmsim_data_offset = 0u; + + eap_status_e status = add_client_error_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + m_client_error_code); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + eap_client_error_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_client_error_packet.set_data_length(packet_buffer_offset); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" send: EAP-Response/Client-Error packet"), + gsmsim_response.get_header_buffer(gsmsim_response.get_length()), + gsmsim_response.get_length())); + + status = packet_send( + &m_send_network_id, + &eap_client_error_packet, + m_gsmsim_header_offset, + gsmsim_response.get_length(), + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_challenge_response_message( + eap_variable_data_c * const K_aut) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: GSMSIM-type %10s, %s, state %2d=%s\n"), + EAPL("gsmsim_subtype_Challenge"), + (m_is_client) ? EAPL("client") : EAPL("server"), + m_state, + get_state_string() + )); + + eap_buf_chain_wr_c gsmsim_initial_reply( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (gsmsim_initial_reply.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means GSMSIM does process every re-transmitted EAP-Request. + gsmsim_initial_reply.set_do_packet_retransmission(false); + } +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + + EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_gsmsim_header_offset+m_MTU; + } + + gsmsim_header_c gsmsim_response( + m_am_tools, + gsmsim_initial_reply.get_data_offset( + m_gsmsim_header_offset, + (packet_buffer_free-m_gsmsim_header_offset)), + (packet_buffer_free-m_gsmsim_header_offset)); + + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + gsmsim_response.reset_header( + packet_buffer_free, + m_use_eap_expanded_type); + gsmsim_response.set_length( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_code(eap_code_response); + gsmsim_response.set_identifier(m_last_eap_identifier); + gsmsim_response.set_type( + eap_type_gsmsim, + m_use_eap_expanded_type); + gsmsim_response.set_subtype(gsmsim_subtype_Challenge); + + update_buffer_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + m_gsmsim_header_offset+gsmsim_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_type_gsmsim_c::send_challenge_response_message(0x%08x).\n"), + this)); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t gsmsim_data_free = packet_buffer_free; + u32_t gsmsim_data_offset = 0u; + eap_status_e status = eap_status_process_general_error; + + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_gsmsim_MAC_attributes_c MAC_attributes; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_use_result_indication == true) + { + // We support use of protected success indications. + status = add_simple_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + gsmsim_payload_AT_RESULT_IND); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + status = add_mac_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + gsmsim_initial_reply.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + gsmsim_response.get_header_buffer(gsmsim_response.get_length()), + gsmsim_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + gsmsim_response.get_subtype(), + gsmsim_response.get_code(), + K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + gsmsim_initial_reply.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = packet_send( + &m_send_network_id, + &gsmsim_initial_reply, + m_gsmsim_header_offset, + gsmsim_response.get_header_length()+gsmsim_response.get_data_length(), + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_reauthentication_response_message( + const eap_variable_data_c * const orig_XKEY, + const eap_variable_data_c * const orig_K_aut, + const eap_variable_data_c * const orig_K_encr, + const eap_variable_data_c * const reauth_username, + const eap_variable_data_c * const reauth_nonce_s, + const u16_t reauth_counter, + const u8_t eap_identifier, + const bool include_at_counter_too_small) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: GSMSIM-subtype %10s, %s, state %2d=%s\n"), + EAPL("gsmsim_subtype_Re_authentication"), + EAPL("client"), + m_state, + get_state_string() + )); + + eap_status_e status = eap_status_process_general_error; + + eap_buf_chain_wr_c request_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (request_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means GSMSIM does process every re-transmitted EAP-Request. + request_packet.set_do_packet_retransmission(false); + } +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + + EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_gsmsim_header_offset+m_MTU; + } + + gsmsim_header_c gsmsim_response( + m_am_tools, + request_packet.get_data_offset( + m_gsmsim_header_offset, + (packet_buffer_free-m_gsmsim_header_offset)), + (packet_buffer_free-m_gsmsim_header_offset)); + + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_reauthentication_response_message: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gsmsim_response.reset_header( + packet_buffer_free-m_gsmsim_header_offset, + m_use_eap_expanded_type); + gsmsim_response.set_length( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_code(eap_code_response); + gsmsim_response.set_identifier(eap_identifier); + gsmsim_response.set_type( + eap_type_gsmsim, + m_use_eap_expanded_type); + gsmsim_response.set_subtype(gsmsim_subtype_Re_authentication); + + update_buffer_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + m_gsmsim_header_offset+gsmsim_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_reauthentication_response_message(0x%08x).\n"), + this)); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t gsmsim_data_free = packet_buffer_free; + u32_t gsmsim_data_offset = 0u; + + eap_variable_data_c master_session_key(m_am_tools); + + status = generate_reauth_shared_secred_keys( + EAP_TYPE_GSMSIM_KEYMAT_SIZE, + orig_XKEY, + reauth_counter, + reauth_username, + reauth_nonce_s, + &master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + if (m_use_result_indication == true) + { + // We support use of protected success indications. + status = add_simple_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + gsmsim_payload_AT_RESULT_IND); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_type_gsmsim->generate_encryption_IV( + m_IV.get_payload_buffer(), + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = add_variable_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + m_IV.get_payload_buffer(), + gsmsim_payload_AT_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_gsmsim_MAC_attributes_c MAC_attributes; + + // Encrypted data. + { + gsmsim_payload_AT_header_c gp_encrypted_data( + m_am_tools, + gsmsim_response.get_data_offset( + gsmsim_data_offset, + gsmsim_data_free), + gsmsim_data_free); + if (gp_encrypted_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Initialize the length of encrypted data to maximum length. + // Later this will be set to correct length. + gp_encrypted_data.reset_header(gsmsim_payload_AT_header_c::get_max_payload_data_length()); + gp_encrypted_data.set_current_payload(gsmsim_payload_AT_ENCR_DATA); + + update_payload_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + gp_encrypted_data.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_offset, + &packet_buffer_free); + + u32_t encrypted_data_offset_begin = packet_buffer_offset; + + + // - - - - - - - - - - - - + + if (include_at_counter_too_small == true) + { + status = add_simple_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + gsmsim_payload_AT_COUNTER_TOO_SMALL); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + status = add_counter_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + reauth_counter); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_padding_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + (packet_buffer_offset - encrypted_data_offset_begin) // Length of the plain text. + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + gp_encrypted_data.set_data_length( + static_cast(packet_buffer_offset - encrypted_data_offset_begin)); + + // - - - - - - - - - - - - + + status = encrypt_DATA_payload( + gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), + gp_encrypted_data.get_data_length(), + m_IV.get_payload_buffer(), + orig_K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); + } + + + + // - - - - - - - - - - - - + + status = add_mac_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + request_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + gsmsim_response.get_header_buffer(gsmsim_response.get_length()), + gsmsim_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + gsmsim_response.get_subtype(), + gsmsim_response.get_code(), + orig_K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + request_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_reauthentication_request_message()\n"))); + + status = packet_send( + &m_send_network_id, + &request_packet, + m_gsmsim_header_offset, + gsmsim_response.get_header_length()+gsmsim_response.get_data_length(), + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + if (include_at_counter_too_small == false) + { + status = m_master_session_key.set_copy_of_buffer(&master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (include_at_counter_too_small == true) + { + // The full authentication must follow. + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::decrypt_DATA_payload( + gsmsim_payloads_c * const p_gsmsim_payloads, + const eap_variable_data_c * const encryption_key + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t aes_key_length = aes.get_key_length(); + if (encryption_key->get_data_length() < aes_key_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + if (p_gsmsim_payloads->get_ENCR_DATA()->get_data_length() == 0 + || (p_gsmsim_payloads->get_ENCR_DATA()->get_data_length() % aes_key_length) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + if (p_gsmsim_payloads->get_IV()->get_payload_included() == false + || p_gsmsim_payloads->get_IV()->get_data_length() == 0u + || encryption_key->get_is_valid_data() == false + || encryption_key->get_data_length() == 0u) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + if (p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == false + || p_gsmsim_payloads->get_ENCR_DATA()->get_data_length() == 0u) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); + } + + + status = cbc_aes.set_decryption_key( + p_gsmsim_payloads->get_IV()->get_data(p_gsmsim_payloads->get_IV()->get_data_length()), + p_gsmsim_payloads->get_IV()->get_data_length(), + encryption_key->get_data(), + aes_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = cbc_aes.decrypt_data( + p_gsmsim_payloads->get_ENCR_DATA()->get_data(p_gsmsim_payloads->get_ENCR_DATA()->get_data_length()), + p_gsmsim_payloads->get_ENCR_DATA()->get_data_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_DATA_payload( + const gsmsim_subtype_e subtype, + gsmsim_payloads_c * const p_gsmsim_payloads + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (p_gsmsim_payloads->get_ENCR_DATA() == 0 + || p_gsmsim_payloads->get_ENCR_DATA()->get_data_length() == 0u) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t state_payload_buffer_length = p_gsmsim_payloads->get_ENCR_DATA()->get_data_length(); + const gsmsim_payload_AT_header_c gp_data_payload( + m_am_tools, + p_gsmsim_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), + state_payload_buffer_length); + + if (gp_data_payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_gsmsim_payload( + &gp_data_payload, + &state_payload_buffer_length, + p_gsmsim_payloads, + subtype); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (p_gsmsim_payloads->get_NEXT_PSEUDONYM()->get_payload_included() == true) + { + if (p_gsmsim_payloads->get_padding_payload()->get_payload_included() == true + && p_gsmsim_payloads->get_padding_payload()->get_data_length() > 0u) + { + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Check the padding bytes. + // Must be filled with zero (0x00) bytes. + status = cbc_aes.check_padding_bytes( + p_gsmsim_payloads->get_padding_payload()->get_data(p_gsmsim_payloads->get_padding_payload()->get_data_length()), + p_gsmsim_payloads->get_padding_payload()->get_data_length(), + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // GSMSIM AM could store pseudonym to favourite place. + status = m_am_type_gsmsim->store_pseudonym_id( + &m_send_network_id, + p_gsmsim_payloads->get_NEXT_PSEUDONYM()->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (p_gsmsim_payloads->get_NEXT_REAUTH_ID()->get_payload_included() == true) + { + if (p_gsmsim_payloads->get_padding_payload()->get_payload_included() == true + && p_gsmsim_payloads->get_padding_payload()->get_data_length() > 0u) + { + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Check the padding bytes. + // Must be filled with zero (0x00) bytes. + status = cbc_aes.check_padding_bytes( + p_gsmsim_payloads->get_padding_payload()->get_data(p_gsmsim_payloads->get_padding_payload()->get_data_length()), + p_gsmsim_payloads->get_padding_payload()->get_data_length(), + 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // GSMSIM AM could store pseudonym to favourite place. + status = m_am_type_gsmsim->store_reauthentication_id( + &m_send_network_id, + p_gsmsim_payloads->get_NEXT_REAUTH_ID()->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // GSMSIM AM should remove re-authentication identity from favourite place. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_DATA_payload(0x%08x): Resets re-authentication identity from database.\n"), + this)); + + status = m_am_type_gsmsim->store_reauthentication_id( + &m_send_network_id, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_reauthentication_identity.reset(); + } + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_start_request_message( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t /* gsmsim_packet_length */, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + eap_status_e status = eap_status_process_general_error; + +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + const eap_type_gsmsim_state_variable_e gsmsim_start_request_states[] = + { + eap_type_gsmsim_state_waiting_for_start_request, + eap_type_gsmsim_state_pseydonym_waiting_for_start_request, + eap_type_gsmsim_state_imsi_waiting_for_start_request, + eap_type_gsmsim_state_waiting_for_challenge_request, + eap_type_gsmsim_state_waiting_for_reauth_request, + }; + + if (verify_states(gsmsim_start_request_states, GSMSIM_STATE_COUNT(gsmsim_start_request_states)) == true) +#else + if (m_state == eap_type_gsmsim_state_waiting_for_start_request + || m_state == eap_type_gsmsim_state_pseydonym_waiting_for_start_request + || m_state == eap_type_gsmsim_state_imsi_waiting_for_start_request + || m_state == eap_type_gsmsim_state_waiting_for_challenge_request + || m_state == eap_type_gsmsim_state_waiting_for_reauth_request) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { + // This could be first or retransmission request. + + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be // RESULT_IND + ) == true + ) + { + // NOTE, this message is unauthenticated. Anybody could sent this message. + + bool includes_other_version_than_1 = false; + + eap_gsmsim_version selected_version = select_version( + p_gsmsim_payloads->get_VERSION_LIST(), + &includes_other_version_than_1); + + if (selected_version == GSMSIM_ILLEGAL_VERSION) + { + // ERROR, no supported version. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_request_message(0x%08x), illegal version list.\n"), + this)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + if (p_gsmsim_payloads->get_includes_unknown_attribute() != gsmsim_payload_NONE + && includes_other_version_than_1 == false) + { + // EAP-SIM version 1 must NOT include unknown attributes. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_request_message(0x%08x), illegal payload %d=0x%04x.\n"), + this, + p_gsmsim_payloads->get_includes_unknown_attribute(), + p_gsmsim_payloads->get_includes_unknown_attribute())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gsmsim_payload_AT_type_e include_identity_to_start_response = gsmsim_payload_NONE; + + + { + if ((p_gsmsim_payloads->get_PERMANENT_ID_REQ()->get_payload_included() == true + && p_gsmsim_payloads->get_FULLAUTH_ID_REQ()->get_payload_included() == true) + || (p_gsmsim_payloads->get_PERMANENT_ID_REQ()->get_payload_included() == true + && p_gsmsim_payloads->get_ANY_ID_REQ()->get_payload_included() == true) + || (p_gsmsim_payloads->get_FULLAUTH_ID_REQ()->get_payload_included() == true + && p_gsmsim_payloads->get_ANY_ID_REQ()->get_payload_included() == true)) + { + // Only one of these is allowed. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_request_message(0x%08x), illegal payloads.\n"), + this)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (p_gsmsim_payloads->get_PERMANENT_ID_REQ()->get_payload_included() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message ") + EAPL("gsmsim_payload_AT_PERMANENT_ID_REQ\n"))); + // Note, this is optional, included only when pseudonym decode failed in server. + include_identity_to_start_response = gsmsim_payload_AT_PERMANENT_ID_REQ; + } + else if (p_gsmsim_payloads->get_FULLAUTH_ID_REQ()->get_payload_included() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message ") + EAPL("gsmsim_payload_AT_FULLAUTH_ID_REQ\n"))); + // Note, this is optional, included only when reauthentication identity decode failed in server. + include_identity_to_start_response = gsmsim_payload_AT_FULLAUTH_ID_REQ; + } + else if (p_gsmsim_payloads->get_ANY_ID_REQ()->get_payload_included() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message ") + EAPL("gsmsim_payload_AT_ANY_ID_REQ\n"))); + // Note, this is optional, included only when server have no identity of client. + include_identity_to_start_response = gsmsim_payload_AT_ANY_ID_REQ; + } + } + + if (m_nonce_mt.get_is_valid_data() == false) + { + // Note, if this message is retransmitted request the NONCE_MT + // is already generated. + status = generate_nonce(EAP_TYPE_GSMSIM_NONCE_MT_SIZE, &m_nonce_mt); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + u32_t version_payload_length = p_gsmsim_payloads->get_VERSION_LIST()->get_original_header()->get_data_length(); + u32_t real_payload_length = p_gsmsim_payloads->get_VERSION_LIST()->get_original_header()->get_reserved(); + + if (real_payload_length == 0 + || real_payload_length > version_payload_length) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + u32_t version_count = real_payload_length/sizeof(u16_t); + u16_t *payload_version_list = reinterpret_cast(p_gsmsim_payloads->get_VERSION_LIST() + ->get_original_header()->get_data(real_payload_length)); + + status = save_version(payload_version_list, version_count, selected_version); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_include_identity_to_start_response = include_identity_to_start_response; + + + if (include_identity_to_start_response == gsmsim_payload_NONE + && (m_identity.get_is_valid_data() == false)) + { + // We must query the previous sent EAP-Identity from EAP_Core. + // The EAP_Core saves the sent EAP-Identity when the EAP-Identity is + // sent to the network. + // Previous EAP-type was NOT this instance. EAP-Identity was queried from other instance. + status = get_type_partner()->get_saved_eap_identity(&m_identity); + if (status != eap_status_ok) + { + // We do not have the identity server accepted anymore. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_NAI.set_copy_of_buffer(&m_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + if (include_identity_to_start_response == gsmsim_payload_AT_ANY_ID_REQ + && (m_reauthentication_identity.get_is_valid_data() == false + && m_pseudonym.get_is_valid_data() == false + && m_IMSI.get_is_valid_data() == false + && m_automatic_realm_read == false)) + { + eap_variable_data_c IMSI(m_am_tools); + eap_variable_data_c pseudonym(m_am_tools); + eap_variable_data_c reauthentication_identity(m_am_tools); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message ") + EAPL("gsmsim_payload_AT_ANY_ID_REQ\n"))); + + status = query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + &IMSI, + &pseudonym, + &reauthentication_identity, + &m_automatic_realm, + &m_length_of_mnc, + false, + include_identity_to_start_response, + eap_type_gsmsim_complete_start_request, + received_gsmsim->get_identifier()); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") + EAPL("completed returns eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok) + { + // This is the error case. + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") + EAPL("error returns eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (reauthentication_identity.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message ") + EAPL("reauthentication_identity\n"))); + + status = m_reauthentication_identity.set_copy_of_buffer(&reauthentication_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(&m_reauthentication_identity, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (pseudonym.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message pseudonym\n"))); + + m_reauthentication_identity.reset(); + status = m_pseudonym.set_copy_of_buffer(&pseudonym); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(&m_pseudonym, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (IMSI.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message IMSI\n"))); + + m_reauthentication_identity.reset(); + m_pseudonym.reset(); + status = m_IMSI.set_copy_of_buffer(&IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(&m_IMSI, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (include_identity_to_start_response == gsmsim_payload_AT_FULLAUTH_ID_REQ + && (m_pseudonym.get_is_valid_data() == false + && m_IMSI.get_is_valid_data() == false + && m_automatic_realm_read == false)) + { + eap_variable_data_c IMSI(m_am_tools); + eap_variable_data_c pseudonym(m_am_tools); + eap_variable_data_c reauthentication_identity(m_am_tools); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message ") + EAPL("gsmsim_payload_AT_FULLAUTH_ID_REQ\n"))); + + status = query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + &IMSI, + &pseudonym, + &reauthentication_identity, + &m_automatic_realm, + &m_length_of_mnc, + false, + include_identity_to_start_response, + eap_type_gsmsim_complete_start_request, + received_gsmsim->get_identifier()); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") + EAPL("completed returns eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok) + { + // This is the error case. + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") + EAPL("error returns eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (pseudonym.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message pseudonym\n"))); + + m_reauthentication_identity.reset(); + status = m_pseudonym.set_copy_of_buffer(&pseudonym); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(&m_pseudonym, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (IMSI.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message IMSI\n"))); + + m_reauthentication_identity.reset(); + m_pseudonym.reset(); + status = m_IMSI.set_copy_of_buffer(&IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(&m_IMSI, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (include_identity_to_start_response == gsmsim_payload_AT_PERMANENT_ID_REQ + && m_IMSI.get_is_valid_data() == false + && m_automatic_realm_read == false) + { + eap_variable_data_c IMSI(m_am_tools); + eap_variable_data_c pseudonym(m_am_tools); + eap_variable_data_c reauthentication_identity(m_am_tools); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message ") + EAPL("gsmsim_payload_AT_PERMANENT_ID_REQ\n"))); + + status = query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + &IMSI, + &pseudonym, + &reauthentication_identity, + &m_automatic_realm, + &m_length_of_mnc, + false, + include_identity_to_start_response, + eap_type_gsmsim_complete_start_request, + received_gsmsim->get_identifier()); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") + EAPL("completed returns eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok) + { + // This is the error case. + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") + EAPL("error returns eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (IMSI.get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message IMSI\n"))); + + m_reauthentication_identity.reset(); + m_pseudonym.reset(); + status = m_IMSI.set_copy_of_buffer(&IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(&m_IMSI, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + save_current_state(); + set_state(eap_type_gsmsim_state_analyse_start_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_start_request_message(0x%08x).\n"), + this)); + + status = send_start_response_message( + receive_network_id, + received_gsmsim->get_identifier(), + selected_version, + include_identity_to_start_response, + &m_automatic_realm, + m_length_of_mnc); + + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_request_message(1): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_gsmsim_notification_request_message_reauthentication( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t /*gsmsim_packet_length*/, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: GSMSIM-type %10s, %s, state %2d=%s\n"), + EAPL("handle_gsmsim_notification_request_message_reauthentication"), + (m_is_client) ? EAPL("client") : EAPL("server"), + m_state, + get_state_string() + )); + +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + const eap_type_gsmsim_state_variable_e gsmsim_notification_request_message_reauthentication_states_1[] = + { + eap_type_gsmsim_state_waiting_for_success, + eap_type_gsmsim_state_success, + eap_type_gsmsim_state_waiting_for_notification_request_success, + }; + + const eap_type_gsmsim_state_variable_e gsmsim_notification_request_message_reauthentication_states_2[] = + { + eap_type_gsmsim_state_waiting_for_identity_request, + eap_type_gsmsim_state_pending_identity_query, + eap_type_gsmsim_state_waiting_for_start_request, + eap_type_gsmsim_state_imsi_waiting_for_start_request, + eap_type_gsmsim_state_pseydonym_waiting_for_start_request, + eap_type_gsmsim_state_analyse_start_request, + eap_type_gsmsim_state_waiting_for_challenge_request, + eap_type_gsmsim_state_analyses_challenge_request, + eap_type_gsmsim_state_pending_kc_sres_query, + eap_type_gsmsim_state_waiting_for_reauth_request, + eap_type_gsmsim_state_analyses_reauthentication_request, + eap_type_gsmsim_state_waiting_for_success, + eap_type_gsmsim_state_success, + eap_type_gsmsim_state_waiting_for_notification_request_success, + eap_type_gsmsim_state_failure, + }; + + if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == false + && verify_states(gsmsim_notification_request_message_reauthentication_states_1, + GSMSIM_STATE_COUNT(gsmsim_notification_request_message_reauthentication_states_1)) == true) +#else + // The second most significant bit of the notification code is called + // the Phase bit (P bit). It specifies at which phase of the EAP-SIM + // exchange the notification can be used. + if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == false + && (m_state == eap_type_gsmsim_state_waiting_for_success + || m_state == eap_type_gsmsim_state_success + || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success) + ) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { + // If the P bit is set to zero, + // the notification can only be used after a successful EAP/SIM/ + // Challenge round in full authentication or a successful EAP/SIM/ + // Re-authentication round in reautentication. A re-authentication round + // is considered successful only if the peer has successfully verified + // AT_MAC and AT_COUNTER attributes, and does not include the + // AT_COUNTER_TOO_SMALL attribute in EAP-Response/SIM/Re-authentication. + + // The AT_MAC attribute MUST beincluded if the P bit of the notification + // code in AT_NOTIFICATION is set to zero, and MUST NOT be included in + // cases when the P bit is set to one. The P bit is discussed in Section + // 4.4. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be // RESULT_IND + ) == true + ) + { + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_aut(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + u32_t reauth_counter = 0u; + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_gsmsim->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_gsmsim_notification_request_message_reauthentication(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + reauth_counter)); + + status = check_message_authentication_code( + &orig_K_aut, + p_gsmsim_payloads, + received_gsmsim, + received_gsmsim->get_length()); + if (status != eap_status_ok) + { + (void) initialize_error_message(status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + bool authentication_ok = true; + + // Decrypt and parse encrypted payload. + { + gsmsim_payloads_c * const l_gsmsim_payloads = new gsmsim_payloads_c(m_am_tools); + eap_automatic_variable_c l_gsmsim_payloads_automatic(m_am_tools, l_gsmsim_payloads); + + if (l_gsmsim_payloads == 0 + || l_gsmsim_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = decrypt_DATA_payload( + p_gsmsim_payloads, + &orig_K_encr); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t state_payload_buffer_length = p_gsmsim_payloads->get_ENCR_DATA()->get_data_length(); + const gsmsim_payload_AT_header_c gp_data_payload( + m_am_tools, + p_gsmsim_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), + state_payload_buffer_length); + + status = parse_gsmsim_payload( + &gp_data_payload, + &state_payload_buffer_length, + l_gsmsim_payloads, + received_gsmsim->get_subtype()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (l_gsmsim_payloads->get_COUNTER()->get_payload_included() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u32_t counter = l_gsmsim_payloads->get_COUNTER()->get_original_header()->get_reserved(); + + if (counter == reauth_counter) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_gsmsim_notification_request_message_reauthentication(): ") + EAPL("reauth counter %d OK, %d=%s.\n"), + reauth_counter, + m_state, + get_state_string())); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message_reauthentication(): ") + EAPL("reauth counter %d wrong, should be %d, %d=%s.\n"), + counter, + reauth_counter, + m_state, + get_state_string())); + + authentication_ok = false; + } + } + + + bool do_increase_reauth_counter(false); + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (authentication_ok == false + || get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + + set_state(eap_type_gsmsim_state_failure); + + // This will terminate session immediately. + get_type_partner()->set_session_timeout(0ul); + } + else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + if (m_gsmsim_notification_code == eap_gsmsim_notification_F_set_no_P_user_authenticated) + { + do_increase_reauth_counter = true; + + if (m_wait_eap_success_packet == false) + { + status = finish_successful_authentication( + receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // This version waits the EAP-Success message. + set_state(eap_type_gsmsim_state_waiting_for_success); + status = eap_status_ok; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, re-authentication OK, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + } + } + + status = send_gsmsim_notification_response( + m_gsmsim_notification_code, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (do_increase_reauth_counter == true) + { + // Re-authentication counter is increased only on first time. + // In order to use re-authentication, the client and the server need to + // update re-authentication counter value. + status = m_am_type_gsmsim->increase_reauth_counter(); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(1): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + else if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == true + && verify_states(gsmsim_notification_request_message_reauthentication_states_2, + GSMSIM_STATE_COUNT(gsmsim_notification_request_message_reauthentication_states_2)) == true) +#else + else if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == true + && (m_state == eap_type_gsmsim_state_waiting_for_identity_request + || m_state == eap_type_gsmsim_state_pending_identity_query + || m_state == eap_type_gsmsim_state_waiting_for_start_request + || m_state == eap_type_gsmsim_state_imsi_waiting_for_start_request + || m_state == eap_type_gsmsim_state_pseydonym_waiting_for_start_request + || m_state == eap_type_gsmsim_state_analyse_start_request + || m_state == eap_type_gsmsim_state_waiting_for_challenge_request + || m_state == eap_type_gsmsim_state_analyses_challenge_request + || m_state == eap_type_gsmsim_state_pending_kc_sres_query + || m_state == eap_type_gsmsim_state_waiting_for_reauth_request + || m_state == eap_type_gsmsim_state_analyses_reauthentication_request + || m_state == eap_type_gsmsim_state_waiting_for_success + || m_state == eap_type_gsmsim_state_success + || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success + || m_state == eap_type_gsmsim_state_failure)) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { + // If the P bit is set to one, the notification can only by used before + // the EAP/SIM/Challenge round in full authentication, or before the + // EAP/SIM/Re-authentication round in reauthentication. + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + } + else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + } + + status = initialize_notification_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_gsmsim_notification_request_message_full_authentication( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t /*gsmsim_packet_length*/, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: GSMSIM-type %10s, %s, state %2d=%s\n"), + EAPL("handle_gsmsim_notification_request_message_full_authentication"), + (m_is_client) ? EAPL("client") : EAPL("server"), + m_state, + get_state_string() + )); + +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + const eap_type_gsmsim_state_variable_e gsmsim_notification_request_message_full_authentication_states_1[] = + { + eap_type_gsmsim_state_waiting_for_success, + eap_type_gsmsim_state_success, + eap_type_gsmsim_state_waiting_for_notification_request_success, + }; + + const eap_type_gsmsim_state_variable_e gsmsim_notification_request_message_full_authentication_states_2[] = + { + eap_type_gsmsim_state_waiting_for_identity_request, + eap_type_gsmsim_state_pending_identity_query, + eap_type_gsmsim_state_waiting_for_start_request, + eap_type_gsmsim_state_imsi_waiting_for_start_request, + eap_type_gsmsim_state_pseydonym_waiting_for_start_request, + eap_type_gsmsim_state_analyse_start_request, + eap_type_gsmsim_state_waiting_for_challenge_request, + eap_type_gsmsim_state_analyses_challenge_request, + eap_type_gsmsim_state_pending_kc_sres_query, + eap_type_gsmsim_state_waiting_for_reauth_request, + eap_type_gsmsim_state_analyses_reauthentication_request, + eap_type_gsmsim_state_waiting_for_success, + eap_type_gsmsim_state_success, + eap_type_gsmsim_state_waiting_for_notification_request_success, + eap_type_gsmsim_state_failure, + }; + + if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == false + && verify_states(gsmsim_notification_request_message_full_authentication_states_1, + GSMSIM_STATE_COUNT(gsmsim_notification_request_message_full_authentication_states_1)) == true) +#else + // The second most significant bit of the notification code is called + // the Phase bit (P bit). It specifies at which phase of the EAP-SIM + // exchange the notification can be used. + if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == false + && (m_state == eap_type_gsmsim_state_waiting_for_success + || m_state == eap_type_gsmsim_state_success + || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success) + ) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { + // If the P bit is set to zero, + // the notification can only be used after a successful EAP/SIM/ + // Challenge round in full authentication or a successful EAP/SIM/ + // Re-authentication round in reautentication. A re-authentication round + // is considered successful only if the peer has successfully verified + // AT_MAC and AT_COUNTER attributes, and does not include the + // AT_COUNTER_TOO_SMALL attribute in EAP-Response/SIM/Re-authentication. + + // The AT_MAC attribute MUST beincluded if the P bit of the notification + // code in AT_NOTIFICATION is set to zero, and MUST NOT be included in + // cases when the P bit is set to one. The P bit is discussed in Section + // 4.4. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_optional // RESULT_IND + ) == true + ) + { + status = check_message_authentication_code( + &m_K_aut, + p_gsmsim_payloads, + received_gsmsim, + received_gsmsim->get_length()); + if (status != eap_status_ok) + { + (void) initialize_error_message(status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_use_result_indication == false + && m_gsmsim_notification_code == eap_gsmsim_notification_F_set_no_P_user_authenticated) + { + // ERROR: We did not require result indication and server send it to us. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + + set_state(eap_type_gsmsim_state_failure); + + // This will terminate session immediately. + get_type_partner()->set_session_timeout(0ul); + } + else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + if (m_gsmsim_notification_code == eap_gsmsim_notification_F_set_no_P_user_authenticated) + { + if (m_wait_eap_success_packet == false) + { + status = finish_successful_authentication( + receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // This version waits the EAP-Success message. + set_state(eap_type_gsmsim_state_waiting_for_success); + status = eap_status_ok; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, full-authentication OK, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + } + } + + status = send_gsmsim_notification_response( + m_gsmsim_notification_code, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(1): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + else if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == true + && verify_states(gsmsim_notification_request_message_full_authentication_states_2, + GSMSIM_STATE_COUNT(gsmsim_notification_request_message_full_authentication_states_2)) == true) +#else + else if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == true + && (m_state == eap_type_gsmsim_state_waiting_for_identity_request + || m_state == eap_type_gsmsim_state_pending_identity_query + || m_state == eap_type_gsmsim_state_waiting_for_start_request + || m_state == eap_type_gsmsim_state_imsi_waiting_for_start_request + || m_state == eap_type_gsmsim_state_pseydonym_waiting_for_start_request + || m_state == eap_type_gsmsim_state_analyse_start_request + || m_state == eap_type_gsmsim_state_waiting_for_challenge_request + || m_state == eap_type_gsmsim_state_analyses_challenge_request + || m_state == eap_type_gsmsim_state_pending_kc_sres_query + || m_state == eap_type_gsmsim_state_waiting_for_reauth_request + || m_state == eap_type_gsmsim_state_analyses_reauthentication_request + || m_state == eap_type_gsmsim_state_waiting_for_success + || m_state == eap_type_gsmsim_state_success + || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success + || m_state == eap_type_gsmsim_state_failure)) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { + // If the P bit is set to one, the notification can only by used before + // the EAP/SIM/Challenge round in full authentication, or before the + // EAP/SIM/Re-authentication round in reauthentication. + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + } + else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + } + + status = initialize_notification_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_gsmsim_notification_request_message( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_UNREFERENCED_PARAMETER(received_gsmsim); + EAP_UNREFERENCED_PARAMETER(gsmsim_packet_length); + EAP_UNREFERENCED_PARAMETER(receive_network_id); + +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + const eap_type_gsmsim_state_variable_e gsmsim_notification_request_message_states[] = + { + eap_type_gsmsim_state_waiting_for_identity_request, + eap_type_gsmsim_state_pending_identity_query, + eap_type_gsmsim_state_waiting_for_start_request, + eap_type_gsmsim_state_imsi_waiting_for_start_request, + eap_type_gsmsim_state_pseydonym_waiting_for_start_request, + eap_type_gsmsim_state_analyse_start_request, + eap_type_gsmsim_state_waiting_for_challenge_request, + eap_type_gsmsim_state_analyses_challenge_request, + eap_type_gsmsim_state_pending_kc_sres_query, + eap_type_gsmsim_state_waiting_for_notification_request_success, + eap_type_gsmsim_state_waiting_for_success, + eap_type_gsmsim_state_waiting_for_reauth_request, + eap_type_gsmsim_state_analyses_reauthentication_request, + eap_type_gsmsim_state_success, + eap_type_gsmsim_state_failure, + }; + + if (verify_states(gsmsim_notification_request_message_states, + GSMSIM_STATE_COUNT(gsmsim_notification_request_message_states)) == true) +#else + if (m_state == eap_type_gsmsim_state_waiting_for_identity_request + || m_state == eap_type_gsmsim_state_pending_identity_query + || m_state == eap_type_gsmsim_state_waiting_for_start_request + || m_state == eap_type_gsmsim_state_imsi_waiting_for_start_request + || m_state == eap_type_gsmsim_state_pseydonym_waiting_for_start_request + || m_state == eap_type_gsmsim_state_analyse_start_request + || m_state == eap_type_gsmsim_state_waiting_for_challenge_request + || m_state == eap_type_gsmsim_state_analyses_challenge_request + || m_state == eap_type_gsmsim_state_pending_kc_sres_query + || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success + || m_state == eap_type_gsmsim_state_waiting_for_success + || m_state == eap_type_gsmsim_state_waiting_for_reauth_request + || m_state == eap_type_gsmsim_state_analyses_reauthentication_request + || m_state == eap_type_gsmsim_state_success + || m_state == eap_type_gsmsim_state_failure + ) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { + // This could be first or retransmission request. + + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_optional // RESULT_IND + ) == true + ) + { + // NOTE, this message is unauthenticated. Anybody could sent this message. + + // We store the received notification code. This will be handled after session timeouts. + m_gsmsim_notification_code = + static_cast( + p_gsmsim_payloads->get_NOTIFICATION()->get_original_header()->get_reserved()); + + save_current_state(); + + m_last_eap_identifier = received_gsmsim->get_identifier(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_gsmsim_notification_request_message(0x%08x), ") + EAPL("notification_code = 0x%04x, F bit %d, P bit %d, state %d=%s.\n"), + this, + m_gsmsim_notification_code, + get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code), + get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code), + m_state, + get_state_string())); + + if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + status = handle_gsmsim_notification_request_message_reauthentication( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = handle_gsmsim_notification_request_message_full_authentication( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(1): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_challenge_request_message( + const eap_am_network_id_c * const /* receive_network_id */, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + if (m_state == eap_type_gsmsim_state_waiting_for_challenge_request + || (m_state == eap_type_gsmsim_state_waiting_for_success && m_use_result_indication == false) + || (m_state == eap_type_gsmsim_state_waiting_for_notification_request_success && m_use_result_indication == true)) + { + // This could be first or retransmission request. + + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_optional // RESULT_IND + ) == true + ) + { + if (p_gsmsim_payloads->get_RESULT_IND()->get_payload_included() == true) + { + m_use_result_indication = m_allow_use_result_indication; + } + else + { + m_use_result_indication = false; + } + + if (p_gsmsim_payloads->get_IV()->get_payload_included() == true + || p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true) + { + if (p_gsmsim_payloads->get_IV()->get_payload_included() == true + && p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true) + { + // OK + } + else + { + // All of these must be included + // or none of these must be included. + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + + // The whole EAP packet must copied. + // The MAC is checked later after n*Kc and n*SRES is get from SIM. + status = m_saved_EAP_packet.set_copy_of_buffer( + received_gsmsim->get_header_buffer(gsmsim_packet_length), + gsmsim_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_last_eap_identifier = received_gsmsim->get_identifier(); + + save_current_state(); + set_state(eap_type_gsmsim_state_analyses_challenge_request); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c n_kc(m_am_tools); + eap_variable_data_c n_sres(m_am_tools); + + status = query_SIM_kc_sres( + p_gsmsim_payloads->get_n_RANDs()->get_payload_buffer(), + &n_kc, + &n_sres); + if (status == eap_status_pending_request) + { + // Request will be completed later using complete_SIM_kc_sres() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status == eap_status_completed_request) + { + // Request was already completed by AM using complete_SIM_kc_sres() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status == eap_status_success) + { + // eap_status_success means the authentication was successful. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_ok) + { + // The query_SIM_kc_sres() function call is synchronous. + // We must call process_SIM_kc_sres(). + } + else + { + // This is an error case. + restore_saved_previous_state(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // eap_status_ok status value means n_kc and n_sres were read but not processed. + // Next we must call process_SIM_kc_sres(). + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = process_SIM_kc_sres( + p_gsmsim_payloads->get_n_RANDs()->get_payload_buffer(), + &n_kc, + &n_sres); + + if (status != eap_status_ok + && status != eap_status_success) + { + (void) initialize_error_message(status); + + restore_saved_previous_state(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_challenge_request_message(6): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (m_state == eap_type_gsmsim_state_pending_kc_sres_query) + { + // This is re-transmitted EAP-Request/SIM/Challenge. + // We dischard it quietly. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_gsmsim_c::handle_challenge_request_message(): ") + EAPL("Re-transmitted message %d=%s dropped in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else + { + // Wrong message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_challenge_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_reauthentication_request_message( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + if (m_state == eap_type_gsmsim_state_waiting_for_reauth_request + || (m_state == eap_type_gsmsim_state_waiting_for_success && m_use_result_indication == false) + || (m_state == eap_type_gsmsim_state_waiting_for_notification_request_success && m_use_result_indication == true)) + { + // This could be first or retransmission request. + + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_optional // RESULT_IND + ) == true + ) + { + + m_last_eap_identifier = received_gsmsim->get_identifier(); + + save_current_state(); + set_state(eap_type_gsmsim_state_analyses_reauthentication_request); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_aut(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + u32_t reauth_counter = 0u; + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_gsmsim->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_reauthentication_request_message(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + reauth_counter)); + + status = check_message_authentication_code( + &orig_K_aut, + p_gsmsim_payloads, + received_gsmsim, + gsmsim_packet_length); + if (status != eap_status_ok) + { + (void) initialize_error_message(status); + + restore_saved_previous_state(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (p_gsmsim_payloads->get_RESULT_IND()->get_payload_included() == true) + { + m_use_result_indication = m_allow_use_result_indication; + } + else + { + m_use_result_indication = false; + } + + // Decrypt and parse encrypted payload. + if (p_gsmsim_payloads->get_IV()->get_payload_included() == true + || p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true) + { + if (p_gsmsim_payloads->get_IV()->get_payload_included() == true + && p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true + && p_gsmsim_payloads->get_MAC()->get_payload_included() == true) + { + gsmsim_payloads_c * const l_gsmsim_payloads = new gsmsim_payloads_c(m_am_tools); + eap_automatic_variable_c l_gsmsim_payloads_automatic(m_am_tools, l_gsmsim_payloads); + + if (l_gsmsim_payloads == 0 + || l_gsmsim_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + bool include_at_counter_too_small = false; + + status = decrypt_DATA_payload( + p_gsmsim_payloads, + &orig_K_encr); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t state_payload_buffer_length = p_gsmsim_payloads->get_ENCR_DATA()->get_data_length(); + const gsmsim_payload_AT_header_c gp_data_payload( + m_am_tools, + p_gsmsim_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), + state_payload_buffer_length); + + status = parse_gsmsim_payload( + &gp_data_payload, + &state_payload_buffer_length, + l_gsmsim_payloads, + received_gsmsim->get_subtype()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (l_gsmsim_payloads->get_COUNTER()->get_payload_included() == false + || l_gsmsim_payloads->get_NONCE_S()->get_payload_included() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u32_t counter = l_gsmsim_payloads->get_COUNTER()->get_original_header()->get_reserved(); + + if (m_gsmsim_test_version == true + && m_fail_reauthentication_counter_check == true) + { + --counter; + } + + if (m_saved_previous_state == eap_type_gsmsim_state_waiting_for_reauth_request) + { + if (counter < reauth_counter) + { + // When the client detects that the + // counter value is not fresh, it includes the AT_COUNTER_TOO_SMALL + // attribute in EAP-Response/SIM/Re-authentication. This attribute + // doesn't contain any data but it is a request for the server to + // initiate full authentication. In this case, the client MUST ignore + // the contents of the server's AT_NEXT_REAUTH_ID attribute. + include_at_counter_too_small = true; + l_gsmsim_payloads->get_NEXT_REAUTH_ID()->reset(); + } + } + else if (m_saved_previous_state == eap_type_gsmsim_state_waiting_for_success + || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success) + { + // This is retransmission request. + if (counter+1ul < reauth_counter) + { + // When the client detects that the + // counter value is not fresh, it includes the AT_COUNTER_TOO_SMALL + // attribute in EAP-Response/SIM/Re-authentication. This attribute + // doesn't contain any data but it is a request for the server to + // initiate full authentication. In this case, the client MUST ignore + // the contents of the server's AT_NEXT_REAUTH_ID attribute. + include_at_counter_too_small = true; + l_gsmsim_payloads->get_NEXT_REAUTH_ID()->reset(); + } + } + + if (l_gsmsim_payloads->get_NEXT_REAUTH_ID()->get_payload_included() == true) + { + // Save next re-authentication identity. + // GSMSIM AM could store pseudonym to favourite place. + status = m_am_type_gsmsim->store_reauthentication_id( + &m_send_network_id, + l_gsmsim_payloads->get_NEXT_REAUTH_ID()->get_payload_buffer()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // GSMSIM AM should remove re-authentication identity from favourite place. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_reauthentication_request_message(0x%08x): Resets re-authentication identity from database.\n"), + this)); + + status = m_am_type_gsmsim->store_reauthentication_id( + &m_send_network_id, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_reauthentication_identity.reset(); + } + + status = m_nonce_s.set_copy_of_buffer( + l_gsmsim_payloads->get_NONCE_S()->get_payload_buffer()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_reauthentication_response_message( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &m_NAI, + l_gsmsim_payloads->get_NONCE_S()->get_payload_buffer(), + static_cast(counter), + received_gsmsim->get_identifier(), + include_at_counter_too_small); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // OK, server re-authenticates correcly. + + if (m_use_result_indication == false + && m_saved_previous_state == eap_type_gsmsim_state_waiting_for_reauth_request) + { + // Re-authentication counter is increased only on first time. + // In order to use re-authentication, the client and the server need to + // update re-authentication counter value. + status = m_am_type_gsmsim->increase_reauth_counter(); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (include_at_counter_too_small == true) + { + // Re-authentication failed. + // We will expect full authentication. + set_state(eap_type_gsmsim_state_waiting_for_start_request); + status = eap_status_ok; + } + else + { + // Authentication was successful. + if (m_use_result_indication == true) + { + // This version waits the result indication. + set_state(eap_type_gsmsim_state_waiting_for_notification_request_success); + status = eap_status_ok; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, re-authentication OK, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else if (m_wait_eap_success_packet == false) + { + // This version does not wait EAP-Success message. + status = finish_successful_authentication( + receive_network_id); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // This version waits the EAP-Success message. + set_state(eap_type_gsmsim_state_waiting_for_success); + status = eap_status_ok; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, re-authentication OK, waits EAP-Success\n"), + (m_is_client == true) ? "client": "server")); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // All of these must be included + // or none of these must be included. + restore_saved_previous_state(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + else + { + // Not correct GSMSIM-payloads are included. + restore_saved_previous_state(); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_reauthentication_request_message(6): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_reauthentication_request_message(6): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_reauthentication_request_message(): ") + EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +// +eap_status_e eap_type_gsmsim_c::handle_eap_identity_query( + const eap_am_network_id_c * const send_network_id, + eap_variable_data_c * const p_identity, + const u8_t eap_identifier, + const eap_variable_data_c * const IMSI, + const eap_variable_data_c * const pseudonym, + const eap_variable_data_c * const reauthentication_identity, + const eap_variable_data_c * const automatic_realm, + const u32_t length_of_mnc, + const bool must_be_synchronous) +{ + const eap_variable_data_c *current_identity = 0; + eap_variable_data_c manual_identity(m_am_tools); + bool IMSI_is_used = false; + bool reauth_id_is_used = false; + eap_status_e status = eap_status_process_general_error; + + if (m_state != eap_type_gsmsim_state_pending_identity_query) + { + // Authentication is state is wrong. Cannot continue. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_gsmsim_state); + } + + if (must_be_synchronous == true + && p_identity == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (IMSI == 0 + || IMSI->get_is_valid_data() == false + || IMSI->get_data_length() < EAP_TYPE_GSMSIM_MINIMUM_IMSI_LENGTH) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + + // We must save queried re-authentication and pseudonym identity. + if (reauthentication_identity != 0 + && reauthentication_identity->get_is_valid_data() == true) + { + status = m_reauthentication_identity.set_copy_of_buffer(reauthentication_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (pseudonym != 0 + && pseudonym->get_is_valid_data() == true) + { + status = m_pseudonym.set_copy_of_buffer(pseudonym); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + if (m_use_manual_username == true + && m_manual_username.get_is_valid_data() == true + && m_use_manual_realm == true + && m_manual_realm.get_is_valid_data() == true) + { + // Here manual username could be zero or more bytes in length. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends manual username and realm.\n"))); + + status = manual_identity.set_copy_of_buffer(&m_manual_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + current_identity = &manual_identity; + IMSI_is_used = false; + } + else if (m_use_manual_username == true + && m_manual_username.get_is_valid_data() == true + && m_use_manual_realm == false) + { + // We will send manual username with automatic realm. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends manual username and automatic realm.\n"))); + + status = manual_identity.set_copy_of_buffer(&m_manual_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + current_identity = &manual_identity; + IMSI_is_used = false; + } + else if (reauthentication_identity != 0 + && reauthentication_identity->get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends re-authentication identity.\n"))); + + current_identity = reauthentication_identity; + IMSI_is_used = false; + reauth_id_is_used = true; + + status = m_reauthentication_identity.set_copy_of_buffer(reauthentication_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (pseudonym != 0 + && pseudonym->get_is_valid_data() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends pseudonym username.\n"))); + + current_identity = pseudonym; + IMSI_is_used = false; + + status = m_pseudonym.set_copy_of_buffer(pseudonym); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (m_use_random_identity_on_eap_identity_response == true) + { + // Generate random username. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends random username.\n"))); + + const u32_t EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH = 16; + eap_variable_data_c random_username(m_am_tools); + eap_variable_data_c random_bytes(m_am_tools); + + status = random_bytes.init(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + random_bytes.set_is_valid(); + random_bytes.set_data_length(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH); + + status = m_am_tools->get_crypto()->get_rand_bytes( + random_bytes.get_data(), + random_bytes.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Change first byte to 'r' to make it different than the default IMSI prefix '1'. + // This will cause the first identity char 'S' after ascii armor conversion. + *random_bytes.get_data(1ul) = static_cast('r'); + + const u32_t EAP_GSMSIM_RANDOM_IDENTITY_BUFFER_LENGTH + = 3ul+(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH+1u)*4u/3u; + + status = random_username.init(EAP_GSMSIM_RANDOM_IDENTITY_BUFFER_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + random_username.set_is_valid(); + random_username.set_data_length(EAP_GSMSIM_RANDOM_IDENTITY_BUFFER_LENGTH); + + u32_t random_identity_length = random_username.get_data_length(); + + status = m_am_tools->convert_bytes_to_ascii_armor( + random_bytes.get_data(), + random_bytes.get_data_length(), + random_username.get_data(random_username.get_data_length()), + &random_identity_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + random_username.set_data_length(random_identity_length); + + status = manual_identity.set_copy_of_buffer(&random_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + current_identity = &manual_identity; + IMSI_is_used = false; + } + else if (IMSI != 0 + && IMSI->get_is_valid_data() == true + && IMSI->get_data_length() >= EAP_TYPE_GSMSIM_MINIMUM_IMSI_LENGTH) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends IMSI username.\n"))); + + current_identity = IMSI; + IMSI_is_used = true; + } + + if (current_identity != 0) + { + status = m_IMSI.set_copy_of_buffer(IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = store_identity(current_identity, IMSI_is_used); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("current_identity"), + current_identity->get_data(), + current_identity->get_data_length())); + + eap_variable_data_c NAI(m_am_tools); + + if (reauth_id_is_used == true) + { + // Re-authentication identity is NAI. + status = NAI.set_copy_of_buffer(current_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = generate_nai( + &NAI, + m_use_manual_realm, + get_nai_realm(), + current_identity, + IMSI_is_used, + &m_IMSI, + automatic_realm, + length_of_mnc); + } + + if (status == eap_status_ok) + { + status = m_NAI.set_copy_of_buffer(&NAI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (must_be_synchronous == false) + { + status = get_type_partner()->complete_eap_identity_query( + send_network_id, + &m_NAI, + eap_identifier); + if (status == eap_status_ok) + { + if (p_identity != 0) + { + status = p_identity->set_copy_of_buffer(&m_NAI); + } + + if (status == eap_status_ok) + { + status = eap_status_completed_request; + } + } + } + else + { + status = p_identity->set_copy_of_buffer(&m_NAI); + } + + if (status == eap_status_ok + || status == eap_status_completed_request) + { + if (m_use_random_identity_on_eap_identity_response == true) + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_NONE; + set_identity_type(GSMSIM_IDENTITY_TYPE_NONE); + set_state(eap_type_gsmsim_state_waiting_for_start_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(0x%08x): Selects none.\n"), + this)); + } + else if (reauthentication_identity != 0 + && reauthentication_identity->get_is_valid_data() == true) + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION; + set_identity_type(GSMSIM_IDENTITY_TYPE_RE_AUTH_ID); + set_state(eap_type_gsmsim_state_waiting_for_reauth_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(0x%08x): Selects fast re-authentication and re-authentication identity.\n"), + this)); + } + else if (pseudonym != 0 + && pseudonym->get_is_valid_data() == true) + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID); + set_state(eap_type_gsmsim_state_pseydonym_waiting_for_start_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(0x%08x): Selects full authentication and pseudonym identity.\n"), + this)); + } + else + { + if (m_use_manual_username == true) + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_NONE; + set_identity_type(GSMSIM_IDENTITY_TYPE_NONE); + set_state(eap_type_gsmsim_state_waiting_for_start_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(0x%08x): Selects none.\n"), + this)); + } + else + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + set_identity_type(GSMSIM_IDENTITY_TYPE_IMSI_ID); + set_state(eap_type_gsmsim_state_imsi_waiting_for_start_request); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(0x%08x): Selects full authentication and IMSI identity.\n"), + this)); + } + } + } + } + } + else + { + status = eap_status_illegal_nai; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eap_type_gsmsim_c::query_eap_identity( + const bool must_be_synchronous, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_variable_data_c IMSI(m_am_tools); + eap_variable_data_c pseudonym(m_am_tools); + eap_variable_data_c reauthentication_identity(m_am_tools); + + if (IMSI.get_is_valid() == false + || pseudonym.get_is_valid() == false + || reauthentication_identity.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (send_network_id.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_status_process_general_error; + + if (m_state == eap_type_gsmsim_state_none) + { + status = new_handler( + receive_network_id, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::query_eap_identity(): eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + const eap_type_gsmsim_state_variable_e gsmsim_query_eap_identity_states[] = + { + eap_type_gsmsim_state_waiting_for_start_request, + eap_type_gsmsim_state_pseydonym_waiting_for_start_request, + eap_type_gsmsim_state_imsi_waiting_for_start_request, + eap_type_gsmsim_state_waiting_for_reauth_request, + }; +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + + + if (m_state == eap_type_gsmsim_state_waiting_for_identity_request + || (m_gsmsim_test_version == true + && m_state == eap_type_gsmsim_state_success)) // This one is for testing purposes. + { + m_last_eap_identifier = eap_identifier; + + eap_variable_data_c automatic_realm(m_am_tools); + + status = query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + &IMSI, + &pseudonym, + &reauthentication_identity, + &automatic_realm, + &m_length_of_mnc, + must_be_synchronous, + gsmsim_payload_AT_ANY_ID_REQ, + eap_type_gsmsim_complete_query_eap_identity, + eap_identifier); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::query_eap_identity(): ") + EAPL("completed returns eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok) + { + // This is the error case. + restore_saved_previous_state(); + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::query_eap_identity(): ") + EAPL("error returns eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // status == eap_status_ok + { + status = handle_eap_identity_query( + &send_network_id, + identity, + eap_identifier, + &IMSI, + &pseudonym, + &reauthentication_identity, + &automatic_realm, + m_length_of_mnc, + must_be_synchronous); + + if (status != eap_status_ok + && status != eap_status_completed_request) + { + restore_saved_previous_state(); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::query_eap_identity(): handle_eap_identity_query() ") + EAPL("returns eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + else if (verify_states(gsmsim_query_eap_identity_states, + GSMSIM_STATE_COUNT(gsmsim_query_eap_identity_states)) == true) +#else + else if (m_state == eap_type_gsmsim_state_waiting_for_start_request + || m_state == eap_type_gsmsim_state_pseydonym_waiting_for_start_request + || m_state == eap_type_gsmsim_state_imsi_waiting_for_start_request + || m_state == eap_type_gsmsim_state_waiting_for_reauth_request) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { + // This is re-transmission request. We do not change our state. + // Just send EAP-Identity again. + if (m_NAI.get_is_valid_data() == true) + { + status = identity->set_copy_of_buffer(&m_NAI); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::query_eap_identity(): handle_eap_identity_query() ") + EAPL("returns eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::query_eap_identity(): ") + EAPL("EAP-Request/Identity cannot be completed, identity (NAI) ") + EAPL("is missing. in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_state == eap_type_gsmsim_state_pending_identity_query) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::query_eap_identity(): ignores re-transmitted query_eap_identity()") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); + } + + + // Wrong message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("WARNING: eap_type_gsmsim_c::query_eap_identity(): ") + EAPL("Wrong message EAP-Request/Identity in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::eap_acknowledge( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + if (m_state == eap_type_gsmsim_state_waiting_for_success + && m_wait_eap_success_packet == true) + { + status = finish_successful_authentication( + receive_network_id); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ignored eap_acknowledge(): state %d=%s, is client %d\n"), + m_state, + get_state_string(), + (m_is_client == true))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::set_initial_eap_identifier( + const eap_am_network_id_c * const receive_network_id, + const u8_t initial_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = new_handler( + receive_network_id, + false); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::set_initial_eap_identifier(): ") + EAPL("new_handler() failed, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_last_eap_identifier = static_cast(initial_identifier-1u); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + #include "read_rand_and_triplets.h" +#endif //#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::generate_nonce( + const u32_t nonce_size, + eap_variable_data_c * const nonce) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = nonce->init(nonce_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + nonce->set_is_valid(); + nonce->set_data_length(nonce_size); + +#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + if (m_nonce_mt_file.get_is_valid_data() == true) + { + status = read_rand_from_file(m_am_tools, &m_nonce_mt_file, nonce); + if (status != eap_status_ok) + { + status = m_am_tools->get_crypto()->get_rand_bytes( + nonce->get_data(), + nonce->get_data_length()); + } + } + else +#endif //#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + { + status = m_am_tools->get_crypto()->get_rand_bytes( + nonce->get_data(), + nonce->get_data_length()); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,455 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 78 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_type_gsmsim_header.h" +#include "eap_header_string.h" + + +/** @file */ + + +// +EAP_FUNC_EXPORT gsmsim_payload_AT_header_c::~gsmsim_payload_AT_header_c() +{ +} + +// +EAP_FUNC_EXPORT gsmsim_payload_AT_header_c::gsmsim_payload_AT_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT gsmsim_payload_AT_type_e gsmsim_payload_AT_header_c::get_current_payload() const +{ + const u8_t * const payload_data = get_header_offset(m_type_offset, sizeof(u8_t)); + if (payload_data != 0) + { + return static_cast(*payload_data); + } + else + { + return gsmsim_payload_NONE; + } +} + +EAP_FUNC_EXPORT u16_t gsmsim_payload_AT_header_c::get_payload_length() const +{ + const u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u8_t)); + if (length_data != 0) + { + return static_cast(*length_data * 4u); + } + else + { + return 0ul; + } +} + +EAP_FUNC_EXPORT u16_t gsmsim_payload_AT_header_c::get_reserved() const +{ + const u8_t * const reserved = get_header_offset(m_reserved_offset, sizeof(u16_t)); + if (reserved != 0) + { + return eap_read_u16_t_network_order(reserved, sizeof(u16_t)); + } + else + { + // this is illegal reserved field value. + return 0xffff; + } +} + +EAP_FUNC_EXPORT u32_t gsmsim_payload_AT_header_c::get_data_length() const +{ + if (get_payload_length() > get_header_length()) + return static_cast(get_payload_length()-get_header_length()); + else + return 0; +} + +EAP_FUNC_EXPORT u16_t gsmsim_payload_AT_header_c::get_header_length() +{ + return m_data_offset; +} + +EAP_FUNC_EXPORT u16_t gsmsim_payload_AT_header_c::get_max_payload_data_length() +{ + return static_cast((0xff*4u-get_header_length())); +} + +EAP_FUNC_EXPORT u8_t * gsmsim_payload_AT_header_c::get_data(const u32_t contignuous_bytes) const +{ + if (get_data_length() >= contignuous_bytes + && contignuous_bytes > 0) + { + return get_header_offset(m_data_offset, contignuous_bytes); // Data begins after the header. + } + else + { + EAP_ASSERT( + get_data_length() >= contignuous_bytes + && contignuous_bytes > 0); + } + return 0; +} + +EAP_FUNC_EXPORT u8_t * gsmsim_payload_AT_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + if (get_header_buffer_length()-get_header_length() >= offset+contignuous_bytes + && contignuous_bytes > 0) + { + u8_t * const data = get_header_offset(m_data_offset, contignuous_bytes); + if (data != 0) + { + return data+offset; // Data begins after the header. + } + else + { + return 0; + } + } + else + { + EAP_ASSERT( + get_data_length() >= offset+contignuous_bytes + && contignuous_bytes > 0); + } + return 0; +} + +EAP_FUNC_EXPORT u8_t * gsmsim_payload_AT_header_c::get_next_header() const +{ + if (get_header_buffer_length() >= get_data_length()+2ul*get_header_length()) + { + return get_data_offset(get_data_length(), get_header_length()); + } + else + { + return 0; + } +} + +// Mostly this is zero. +// With some attributes this is used for special purposes. +EAP_FUNC_EXPORT void gsmsim_payload_AT_header_c::set_reserved( + const u16_t reserved) +{ + u8_t *reserved_data = get_header_offset(m_reserved_offset, sizeof(u16_t)); + + EAP_ASSERT(reserved_data != 0); + + reserved_data[0] = static_cast(((reserved & 0xff00) >> 8)); + reserved_data[1] = static_cast((reserved & 0x00ff)); +} + +EAP_FUNC_EXPORT void gsmsim_payload_AT_header_c::set_current_payload( + const gsmsim_payload_AT_type_e p_current_payload) +{ + EAP_ASSERT_ALWAYS(p_current_payload == static_cast(static_cast(p_current_payload))); + + u8_t * const payload_type = get_header_offset(m_type_offset, sizeof(u8_t)); + + EAP_ASSERT(payload_type != 0); + + *payload_type = static_cast(p_current_payload); +} + +EAP_FUNC_EXPORT void gsmsim_payload_AT_header_c::set_data_length(const u16_t p_data_length) +{ + u32_t total_length = p_data_length+gsmsim_payload_AT_header_c::get_header_length(); + u32_t remaider = total_length % 4u; + + EAP_ASSERT(remaider == 0); + EAP_ASSERT((total_length / 4u) <= 0xff); + + EAP_UNREFERENCED_PARAMETER(remaider); + + u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u8_t)); + + EAP_ASSERT(length_data != 0); + + *length_data = static_cast(total_length/4u); +} + +EAP_FUNC_EXPORT void gsmsim_payload_AT_header_c::reset_header(const u16_t data_length) +{ + set_reserved(0u); + set_current_payload(gsmsim_payload_NONE); + set_data_length(data_length); +} + +EAP_FUNC_EXPORT eap_const_string gsmsim_payload_AT_header_c::get_payload_AT_string( + const gsmsim_payload_AT_type_e payload_type) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_NONE) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_RAND) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_PADDING) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_NONCE_MT) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_PERMANENT_ID_REQ) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_MAC) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_NOTIFICATION) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_ANY_ID_REQ) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_IDENTITY) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_VERSION_LIST) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_SELECTED_VERSION) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_FULLAUTH_ID_REQ) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_COUNTER) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_COUNTER_TOO_SMALL) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_NONCE_S) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_CLIENT_ERROR_CODE) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_IV) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_ENCR_DATA) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_NEXT_PSEUDONYM) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_NEXT_REAUTH_ID) + else EAP_IF_RETURN_STRING(payload_type, gsmsim_payload_AT_RESULT_IND) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(payload_type); + return EAPL("Unknown GSMSIM payload AT"); + } +} + +EAP_FUNC_EXPORT eap_const_string gsmsim_payload_AT_header_c::get_payload_AT_string() const +{ + return get_payload_AT_string(get_current_payload()); +} + +EAP_FUNC_EXPORT eap_status_e gsmsim_payload_AT_header_c::check_header() const +{ + if (get_reserved() != 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//---------------------------------------------------------------------------- + + +// +EAP_FUNC_EXPORT gsmsim_header_c::~gsmsim_header_c() +{ +} + +// +EAP_FUNC_EXPORT gsmsim_header_c::gsmsim_header_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length) + : eap_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT gsmsim_subtype_e gsmsim_header_c::get_subtype() const +{ + u32_t subtype_offset(get_sub_type_offset()); + + const u8_t * const subtype_data = get_header_offset(subtype_offset, sizeof(u8_t)); + if (subtype_data != 0) + { + return static_cast(*subtype_data); + } + else + { + return gsmsim_subtype_NONE; + } +} + +EAP_FUNC_EXPORT u16_t gsmsim_header_c::get_data_length() const +{ + if (get_length() > static_cast(get_header_length())) + { + return static_cast(get_length()-static_cast(get_header_length())); + } + else + { + return 0; + } +} + +u32_t gsmsim_header_c::get_sub_type_offset() const +{ + return eap_header_base_c::get_header_length() + eap_header_base_c::get_type_field_length() + m_subtype_delta_offset; +} + +EAP_FUNC_EXPORT u32_t gsmsim_header_c::get_header_length() const +{ + return get_sub_type_offset() + m_data_delta_offset; +} + +EAP_FUNC_EXPORT u8_t * gsmsim_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + u32_t data_length = get_data_length(); + + if (data_length >= offset+contignuous_bytes + && contignuous_bytes > 0u) + { + return (get_header_offset(get_header_length(), contignuous_bytes)+offset); // Data begins after the header. + } + else + { + EAP_ASSERT(get_data_length() > 0u); + } + return 0; +} + + +EAP_FUNC_EXPORT u8_t * gsmsim_header_c::get_data(const u32_t contignuous_bytes) const +{ + return get_data_offset(0u, contignuous_bytes); +} + + +EAP_FUNC_EXPORT u16_t gsmsim_header_c::get_reserved() const +{ + u32_t reserved_offset(get_sub_type_offset()+m_reserved_delta_offset); + + u8_t * const reserved_data = get_header_offset(reserved_offset, sizeof(u16_t)); + if (reserved_data != 0) + { + return eap_read_u16_t_network_order(reserved_data, sizeof(u16_t)); + } + else + { + // This is illegal reserved data value. + return 0xffff; + } +} + + +EAP_FUNC_EXPORT eap_status_e gsmsim_header_c::check_header() const +{ + if (get_type() != eap_type_gsmsim) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (get_reserved() != static_cast(0ul)) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +EAP_FUNC_EXPORT eap_const_string gsmsim_header_c::get_subtype_string() const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + const gsmsim_subtype_e packet_type = get_subtype(); + + EAP_IF_RETURN_STRING(packet_type, gsmsim_subtype_NONE) + else EAP_IF_RETURN_STRING(packet_type, gsmsim_subtype_Start) + else EAP_IF_RETURN_STRING(packet_type, gsmsim_subtype_Challenge) + else EAP_IF_RETURN_STRING(packet_type, gsmsim_subtype_Notification) + else EAP_IF_RETURN_STRING(packet_type, gsmsim_subtype_Re_authentication) + else EAP_IF_RETURN_STRING(packet_type, gsmsim_subtype_Client_Error) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown GSMSIM-type"); + } +} + +EAP_FUNC_EXPORT eap_const_string gsmsim_header_c::get_code_string() const +{ + return eap_header_string_c::get_eap_code_string(get_code()); +} + +EAP_FUNC_EXPORT eap_const_string gsmsim_header_c::get_eap_type_string() const +{ + if (get_length() <= eap_header_base_c::get_header_length()) + { + return EAPL("No EAP-type"); + } + + return eap_header_string_c::get_eap_type_string(get_type()); +} + +EAP_FUNC_EXPORT void gsmsim_header_c::set_reserved(const u16_t reserved) +{ + u32_t reserved_offset(get_sub_type_offset()+m_reserved_delta_offset); + u8_t *reserved_data = get_header_offset(reserved_offset, sizeof(u16_t)); + + EAP_ASSERT(reserved_data != 0); + + reserved_data[0] = static_cast((reserved & 0xff00) >> 8); + reserved_data[1] = static_cast(reserved & 0x00ff); +} + +EAP_FUNC_EXPORT void gsmsim_header_c::set_subtype(const gsmsim_subtype_e p_subtype) +{ + u32_t subtype_offset(get_sub_type_offset()+m_subtype_delta_offset); + u8_t * const subtype_data = get_header_offset(subtype_offset, sizeof(u8_t)); + + EAP_ASSERT(subtype_data != 0); + + *subtype_data = static_cast(p_subtype); +} + +EAP_FUNC_EXPORT void gsmsim_header_c::set_data_length( + const u32_t p_data_length, + const bool expanded_type_when_true) +{ + EAP_ASSERT_ALWAYS(p_data_length+get_header_length() <= 0xffff); + + set_length( + static_cast(p_data_length+get_header_length()), + expanded_type_when_true); +} + +EAP_FUNC_EXPORT void gsmsim_header_c::reset_header( + const u32_t buffer_length, + const bool expanded_type_when_true) +{ + eap_header_base_c::set_length( + static_cast(buffer_length), + expanded_type_when_true); + + set_code(eap_code_none); + set_identifier(0u); + + set_type( + eap_type_gsmsim, + expanded_type_when_true); // SIM = 18 + + set_subtype(gsmsim_subtype_NONE); + set_reserved(0u); +} + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_initialized.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_initialized.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 79 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_type_gsmsim_initialized.h" + + +// +eap_type_gsmsim_initialized_c::~eap_type_gsmsim_initialized_c() +{ +} + +// +eap_type_gsmsim_initialized_c::eap_type_gsmsim_initialized_c( + abs_eap_am_tools_c * const tools, + abs_eap_type_gsmsim_state_c * const /*partner*/) + : m_am_tools(tools) + , m_counter(1u) +{ +} + +u32_t eap_type_gsmsim_initialized_c::counter() +{ + return m_counter; +} + +void eap_type_gsmsim_initialized_c::increment() +{ + ++m_counter; +} + +//-------------------------------------------------- + +void eap_type_gsmsim_initialized_c::reset() +{ + m_counter = 0u; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_mac_attributes.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_mac_attributes.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 80 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_type_gsmsim_mac_attributes.h" + + +//-------------------------------------------------- + +eap_type_gsmsim_MAC_attributes_c::~eap_type_gsmsim_MAC_attributes_c() +{ +} + +eap_type_gsmsim_MAC_attributes_c::eap_type_gsmsim_MAC_attributes_c() + : m_MAC(0) + , m_MAC_size(0) + , m_data(0) + , m_data_length(0u) +{ +} + +eap_type_gsmsim_MAC_attributes_c::eap_type_gsmsim_MAC_attributes_c( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length) + : m_MAC(MAC) + , m_MAC_size(MAC_size) + , m_data(EAP_data) + , m_data_length(EAP_data_length) +{ +} + +void eap_type_gsmsim_MAC_attributes_c::init( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length) +{ + m_MAC = (MAC); + m_MAC_size = (MAC_size); + m_data = (EAP_data); + m_data_length = (EAP_data_length); +} + +u8_t * eap_type_gsmsim_MAC_attributes_c::get_MAC() const +{ + return m_MAC; +} + +void eap_type_gsmsim_MAC_attributes_c::set_MAC(u8_t * MAC) +{ + m_MAC = MAC; +} + +u32_t eap_type_gsmsim_MAC_attributes_c::get_MAC_size() const +{ + return m_MAC_size; +} + +eap_type_gsmsim_MAC_attributes_c * eap_type_gsmsim_MAC_attributes_c::copy() const +{ + return new eap_type_gsmsim_MAC_attributes_c( + m_MAC, + m_MAC_size, + m_data, + m_data_length); +} + +u8_t * eap_type_gsmsim_MAC_attributes_c::get_data() const +{ + return m_data; +} + +u32_t eap_type_gsmsim_MAC_attributes_c::get_data_length() +{ + return m_data_length; +} + +void eap_type_gsmsim_MAC_attributes_c::set_data(u8_t * const data) +{ + m_data = data; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_payloads.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_payloads.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,418 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 81 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_type_gsmsim_payloads.h" +#include "abs_eap_am_tools.h" +#include "eap_tools.h" + + +EAP_FUNC_EXPORT gsmsim_fixed_data_c::~gsmsim_fixed_data_c() +{ +} + +EAP_FUNC_EXPORT gsmsim_fixed_data_c::gsmsim_fixed_data_c( + abs_eap_am_tools_c * const tools) + : m_is_valid(false) + , m_original_header(tools, 0, 0) + , m_type(0) + , m_data(0) +{ +} + +EAP_FUNC_EXPORT bool gsmsim_fixed_data_c::get_is_valid() const +{ + return m_is_valid; +} + +EAP_FUNC_EXPORT const gsmsim_payload_AT_header_c * gsmsim_fixed_data_c::get_original_header() +{ + return &m_original_header; +} + +EAP_FUNC_EXPORT u16_t gsmsim_fixed_data_c::get_type(abs_eap_am_tools_c * const m_am_tools) const +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + if (m_is_valid == true) + { + return m_type; + } + else + { + EAP_ASSERT_ALWAYS(m_is_valid == true); + return 0u; + } +} + +EAP_FUNC_EXPORT u16_t gsmsim_fixed_data_c::get_data(abs_eap_am_tools_c * const m_am_tools) const +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + if (m_is_valid == true) + { + return m_data; + } + else + { + EAP_ASSERT_ALWAYS(m_is_valid == true); + return 0u; + } +} + +EAP_FUNC_EXPORT void gsmsim_fixed_data_c::set_data(const gsmsim_payload_AT_header_c * const original_header, + const u16_t type, const u16_t data) +{ + m_is_valid = true; + m_original_header.set_header_buffer( + original_header->get_header_buffer(original_header->get_header_buffer_length()), + original_header->get_header_buffer_length()); + m_type = static_cast(type & 0x7FFF); // Mask out the AF bit. + m_data = data; +} + + + +EAP_FUNC_EXPORT gsmsim_variable_data_c::~gsmsim_variable_data_c() +{ +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c::gsmsim_variable_data_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_data(tools) + , m_original_header(tools, 0, 0) + , m_payload_included(false) +{ +} + +EAP_FUNC_EXPORT eap_status_e gsmsim_variable_data_c::reset() +{ + m_payload_included = false; + m_original_header.reset_header(0ul); + return m_data.reset(); +} + +EAP_FUNC_EXPORT const gsmsim_payload_AT_header_c * gsmsim_variable_data_c::get_original_header() const +{ + return &m_original_header; +} + +EAP_FUNC_EXPORT eap_status_e gsmsim_variable_data_c::set_buffer(const gsmsim_payload_AT_header_c * const original_header, + u8_t *buffer, const u32_t buffer_length, + const bool free_buffer, const bool is_writable) +{ + m_original_header.set_header_buffer( + original_header->get_header_buffer(original_header->get_header_buffer_length()), + original_header->get_header_buffer_length()); + if (m_original_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_status_e status = m_data.set_buffer(buffer, buffer_length, free_buffer, is_writable); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_payload_included = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT bool gsmsim_variable_data_c::get_payload_included() const +{ + return m_payload_included; +} + +EAP_FUNC_EXPORT u32_t gsmsim_variable_data_c::get_data_length() const +{ + return m_data.get_data_length(); +} + +EAP_FUNC_EXPORT u8_t * gsmsim_variable_data_c::get_data(const u32_t data_length) const +{ + return m_data.get_data(data_length); +} + +EAP_FUNC_EXPORT eap_variable_data_c * gsmsim_variable_data_c::get_payload_buffer() +{ + return &m_data; +} + + +EAP_FUNC_EXPORT gsmsim_payloads_c::~gsmsim_payloads_c() +{ +} + +EAP_FUNC_EXPORT gsmsim_payloads_c::gsmsim_payloads_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_nonce_mt(tools) + , m_nonce_s(tools) + , m_MAC(tools) + , m_ENCR_DATA(tools) + , m_IDENTITY_payload(tools) + , m_padding_payload(tools) + , m_n_RANDs(tools) + , m_PERMANENT_ID_REQ(tools) + , m_FULLAUTH_ID_REQ(tools) + , m_ANY_ID_REQ(tools) + , m_IV(tools) + , m_NEXT_PSEUDONYM(tools) + , m_NEXT_REAUTH_ID(tools) + , m_NOTIFICATION(tools) + , m_VERSION_LIST(tools) + , m_SELECTED_VERSION(tools) + , m_COUNTER(tools) + , m_COUNTER_TOO_SMALL(tools) + , m_CLIENT_ERROR_CODE(tools) + , m_RESULT_IND(tools) + , m_unknown_payload(gsmsim_payload_NONE) + , m_includes_other_version_than_1(false) + , m_is_valid(false) +{ + m_is_valid = true; +} + +EAP_FUNC_EXPORT bool gsmsim_payloads_c::check_one_payload( + const eap_gsmsim_payload_status_e status, + const gsmsim_variable_data_c * const payload) +{ + if (status == eap_gsmsim_payload_status_optional) + { + return true; + } + else if (status == eap_gsmsim_payload_status_must_not_be + && payload->get_payload_included() == false) + { + return true; + } + else if (status == eap_gsmsim_payload_status_must_be + && payload->get_payload_included() == true) + { + return true; + } + else + { + return false; + } +} + +EAP_FUNC_EXPORT bool gsmsim_payloads_c::check_payloads( + const eap_gsmsim_payload_status_e nonce_mt, + const eap_gsmsim_payload_status_e nonce_s, + const eap_gsmsim_payload_status_e MAC, + const eap_gsmsim_payload_status_e ENCR_DATA, + const eap_gsmsim_payload_status_e IDENTITY, + const eap_gsmsim_payload_status_e padding, + const eap_gsmsim_payload_status_e n_RANDs, + const eap_gsmsim_payload_status_e PERMANENT_ID_REQ, + const eap_gsmsim_payload_status_e FULLAUTH_ID_REQ, + const eap_gsmsim_payload_status_e ANY_ID_REQ, + const eap_gsmsim_payload_status_e IV, + const eap_gsmsim_payload_status_e NEXT_PSEUDONYM, + const eap_gsmsim_payload_status_e NEXT_REAUTH_ID, + const eap_gsmsim_payload_status_e NOTIFICATION, + const eap_gsmsim_payload_status_e VERSION_LIST, + const eap_gsmsim_payload_status_e SELECTED_VERSION, + const eap_gsmsim_payload_status_e COUNTER, + const eap_gsmsim_payload_status_e COUNTER_TOO_SMALL, + const eap_gsmsim_payload_status_e CLIENT_ERROR_CODE, + const eap_gsmsim_payload_status_e RESULT_IND + ) +{ + if (check_one_payload(nonce_mt, get_NONCE_MT()) == true + && check_one_payload(nonce_s, get_NONCE_S()) == true + && check_one_payload(MAC, get_MAC()) == true + && check_one_payload(ENCR_DATA, get_ENCR_DATA()) == true + && check_one_payload(IDENTITY, get_IDENTITY_payload()) == true + && check_one_payload(padding, get_padding_payload()) == true + && check_one_payload(n_RANDs, get_n_RANDs()) == true + && check_one_payload(PERMANENT_ID_REQ, get_PERMANENT_ID_REQ()) == true + && check_one_payload(FULLAUTH_ID_REQ, get_FULLAUTH_ID_REQ()) == true + && check_one_payload(ANY_ID_REQ, get_ANY_ID_REQ()) == true + && check_one_payload(IV, get_IV()) == true + && check_one_payload(NEXT_PSEUDONYM, get_NEXT_PSEUDONYM()) == true + && check_one_payload(NEXT_REAUTH_ID, get_NEXT_REAUTH_ID()) == true + && check_one_payload(NOTIFICATION, get_NOTIFICATION()) == true + && check_one_payload(VERSION_LIST, get_VERSION_LIST()) == true + && check_one_payload(SELECTED_VERSION, get_SELECTED_VERSION()) == true + && check_one_payload(COUNTER, get_COUNTER()) == true + && check_one_payload(COUNTER_TOO_SMALL, get_COUNTER_TOO_SMALL()) == true + && check_one_payload(CLIENT_ERROR_CODE, get_CLIENT_ERROR_CODE()) == true + && check_one_payload(RESULT_IND, get_RESULT_IND()) == true + ) + { + return true; + } + else + { + return false; + } +} + + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_NONCE_MT() +{ + return static_cast(&m_nonce_mt); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_NONCE_S() +{ + return static_cast(&m_nonce_s); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_MAC() +{ + return static_cast(&m_MAC); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_ENCR_DATA() +{ + return static_cast(&m_ENCR_DATA); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_IDENTITY_payload() +{ + return static_cast(&m_IDENTITY_payload); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_padding_payload() +{ + return static_cast(&m_padding_payload); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_n_RANDs() +{ + return static_cast(&m_n_RANDs); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_PERMANENT_ID_REQ() +{ + return static_cast(&m_PERMANENT_ID_REQ); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_FULLAUTH_ID_REQ() +{ + return static_cast(&m_FULLAUTH_ID_REQ); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_ANY_ID_REQ() +{ + return static_cast(&m_ANY_ID_REQ); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_IV() +{ + return static_cast(&m_IV); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_NEXT_PSEUDONYM() +{ + return static_cast(&m_NEXT_PSEUDONYM); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_NEXT_REAUTH_ID() +{ + return static_cast(&m_NEXT_REAUTH_ID); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_NOTIFICATION() +{ + return static_cast(&m_NOTIFICATION); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_RESULT_IND() +{ + return static_cast(&m_RESULT_IND); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_VERSION_LIST() +{ + return static_cast(&m_VERSION_LIST); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_SELECTED_VERSION() +{ + return static_cast(&m_SELECTED_VERSION); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_CLIENT_ERROR_CODE() +{ + return static_cast(&m_CLIENT_ERROR_CODE); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_COUNTER() +{ + return static_cast(&m_COUNTER); +} + +EAP_FUNC_EXPORT gsmsim_variable_data_c * gsmsim_payloads_c::get_COUNTER_TOO_SMALL() +{ + return static_cast(&m_COUNTER_TOO_SMALL); +} + + +EAP_FUNC_EXPORT void gsmsim_payloads_c::set_includes_unknown_attribute(const gsmsim_payload_AT_type_e unknown_payload) +{ + if (m_unknown_payload == gsmsim_payload_NONE) + { + // Only the first one is recorded. + m_unknown_payload = unknown_payload; + } +} + +EAP_FUNC_EXPORT gsmsim_payload_AT_type_e gsmsim_payloads_c::get_includes_unknown_attribute() +{ + return m_unknown_payload; +} + +EAP_FUNC_EXPORT void gsmsim_payloads_c::set_includes_other_version_than_1(const bool includes_other_version_than_1) +{ + m_includes_other_version_than_1 = includes_other_version_than_1; +} + +EAP_FUNC_EXPORT bool gsmsim_payloads_c::get_includes_other_version_than_1() +{ + return m_includes_other_version_than_1; +} + +EAP_FUNC_EXPORT bool gsmsim_payloads_c::get_is_valid() const +{ + return m_is_valid; +} + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_server.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_server.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,4746 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 82 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_type_gsmsim.h" +#include "eap_type_gsmsim_header.h" +#include "eap_type_gsmsim_payloads.h" +#include "eap_type_gsmsim_mac_attributes.h" +#include "abs_eap_am_type_gsmsim.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" +#include "eap_automatic_variable.h" +#include "eap_am_type_gsmsim.h" + + +//-------------------------------------------------- + +/** @file */ + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_n_rand_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + eap_type_sim_triplet_array_c * const triplets) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + gsmsim_payload_AT_header_c gp_n_rands( + m_am_tools, + gsmsim->get_data_offset(*gsmsim_data_offset, *gsmsim_data_free), + *gsmsim_data_free); + + if (gp_n_rands.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u32_t rand_data_length = triplets->get_triplet_count() * SIM_RAND_LENGTH; + + + gp_n_rands.reset_header(static_cast(rand_data_length)); + gp_n_rands.set_current_payload(gsmsim_payload_AT_RAND); + + u8_t *n_rands = gp_n_rands.get_data(rand_data_length); + if (n_rands == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + for (u32_t ind = 0u; ind < triplets->get_triplet_count(); ind++) + { + eap_type_saesim_triplet_c *triplet = triplets->get_triplet(m_am_tools, ind); + + u8_t * const source = triplet->get_rand()->get_data(); + if (source == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + n_rands+(ind*SIM_RAND_LENGTH), + source, + triplet->get_rand()->get_data_length()); + } + + status = eap_status_ok; + + update_payload_indexes( + gsmsim_buffer_length, + eap_header_size, + gp_n_rands.get_header_length()+gp_n_rands.get_data_length(), + gsmsim_data_offset, + gsmsim_data_free, + packet_buffer_offset, + packet_buffer_free); + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_n_rands); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_reauthentication_request_message( + const eap_variable_data_c * const username, + const bool pseudonym_decode_failed, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(pseudonym_decode_failed); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: GSMSIM-subtype %10s, %s, state %2d=%s\n"), + EAPL("gsmsim_subtype_Re_authentication"), + EAPL("server"), + m_state, + get_state_string() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_reauthentication_request_message(): %s, m_identity_type %d=%s, requested identity payload is %d=%s.\n"), + (m_is_client == true ? "client": "server"), + m_identity_type, + get_identity_string(m_identity_type), + m_start_response_includes_identity, + gsmsim_payload_AT_header_c::get_payload_AT_string(m_start_response_includes_identity))); + + eap_status_e status = eap_status_process_general_error; + + eap_buf_chain_wr_c request_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (request_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means GSMSIM does process every re-transmitted EAP-Request. + request_packet.set_do_packet_retransmission(false); + } +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + + EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_gsmsim_header_offset+m_MTU; + } + + gsmsim_header_c gsmsim_response( + m_am_tools, + request_packet.get_data_offset( + m_gsmsim_header_offset, + (packet_buffer_free-m_gsmsim_header_offset)), + (packet_buffer_free-m_gsmsim_header_offset)); + + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_reauthentication_request_message: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + gsmsim_response.reset_header( + packet_buffer_free-m_gsmsim_header_offset, + m_use_eap_expanded_type); + gsmsim_response.set_length( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_code(eap_code_request); + gsmsim_response.set_identifier(eap_identifier); + gsmsim_response.set_type( + eap_type_gsmsim, + m_use_eap_expanded_type); + gsmsim_response.set_subtype(gsmsim_subtype_Re_authentication); + + update_buffer_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + m_gsmsim_header_offset+gsmsim_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_reauthentication_request_message(0x%08x).\n"), + this)); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t gsmsim_data_free = packet_buffer_free; + u32_t gsmsim_data_offset = 0u; + + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_aut(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + u32_t reauth_counter = 0u; + eap_variable_data_c reauth_nonce_s(m_am_tools); + + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_gsmsim->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_reauthentication_request_message(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + reauth_counter)); + + status = generate_nonce(EAP_TYPE_GSMSIM_NONCE_MT_SIZE, &reauth_nonce_s); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_nonce_s.set_copy_of_buffer(&reauth_nonce_s); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c master_session_key(m_am_tools); + + status = generate_reauth_shared_secred_keys( + EAP_TYPE_GSMSIM_KEYMAT_SIZE, + &orig_XKEY, + reauth_counter, + username, + &reauth_nonce_s, + &master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + m_use_result_indication = m_allow_use_result_indication; + + if (m_use_result_indication == true) + { + // We support use of protected success indications. + status = add_simple_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + gsmsim_payload_AT_RESULT_IND); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_type_gsmsim->generate_encryption_IV( + m_IV.get_payload_buffer(), + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_variable_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + m_IV.get_payload_buffer(), + gsmsim_payload_AT_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_gsmsim_MAC_attributes_c MAC_attributes; + + // Encrypted data. + { + gsmsim_payload_AT_header_c gp_encrypted_data( + m_am_tools, + gsmsim_response.get_data_offset( + gsmsim_data_offset, + gsmsim_data_free), + gsmsim_data_free); + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Initialize the length of encrypted data to maximum length. + // Later this will be set to correct length. + gp_encrypted_data.reset_header(gsmsim_payload_AT_header_c::get_max_payload_data_length()); + gp_encrypted_data.set_current_payload(gsmsim_payload_AT_ENCR_DATA); + + update_payload_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + gp_encrypted_data.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_offset, + &packet_buffer_free); + + u32_t encrypted_data_offset_begin = packet_buffer_offset; + + // - - - - - - - - - - - - + + status = add_counter_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + static_cast(reauth_counter)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_variable_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &reauth_nonce_s, + gsmsim_payload_AT_NONCE_S); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = m_am_type_gsmsim->generate_reauthentication_id( + &m_send_network_id, + &m_IMSI, + &m_reauthentication_identity, + EAP_TYPE_GSMSIM_MAX_NAI_LENGTH); + if (status == eap_status_ok) + { + status = add_pseudonym_or_imsi_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &m_reauthentication_identity, + gsmsim_payload_AT_NEXT_REAUTH_ID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + status = add_padding_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + (packet_buffer_offset - encrypted_data_offset_begin) // Length of the plain text. + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + gp_encrypted_data.set_data_length( + static_cast(packet_buffer_offset - encrypted_data_offset_begin)); + + // - - - - - - - - - - - - + + status = encrypt_DATA_payload( + gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), + gp_encrypted_data.get_data_length(), + m_IV.get_payload_buffer(), + &orig_K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); + } + + // - - - - - - - - - - - - + + status = add_mac_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + request_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + gsmsim_response.get_header_buffer(gsmsim_response.get_length()), + gsmsim_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + gsmsim_response.get_subtype(), + gsmsim_response.get_code(), + &orig_K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + request_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_reauthentication_request_message()\n"))); + + status = packet_send( + &m_send_network_id, + &request_packet, + m_gsmsim_header_offset, + gsmsim_response.get_header_length()+gsmsim_response.get_data_length(), + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + status = m_master_session_key.set_copy_of_buffer(&master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + set_state(eap_type_gsmsim_state_waiting_for_reauth_response); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_start_request_message( + const bool pseudonym_decode_failed, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: %s, GSMSIM-subtype %10s, %s, state %2d=%s\n"), + EAPL("initiator"), + EAPL("gsmsim_subtype_Start"), + EAPL("server"), + m_state, + get_state_string() + )); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_request_message(): ") + EAPL("m_identity_type %d=%s, requested identity payload is %d=%s, state %d=%s, pseudonym decode %d.\n"), + m_identity_type, + get_identity_string(m_identity_type), + m_start_response_includes_identity, + gsmsim_payload_AT_header_c::get_payload_AT_string(m_start_response_includes_identity), + m_state, + get_state_string(), + pseudonym_decode_failed)); + + eap_status_e status = eap_status_process_general_error; + + eap_buf_chain_wr_c request_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (request_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means GSMSIM does process every re-transmitted EAP-Request. + request_packet.set_do_packet_retransmission(false); + } +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + + EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_gsmsim_header_offset+m_MTU; + } + + gsmsim_header_c gsmsim_response( + m_am_tools, + request_packet.get_data_offset( + m_gsmsim_header_offset, + (packet_buffer_free-m_gsmsim_header_offset)), + (packet_buffer_free-m_gsmsim_header_offset)); + + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_start_request_message: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gsmsim_response.reset_header( + packet_buffer_free-m_gsmsim_header_offset, + m_use_eap_expanded_type); + gsmsim_response.set_length( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_code(eap_code_request); + gsmsim_response.set_identifier(eap_identifier); + gsmsim_response.set_type( + eap_type_gsmsim, + m_use_eap_expanded_type); + gsmsim_response.set_subtype(gsmsim_subtype_Start); + + update_buffer_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + m_gsmsim_header_offset+gsmsim_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_request_message(0x%08x).\n"), + this)); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t gsmsim_data_free = packet_buffer_free; + u32_t gsmsim_data_offset = 0u; + + if (pseudonym_decode_failed == true) + { + gsmsim_payload_AT_type_e next_identity_request = gsmsim_payload_NONE; + eap_type_gsmsim_state_variable_e next_state = eap_type_gsmsim_state_failure; + + if (m_identity.get_is_valid_data() == true) + { + if (m_start_response_includes_identity == gsmsim_payload_AT_FULLAUTH_ID_REQ) + { + next_identity_request = gsmsim_payload_AT_FULLAUTH_ID_REQ; + next_state = eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity; + } + else if (m_start_response_includes_identity == gsmsim_payload_AT_PERMANENT_ID_REQ) + { + next_identity_request = gsmsim_payload_AT_PERMANENT_ID_REQ; + next_state = eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity; + } + else if (m_start_response_includes_identity == gsmsim_payload_AT_ANY_ID_REQ) + { + next_identity_request = gsmsim_payload_AT_ANY_ID_REQ; + next_state = eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity; + } + else + { + // We drop this message because no real identity is received from client. + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_GSMSIM_ERROR, (EAPL("ERROR: send_start_request_message: no real identity received.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + else + { + next_identity_request = gsmsim_payload_AT_ANY_ID_REQ; + next_state = eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity; + } + + status = add_variable_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + 0, + next_identity_request); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(next_state); + } + else + { + set_state(eap_type_gsmsim_state_waiting_for_start_response); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + + eap_gsmsim_version version_list = GSMSIM_VERSION_1; + + status = add_version_list( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &version_list, + sizeof(version_list)/sizeof(eap_gsmsim_version), + gsmsim_payload_AT_VERSION_LIST); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // - - - - - - - - - - - - - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + request_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_start_request_message()\n"))); + + status = packet_send( + &m_send_network_id, + &request_packet, + m_gsmsim_header_offset, + gsmsim_response.get_header_length()+gsmsim_response.get_data_length(), + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_challenge_request_message( + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: GSMSIM-type %10s, %s, state %2d=%s\n"), + EAPL("gsmsim_subtype_Challenge"), + (m_is_client) ? EAPL("client") : EAPL("server"), + m_state, + get_state_string() + )); + + eap_buf_chain_wr_c gsmsim_initial_reply( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (gsmsim_initial_reply.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means GSMSIM does process every re-transmitted EAP-Request. + gsmsim_initial_reply.set_do_packet_retransmission(false); + } +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + + EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_gsmsim_header_offset+m_MTU; + } + + gsmsim_header_c gsmsim_response( + m_am_tools, + gsmsim_initial_reply.get_data_offset( + m_gsmsim_header_offset, + (packet_buffer_free-m_gsmsim_header_offset)), + (packet_buffer_free-m_gsmsim_header_offset)); + + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + gsmsim_response.reset_header( + packet_buffer_free-m_gsmsim_header_offset, + m_use_eap_expanded_type); + gsmsim_response.set_length( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_code(eap_code_request); + gsmsim_response.set_identifier(eap_identifier); + gsmsim_response.set_type( + eap_type_gsmsim, + m_use_eap_expanded_type); + + gsmsim_response.set_subtype(gsmsim_subtype_Challenge); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_challenge_request_message(0x%08x).\n"), + this)); + + update_buffer_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + m_gsmsim_header_offset+gsmsim_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t gsmsim_data_free = packet_buffer_free; + u32_t gsmsim_data_offset = 0u; + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c n_rand(m_am_tools); + eap_variable_data_c n_kc(m_am_tools); + + u32_t count = m_triplets->get_triplet_count(); + + if (count == 0u) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + status = n_rand.init(SIM_RAND_LENGTH*count); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + n_rand.set_is_valid(); + n_rand.set_data_length(0u); + + status = n_kc.init(SIM_KC_LENGTH*count); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + n_kc.set_is_valid(); + n_kc.set_data_length(0u); + + status = m_n_sres.init(SIM_KC_LENGTH*count); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_n_sres.set_is_valid(); + m_n_sres.set_data_length(0u); + + u32_t ind; + for (ind = 0u; ind < count; ind++) + { + eap_type_saesim_triplet_c *tripl = m_triplets->get_triplet(m_am_tools, ind); + if (tripl == 0 + || tripl->get_rand()->get_data_length() == 0u + || tripl->get_kc()->get_data_length() == 0u + || tripl->get_sres()->get_data_length() == 0u) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + n_rand.add_data( + tripl->get_rand()->get_data(), + tripl->get_rand()->get_data_length()); + + n_kc.add_data( + tripl->get_kc()->get_data(), + tripl->get_kc()->get_data_length()); + + m_n_sres.add_data( + tripl->get_sres()->get_data(), + tripl->get_sres()->get_data_length()); + } // for() + + + if (n_rand.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (n_kc.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_n_sres.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_identity.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_IMSI.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_nonce_mt.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("n*RAND"), + n_rand.get_data(), + n_rand.get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("n*KC"), + n_kc.get_data(), + n_kc.get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("n*SRES"), + m_n_sres.get_data(), + m_n_sres.get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("identity"), + m_identity.get_data(), + m_identity.get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IMSI"), + m_IMSI.get_data(), + m_IMSI.get_data_length())); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("NONCE MT"), + m_nonce_mt.get_data(), + m_nonce_mt.get_data_length())); + + + eap_variable_data_c XKEY(m_am_tools); + eap_variable_data_c K_encr(m_am_tools); + eap_variable_data_c K_aut(m_am_tools); + eap_variable_data_c master_session_key(m_am_tools); + + status = generate_shared_secred_keys( + EAP_TYPE_GSMSIM_KEYMAT_SIZE, + &n_kc, + &m_n_sres, + &XKEY, + &K_encr, + &K_aut, + &master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + m_use_result_indication = m_allow_use_result_indication; + + if (m_use_result_indication == true) + { + // We support use of protected success indications. + status = add_simple_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + gsmsim_payload_AT_RESULT_IND); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - + + status = add_n_rand_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + m_triplets); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_gsmsim_MAC_attributes_c MAC_attributes; + + if (m_use_pseudonym_identity == true + || m_use_reauthentication_identity == true) + { + u32_t saved_gsmsim_data_offset = gsmsim_data_offset; + u32_t saved_gsmsim_data_free = gsmsim_data_free; + u32_t saved_packet_buffer_offset = packet_buffer_offset; + u32_t saved_packet_buffer_free = packet_buffer_free; + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_type_gsmsim->generate_encryption_IV( + m_IV.get_payload_buffer(), + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = add_variable_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + m_IV.get_payload_buffer(), + gsmsim_payload_AT_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // Encrypted data. + { + gsmsim_payload_AT_header_c gp_encrypted_data( + m_am_tools, + gsmsim_response.get_data_offset( + gsmsim_data_offset, + gsmsim_data_free), + gsmsim_data_free); + if (gp_encrypted_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Initialize the length of encrypted data to maximum length. + // Later this will be set to correct length. + gp_encrypted_data.reset_header(gsmsim_payload_AT_header_c::get_max_payload_data_length()); + gp_encrypted_data.set_current_payload(gsmsim_payload_AT_ENCR_DATA); + + update_payload_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + gp_encrypted_data.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_offset, + &packet_buffer_free); + + u32_t encrypted_data_offset_begin = packet_buffer_offset; + + // - - - - - - - - - - - - + + if (m_use_pseudonym_identity == true) + { + status = m_am_type_gsmsim->generate_pseudonym_id( + &m_send_network_id, + &m_IMSI, + &m_pseudonym, + EAP_TYPE_GSMSIM_MAX_NAI_LENGTH); + if (status == eap_status_ok) + { + status = add_pseudonym_or_imsi_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &m_pseudonym, + gsmsim_payload_AT_NEXT_PSEUDONYM); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + // - - - - - - - - - - - - + + if (m_use_reauthentication_identity == true) + { + status = m_am_type_gsmsim->generate_reauthentication_id( + &m_send_network_id, + &m_IMSI, + &m_reauthentication_identity, + EAP_TYPE_GSMSIM_MAX_NAI_LENGTH); + if (status == eap_status_ok) + { + status = add_pseudonym_or_imsi_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &m_reauthentication_identity, + gsmsim_payload_AT_NEXT_REAUTH_ID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + // - - - - - - - - - - - - + + u32_t plain_text_length = packet_buffer_offset - encrypted_data_offset_begin; + + if (plain_text_length > 0ul) + { + status = add_padding_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + plain_text_length + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Re calculate after adding the padding. + plain_text_length = packet_buffer_offset - encrypted_data_offset_begin; + + gp_encrypted_data.set_data_length( + static_cast(plain_text_length)); + + // - - - - - - - - - - - - + + status = encrypt_DATA_payload( + gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), + gp_encrypted_data.get_data_length(), + m_IV.get_payload_buffer(), + &K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); + } + else + { + // No encrypted data, remove AT_ENCR_DATA header. + gsmsim_data_offset = saved_gsmsim_data_offset; + gsmsim_data_free = saved_gsmsim_data_free; + packet_buffer_offset = saved_packet_buffer_offset; + packet_buffer_free = saved_packet_buffer_free; + } + } + } + + // - - - - - - - - - - - - + + status = add_mac_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + gsmsim_initial_reply.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + gsmsim_response.get_header_buffer(gsmsim_response.get_length()), + gsmsim_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + gsmsim_response.get_subtype(), + gsmsim_response.get_code(), + &K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + gsmsim_initial_reply.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = packet_send( + &m_send_network_id, + &gsmsim_initial_reply, + m_gsmsim_header_offset, + gsmsim_response.get_header_length()+gsmsim_response.get_data_length(), + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + // Store keys. + status = m_XKEY.set_copy_of_buffer(&XKEY); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = m_K_encr.set_copy_of_buffer(&K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = m_K_aut.set_copy_of_buffer(&K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = m_master_session_key.set_copy_of_buffer(&master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_gsmsim_notification_request( + const eap_gsmsim_notification_codes_e notification_code, + const bool add_at_counter_attribute) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: GSMSIM-type %10s, %s, state %2d=%s, notification_code = %d\n"), + EAPL("send_gsmsim_notification_request"), + (m_is_client) ? EAPL("client") : EAPL("server"), + m_state, + get_state_string(), + notification_code + )); + + eap_buf_chain_wr_c eap_notification_packet( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_notification_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + if (m_is_client == true + && m_client_responds_retransmitted_packets == true) + { + // We do not wan't lower layers do re-transmissions behalf of us. + // This means GSMSIM does process every re-transmitted EAP-Request. + eap_notification_packet.set_do_packet_retransmission(false); + } +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + + EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); + u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_gsmsim_header_offset+m_MTU; + } + + gsmsim_header_c gsmsim_response( + m_am_tools, + eap_notification_packet.get_data_offset( + m_gsmsim_header_offset, + (packet_buffer_free-m_gsmsim_header_offset)), + (packet_buffer_free-m_gsmsim_header_offset)); + + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + m_last_eap_identifier = static_cast(m_last_eap_identifier+1u); + + gsmsim_response.reset_header( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_length( + static_cast(packet_buffer_free-m_gsmsim_header_offset), + m_use_eap_expanded_type); + gsmsim_response.set_code(eap_code_request); + gsmsim_response.set_identifier(m_last_eap_identifier); + gsmsim_response.set_type( + eap_type_gsmsim, + m_use_eap_expanded_type); + gsmsim_response.set_subtype(gsmsim_subtype_Notification); + + + update_buffer_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + m_gsmsim_header_offset+gsmsim_response.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t gsmsim_data_free = packet_buffer_free; + u32_t gsmsim_data_offset = 0u; + + eap_status_e status = add_notification_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + notification_code); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_variable_data_c * K_aut = 0; + eap_variable_data_c orig_K_aut(m_am_tools); + + if (get_gsmsim_notification_code_P_bit(notification_code) == false) + { + u8_t *MAC_data = 0; + u32_t MAC_data_length = 0u; + eap_type_gsmsim_MAC_attributes_c MAC_attributes; + + if (add_at_counter_attribute == true) + { + // If EAP-Request/SIM/Notification is used on fast a re-authentication + // exchange, and if the P bit in AT_NOTIFICATION is set to zero, then + // AT_COUNTER is used for replay protection. In this case, the + // AT_ENCR_DATA and AT_IV attributes MUST be included, and the + // encapsulated plaintext attributes MUST include the AT_COUNTER + // attribute. The counter value included in AT_COUNTER MUST be the same + // as in the EAP-Request/SIM/Re-authentication packet on the same fast + // re-authentication exchange. + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + u32_t reauth_counter = 0u; + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_gsmsim->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::send_gsmsim_notification_request(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + reauth_counter)); + + K_aut = &orig_K_aut; + + // - - - - - - - - - - - - + + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_type_gsmsim->generate_encryption_IV( + m_IV.get_payload_buffer(), + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = add_variable_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + m_IV.get_payload_buffer(), + gsmsim_payload_AT_IV); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + // Encrypted data. + { + gsmsim_payload_AT_header_c gp_encrypted_data( + m_am_tools, + gsmsim_response.get_data_offset( + gsmsim_data_offset, + gsmsim_data_free), + gsmsim_data_free); + if (gsmsim_response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Initialize the length of encrypted data to maximum length. + // Later this will be set to correct length. + gp_encrypted_data.reset_header(gsmsim_payload_AT_header_c::get_max_payload_data_length()); + gp_encrypted_data.set_current_payload(gsmsim_payload_AT_ENCR_DATA); + + update_payload_indexes( + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + gp_encrypted_data.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_offset, + &packet_buffer_free); + + u32_t encrypted_data_offset_begin = packet_buffer_offset; + + // - - - - - - - - - - - - + + status = add_counter_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + static_cast(reauth_counter)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + status = add_padding_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + (packet_buffer_offset - encrypted_data_offset_begin) // Length of the plain text. + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + gp_encrypted_data.set_data_length( + static_cast(packet_buffer_offset - encrypted_data_offset_begin)); + + // - - - - - - - - - - - - + + status = encrypt_DATA_payload( + gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), + gp_encrypted_data.get_data_length(), + m_IV.get_payload_buffer(), + &orig_K_encr); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); + } + + } + else + { + K_aut = &m_K_aut; + } // if (add_counter_payload == true) + + // - - - - - - - - - - - - + + // Add AT_MAC attribute. + status = add_mac_payload( + &gsmsim_response, + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, + gsmsim_response.get_header_length(), + &gsmsim_data_offset, + &gsmsim_data_free, + &packet_buffer_free, + &packet_buffer_offset, + &MAC_data, + &MAC_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - + + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + + // - - - - - - - - - - - - + + MAC_attributes.init( + MAC_data, + MAC_data_length, + gsmsim_response.get_header_buffer(gsmsim_response.get_length()), + gsmsim_response.get_length()); + + status = create_message_authentication_code( + &MAC_attributes, + gsmsim_response.get_subtype(), + gsmsim_response.get_code(), + K_aut); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + else + { + gsmsim_response.set_data_length( + gsmsim_data_offset, + m_use_eap_expanded_type); + + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() + == packet_buffer_offset); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_notification_packet.set_data_length(packet_buffer_offset); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" send: EAP-Response/Notification packet"), + gsmsim_response.get_header_buffer(gsmsim_response.get_length()), + gsmsim_response.get_length())); + + status = packet_send( + &m_send_network_id, + &eap_notification_packet, + m_gsmsim_header_offset, + gsmsim_response.get_length(), + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::query_SIM_triplets( + eap_type_gsmsim_identity_type * const identity_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_type_sim_triplet_array_c triplets(m_am_tools); + + set_state(eap_type_gsmsim_state_pending_triplet_query); + + eap_status_e status = m_am_type_gsmsim->query_SIM_triplets( + false, + &m_identity, // This is username part from payload AT_IDENTITY. + &m_IMSI, // This is the real IMSI. If this is uninitialized get_identity() must be initialized, imsi will be initialized after this call is complete. + &triplets, + identity_type); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_SIM_triplets() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This query was already completed by complete_SIM_triplets() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok) + { + // Some error occurred. + restore_saved_previous_state(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_triplets(triplets.copy()); + if (m_triplets == 0 + || m_triplets->get_triplet_count() == 0) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::complete_SIM_triplets( + eap_type_sim_triplet_array_c * const triplets, + const eap_variable_data_c * const IMSI, + const eap_gsmsim_triplet_status_e triplet_status, + const eap_type_gsmsim_identity_type identity_type, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("eap_type_gsmsim_c::complete_SIM_triplets(): identity_type %d=%s, requested identity payload is %d=%s, state %d=%s\n"), + identity_type, + get_identity_string(identity_type), + m_start_response_includes_identity, + gsmsim_payload_AT_header_c::get_payload_AT_string(m_start_response_includes_identity), + m_state, + get_state_string())); + + if (completion_status != eap_status_ok + || triplets == 0) + { + set_state(eap_type_gsmsim_state_failure); + + // The eap_status_process_general_error error value is more important + // than return value of set_session_timeout(). + get_type_partner()->set_session_timeout(0ul); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + + if (m_state != eap_type_gsmsim_state_pending_triplet_query) + { + // Authentication is terminated or state is wrong. Cannot continue. + set_state(eap_type_gsmsim_state_failure); + + // The eap_status_handler_does_not_exists_error error value is more important + // than return value of set_session_timeout(). + get_type_partner()->set_session_timeout(0ul); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + + eap_status_e status = eap_status_process_general_error; + + if (m_identity_type != GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) + { + set_identity_type(identity_type); + } + + if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID + && IMSI->get_is_valid_data() == true) + { + status = m_IMSI.set_copy_of_buffer(IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (triplet_status == eap_gsmsim_triplet_status_ok) + { + // First check the identity type is correct. + if ((m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID + && (m_start_response_includes_identity == gsmsim_payload_AT_PERMANENT_ID_REQ + || m_start_response_includes_identity == gsmsim_payload_AT_FULLAUTH_ID_REQ + || m_start_response_includes_identity == gsmsim_payload_AT_ANY_ID_REQ)) + || (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID + && (m_start_response_includes_identity == gsmsim_payload_AT_FULLAUTH_ID_REQ + || m_start_response_includes_identity == gsmsim_payload_AT_ANY_ID_REQ)) + || (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID + && m_start_response_includes_identity == gsmsim_payload_AT_ANY_ID_REQ) + || m_start_response_includes_identity == gsmsim_payload_NONE) + { + // OK, correct identity received. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::complete_SIM_triplets(): OK\n"))); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::complete_SIM_triplets(): ") + EAPL("EAP-identity is wrong, state %d=%s.\n"), + m_state, get_state_string())); + + if (m_start_response_includes_identity == gsmsim_payload_AT_PERMANENT_ID_REQ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::complete_SIM_triplets(): ") + EAPL("permanent identity was required, %d=%s was get.\n"), + m_identity_type, + get_identity_string(m_identity_type))); + } + else if (m_start_response_includes_identity == gsmsim_payload_AT_FULLAUTH_ID_REQ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::complete_SIM_triplets(): ") + EAPL("full authentication identity was required, %d=%s was get.\n"), + m_identity_type, + get_identity_string(m_identity_type))); + } + else if (m_start_response_includes_identity == gsmsim_payload_AT_ANY_ID_REQ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::complete_SIM_triplets(): ") + EAPL("any identity was required, %d=%s was get.\n"), + m_identity_type, + get_identity_string(m_identity_type))); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::complete_SIM_triplets(): ") + EAPL("no special identity was required, %d=%s was get.\n"), + m_identity_type, + get_identity_string(m_identity_type))); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR, wrong identity"), + m_NAI.get_data(), + m_NAI.get_data_length())); + + restore_saved_previous_state(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + if (m_IMSI.get_is_valid_data() == false + && IMSI != &m_IMSI) + { + // We must copy queried IMSI. + status = m_IMSI.set_copy_of_buffer(IMSI); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + set_triplets(triplets->copy()); + if (m_triplets == 0 + || m_triplets->get_triplet_count() == 0) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u8_t local_eap_identifier; + + if (m_saved_previous_state == eap_type_gsmsim_state_waiting_for_challenge_response) + { + // Do not increase EAP-Identifier, this was re-transmission. + local_eap_identifier = m_last_eap_identifier; + } + else + { + local_eap_identifier = static_cast(m_last_eap_identifier+1u); + } + + status = send_challenge_request_message( + local_eap_identifier); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_last_eap_identifier = local_eap_identifier; + set_state(eap_type_gsmsim_state_waiting_for_challenge_response); + } + else + { + // Error occurred in tripler query. + // We must send EAP-Notification message. + // + // eap_gsmsim_notification_no_F_no_P_users_calls_are_barred and eap_gsmsim_notification_no_F_no_P_user_has_not_subscribed_to_the_requested_service cannot be used because P bit is not set. + m_gsmsim_notification_code = eap_gsmsim_notification_no_F_P_set_general_failure; + + status = initialize_notification_message(); + + m_last_eap_identifier = static_cast(m_last_eap_identifier+1u); + + set_state(eap_type_gsmsim_state_waiting_for_notification_response_failure); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_gsmsim_c::randomly_refuse_eap_identity() +{ + bool skip_query_imsi_from_username = false; + + if (m_gsmsim_test_version == true + && m_gsmsim_randomly_refuse_eap_identity == true) + { + crypto_random_c rand(m_am_tools); + + if (rand.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; + } + + u32_t random_guard; + + eap_status_e status = rand.get_rand_bytes( + reinterpret_cast(&random_guard), + sizeof(random_guard)); + if (status != eap_status_ok) + { + return false; + } + + if ((random_guard % 2) == 0) + { + // Note, this is just for testing. + skip_query_imsi_from_username = true; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: eap_type_gsmsim_c::randomly_refuse_eap_identity(): ") + EAPL("randomly fails EAP-Identity.\n"))); + } + } + + return skip_query_imsi_from_username; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_identity_response_message( + eap_header_rd_c * const eap_header, + const u32_t gsmsim_packet_length) +{ + eap_status_e status = eap_status_process_general_error; + +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + const eap_type_gsmsim_state_variable_e gsmsim_identity_response_states_1[] = + { + eap_type_gsmsim_state_waiting_for_identity_response, + eap_type_gsmsim_state_waiting_for_start_response, + eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity, + eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity, + eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity, + }; + + const eap_type_gsmsim_state_variable_e gsmsim_identity_response_states_2[] = + { + eap_type_gsmsim_state_waiting_for_start_response, + eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity, + eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity, + eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity, + }; + + if (verify_states(gsmsim_identity_response_states_1, GSMSIM_STATE_COUNT(gsmsim_identity_response_states_1)) == true + // In test version new authentication could start from this state. + || (m_gsmsim_test_version == true + && m_state == eap_type_gsmsim_state_success) // This one is for testing purposes. + ) +#else + if (m_state == eap_type_gsmsim_state_waiting_for_identity_response + || m_state == eap_type_gsmsim_state_waiting_for_start_response + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity + // In test version new authentication could start from this state. + || (m_gsmsim_test_version == true + && m_state == eap_type_gsmsim_state_success) // This one is for testing purposes. + ) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { + // OK correct state. + } + else + { + // Wrong state, dischard packet. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_identity_response_message(): ") + EAPL("EAP-Response/Identity received in wrong state %d=%s. This EAP-packet is dropped.\n"), + m_state, get_state_string())); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: erroneous EAP packet: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, type=0x%08x, client %d\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + convert_eap_type_to_u32_t(eap_header->get_type()), + get_is_client())); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (m_check_identifier_of_eap_identity_response == true) + { + if (m_state == eap_type_gsmsim_state_waiting_for_identity_response + && eap_header->get_identifier() != m_last_eap_identifier) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + eap_header->get_identifier(), + m_last_eap_identifier, + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + else if (verify_states(gsmsim_identity_response_states_2, GSMSIM_STATE_COUNT(gsmsim_identity_response_states_2)) == true + && eap_header->get_identifier() != m_last_eap_identifier-1u) +#else + else if ((m_state == eap_type_gsmsim_state_waiting_for_start_response + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity + ) + && eap_header->get_identifier() != m_last_eap_identifier-1u) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + eap_header->get_identifier(), + m_last_eap_identifier-1u, + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + // In test version new authentication could start from this state. + else if (m_gsmsim_test_version == true + && m_state == eap_type_gsmsim_state_success) // This one is for testing purposes. + { + // NOTE here we can not check the EAP-identifier. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_gsmsim_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is not checked in eap_type_gsmsim_state_variable_e %d=%s.\n"), + eap_header->get_identifier(), + m_state, + get_state_string())); + } + } + + { + // This could be first or retransmission request. + + if (eap_header->get_type_data_length() > gsmsim_packet_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + status = parse_identity( + eap_header->get_type_data( + eap_header->get_type_data_length()), + eap_header->get_type_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("GSMSIM received EAP-identity NAI"), + m_NAI.get_data(), + m_NAI.get_data_length())); + + u8_t next_eap_identifier = static_cast(eap_header->get_identifier()+1u); + +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + if (verify_states(gsmsim_identity_response_states_2, GSMSIM_STATE_COUNT(gsmsim_identity_response_states_2)) == true) +#else + if (m_state == eap_type_gsmsim_state_waiting_for_start_response + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity + ) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { + // This is retransmission, so the EAP-identifier is not increased. + next_eap_identifier = m_last_eap_identifier; + } + // In test version new authentication could start from this state. + else if (m_gsmsim_test_version == true + && m_state == eap_type_gsmsim_state_success) // This one is for testing purposes. + { + // NOTE here we can not check the EAP-identifier. + next_eap_identifier = static_cast(eap_header->get_identifier()+1u); + set_state(eap_type_gsmsim_state_waiting_for_identity_response); + m_IMSI.reset(); + } + + save_current_state(); + set_state(eap_type_gsmsim_state_pending_pseudonym_decode_query); + + eap_type_gsmsim_identity_type identity_type = GSMSIM_IDENTITY_TYPE_NONE; + + if (m_accept_eap_identity_response == true) + { + if (randomly_refuse_eap_identity() == false) + { + status = m_am_type_gsmsim->query_imsi_from_username( + false, + next_eap_identifier, + &m_send_network_id, + &m_identity, + &m_IMSI, + &identity_type, + eap_type_gsmsim_complete_handle_imsi_from_username); + } + else + { + status = eap_status_illegal_eap_identity; + } + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_imsi_from_username() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_imsi_from_username() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status != eap_status_ok) + { + // Identity decoding failed. + // We must query IMSI of client. + + if (m_use_manual_username == true) + { + // We reset the illegal identity. + // EAP-SIM/request/start will query identity. + m_identity.reset(); + } + } + else // status == eap_status_ok + { + // The query_imsi_from_username() function call was synchronous. + // We must call send_start_request_message(). + } + } + + + { + status = handle_imsi_from_username( + next_eap_identifier, + &m_send_network_id, + &m_identity, + &m_IMSI, + identity_type); + if (status != eap_status_ok) + { + // ERROR in handle_imsi_from_username(). + // This will return error status of handle_imsi_from_username() call. + } + else + { + // OK handle_imsi_from_username(). + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + const eap_variable_data_c * const imsi, ///< The result is stored to imsi parameter. + const eap_type_gsmsim_identity_type received_identity_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(username); + EAP_UNREFERENCED_PARAMETER(network_id); + + EAP_ASSERT(received_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID + || received_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID + || received_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID + || received_identity_type == GSMSIM_IDENTITY_TYPE_NONE); + + if (m_state != eap_type_gsmsim_state_pending_pseudonym_decode_query) + { + // State is wrong. Cannot continue. + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_gsmsim_state); + } + + eap_status_e status = eap_status_process_general_error; + bool pseudonym_decode_failed = true; + + set_identity_type(received_identity_type); + + if (imsi != 0 + && imsi->get_is_valid_data() == true) + { + pseudonym_decode_failed = false; + status = m_IMSI.set_copy_of_buffer(imsi); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (received_identity_type == GSMSIM_IDENTITY_TYPE_NONE) + { + set_identity_type(GSMSIM_IDENTITY_TYPE_IMSI_ID); + } + } + else + { + m_IMSI.reset(); + } + + if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID) + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: IMSI\n"))); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID) + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: pseudonym\n"))); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: re-authentication\n"))); + } + else + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_NONE; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: other\n"))); + } + + if ((m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID + && (m_saved_previous_state == eap_type_gsmsim_state_waiting_for_identity_response + || m_saved_previous_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity + || m_saved_previous_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity + || m_saved_previous_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity + || m_saved_previous_state == eap_type_gsmsim_state_waiting_for_start_response)) + || (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID + && (m_saved_previous_state == eap_type_gsmsim_state_waiting_for_identity_response + || m_saved_previous_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity + || m_saved_previous_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity + || m_saved_previous_state == eap_type_gsmsim_state_waiting_for_start_response)) + || m_identity_type == GSMSIM_IDENTITY_TYPE_NONE) + { + + if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID) + { + set_start_response_includes_identity(gsmsim_payload_AT_PERMANENT_ID_REQ); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID) + { + set_start_response_includes_identity(gsmsim_payload_AT_FULLAUTH_ID_REQ); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_NONE) + { + set_start_response_includes_identity(gsmsim_payload_AT_ANY_ID_REQ); + pseudonym_decode_failed = true; + } + + status = send_start_request_message( + pseudonym_decode_failed, + next_eap_identifier); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID + && (m_saved_previous_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity + || m_saved_previous_state == eap_type_gsmsim_state_waiting_for_identity_response + || m_saved_previous_state == eap_type_gsmsim_state_waiting_for_start_response)) + { + // Here we need to send EAP-Request/Re-authentication + status = send_reauthentication_request_message( + &m_NAI, + pseudonym_decode_failed, + next_eap_identifier); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_imsi_from_username(): ") + EAPL("EAP-Identity type 0x%02x is wrong in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_identity_type, + m_saved_previous_state, + get_saved_previous_state_string())); + + status = eap_status_illegal_eap_identity; + } + + if (status != eap_status_ok) + { + restore_saved_previous_state(); + } + else + { + m_last_eap_identifier = next_eap_identifier; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::complete_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + const eap_variable_data_c * const imsi, ///< The result is stored to imsi parameter. + const eap_type_gsmsim_identity_type identity_type, + const eap_status_e completion_status, + const eap_type_gsmsim_complete_e completion_action) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("eap_type_gsmsim_c::complete_imsi_from_username(): identity_type %d=%s, requested identity payload is %d=%s\n"), + identity_type, + get_identity_string(identity_type), + m_start_response_includes_identity, + gsmsim_payload_AT_header_c::get_payload_AT_string(m_start_response_includes_identity))); + + EAP_UNREFERENCED_PARAMETER(username); + EAP_UNREFERENCED_PARAMETER(network_id); + + if (completion_status != eap_status_ok) + { + set_state(eap_type_gsmsim_state_failure); + + // The completion_status error value is more important + // than return value of set_session_timeout(). + get_type_partner()->set_session_timeout(0ul); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, completion_status); + } + + eap_status_e status = eap_status_not_supported; + + if (completion_action == eap_type_gsmsim_complete_handle_imsi_from_username) + { + status = handle_imsi_from_username( + next_eap_identifier, + network_id, + username, + imsi, ///< The result is stored to imsi parameter. + identity_type); + + status = eap_status_completed_request; + } + else if (completion_action == eap_type_gsmsim_complete_handle_start_response_message_completion) + { + // NOTE the identity_payload_was_included parameter is + // true in this completion. + status = handle_start_response_message_completion( + next_eap_identifier, + completion_status, + identity_type, + true); + + status = eap_status_completed_request; + } + else + { + // Unknown completion. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::complete_imsi_from_username(): ") + EAPL("Unknown eap_type_gsmsim_complete_e %d in eap_type_gsmsim_state_variable_e %d=%s.\n"), + completion_action, + m_saved_previous_state, + get_saved_previous_state_string())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_start_response_message_completion( + const u8_t next_eap_identifier, + const eap_status_e identity_status, + eap_type_gsmsim_identity_type received_identity_type, + const bool identity_payload_was_included) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("eap_type_gsmsim_c::handle_start_response_message_completion(): received_identity_type %d=%s, requested identity payload is %d=%s\n"), + received_identity_type, + get_identity_string(received_identity_type), + m_start_response_includes_identity, + gsmsim_payload_AT_header_c::get_payload_AT_string(m_start_response_includes_identity))); + + if (m_state == eap_type_gsmsim_state_none) + { + // Authentication is terminated or state is wrong. Cannot continue. + + // The eap_status_handler_does_not_exists_error error value is more important + // than return value of set_session_timeout(). + get_type_partner()->set_session_timeout(0ul); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + } + + if (identity_payload_was_included == true) + { + if (identity_status != eap_status_ok + || received_identity_type == GSMSIM_IDENTITY_TYPE_NONE) + { + // We did not get valid identity. + set_identity_type(GSMSIM_IDENTITY_TYPE_NONE); + received_identity_type = GSMSIM_IDENTITY_TYPE_NONE; + + if (m_start_response_includes_identity == gsmsim_payload_AT_ANY_ID_REQ) + { + set_start_response_includes_identity(gsmsim_payload_AT_FULLAUTH_ID_REQ); + } + else // if (m_start_response_includes_identity == gsmsim_payload_AT_FULLAUTH_ID_REQ) + { + set_start_response_includes_identity(gsmsim_payload_AT_PERMANENT_ID_REQ); + } + } + else + { + set_identity_type(received_identity_type); + } + + if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID) + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: IMSI\n"))); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID) + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: pseudonym\n"))); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: re-authentication\n"))); + + // Here nonce_mt and SELECTED_VERSION MUST NOT be included. + // Note nonce_mt is copied earlier to handler. + if (m_nonce_mt.get_is_valid_data() == true + || m_gsmsim_selected_version != GSMSIM_ILLEGAL_VERSION) + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message_completion(4): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_NONE; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Identity: other\n"))); + } + } + else + { + // No AT_IDENTITY payload. + // We may have identity already. + if (m_identity.get_is_valid_data() == true + && m_authentication_type != GSMSIM_AUTHENTICATION_TYPE_NONE + && m_identity_type != GSMSIM_IDENTITY_TYPE_NONE) + { + // OK identity is known. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("eap_type_gsmsim_c::handle_start_response_message_completion(): Known m_identity_type %d=%s, requested identity payload is %d=%s\n"), + m_identity_type, + get_identity_string(m_identity_type), + m_start_response_includes_identity, + gsmsim_payload_AT_header_c::get_payload_AT_string(m_start_response_includes_identity))); + } + else + { + // ERROR no accepted identity. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message_completion(5): ") + EAPL("No correct GSMSIM-identity were received in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + + + + save_current_state(); + + u8_t local_eap_identifier(next_eap_identifier); + + if (m_identity_type == GSMSIM_IDENTITY_TYPE_NONE) + { + // This will send EAP-Request/SIM/Start with identity request. + eap_status_e local_status = send_start_request_message( + true, + local_eap_identifier); + if (local_status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + m_last_eap_identifier = local_eap_identifier; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID + || m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID + || (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID + && m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH)) + { + eap_type_gsmsim_identity_type local_identity_type = m_identity_type; + + eap_status_e local_status = query_SIM_triplets(&local_identity_type); + if (local_status == eap_status_pending_request) + { + // Request will be completed later with complete_SIM_triplets() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (local_status == eap_status_completed_request) + { + // Request was already completed with complete_SIM_triplets() function. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (local_status != eap_status_ok) + { + // This is an error case. + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + else //if (local_status == eap_status_ok) + { + // The query_SIM_triplets() function call is synchronous. + // We must call send_challenge_request_message(). + } + + local_status = send_challenge_request_message( + local_eap_identifier); + if (local_status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + + m_last_eap_identifier = local_eap_identifier; + set_state(eap_type_gsmsim_state_waiting_for_challenge_response); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID + && m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + // Here we need to send EAP-Request/Re-authentication + eap_status_e local_status = send_reauthentication_request_message( + &m_NAI, + false, + local_eap_identifier); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + else + { + // Unnown identity type, do nothing. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_start_response_message( + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("eap_type_gsmsim_c::handle_start_response_message(): m_identity_type %d=%s, requested identity payload is %d=%s\n"), + m_identity_type, + get_identity_string(m_identity_type), + m_start_response_includes_identity, + gsmsim_payload_AT_header_c::get_payload_AT_string(m_start_response_includes_identity))); + + if (gsmsim_packet_length < received_gsmsim->get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message(): ") + EAPL("gsmsim_packet_length < received_gsmsim->get_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + const eap_type_gsmsim_state_variable_e gsmsim_start_response_states_1[] = + { + eap_type_gsmsim_state_waiting_for_start_response, + eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity, + eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity, + eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity, + eap_type_gsmsim_state_waiting_for_challenge_response, + }; + + const eap_type_gsmsim_state_variable_e gsmsim_start_response_states_2[] = + { + eap_type_gsmsim_state_waiting_for_start_response, + eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity, + eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity, + eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity, + }; + + if (verify_states(gsmsim_start_response_states_1, GSMSIM_STATE_COUNT(gsmsim_start_response_states_1)) == true) +#else + if (m_state == eap_type_gsmsim_state_waiting_for_start_response + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity + || m_state == eap_type_gsmsim_state_waiting_for_challenge_response + ) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { +#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + if (verify_states(gsmsim_start_response_states_2, GSMSIM_STATE_COUNT(gsmsim_start_response_states_2)) == true) +#else + if (m_state == eap_type_gsmsim_state_waiting_for_start_response + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity + || m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity + ) +#endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) + { + if (received_gsmsim->get_identifier() != m_last_eap_identifier) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_identifier(), + m_last_eap_identifier, + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + else // if (m_state == eap_type_gsmsim_state_waiting_for_challenge_response) + { + // This might be retransmission response. + if (received_gsmsim->get_identifier() != m_last_eap_identifier-1u) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_identifier(), + m_last_eap_identifier-1u, + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + + + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // nonce_mt, not included in re-authentication + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // SELECTED_VERSION, not included in re-authentication + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be // RESULT_IND + ) == true + ) + { + if (m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity) + { + if (p_gsmsim_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + // OK, NAI identity is included. + // Identity must be IMSI. query_SIM_triplets() must decode identity. + + set_start_response_includes_identity(gsmsim_payload_AT_PERMANENT_ID_REQ); + } + else + { + // AT_IDENTITY is missing. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message(0x%08x), ") + EAPL("AT_IDENTITY is missing.\n"), + this)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity) + { + if (p_gsmsim_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + // OK, NAI identity is included. + // Identity must be IMSI or pseudonym identity. query_SIM_triplets() must decode identity. + + set_start_response_includes_identity(gsmsim_payload_AT_FULLAUTH_ID_REQ); + } + else + { + // AT_IDENTITY is missing. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message(0x%08x), ") + EAPL("AT_IDENTITY is missing.\n"), + this)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (m_state == eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity) + { + if (p_gsmsim_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + // OK, NAI identity is included. + // Identity must be IMSI, pseudonym or re-authentication identity. query_SIM_triplets() must decode identity. + + set_start_response_includes_identity(gsmsim_payload_AT_ANY_ID_REQ); + } + else + { + // AT_IDENTITY is missing. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message(0x%08x), ") + EAPL("AT_IDENTITY is missing.\n"), + this)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (m_state == eap_type_gsmsim_state_waiting_for_challenge_response) + { + // This is re-transmission. + if (p_gsmsim_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + if (m_start_response_includes_identity == gsmsim_payload_AT_PERMANENT_ID_REQ + || m_start_response_includes_identity == gsmsim_payload_AT_FULLAUTH_ID_REQ + || m_start_response_includes_identity == gsmsim_payload_AT_ANY_ID_REQ) + { + // OK, NAI identity is included. + } + else + { + // Illegal IDENTITY is included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message(0x%08x), ") + EAPL("illegal AT_IDENTITY included.\n"), + this)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + } + else + { + if (p_gsmsim_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + // Illegal IDENTITY is included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message(0x%08x), ") + EAPL("illegal AT_IDENTITY included.\n"), + this)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + + + if (p_gsmsim_payloads->get_NONCE_MT()->get_payload_included() == true) + { + // NOTE on re-authentication Start-message does not include NONCE_MT. + eap_status_e local_status = m_nonce_mt.set_copy_of_buffer( + p_gsmsim_payloads->get_NONCE_MT()->get_payload_buffer()); + if (local_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + } + + + if (p_gsmsim_payloads->get_SELECTED_VERSION()->get_payload_included() == true) + { + // NOTE on re-authentication Start-message does not include SELECTED_VERSION. + const eap_gsmsim_version selected_version + = static_cast(p_gsmsim_payloads + ->get_SELECTED_VERSION()->get_original_header()->get_reserved()); + + u16_t supported_versions[GSMSIM_LAST_VERSION]; + + for (u32_t ind = 0u; ind < GSMSIM_LAST_VERSION; ind++) + { + supported_versions[ind] = eap_htons(static_cast(m_supported_versions[ind])); + } + + { + eap_status_e local_status = save_version( + supported_versions, + GSMSIM_LAST_VERSION, + selected_version); + if (local_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, local_status); + } + } + + if (p_gsmsim_payloads->get_includes_unknown_attribute() != gsmsim_payload_NONE + && selected_version == GSMSIM_VERSION_1) + { + // EAP-SIM version 1 must NOT include unknown attributes. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message(0x%08x), illegal payload %d=0x%04x.\n"), + this, + p_gsmsim_payloads->get_includes_unknown_attribute(), + p_gsmsim_payloads->get_includes_unknown_attribute())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + + + eap_type_gsmsim_identity_type identity_type = GSMSIM_IDENTITY_TYPE_NONE; + bool identity_payload_was_included = false; + const u8_t next_eap_identifier = static_cast(received_gsmsim->get_identifier()+1u); + + if (p_gsmsim_payloads->get_IDENTITY_payload()->get_payload_included() == true) + { + status = parse_identity( + p_gsmsim_payloads->get_IDENTITY_payload()->get_data(p_gsmsim_payloads->get_IDENTITY_payload()->get_data_length()), + p_gsmsim_payloads->get_IDENTITY_payload()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + identity_payload_was_included = true; + + // We must ask AM module whether the identity is IMSI, pseudonym or re-authentication identity. + // If we have re-authentication identity we must send re-authentication query. + + if (randomly_refuse_eap_identity() == false) + { + status = m_am_type_gsmsim->query_imsi_from_username( + false, + next_eap_identifier, + &m_send_network_id, + &m_identity, + &m_IMSI, + &identity_type, + eap_type_gsmsim_complete_handle_start_response_message_completion); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_imsi_from_username() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_imsi_from_username() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else if (status != eap_status_ok) + { + // ERROR in query_imsi_from_username(). + // This will return error status of query_imsi_from_username() call. + + // Let handle_start_response_message_completion() handle error cases. + } + else // status == eap_status_ok + { + // The query_imsi_from_username() function call was synchronous. + // We must call handle_start_response_message_completion(). + } + } + else + { + status = eap_status_illegal_eap_identity; + } + } + + + status = handle_start_response_message_completion( + next_eap_identifier, + status, + identity_type, + identity_payload_was_included); + + + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message(4): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (m_state == eap_type_gsmsim_state_pending_triplet_query) + { + // This is retransmission of EAP-Response/SIM/Start. + // Triplet query is already initialized. + // We will drop this message quietly. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_gsmsim_c::handle_start_response_message(5): ") + EAPL("Retransmission of EAP-Response/SIM/Start in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else + { + // Wrong message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_start_response_message(): ") + EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_notification_response_message_reauthentication( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t /*gsmsim_packet_length*/, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: GSMSIM-type %10s, %s, state %2d=%s\n"), + EAPL("handle_notification_response_message_reauthentication"), + (m_is_client) ? EAPL("client") : EAPL("server"), + m_state, + get_state_string() + )); + + // The second most significant bit of the notification code is called + // the Phase bit (P bit). It specifies at which phase of the EAP-SIM + // exchange the notification can be used. + if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == false) + { + // If the P bit is set to zero, + // the notification can only be used after a successful EAP/SIM/ + // Challenge round in full authentication or a successful EAP/SIM/ + // Re-authentication round in reautentication. A re-authentication round + // is considered successful only if the peer has successfully verified + // AT_MAC and AT_COUNTER attributes, and does not include the + // AT_COUNTER_TOO_SMALL attribute in EAP-Response/SIM/Re-authentication. + + // The AT_MAC attribute MUST be included if the P bit of the notification + // code in AT_NOTIFICATION is set to zero, and MUST NOT be included in + // cases when the P bit is set to one. The P bit is discussed in Section + // 4.4. + + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be // RESULT_IND + ) == true + ) + { + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_aut(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + u32_t reauth_counter = 0u; + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_gsmsim->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_notification_response_message_reauthentication(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + reauth_counter)); + + status = check_message_authentication_code( + &orig_K_aut, + p_gsmsim_payloads, + received_gsmsim, + received_gsmsim->get_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + bool authentication_ok = true; + + // Decrypt and parse encrypted payload. + { + gsmsim_payloads_c * const l_gsmsim_payloads = new gsmsim_payloads_c(m_am_tools); + eap_automatic_variable_c l_gsmsim_payloads_automatic(m_am_tools, l_gsmsim_payloads); + + if (l_gsmsim_payloads == 0 + || l_gsmsim_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = decrypt_DATA_payload( + p_gsmsim_payloads, + &orig_K_encr); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t state_payload_buffer_length = p_gsmsim_payloads->get_ENCR_DATA()->get_data_length(); + const gsmsim_payload_AT_header_c gp_data_payload( + m_am_tools, + p_gsmsim_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), + state_payload_buffer_length); + + status = parse_gsmsim_payload( + &gp_data_payload, + &state_payload_buffer_length, + l_gsmsim_payloads, + received_gsmsim->get_subtype()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (l_gsmsim_payloads->get_COUNTER()->get_payload_included() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u32_t counter = l_gsmsim_payloads->get_COUNTER()->get_original_header()->get_reserved(); + + if (counter == reauth_counter) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_notification_response_message_reauthentication(): ") + EAPL("reauth counter %d OK, %d=%s.\n"), + reauth_counter, + m_state, + get_state_string())); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_notification_response_message_reauthentication(): ") + EAPL("reauth counter %d wrong, should be %d, %d=%s.\n"), + counter, + reauth_counter, + m_state, + get_state_string())); + + authentication_ok = false; + } + } + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (authentication_ok == false + || get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + + m_last_eap_identifier = static_cast(m_last_eap_identifier+1u); + set_state(eap_type_gsmsim_state_failure); + + // This will terminate session immediately. + get_type_partner()->set_session_timeout(0UL); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + if (m_gsmsim_notification_code == eap_gsmsim_notification_F_set_no_P_user_authenticated) + { + // In order to use re-authentication, the client and the server need to + // update re-authentication counter value. + status = m_am_type_gsmsim->increase_reauth_counter(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = finish_successful_authentication( + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_notification_response_message_reauthentication(): ") + EAPL("Not correct GSMSIM-payloads are included ") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else //if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == true) + { + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be // RESULT_IND + ) == true + ) + { + // If the P bit is set to one, the notification can only by used before + // the EAP/SIM/Challenge round in full authentication, or before the + // EAP/SIM/Re-authentication round in reauthentication. + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + } + else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + } + + status = initialize_error_message( + eap_status_process_general_error); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_notification_response_message_reauthentication(): ") + EAPL("Not correct GSMSIM-payloads are included ") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_notification_response_message_full_authentication( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t /*gsmsim_packet_length*/, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send: GSMSIM-type %10s, %s, state %2d=%s\n"), + EAPL("handle_notification_response_message_full_authentication"), + (m_is_client) ? EAPL("client") : EAPL("server"), + m_state, + get_state_string() + )); + + // The second most significant bit of the notification code is called + // the Phase bit (P bit). It specifies at which phase of the EAP-SIM + // exchange the notification can be used. + if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == false) + { + // If the P bit is set to zero, + // the notification can only be used after a successful EAP/SIM/ + // Challenge round in full authentication or a successful EAP/SIM/ + // Re-authentication round in reautentication. A re-authentication round + // is considered successful only if the peer has successfully verified + // AT_MAC and AT_COUNTER attributes, and does not include the + // AT_COUNTER_TOO_SMALL attribute in EAP-Response/SIM/Re-authentication. + + // The AT_MAC attribute MUST be included if the P bit of the notification + // code in AT_NOTIFICATION is set to zero, and MUST NOT be included in + // cases when the P bit is set to one. The P bit is discussed in Section + // 4.4. + + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be // RESULT_IND + ) == true + ) + { + eap_status_e status = check_message_authentication_code( + &m_K_aut, + p_gsmsim_payloads, + received_gsmsim, + received_gsmsim->get_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + + m_last_eap_identifier = static_cast(m_last_eap_identifier+1u); + set_state(eap_type_gsmsim_state_failure); + + // This will terminate session immediately. + get_type_partner()->set_session_timeout(0UL); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + if (m_gsmsim_notification_code == eap_gsmsim_notification_F_set_no_P_user_authenticated) + { + status = finish_successful_authentication( + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_notification_response_message_full_authentication(): ") + EAPL("Not correct GSMSIM-payloads are included ") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else //if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == true) + { + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be // RESULT_IND + ) == true + ) + { + // If the P bit is set to one, the notification can only by used before + // the EAP/SIM/Challenge round in full authentication, or before the + // EAP/SIM/Re-authentication round in reauthentication. + + // The most significant bit is called the Failure bit (F bit). + // The F bit specifies whether the notification implies failure. + if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) + { + // The code values with the F bit set to zero (code values 0...32767) + // are used on unsuccessful cases. + // The receipt of a notification code from this range implies failed EAP + // exchange, so the peer can use the notification as a failure indication. + } + else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) + { + // The receipt of a notification code with the F bit set to one (values + // 32768...65536) does not imply failure. Notification code 32768 has + // been reserved as a general notification code to indicate successful + // authentication. + } + + eap_status_e status = initialize_error_message( + eap_status_process_general_error); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_notification_response_message_full_authentication(): ") + EAPL("Not correct GSMSIM-payloads are included ") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_notification_response_message( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + if (gsmsim_packet_length < received_gsmsim->get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_notification_response_message(): ") + EAPL("gsmsim_packet_length < received_gsmsim->get_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + eap_status_e status = eap_status_process_general_error; + + if (m_state == eap_type_gsmsim_state_waiting_for_notification_response_success + || m_state == eap_type_gsmsim_state_waiting_for_notification_response_failure) + { + // NOTE, this message is unauthenticated. Anybody could sent this message. + + if (received_gsmsim->get_identifier() != m_last_eap_identifier) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_notification_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_identifier(), m_last_eap_identifier, + m_state, get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + + if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) + { + status = handle_notification_response_message_reauthentication( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = handle_notification_response_message_full_authentication( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Wrong message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_notification_response_message(): ") + EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::check_challenge_response_message( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_optional // RESULT_IND + ) == true + ) + { + save_current_state(); + set_state(eap_type_gsmsim_state_analyses_challenge_response); + + status = m_saved_EAP_packet.set_buffer( + received_gsmsim->get_header_buffer(gsmsim_packet_length), + gsmsim_packet_length, + false, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = check_message_authentication_code( + &m_K_aut, + p_gsmsim_payloads, + received_gsmsim, + gsmsim_packet_length); + + if (status == eap_status_ok) + { + // Ok, client successfully authenticated. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Authentication OK.\n"))); + + if (m_use_result_indication == false + && p_gsmsim_payloads->get_RESULT_IND()->get_payload_included() == true) + { + // ERROR: We did not send AT_RESULT_IND and client responds with it. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + else if (m_use_result_indication == true + && p_gsmsim_payloads->get_RESULT_IND()->get_payload_included() == false) + { + // Client does not expect result indication. + m_use_result_indication = false; + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (m_master_session_key.get_is_valid_data() == false + || m_master_session_key.get_data_length() == 0u) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_gsmsim->store_reauth_parameters( + &m_XKEY, + &m_K_aut, + &m_K_encr, + EAP_TYPE_GSMSIM_INITIAL_REAUTH_COUNTER); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_use_result_indication == true) + { + // Send EAP-Request/SIM/Notification. + + eap_type_gsmsim_state_variable_e next_state = eap_type_gsmsim_state_failure; + + if (m_randomly_fail_successfull_authentication == true + && random_selection() == true) + { + m_gsmsim_notification_code = eap_gsmsim_notification_no_F_P_set_general_failure; + next_state = eap_type_gsmsim_state_waiting_for_notification_response_failure; + } + else + { + m_gsmsim_notification_code = eap_gsmsim_notification_F_set_no_P_user_authenticated; + next_state = eap_type_gsmsim_state_waiting_for_notification_response_success; + } + + status = send_gsmsim_notification_request( + m_gsmsim_notification_code, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(next_state); + } + else + { + if (m_randomly_fail_successfull_authentication == true + && random_selection() == true) + { + // This is for testing. + m_gsmsim_notification_code = eap_gsmsim_notification_no_F_no_P_general_failure; + + status = initialize_notification_message(); + } + else + { + // Note the EAP-Identifier of EAP-Success must be the same as + // EAP-Identifier in the last EAP-Request - EAP-Response roundtrip. + status = finish_successful_authentication( + receive_network_id); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::check_challenge_response_message(6): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_challenge_response_message( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + if (m_state == eap_type_gsmsim_state_waiting_for_challenge_response) + { + if (received_gsmsim->get_identifier() != m_last_eap_identifier) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_challenge_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_identifier(), m_last_eap_identifier, + m_state, get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + status = check_challenge_response_message( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + } + else if (m_state == eap_type_gsmsim_state_success) + { + if (received_gsmsim->get_identifier() != m_last_eap_identifier-1u) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_challenge_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) ") + EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_identifier(), + m_last_eap_identifier-1u, + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + status = check_challenge_response_message( + receive_network_id, + received_gsmsim, + gsmsim_packet_length, + p_gsmsim_payloads); + } + else if (m_state == eap_type_gsmsim_state_pending_triplet_query) + { + // This is re-transmitted EAP-Response/SIM/Challenge. + // We dischard it quietly. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_gsmsim_c::handle_challenge_response_message(): ") + EAPL("Re-transmitted message %d=%s dropped in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else + { + // Wrong message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_challenge_response_message(): ") + EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_reauthentication_response_message( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_reauthentication_response_message(): %s, m_identity_type %d=%s, requested identity payload is %d=%s.\n"), + (m_is_client == true ? "client": "server"), + m_identity_type, + get_identity_string(m_identity_type), + m_start_response_includes_identity, + gsmsim_payload_AT_header_c::get_payload_AT_string(m_start_response_includes_identity))); + + if (m_state == eap_type_gsmsim_state_waiting_for_reauth_response) + { + // This could be first or retransmission request. + + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_optional // RESULT_IND + ) == true + ) + { + + m_last_eap_identifier = received_gsmsim->get_identifier(); + + save_current_state(); + set_state(eap_type_gsmsim_state_analyses_reauthentication_response); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_variable_data_c orig_XKEY(m_am_tools); + eap_variable_data_c orig_K_aut(m_am_tools); + eap_variable_data_c orig_K_encr(m_am_tools); + u32_t reauth_counter = 0u; + // In order to use re-authentication, the client and the server need to + // store the following values: original XKEY, K_aut, K_encr, latest + // counter value and the next re-authentication identity. + status = m_am_type_gsmsim->query_reauth_parameters( + &orig_XKEY, + &orig_K_aut, + &orig_K_encr, + &reauth_counter); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_gsmsim_c::handle_reauthentication_response_message(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + reauth_counter)); + + status = check_message_authentication_code( + &orig_K_aut, + p_gsmsim_payloads, + received_gsmsim, + gsmsim_packet_length); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: Re-authentication failed: %s, state %s\n"), + status_string.get_status_string(status), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Decrypt and parse encrypted payload. + if (p_gsmsim_payloads->get_IV()->get_payload_included() == true + || p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true) + { + if (p_gsmsim_payloads->get_IV()->get_payload_included() == true + && p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true + && p_gsmsim_payloads->get_MAC()->get_payload_included() == true) + { + if (m_use_result_indication == false + && p_gsmsim_payloads->get_RESULT_IND()->get_payload_included() == true) + { + // ERROR: We did not send AT_RESULT_IND and client responds with it. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + else if (m_use_result_indication == true + && p_gsmsim_payloads->get_RESULT_IND()->get_payload_included() == false) + { + // Client does not expect result indication. + m_use_result_indication = false; + } + + gsmsim_payloads_c * const l_gsmsim_payloads = new gsmsim_payloads_c(m_am_tools); + eap_automatic_variable_c l_gsmsim_payloads_automatic(m_am_tools, l_gsmsim_payloads); + + if (l_gsmsim_payloads == 0 + || l_gsmsim_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = decrypt_DATA_payload( + p_gsmsim_payloads, + &orig_K_encr); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t state_payload_buffer_length = p_gsmsim_payloads->get_ENCR_DATA()->get_data_length(); + + const gsmsim_payload_AT_header_c gp_data_payload( + m_am_tools, + p_gsmsim_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), + state_payload_buffer_length); + + if (gp_data_payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_gsmsim_payload( + &gp_data_payload, + &state_payload_buffer_length, + l_gsmsim_payloads, + received_gsmsim->get_subtype()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (l_gsmsim_payloads->get_COUNTER_TOO_SMALL()->get_payload_included() == true) + { + // When the client detects that the + // counter value is not fresh, it includes the AT_COUNTER_TOO_SMALL + // attribute in EAP-Response/SIM/Re-authentication. This attribute + // doesn't contain any data but it is a request for the server to + // initiate full authentication. + + // The full authentication must follow. + m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; + set_start_response_includes_identity(gsmsim_payload_NONE); + + bool pseudonym_decode_failed = false; + + if (m_identity.get_is_valid_data() == false + || (m_identity_type != GSMSIM_IDENTITY_TYPE_IMSI_ID + && m_identity_type != GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID + && m_identity_type != GSMSIM_IDENTITY_TYPE_RE_AUTH_ID)) + { + // We do not have any identity of the client. + set_start_response_includes_identity(gsmsim_payload_AT_FULLAUTH_ID_REQ); + set_identity_type(GSMSIM_IDENTITY_TYPE_NONE); + (void) m_identity.reset(); + pseudonym_decode_failed = true; + } + + status = send_start_request_message( + pseudonym_decode_failed, + static_cast(received_gsmsim->get_identifier()+1u)); + if (status == eap_status_ok) + { + m_last_eap_identifier = static_cast(received_gsmsim->get_identifier()+1u); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (l_gsmsim_payloads->get_COUNTER()->get_payload_included() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u32_t counter = l_gsmsim_payloads->get_COUNTER()->get_original_header()->get_reserved(); + + if (counter != reauth_counter) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // OK, client re-authenticates correctly. + + if (m_use_result_indication == true) + { + // Send EAP-Request/SIM/Notification. + m_gsmsim_notification_code = eap_gsmsim_notification_F_set_no_P_user_authenticated; + + status = send_gsmsim_notification_request( + m_gsmsim_notification_code, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(eap_type_gsmsim_state_waiting_for_notification_response_success); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_GSMSIM: %s, re-authentication OK, waits result indication\n"), + (m_is_client == true) ? "client": "server")); + } + else + { + if (m_randomly_fail_successfull_authentication == true + && random_selection() == true) + { + // This is for testing. + m_gsmsim_notification_code = eap_gsmsim_notification_no_F_no_P_general_failure; + + status = initialize_notification_message(); + } + else + { + // In order to use re-authentication, the client and the server need to + // update re-authentication counter value. + status = m_am_type_gsmsim->increase_reauth_counter(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Note the EAP-Identifier of EAP-Success must be the same as + // EAP-Identifier in the last EAP-Request - EAP-Response roundtrip. + status = finish_successful_authentication( + receive_network_id); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // All of these must be included + // or none of these must be included. + restore_saved_previous_state(); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + else + { + // Not correct GSMSIM-payloads are included. + restore_saved_previous_state(); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_reauthentication_response_message(6): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_reauthentication_response_message(6): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else + { + // Wrong message in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_reauthentication_response_message(): ") + EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), + received_gsmsim->get_subtype(), + received_gsmsim->get_subtype_string(), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_client_error_response_message( + const eap_am_network_id_c * const /* receive_network_id */, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads) +{ + EAP_UNREFERENCED_PARAMETER(gsmsim_packet_length); + EAP_UNREFERENCED_PARAMETER(received_gsmsim); + + eap_status_e status = eap_status_process_general_error; + + // This could be first, retransmission request + // or some nasty attacker to make denial of service. + + // Checks the payloads existence. + if (p_gsmsim_payloads->check_payloads( + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // MAC + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ENCR_DATA + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IV + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL + gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // CLIENT_ERROR_CODE + gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be // RESULT_IND + ) == true + ) + { + eap_status_e client_status = eap_status_process_general_error; + + /** @{ Add some use for the Client Error Code. } */ + eap_gsmsim_client_error_code_e client_error_code + = static_cast(p_gsmsim_payloads->get_CLIENT_ERROR_CODE() + ->get_original_header()->get_reserved()); + + EAP_UNREFERENCED_PARAMETER(client_error_code); + + status = initialize_error_message( + client_status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct GSMSIM-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: eap_type_gsmsim_c::handle_client_error_response_message(): ") + EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), + m_state, + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::check_NAI( + const u8_t * const identity, + const u32_t identity_length, + const u8_t * const at_character) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + bool includes_at = false; + bool includes_dot = false; + u32_t username_length = 0u; + u32_t realm_length = 0u; + + for (u32_t ind = 0; ind < identity_length; ind++) + { + const u8_t character = identity[ind]; + + if (includes_at == false) + { + if (character != GSMSIM_NAI_AT_BYTE) + { + ++username_length; + } + } + else + { + ++realm_length; + } + + + if ('0' <= character && character <= '9') + { + // OK. + } + else if ('a' <= character && character <= 'z') + { + // OK. + } + else if ('A' <= character && character <= 'Z') + { + // OK. + } + else if (character == GSMSIM_NAI_AT_BYTE) + { + if (includes_at == false) + { + includes_at = true; + } + else + { + // Second at ('@'). + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Illegal NAI, includes second at \'@\' character."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + else if (character == '.') + { + if (includes_at == true) + { + // OK. + includes_dot = true; + } + else + { + // dot ('.') within username + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Illegal NAI, dot \'.\' within username."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + else if (character == '<' + || character == '>' + || character == '(' + || character == ')' + || character == '[' + || character == ']' + || character == '\\' + || character == '.' + || character == ',' + || character == ';' + || character == ':' + || character == GSMSIM_NAI_AT_BYTE + || character == ' ' // space + || character <= 0x1f // Ctrl + || character >= 0x7f) // extented characters + { + // Illegal character. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_GSMSIM_ERROR, + (EAPL("ERROR: Illegal NAI, includes illegal character 0x%02x=%c.\n"), + character, + character)); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Illegal NAI, includes illegal character."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + else + { + // All other ascii values are OK. + } + } + + // Note the username could be zero length. + if ((realm_length == 1u && includes_at == true) // one at ('@') is illegal. + || (realm_length == 2u && includes_at == true && includes_dot == true)) // one at ('@') and one dot is illegal. + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, (EAPL("Illegal NAI."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + + if (m_check_nai_realm == true) + { + if (at_character == 0 + && realm_length == 0 + && get_nai_realm()->get_data_length() == 0) + { + // OK, no realm. + } + else if (at_character == 0 + || realm_length != get_nai_realm()->get_data_length() + || m_am_tools->memcmp( + at_character+1u, + get_nai_realm()->get_data(), + get_nai_realm()->get_data_length()) != 0) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Illegal NAI, realm unknown."), + identity, + identity_length)); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("NAI should be"), + get_nai_realm()->get_data(), + get_nai_realm()->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::parse_identity( + const u8_t * const identity, + const u32_t identity_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + if (identity_length < 1u) + { + status = m_identity.init(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_NAI.init(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + const u8_t *at_character = reinterpret_cast(m_am_tools->memchr( + identity, + GSMSIM_AT_CHARACTER[0], + identity_length)); + + // NOTE, at_character could be NULL. Realm is optional. + + status = check_NAI(identity, identity_length, at_character); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_process_general_error; + + u32_t username_length = identity_length; + if (at_character != 0) + { + username_length = static_cast(at_character-identity); + } + + status = m_identity.set_copy_of_buffer( + identity, // Note we do store whole IMSI or pseudonym including possible prefix. + username_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_NAI.set_copy_of_buffer(identity, identity_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_state.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_state.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,105 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 83 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_type_gsmsim_header.h" +#include "eap_type_gsmsim_types.h" +#include "eap_type_gsmsim_payloads.h" +#include "abs_eap_type_gsmsim_state.h" +#include "abs_eap_base_timer.h" +#include "eap_type_gsmsim_state.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_type_gsmsim_state_variable_parameters_c::~eap_type_gsmsim_state_variable_parameters_c() +{ +} + +EAP_FUNC_EXPORT eap_type_gsmsim_state_variable_parameters_c::eap_type_gsmsim_state_variable_parameters_c() + : m_must_be_initiator(false) + , m_must_be_responder(false) +{ + u32_t ind = 0; + for (ind = 0; ind < GSMSIM_STATE_MAX_TYPES; ind++) + { + m_valid_types[ind] = gsmsim_subtype_NONE; + } +} + + +EAP_FUNC_EXPORT bool eap_type_gsmsim_state_variable_parameters_c::check_valid_types(gsmsim_subtype_e type) const +{ + for (u32_t ind = 0u; ind < GSMSIM_STATE_MAX_TYPES; ind++) + { + if (type == m_valid_types[ind]) + { + return true; + } + } + return false; +} + +EAP_FUNC_EXPORT bool eap_type_gsmsim_state_variable_parameters_c::check_initiator(const bool is_initiator) const +{ + if (m_must_be_initiator == true && is_initiator == false + || m_must_be_responder == true && is_initiator == true) + { + return false; + } + return true; +} + +EAP_FUNC_EXPORT void eap_type_gsmsim_state_variable_parameters_c::init_state( + const bool must_be_initiator, + const bool must_be_responder, + const gsmsim_subtype_e type0, + const gsmsim_subtype_e type1, + const gsmsim_subtype_e type2, + const gsmsim_subtype_e type3) +{ + m_must_be_initiator = (must_be_initiator); + m_must_be_responder = (must_be_responder); + m_valid_types[0] = (type0); + m_valid_types[1] = (type1); + m_valid_types[2] = (type2); + m_valid_types[3] = (type3); +} + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_state_notification.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim_state_notification.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 84 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_type_gsmsim_state_notification.h" +#include "eap_type_gsmsim_types.h" +#include "eap_tools.h" +#include "eap_type_gsmsim.h" + + +EAP_FUNC_EXPORT eap_type_gsmsim_state_notification_c::~eap_type_gsmsim_state_notification_c() +{ +} + +EAP_FUNC_EXPORT eap_type_gsmsim_state_notification_c::eap_type_gsmsim_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e type, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + protocol, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + + +#if defined(USE_EAP_EXPANDED_TYPES) + +EAP_FUNC_EXPORT eap_type_gsmsim_state_notification_c::eap_type_gsmsim_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e type, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + eap_type, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + +EAP_FUNC_EXPORT eap_type_gsmsim_state_notification_c::eap_type_gsmsim_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e type, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + eap_type, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/core/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/core/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,30 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_gsmsim + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_client.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_payloads.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_server.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_state.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_state_notification.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_header.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_initialized.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_mac_attributes.cpp + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_gsmsim_simulator.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_testing_tools.$(LIB) \ + -lstdc++ + +# $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_dummy_sim.$(LIB) \ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/include/abs_eap_type_gsmsim_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/include/abs_eap_type_gsmsim_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,146 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_GSMSIM_STATE_H_) +#define _ABS_GSMSIM_STATE_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_buffer.h" +#include "eap_base_type.h" +#include "eap_config.h" +#include "eap_type_gsmsim_types.h" + + +/// This class declares the functions eap_type_gsmsim_state_c +/// requires from the partner class. +class EAP_EXPORT abs_eap_type_gsmsim_state_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Constructor does nothing. + */ + virtual ~abs_eap_type_gsmsim_state_c() + { + } + + /** + * Desstructor does nothing. + */ + abs_eap_type_gsmsim_state_c() + { + } + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @see abs_eap_base_type_c::get_header_offset(). + */ + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + //-------------------------------------------------- +}; // class abs_eap_type_gsmsim_state_c + + + +#endif //#if !defined(_ABS_GSMSIM_STATE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_gsmsim_state_notification.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_gsmsim_state_notification.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_GSMSIM_STATE_NOTIFICATION_H_) +#define _EAP_GSMSIM_STATE_NOTIFICATION_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_protocol_layer.h" +#include "abs_eap_state_notification.h" + + +/// A eap_gsmsim_state_notification_c class. +/// This is used for debugging and protocol testing. +class EAP_EXPORT eap_gsmsim_state_notification_c +: public abs_eap_state_notification_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; ///< This is pointer to the tools class. @see abs_eap_am_tools_c. + + eap_protocol_layer_e m_layer; ///< Here is the protocol layer (EAP type). + + eap_variable_data_c m_notification_string; ///< Here is the notification string. + + eap_boolean_e m_needs_confirmation_from_user; ///< This flag tells whether user interaction is required. + + u32_t m_protocol; ///< Here is the EAP type. + + u32_t m_previous_state; ///< Here is the previous state of the EAP type. + + u32_t m_current_state; ///< Here is the current state of the EAP type. + + const eap_am_network_id_c *m_send_network_id; + + eap_boolean_e m_is_client; + + u8_t m_eap_identifier; + + eap_boolean_e m_allow_send_eap_success; + + EAP_FUNC_IMPORT eap_const_string get_state_string(const u32_t state) const; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_gsmsim_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_gsmsim_state_notification_c(); + + /** + * The constructor of the eap_gsmsim_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT eap_gsmsim_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + eap_boolean_e is_client, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + eap_boolean_e allow_send_eap_success); + + // This is commented in abs_eap_state_notification_c::get_send_network_id(). + EAP_FUNC_IMPORT const eap_am_network_id_c * const get_send_network_id() const; + + // This is commented in abs_eap_state_notification_c::get_protocol_layer(). + EAP_FUNC_IMPORT const eap_protocol_layer_e get_protocol_layer() const; + + // This is commented in abs_eap_state_notification_c::get_protocol(). + EAP_FUNC_IMPORT const u32_t get_protocol() const; + + // This is commented in abs_eap_state_notification_c::get_previous_state(). + EAP_FUNC_IMPORT const u32_t get_previous_state() const; + + // This is commented in abs_eap_state_notification_c::get_previous_state_string(). + EAP_FUNC_IMPORT eap_const_string get_previous_state_string() const; + + // This is commented in abs_eap_state_notification_c::get_current_state(). + EAP_FUNC_IMPORT const u32_t get_current_state() const; + + // This is commented in abs_eap_state_notification_c::get_current_state_string(). + EAP_FUNC_IMPORT eap_const_string get_current_state_string() const; + + // This is commented in abs_eap_state_notification_c::get_is_client(). + EAP_FUNC_IMPORT const eap_boolean_e get_is_client() const; + + // This is commented in abs_eap_state_notification_c::get_eap_identifier(). + EAP_FUNC_IMPORT const u8_t get_eap_identifier() const; + + // This is commented in abs_eap_state_notification_c::get_allow_send_eap_success(). + EAP_FUNC_IMPORT eap_boolean_e get_allow_send_eap_success() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT const eap_status_e set_notification_string( + const eap_variable_data_c * const notification_string, + const eap_boolean_e needs_confirmation_from_user); + + //-------------------------------------------------- +}; // class eap_gsmsim_state_notification_c + +#endif //#if !defined(_EAP_GSMSIM_STATE_NOTIFICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1873 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_GSMSIM_CORE_H_) +#define _GSMSIM_CORE_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_type_gsmsim_types.h" +#include "eap_type_gsmsim_payloads.h" +#include "eap_type_gsmsim_state.h" +#include "abs_eap_base_timer.h" +#include "abs_eap_am_type_gsmsim.h" +#include "eap_master_session_key.h" + + +class eap_type_gsmsim_MAC_attributes_c; +class eap_am_type_gsmsim_c; +class crypto_hmac_c; + +//#define USE_EAP_GSMSIM_VERIFY_STATES + +//-------------------------------------------------- + + +/// This class is implementation of GSMSIM EAP-type. +class EAP_EXPORT eap_type_gsmsim_c +: public abs_eap_type_gsmsim_state_c +, public abs_eap_am_type_gsmsim_c +, public abs_eap_base_timer_c +, public eap_base_type_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- + +#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + /// This attribute stores the valid GSMSIM states (eap_type_gsmsim_state_variable_e). + /// Each eap_type_gsmsim_state_variable_parameters_c includes the valid + /// GSMSIM messages within the state. + eap_type_gsmsim_state_variable_parameters_c m_parameters[eap_type_gsmsim_state_last_value]; +#endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + + /// This is the current state. + eap_type_gsmsim_state_variable_e m_state; + + /// This is the saved previous state. On error case this is the state where continue. + eap_type_gsmsim_state_variable_e m_saved_previous_state; + + /// This is network identity of the sent packet from this handler. + eap_am_network_id_c m_send_network_id; + + /// This is the NONCE_MT. Client generates NONCE_MT and sends it to server + /// within the EAP-Response/SIM/Start message. + eap_variable_data_c m_nonce_mt; + + /// This is the NONCE_S. Server generates NONCE_S and sends it to client + /// within the EAP-Request/SIM/Re-authentication message. + eap_variable_data_c m_nonce_s; + + // - - - - - - - - - - - - - - - - - - - - + + /// Server sends IV to client within EAP-Request/SIM/Challenge message. + /// The AT_IV payload is optional. + gsmsim_variable_data_c m_IV; + + /// EAP-Request/SIM/Challenge message must be saved until n*Kc and n*SRES are get from SIM. + eap_variable_data_c m_saved_EAP_packet; + + // - - - - - - - - - - - - - - - - - - - - + + /// XKEY = SHA1(n*Kc| NONCE_MT) + eap_variable_data_c m_XKEY; + + /// K_encr is the first 16 octets of generated Key_block:s. + eap_variable_data_c m_K_encr; + + /// K_aut is the 16 octets after K_encr of generated Key_block:s. + eap_variable_data_c m_K_aut; + + /// m_master_session_key is the 20 octets after m_K_aut of generated Key_block:s. + eap_master_session_key_c m_master_session_key; + + // - - - - - - - - - - - - - - - - - - - - + + /// This is the real IMSI. + eap_variable_data_c m_IMSI; + + /// This is the pseudonym for IMSI. This is used only if server supports use of pseudonym. + eap_variable_data_c m_pseudonym; + + /// This is the reauthentication identity. This is used only if server supports use of reauthentication identity. + eap_variable_data_c m_reauthentication_identity; + + /// This is the automatic realm generated in AM of EAP-SIM. + /// Note this could be invalid data when automatic realm is not used. + /// The m_automatic_realm_read flag tells whether m_automatic_realm is read from AM of EAP-SIM. + eap_variable_data_c m_automatic_realm; + + /// This flag tells whether automatic realm is read from AM of EAP-SIM. + /// Note the data of m_automatic_realm could be invalid data when it is not used. + bool m_automatic_realm_read; + + /// This is identity used in authentication. This is real IMSI or pseudonym. + /// Pseudonym is used only if server supports use of pseudonym. + eap_variable_data_c m_identity; + + /// This is the NAI. Format is "username@realm". + eap_variable_data_c m_NAI; + + eap_variable_data_c m_n_rands; + + eap_variable_data_c m_n_sres; + + /// This variable stores the received GSMSIM version list. + eap_variable_data_c m_gsmsim_version_list; + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /// Here is stored the received triplets. + eap_type_sim_triplet_array_c *m_triplets; +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + u32_t m_reauthentication_counter; + + gsmsim_payload_AT_type_e m_include_identity_to_start_response; + + /// Identity of this type is included in start response. + gsmsim_payload_AT_type_e m_start_response_includes_identity; + + /// This flag indicates whether the EAP-Failure was received. + /// On successfull authentication bogus EAP-Failure is ignored. + bool m_failure_message_received; + /// This flag indicated whether the authentication was successfull (true). + bool m_authentication_finished_successfully; + + /// This variable stores the last used EAP-Identifier. + /// Client will always send EAP-Response with this identifier. + /// Server will always send EAP-Request with this identifier increased by one. + /// Server increase this identifier after successfull packet send. + u8_t m_last_eap_identifier; + + eap_gsmsim_version m_gsmsim_selected_version; + + eap_variable_data_c m_2_digit_mnc_map_of_mcc_of_imsi_array; + + eap_variable_data_c m_uma_automatic_realm_prefix; + + bool m_use_uma_profile; + + //-------------------------------------------------- + + /// This is pointer to adaptation module of GSMSIM EAP type. + eap_am_type_gsmsim_c * const m_am_type_gsmsim; + +#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + eap_variable_data_c m_nonce_mt_file; +#endif //#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + + eap_variable_data_c m_manual_username; + + eap_variable_data_c m_manual_realm; + + /// This eap_gsmsim_version array is the supported GSMSIM version list. + eap_gsmsim_version m_supported_versions[GSMSIM_LAST_VERSION]; + + /// This is offset in bytes of the EAP-type header in the packet buffer. + /// Offset is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_gsmsim_header_offset; + + /// This is maximum transfer unit in bytes. + /// MTU is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_MTU; + + /// This is length of the trailer in bytes. + /// Trailer length is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_trailer_length; + + /// This is minimum count of RAND challenges accepted. + u32_t m_minimum_rand_count; + + u32_t m_length_of_mnc; + + /// This stores the current authentication type. + /// Look at the m_identity_type too. + eap_gsmsim_authentication_type_e m_authentication_type; + + /// This stores the current identity type. + /// NOTE there is one stupid case where m_identity_type is GSMSIM_IDENTITY_TYPE_RE_AUTH_ID + /// and m_authentication_type is GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH. + /// Look at the Chapter "Fast Re-authentication Procedure when Counter is Too Small" + /// in the EAP-SIM specification. + /// Because of that illogical specification we need separate + /// attributes for authentication type and identity type. + eap_type_gsmsim_identity_type m_identity_type; + + /// This is the first client error. + eap_gsmsim_client_error_code_e m_client_error_code; + + /// This is saved GSMSIM notificatoin code. + /// If this value is eap_gsmsim_notification_none, no notification is stored. + eap_gsmsim_notification_codes_e m_gsmsim_notification_code; + + u32_t m_failure_message_delay_time; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + /// True value of this flag indicates the EAP-Success packet must be received + /// in successfull authentication of clien. + /// This value is configured with EAP_GSMSIM_wait_eap_success_packet. + bool m_wait_eap_success_packet; + + /// True value of this flag indicates the identifier of the EAP-Response/Identity must be checked. + /// This is not possible cases where identifier of the EAP-Request/Identity is generated by other network entities. + bool m_check_identifier_of_eap_identity_response; + + + /// True value means m_am_type_gsmsim is allocated within eap_type_gsmsim_c + /// and m_am_type_gsmsim must be freed in destructor. + bool m_free_am_type_gsmsim; + +#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + /// True value means client responds to all re-transmitted EAP-SIM packets. + /// False value means client does not respond to any re-transmitted EAP-SIM packets. + bool m_client_responds_retransmitted_packets; +#endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) + + /// True value means this is a test version of GSMSIM. + bool m_gsmsim_test_version; + + /// True value means server refuses EAP-identity randomly. + /// False value means does not refuse EAP-identity randomly. + /// NOTE EAP_GSMSIM_test_version option must be true also. + bool m_gsmsim_randomly_refuse_eap_identity; + + /// This flag forces check of NAI realm. Realm must be the same as given in EAP_GSMSIM_manual_realm configuration option. + /// Default value is false, check is not done by default. + bool m_check_nai_realm; + + /// This is for testing purposes. True value will cause failed test of re-authentication counter. + bool m_fail_reauthentication_counter_check; + + /// True value of this flag allows acception of EAP-Response/Identity. + /// False value does not accept EAP-Response/Identity. Instead identity is queried + /// in EAP-Request/SIM/Start with AT_ANY_ID_REQ attribute. + bool m_accept_eap_identity_response; + + /// True value of this flag returns random + /// identity on EAP-Response/Identity. + /// False value returns real identity + /// (IMSI, pseudonym or re-authentication identity). + bool m_use_random_identity_on_eap_identity_response; + + /// This flag is set true when shutdown() function is called. + bool m_shutdown_was_called; + + /// This flag is set true when reset() function is called. + /// This flag prevent multiple subsequent calls of rset() function. + bool m_reset_was_called; + + /// This flag tells whether the client should check uniqueness of RANDs (true) or not (false). + bool m_do_rand_uniqueness_check; + + /// This flag tells whether the pseudonym identity could be used (true) or not (false). + bool m_use_pseudonym_identity; + + /// This flag tells whether the re-authentication identity could be used (true) or not (false). + bool m_use_reauthentication_identity; + + /// This is set true when erroneus packet is received. + bool m_erroneus_packet_received; + + /// This is set true when SIM notification packet is received. + bool m_sim_notification_packet_received; + + /// This flag allows use of Windows RAS identity in EAP-Identity/Response. + /// EAP-Request/Start will include identity query attribute. + bool m_use_manual_username; + + /// Default value is false. That will cause use of automatic realm. + /// If this is true then + /// cf_str_EAP_GSMSIM_manual_realm is used as the realm. + bool m_use_manual_realm; + + bool m_randomly_fail_successfull_authentication; + + bool m_allow_use_result_indication; + + bool m_use_result_indication; + + bool m_use_eap_expanded_type; + + //-------------------------------------------------- + + /** + * This function stores the last encryption IV. In CBC-mode previous encrypted block is + * used as a IV of next block. + */ + eap_status_e store_last_encryption_iv(const eap_variable_data_c * const encryption_IV); + + /** + * This function selects best version from version list payload. + */ + EAP_FUNC_IMPORT eap_gsmsim_version select_version( + const gsmsim_variable_data_c * const version_payload, + bool * const includes_other_version_than_1); + + /** + * This function returns string of the current state. This is for trace purposes. + */ + EAP_FUNC_IMPORT eap_const_string get_state_string() const; + + /** + * This function returns string of the current state. This is for trace purposes. + */ + EAP_FUNC_IMPORT eap_const_string get_saved_previous_state_string() const; + + /** + * This function sets the new state and notifies the lower layer of this change. + */ + void set_state(eap_type_gsmsim_state_variable_e state); + + #define GSMSIM_STATE_COUNT(array) (sizeof(array)/sizeof(array[0])) + + /** + * This function checks the valid states. + */ + bool verify_states( + const eap_type_gsmsim_state_variable_e * const valid_states, + const u32_t count) const; + + +#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + + /** + * This function checks the received GSMSIM subtype is valid in current state. + * This is used for quick check. + */ + EAP_FUNC_IMPORT eap_status_e check_valid_state(gsmsim_subtype_e type); + + /** + * This function returns the eap_type_gsmsim_state_variable_parameters_c object of current state. + */ + EAP_FUNC_IMPORT const eap_type_gsmsim_state_variable_parameters_c * get_state_variable(); + +#endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + + + /** + * This function saves the current m_state to m_saved_previous_state. + * The saved state is restored in error case. + */ + EAP_FUNC_IMPORT void save_current_state(); + + /** + * This function restores the saved state. + */ + EAP_FUNC_IMPORT void restore_saved_previous_state(); + + /** + * This function stores identity. + */ + EAP_FUNC_IMPORT eap_status_e store_identity( + const eap_variable_data_c * const IMSI_or_pseudonym, + const bool IMSI_is_used); + +#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + /** + * This function initializes the allowed messages within one specific state. + */ + EAP_FUNC_IMPORT void initialize_state( + const eap_type_gsmsim_state_variable_e state, + const bool must_be_initiator, + const bool must_be_responder, + const gsmsim_subtype_e type0, + const gsmsim_subtype_e type1, + const gsmsim_subtype_e type2, + const gsmsim_subtype_e type3); +#endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK) + + /** + * This function expands key and seed data to key_length of expansion. + * expansion_0 = prf(key, seed | 0) + * expansion_i = prf(key, expansion_i-1 | seed | i), where i = 1, 2... + */ + EAP_FUNC_IMPORT eap_status_e data_exp( + const u32_t key_length, + eap_variable_data_c * const expansion, + const eap_variable_data_c * const key, + const eap_variable_data_c * const seed); + + /** + * This function generates K_encr, K_aut and master_session_key. + */ + EAP_FUNC_IMPORT eap_status_e generate_shared_secred_keys( + const u32_t key_length, + const eap_variable_data_c * const n_Kc, + const eap_variable_data_c * const n_sres, + eap_variable_data_c * const XKEY, + eap_variable_data_c * const K_encr, + eap_variable_data_c * const K_aut, + eap_variable_data_c * const master_session_key); + + + /** + * This function generates K_encr, K_aut and master_session_key. + */ + EAP_FUNC_IMPORT eap_status_e generate_reauth_shared_secred_keys( + const u32_t key_length, + const eap_variable_data_c * const orig_XKEY, + const u32_t reauth_counter, + const eap_variable_data_c * const reauth_identity, + const eap_variable_data_c * const reauth_nonce_s, + eap_variable_data_c * const master_session_key); + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function stores pointer to the received triplet array. + */ + void set_triplets(eap_type_sim_triplet_array_c * const triplets); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + /** + * This function saves version list from version list payload. + */ + EAP_FUNC_IMPORT eap_status_e save_version( + const u16_t * const payload_version_list, + const u32_t version_count, + const eap_gsmsim_version selected_version); + + /** + * This function generates a new NAI from domain and IMSI. + */ + EAP_FUNC_IMPORT eap_status_e generate_nai( + eap_variable_data_c * const new_nai, ///< This is the new generated NAI. + const bool use_manual_default_realm, ///< When true uses realm parameter, when false generates automatic realm. + const eap_variable_data_c * const realm, ///< This is the domain part of the NAI. + const eap_variable_data_c * const id_IMSI_or_pseydonym, ///< This is IMSI or pseudonym. + const bool id_is_imsi, ///< This parameter tells whether id_IMSI_or_pseydonym is IMSI (true) or pseudonym (false). + const eap_variable_data_c * const IMSI, ///< This parameter must be IMSI always. + const eap_variable_data_c * const automatic_realm, ///< This could be zero pointer if this is not used. + const u32_t length_of_mnc + ); + + /** + * This function adds generic attribute payload to GSMSIM message. + * @param gsmsim is pointer to EAP header including GSMSIM fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also gsmsim_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in GSMSIM EAP packet. + * It is the value of GSMSIM sub-type data. + * @param data_free is the remaining free GSMSIM data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param data_payload is the new payload to be added. + * @param data_payload_type is the attribute payload type to be added. + * + * See also eap_type_gsmsim_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT type | Payload Length| Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Any variable length payload | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_variable_payload( + gsmsim_header_c * const gsmsim, + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_free, + u32_t * const buffer_offset, + const eap_variable_data_c * const data_payload, + const gsmsim_payload_AT_type_e data_payload_type); + + + /** + * This function adds IMSI or pseudonym attribute payload to GSMSIM message. + * @param gsmsim is pointer to EAP header including GSMSIM fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also gsmsim_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in GSMSIM EAP packet. + * It is the value of GSMSIM sub-type data. + * @param data_free is the remaining free GSMSIM data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param pseudonym_or_imsi is the IMSI or pseudonym payload to be added. + * @param data_payload_type is the attribute payload type to be added. + * + * See also eap_type_gsmsim_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT_ | Length | Actual Pseudonym Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Pseudonym or IMSI | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_pseudonym_or_imsi_payload( + gsmsim_header_c * const gsmsim, + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_free, + u32_t * const buffer_offset, + const eap_variable_data_c * const pseudonym_or_imsi, + const gsmsim_payload_AT_type_e data_payload_type); + + + /** + * This function adds version list attribute payload to GSMSIM message. + * @param gsmsim is pointer to EAP header including GSMSIM fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also gsmsim_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in GSMSIM EAP packet. + * It is the value of GSMSIM sub-type data. + * @param data_free is the remaining free GSMSIM data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param gsmsim_versions is the version list (actually array) payload to be added. + * @param gsmsim_versions_count is the count versions in the array. + * @param data_payload_type is the attribute payload type to be added. + * + * See also eap_type_gsmsim_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT_VERSION_L..| Length | Actual Version List Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Supported Version 1 | Padding | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_version_list( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_gsmsim_version *gsmsim_versions, + const u32_t gsmsim_versions_count, + const gsmsim_payload_AT_type_e data_payload_type); + + + /** + * This function adds selected version attribute payload to GSMSIM message. + * @param gsmsim is pointer to EAP header including GSMSIM fields. + * @param gsmsim_buffer_length is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also gsmsim_header_c and eap_header_base_c. + * @param gsmsim_data_offset is the offset of inserted payloads in GSMSIM EAP packet. + * It is the value of GSMSIM sub-type data. + * @param gsmsim_data_free is the remaining free GSMSIM data buffer size. + * @param packet_buffer_free is the remaining free packet buffer size. + * @param packet_buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param version is the selected GSMSIM version. + * + * See also eap_type_gsmsim_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |AT_SELECTED_...| Length = 1 | Notification Code | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_version_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_gsmsim_version version); + + /** + * This function adds selected version attribute payload to GSMSIM message. + * @param gsmsim is pointer to EAP header including GSMSIM fields. + * @param gsmsim_buffer_length is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also gsmsim_header_c and eap_header_base_c. + * @param gsmsim_data_offset is the offset of inserted payloads in GSMSIM EAP packet. + * It is the value of GSMSIM sub-type data. + * @param gsmsim_data_free is the remaining free GSMSIM data buffer size. + * @param packet_buffer_free is the remaining free packet buffer size. + * @param packet_buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param counter is the re-authentication counter. + * + * See also eap_type_gsmsim_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |AT_COUNTER | Length = 1 | Counter | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_counter_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + u16_t counter); + + /** + * This function adds simple attribute payload to GSMSIM message. + * @param gsmsim is pointer to EAP header including GSMSIM fields. + * @param gsmsim_buffer_length is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also gsmsim_header_c and eap_header_base_c. + * @param gsmsim_data_offset is the offset of inserted payloads in GSMSIM EAP packet. + * It is the value of GSMSIM sub-type data. + * @param gsmsim_data_free is the remaining free GSMSIM data buffer size. + * @param packet_buffer_free is the remaining free packet buffer size. + * @param packet_buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param data_payload_type is the type of simple payload. + * + * See also eap_type_gsmsim_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |AT_XXX | Length = 1 | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_simple_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const gsmsim_payload_AT_type_e data_payload_type); + + /** + * This function adds Notification attribute payload to GSMSIM message. + * @param gsmsim is pointer to EAP header including GSMSIM fields. + * @param gsmsim_buffer_length is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also gsmsim_header_c and eap_header_base_c. + * @param gsmsim_data_offset is the offset of inserted payloads in GSMSIM EAP packet. + * It is the value of GSMSIM sub-type data. + * @param gsmsim_data_free is the remaining free GSMSIM data buffer size. + * @param packet_buffer_free is the remaining free packet buffer size. + * @param packet_buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param triplet_status is the notification. + * + * See also eap_type_gsmsim_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |AT_NOTIFICATION| Length = 1 | Notification Code | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_notification_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_gsmsim_notification_codes_e notification_code); + + /** + * This function adds AT_CLIENT_ERROR_CODE attribute payload to GSMSIM message. + * @param gsmsim is pointer to EAP header including GSMSIM fields. + * @param gsmsim_buffer_length is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also gsmsim_header_c and eap_header_base_c. + * @param gsmsim_data_offset is the offset of inserted payloads in GSMSIM EAP packet. + * It is the value of GSMSIM sub-type data. + * @param gsmsim_data_free is the remaining free GSMSIM data buffer size. + * @param packet_buffer_free is the remaining free packet buffer size. + * @param packet_buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param client_error_code is the error code to be sent. + * + * See also eap_type_gsmsim_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |AT_CLIENT_ERR..| Length = 1 | Client Error Code | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_client_error_payload( + gsmsim_header_c * const gsmsim, + const u32_t gsmsim_buffer_length, + const u32_t eap_header_size, + u32_t * const gsmsim_data_offset, + u32_t * const gsmsim_data_free, + u32_t * const packet_buffer_free, + u32_t * const packet_buffer_offset, + const eap_gsmsim_client_error_code_e client_error_code); + + + /** + * This function adds message authentication code (MAC) attribute payload to GSMSIM message. + * This MAC is written later in the create_message_authentication_code() function. + * MAC includes the whole EAP message. + * @param gsmsim is pointer to EAP header including GSMSIM fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also gsmsim_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in GSMSIM EAP packet. + * It is the value of GSMSIM sub-type data. + * @param data_free is the remaining free GSMSIM data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param MAC_data is the start of the message authentication code (MAC) to be written. + * @param MAC_data_length is the length of the message authentication code (MAC) to be written. + * + * See also eap_type_gsmsim_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT_MAC | Length | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MAC | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_mac_payload( + gsmsim_header_c * const gsmsim, + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_free, + u32_t * const buffer_offset, + u8_t ** const MAC_data, + u32_t * const MAC_data_length); + + /** + * This function adds message authentication code (MAC) attribute payload to GSMSIM message. + * This MAC is written later in the create_message_authentication_code() function. + * @param gsmsim is pointer to EAP header including GSMSIM fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also gsmsim_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in GSMSIM EAP packet. + * It is the value of GSMSIM sub-type data. + * @param data_free is the remaining free GSMSIM data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param plaintext_length is the length of the plain text. Padding length is calculated from this. + * + * See also eap_type_gsmsim_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT_PADDING | Length | Padding set to zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Zero or more padding octets. Padding octet is 0x00. | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_padding_payload( + gsmsim_header_c * const gsmsim_packet, + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_free, + u32_t * const buffer_offset, + const u32_t plaintext_length); + + /** + * This function verifies the message authentication code (MAC) is correct. + * @see add_mac_payload(). + */ + EAP_FUNC_IMPORT eap_status_e check_message_authentication_code( + const eap_variable_data_c * const authentication_key, + gsmsim_payloads_c * const p_gsmsim_payloads, ///< This is pointer to all payloads of the received EAP packet. + const gsmsim_header_c * const gsmsim_packet, + const u32_t gsmsim_packet_length); + + /** + * This function handles the received GSMSIM EAP packet. + * + * First is checked the valid massage is received in valid state. + * See also eap_type_gsmsim_state_c::check_valid_state(). + * + * Second is parsed the payloads and checked syntax of the received GSMSIM EAP packet. + * See also parse_gsmsim_packet(). + * + * Third is analysed the GSMSIM EAP packet. This includes the payload and values of each payload. + * See also analyse_gsmsim_packet(). + */ + EAP_FUNC_IMPORT eap_status_e handle_gsmsim_packet( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + gsmsim_header_c * const gsmsim, ///< This is pointer to EAP header including GSMSIM fields. + const u32_t gsmsim_length, ///< This is length of received GSMSIM EAP packet. + gsmsim_payloads_c * const p_gsmsim_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + /** + * This function analyses the received GSMSIM EAP packet. + * Each sub-type is handled in separate function. + * @see Client messages are handled in handle_start_request_message() and handle_challenge_request_message(). + * @see Server messages are handled in handle_start_response_message() and handle_challenge_response_message(). + */ + EAP_FUNC_IMPORT eap_status_e analyse_gsmsim_packet( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + gsmsim_header_c * const received_gsmsim, ///< This is pointer to EAP header including GSMSIM fields. + const u32_t gsmsim_packet_length, ///< This is length of received GSMSIM EAP packet. + gsmsim_payloads_c * const p_gsmsim_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + /** + * This function parses the payloads starting from specified payload (p_payload). + * Function parses all payloads from the buffer. + * Payloads are stored to p_gsmsim_payloads. + * @return If the length of the buffer and sum of the length of all payloads does not match + * function returns eap_status_header_corrupted. + * Also error is returned when illegal payload attribute is recognised. + */ + EAP_FUNC_IMPORT eap_status_e parse_gsmsim_payload( + const gsmsim_payload_AT_header_c * const p_payload, ///< This is the start of the buffer and the first parsed payload. + u32_t * const buffer_length, ///< This is the length of the buffer. This must match with the length of all payloads. + gsmsim_payloads_c * const p_gsmsim_payloads, ///< This is pointer to all payloads of the received EAP packet. + const gsmsim_subtype_e subtype + ); + + /** + * This function checks the version list payload of the GSMSIM EAP packet is correct. + */ + EAP_FUNC_IMPORT eap_status_e check_version_list( + const gsmsim_payload_AT_header_c * const payload, + const u16_t version_list_length, + u8_t * version_list, + bool * const includes_other_version_than_1); + + /** + * This function parses all payloads of the whole GSMSIM EAP packet. + * Payloads are stored to p_gsmsim_payloads. + * @see parse_gsmsim_payload(). + */ + EAP_FUNC_IMPORT eap_status_e parse_gsmsim_packet( + gsmsim_header_c * const gsmsim, ///< This is pointer to EAP header including GSMSIM fields. + const u32_t gsmsim_packet_length, ///< This is length of received GSMSIM EAP packet. + gsmsim_payloads_c * const p_gsmsim_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + /** + * This function parses each payload attributes. + * @return If payload attribute is illegal function returns eap_status_header_corrupted. + * If payload attribute is unknown function returns eap_status_unsupported_gsmsim_payload. + */ + EAP_FUNC_IMPORT eap_status_e parse_generic_payload( + const gsmsim_payload_AT_type_e current_payload, ///< This is the type of current payload attribute. + const gsmsim_payload_AT_header_c * const payload, ///< This is the current parsed payload. + gsmsim_payloads_c * const p_gsmsim_payloads, ///< This is pointer to all payloads of the received EAP packet. + const gsmsim_subtype_e subtype); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function sends the EAP-Request/SIM/Re-authentication message. + */ + EAP_FUNC_IMPORT eap_status_e send_reauthentication_request_message( + const eap_variable_data_c * const username, + const bool pseudonym_decode_failed, + const u8_t eap_identifier); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function sends the EAP-Request/SIM/Start message. + */ + EAP_FUNC_IMPORT eap_status_e send_start_request_message( + const bool pseudonym_decode_failed, ///< This identifies whether the pseudonym decode was failed (true). We must send a IMSI request. + const u8_t eap_identifier ///< This is the EAP-Identifier used with this message. + ); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + /** + * This function sends the EAP-Response/SIM/Start message. + */ + EAP_FUNC_IMPORT eap_status_e send_start_response_message( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. NOTE received. + const u8_t received_eap_identifier, ///< This is the EAP-identifier of the received EAP-request message. + const eap_gsmsim_version version, ///< This is the selected GSMSIM version. + const gsmsim_payload_AT_type_e include_identity_to_start_response, ///< This is the queried identity type. + const eap_variable_data_c * const automatic_realm, ///< This could be zero pointer if this is not used. + const u32_t length_of_mnc + ); + + /** + * This function sends the EAP-Response/SIM/Notification message. + */ + EAP_FUNC_IMPORT eap_status_e send_gsmsim_notification_response( + const eap_gsmsim_notification_codes_e notification_code, ///< This is the status of the failed triplet query. + const bool add_at_counter_attribute + ); + + /** + * This function sends the EAP-Response/SIM/Client-Error message. + */ + EAP_FUNC_IMPORT eap_status_e send_gsmsim_client_error_response(); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function sends the EAP-Request/SIM/Challenge message. + */ + EAP_FUNC_IMPORT eap_status_e send_challenge_request_message( + const u8_t eap_identifier ///< This is the EAP-Identifier used with this message. + ); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + /** + * This function sends the EAP-Response/SIM/Challenge message. + */ + EAP_FUNC_IMPORT eap_status_e send_challenge_response_message( + eap_variable_data_c * const K_aut); + + EAP_FUNC_IMPORT eap_status_e send_reauthentication_response_message( + const eap_variable_data_c * const orig_XKEY, + const eap_variable_data_c * const orig_K_aut, + const eap_variable_data_c * const orig_K_encr, + const eap_variable_data_c * const reauth_username, + const eap_variable_data_c * const reauth_nonce_s, + const u16_t reauth_counter, + const u8_t eap_identifier, + const bool include_at_counter_too_small); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function sends the EAP-Request/SIM/Notification message. + * Message includes the localizable notification string. + */ + EAP_FUNC_IMPORT eap_status_e send_gsmsim_notification_request( + const eap_gsmsim_notification_codes_e notification_code, ///< This is the status of the failed triplet query. + const bool add_at_counter_attribute + ); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + /** + * This function encrypts the payload. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_DATA_payload( + u8_t * const EAP_data, ///< This is pointer to the begin of the encrypted payload. + const u32_t cbc_aes_data_length, ///< This is the length of the encrypted payload. This must be aligned to AES block length. + const eap_variable_data_c * const IV, + const eap_variable_data_c * const encryption_key + ); + + + /** + * This function decrypts the payload. + * p_gsmsim_payloads->get_ENCR_DATA() points to the decrypted payload. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_DATA_payload( + gsmsim_payloads_c * const p_gsmsim_payloads, ///< This is pointer to all payloads of the received EAP packet. + const eap_variable_data_c * const encryption_key + ); + + /** + * This function handles the received DATA payload attribute. + * The received encrypte payload have been decrypted before thiscall. + * p_gsmsim_payloads->get_ENCR_DATA() includes decrypted DATA payload. + */ + EAP_FUNC_IMPORT eap_status_e handle_DATA_payload( + const gsmsim_subtype_e subtype, + gsmsim_payloads_c * const p_gsmsim_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + //-------------------------------------------------- + + /** + * This function generate a new NONCE of nonce_size octets length. + */ + EAP_FUNC_IMPORT eap_status_e generate_nonce( + const u32_t nonce_size, + eap_variable_data_c * const nonce); + + /** + * This function returns the domain name. + */ + EAP_FUNC_IMPORT eap_variable_data_c * get_nai_realm(); + + /** + * This is the situation before the update_buffer_indexes() call. + * @code + * + * |<---------buffer_offset-------->|<----------buffer_free----------------->| + * | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * This is the situation after the update_buffer_indexes() call. + * @code + * + * |<-----------------buffer_offset--------------------->|<---buffer_free--->| + * | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * Note maximum_buffer_size could be larger than (m_gsmsim_header_offset + m_MTU + m_trailer_length). + */ + EAP_FUNC_IMPORT void update_buffer_indexes( + const u32_t maximum_buffer_size, + const u32_t payload_size, + u32_t * const buffer_offset, + u32_t * const buffer_free); + + /** + * This is the situation before the update_payload_indexes() call. + * @code + * + * |<---------buffer_offset-------->|<----------buffer_free----------------->| + * | | | + * | |<-data_offset->|<--------data_free--------------------->| + * | | | | + * | | |<---payload_size--->| | + * | | | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * This is the situation after the update_payload_indexes() call. + * @code + * + * |<-----------------buffer_offset--------------------->|<---buffer_free--->| + * | | | + * | |<----------data_offset------------->|<----data_free---->| + * | | | | + * | | |<---payload_size--->| | + * | | | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * Note maximum_buffer_size could be larger than (m_gsmsim_header_offset + m_MTU + m_trailer_length). + */ + EAP_FUNC_IMPORT void update_payload_indexes( + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + const u32_t payload_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_offset, + u32_t * const buffer_free); + + /** + * This function queries the IMSI or saved pseudonym. IMSI is queried always. The optional + * pseudonym is returned if it has been received and it has been stored to GSMSIM AM. + * This function could be synchronous or asynchronous. Parameter must_be_synchronous could be + * used if only synchronous call is accepted. + * + * @return Successful syncronous call returns eap_status_ok. + * The process_SIM_IMSI() function must be called immediately. + * + * @return Successful asynchronous call returns eap_status_ok. + * This means call was indeed synchronous. + * The process_SIM_IMSI() function must be called immediately. + * + * @return Pending asynchronous call returns eap_status_pending_request. + * AM will complete this call later by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + * + * @return Immediately comleted asynchronous call returns eap_status_completed_request. + * AM already called the complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query(). + * + * @return Other return values are errors. + */ + EAP_FUNC_IMPORT eap_status_e query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + eap_variable_data_c * const IMSI, ///< Pointer to IMSI. Buffer for IMSI is allocated during the call. + eap_variable_data_c * const pseudonym_identity, ///< Pointer to pseudonym. Buffer for pseudonym is allocated during the call. + eap_variable_data_c * const reauthentication_identity, ///< Pointer to reauthentication_identity. Buffer for reauthentication_identity is allocated during the call. + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const length_of_mnc, + const bool must_be_synchronous, ///< True value indicates only synchronous call is accepted. + const gsmsim_payload_AT_type_e required_identity, ///< This parameter indicated the type of identity required. + const eap_type_gsmsim_complete_e required_completion, ///< This parameter tells the required completion after this call is completed, if this is asyncronous. Use this value with abs_eap_am_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + const u8_t received_eap_identifier ///< This is the EAP-identifier of the received EAP-request message. Use this value with abs_eap_am_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + ); + + /** + * This function queries KC and SRES. Each of them could include multiple concatenated items. + * This function could be synchronous or asynchronous. + * + * @return Successful call returns eap_status_ok. + * This means call was indeed synchronous. + * The process_SIM_kc_sres() function must be called immediately. + * + * @return Pending asynchronous call returns eap_status_pending_request. + * AM will complete this call later by complete_SIM_kc_sres() call. + * + * @return Immediately comleted asynchronous call returns eap_status_completed_request. + * AM already called the complete_SIM_kc_sres(). + * + * @return Other return values are errors. + */ + EAP_FUNC_IMPORT eap_status_e query_SIM_kc_sres( + const eap_variable_data_c * const n_rands, ///< This includes concatenated n RAND as input. + eap_variable_data_c * const n_kc, ///< This includes concatenated n KC as output. + eap_variable_data_c * const n_sres ///< This includes concatenated n SRES as output. + ); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function queries the triplets. The triplets are stored to handler->get_triplets(). + * This function could be synchronous or asynchronous. + * + * @return Successful call returns eap_status_ok. + * This means call was indeed synchronous. + * The send_challenge_request_message() function must be called immediately. + * + * @return Pending asynchronous call returns eap_status_pending_request. + * AM will complete this call later by complete_SIM_triplets() call. + * + * @return Immediately comleted asynchronous call returns eap_status_completed_request. + * AM already called the complete_SIM_triplets(). + * + * @return Other return values are errors. + */ + EAP_FUNC_IMPORT eap_status_e query_SIM_triplets( + eap_type_gsmsim_identity_type * const identity_type + ); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + /** + * This function creates local copy of MAC_RAND and checks the received one match with local MAC_RAND. + * After succesfull MAC_RAND check function parses the GSMSIM payloads from saved GSMSIM EAP packet. + * This is because of the process_SIM_kc_sres() function could be called asynchronously and + * the received GSMSIM EAP packet is stored to handler->get_saved_EAP_packet(). + * Also encrypted payload (l_gsmsim_payloads.get_ENCR_DATA()) is handled here. + * This is the first place where we have the K_encr (handler->get_K_encr()) available. + * The decrpted DATA payload is handled immediately in handle_DATA_payload() function. + * Then function calculates MAC_SRES and sends EAP-Response/SIM/Challenge. + */ + EAP_FUNC_IMPORT eap_status_e process_SIM_kc_sres( + const eap_variable_data_c * const n_rand, ///< This includes concatenated n RAND. + const eap_variable_data_c * const n_kc, ///< This includes concatenated n KC. + const eap_variable_data_c * const n_sres ///< This includes concatenated n SRES. + ); + + /** + * This function selects whether to use pseudonym or IMSI. + * Function creates NAI and EAP-Response/Identity message. + * Message is sent immediately. + */ + EAP_FUNC_IMPORT eap_status_e process_SIM_IMSI( + const eap_variable_data_c * const IMSI, ///< This is the IMSI. + const eap_variable_data_c * const pseudonym ///< This is the pseudonym. + ); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function adds RAND attribute payload to GSMSIM message. + * Payload includes one or more RANDs. + * @param gsmsim is pointer to EAP header including GSMSIM fields. + * @param maximum_buffer_size is the maximum length of sent packet. + * @param eap_header_size is length of EAP header. + * See also gsmsim_header_c and eap_header_base_c. + * @param data_offset is the offset of inserted payloads in GSMSIM EAP packet. + * It is the value of GSMSIM sub-type data. + * @param data_free is the remaining free GSMSIM data buffer size. + * @param buffer_free is the remaining free packet buffer size. + * @param buffer_offset is the offset from the begin of the packet buffer + * to the end of the last data payload. + * @param triplets includes all triplets used in this authentication session. + * See also eap_type_sim_triplet_array_c. + * + * See also eap_type_gsmsim_c::update_payload_indexes(). + * + * Format of the payload is as follows: + * @code + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AT_RAND | Length | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | n*RAND ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e add_n_rand_payload( + gsmsim_header_c * const gsmsim, + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_free, + u32_t * const buffer_offset, + eap_type_sim_triplet_array_c * const triplets); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + /** + * This function calculates the MAC_SRES. + */ + EAP_FUNC_IMPORT eap_status_e calculate_MAC_SRES( + eap_variable_data_c * const MAC_SRES, ///< This is the calculated MAC_SRES. + const eap_variable_data_c * const n_kc, ///< This includes concatenated n KC. + const eap_variable_data_c * const n_sres ///< This includes concatenated n SRES. + ); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function reads the identity payload. Identity is stored to handler->get_identity(). + */ + EAP_FUNC_IMPORT eap_status_e parse_identity( + const u8_t * const identity, ///< This is pointer to received EAP-Identity buffer. + const u32_t identity_length ///< This is length of received EAP-Identity buffer. + //const u32_t eap_packet_length ///< This is length of received EAP-Identity buffer. + ); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + EAP_FUNC_IMPORT eap_status_e handle_eap_identity_query( + const eap_am_network_id_c * const send_network_id, + eap_variable_data_c * const identity, + const u8_t eap_identifier, + const eap_variable_data_c * const IMSI, + const eap_variable_data_c * const pseudonym, + const eap_variable_data_c * const reauthentication_identity, + const eap_variable_data_c * const automatic_realm, ///< This could be zero pointer if this is not used. + const u32_t length_of_mnc, + const bool must_be_synchronous + ); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function handles the received EAP-Response/Identity message. + * First function parses the identity. + * Function queries the AM (query_imsi_from_username()) whether the pseudonym + * is known or should it query peer the IMSI. + * Currently the query_imsi_from_username() is synchronous call. + * The send_start_request_message() function will send the EAP-Request/SIM/Start message. + */ + EAP_FUNC_IMPORT eap_status_e handle_identity_response_message( + eap_header_rd_c * const eap_header, ///< This is the received EAP-Identity packet, pointer points to the header. + const u32_t gsmsim_packet_length ///< This is length of received GSMSIM EAP packet. + ); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + /** + * This function handles the received EAP-Request/SIM/Start message. + * Function checks the valid payloads and calls send_start_response_message() that sends EAP-Response/SIM/Start message. + */ + EAP_FUNC_IMPORT eap_status_e handle_start_request_message( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + gsmsim_header_c * const received_gsmsim, ///< This is pointer to EAP header including GSMSIM fields. + const u32_t gsmsim_packet_length, ///< This is length of received GSMSIM EAP packet. + gsmsim_payloads_c * const p_gsmsim_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + EAP_FUNC_IMPORT eap_status_e handle_gsmsim_notification_request_message_reauthentication( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads); + + EAP_FUNC_IMPORT eap_status_e handle_gsmsim_notification_request_message_full_authentication( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads); + + /** + * This function handles the received EAP-Request/SIM/Notification message. + * Function checks the valid payloads and calls send_notification_response_message() that sends EAP-Response/SIM/Notification message. + */ + EAP_FUNC_IMPORT eap_status_e handle_gsmsim_notification_request_message( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads); + + /** + * This function handles the received EAP-Request/SIM/Challenge message. + * Function checks the valid payloads. The whole EAP-Request/SIM/Challenge message is + * saved to handler->get_saved_EAP_packet() if there is encrypted payload. + * This is because the MAC could be checked and payload dercypted later + * after n*Kc and n*SRES is get from SIM. + * Function calls query_SIM_kc_sres(). The query_SIM_kc_sres() function + * is completed using complete_SIM_kc_sres() function. The complete_SIM_kc_sres() + * function will call process_SIM_kc_sres(). + */ + EAP_FUNC_IMPORT eap_status_e handle_challenge_request_message( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + gsmsim_header_c * const received_gsmsim, ///< This is pointer to EAP header including GSMSIM fields. + const u32_t gsmsim_packet_length, ///< This is length of received GSMSIM EAP packet. + gsmsim_payloads_c * const p_gsmsim_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + /** + * This function handles the received EAP-Request/SIM/Re-authentication message. + * Function checks the valid payloads. The whole EAP-Request/SIM/Challenge message is + * saved to handler->get_saved_EAP_packet() if there is encrypted payload. + * This is because the MAC could be checked and payload dercypted later + * after n*Kc and n*SRES is get from SIM. + * Function calls query_SIM_kc_sres(). The query_SIM_kc_sres() function + * is completed using complete_SIM_kc_sres() function. The complete_SIM_kc_sres() + * function will call process_SIM_kc_sres(). + */ + EAP_FUNC_IMPORT eap_status_e handle_reauthentication_request_message( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + EAP_FUNC_IMPORT eap_status_e check_challenge_response_message( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function handles the received EAP-Response/SIM/Start message. + * Function checks the valid payloads. If IMSI is included it is copied to handler->get_IMSI(). + * Also the included NONCE_MT is copied to handler->get_NONCE_MT(). + * Function calls the query_SIM_triplets() of AM to get fresh triplets. + * The query_SIM_triplets() function is completed by AM using complete_SIM_triplets() function. + */ + EAP_FUNC_IMPORT eap_status_e handle_start_response_message( + gsmsim_header_c * const received_gsmsim, ///< This is pointer to EAP header including GSMSIM fields. + const u32_t gsmsim_packet_length, ///< This is length of received GSMSIM EAP packet. + gsmsim_payloads_c * const p_gsmsim_payloads ///< This is pointer to all payloads of the received EAP packet. + ); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + EAP_FUNC_IMPORT eap_status_e handle_notification_response_message_reauthentication( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + EAP_FUNC_IMPORT eap_status_e handle_notification_response_message_full_authentication( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function handles the received EAP-Response/SIM/Notification message. + * Function checks the valid payloads. + */ + EAP_FUNC_IMPORT eap_status_e handle_notification_response_message( + const eap_am_network_id_c * const receive_network_id, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function handles the received EAP-Response/SIM/Challenge message. + * Function checks the valid payloads. The analyse_MAC_SRES_payload() function is + * called to check MAC_SRES. If it returns eap_status_success the authentication was succesfull + * and this function calls the send_eap_success() to send EAP-Success message. + */ + EAP_FUNC_IMPORT eap_status_e handle_challenge_response_message( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + gsmsim_header_c * const received_gsmsim, ///< This is pointer to EAP header including GSMSIM fields. + const u32_t gsmsim_packet_length, ///< This is length of received GSMSIM EAP packet. + gsmsim_payloads_c * const p_gsmsim_payloads ///< This is pointer to all payloads of the received EAP packet. + ); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + EAP_FUNC_IMPORT eap_status_e handle_reauthentication_response_message( + const eap_am_network_id_c * const /* receive_network_id */, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + EAP_FUNC_IMPORT eap_status_e handle_client_error_response_message( + const eap_am_network_id_c * const /* receive_network_id */, + gsmsim_header_c * const received_gsmsim, + const u32_t gsmsim_packet_length, + gsmsim_payloads_c * const p_gsmsim_payloads); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + /** + * This function sends and traces all messages. + */ + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** + * This function chechs NAI. + */ + EAP_FUNC_IMPORT eap_status_e check_NAI( + const u8_t * const identity, + const u32_t identity_length, + const u8_t * const at_character); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TRACE) + + /** + * This function traces the EAP packet. + */ + EAP_FUNC_IMPORT void packet_trace( + eap_const_string prefix, + const eap_am_network_id_c * const receive_network_id, + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length); + + #define EAP_GSMSIM_PACKET_TRACE(prefix, receive_network_id, received_eap, eap_packet_length) \ + packet_trace((prefix), (receive_network_id), (received_eap), (eap_packet_length)) + +#else + + #define EAP_GSMSIM_PACKET_TRACE(prefix, receive_network_id, received_eap, eap_packet_length) + +#endif //#if !defined(USE_EAP_TRACE) + + + /** + * This function finishes the successfull authentication. + * Generated keys are offered to lower layer. + * Connection handle is initialised. + */ + EAP_FUNC_IMPORT eap_status_e finish_successful_authentication( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function sends a notification of possible failed authentication + * to lower layer. + */ + EAP_FUNC_IMPORT eap_status_e send_final_notification(); + + EAP_FUNC_IMPORT eap_status_e new_handler( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true); + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + EAP_FUNC_IMPORT bool randomly_refuse_eap_identity(); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + EAP_FUNC_IMPORT eap_status_e check_rands( + const eap_variable_data_c * const n_rands + ); + + /** + * This function processes the GSMSIM packets. + */ + EAP_FUNC_IMPORT eap_status_e gsmsim_packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + gsmsim_header_c * const received_gsmsim, ///< This is pointer to EAP header including GSMSIM fields. + const u32_t gsmsim_packet_length, ///< This is length of received GSMSIM EAP packet. + const bool is_client_when_true ///< Indicates whether this is client (true) or server (false). + ); + + EAP_FUNC_IMPORT eap_status_e cancel_error_message_delay_timer(); + + EAP_FUNC_IMPORT eap_status_e set_error_message_delay_timer(); + + EAP_FUNC_IMPORT eap_status_e handle_error_packet(); + + /** + * This function initializes the error message. + */ + EAP_FUNC_IMPORT eap_status_e initialize_error_message( + const eap_status_e error_status + ); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + EAP_FUNC_IMPORT eap_status_e handle_start_response_message_completion( + const u8_t next_eap_identifier, + const eap_status_e identity_status, + const eap_type_gsmsim_identity_type identity_type, + const bool identity_payload_was_included); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + EAP_FUNC_IMPORT eap_status_e initialize_notification_message(); + + EAP_FUNC_IMPORT eap_status_e cancel_notification_message_delay_timer(); + + EAP_FUNC_IMPORT eap_status_e set_notification_message_delay_timer(); + + EAP_FUNC_IMPORT eap_status_e handle_notification_packet(); + + const bool get_gsmsim_notification_code_F_bit(const eap_gsmsim_notification_codes_e notification_code) + { + return ((notification_code & gsmsim_notification_code_bit_f) != 0); + } + + const bool get_gsmsim_notification_code_P_bit(const eap_gsmsim_notification_codes_e notification_code) + { + return ((notification_code & gsmsim_notification_code_bit_p) != 0); + } + + EAP_FUNC_IMPORT bool random_selection(); + + u32_t get_mnc_length(const u32_t mcc); + + eap_status_e create_uma_realm( + eap_variable_data_c * const automatic_realm, + const eap_variable_data_c * const IMSI, + const u32_t length_of_mnc); + + void set_start_response_includes_identity(gsmsim_payload_AT_type_e type); + + void set_identity_type(eap_type_gsmsim_identity_type type); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor cancels all timers and deletes member attributes. + */ + EAP_FUNC_IMPORT virtual ~eap_type_gsmsim_c(); + + /** + * Constructor initializes all member attributes. + */ + EAP_FUNC_IMPORT eap_type_gsmsim_c( + abs_eap_am_tools_c * const tools, ///< This is pointer to the tools AM of current platform. + abs_eap_base_type_c * const partner, ///< This is back pointer to object which created this object. + eap_am_type_gsmsim_c * const am_type_gsmsim, ///< This is pointer to adaptation module of GSMSIM EAP type. + const bool free_am_type_gsmsim, ///< True value means m_am_type_gsmsim is allocated within eap_type_gsmsim_c and m_am_type_gsmsim must be freed in destructor. + const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false). + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT static eap_const_string get_identity_string(const eap_type_gsmsim_identity_type identity_type); + + /** + * This function returns string of the state. This is for trace purposes. + * NOTE this is static member function. + */ + EAP_FUNC_IMPORT static eap_const_string get_state_string(eap_type_gsmsim_state_variable_e state); + + /** + * This function tells if the object is a client or a server.. + */ + EAP_FUNC_IMPORT bool get_is_client(); + + // This is commented in abs_eap_am_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query(). + EAP_FUNC_IMPORT eap_status_e complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query( + const eap_variable_data_c * const IMSI, ///< This is the IMSI. + const eap_variable_data_c * const pseudonym, ///< This is the pseudonym. + const eap_variable_data_c * const reauthentication_identity, ///< This is the re-authentication identity. + const eap_variable_data_c * const automatic_realm, ///< This could be zero pointer if this is not used. + const u32_t length_of_mnc, + const eap_type_gsmsim_complete_e required_completion, ///< This parameter tells the required completion + const u8_t received_eap_identifier, ///< This parameter is the EAP-identifier of EAP-request + const eap_status_e completion_status + ); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + // This is commented in abs_eap_am_type_gsmsim_c::complete_SIM_triplets(). + EAP_FUNC_IMPORT eap_status_e complete_SIM_triplets( + eap_type_sim_triplet_array_c * const triplets, ///< triplets includes all triplets used in this authentication session. + const eap_variable_data_c * const IMSI, ///< IMSI may be queried during query_SIM_triplets() function call. It must be copied to state. + const eap_gsmsim_triplet_status_e triplet_status, ///< This is the status of the failed triplet query. + const eap_type_gsmsim_identity_type type, ///< This is type of the identity. + const eap_status_e completion_status + ); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + // This is commented in abs_eap_am_type_gsmsim_c::complete_SIM_kc_sres(). + EAP_FUNC_IMPORT eap_status_e complete_SIM_kc_sres( + const eap_variable_data_c * const n_rand, ///< This includes concatenated n RAND. + const eap_variable_data_c * const n_kc, ///< This includes concatenated n KC. + const eap_variable_data_c * const n_sres, ///< This includes concatenated n SRES. + const eap_status_e completion_status + ); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + /** Client calls this function. + * This function IMSI and username to GSMSIM EAP type. + */ + EAP_FUNC_IMPORT eap_status_e handle_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + const eap_variable_data_c * const imsi, ///< The result is stored to imsi parameter. + const eap_type_gsmsim_identity_type identity_type); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + // This is commented in abs_eap_am_type_gsmsim_c::complete_imsi_from_username(). + EAP_FUNC_IMPORT eap_status_e complete_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + const eap_variable_data_c * const imsi, ///< The result is stored to imsi parameter. + const eap_type_gsmsim_identity_type type, + const eap_status_e completion_status, + const eap_type_gsmsim_complete_e completion_action); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + /** + * The partner class calls this function when EAP/GSMSIM packet is received. + * see also eap_base_type_c::packet_process(). + */ + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + /** + * This function obtains header offset, MTU and trailer length. + * See also abs_eap_base_type_c::get_header_offset(). + */ + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length + ); + + /** + * This function creates a message authentication code (MAC) + */ + EAP_FUNC_IMPORT eap_status_e create_message_authentication_code( + eap_type_gsmsim_MAC_attributes_c *MAC_attributes, ///< This includes required parameters. + const gsmsim_subtype_e subtype, + const eap_code_value_e code, + const eap_variable_data_c * const authentication_key + ); + + /** + * This function adds addiditional data to MAC calculation. + */ + EAP_FUNC_IMPORT eap_status_e extra_message_authentication_code_bytes( + const gsmsim_subtype_e subtype, + const eap_code_value_e code, + crypto_hmac_c *hmac_sha1); + + // This is commented in abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data + ); + + // This is commented in abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data + ); + + // This is commented in eap_base_type_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + + // This is commented in eap_base_type_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + // This is commented in eap_base_type_c::configure(). + /** + * EAP-type GSMSIM reads configuration. + */ + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is commented in eap_base_type_c::shutdown(). + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + EAP_FUNC_IMPORT eap_status_e shutdown(); + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ); + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ); + + // See abs_eap_base_type_c::state_notification(). + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state + ); + + // This is commented in eap_base_type_c::query_eap_identity(). + EAP_FUNC_IMPORT eap_status_e query_eap_identity( + const bool must_be_synchronous, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier); + + // This is commented in eap_base_type_c::query_eap_identity(). + EAP_FUNC_IMPORT eap_status_e set_initial_eap_identifier( + const eap_am_network_id_c * const receive_network_id, + const u8_t initial_identifier); + + // This is commented in eap_base_type_c::eap_acknowledge(). + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function must reset the state of object to same as + * state was after the configure() function call. + * If object reset succeeds this function must return eap_status_ok. + * If object reset fails this function must return corresponding error status. + * @return This function returns the status of reset operation. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + // + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + // + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + //-------------------------------------------------- +}; // class eap_type_gsmsim_c + +#endif //#if !defined(_GSMSIM_CORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,235 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_GSMSIM_HEADER_H_) +#define _GSMSIM_HEADER_H_ + +#include "eap_tools.h" +#include "eap_header.h" +#include "eap_type_gsmsim_types.h" + +/** @file */ + +const u32_t TRACE_FLAGS_GSMSIM_ERROR = eap_am_tools_c::eap_trace_mask_error; + + +//---------------------------------------------------------------------------- + + +/// This class defines the attribute payload header of GSMSIM EAP-type. +/** + * Here is a figure of attribute payload header of GSMSIM EAP-type. + * Attribute payload data is (m_length*4)-sizeof(gsmsim_payload_AT_header_c) + * data octets that follows gsmsim_payload_AT_header_c. + * @code + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Length | Value ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Attribute payload data ... + * +-+-+-+-+-+-+-+-+-+-+- + * @endcode + * + */ +class EAP_EXPORT gsmsim_payload_AT_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + enum offsets + { + m_type_offset = 0ul, + m_length_offset = m_type_offset+sizeof(u8_t), + m_reserved_offset = m_length_offset+sizeof(u8_t), + m_data_offset = m_reserved_offset+sizeof(u16_t), + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~gsmsim_payload_AT_header_c(); + + // + EAP_FUNC_IMPORT gsmsim_payload_AT_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT gsmsim_payload_AT_type_e get_current_payload() const; + + EAP_FUNC_IMPORT u16_t get_payload_length() const; + + EAP_FUNC_IMPORT u16_t get_reserved() const; + + EAP_FUNC_IMPORT u32_t get_data_length() const; + + EAP_FUNC_IMPORT static u16_t get_header_length(); + + EAP_FUNC_IMPORT static u16_t get_max_payload_data_length(); + + EAP_FUNC_IMPORT u8_t * get_data(const u32_t contignuous_bytes) const; + + EAP_FUNC_IMPORT u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + EAP_FUNC_IMPORT u8_t * get_next_header() const; + + // Mostly this is zero. + // With some attributes this is used for special purposes. + EAP_FUNC_IMPORT void set_reserved(const u16_t reserved); + + EAP_FUNC_IMPORT void set_current_payload(const gsmsim_payload_AT_type_e p_current_payload); + + EAP_FUNC_IMPORT void set_data_length(const u16_t p_data_length); + + EAP_FUNC_IMPORT void reset_header(const u16_t data_length); + + EAP_FUNC_IMPORT static eap_const_string get_payload_AT_string(const gsmsim_payload_AT_type_e payload_type); + + EAP_FUNC_IMPORT eap_const_string get_payload_AT_string() const; + + EAP_FUNC_IMPORT eap_status_e check_header() const; + + // + //-------------------------------------------------- +}; // class gsmsim_payload_AT_header_c + + + +//---------------------------------------------------------------------------- + + +/// This class defines header of GSMSIM EAP-type. +/** + * Here is a figure of header of GSMSIM EAP-type. + * Subtype-Data is m_length-sizeof(gsmsim_header_c) data octets that follows gsmsim_header_c. + * @code + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Code | Identifier | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type=18 | Subtype | Reserved = 0 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Subtype-Data... + * +-+-+-+-+-+-+-+-+-+-+- + * @endcode + * + */ +class gsmsim_header_c +: public eap_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + enum delta_offsets + { + m_subtype_delta_offset = 0ul, // This is offset from the end of the type field. NOTE type field could be extented 8 bytes in length. + m_reserved_delta_offset = m_subtype_delta_offset+sizeof(u8_t), + m_data_delta_offset = m_reserved_delta_offset+sizeof(u16_t), + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~gsmsim_header_c(); + + // + EAP_FUNC_IMPORT gsmsim_header_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_buffer, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT gsmsim_subtype_e get_subtype() const; + + EAP_FUNC_IMPORT u16_t get_data_length() const; + + /// This returns the length of EAP-header, EAP-type, subtype and reserved fields. + EAP_FUNC_IMPORT u32_t get_header_length() const; + + EAP_FUNC_IMPORT u32_t get_sub_type_offset() const; + + EAP_FUNC_IMPORT u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + EAP_FUNC_IMPORT u8_t * get_data(const u32_t contignuous_bytes) const; + + EAP_FUNC_IMPORT u16_t get_reserved() const; + + EAP_FUNC_IMPORT eap_status_e check_header() const; + + EAP_FUNC_IMPORT eap_const_string get_subtype_string() const; + + EAP_FUNC_IMPORT eap_const_string get_code_string() const; + + EAP_FUNC_IMPORT eap_const_string get_eap_type_string() const; + + EAP_FUNC_IMPORT void set_reserved(const u16_t reserved); + + EAP_FUNC_IMPORT void set_subtype(const gsmsim_subtype_e p_subtype); + + EAP_FUNC_IMPORT void set_data_length( + const u32_t p_data_length, + const bool expanded_type_when_true); + + EAP_FUNC_IMPORT void reset_header( + const u32_t buffer_length, + const bool expanded_type_when_true); + + // + //-------------------------------------------------- +}; // class gsmsim_header_c + +//-------------------------------------------------- + +/// Macro traces payload type and data. +#define EAP_GSMSIM_TRACE_PAYLOAD(prefix, payload) \ + { \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("%s (0x%08x): current payload 0x%04x=%s, data length 0x%04x.\n"), \ + prefix, (payload)->get_header_buffer((payload)->get_payload_length()), (payload)->get_current_payload(), \ + (payload)->get_payload_AT_string(), (payload)->get_data_length())); \ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("payload"), \ + (payload)->get_header_buffer((payload)->get_payload_length()), \ + (payload)->get_payload_length())); \ + } + +//-------------------------------------------------- + +#endif //#if !defined(_GSMSIM_HEADER_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_initialized.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_initialized.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_GSMSIM_INITIALIZED_H_) +#define _GSMSIM_INITIALIZED_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_type_gsmsim_header.h" +#include "eap_type_gsmsim_types.h" +#include "eap_type_gsmsim_payloads.h" +#include "abs_eap_type_gsmsim_state.h" +#include "abs_eap_am_tools.h" + + +const u32_t GSMSIM_MAX_OFFER_COUNT = 3; + + +class EAP_EXPORT eap_type_gsmsim_initialized_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + u32_t m_counter; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_type_gsmsim_initialized_c(); + + // + eap_type_gsmsim_initialized_c( + abs_eap_am_tools_c * const tools, + abs_eap_type_gsmsim_state_c * const /*partner*/); + + u32_t counter(); + + void increment(); + + void reset(); + +}; + + +#endif //#if !defined(_GSMSIM_INITIALIZED_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_mac_attributes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_mac_attributes.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TYPE_GSMSIM_MAC_ATTRIBUTES_H_) +#define _EAP_TYPE_GSMSIM_MAC_ATTRIBUTES_H_ + +#include "eap_type_gsmsim_header.h" +#include "eap_type_all_types.h" + +//-------------------------------------------------- + +/// These are the stored attributes for message authentication calculations. +class eap_type_gsmsim_MAC_attributes_c +{ +private: + //-------------------------------------------------- + + u8_t * m_MAC; ///< This is the pointer to MAC. + u32_t m_MAC_size; ///< This is the size of the MAC. + u8_t *m_data; ///< This is the pointer to the authenticated data. + u32_t m_data_length; ///< This the length of the authenticated data. + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + virtual ~eap_type_gsmsim_MAC_attributes_c(); + + eap_type_gsmsim_MAC_attributes_c(); + + eap_type_gsmsim_MAC_attributes_c( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length); + + void init( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length); + + u8_t * get_MAC() const; + + void set_MAC(u8_t * MAC); + + u32_t get_MAC_size() const; + + eap_type_gsmsim_MAC_attributes_c * copy() const; + + u8_t * get_data() const; + + u32_t get_data_length(); + + void set_data(u8_t * const data); + + //-------------------------------------------------- +}; + + +#endif //#if !defined(_EAP_TYPE_GSMSIM_MAC_ATTRIBUTES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_payloads.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,290 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_GSMSIM_RESULT_H_) +#define _GSMSIM_RESULT_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_type_gsmsim_header.h" + + + +class EAP_EXPORT gsmsim_fixed_data_c +{ +private: + //-------------------------------------------------- + + bool m_is_valid; + gsmsim_payload_AT_header_c m_original_header; + u16_t m_type; + u16_t m_data; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~gsmsim_fixed_data_c(); + + EAP_FUNC_IMPORT gsmsim_fixed_data_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT bool get_is_valid() const; + + EAP_FUNC_IMPORT const gsmsim_payload_AT_header_c * get_original_header(); + + EAP_FUNC_IMPORT u16_t get_type(abs_eap_am_tools_c * const m_am_tools) const; + + EAP_FUNC_IMPORT u16_t get_data(abs_eap_am_tools_c * const m_am_tools) const; + + EAP_FUNC_IMPORT void set_data( + const gsmsim_payload_AT_header_c * const original_header, + const u16_t type, const u16_t data); + + //-------------------------------------------------- +}; // class gsmsim_fixed_data_c + + +class EAP_EXPORT gsmsim_variable_data_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + eap_variable_data_c m_data; + + gsmsim_payload_AT_header_c m_original_header; + + bool m_payload_included; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~gsmsim_variable_data_c(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c(abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT const gsmsim_payload_AT_header_c * get_original_header() const; + + EAP_FUNC_IMPORT eap_status_e set_buffer( + const gsmsim_payload_AT_header_c * const original_header, + u8_t *buffer, + const u32_t buffer_length, + const bool free_buffer, + const bool is_writable); + + EAP_FUNC_IMPORT bool get_payload_included() const; + + EAP_FUNC_IMPORT u32_t get_data_length() const; + + EAP_FUNC_IMPORT u8_t * get_data(const u32_t data_length) const; + + EAP_FUNC_IMPORT eap_variable_data_c * get_payload_buffer(); + + EAP_FUNC_IMPORT eap_status_e reset(); + + //-------------------------------------------------- +}; // class gsmsim_variable_data_c + + +//-------------------------------------------------- + + +// +class EAP_EXPORT gsmsim_payloads_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + gsmsim_variable_data_c m_nonce_mt; + + gsmsim_variable_data_c m_nonce_s; + + gsmsim_variable_data_c m_MAC; + + gsmsim_variable_data_c m_ENCR_DATA; + + gsmsim_variable_data_c m_IDENTITY_payload; + + gsmsim_variable_data_c m_padding_payload; + + gsmsim_variable_data_c m_n_RANDs; + + gsmsim_variable_data_c m_PERMANENT_ID_REQ; + + gsmsim_variable_data_c m_FULLAUTH_ID_REQ; + + gsmsim_variable_data_c m_ANY_ID_REQ; + + gsmsim_variable_data_c m_IV; + + gsmsim_variable_data_c m_NEXT_PSEUDONYM; + + gsmsim_variable_data_c m_NEXT_REAUTH_ID; + + gsmsim_variable_data_c m_NOTIFICATION; + + gsmsim_variable_data_c m_VERSION_LIST; + + gsmsim_variable_data_c m_SELECTED_VERSION; + + gsmsim_variable_data_c m_COUNTER; + + gsmsim_variable_data_c m_COUNTER_TOO_SMALL; + + gsmsim_variable_data_c m_CLIENT_ERROR_CODE; + + gsmsim_variable_data_c m_RESULT_IND; + + gsmsim_payload_AT_type_e m_unknown_payload; + + bool m_includes_other_version_than_1; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + + enum eap_gsmsim_payload_status_e + { + eap_gsmsim_payload_status_optional, + eap_gsmsim_payload_status_must_be, + eap_gsmsim_payload_status_must_not_be + }; + + + EAP_FUNC_IMPORT virtual ~gsmsim_payloads_c(); + + EAP_FUNC_IMPORT gsmsim_payloads_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT bool check_one_payload( + const eap_gsmsim_payload_status_e status, + const gsmsim_variable_data_c * const payload); + + /** This function checks the correct set of payloads are included in the message. + * NOTE do not change the order of parameters. + * Add new payload type to the last of the parameter list. + */ + EAP_FUNC_IMPORT bool check_payloads( + const eap_gsmsim_payload_status_e nonce_mt, + const eap_gsmsim_payload_status_e nonce_s, + const eap_gsmsim_payload_status_e MAC, + const eap_gsmsim_payload_status_e ENCR_DATA, + const eap_gsmsim_payload_status_e IDENTITY, + const eap_gsmsim_payload_status_e padding, + const eap_gsmsim_payload_status_e n_RANDs, + const eap_gsmsim_payload_status_e PERMANENT_ID_REQ, + const eap_gsmsim_payload_status_e FULLAUTH_ID_REQ, + const eap_gsmsim_payload_status_e ANY_ID_REQ, + const eap_gsmsim_payload_status_e IV, + const eap_gsmsim_payload_status_e NEXT_PSEUDONYM, + const eap_gsmsim_payload_status_e NEXT_REAUTH_ID, + const eap_gsmsim_payload_status_e NOTIFICATION, + const eap_gsmsim_payload_status_e VERSION_LIST, + const eap_gsmsim_payload_status_e SELECTED_VERSION, + const eap_gsmsim_payload_status_e COUNTER, + const eap_gsmsim_payload_status_e COUNTER_TOO_SMALL, + const eap_gsmsim_payload_status_e CLIENT_ERROR_CODE, + const eap_gsmsim_payload_status_e RESULT_IND + ); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_NONCE_MT(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_NONCE_S(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_MAC(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_ENCR_DATA(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_IDENTITY_payload(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_padding_payload(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_n_RANDs(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_PERMANENT_ID_REQ(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_FULLAUTH_ID_REQ(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_ANY_ID_REQ(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_IV(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_NEXT_PSEUDONYM(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_NEXT_REAUTH_ID(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_NOTIFICATION(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_RESULT_IND(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_VERSION_LIST(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_SELECTED_VERSION(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_CLIENT_ERROR_CODE(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_COUNTER(); + + EAP_FUNC_IMPORT gsmsim_variable_data_c * get_COUNTER_TOO_SMALL(); + + + EAP_FUNC_IMPORT void set_includes_unknown_attribute(const gsmsim_payload_AT_type_e unknown_payload); + + EAP_FUNC_IMPORT gsmsim_payload_AT_type_e get_includes_unknown_attribute(); + + + EAP_FUNC_IMPORT void set_includes_other_version_than_1(const bool includes_other_version_than_1); + + EAP_FUNC_IMPORT bool get_includes_other_version_than_1(); + + + EAP_FUNC_IMPORT bool get_is_valid() const; + + //-------------------------------------------------- +}; // class gsmsim_payloads_c + + +#endif //#if !defined(_GSMSIM_RESULT_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_GSMSIM_STATE_H_) +#define _GSMSIM_STATE_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_type_gsmsim_header.h" +#include "eap_type_gsmsim_types.h" +#include "eap_type_gsmsim_payloads.h" +#include "abs_eap_type_gsmsim_state.h" +#include "abs_eap_base_timer.h" +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + #include "eap_sim_triplets.h" +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) +#include "eap_type_gsmsim_state_notification.h" +#include "eap_am_network_id.h" + + +const u32_t GSMSIM_STATE_MAX_TYPES = 4; + + +//----------------------------------------------- + +/// This class stores the valid GSMSIM messages (gsmsim_subtype_e) +/// within a one state (eap_type_gsmsim_state_variable_e). +class EAP_EXPORT eap_type_gsmsim_state_variable_parameters_c +{ +private: + + /// Array includes valid GSMSIM messages (gsmsim_subtype_e). + gsmsim_subtype_e m_valid_types[GSMSIM_STATE_MAX_TYPES]; + + /// The handler of this state must be initiator (server, authenticator). + bool m_must_be_initiator; + + /// The handler of this state must be responsed (client, peer). + bool m_must_be_responder; + +public: + + /** + * Destructor does nothing. + */ + EAP_FUNC_IMPORT virtual ~eap_type_gsmsim_state_variable_parameters_c(); + + /** + * Constructor initializes attributes with default values. + */ + EAP_FUNC_IMPORT eap_type_gsmsim_state_variable_parameters_c(); + + /** + * This function checks the GSMSIM message is valid in this state. + */ + EAP_FUNC_IMPORT bool check_valid_types(gsmsim_subtype_e type) const; + + /** + * This function checks the initiator is valid in this state. + */ + EAP_FUNC_IMPORT bool check_initiator(const bool is_initiator) const; + + /** + * This function initializes this state to allow three GSMSIM message types. + */ + EAP_FUNC_IMPORT void init_state( + const bool must_be_initiator, + const bool must_be_responder, + const gsmsim_subtype_e type0, + const gsmsim_subtype_e type1, + const gsmsim_subtype_e type2, + const gsmsim_subtype_e type3 + ); +}; + + +#endif //#if !defined(_GSMSIM_STATE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_state_notification.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_state_notification.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,104 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_GSMSIM_STATE_NOTIFICATION_H_) +#define _EAP_GSMSIM_STATE_NOTIFICATION_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_protocol_layer.h" +#include "eap_state_notification.h" + + +/// A eap_type_gsmsim_state_notification_c class. +/// This is used for debugging and protocol testing. +class EAP_EXPORT eap_type_gsmsim_state_notification_c +: public eap_state_notification_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_type_gsmsim_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_type_gsmsim_state_notification_c(); + + /** + * The constructor of the eap_type_gsmsim_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT eap_type_gsmsim_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + + +#if defined(USE_EAP_EXPANDED_TYPES) + + EAP_FUNC_IMPORT eap_type_gsmsim_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + + EAP_FUNC_IMPORT eap_type_gsmsim_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + + + //-------------------------------------------------- +}; // class eap_type_gsmsim_state_notification_c + +#endif //#if !defined(_EAP_GSMSIM_STATE_NOTIFICATION_H_) + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/gsmsim/include/eap_type_gsmsim_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,786 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_GSMSIM_TYPES_H_) +#define _GSMSIM_TYPES_H_ + +#include "eap_type_all_types.h" +#include "eap_configuration_field.h" + +/** @file eap_type_gsmsim_types.h + * @brief This file defines the constants of the GSMSIM EAP type. + */ + +const u32_t GSMSIM_FIRST_SEQUENCE = 1u; +const u32_t GSMSIM_PAYLOAD_LENGTH_ALIGN = 4u; +const u32_t GSMSIM_PAYLOAD_ZERO_DATA_LENGTH = 0u; +const u8_t GSMSIM_NAI_AT_BYTE = '@'; + + +enum eap_gsmsim_version +{ + GSMSIM_ILLEGAL_VERSION = 0x0000, + GSMSIM_VERSION_1 = 0x0001, + GSMSIM_LAST_VERSION = 0x0001, ///< Keep this same as the last acceptable version. +}; + + +enum gsmsim_subtype_e +{ + gsmsim_subtype_NONE = 0, + gsmsim_subtype_Start = 10, + gsmsim_subtype_Challenge = 11, + gsmsim_subtype_Notification = 12, + gsmsim_subtype_Re_authentication = 13, + gsmsim_subtype_Client_Error = 14, +}; + +enum gsmsim_payload_AT_type_e +{ + gsmsim_payload_NONE = 0, + + gsmsim_payload_AT_RAND = 1, + gsmsim_payload_AT_PADDING = 6, + gsmsim_payload_AT_NONCE_MT = 7, + gsmsim_payload_AT_PERMANENT_ID_REQ = 10, + gsmsim_payload_AT_MAC = 11, + gsmsim_payload_AT_NOTIFICATION = 12, + gsmsim_payload_AT_ANY_ID_REQ = 13, + gsmsim_payload_AT_IDENTITY = 14, + gsmsim_payload_AT_VERSION_LIST = 15, + gsmsim_payload_AT_SELECTED_VERSION = 16, + gsmsim_payload_AT_FULLAUTH_ID_REQ = 17, + gsmsim_payload_AT_COUNTER = 19, + gsmsim_payload_AT_COUNTER_TOO_SMALL = 20, + gsmsim_payload_AT_NONCE_S = 21, + gsmsim_payload_AT_CLIENT_ERROR_CODE = 22, + + gsmsim_payload_AT_IV = 129, + gsmsim_payload_AT_ENCR_DATA = 130, + gsmsim_payload_AT_NEXT_PSEUDONYM = 132, + gsmsim_payload_AT_NEXT_REAUTH_ID = 133, + gsmsim_payload_AT_RESULT_IND = 135, +}; + +enum eap_gsmsim_client_error_code_e +{ + eap_gsmsim_client_error_code_unable_to_process_packet = 0, + eap_gsmsim_client_error_code_unsupported_version = 1, + eap_gsmsim_client_error_code_insufficient_number_of_challenges = 2, + eap_gsmsim_client_error_code_rands_are_not_fresh = 3, + eap_gsmsim_client_error_code_maximum_value = eap_gsmsim_client_error_code_rands_are_not_fresh, + eap_gsmsim_client_error_code_none = 0xff, +}; + + +/** + * This is the internal state of the GSMSIM EAP type. + */ +enum eap_type_gsmsim_state_variable_e +{ + eap_type_gsmsim_state_none , ///< This is the initial state + eap_type_gsmsim_state_waiting_for_identity_request , ///< Client state waiting_for_identity_request + eap_type_gsmsim_state_pending_identity_query , ///< Client state pending_identity_query + eap_type_gsmsim_state_waiting_for_start_request , ///< Client state imsi_waiting_for_start_request + eap_type_gsmsim_state_imsi_waiting_for_start_request , ///< Client state imsi_waiting_for_start_request + eap_type_gsmsim_state_pseydonym_waiting_for_start_request , ///< Client state pseydonym_waiting_for_start_request + eap_type_gsmsim_state_analyse_start_request , ///< Client state analyse_start_request + eap_type_gsmsim_state_waiting_for_challenge_request , ///< Client state waiting_for_challenge_request + eap_type_gsmsim_state_analyses_challenge_request , ///< Client state analyses_challenge_request + eap_type_gsmsim_state_pending_kc_sres_query , ///< Client state pending_kc_sres_query + eap_type_gsmsim_state_waiting_for_notification_request_success , ///< Client state waiting_for_notification_request_success + eap_type_gsmsim_state_waiting_for_success , ///< Client state waiting_for_success + eap_type_gsmsim_state_waiting_for_reauth_request , ///< Client state waiting_for_reauth_request + eap_type_gsmsim_state_analyses_reauthentication_request , ///< Client state analyses_reauthentication_request + + eap_type_gsmsim_state_pending_pseudonym_decode_query , ///< Server state pending_pseudonym_decode_query + eap_type_gsmsim_state_waiting_for_identity_response , ///< Server state waiting_for_identity_response + eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity , ///< Server state waiting_for_start_response_with_at_permanen_identity + eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity , ///< Server state waiting_for_start_response_with_at_identity + eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity , ///< Server state waiting_for_start_response_with_at_identity + eap_type_gsmsim_state_waiting_for_start_response , ///< Server state waiting_for_start_response + eap_type_gsmsim_state_waiting_for_challenge_response , ///< Server state waiting_for_challenge_response + eap_type_gsmsim_state_pending_triplet_query , ///< Server state pending_triplet_query + eap_type_gsmsim_state_analyses_challenge_response , ///< Server state analyses_challenge_response + eap_type_gsmsim_state_analyses_start_response , ///< Server state analyses_start_response + eap_type_gsmsim_state_waiting_for_notification_response_failure , ///< Server state waiting_for_notification_response, authentication failed + eap_type_gsmsim_state_waiting_for_notification_response_success , ///< Server state waiting_for_notification_response, authentication success + eap_type_gsmsim_state_waiting_for_reauth_response , ///< Server state waiting_for_reauth_response + eap_type_gsmsim_state_analyses_reauthentication_response , ///< Server state analyses_reauthentication_response + + eap_type_gsmsim_state_success , ///< State state_success + eap_type_gsmsim_state_failure , ///< State state_failure + + eap_type_gsmsim_state_last_value ///< Keep this enum the last one. +}; + + +/** + * This is the required completion after a asyncronous call. + */ +enum eap_type_gsmsim_complete_e +{ + eap_type_gsmsim_complete_none, ///< No completion required + eap_type_gsmsim_complete_start_request, ///< GSMSIM start request must be completed + eap_type_gsmsim_complete_query_eap_identity, ///< GSMSIM EAP-identity query must be completed + eap_type_gsmsim_complete_handle_imsi_from_username, + eap_type_gsmsim_complete_handle_start_response_message_completion, +}; + + +/** + * This is the status of the triplet. + */ +enum eap_gsmsim_triplet_status_e +{ + eap_gsmsim_triplet_status_ok = 0, + eap_gsmsim_triplet_status_no_roaming_agreement = 1024, ///< No roaming agreement. + eap_gsmsim_triplet_status_users_calls_are_barred = 1026, ///< User's calls are barred. + eap_gsmsim_triplet_status_user_has_not_subscribed_to_the_requested_service = 1031, ///< User has not subrcibed to the requested service. +}; + + +enum eap_gsmsim_notification_codes_e +{ + eap_gsmsim_notification_no_F_no_P_general_failure = 0, ///< General failure. (implies failure, used after successful authentication) + eap_gsmsim_notification_no_F_P_set_general_failure = 16384, ///< General failure. (implies failure, used before authentication) + eap_gsmsim_notification_F_set_no_P_user_authenticated = 32768, ///< User has been successfully authenticated. (does not imply failure, used after successful authentication). The usage of this code is discussed in Section 4.4.2. + eap_gsmsim_notification_no_F_no_P_users_calls_are_barred = 1026, ///< User has been temporarily denied access to the requested service. (Implies failure, used after successful authentication) + eap_gsmsim_notification_no_F_no_P_user_has_not_subscribed_to_the_requested_service = 1031, ///< User has not subscribed to the requested service (implies failure, used after successful authentication) + eap_gsmsim_notification_none = 0xffff, ///< No code. +}; + + +enum gsmsim_notification_code_bits_e +{ + gsmsim_notification_code_bit_f = 0x8000, + gsmsim_notification_code_bit_p = 0x4000, + gsmsim_notification_code_value = 0x3FFF, +}; + + +/** See eap_gsmsim_triplet_status_e. */ +const u8_t EAP_GSMSIM_NOTIFICATION_NO_ROAMING_AGREEMENT[] + = "1024 Visited network does not have a roaming agreement with user's home operator"; +/** See eap_gsmsim_triplet_status_e. */ +const u8_t EAP_GSMSIM_NOTIFICATION_USERS_CALLS_ARE_BARRED[] + = "1026 User's calls are barred"; +/** See eap_gsmsim_triplet_status_e. */ +const u8_t EAP_GSMSIM_NOTIFICATION_USER_HAS_NOT_SUBSCRIBED_TO_THE_REQUESTED_SERVICE[] + = "1031 User has not subscribed to the requested service"; + +/** + * This is the type of the GSMSIM identity. + */ +enum eap_type_gsmsim_identity_type +{ + GSMSIM_IDENTITY_TYPE_NONE, + GSMSIM_IDENTITY_TYPE_IMSI_ID, + GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID, + GSMSIM_IDENTITY_TYPE_RE_AUTH_ID, +}; + +enum eap_gsmsim_authentication_type_e +{ + GSMSIM_AUTHENTICATION_TYPE_NONE, + GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH, + GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION, +}; + +const u8_t GSMSIM_IMSI_PREFIX_CHARACTER[] = "1"; +const u32_t GSMSIM_IMSI_PREFIX_CHARACTER_LENGTH = sizeof(GSMSIM_IMSI_PREFIX_CHARACTER)-1ul; + +const u8_t GSMSIM_AT_CHARACTER[] = "@"; +const u32_t GSMSIM_AT_CHARACTER_LENGTH = sizeof(GSMSIM_AT_CHARACTER)-1ul; + +const u8_t GSMSIM_OWLAN_ORG_PREFIX_STRING[] = "wlan"; +const u32_t GSMSIM_OWLAN_ORG_PREFIX_STRING_LENGTH = sizeof(GSMSIM_OWLAN_ORG_PREFIX_STRING)-1ul; + +const u8_t GSMSIM_UMA_PREFIX_STRING[] = "uma"; +const u32_t GSMSIM_UMA_PREFIX_STRING_LENGTH = sizeof(GSMSIM_UMA_PREFIX_STRING)-1ul; + +const u8_t GSMSIM_OWLAN_MNC_STRING[] = "mnc"; +const u32_t GSMSIM_OWLAN_MNC_STRING_LENGTH = sizeof(GSMSIM_OWLAN_MNC_STRING)-1ul; + +const u8_t GSMSIM_OWLAN_DOT_STRING[] = "."; +const u32_t GSMSIM_OWLAN_DOT_STRING_LENGTH = sizeof(GSMSIM_OWLAN_DOT_STRING)-1ul; + +const u8_t GSMSIM_OWLAN_MCC_STRING[] = "mcc"; +const u32_t GSMSIM_OWLAN_MCC_STRING_LENGTH = sizeof(GSMSIM_OWLAN_MCC_STRING)-1ul; + +const u8_t GSMSIM_OWLAN_ORG_STRING[] = "3gppnetwork.org"; +const u32_t GSMSIM_OWLAN_ORG_STRING_LENGTH = sizeof(GSMSIM_OWLAN_ORG_STRING)-1ul; + + +enum eap_type_gsmsim_constants_e +{ + EAP_TYPE_GSMSIM_NONCE_MT_SIZE = 16u, ///< bytes = 128 bits + EAP_TYPE_GSMSIM_MAC_SIZE = 16u, ///< bytes = 128 bits + EAP_TYPE_GSMSIM_KEYMAT_SIZE = 20u, ///< bytes = 160 bits + EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE = 4u*32u, ///< bytes + EAP_TYPE_GSMSIM_MAX_NAI_LENGTH = 255u, ///< bytes + EAP_TYPE_GSMSIM_MAX_USER_NAI_LENGTH = 255u, ///< bytes + EAP_TYPE_GSMSIM_DEFAULT_MINIMUM_RAND_COUNT = 2ul, ///< count + EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH = 512u, ///< This is the size of the local send buffer. + EAP_TYPE_GSMSIM_PADDING_MODULUS = 4ul, ///< Padding length is always mudulus of 4. + EAP_TYPE_GSMSIM_PADDING_MAX_VALUE = 12ul, ///< Maximum padding length is 12 bytes. + EAP_TYPE_GSMSIM_INITIAL_REAUTH_COUNTER = 1ul, + EAP_TYPE_GSMSIM_DEFAULT_MNC_LENGTH_3_BYTES = 3ul, + EAP_TYPE_GSMSIM_MNC_LENGTH_2_BYTES = 2ul, + EAP_TYPE_GSMSIM_MNC_OFFSET = 3ul, + EAP_TYPE_GSMSIM_MCC_LENGTH = 3ul, + EAP_TYPE_GSMSIM_MCC_OFFSET = 0ul, + EAP_TYPE_GSMSIM_MINIMUM_IMSI_LENGTH = EAP_TYPE_GSMSIM_MCC_LENGTH+EAP_TYPE_GSMSIM_MNC_LENGTH_2_BYTES+1, +}; + +enum eap_type_gsmsim_timer_id_e +{ + EAP_TYPE_GSMSIM_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID, + EAP_TYPE_GSMSIM_TIMER_DELAY_NOTIFICATION_MESSAGE_ID, +}; + +enum eap_type_gsmsim_timer_timeout_value_e +{ + EAP_TYPE_GSMSIM_TIMER_TIMEOUT_VALUE_DELAY_FAILURE_MESSAGE_SENT = 0ul, ///< This is the default value. Zero means error message is handled immediately. +}; + +enum eap_type_gsmsim_stored_e +{ + eap_type_gsmsim_stored_none, + eap_type_gsmsim_stored_reauth_xkey, + eap_type_gsmsim_stored_reauth_k_aut, + eap_type_gsmsim_stored_reauth_k_encr, + eap_type_gsmsim_stored_pseudonym_identity, + eap_type_gsmsim_stored_reauth_identity, + eap_type_gsmsim_stored_pseudonym_key, + eap_type_gsmsim_stored_pseudonym_mac_key, + eap_type_gsmsim_stored_prev_pseudonym_key, + eap_type_gsmsim_stored_prev_pseudonym_mac_key, + eap_type_gsmsim_stored_pseudonym_key_index, + eap_type_gsmsim_stored_pseudonym_key_use_count, + eap_type_gsmsim_stored_pseudonym_use_count, + eap_type_gsmsim_stored_reauth_use_count, + eap_type_gsmsim_stored_saved_reauth_counter, + eap_type_gsmsim_stored_saved_dublicate_rand, +}; + +/** + * @defgroup GSMSIM_config_options Configuration options of GSMSIM. + * The following configuration options are read through abs_eap_base_type_c::read_configure() function. + * @{ + */ + +/** + * This u32_t configuration option is timeout in milli seconds before erroneous message is processed. + * This is useful in protocol testing or if some delay is needed in final application. + * Default value is 0. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_failure_message_delay_time, + "EAP_GSMSIM_failure_message_delay_time", + eap_configure_type_u32_t, + false); + +/** + * This u32_t configuration option is minimum count of allowed RANDs in GSMSIM. + * Default value is 2. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_minimum_rand_count, + "EAP_GSMSIM_minimum_rand_count", + eap_configure_type_u32_t, + false); + +/** + * This boolean configuration option specifies whether the username should + * be generated automatically. + * Default value is 0. That will cause use of automatic username. If this is 1 + * then cf_str_EAP_GSMSIM_manual_username is used as the username. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_use_manual_username, + "EAP_GSMSIM_use_manual_username", + eap_configure_type_boolean, + false); + +/** + * This string configuration option is the username part of EAP-type GSMSIM identity. + * Default value is empty string. That will cause use of automatic username. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_manual_username, + "EAP_GSMSIM_manual_username", + eap_configure_type_string, + false); + +/** + * This boolean configuration option specifies whether the realm should + * be generated automatically. + * Default value is 0. That will cause use of automatic realm. If this is 1 + * then cf_str_EAP_GSMSIM_manual_realm is used as the realm. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_use_manual_realm, + "EAP_GSMSIM_use_manual_realm", + eap_configure_type_boolean, + false); + +/** + * This string configuration option is the realm part of EAP-type GSMSIM identity. + * Default value is empty string. That will cause use of automatic realm. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_manual_realm, + "EAP_GSMSIM_manual_realm", + eap_configure_type_string, + false); + +/** + * This is boolean configuration option. + * True value means on successfull authentication EAP-type GSMSIM waits the EAP-Success message. + * False value means on successfull authentication EAP-type GSMSIM does NOT wait the EAP-Success message. + * NOTE: True value is needed in Windows RAS. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_wait_eap_success_packet, + "EAP_GSMSIM_wait_eap_success_packet", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means on EAP-type GSMSIM must check identifier of EAP-Response/Identity message. + * False value means on EAP-type GSMSIM does not check identifier of EAP-Response/Identity message. + * This is not possible in cases where identifier of the EAP-Request/Identity is generated by other network entities. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_check_identifier_of_eap_identity_response, + "EAP_GSMSIM_check_identifier_of_eap_identity_response", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag activates NAI realm check. Default value is false. + * When active NAI realm muts be the same as realm given by EAP_GSMSIM_manual_realm option. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_check_nai_realm, + "EAP_GSMSIM_check_nai_realm", + eap_configure_type_boolean, + false); + +/** + * This is for testing. + * This string configuration option is the full path name of the nonce_mt file. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_nonce_mt_file, + "EAP_GSMSIM_nonce_mt_file", + eap_configure_type_string, + false); + +/** + * This is for testing. + * This string configuration option is the full path name of the triplet file. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_triplet_file, + "EAP_GSMSIM_triplet_file", + eap_configure_type_string, + false); + +/** + * This is for testing. + * This string configuration option is the full path name of the pseudonym file. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_pseudonym_file, + "EAP_GSMSIM_pseudonym_file", + eap_configure_type_string, + false); + +/** + * This is for testing. + * This string configuration option is the full path name of the reauthentication file. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_reauthentication_file, + "EAP_GSMSIM_reauthentication_file", + eap_configure_type_string, + false); + +/** + * This is for testing. + * This string configuration option is the full path name of the encryption IV file. + * Default value is empty string. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_encryption_iv_file, + "EAP_GSMSIM_encryption_iv_file", + eap_configure_type_string, + false); + +/** + * This is boolean configuration option. + * True value means client of EAP-type GSMSIM responds to every re-transmitted EAP-SIM request packets. + * False value means client of EAP-type GSMSIM does not respond to any re-transmitted EAP-SIM request packets, + * instead the EAP layer does re-transmit the response. + * The default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_client_responds_retransmitted_packets, + "EAP_GSMSIM_client_responds_retransmitted_packets", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is for testing. + * True value means test version of EAP-type GSMSIM is used. + * Test version tries to make as many authentications as it is possible. + * False value means on real version of EAP-type GSMSIM is used. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_test_version, + "EAP_GSMSIM_test_version", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is for testing. + * True value means server refuses EAP-identity randomly. + * False value means does not refuse EAP-identity randomly. + * NOTE EAP_GSMSIM_test_version option must be true also. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_randomly_refuse_eap_identity, + "EAP_GSMSIM_randomly_refuse_eap_identity", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means on test of re-authentication counter of EAP-type GSMSIM will fail always. + * NOTE EAP_GSMSIM_test_version option must be true also. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_fail_re_authentication_counter_check, + "EAP_GSMSIM_fail_re_authentication_counter_check", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value of this flag allows server accept the EAP-Response/Identity message. + * False value does not allow server accept the EAP-Response/Identity message. + * Instead server queries identity in EAP-Request/SIM/Start with AT_ANY_ID_REQ attribute. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_accept_eap_identity_response, + "EAP_GSMSIM_accept_eap_identity_response", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value of this flag causes client return random + * identity on EAP-Response/Identity. + * False value causes client return real identity + * (IMSI, pseudonym or re-authentication identity) + * in EAP-Response/Identity. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_use_random_identity_on_eap_identity_response, + "EAP_GSMSIM_use_random_identity_on_eap_identity_response", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value of this flag causes client check the RANDs are unique. + * False value causes client skip the uniqueness check of the RANDs. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_do_rand_uniqueness_check, + "EAP_GSMSIM_do_rand_uniqueness_check", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means progress bar is shown to user. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_enable_progress_bar, + "EAP_GSMSIM_enable_progress_bar", + eap_configure_type_boolean, + false); + +/** + * This is string configuration option. + * This option selects the SIM algorithm used in simulation. + * Possible values are "nokia_test_network_xor" or "tls_prf_with_shared_secret". + * The default value is nokia_test_network_xor. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_simulator_sim_algorithm, + "EAP_GSMSIM_simulator_sim_algorithm", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_simulator_sim_algorithm_config_value_nokia_test_network_xor, + "nokia_test_network_xor", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_simulator_sim_algorithm_config_value_tls_prf_with_shared_secret, + "tls_prf_with_shared_secret", + eap_configure_type_string, + false); + +/** + * This is hex data configuration option. + * This Ki is used in software-SIM (SW-SIM). + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_simulator_sim_ki, + "EAP_GSMSIM_simulator_sim_ki", + eap_configure_type_hex_data, + false); + +/** + * This is boolean configuration option. + * This flag tells whether the UMA profile is used (true) or not (false). + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_UMA_profile, + "EAP_GSMSIM_UMA_profile", + eap_configure_type_boolean, + false); + +/** + * This is string configuration option. + * The string is the prefix of automatic realm in the UMA profile. + * Note also the EAP_GSMSIM_UMA_profile must be true before + * this option is used. + * Default value is empty. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_UMA_realm_prefix, + "EAP_GSMSIM_UMA_realm_prefix", + eap_configure_type_string, + false); + +/** + * This is boolean configuration option. + * This flag tells whether the pseudonym identity could be used (true) or not (false). + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_use_pseudonym_identity, + "EAP_GSMSIM_use_pseudonym_identity", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag tells whether the re-authentication identity could be used (true) or not (false). + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_use_reauthentication_identity, + "EAP_GSMSIM_use_reauthentication_identity", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means queries to AM are completed asyncronous. + * False value means queries to AM are completed syncronous. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_do_asyncronous_completions, + "EAP_GSMSIM_do_asyncronous_completions", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means triplet queries to AM are failed randomly. + * False value means triplet queries to AM are not failed. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_fail_SIM_triplets_query_randomly, + "EAP_GSMSIM_fail_SIM_triplets_query_randomly", + eap_configure_type_boolean, + false); + + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means server sends dublicate RANDS. + * False value means server sends random RANDs. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_test_dublicate_triplets, + "EAP_GSMSIM_test_dublicate_triplets", + eap_configure_type_boolean, + false); + + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means queries to AM are randomly completed asyncronous. + * False value means queries to AM are randomly completed syncronous. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_do_asyncronous_completions_randomly, + "EAP_GSMSIM_do_asyncronous_completions_randomly", + eap_configure_type_boolean, + false); + + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means EAP-SIM server fails randomly successfull authentication. + * False value means EAP-SIM server does NOT fail randomly successfull authentication. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_randomly_fail_successfull_authentication, + "EAP_GSMSIM_randomly_fail_successfull_authentication", + eap_configure_type_boolean, + false); + + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means EAP-SIM client and server allows result indications. + * False value means EAP-SIM client and server does NOT allow result indications. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_allow_use_result_indication, + "EAP_GSMSIM_allow_use_result_indication", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means EAP-SIM server allows result indications. + * False value means EAP-SIM server does NOT allow result indications. + * NOTE this option over rides cf_str_EAP_GSMSIM_allow_use_result_indication + * in server. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_server_allow_use_result_indication, + "EAP_GSMSIM_server_allow_use_result_indication", + eap_configure_type_boolean, + false); + + +/** + * This u32_t array configuration option is includes those MCCs that uses 2 digit MNC. + * Default value is empty array. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_2_digit_mnc_map_of_mcc_of_imsi_array, + "EAP_AKA_GSMSIM_2_digit_mnc_map_of_mcc_of_imsi_array", + eap_configure_type_u32array, + false); + + + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means EAP-SIM server randomly skip pseudonym and fast-reauth identity generation. + * False value means EAP-SIM server does generate those identities. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_server_randomly_skip_identity_generation, + "EAP_GSMSIM_server_randomly_skip_identity_generation", + eap_configure_type_boolean, + false); + + +/** + * This is boolean configuration option. True value activates use of expanded EAP type field of 64-bits in length. + * False value forces to use the normal 8-bit EAP type field. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_use_eap_expanded_type, + "EAP_GSMSIM_use_eap_expanded_type", + eap_configure_type_boolean, + false); + +/** + * This u32_t configuration value specifies the maximum session validity time in seconds. + * Default value is 12 hours in seconds, which is 43200 seconds. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GSMSIM_max_session_validity_time, + "EAP_GSMSIM_max_session_validity_time", + eap_configure_type_u32_t, + false); + + +/** @} */ // End of group GSMSIM_config_options. + +#endif //#if !defined(_GSMSIM_TYPES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,50 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_all + +SRC_FILES_CPP = $(WLAN_COMMON)/type/eap_type_all.cpp \ + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_gsmsim.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_tls_peap.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_tls_peap.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_gsmsim_simulator.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_tls_peap_simulator.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_simple_config.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_simple_config_simulator.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_tls_tools.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_simple_config_tools.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_aka.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_aka_simulator.$(LIB) \ + +ifdef USE_SAE_EAP_TYPE +LIBS := ${LIBS} \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_sim_simulator.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_dummy_sim.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_saesim_core.$(LIB) +endif + +ifdef USE_MSCHAPV2_EAP_TYPE +LIBS := $(LIBS) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_mschapv2_simulator.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_mschapv2.$(LIB) +endif + +ifdef USE_SECURID_EAP_TYPE +LIBS := ${LIBS} \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_securid.$(LIB) +endif + +ifdef USE_LEAP_EAP_TYPE +LIBS := ${LIBS} \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_leap.$(LIB) +endif + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2281 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 95 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "eap_am_memory.h" +#include "eap_state_notification.h" +#include "eap_type_mschapv2_header.h" +#include "eap_type_mschapv2.h" +#include "eap_type_mschapv2_credential_store.h" +#include "eap_buffer.h" +#include "eap_config.h" +#include "eap_master_session_key.h" +#include "eap_automatic_variable.h" + +/** +* Constructor initializes all member attributes. +*/ + +EAP_FUNC_EXPORT eap_type_mschapv2_c::eap_type_mschapv2_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + eap_am_type_mschapv2_c * const am_type_mschapv2, + const bool free_am_type_mschapv2, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) + : eap_base_type_c(tools, partner) + , m_am_type_mschapv2(am_type_mschapv2) + , m_am_tools(tools) + , m_session(tools, is_client_when_true) + , m_send_network_id(tools) + , m_rand(tools) + , m_username_utf8(tools) + , m_password_utf8(tools) + , m_old_password_utf8(tools) + , m_password_hash(tools) + , m_password_hash_hash(tools) +#if defined(USE_FAST_EAP_TYPE) + , m_client_EAP_FAST_challenge(tools) + , m_server_EAP_FAST_challenge(tools) +#endif //#if defined(USE_FAST_EAP_TYPE) + , m_offset(0) + , m_mtu_length(0) + , m_trailer_length(0) + , m_error_code(0) + , m_is_valid(false) + , m_is_client(is_client_when_true) + , m_free_am_type_mschapv2(free_am_type_mschapv2) + , m_is_pending(false) + , m_identity_asked(false) + , m_wait_eap_success(false) + , m_wait_eap_success_packet(true) + , m_is_reauthentication(false) + , m_is_notification_sent(false) + , m_shutdown_was_called(false) + , m_password_prompt_enabled(true) + , m_identifier(0) + , m_mschapv2id(0) +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + , m_use_implicit_challenge(false) +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) +#if defined(EAP_MSCHAPV2_SERVER) + , m_do_password_expiration_tests(false) + , m_password_expired(false) +#endif //#if defined(EAP_MSCHAPV2_SERVER) + , m_do_wrong_password_tests(false) + , m_use_eap_expanded_type(false) +#if defined(USE_FAST_EAP_TYPE) + , m_use_EAP_FAST_full_key(false) + , m_use_EAP_FAST_challenge(false) +#endif //#if defined(USE_FAST_EAP_TYPE) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::eap_type_mschapv2_c(): this = 0x%08x, ") + EAPL("partner 0x%08x, type partner 0x%08x, compiled %s %s\n"), + this, + partner, + get_type_partner(), + __DATE__, + __TIME__)); + + m_am_type_mschapv2->set_am_partner(this); + + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + eap_status_e status = m_send_network_id.set_copy_of_network_id(&send_network_id); + + if (status != eap_status_ok + || m_send_network_id.get_is_valid_data() == false) + { + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + } + + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_mschapv2_c::~eap_type_mschapv2_c() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::~eap_type_mschapv2_c(): this = 0x%08x\n"), + this)); + + EAP_ASSERT(m_shutdown_was_called == true); + + if (m_free_am_type_mschapv2 == true) + { + delete m_am_type_mschapv2; + } + m_free_am_type_mschapv2 = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::shutdown() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::shutdown(): this = 0x%08x, m_session.get_state()=%d, m_is_notification_sent=%d\n"), + this, + m_session.get_state(), + m_is_notification_sent)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_mschapv2_c::shutdown()"); + + m_am_type_mschapv2->shutdown(); + m_shutdown_was_called = true; + + if (m_session.get_state() != eap_type_mschapv2_state_none) + { + if (m_is_notification_sent == false) + { + finish_unsuccessful_authentication(false); + } + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_type_mschapv2_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_mschapv2_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_mschapv2_c::get_is_client() +{ + return m_is_client; +} + +//-------------------------------------------------- + +void eap_type_mschapv2_c::send_error_notification(const eap_status_e error) +{ + // Notifies the lower level of an authentication error. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, + eap_type_mschapv2, + eap_state_none, + eap_general_state_authentication_error, + 0, + false); + + notification.set_authentication_error(error); + + get_type_partner()->state_notification(¬ification); +} + +//-------------------------------------------------- + +eap_buf_chain_wr_c * eap_type_mschapv2_c::create_send_packet(u32_t length) +{ + eap_buf_chain_wr_c * packet = new eap_buf_chain_wr_c( + eap_write_buffer, + m_am_tools, + length + m_offset + m_trailer_length); + if (!packet) + { + return 0; + } + if (packet->get_is_valid() == false) + { + delete packet; + return 0; + } + packet->set_data_length(length + m_offset); + + return packet; +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::packet_send( + eap_buf_chain_wr_c * const data, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (m_mtu_length < data_length) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (data->get_is_valid_data() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = get_type_partner()->packet_send( + &m_send_network_id, + data, + m_offset, + data_length, + data->get_buffer_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::finish_successful_authentication() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: %s: EAP-SUCCESS: function: eap_type_mschapv2_c::finish_successful_authentication()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_mschapv2_c::finish_successful_authentication()"); + + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_type_mschapv2, + eap_state_none, + eap_state_authentication_finished_successfully, + m_identifier, + true); + get_type_partner()->state_notification(¬ification); + + // set notification flag + m_is_notification_sent = true; + + // Store credential for reauthentication (client only) + //if (m_is_client) + { + eap_variable_data_c key(m_am_tools); + eap_status_e status = m_am_type_mschapv2->get_memory_store_key(&key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = key.add_data( + &m_is_client, + sizeof(m_is_client)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Remove the old data. Do not care status. + (void) m_am_tools->memory_store_remove_data(&key); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: EAP_type_MSCHAPV2: finish_successful_authentication(): Credentials removed from mem store\n"), + (m_is_client == true) ? "client": "server")); + + // Store the creditials always, if the password prompt is NOT enabled or + // if the Session is valid. + + if(m_password_prompt_enabled == false + || m_am_type_mschapv2->is_session_valid() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: EAP_type_MSCHAPV2: finish_successful_authentication(): Session valid or PW prompt disabled, Storing Credentials\n"), + (m_is_client == true) ? "client": "server")); + + eap_tlv_message_data_c tlv_data(m_am_tools); + + status = tlv_data.add_message_data( + eap_type_mschapv2_stored_username, + m_username_utf8.get_data_length(), + m_username_utf8.get_data()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tlv_data.add_message_data( + eap_type_mschapv2_stored_password, + m_password_utf8.get_data_length(), + m_password_utf8.get_data()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(EAP_MSCHAPV2_SERVER) + status = tlv_data.add_message_data( + eap_type_mschapv2_stored_password_expired_flag, + sizeof(m_password_expired), + &m_password_expired); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + status = m_am_tools->memory_store_add_data( + &key, + &tlv_data, + eap_type_default_credential_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: finish_successful_authentication(): cannot store credentials\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: EAP_type_MSCHAPV2: finish_successful_authentication(): Credentials stored \n"), + (m_is_client == true) ? "client": "server")); + + } // End of if(m_password_prompt_enabled == true .... + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::finish_unsuccessful_authentication( + const bool authentication_cancelled) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s: EAP_type_MSCHAPV2: FAILED: function: eap_type_mschapv2_c::finish_unsuccessful_authentication()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_mschapv2_c::finish_unsuccessful_authentication()"); + + if (m_is_client == true) + { + if (authentication_cancelled == true) + { + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, // This must be used with eap_general_state_authentication_cancelled. + eap_type_mschapv2, + eap_state_none, + eap_general_state_authentication_cancelled, + m_identifier, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + get_type_partner()->state_notification(¬ification); + } + else + { + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_type_mschapv2, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + m_identifier, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + get_type_partner()->state_notification(¬ification); + } + +#if defined(USE_USER_NOTIFICATIONS) + eap_variable_data_c string(m_am_tools); + eap_status_e status = m_am_type_mschapv2->read_auth_failure_string(EAP_MSCHAPV2_ERROR_AUTHENTICATION_FAILURE, string); + if (status == eap_status_ok) + { + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, // This must be used with eap_general_state_show_notification_string. + eap_type_mschapv2, + eap_state_none, + eap_general_state_show_notification_string, + 0, + false); + status = notification.set_notification_string(&string, true); + if (status == eap_status_ok) + { + get_type_partner()->state_notification(¬ification); + } + } +#endif //#if defined(USE_USER_NOTIFICATIONS) + } + else + { + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_type_mschapv2, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + m_identifier, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + get_type_partner()->state_notification(¬ification); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: EAP_type_MSCHAPV2: finish_unsuccessful_authentication(): EAP-FAILED\n"), + (m_is_client == true) ? "client": "server")); + + // set notification flag + m_is_notification_sent = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::packet_process( + const eap_am_network_id_c * const /*receive_network_id*/, + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_drop_packet_quietly; + + if (eap_packet_length > received_eap->get_header_buffer_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + if (eap_packet_length < eap_header_base_c::get_header_length()) // Without type code + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + if (received_eap->get_type() == eap_type_notification) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + +#ifdef EAP_MSCHAPV2_SERVER + if (m_is_client) // Client + { +#endif + + status = client_packet_process( + received_eap, + eap_packet_length); + +#ifdef EAP_MSCHAPV2_SERVER + } + else // Server + { + status = server_packet_process( + received_eap, + eap_packet_length); + } +#endif + + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(received_eap, false); + } + + if (status == eap_status_ok + || status == eap_status_pending_request + || status == eap_status_drop_packet_quietly) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Internal error + status = finish_unsuccessful_authentication(false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::configure(): this = 0x%08x\n"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_mschapv2_c::configure()"); + + eap_status_e status = eap_status_process_general_error; + + status = m_am_type_mschapv2->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_offset = get_type_partner()->get_header_offset(&m_mtu_length, &m_trailer_length); + + // read configures + + // Password promt + eap_variable_data_c password_prompt(m_am_tools); + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_password_prompt.get_field(), + &password_prompt); + if (status == eap_status_ok) + { + const u32_t * const flag = reinterpret_cast( + password_prompt.get_data(sizeof(u32_t))); + if (flag && *flag == 0) + { + m_password_prompt_enabled = false; + } + else + { + m_password_prompt_enabled = true; + } + } + + // Username + eap_variable_data_c username_uc(m_am_tools); + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_username.get_field(), + &m_username_utf8); + if (status != eap_status_ok + || m_username_utf8.get_is_valid() == false) + { + // This is optional. + } + + // Password + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_password.get_field(), + &m_password_utf8); + if (status != eap_status_ok + || m_password_utf8.get_is_valid() == false) + { + // This is optional. + } + + if (m_is_client == true + && m_password_prompt_enabled == true) + { + m_password_utf8.reset(); + } + + + +#if defined(EAP_MSCHAPV2_SERVER) + { + eap_variable_data_c do_password_expiration_tests(m_am_tools); + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_do_password_expiration_tests.get_field(), + &do_password_expiration_tests); + if (status == eap_status_ok) + { + const u32_t * const flag = reinterpret_cast( + do_password_expiration_tests.get_data(sizeof(u32_t))); + if (flag != 0 + && *flag == 0) + { + m_do_password_expiration_tests = false; + } + else + { + m_do_password_expiration_tests = true; + } + } + } +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + + if (m_is_client == true) + { + eap_variable_data_c do_wrong_password_tests(m_am_tools); + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_do_wrong_password_tests.get_field(), + &do_wrong_password_tests); + if (status == eap_status_ok) + { + const u32_t * const flag = reinterpret_cast( + do_wrong_password_tests.get_data(sizeof(u32_t))); + if (flag != 0 + && *flag == 0) + { + m_do_wrong_password_tests = false; + } + else + { + m_do_wrong_password_tests = true; + } + } + } + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + { + eap_variable_data_c use_implicit_challenge(m_am_tools); + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_use_implicit_challenge.get_field(), + &use_implicit_challenge); + if (status == eap_status_ok) + { + const u32_t * const flag = reinterpret_cast( + use_implicit_challenge.get_data(sizeof(u32_t))); + if (flag != 0 && *flag != 0) + { + m_use_implicit_challenge = true; + } + else + { + m_use_implicit_challenge = false; + } + } + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + //---------------------------------------------------------- + +#if defined(USE_EAP_EXPANDED_TYPES) + { + eap_variable_data_c use_eap_expanded_type(m_am_tools); + + eap_status_e status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + + if (status != eap_status_ok) + { + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_CORE_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + } + + if (status == eap_status_ok + && use_eap_expanded_type.get_data_length() == sizeof(u32_t) + && use_eap_expanded_type.get_data() != 0) + { + u32_t *flag = reinterpret_cast(use_eap_expanded_type.get_data(use_eap_expanded_type.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_use_eap_expanded_type = true; + } + else + { + m_use_eap_expanded_type = false; + } + } + } + } +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + //---------------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + + { + eap_variable_data_c use_EAP_FAST_challenge(m_am_tools); + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_use_EAP_FAST_challenge.get_field(), + &use_EAP_FAST_challenge); + if (status == eap_status_ok) + { + const u32_t * const flag = reinterpret_cast( + use_EAP_FAST_challenge.get_data(sizeof(u32_t))); + if (flag != 0 && *flag != 0) + { + m_use_EAP_FAST_challenge = true; + } + else + { + m_use_EAP_FAST_challenge = false; + } + } + } + + if (m_use_EAP_FAST_challenge == true) + { + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_client_EAP_FAST_challenge.get_field(), + &m_client_EAP_FAST_challenge); + if (status != eap_status_ok + || m_client_EAP_FAST_challenge.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::configure(): m_client_EAP_FAST_challenge"), + m_client_EAP_FAST_challenge.get_data(), + m_client_EAP_FAST_challenge.get_data_length())); + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_server_EAP_FAST_challenge.get_field(), + &m_server_EAP_FAST_challenge); + if (status != eap_status_ok + || m_server_EAP_FAST_challenge.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::configure(): m_server_EAP_FAST_challenge"), + m_server_EAP_FAST_challenge.get_data(), + m_server_EAP_FAST_challenge.get_data_length())); + } + + { + eap_variable_data_c use_EAP_FAST_full_key(m_am_tools); + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_use_EAP_FAST_full_key.get_field(), + &use_EAP_FAST_full_key); + if (status == eap_status_ok) + { + const u32_t * const flag = reinterpret_cast( + use_EAP_FAST_full_key.get_data(sizeof(u32_t))); + if (flag != 0 && *flag != 0) + { + m_use_EAP_FAST_full_key = true; + } + else + { + m_use_EAP_FAST_full_key = false; + } + } + } + + +#endif //#if defined(USE_FAST_EAP_TYPE) + + //---------------------------------------------------------- + + eap_variable_data_c wait_eap_success_prompt(m_am_tools); + + m_wait_eap_success = true; + + // Check if the case is reauthentication (client only) + //if (m_is_client) + { + eap_variable_data_c key(m_am_tools); + status = m_am_type_mschapv2->get_memory_store_key(&key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = key.add_data( + &m_is_client, + sizeof(m_is_client)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_tlv_message_data_c tlv_data(m_am_tools); + + status = m_am_tools->memory_store_get_data( + &key, + &tlv_data); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: configure(): cannot get credentials\n"))); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: configure: credentials found\n"))); + + // Parse read data. + eap_array_c tlv_blocks(m_am_tools); + + status = tlv_data.parse_message_data(&tlv_blocks); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (u32_t ind = 0ul; ind < tlv_blocks.get_object_count(); ind++) + { + eap_tlv_header_c * const tlv = tlv_blocks.get_object(ind); + if (tlv != 0) + { + if (tlv->get_type() == eap_type_mschapv2_stored_username) + { + if (m_username_utf8.get_is_valid_data() == false) + { + status = m_username_utf8.set_copy_of_buffer( + tlv->get_value(tlv->get_value_length()), + tlv->get_value_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (tlv->get_type() == eap_type_mschapv2_stored_password) + { + if (m_password_prompt_enabled == true + || m_password_utf8.get_is_valid_data() == false) + { + status = m_password_utf8.set_copy_of_buffer( + tlv->get_value(tlv->get_value_length()), + tlv->get_value_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } +#if defined(EAP_MSCHAPV2_SERVER) + else if (tlv->get_type() == eap_type_mschapv2_stored_password_expired_flag) + { + bool * const password_expired = reinterpret_cast(tlv->get_value(sizeof(*password_expired))); + if (password_expired == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_password_expired = *password_expired; + } +#endif //#if defined(EAP_MSCHAPV2_SERVER) + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: unknown credential type %d, length %d\n"), + tlv->get_type(), + tlv->get_value_length())); + } + } + } + + status = m_am_tools->memory_store_remove_data(&key); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: configure: credentials removed from eapol\n"))); + + m_is_reauthentication = true; + m_identity_asked = true; + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: configure, username:"), + m_username_utf8.get_data(), + m_username_utf8.get_buffer_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: configure, password:"), + m_password_utf8.get_data(), + m_password_utf8.get_buffer_length())); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// This function is to allow reuse of this object. +// The whole object state must be reset. +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::reset(): this = 0x%08x\n"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_mschapv2_c::reset()"); + + m_session.set_state(eap_type_mschapv2_state_none); + + m_username_utf8.reset(); + eap_variable_data_c username_uc(m_am_tools); + + eap_status_e status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_username.get_field(), + &m_username_utf8); + if (status != eap_status_ok + || m_username_utf8.get_is_valid() == false) + { + // This is optional. + } + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_password.get_field(), + &m_password_utf8); + if (status != eap_status_ok + || m_password_utf8.get_is_valid() == false) + { + // This is optional. + } + + if (m_is_client == true + && m_password_prompt_enabled == true) + { + m_password_utf8.reset(); + } + + m_old_password_utf8.reset(); + + m_is_notification_sent = false; + m_is_reauthentication = false; + + status = m_am_type_mschapv2->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_FAST_EAP_TYPE) + + { + eap_variable_data_c use_EAP_FAST_challenge(m_am_tools); + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_use_EAP_FAST_challenge.get_field(), + &use_EAP_FAST_challenge); + if (status == eap_status_ok) + { + const u32_t * const flag = reinterpret_cast( + use_EAP_FAST_challenge.get_data(sizeof(u32_t))); + if (flag != 0 && *flag != 0) + { + m_use_EAP_FAST_challenge = true; + } + else + { + m_use_EAP_FAST_challenge = false; + } + } + } + + if (m_use_EAP_FAST_challenge == true) + { + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_client_EAP_FAST_challenge.get_field(), + &m_client_EAP_FAST_challenge); + if (status != eap_status_ok + || m_client_EAP_FAST_challenge.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::reset(): m_client_EAP_FAST_challenge"), + m_client_EAP_FAST_challenge.get_data(), + m_client_EAP_FAST_challenge.get_data_length())); + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_server_EAP_FAST_challenge.get_field(), + &m_server_EAP_FAST_challenge); + if (status != eap_status_ok + || m_server_EAP_FAST_challenge.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::reset(): m_server_EAP_FAST_challenge"), + m_server_EAP_FAST_challenge.get_data(), + m_server_EAP_FAST_challenge.get_data_length())); + + } + + { + eap_variable_data_c use_EAP_FAST_full_key(m_am_tools); + + status = m_am_type_mschapv2->type_configure_read( + cf_str_EAP_MSCHAPV2_use_EAP_FAST_full_key.get_field(), + &use_EAP_FAST_full_key); + if (status == eap_status_ok) + { + const u32_t * const flag = reinterpret_cast( + use_EAP_FAST_full_key.get_data(sizeof(u32_t))); + if (flag != 0 && *flag != 0) + { + m_use_EAP_FAST_full_key = true; + } + else + { + m_use_EAP_FAST_full_key = false; + } + } + } + + +#endif //#if defined(USE_FAST_EAP_TYPE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::mschapv2_convert_unicode_to_ascii( + eap_variable_data_c & dest, + const eap_variable_data_c & src) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::mschapv2_convert_unicode_to_ascii(): this = 0x%08x\n"), + this)); + + if (src.get_is_valid()) + { + u32_t len = src.get_data_length(); + u8_t * ascii = new u8_t[len / 2]; + if (!ascii) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + u8_t * src_ptr = src.get_data(len); + u32_t dest_len = len / 2; + u32_t i; + for (i = 0; i < dest_len; i++) + { + ascii[i] = src_ptr[i * 2]; + } + + return dest.set_buffer(ascii, dest_len, true, true); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); +} + +//-------------------------------------------------- + +/* Pseudocode implementation can be found from */ +/* RFC 2759 Microsoft PPP CHAP Extensions, Version 2 */ + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::generate_nt_response( + const u8_t * const authenticator_challenge, + const u8_t * const peer_challenge, + const u8_t * const username_utf8, + const u32_t username_size, + const eap_variable_data_c * const password_hash, + u8_t * const response) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::generate_nt_response(): this = 0x%08x\n"), + this)); + + if (!authenticator_challenge + || !peer_challenge + || !username_utf8 + || username_size == 0 + || username_size > EAP_MSCHAPV2_USERNAME_MAX_SIZE + || !password_hash + || !response) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: generate_nt_response, authenticator challenge:"), + authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: generate_nt_response, peer challenge:"), + peer_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: generate_nt_response, username_utf8:"), + username_utf8, + username_size)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: generate_nt_response, password_hash:"), + password_hash->get_data(), + password_hash->get_data_length())); + + u8_t * const challenge = new u8_t[8]; + if (!challenge) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = challenge_hash( + peer_challenge, + authenticator_challenge, + username_utf8, + username_size, + challenge); + if (status != eap_status_ok) + { + delete [] challenge; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: generate_nt_response, challenge_hash:"), + challenge, + EAP_MSCHAPV2_CHALLENGE_HASH_SIZE)); + + status = challenge_response( + challenge, + password_hash->get_data(), + response); + delete [] challenge; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::challenge_hash( + const u8_t * const peer_challenge, + const u8_t * const authenticator_challenge, + const u8_t * const username, + const u32_t username_size, + u8_t * const challenge) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::challenge_hash(): this = 0x%08x\n"), + this)); + + if (!peer_challenge + || !authenticator_challenge + || !username + || username_size == 0 + || username_size > EAP_MSCHAPV2_USERNAME_MAX_SIZE + || !challenge) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + crypto_sha1_c sha1(m_am_tools); + + eap_status_e status = sha1.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update(peer_challenge, EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update(authenticator_challenge, EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // username without domain part + u32_t i; + for (i = username_size; i > 0 && username[i - 1] != '\\'; i--) + { + // Nothing to do, the index is the output. + } + + status = sha1.hash_update(username + i, username_size - i); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const digest = new u8_t[EAP_MSCHAPV2_SHA1_DIGEST_SIZE]; + if (!digest) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = sha1.hash_final(digest, 0); + if (status != eap_status_ok) + { + delete [] digest; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_am_tools->memmove(challenge, digest, EAP_MSCHAPV2_CHALLENGE_HASH_SIZE); + + delete [] digest; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::challenge_response( + const u8_t * const challenge, // 8 bytes + const u8_t * const password_hash, // 16 bytes + u8_t * const response) // 24 bytes +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::challenge_response(): this = 0x%08x\n"), + this)); + + if (!challenge + || !password_hash + || !response) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // 3rd 7-octets of password_hash has to be zero padded + u8_t * zero_padded_password_hash_last_part = new u8_t[7]; + if (!zero_padded_password_hash_last_part) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + zero_padded_password_hash_last_part, + password_hash + 14, // 2 * 7 bytes + 2); // 16 - 2 * 7 bytes + + // Zero padding + m_am_tools->memset( + zero_padded_password_hash_last_part + 2, // 16 - 2 * 7 + 0, // 7 - 2 + 5); + + eap_status_e status = des_encrypt( + challenge, + zero_padded_password_hash_last_part, // 3rd 7-octets of (zero_padded_)password_hash + response + 16); // 3rd 8-octets of response + + delete [] zero_padded_password_hash_last_part; + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = des_encrypt( + challenge, + password_hash, // 1st 7-octets of password_hash + response); // 1st 8-octets of response + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = des_encrypt( + challenge, + password_hash + 7, // 2nd 7-octets of password_hash + response + 8); // 2nd 8-octets of response + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::des_crypt( + const u8_t * const data_in, // 8 octets + const u8_t * const key, // 56 bits + u8_t * const data_out, + const bool is_encrypt) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::des_crypt(): this = 0x%08x\n"), + this)); + + if (!data_in + || !key + || !data_out) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + u8_t * const newkey = new u8_t[3 * EAP_MSCHAPV2_DES_KEY_SIZE]; // 3des key is triple size + + if (!newkey) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memset(newkey, 0, 3 * EAP_MSCHAPV2_DES_KEY_SIZE); // 3 * 8 bytes + + // Add parity bits to key, 56 -> 64 bits + + // First octet + // key bit shifting [1, 7] + // newkey copy bit shifting [1, 7], parity bit shifting 0 + + // Second octet + // key bit shifting for second octet [2, 7] and for first octet 0 + // newkey copy bit shifting [1, 7], parity bit shifting 0 + + // Third octet + // key bit shifting for second octet [3, 7] and for first octet [0, 1} + // newkey copy bit shifting [1, 7], parity bit shifting 0 + + // bit no: 7 6 5 4 3 2 1 0, 0 = parity bit + { + int newkey_byte, newkey_bit, newkey_bit_shifting, + key_bit_no, key_byte, key_bit_shifting, bit_counter; + + for (newkey_byte = 0; newkey_byte < 8; newkey_byte++) + { + bit_counter = 0; + + for (newkey_bit = 0; newkey_bit < 7; newkey_bit++) + { + key_bit_no = newkey_byte * 7 + newkey_bit; + key_byte = key_bit_no / 8; + + key_bit_shifting = 7 - (key_bit_no % 8); + newkey_bit_shifting = 7 - (key_bit_no % 7); + + if (key[key_byte] & (1 << key_bit_shifting)) // If bit is 1... + { + newkey[newkey_byte] |= (1 << newkey_bit_shifting); // ...set bit to 1 + bit_counter++; + } + } + + if (bit_counter % 2 == 0) // If even number of bits... + { + // Add parity bit + newkey[newkey_byte] |= 1; // ...set the 1st bit to 1 + } + } + } + + // Copy key three times into triple size key because we are internally using 3des instead of des + // des: Ek == 3des: Ek3(Dk2(Ek1)) when k == k1 == k2 == k3 + m_am_tools->memmove(newkey + EAP_MSCHAPV2_DES_KEY_SIZE, newkey, EAP_MSCHAPV2_DES_KEY_SIZE); + m_am_tools->memmove(newkey + 2 * EAP_MSCHAPV2_DES_KEY_SIZE, newkey, EAP_MSCHAPV2_DES_KEY_SIZE); + + eap_status_e status; + + crypto_3des_ede_c des(m_am_tools); + + if (is_encrypt) + { + status = des.set_encryption_key(newkey, 3 * EAP_MSCHAPV2_DES_KEY_SIZE); + + if (status != eap_status_ok) + { + delete [] newkey; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = des.encrypt_block(data_in, data_out, EAP_MSCHAPV2_DES_BLOCK_SIZE); + } + + else // Decrypt mode + { + status = des.set_decryption_key(newkey, 3 * EAP_MSCHAPV2_DES_KEY_SIZE); + if (status != eap_status_ok) + { + delete [] newkey; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = des.decrypt_block(data_in, data_out, EAP_MSCHAPV2_DES_BLOCK_SIZE); + } + + delete [] newkey; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +static const u8_t eap_type_mschapv2_magic1a[] = { + 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, + 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; + +static const u8_t eap_type_mschapv2_magic2a[] = { + 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, + 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, + 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E }; + +eap_status_e eap_type_mschapv2_c::generate_authenticator_response( + const u8_t * const password_hash_hash, + const u8_t * const nt_response, + const u8_t * const peer_challenge, + const u8_t * const authenticator_challenge, + const u8_t * const username, + const u32_t username_size, + u8_t * const authenticator_response) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::generate_authenticator_response(): this = 0x%08x\n"), + this)); + + if (!password_hash_hash + || !nt_response + || !peer_challenge + || !authenticator_challenge + || !username + || username_size == 0 + || username_size > EAP_MSCHAPV2_USERNAME_MAX_SIZE + || !authenticator_response) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + crypto_sha1_c sha1(m_am_tools); + + eap_status_e status = sha1.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + status = sha1.hash_update(password_hash_hash, EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = sha1.hash_update(nt_response, EAP_MSCHAPV2_NT_RESPONSE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update(eap_type_mschapv2_magic1a, sizeof(eap_type_mschapv2_magic1a)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const digest = new u8_t[EAP_MSCHAPV2_SHA1_DIGEST_SIZE]; + if (!digest) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = sha1.hash_final(digest, 0); + + if (status != eap_status_ok) + { + delete [] digest; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t * const challenge = new u8_t[EAP_MSCHAPV2_CHALLENGE_HASH_SIZE]; + if (!challenge) + { + delete [] digest; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = challenge_hash( + peer_challenge, + authenticator_challenge, + username, + username_size, + challenge); + + if (status != eap_status_ok) + { + delete [] digest; + delete [] challenge; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + sha1.hash_cleanup(); + + status = sha1.hash_init(); + if (status != eap_status_ok) + { + delete [] digest; + delete [] challenge; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update(digest, EAP_MSCHAPV2_SHA1_DIGEST_SIZE); + + if (status != eap_status_ok) + { + delete [] digest; + delete [] challenge; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update(challenge, EAP_MSCHAPV2_CHALLENGE_HASH_SIZE); + + delete [] challenge; + + if (status != eap_status_ok) + { + delete [] digest; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update(eap_type_mschapv2_magic2a, sizeof(eap_type_mschapv2_magic2a)); + if (status != eap_status_ok) + { + delete [] digest; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_final(digest, 0); + + if (status != eap_status_ok) + { + delete [] digest; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_am_tools->memmove(authenticator_response, "S=", 2); + u32_t length = EAP_MSCHAPV2_SHA1_DIGEST_SIZE * 2; + m_am_tools->convert_bytes_to_hex_ascii( + digest, + EAP_MSCHAPV2_SHA1_DIGEST_SIZE, + authenticator_response + 2, + &length); + + m_am_tools->convert_ascii_to_uppercase(authenticator_response + 2, length); + + delete [] digest; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::check_authenticator_response( + const eap_variable_data_c * const password_hash_hash, + const u8_t * const nt_response, + const u8_t * const peer_challenge, + const u8_t * const authenticator_challenge, + const u8_t * const username, + const u32_t username_size, + const u8_t * const received_response, + bool & response_ok) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::check_authenticator_response(): this = 0x%08x\n"), + this)); + + if (!password_hash_hash + || password_hash_hash->get_data_length() < EAP_MSCHAPV2_MD4_DIGEST_SIZE + || !nt_response + || !peer_challenge + || !authenticator_challenge + || !username + || username_size == 0 + || username_size > EAP_MSCHAPV2_USERNAME_MAX_SIZE + || !received_response) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + response_ok = false; + + u8_t * const response = new u8_t[EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE]; + if (!response) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = generate_authenticator_response( + password_hash_hash->get_data(), + nt_response, + peer_challenge, + authenticator_challenge, + username, + username_size, + response); + if (status != eap_status_ok) + { + delete [] response; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("client_handle_success_request(): response"), + response, + EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("client_handle_success_request(): received_response"), + received_response, + EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE)); + + if (m_am_tools->memcmp( + response, + received_response, + EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE) + == 0) + { + response_ok = true; + } + else + { +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true) + { + (void) send_error_notification(eap_status_tunnel_compromise_error); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + } + + delete [] response; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::new_password_encrypted_with_old_nt_password_hash( + const eap_variable_data_c * const new_password_utf8, + const eap_variable_data_c * const old_password_hash, + u8_t * encrypted_pw_block) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::new_password_encrypted_with_old_nt_password_hash(): this = 0x%08x\n"), + this)); + + if (!new_password_utf8 + || new_password_utf8->get_data_length() > EAP_MSCHAPV2_PASSWORD_MAX_SIZE + || !old_password_hash + || !encrypted_pw_block) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_status_e status = encrypt_pw_block_with_password_hash( + new_password_utf8, + old_password_hash->get_data(), + encrypted_pw_block); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::encrypt_pw_block_with_password_hash( + const eap_variable_data_c * const password_utf8, + const u8_t * const password_hash, + u8_t * pw_block) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::encrypt_pw_block_with_password_hash(): this = 0x%08x\n"), + this)); + + if (!password_utf8 + || password_utf8->get_data_length() > EAP_MSCHAPV2_PASSWORD_MAX_SIZE + || !password_hash + || !pw_block + || !m_rand.get_is_valid()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_status_e status = m_rand.add_rand_seed_hw_ticks(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_rand.add_rand_seed(password_utf8->get_data(), password_utf8->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + pw_block_s * clear_pw_block = new pw_block_s; + if (!clear_pw_block) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c tmp_password_unicode(m_am_tools); + status = m_am_tools->convert_utf8_to_unicode(tmp_password_unicode, *password_utf8); + if (status != eap_status_ok) + { + delete clear_pw_block; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t pw_offset = EAP_MSCHAPV2_PASSWORD_MAX_SIZE - tmp_password_unicode.get_data_length(); + + // Fill begin of clear_pw_block with random octet values + status = m_rand.get_rand_bytes(clear_pw_block->password, pw_offset); + if (status != eap_status_ok) + { + delete clear_pw_block; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Copy password to end of clear_pw_block + m_am_tools->memmove( + clear_pw_block->password + pw_offset, + tmp_password_unicode.get_data(), + tmp_password_unicode.get_data_length()); + + // Password size must be little endian +#ifdef EAP_BIG_ENDIAN + u8_t * pw_bytes = reinterpret_cast(&pw_size); + u8_t tmp; + + tmp = bytes[0]; + bytes[0] = bytes[3]; + bytes[3] = tmp; + tmp = bytes[1]; + bytes[1] = bytes[2]; + bytes[2] = tmp; +#endif + + clear_pw_block->password_length = tmp_password_unicode.get_data_length(); + + status = rc4_encrypt( + reinterpret_cast(clear_pw_block), + sizeof(pw_block_s), + password_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE, + pw_block); + + delete clear_pw_block; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::rc4_encrypt( + const u8_t * const clear, + const u32_t clear_length, + const u8_t * const key, + const u32_t key_length, + u8_t * const cypher) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::rc4_encrypt(): this = 0x%08x\n"), + this)); + + if (!clear + || clear_length == 0 + || !key + || key_length == 0 + || !cypher) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_variable_data_c v_key(m_am_tools); + + eap_status_e status = v_key.set_buffer(key, key_length, false, false); // Cannot fail + if (status != eap_status_ok + || v_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + crypto_rc4_c rc4(m_am_tools); + + status = rc4.set_key(&v_key); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.encrypt_data(clear, cypher, clear_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::old_nt_password_hash_encrypted_with_new_nt_password_hash( + const eap_variable_data_c * const new_password_hash, + const eap_variable_data_c * const old_password_hash, + eap_variable_data_c * const encrypted_password_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::old_nt_password_hash_encrypted_with_new_nt_password_hash(): this = 0x%08x\n"), + this)); + + if (!new_password_hash + || !old_password_hash + || !encrypted_password_hash) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_status_e status = nt_password_hash_encrypted_with_block( + old_password_hash, + new_password_hash, + encrypted_password_hash); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::nt_password_hash_encrypted_with_block( + const eap_variable_data_c * const password_hash, + const eap_variable_data_c * const block, + eap_variable_data_c * const cypher) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::nt_password_hash_encrypted_with_block(): this = 0x%08x\n"), + this)); + + if (!password_hash + || !block + || !cypher) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_status_e status = cypher->set_buffer_length(EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = cypher->set_data_length(EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = des_encrypt( + password_hash->get_data(), // 1st 8-octets password_hash + block->get_data(), // 1st 7-octets block + cypher->get_data(EAP_MSCHAPV2_DES_BLOCK_SIZE)); // giving 1st 8-octets cypher + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = des_encrypt( + password_hash->get_data_offset(8,8), // 2nd 8-octets password_hash + block->get_data_offset(7,7), // 2nd 7-octets block + cypher->get_data_offset(8,EAP_MSCHAPV2_DES_BLOCK_SIZE)); // giving 2nd 8-octets cypher + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_type_mschapv2_c::generate_session_key( + eap_master_session_key_c * const key) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::generate_session_key(): this = 0x%08x\n"), + this)); + + eap_status_e status(eap_status_ok); + + eap_variable_data_c master_key(m_am_tools); + if (master_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + crypto_nt_hash_c nt_hash(m_am_tools); + if (nt_hash.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c nt_response(m_am_tools); + if (nt_response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = nt_response.set_buffer( + m_nt_response, + EAP_MSCHAPV2_NT_RESPONSE_SIZE, + false, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = nt_hash.get_master_key( + &m_password_hash_hash, + &nt_response, + &master_key, + EAP_MSCHAPV2_MASTER_KEY_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), master_key"), + master_key.get_data(), + master_key.get_data_length())); + + eap_variable_data_c asymmetric_start_key(m_am_tools); + + if (asymmetric_start_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_full_key == true) + { + eap_variable_data_c session_key_2(m_am_tools); + + if (session_key_2.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = nt_hash.get_asymmetric_start_key( + &master_key, + &asymmetric_start_key, + EAP_MSCHAPV2_MASTER_KEY_SIZE, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), asymmetric_start_key_1"), + asymmetric_start_key.get_data(), + asymmetric_start_key.get_data_length())); + + status = key->set_copy_of_buffer(&asymmetric_start_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = nt_hash.get_asymmetric_start_key( + &master_key, + &asymmetric_start_key, + EAP_MSCHAPV2_MASTER_KEY_SIZE, + true, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), asymmetric_start_key_2"), + asymmetric_start_key.get_data(), + asymmetric_start_key.get_data_length())); + + status = key->add_data(&asymmetric_start_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + status = nt_hash.get_asymmetric_start_key( + &master_key, + &asymmetric_start_key, + EAP_MSCHAPV2_MASTER_KEY_SIZE, + true, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), asymmetric_start_key_2"), + asymmetric_start_key.get_data(), + asymmetric_start_key.get_data_length())); + + status = key->set_copy_of_buffer(&asymmetric_start_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_client.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_client.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1753 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 94 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_base_type.h" +#include "eap_state_notification.h" +#include "eap_type_mschapv2.h" +#include "eap_am_type_mschapv2.h" +#include "eap_buffer.h" +#include "eap_master_session_key.h" +#include "eap_network_id_selector.h" +#include "eap_tlv_message_data.h" +#include "eap_config.h" + + +eap_status_e eap_type_mschapv2_c::client_packet_process( + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::client_packet_process(): this = 0x%08x, m_session.get_state()=%d\n"), + this, + m_session.get_state())); + + eap_status_e status = eap_status_drop_packet_quietly; + + m_identifier = received_eap->get_identifier(); + + if (received_eap->get_type() == eap_type_identity) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + if (received_eap->get_code() == eap_code_failure) + { + if (m_session.is_valid_state(eap_type_mschapv2_state_failure) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + status = finish_unsuccessful_authentication(false); + + m_session.set_state(eap_type_mschapv2_state_failure); + } + else if (received_eap->get_code() == eap_code_success) + { + if (m_session.is_valid_state(eap_type_mschapv2_state_success) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + eap_master_session_key_c key( + m_am_tools, + eap_type_mschapv2); + if (key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = generate_session_key(&key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_type_partner()->packet_data_crypto_keys(&m_send_network_id, &key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Check wait for eap success + + status = finish_successful_authentication(); + + m_session.set_state(eap_type_mschapv2_state_success); + } + else if (received_eap->get_code() == eap_code_request) // Request + { + // MsChapV2 + if (received_eap->get_type() == eap_type_mschapv2) + { + status = client_mschapv2_packet_process( + received_eap, + eap_packet_length); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +eap_status_e eap_type_mschapv2_c::client_mschapv2_packet_process( + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::client_mschapv2_packet_process(): this = 0x%08x\n"), + this)); + + eap_status_e status = eap_status_drop_packet_quietly; + + if (eap_packet_length <= eap_header_base_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else if (eap_packet_length == received_eap->get_data_length()) + { + // MsChapV2 packet without any data, unspecified packet? + // lets finish unsuccesfully? + if (m_session.is_valid_state(eap_type_mschapv2_state_failure) == true) + { + status = finish_unsuccessful_authentication(false); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t type_data_length = received_eap->get_type_data_length(); + + if (received_eap->get_type_data_offset(0, type_data_length) == 0) + { + // Not enough data. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + mschapv2_header_c mschapv2_header( + m_am_tools, + received_eap->get_type_data_offset(0, type_data_length), + type_data_length); + + if (mschapv2_header.check_header() != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + switch (mschapv2_header.get_opcode()) + { + case mschapv2_opcode_challenge: + if (m_session.is_valid_state(eap_type_mschapv2_state_challenge_request) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + status = client_handle_challenge_request(mschapv2_header); + break; + + case mschapv2_opcode_success: + if (m_session.is_valid_state(eap_type_mschapv2_state_success_request) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + status = client_handle_success_request(mschapv2_header); + break; + + case mschapv2_opcode_failure: + if (m_session.is_valid_state(eap_type_mschapv2_state_failure_request) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + status = client_handle_failure_request(mschapv2_header); + break; + + default: + break; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +eap_status_e eap_type_mschapv2_c::client_handle_challenge_request(mschapv2_header_c &challenge_request) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::client_handle_challenge_request(): this = 0x%08x\n"), + this)); + + eap_status_e status = eap_status_drop_packet_quietly; + + if (challenge_request.get_data_length() < mschapv2_challenge_c::get_header_minimum_size()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_mschapv2id = challenge_request.get_mschapv2_id(); + + mschapv2_challenge_c challenge_payload( + m_am_tools, + challenge_request.get_data(), + challenge_request.get_data_length()); + + if (challenge_payload.check_header() != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("client_handle_challenge_request(): mschapv2id"), + &m_mschapv2id, + sizeof(m_mschapv2id))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("client_handle_challenge_request(): m_authenticator_challenge"), + challenge_payload.get_challenge(), + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + m_am_tools->memmove( + m_authenticator_challenge, + challenge_payload.get_challenge(), + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE); + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true) + { + // Note the received authenticator challenge is zero bytes in EAP-FAST. + if (m_server_EAP_FAST_challenge.get_is_valid_data() == false + || m_server_EAP_FAST_challenge.get_data_length() != EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + m_am_tools->memmove( + m_authenticator_challenge, + m_server_EAP_FAST_challenge.get_data(), + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("client_handle_challenge_request(): EAP-FAST m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + // If no identity, ask it + if (!m_identity_asked + && (m_password_prompt_enabled + || m_username_utf8.get_is_valid_data() == false)) + { + // Prefill username with identity if it is possible + if (m_username_utf8.get_is_valid_data() == false) + { + status = get_type_partner()->get_saved_eap_identity(&m_username_utf8); + } + + // Open username/password dialog + status = m_am_type_mschapv2->show_username_password_dialog( + m_username_utf8, + m_password_utf8, + m_password_prompt_enabled, + false); + } + else + { + status = client_send_challenge_response(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +eap_status_e eap_type_mschapv2_c::client_send_challenge_response() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::client_send_challenge_response(): this = 0x%08x\n"), + this)); + + eap_status_e status = m_rand.add_rand_seed_hw_ticks(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true + && m_client_EAP_FAST_challenge.get_is_valid_data() == true + && m_client_EAP_FAST_challenge.get_data_length() == EAP_MSCHAPV2_PEER_CHALLENGE_SIZE) + { + m_am_tools->memmove( + m_peer_challenge, + m_client_EAP_FAST_challenge.get_data(), + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + status = m_rand.get_rand_bytes(m_peer_challenge, EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + crypto_nt_hash_c nt_hash(m_am_tools); + if (nt_hash.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_do_wrong_password_tests == true) + { + u8_t crap_from_stack; + status = m_password_utf8.add_data(&crap_from_stack, sizeof(crap_from_stack)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = nt_hash.nt_password_hash( + &m_password_utf8, + &m_password_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = nt_hash.hash_nt_password_hash( + &m_password_hash, + &m_password_hash_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), m_password_utf8"), + m_password_utf8.get_data(), + m_password_utf8.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), m_peer_challenge"), + m_peer_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), m_password_hash"), + m_password_hash.get_data(), + m_password_hash.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), m_username_utf8"), + m_username_utf8.get_data(), + m_username_utf8.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(): m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + status = generate_nt_response( + m_authenticator_challenge, + m_peer_challenge, + m_username_utf8.get_data(), + m_username_utf8.get_data_length(), + &m_password_hash, + m_nt_response); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), m_nt_response:"), + m_nt_response, + EAP_MSCHAPV2_NT_RESPONSE_SIZE)); + + // Send response + + const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length + + mschapv2_response_c::get_header_minimum_size() + + m_username_utf8.get_data_length(); + + const u32_t packet_length + = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + type_data_length; + + eap_buf_chain_wr_c * packet = create_send_packet(packet_length); + if (!packet) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_base_c eap_header( + m_am_tools, + packet->get_data_offset(m_offset, packet_length), + packet_length); + if (eap_header.get_is_valid() == false) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + eap_header.set_code(eap_code_response); + eap_header.set_identifier(m_identifier); + eap_header.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + eap_header.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + eap_header.get_type_data_offset(0, eap_header.get_type_data_length()), + eap_header.get_type_data_length()); + + mschapv2_header.set_opcode(mschapv2_opcode_response); + mschapv2_header.set_mschapv2_id(m_mschapv2id); + mschapv2_header.set_ms_length(static_cast(type_data_length)); + + mschapv2_response_c response( + m_am_tools, + mschapv2_header.get_data(), + mschapv2_header.get_data_length()); + if (response.get_is_valid() == false) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = response.set_constants(); + if (status != eap_status_ok) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true) + { + // EAP-FAST sends peer challenge containing only zeroes. + response.set_peer_challenge(EAP_MSCHAPV2_ZERO_CHALLENGE); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + response.set_peer_challenge(m_peer_challenge); + } + + response.set_nt_response(m_nt_response); + + // Copy username to end of response packet + u32_t username_ascii_size = m_username_utf8.get_data_length(); + response.set_name(m_username_utf8.get_data(username_ascii_size)); + + // Send + status = packet_send(packet, packet_length); + + delete packet; + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_session.set_state(eap_type_mschapv2_state_challenge_request); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +eap_status_e eap_type_mschapv2_c::client_handle_success_request(mschapv2_header_c & success_request) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::client_handle_success_request(): this = 0x%08x\n"), + this)); + + eap_status_e status = eap_status_drop_packet_quietly; + + if (success_request.get_data_length() < EAP_MSCHAPV2_SUCCESS_REQUEST_MESSAGE_MIN_LENGTH) // Check this out + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_mschapv2id = success_request.get_mschapv2_id(); + + u8_t * success_payload = success_request.get_data(); + bool response_check; + + eap_variable_data_c new_password_hash(m_am_tools); + eap_variable_data_c new_password_hash_hash(m_am_tools); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("client_handle_success_request(): m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("client_handle_success_request(): m_peer_challenge"), + m_peer_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("client_handle_success_request(): m_nt_response"), + m_nt_response, + EAP_MSCHAPV2_NT_RESPONSE_SIZE)); + + if (m_session.get_state() == eap_type_mschapv2_state_change_password_request) + { + // Here we need to generate password hashes from new_password + + crypto_nt_hash_c nt_hash(m_am_tools); + if (nt_hash.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = nt_hash.nt_password_hash( + &m_password_utf8, + &new_password_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = nt_hash.hash_nt_password_hash( + &new_password_hash, + &new_password_hash_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = check_authenticator_response( + &new_password_hash_hash, + m_nt_response, + m_peer_challenge, + m_authenticator_challenge, + m_username_utf8.get_data(), + m_username_utf8.get_data_length(), + success_payload, + response_check); + } + else + { + status = check_authenticator_response( + &m_password_hash_hash, + m_nt_response, + m_peer_challenge, + m_authenticator_challenge, + m_username_utf8.get_data(), + m_username_utf8.get_data_length(), + success_payload, + response_check); + } + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (response_check) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_handle_success_request(): mschapv2_opcode_success, authenticator_response correct\n"))); + + // Check if earlier state was password change + if (m_session.get_state() == eap_type_mschapv2_state_change_password_request) + { + if (m_password_prompt_enabled == false) + { + // Save new password + status = m_am_type_mschapv2->update_username_password(); + } + + // Save new hashes + status = m_password_hash.set_copy_of_buffer(&new_password_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_password_hash_hash.set_copy_of_buffer(&new_password_hash_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // Send success response + + // Return value will be not checked. If fails we still try to finish authentication + status = send_success_failure_response(true); + + if (m_wait_eap_success == false) + { + status = finish_successful_authentication(); + m_session.set_state(eap_type_mschapv2_state_success); + } + else + { + m_session.set_state(eap_type_mschapv2_state_success_request); + } + } + else // drop + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_handle_success_request(): mschapv2_opcode_success, authenticator_response incorrect\n"))); + + status = eap_status_drop_packet_quietly; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +eap_status_e eap_type_mschapv2_c::client_handle_failure_request(mschapv2_header_c & failure_request) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::client_handle_failure_request(): this = 0x%08x\n"), + this)); + + eap_status_e status = eap_status_drop_packet_quietly; + + u32_t buffer_left = failure_request.get_data_length(); + if (buffer_left < EAP_MSCHAPV2_FAILURE_MIN_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + m_mschapv2id = failure_request.get_mschapv2_id(); + + const u8_t * buffer_ptr = failure_request.get_data(); + + // "E=" + if (*buffer_ptr != 'E' || *(buffer_ptr + 1) != '=') + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + buffer_ptr += 2; + buffer_left -= 2; + + while (buffer_left && *buffer_ptr == '0') + { + buffer_ptr++; + buffer_left--; + } + + if (buffer_left == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + const u8_t * error_code_str = buffer_ptr; + + while (buffer_left && *buffer_ptr != ' ') + { + if (*buffer_ptr < '0' || *buffer_ptr > '9') + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + buffer_ptr++; + buffer_left--; + } + + u32_t error_code_str_len = buffer_ptr - error_code_str; + if (buffer_left < 43 || error_code_str_len != 3 || *buffer_ptr != ' ') // " R=x C=<32 bytes> V=x", min 43 bytes + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + buffer_ptr++; + buffer_left--; + + // "R=" + if (*buffer_ptr != 'R' || *(buffer_ptr + 1) != '=') + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + bool retry_allowed = true; // value = 1 + if (*(buffer_ptr + 2) == '0') + { + retry_allowed = false; + } + else if (*(buffer_ptr + 2) != '1') + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + buffer_ptr += 4; + buffer_left -= 4; + + // "C=" + if (*buffer_ptr != 'C' || *(buffer_ptr + 1) != '=') + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + buffer_ptr += 2; + buffer_left -= 2; + + const u8_t * challenge_str = buffer_ptr; + u32_t i; + for (i = 0; i < EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE * 2; i++) + { + if ((*(buffer_ptr + i) >= '0' && *(buffer_ptr + i) <= '9') + || + (*(buffer_ptr + i) >= 'A' && *(buffer_ptr + i) <= 'F')) + { + continue; + } + break; + } + if (i != EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE * 2) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + buffer_ptr += EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE * 2; + buffer_left -= EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE * 2; + + if (*buffer_ptr != ' ' + || *(buffer_ptr + 1) != 'V' // " V=" + || *(buffer_ptr + 2) != '=') + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + buffer_ptr += 3; + buffer_left -= 3; + + while (buffer_left && *buffer_ptr == '0') + { + buffer_ptr++; + buffer_left--; + } + + if (buffer_left == 0 + || *buffer_ptr != '3') // Version must be 3 + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + u32_t error_code = + (*error_code_str - '0') * 100 + + (*(error_code_str + 1) - '0') * 10 + + (*(error_code_str + 2) - '0'); + m_error_code = error_code; + + { + u32_t length = EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE; + + status = m_am_tools->convert_hex_ascii_to_bytes( + challenge_str, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE * 2, + m_authenticator_challenge, + &length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (length != EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_handle_failure_request(): client got auth_challenge:"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_handle_failure_request(): client has peer_challenge:"), + m_peer_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + } + +#if defined(USE_USER_NOTIFICATIONS) + // Notification to user + eap_variable_data_c string(m_am_tools); + status = m_am_type_mschapv2->read_auth_failure_string(static_cast (m_error_code), string); + if (status == eap_status_ok) + { + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, // This must be used with eap_general_state_show_notification_string. + eap_type_mschapv2, + eap_state_none, + eap_general_state_show_notification_string, + m_identifier, + false); + notification.set_notification_string(&string, true); + get_type_partner()->state_notification(¬ification); + } +#endif //#if defined(USE_USER_NOTIFICATIONS) + + switch (m_error_code) + { + + case EAP_MSCHAPV2_ERROR_RESTRICTED_LOGON_HOURS: + case EAP_MSCHAPV2_ERROR_ACCT_DISABLED: + case EAP_MSCHAPV2_ERROR_NO_DIALIN_PERMISSION: + + // Notification to user + if (m_error_code == EAP_MSCHAPV2_ERROR_RESTRICTED_LOGON_HOURS) + { + send_error_notification(eap_status_restricted_logon_hours); + } + else if (m_error_code == EAP_MSCHAPV2_ERROR_ACCT_DISABLED) + { + send_error_notification(eap_status_account_disabled); + } + else if (m_error_code == EAP_MSCHAPV2_ERROR_NO_DIALIN_PERMISSION) + { + send_error_notification(eap_status_no_dialin_permission); + } + + // Send failure response + status = send_success_failure_response(false); // failure + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + break; + + case EAP_MSCHAPV2_ERROR_AUTHENTICATION_FAILURE: + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_handle_failure_request(): EAP_MSCHAPV2_ERROR_AUTHENTICATION_FAILURE\n"))); + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_handle_failure_request(): m_use_implicit_challenge = %d\n"), + m_use_implicit_challenge)); +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + if (retry_allowed == true +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + // Note, retry is supported only inside EAP-MsChapv2. + // Note, inside TTLS/plain-MsChapv2 the retry is not supported. Authentication will fail immediately. + && m_use_implicit_challenge == false +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + ) + { + m_is_pending = true; + + // Prompt for username/password + status = m_am_type_mschapv2->show_username_password_dialog( + m_username_utf8, + m_password_utf8, + m_password_prompt_enabled, + false); + } + else + { + // Notification to user + send_error_notification(eap_status_authentication_failure); + + // Send failure response + status = send_success_failure_response(false); + } + break; + + case EAP_MSCHAPV2_ERROR_PASSWD_EXPIRED: + case EAP_MSCHAPV2_ERROR_CHANGING_PASSWORD: + + if (m_error_code == EAP_MSCHAPV2_ERROR_PASSWD_EXPIRED) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_handle_failure_request(): EAP_MSCHAPV2_ERROR_PASSWD_EXPIRED\n"))); + } + else if (m_error_code == EAP_MSCHAPV2_ERROR_CHANGING_PASSWORD) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_handle_failure_request(): EAP_MSCHAPV2_ERROR_CHANGING_PASSWORD\n"))); + } + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: client_handle_failure_request(): m_use_implicit_challenge = %d\n"), + m_use_implicit_challenge)); +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + if ( +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + m_use_implicit_challenge == false + && +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + (m_error_code == EAP_MSCHAPV2_ERROR_PASSWD_EXPIRED + || (m_error_code == EAP_MSCHAPV2_ERROR_CHANGING_PASSWORD && retry_allowed))) + { + m_old_password_utf8.set_copy_of_buffer(&m_password_utf8); + + m_is_pending = true; + + m_session.set_state(eap_type_mschapv2_state_failure_request); + + // Prompt for password change + status = m_am_type_mschapv2->show_change_password_dialog( + m_username_utf8, + m_old_password_utf8, + m_password_utf8, + m_password_prompt_enabled); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // Retry not allowed + { + send_error_notification(eap_status_password_expired); + + status = send_success_failure_response(false); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + // Show message without retry + } + break; + + default: + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + }; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::eap_acknowledge( + const eap_am_network_id_c * const /* receive_network_id */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::eap_acknowledge(): this = 0x%08x\n"), + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::set_initial_eap_identifier( + const eap_am_network_id_c * const /*receive_network_id*/, + const u8_t /*initial_identifier*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::set_initial_eap_identifier(): this = 0x%08x\n"), + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::query_eap_identity( + const bool /*must_be_synchronous*/, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::query_eap_identity(): this = 0x%08x\n"), + this)); + + if (m_session.is_valid_state(eap_type_mschapv2_state_identity_request) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + m_identifier = eap_identifier; + + eap_status_e status; + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_type_mschapv2_c::query_eap_identity: m_identity_asked=%d, m_password_prompt_enabled=%d\n"), + m_identity_asked, m_password_prompt_enabled)); + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_type_mschapv2_c::query_eap_identity: user name length=%d, PW length=%d, m_is_pending=%d\n"), + m_username_utf8.get_data_length(), m_password_utf8.get_data_length(), m_is_pending)); + + if (m_identity_asked == false && // Only at first time username/password dialog is shown if needed + (m_username_utf8.get_is_valid_data() == false + || m_username_utf8.get_data_length() == 0 + || m_password_prompt_enabled == true)) + { + // Ask username and password + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: query_eap_identity(): m_username_utf8:"), + m_username_utf8.get_data(), + m_username_utf8.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: query_eap_identity(): m_password_utf8:"), + m_password_utf8.get_data(), + m_password_utf8.get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: query_eap_identity(): password length %d\n"), + m_password_utf8.get_buffer_length())); + + if (m_is_pending == false) + { + m_is_pending = true; + status = m_am_type_mschapv2->show_username_password_dialog( + m_username_utf8, + m_password_utf8, + m_password_prompt_enabled, + true); + if (status == eap_status_pending_request + || status == eap_status_completed_request) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: query_eap_identity(): identity query is already pending!.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); + } + } + + m_identity_asked = true; + + // If this is not the first query, use already stored identity information for reply + status = identity->set_copy_of_buffer(&m_username_utf8); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: query_eap_identity(): identity:"), + identity->get_data(), + identity->get_data_length())); + + m_session.set_state(eap_type_mschapv2_state_identity_request); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::complete_eap_identity_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: complete_eap_identity_query() m_username_utf8:"), + m_username_utf8.get_data(), + m_username_utf8.get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: complete_eap_identity_query(), password length %d\n"), + m_password_utf8.get_buffer_length())); + + m_identity_asked = true; + + m_session.set_state(eap_type_mschapv2_state_identity_request); + + eap_status_e status = get_type_partner()->complete_eap_identity_query( + &m_send_network_id, + &m_username_utf8, + m_identifier); + if (status != eap_status_ok) + { + m_session.set_state(eap_type_mschapv2_state_failure); + } + + m_is_pending = false; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +eap_status_e eap_type_mschapv2_c::send_success_failure_response(bool is_success_response) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::send_success_failure_response(): this = 0x%08x\n"), + this)); + + eap_status_e status = eap_status_allocation_error; + + u32_t packet_length + = EAP_MSCHAPV2_OPCODE_SIZE // OpCode is the only payload + + eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type); + + eap_buf_chain_wr_c * packet = create_send_packet(packet_length); + if (!packet) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_base_c eap_header( + m_am_tools, + packet->get_data_offset(m_offset, packet_length), + packet_length); + if (eap_header.get_is_valid() == false) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + eap_header.set_code(eap_code_response); + eap_header.set_identifier(m_identifier); + eap_header.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + eap_header.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + eap_header.get_type_data_offset(0, eap_header.get_type_data_length()), + eap_header.get_type_data_length()); + + if (is_success_response) + { + mschapv2_header.set_opcode(mschapv2_opcode_success); + m_session.set_state(eap_type_mschapv2_state_success_request); + } + else + { + mschapv2_header.set_opcode(mschapv2_opcode_failure); + m_session.set_state(eap_type_mschapv2_state_failure_request); + } + + status = packet_send(packet, packet_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: send_success_failure_response():\n"))); + + delete packet; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::complete_failure_retry_response() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::complete_failure_retry_response(): this = 0x%08x\n"), + this)); + + m_is_pending = false; + + eap_status_e status = m_rand.add_rand_seed_hw_ticks(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_rand.add_rand_seed( + m_password_utf8.get_data(), + m_password_utf8.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true + && m_client_EAP_FAST_challenge.get_is_valid_data() == true + && m_client_EAP_FAST_challenge.get_data_length() == EAP_MSCHAPV2_PEER_CHALLENGE_SIZE) + { + m_am_tools->memmove( + m_peer_challenge, + m_client_EAP_FAST_challenge.get_data(), + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + status = m_rand.get_rand_bytes( + m_peer_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + crypto_nt_hash_c nt_hash(m_am_tools); + if (nt_hash.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = nt_hash.nt_password_hash( + &m_password_utf8, + &m_password_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = nt_hash.hash_nt_password_hash( + &m_password_hash, + &m_password_hash_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: complete_failure_retry_response(), m_password_utf8"), + m_password_utf8.get_data(), + m_password_utf8.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: complete_failure_retry_response(), m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: complete_failure_retry_response(), m_peer_challenge"), + m_peer_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: complete_failure_retry_response(), m_password_hash"), + m_password_hash.get_data(), + m_password_hash.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: complete_failure_retry_response(), m_username_utf8"), + m_username_utf8.get_data(), + m_username_utf8.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: complete_failure_retry_response(): m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + + status = generate_nt_response( + m_authenticator_challenge, + m_peer_challenge, + m_username_utf8.get_data(), + m_username_utf8.get_data_length(), + &m_password_hash, + m_nt_response); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: complete_failure_retry_response(), m_nt_response:"), + m_nt_response, + EAP_MSCHAPV2_NT_RESPONSE_SIZE)); + + // Send response + + const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length + + mschapv2_response_c::get_header_minimum_size() + + m_username_utf8.get_data_length(); + + const u32_t packet_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + type_data_length; + + eap_buf_chain_wr_c * packet = create_send_packet(packet_length); + + if (!packet) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + eap_header_base_c eap_header( + m_am_tools, + packet->get_data_offset(m_offset, packet_length), + packet_length); + if (eap_header.get_is_valid() == false) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + eap_header.set_code(eap_code_response); + eap_header.set_identifier(m_identifier); + eap_header.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + eap_header.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + eap_header.get_type_data_offset(0, eap_header.get_type_data_length()), + eap_header.get_type_data_length()); + + mschapv2_header.set_opcode(mschapv2_opcode_response); + mschapv2_header.set_mschapv2_id(++m_mschapv2id); + mschapv2_header.set_ms_length(static_cast(type_data_length)); + + mschapv2_response_c response( + m_am_tools, + mschapv2_header.get_data(), + mschapv2_header.get_data_length()); + if (response.get_is_valid() == false) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = response.set_constants(); + if (status != eap_status_ok) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + response.set_nt_response(m_nt_response); + response.set_peer_challenge(m_peer_challenge); + response.set_name(m_username_utf8.get_data()); + + // Send + status = packet_send(packet, packet_length); + delete packet; + + m_session.set_state(eap_type_mschapv2_state_challenge_request); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::complete_change_password_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_c::complete_change_password_query(): this = 0x%08x\n"), + this)); + + eap_status_e status = eap_status_process_general_error; + + m_is_pending = false; + + status = m_rand.add_rand_seed_hw_ticks(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_rand.add_rand_seed( + m_password_utf8.get_data(), + m_password_utf8.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true + && m_client_EAP_FAST_challenge.get_is_valid_data() == true + && m_client_EAP_FAST_challenge.get_data_length() == EAP_MSCHAPV2_PEER_CHALLENGE_SIZE) + { + m_am_tools->memmove( + m_peer_challenge, + m_client_EAP_FAST_challenge.get_data(), + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + status = m_rand.get_rand_bytes(m_peer_challenge, EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + u8_t * encrypted_pw_block = new u8_t[sizeof(pw_block_s)]; + if (!encrypted_pw_block) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c new_password_hash(m_am_tools); + + crypto_nt_hash_c nt_hash(m_am_tools); + if (nt_hash.get_is_valid() == false) + { + delete [] encrypted_pw_block; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = nt_hash.nt_password_hash( + &m_password_utf8, + &new_password_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + delete [] encrypted_pw_block; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = new_password_encrypted_with_old_nt_password_hash( + &m_password_utf8, + &m_password_hash, + encrypted_pw_block); + if (status != eap_status_ok) + { + delete [] encrypted_pw_block; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c encrypted_pw_hash(m_am_tools); + + status = old_nt_password_hash_encrypted_with_new_nt_password_hash( + &new_password_hash, + &m_password_hash, + &encrypted_pw_hash); + if (status != eap_status_ok) + { + delete [] encrypted_pw_block; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_change_password_query(): m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + status = generate_nt_response( + m_authenticator_challenge, + m_peer_challenge, + m_username_utf8.get_data(), + m_username_utf8.get_data_length(), + &new_password_hash, + m_nt_response); + if (status != eap_status_ok) + { + delete [] encrypted_pw_block; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length + + mschapv2_change_password_c::get_header_minimum_size(); + + const u32_t packet_length + = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + type_data_length; + + + eap_buf_chain_wr_c * packet = create_send_packet(packet_length); + if (!packet) + { + delete [] encrypted_pw_block; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_base_c eap_header( + m_am_tools, + packet->get_data_offset(m_offset, packet_length), + packet_length); + if (eap_header.get_is_valid() == false) + { + delete [] encrypted_pw_block; + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + eap_header.set_code(eap_code_response); + eap_header.set_identifier(m_identifier); + eap_header.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + eap_header.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + eap_header.get_type_data_offset(0, eap_header.get_type_data_length()), + eap_header.get_type_data_length()); + + mschapv2_header.set_opcode(mschapv2_opcode_change_password); + mschapv2_header.set_mschapv2_id(static_cast((++m_mschapv2id))); + mschapv2_header.set_ms_length(static_cast(type_data_length)); + + mschapv2_change_password_c response( + m_am_tools, + mschapv2_header.get_data(), + mschapv2_header.get_data_length()); + if (response.get_is_valid() == false) + { + delete [] encrypted_pw_block; + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = response.set_constants(); + if (status != eap_status_ok) + { + delete [] encrypted_pw_block; + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + response.set_encrypted_pw_block(encrypted_pw_block); + delete [] encrypted_pw_block; + response.set_encrypted_hash(encrypted_pw_hash.get_data()); + response.set_peer_challenge(m_peer_challenge); + response.set_nt_response(m_nt_response); + + // Send change password response + status = packet_send(packet, packet_length); + delete packet; + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_session.set_state(eap_type_mschapv2_state_change_password_request); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +// End of file. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_credential_store.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_credential_store.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 96 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "eap_am_memory.h" +#include "eap_type_mschapv2.h" +#include "eap_type_mschapv2_credential_store.h" + + +//-------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,466 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 97 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_type_mschapv2_header.h" +#include "eap_type_mschapv2_types.h" + + +//-------------------------------------------------------------- +//-------------------------------------------------------------- +//-------------------------------------------------------------- + + +EAP_FUNC_EXPORT mschapv2_header_c::~mschapv2_header_c() +{ +} + +EAP_FUNC_EXPORT mschapv2_header_c::mschapv2_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) + , m_length(header_buffer_length) +{ +} + +EAP_FUNC_EXPORT mschapv2_opcode_e mschapv2_header_c::get_opcode() const +{ + const u8_t * const opcode_data = get_header_offset(m_opcode_offset, sizeof(u8_t)); + if (opcode_data) + { + return static_cast(*opcode_data); + } + return mschapv2_opcode_unknown; // Packet will be dropped silently +} + +EAP_FUNC_EXPORT void mschapv2_header_c::set_opcode( + const mschapv2_opcode_e p_opcode) +{ + u8_t * const opcode_data = get_header_offset(m_opcode_offset, sizeof(u8_t)); + EAP_ASSERT(opcode_data != 0); + *opcode_data = static_cast(p_opcode); +} + +EAP_FUNC_EXPORT u8_t mschapv2_header_c::get_mschapv2_id() const +{ + const u8_t * const mschapv2_id_data = get_header_offset(m_mschapv2_id_offset, sizeof(u8_t)); + return *mschapv2_id_data; +} + +EAP_FUNC_EXPORT void mschapv2_header_c::set_mschapv2_id(u8_t p_id) +{ + u8_t * const mschapv2_id_data = get_header_offset(m_mschapv2_id_offset, sizeof(u8_t)); + EAP_ASSERT(mschapv2_id_data != 0); + *mschapv2_id_data = p_id; +} + +EAP_FUNC_EXPORT u16_t mschapv2_header_c::get_ms_length() const +{ + const u8_t * const length_data = get_header_offset(m_ms_length_offset, sizeof(u16_t)); + if (length_data != 0) + { + return static_cast((static_cast(length_data[0]) << 8 | static_cast(length_data[1]))); + } + else + { + return 0ul; + } +} + +EAP_FUNC_EXPORT void mschapv2_header_c::set_ms_length(u16_t p_length) +{ + u8_t * const length_data = get_header_offset(m_ms_length_offset, sizeof(u16_t)); + EAP_ASSERT(length_data != 0); + length_data[0] = static_cast(((p_length & 0xff00) >> 8)); + length_data[1] = static_cast((p_length & 0x00ff)); +} + +EAP_FUNC_EXPORT u8_t * mschapv2_header_c::get_data() const +{ + u8_t * const data_begin = get_header_offset(m_data_offset, 0); + return data_begin; +} + +EAP_FUNC_EXPORT u32_t mschapv2_header_c::get_data_length() const +{ + return m_length - m_data_offset; +} + +EAP_FUNC_EXPORT eap_status_e mschapv2_header_c::check_header() const +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------------------- +//-------------------------------------------------------------- +//-------------------------------------------------------------- + + +EAP_FUNC_EXPORT mschapv2_challenge_c::~mschapv2_challenge_c() +{ +} + +// Challenge +EAP_FUNC_EXPORT mschapv2_challenge_c::mschapv2_challenge_c( + abs_eap_am_tools_c * const tools, + void * const buffer, + const u32_t buffer_length) + : eap_general_header_base_c(tools, buffer, buffer_length) + , m_am_tools(tools) + , m_length(buffer_length) +{ +} + +EAP_FUNC_EXPORT u32_t mschapv2_challenge_c::get_header_minimum_size() +{ + return m_name_offset; +} + +EAP_FUNC_EXPORT eap_status_e mschapv2_challenge_c::check_header() const +{ + const u8_t * const value_size = get_header_offset(m_value_size_offset, sizeof(u8_t)); + if (*value_size == 0x10 && m_length >= 0x11) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); +} + +EAP_FUNC_EXPORT void mschapv2_challenge_c::set_value_size() +{ + u8_t * const value_size = get_header_offset(m_value_size_offset, sizeof(u8_t)); + EAP_ASSERT(value_size != 0); + *value_size = static_cast(0x10); +} + +EAP_FUNC_EXPORT const u8_t * mschapv2_challenge_c::get_challenge() const +{ + const u8_t * const challenge = get_header_offset(m_challenge_offset, sizeof(u8_t)); + return challenge; +} + +EAP_FUNC_EXPORT void mschapv2_challenge_c::set_challenge(const u8_t * const p_challenge) +{ + u8_t * const challenge = get_header_offset(m_challenge_offset, 16); + if (challenge != 0) + { + m_am_tools->memmove(challenge, p_challenge, 16); + } +} + +EAP_FUNC_EXPORT const u8_t * mschapv2_challenge_c::get_name() const +{ + const u8_t * const name = get_header_offset(m_name_offset, sizeof(u8_t)); + return name; +} + +EAP_FUNC_EXPORT u32_t mschapv2_challenge_c::get_name_length() const +{ + return m_length - m_name_offset; +} + +EAP_FUNC_EXPORT void mschapv2_challenge_c::set_name(const u8_t * const p_name) +{ + u8_t * const name = get_header_offset(m_name_offset, sizeof(u8_t)); + if (name != 0) + { + m_am_tools->memmove(name, p_name, m_length - m_name_offset); + } +} + + +//-------------------------------------------------------------- +//-------------------------------------------------------------- +//-------------------------------------------------------------- + + +// Change password + +EAP_FUNC_EXPORT mschapv2_change_password_c::~mschapv2_change_password_c() +{ +} + +EAP_FUNC_EXPORT mschapv2_change_password_c::mschapv2_change_password_c( + abs_eap_am_tools_c * const tools, + void * const buffer, + const u32_t buffer_length) + : eap_general_header_base_c(tools, buffer, buffer_length) + , m_am_tools(tools) + , m_length(buffer_length) +{ +} + +EAP_FUNC_EXPORT u32_t mschapv2_change_password_c::get_header_minimum_size() +{ + return m_flags_offset + EAP_MSCHAPV2_CHANGE_PASSWORD_FLAGS_SIZE; +} + +EAP_FUNC_EXPORT eap_status_e mschapv2_change_password_c::check_header() const +{ + const u8_t * const reserved = get_header_offset(m_reserved_offset, 8); + const u8_t * const flags = get_header_offset(m_flags_offset, 2); + if (!reserved || !flags) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t zero[8]; + m_am_tools->memset(zero, 0, 8); + + if (m_length >= m_flags_offset + 2 + && m_am_tools->memcmp(reserved, &zero, 8) == 0 + && m_am_tools->memcmp(flags, &zero, 2) == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); +} + +EAP_FUNC_EXPORT const u8_t * mschapv2_change_password_c::get_encrypted_pw_block() const +{ + const u8_t * const encrypted_pw_block = get_header_offset(m_encrypted_pw_block_offset, 516); + return encrypted_pw_block; +} + +EAP_FUNC_EXPORT void mschapv2_change_password_c::set_encrypted_pw_block(const u8_t * const p_encrypted_pw_block) +{ + u8_t * const encrypted_pw_block = get_header_offset(m_encrypted_pw_block_offset, 516); + if (encrypted_pw_block != 0) + { + m_am_tools->memmove(encrypted_pw_block, p_encrypted_pw_block, 516); + } +} + +EAP_FUNC_EXPORT const u8_t * mschapv2_change_password_c::get_encrypted_hash() const +{ + const u8_t * const encrypted_hash = get_header_offset(m_encrypted_hash_offset, 16); + return encrypted_hash; +} + +EAP_FUNC_EXPORT void mschapv2_change_password_c::set_encrypted_hash(const u8_t * const p_encrypted_hash) +{ + u8_t * const encrypted_hash = get_header_offset(m_encrypted_hash_offset, 16); + if (encrypted_hash != 0) + { + m_am_tools->memmove(encrypted_hash, p_encrypted_hash, 16); + } +} + +EAP_FUNC_EXPORT const u8_t * mschapv2_change_password_c::get_peer_challenge() const +{ + const u8_t * const peer_challenge = get_header_offset(m_peer_challenge_offset, 16); + return peer_challenge; +} + +EAP_FUNC_EXPORT void mschapv2_change_password_c::set_peer_challenge(const u8_t * const p_peer_challenge) +{ + u8_t * const peer_challenge = get_header_offset(m_peer_challenge_offset, 16); + if (peer_challenge != 0) + { + m_am_tools->memmove(peer_challenge, p_peer_challenge, 16); + } +} + +EAP_FUNC_EXPORT const u8_t * mschapv2_change_password_c::get_nt_response() const +{ + const u8_t * const nt_response = get_header_offset(m_nt_response_offset, 24); + return nt_response; +} + +EAP_FUNC_EXPORT void mschapv2_change_password_c::set_nt_response(const u8_t * const p_nt_response) +{ + u8_t * const nt_response = get_header_offset(m_nt_response_offset, 24); + if (nt_response != 0) + { + m_am_tools->memmove(nt_response, p_nt_response, 24); + } +} + +EAP_FUNC_EXPORT eap_status_e mschapv2_change_password_c::set_constants() +{ + u8_t * const reserved = get_header_offset(m_reserved_offset, 8); + if (reserved == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u8_t * const flags = get_header_offset(m_flags_offset, sizeof(u8_t)); + if (flags == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memset(reserved, 0, 8); + m_am_tools->memset(flags, 0, 2); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------------------- +//-------------------------------------------------------------- +//-------------------------------------------------------------- + + +// Challenge response packet +EAP_FUNC_EXPORT mschapv2_response_c::~mschapv2_response_c() +{ +} + +EAP_FUNC_EXPORT mschapv2_response_c::mschapv2_response_c( + abs_eap_am_tools_c * const tools, + void * const buffer, + const u32_t buffer_length) + : eap_general_header_base_c(tools, buffer, buffer_length) + , m_am_tools(tools) + , m_length(buffer_length) +{ +} + +EAP_FUNC_EXPORT u32_t mschapv2_response_c::get_header_minimum_size() +{ + return m_name_offset; +} + +EAP_FUNC_EXPORT eap_status_e mschapv2_response_c::check_header() const +{ + const u8_t * const reserved = get_header_offset(m_reserved_offset, 8); + const u8_t * const flags = get_header_offset(m_flags_offset, sizeof(u8_t)); + if (!reserved || !flags) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t zero[8]; + m_am_tools->memset(zero, 0, 8); + + if (m_length >= m_flags_offset + 1 + && m_am_tools->memcmp(reserved, &zero, 8) == 0 + && *flags == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); +} + +EAP_FUNC_EXPORT const u8_t * mschapv2_response_c::get_peer_challenge() const +{ + const u8_t * const peer_challenge = get_header_offset(m_peer_challenge_offset, sizeof(u8_t)); + return peer_challenge; +} + +EAP_FUNC_EXPORT void mschapv2_response_c::set_peer_challenge(const u8_t * const p_peer_challenge) +{ + u8_t * const peer_challenge = get_header_offset(m_peer_challenge_offset, 16); + if (peer_challenge != 0) + { + m_am_tools->memmove(peer_challenge, p_peer_challenge, 16); + } +} + +EAP_FUNC_EXPORT const u8_t * mschapv2_response_c::get_nt_response() const +{ + const u8_t * const nt_response = get_header_offset(m_nt_response_offset, 24); + return nt_response; +} + +EAP_FUNC_EXPORT void mschapv2_response_c::set_nt_response(const u8_t * const p_nt_response) +{ + u8_t * const nt_response = get_header_offset(m_nt_response_offset, 24); + if (nt_response != 0) + { + m_am_tools->memmove(nt_response, p_nt_response, 24); + } +} + +EAP_FUNC_EXPORT const u8_t * mschapv2_response_c::get_name() const +{ + const u8_t * const name = get_header_offset(m_name_offset, sizeof(u8_t)); + return name; +} + +EAP_FUNC_EXPORT u32_t mschapv2_response_c::get_name_length() const +{ + return m_length - m_name_offset; +} + +EAP_FUNC_EXPORT void mschapv2_response_c::set_name(const u8_t * const p_name) +{ + u8_t * const name = get_header_offset(m_name_offset, sizeof(u8_t)); + if (name != 0) + { + m_am_tools->memmove(name, p_name, m_length - m_name_offset); + } +} + +EAP_FUNC_EXPORT eap_status_e mschapv2_response_c::set_constants() +{ + { + u8_t * const value_size = get_header_offset(m_value_size_offset, 8); + if (value_size == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memset(value_size, 0x31, 1); + } + + { + u8_t * const reserved = get_header_offset(m_reserved_offset, 8); + if (reserved == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memset(reserved, 0, 8); + } + + if (m_length > m_flags_offset) + { + u8_t * const flags = get_header_offset(m_flags_offset, sizeof(u8_t)); + if (flags == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memset(flags, 0, 1); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------------------- +//-------------------------------------------------------------- +//-------------------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_payloads.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_payloads.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,117 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 98 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +//#include "eap_tools.h" +#include "eap_type_mschapv2_payloads.h" + +EAP_FUNC_EXPORT mschapv2_data_c::mschapv2_data_c(abs_eap_am_tools_c * const tools) + : m_username(tools) + , m_password(tools) + , m_challenge(tools) + , m_peer_challenge(tools) + , m_identifier(1) + , m_mschapv2id(1) + , m_error_code(0) + , m_password_prompt_enabled(eap_boolean_true) + , m_nt_response(tools) + , m_new_password(tools) +{ +} + +EAP_FUNC_EXPORT mschapv2_data_c::~mschapv2_data_c() +{ +}; + +eap_boolean_e mschapv2_data_c::get_password_prompt_enabled() const +{ + return m_password_prompt_enabled; +} + +void mschapv2_data_c::set_password_prompt_enabled(eap_boolean_e is_enabled) +{ + m_password_prompt_enabled = is_enabled; +} + +eap_variable_data_c * const mschapv2_data_c::get_username() +{ + return &m_username; +} + +eap_variable_data_c * const mschapv2_data_c::get_password() +{ + return &m_password; +} + +eap_variable_data_c * const mschapv2_data_c::get_challenge() +{ + return &m_challenge; +} + +eap_variable_data_c * const mschapv2_data_c::get_peer_challenge() +{ + return &m_peer_challenge; +} + +// Client +eap_variable_data_c * const mschapv2_data_c::get_nt_response() +{ + return &m_nt_response; +} + +eap_variable_data_c * const mschapv2_data_c::get_new_password() +{ + return &m_new_password; +} + +u8_t mschapv2_data_c::get_identifier() const +{ + return m_identifier; +} + +void mschapv2_data_c::set_identifier(u8_t identifier) +{ + m_identifier = identifier; +} + +u8_t mschapv2_data_c::get_mschapv2id() const +{ + return m_mschapv2id; +} + +void mschapv2_data_c::set_mschapv2id(u8_t mschapv2id) +{ + m_mschapv2id = mschapv2id; +} + +u32_t mschapv2_data_c::get_error_code() const +{ + return m_error_code; +} + +void mschapv2_data_c::set_error_code(u32_t error_code) +{ + m_error_code = error_code; +} diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_server.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_server.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1406 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 99 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_type_mschapv2.h" +#include "eap_buffer.h" +#include "eap_master_session_key.h" +#include "eap_network_id_selector.h" +#include "eap_tlv_message_data.h" +#include "eap_automatic_variable.h" + + +#if defined(EAP_MSCHAPV2_SERVER) + +eap_status_e eap_type_mschapv2_c::server_packet_process( + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_drop_packet_quietly; + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + if (m_session.get_state() != eap_type_mschapv2_state_none + && m_use_implicit_challenge == false + && m_identifier != received_eap->get_identifier()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else + { + m_identifier = received_eap->get_identifier(); + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + if (received_eap->get_type() == eap_type_identity) + { + status = handle_identity_response_message(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (received_eap->get_code() == eap_code_success + || received_eap->get_code() == eap_code_failure) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else if (received_eap->get_code() == eap_code_response) // Response + { + if (eap_packet_length <= eap_header_base_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + // MsChapV2 + if (received_eap->get_type() == eap_type_mschapv2) + { + status = server_mschapv2_packet_process( + received_eap, + eap_packet_length); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + +#if defined(EAP_MSCHAPV2_SERVER) + +eap_status_e eap_type_mschapv2_c::server_mschapv2_packet_process( + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_drop_packet_quietly; + + u32_t type_data_length = received_eap->get_type_data_length(); + + mschapv2_header_c mschapv2_header( + m_am_tools, + received_eap->get_type_data_offset(0, type_data_length), + type_data_length); + + if (mschapv2_header.check_header() != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + if (eap_packet_length <= eap_header_base_c::get_header_length()) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAP_type_MSCHAPV2: illegal mschapv2 packet length\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + if ((mschapv2_header.get_opcode() == mschapv2_opcode_response + || mschapv2_header.get_opcode() == mschapv2_opcode_change_password) + && type_data_length != mschapv2_header.get_ms_length()) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAP_type_MSCHAPV2: illegal mschapv2 packet length\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + switch (mschapv2_header.get_opcode()) + { + case mschapv2_opcode_response: + status = server_handle_challenge_response(mschapv2_header); + break; + + case mschapv2_opcode_success: + status = server_handle_success_response(); + break; + + case mschapv2_opcode_failure: + status = server_handle_failure_response(); + break; + + case mschapv2_opcode_change_password: + status = server_handle_password_change(mschapv2_header); + break; + + default: + break; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + +#if defined(EAP_MSCHAPV2_SERVER) + +bool eap_type_mschapv2_c::check_expired_password() +{ + if (m_do_password_expiration_tests == true) + { + if (m_password_expired == false) + { + m_password_expired = true; + } + else + { + m_password_expired = false; + } + + return m_password_expired; + } + + return false; +} + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + +#if defined(EAP_MSCHAPV2_SERVER) + +static const u8_t eap_mschapv2_challenge_response_message[] = "Message1"; +static const u8_t eap_mschapv2_failure_message[] = "Message3"; + + +eap_status_e eap_type_mschapv2_c::server_handle_challenge_response(mschapv2_header_c &machapv2_packet) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_header_corrupted; + + mschapv2_response_c response( + m_am_tools, + machapv2_packet.get_data(), + machapv2_packet.get_data_length()); + if (response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_challenge_response(): response packet:"), + response.get_header_buffer(response.get_header_buffer_length()), + response.get_header_buffer_length())); + + if (response.check_header() != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + if (!m_session.is_valid_state(eap_type_mschapv2_state_challenge_response)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + // Check username + m_am_tools->memmove( + m_peer_challenge, + response.get_peer_challenge(), + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true) + { + // Note the received authenticator challenge is zero bytes in EAP-FAST. + if (m_client_EAP_FAST_challenge.get_is_valid_data() == false + || m_client_EAP_FAST_challenge.get_data_length() != EAP_MSCHAPV2_PEER_CHALLENGE_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + m_am_tools->memmove( + m_peer_challenge, + m_client_EAP_FAST_challenge.get_data(), + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("client_handle_challenge_request(): EAP-FAST m_peer_challenge"), + m_peer_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + crypto_nt_hash_c nt_hash(m_am_tools); + if (nt_hash.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = nt_hash.nt_password_hash( + &m_password_utf8, + &m_password_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = nt_hash.hash_nt_password_hash( + &m_password_hash, + &m_password_hash_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_challenge_response(): m_password_utf8"), + m_password_utf8.get_data(), + m_password_utf8.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_challenge_response(): m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_challenge_response(): m_peer_challenge"), + m_peer_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_challenge_response(): m_password_hash"), + m_password_hash.get_data(), + m_password_hash.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_challenge_response(): m_username_utf8"), + m_username_utf8.get_data(), + m_username_utf8.get_data_length())); + + status = generate_nt_response( + m_authenticator_challenge, + m_peer_challenge, + m_username_utf8.get_data(), + m_username_utf8.get_data_length(), + &m_password_hash, + m_nt_response); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_challenge_response(): m_nt_response:"), + m_nt_response, + EAP_MSCHAPV2_NT_RESPONSE_SIZE)); + + // Check peer_response == nt_response + if (m_am_tools->memcmp( + m_nt_response, + response.get_nt_response(), + EAP_MSCHAPV2_NT_RESPONSE_SIZE) + == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_challenge_response(): correct password\n"))); + + // Is password expired? + if (check_expired_password() == true) + { + m_error_code = EAP_MSCHAPV2_ERROR_PASSWD_EXPIRED; + bool retry_allowed = true; // ? + + u32_t message_length = sizeof(eap_mschapv2_challenge_response_message) - 1; + + status = send_failure_request( + retry_allowed, + eap_mschapv2_challenge_response_message, + message_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_session.set_state(eap_type_mschapv2_state_challenge_response, eap_type_mschapv2_state_change_password_response); + + // Any other restrictions? + status = eap_status_ok; + } + else + { + u32_t message_length = sizeof(eap_mschapv2_challenge_response_message) - 1; + + status = send_success_request( + eap_mschapv2_challenge_response_message, + message_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_session.set_state(eap_type_mschapv2_state_challenge_response, eap_type_mschapv2_state_success_response); + status = eap_status_ok; + } + } + else // Incorrect password + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP_type_MSCHAPV2: server_handle_challenge_response(): incorrect password\n"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_challenge_response(): m_nt_response:"), + m_nt_response, + EAP_MSCHAPV2_NT_RESPONSE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_challenge_response(): response.get_nt_response():"), + response.get_nt_response(), + EAP_MSCHAPV2_NT_RESPONSE_SIZE)); + + m_error_code = EAP_MSCHAPV2_ERROR_AUTHENTICATION_FAILURE; + + bool retry_allowed = true; // TEST + + u32_t message_length = sizeof(eap_mschapv2_failure_message) - 1; + + status = send_failure_request( + retry_allowed, + eap_mschapv2_failure_message, + message_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true) + { + (void) send_error_notification(eap_status_tunnel_compromise_error); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + m_session.set_state(eap_type_mschapv2_state_challenge_response, eap_type_mschapv2_state_challenge_response); + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + +#if defined(EAP_MSCHAPV2_SERVER) + +eap_status_e eap_type_mschapv2_c::server_handle_success_response() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_drop_packet_quietly; + + if (m_session.is_valid_state(eap_type_mschapv2_state_success_response)) + { + eap_master_session_key_c key( + m_am_tools, + eap_type_mschapv2); + + status = generate_session_key(&key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_type_partner()->packet_data_crypto_keys(&m_send_network_id, &key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = finish_successful_authentication(); + + m_session.set_state(eap_type_mschapv2_state_success_response); + + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + +#if defined(EAP_MSCHAPV2_SERVER) + +eap_status_e eap_type_mschapv2_c::server_handle_failure_response() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (m_session.is_valid_state(eap_type_mschapv2_state_failure_response)) + { + finish_unsuccessful_authentication(false); + m_session.set_state(eap_type_mschapv2_state_failure_response); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); +} + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + +#if defined(EAP_MSCHAPV2_SERVER) + +static const u8_t eap_mschapv2_password_change_message[] = "Message4"; + +eap_status_e eap_type_mschapv2_c::server_handle_password_change(mschapv2_header_c &machapv2_packet) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (!m_session.is_valid_state(eap_type_mschapv2_state_change_password_response)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + if (machapv2_packet.get_data_length() < mschapv2_change_password_c::get_header_minimum_size()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + mschapv2_change_password_c change_password_payload( + m_am_tools, + machapv2_packet.get_data(), + machapv2_packet.get_data_length()); + if (change_password_payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (change_password_payload.check_header() != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + m_am_tools->memmove( + m_peer_challenge, + change_password_payload.get_peer_challenge(), + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true) + { + if (m_client_EAP_FAST_challenge.get_is_valid_data() == false + || m_client_EAP_FAST_challenge.get_data_length() != EAP_MSCHAPV2_PEER_CHALLENGE_SIZE + || m_client_EAP_FAST_challenge.compare(m_peer_challenge, EAP_MSCHAPV2_PEER_CHALLENGE_SIZE) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + // Encypted-Password has been made by NewPasswordEncryptedWithOldNtPassword() + eap_variable_data_c old_password_hash(m_am_tools); + + crypto_nt_hash_c nt_hash(m_am_tools); + if (nt_hash.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = nt_hash.nt_password_hash( + &m_password_utf8, + &old_password_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_variable_data_c tmp_password_unicode( + m_am_tools); + + eap_variable_data_c tmp_password_utf8( + m_am_tools); + + u8_t * new_password = 0; + + u32_t pw_size; + + { + pw_block_s * new_pw_block = new pw_block_s; + + eap_automatic_variable_c automatic_new_pw_block(m_am_tools, new_pw_block); + + if (!new_pw_block) + { + status = eap_status_allocation_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4_decrypt( + change_password_payload.get_encrypted_pw_block(), // cypher + sizeof(pw_block_s), + old_password_hash.get_data(EAP_MSCHAPV2_MD4_DIGEST_SIZE), // key + EAP_MSCHAPV2_MD4_DIGEST_SIZE, + reinterpret_cast(new_pw_block)); // plain + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#ifdef EAP_BIG_ENDIAN + pw_size = eap_ntohl(new_pw_block->password_length); +#else + pw_size = new_pw_block->password_length; +#endif + if (pw_size > EAP_MSCHAPV2_PASSWORD_MAX_SIZE) + { + const u32_t message_length = sizeof(eap_mschapv2_password_change_message) - 1; + m_error_code = EAP_MSCHAPV2_ERROR_CHANGING_PASSWORD; + bool retry_allowed = true; + + status = send_failure_request( + retry_allowed, + eap_mschapv2_password_change_message, + message_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_session.set_state(eap_type_mschapv2_state_change_password_response, eap_type_mschapv2_state_change_password_response); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + status = tmp_password_unicode.set_copy_of_buffer( + (reinterpret_cast(new_pw_block)) + EAP_MSCHAPV2_PASSWORD_MAX_SIZE - pw_size, // offset, + pw_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_am_tools->convert_unicode_to_utf8(tmp_password_utf8, tmp_password_unicode); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // Encrypted-Hash has been made by old_nt_password_hash_encrypted_with_new_password_hash() + + eap_variable_data_c new_password_hash(m_am_tools); + + status = nt_hash.nt_password_hash( + &tmp_password_utf8, + &new_password_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c encrypted_pw_hash(m_am_tools); + + status = old_nt_password_hash_encrypted_with_new_nt_password_hash( + &new_password_hash, + &m_password_hash, + &encrypted_pw_hash); + if (status != eap_status_ok) + { + delete [] new_password; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_am_tools->memcmp( + encrypted_pw_hash.get_data(EAP_MSCHAPV2_MD4_DIGEST_SIZE), + change_password_payload.get_encrypted_hash(), + EAP_MSCHAPV2_MD4_DIGEST_SIZE) == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_password_change(): password change accepted\n"))); + + // Checked + + // Store new password + status = m_password_utf8.set_copy_of_buffer(&tmp_password_utf8); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_password_hash.set_copy_of_buffer(&new_password_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = nt_hash.hash_nt_password_hash( + &m_password_hash, + &m_password_hash_hash, + EAP_MSCHAPV2_MD4_DIGEST_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("server_handle_password_change(): m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("server_handle_password_change(): m_peer_challenge"), + m_peer_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + + // Generate new nt_response + status = generate_nt_response( + m_authenticator_challenge, + m_peer_challenge, + m_username_utf8.get_data(), + m_username_utf8.get_data_length(), + &m_password_hash, + m_nt_response); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Send Success request + + u8_t message[] = ""; + u32_t message_length = 0; + + status = send_success_request( + message, + message_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_session.set_state(eap_type_mschapv2_state_change_password_response, eap_type_mschapv2_state_success_response); + } + else // Challenge response didn't match + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: server_handle_password_change(): password change NOT accepted\n"))); + + delete [] new_password; + + u32_t message_length = sizeof(eap_mschapv2_password_change_message) - 1; + m_error_code = EAP_MSCHAPV2_ERROR_CHANGING_PASSWORD; + bool retry_allowed = true; + + status = send_failure_request( + retry_allowed, + eap_mschapv2_password_change_message, + message_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_session.set_state(eap_type_mschapv2_state_change_password_response, eap_type_mschapv2_state_failure_response); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + +#if defined(EAP_MSCHAPV2_SERVER) + +EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::handle_identity_response_message() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + // Send challenge + + status = m_rand.add_rand_seed_hw_ticks(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true + && m_server_EAP_FAST_challenge.get_is_valid_data() == true + && m_server_EAP_FAST_challenge.get_data_length() == EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE) + { + m_am_tools->memmove( + m_authenticator_challenge, + m_server_EAP_FAST_challenge.get_data(), + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + if (m_use_implicit_challenge == true) + { + eap_variable_data_c memory_store_key(m_am_tools); + + eap_status_e status = memory_store_key.set_copy_of_buffer( + EAP_MSCHAPV2_IMPLICIT_CHALLENGE_HANDLE_KEY, + sizeof(EAP_MSCHAPV2_IMPLICIT_CHALLENGE_HANDLE_KEY)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = memory_store_key.add_data( + &m_is_client, + sizeof(m_is_client)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_am_network_id_c receive_network_id(m_am_tools, + m_send_network_id.get_destination_id(), + m_send_network_id.get_source_id(), + m_send_network_id.get_type()); + + eap_network_id_selector_c state_selector( + m_am_tools, + &receive_network_id); + + status = memory_store_key.add_data( + &state_selector); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_tlv_message_data_c tlv_data(m_am_tools); + + status = m_am_tools->memory_store_get_data( + &memory_store_key, + &tlv_data); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: handle_identity_response_message(): cannot get credentials\n"))); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: handle_identity_response_message(): credentials found\n"))); + + // Parse read data. + eap_array_c tlv_blocks(m_am_tools); + + status = tlv_data.parse_message_data(&tlv_blocks); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + bool implicit_challenge_read(false); + + for (u32_t ind = 0ul; ind < tlv_blocks.get_object_count(); ind++) + { + eap_tlv_header_c * const tlv = tlv_blocks.get_object(ind); + if (tlv != 0) + { + if (tlv->get_type() == eap_type_mschapv2_implicit_challenge) + { + m_am_tools->memmove( + m_authenticator_challenge, + tlv->get_value(tlv->get_value_length()), + tlv->get_value_length()); + + implicit_challenge_read = true; + } + } + } // for() + + if (implicit_challenge_read == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + } + } + else +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + { + status = m_rand.get_rand_bytes(m_authenticator_challenge, EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("handle_identity_response_message(): m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + const u32_t name_length = m_username_utf8.get_data_length(); + + const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length + + mschapv2_challenge_c::get_header_minimum_size() + + name_length; + + const u32_t packet_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + type_data_length; + + eap_buf_chain_wr_c * packet = create_send_packet(packet_length); + if (!packet) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_base_c eap_header( + m_am_tools, + packet->get_data_offset(m_offset, packet_length), + packet_length); + if (eap_header.get_is_valid() == false) + { + delete packet; + packet = 0; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + eap_header.set_code(eap_code_request); + eap_header.set_identifier(++m_identifier); + eap_header.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + eap_header.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + eap_header.get_type_data_offset(0, eap_header.get_type_data_length()), + eap_header.get_type_data_length()); + + mschapv2_header.set_opcode(mschapv2_opcode_challenge); + mschapv2_header.set_mschapv2_id(static_cast(++m_mschapv2id)); + mschapv2_header.set_ms_length(static_cast(type_data_length)); + + mschapv2_challenge_c challenge_packet( + m_am_tools, + mschapv2_header.get_data(), + mschapv2_header.get_data_length()); + if (challenge_packet.get_is_valid() == false) + { + delete packet; + packet = 0; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true) + { + // EAP-FAST sends authenticator challenge containing only zeroes. + challenge_packet.set_challenge(EAP_MSCHAPV2_ZERO_CHALLENGE); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + challenge_packet.set_challenge(m_authenticator_challenge); + } + + challenge_packet.set_value_size(); + challenge_packet.set_name(m_username_utf8.get_data(name_length)); + + // This must be set before packet_send() call to allow + // the plain MsChapv2 to work. + m_session.set_state(eap_type_mschapv2_state_identity_response); + + // Send packet + status = packet_send(packet, packet_length); + + delete packet; + packet = 0; + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + +#if defined(EAP_MSCHAPV2_SERVER) + +eap_status_e eap_type_mschapv2_c::send_failure_request( + const bool retry_allowed, + const u8_t * const message, + const u32_t message_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAP_type_MSCHAPV2: send_failure_request\n"))); + + u32_t retry = 0; + if (retry_allowed) + { + retry = 1; + } + + // Generate new auth_challenge + + eap_status_e status = m_rand.add_rand_seed_hw_ticks(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_challenge == true + && m_client_EAP_FAST_challenge.get_is_valid_data() == true + && m_client_EAP_FAST_challenge.get_data_length() == EAP_MSCHAPV2_PEER_CHALLENGE_SIZE) + { + m_am_tools->memmove( + m_peer_challenge, + m_client_EAP_FAST_challenge.get_data(), + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + status = m_rand.get_rand_bytes(m_authenticator_challenge, EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: send_failure_request(): m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_MSCHAPV2: send_failure_request(): m_peer_challenge"), + m_peer_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + + u8_t * auth_challenge_str = new u8_t[EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE * 2]; + if (!auth_challenge_str) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t length = 2 * EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE; + + status = m_am_tools->convert_bytes_to_hex_ascii( + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE, + auth_challenge_str, + &length); + if (status != eap_status_ok + || length != 2 * EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE) + { + delete [] auth_challenge_str; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + m_am_tools->convert_ascii_to_uppercase(auth_challenge_str, length); + + const u32_t type_data_length = + + EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length + + EAP_MSCHAPV2_FAILURE_REQUEST_SIZE + + message_length; + + const u32_t packet_length + = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + type_data_length; + + eap_buf_chain_wr_c * packet = create_send_packet(packet_length); + if (!packet) + { + delete [] auth_challenge_str; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_base_c eap_header( + m_am_tools, + packet->get_data_offset(m_offset, packet_length), + packet_length); + if (eap_header.get_is_valid() == false) + { + delete [] auth_challenge_str; + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + eap_header.set_code(eap_code_request); + eap_header.set_identifier(++m_identifier); + eap_header.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + eap_header.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + eap_header.get_type_data_offset(0, eap_header.get_type_data_length()), + eap_header.get_type_data_length()); + + mschapv2_header.set_opcode(mschapv2_opcode_failure); + mschapv2_header.set_mschapv2_id(static_cast(++m_mschapv2id)); + mschapv2_header.set_ms_length(static_cast(type_data_length)); + + u8_t * failure_data = mschapv2_header.get_data(); // @{...} + if (failure_data == 0) + { + delete [] auth_challenge_str; + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + if (m_am_tools->snprintf( + failure_data, + EAP_MSCHAPV2_FAILURE_REQUEST_SIZE, + "E=%010u R=%1u C=12345678901234567890123456789012 V=%010u M=", // auth_challenge will be set by memcpy + m_error_code, + retry, + 3L) != EAP_MSCHAPV2_FAILURE_REQUEST_SIZE) + { + delete [] auth_challenge_str; + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + failure_data + 12 + 1 + 3 + 1 + 2, // pointer to just after "C=" + auth_challenge_str, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE * 2); + + delete [] auth_challenge_str; + + if (message_length != 0) + { + // Copy message to end of packet + m_am_tools->memmove( + failure_data + EAP_MSCHAPV2_FAILURE_REQUEST_SIZE, + message, + message_length); + } + + status = packet_send(packet, packet_length); + delete packet; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + +#if defined(EAP_MSCHAPV2_SERVER) + +eap_status_e eap_type_mschapv2_c::send_success_request( + const u8_t * const message, + const u32_t message_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAP_type_MSCHAPV2: send_success_request\n"))); + + u8_t * auth_response = new u8_t[EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE]; + if (!auth_response) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_success_request(): m_authenticator_challenge"), + m_authenticator_challenge, + EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_success_request(): m_peer_challenge"), + m_peer_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + + eap_status_e status = generate_authenticator_response( + m_password_hash_hash.get_data(EAP_MSCHAPV2_MD4_DIGEST_SIZE), + m_nt_response, + m_peer_challenge, + m_authenticator_challenge, + m_username_utf8.get_data(), + m_username_utf8.get_data_length(), + auth_response); + if (status != eap_status_ok) + { + delete [] auth_response; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t ms_data_length + = EAP_MSCHAPV2_HEADER_SIZE + + EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE + + EAP_MSCHAPV2_MESSAGE_PREFIX_SIZE + + message_length; + + const u32_t packet_length + = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + ms_data_length; + + eap_buf_chain_wr_c * packet = create_send_packet(packet_length); + if (!packet) + { + delete [] auth_response; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_base_c eap_header( + m_am_tools, + packet->get_data_offset(m_offset, packet_length), + packet_length); + if (eap_header.get_is_valid() == false) + { + delete [] auth_response; + delete packet; + packet = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + eap_header.set_code(eap_code_request); + eap_header.set_identifier(++m_identifier); + eap_header.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + eap_header.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + eap_header.get_type_data_offset(0, eap_header.get_type_data_length()), + eap_header.get_type_data_length()); + + mschapv2_header.set_opcode(mschapv2_opcode_success); + mschapv2_header.set_mschapv2_id(static_cast(++m_mschapv2id)); + mschapv2_header.set_ms_length(static_cast(ms_data_length)); + + u8_t * success_data = mschapv2_header.get_data(); + if (success_data == 0) + { + delete [] auth_response; + delete packet; + packet = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Copy auth string after headers + m_am_tools->memmove( + success_data, + auth_response, + EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE); + + delete [] auth_response; + + // Copy message after auth string + m_am_tools->memmove( + success_data + EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE, + EAP_MSCHAPV2_MESSAGE_PREFIX, + EAP_MSCHAPV2_MESSAGE_PREFIX_SIZE); + + if (message_length != 0) + { + m_am_tools->memmove( + success_data + EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE + EAP_MSCHAPV2_MESSAGE_PREFIX_SIZE, + message, + message_length); + } + + status = packet_send(packet, packet_length); + delete packet; + packet = 0; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + +#if defined(EAP_MSCHAPV2_SERVER) + +eap_status_e eap_type_mschapv2_c::rc4_decrypt( + const u8_t * const cypher, + const u32_t cypher_length, + const u8_t * const key, + const u32_t key_length, + u8_t * const clear) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (!cypher + || cypher_length == 0 + || !key + || key_length == 0 + || !clear) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_variable_data_c v_key(m_am_tools); + + eap_status_e status = v_key.set_buffer(key, key_length, false, false); // Cannot fail + if (status != eap_status_ok + || v_key.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + crypto_rc4_c rc4(m_am_tools); + + status = rc4.set_key(&v_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.decrypt_data(cypher, clear, cypher_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + +// end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_state.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/core/eap_type_mschapv2_state.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,261 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 100 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include "eap_am_tools.h" +#include "eap_type_mschapv2_state.h" + +eap_type_mschapv2_state_c::eap_type_mschapv2_state_c(abs_eap_am_tools_c * const tools, const bool client) +: m_am_tools(tools) +, m_is_client(client) +, m_state(eap_type_mschapv2_state_none) +, m_prev_state(eap_type_mschapv2_state_none) +, m_next_state(eap_type_mschapv2_state_none) +, m_failure_message_received(false) +{ + if (m_is_client) + { + m_state = eap_type_mschapv2_state_none; + m_prev_state = eap_type_mschapv2_state_none; + m_next_state = eap_type_mschapv2_state_identity_request; + } + else + { + m_state = eap_type_mschapv2_state_none; + m_prev_state = eap_type_mschapv2_state_none; + m_next_state = eap_type_mschapv2_state_identity_response; + } +} + +EAP_FUNC_EXPORT eap_type_mschapv2_state_c::~eap_type_mschapv2_state_c() +{ +} + +eap_type_mschapv2_state_variable_e eap_type_mschapv2_state_c::get_state() const +{ + return m_state; +} + +void eap_type_mschapv2_state_c::set_state(const eap_type_mschapv2_state_variable_e new_state) +{ + set_state(new_state, eap_type_mschapv2_state_none); +} + +void eap_type_mschapv2_state_c::set_state( + const eap_type_mschapv2_state_variable_e new_state, + const eap_type_mschapv2_state_variable_e new_next_state) + +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_state_c::set_state(): this = 0x%08x, previous state %d, new state %d, new next state %d\n"), + this, + m_prev_state, + new_state, + new_next_state)); + + m_prev_state = m_state; + m_state = new_state; + m_next_state = new_next_state; +} + +bool eap_type_mschapv2_state_c::is_valid_state(const eap_type_mschapv2_state_variable_e new_state) const +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_state_c::is_valid_state(): this = 0x%08x, previous state %d, state %d, new state %d, new next state %d\n"), + this, + m_prev_state, + m_state, + new_state, + m_next_state)); + + if (m_is_client) // Client + { + if (new_state == eap_type_mschapv2_state_identity_request) + { + return true; + } + + // Check validity against (current) state. + // If it fails then against previous state (in case of resending) + + switch (m_state) + { + case eap_type_mschapv2_state_none: + if (new_state == eap_type_mschapv2_state_challenge_request) + { + return true; + } + break; + + case eap_type_mschapv2_state_identity_request: + if (new_state == eap_type_mschapv2_state_challenge_request) + { + return true; + } + break; + + case eap_type_mschapv2_state_challenge_request: + if (new_state == eap_type_mschapv2_state_success_request + || new_state == eap_type_mschapv2_state_failure_request + || new_state == eap_type_mschapv2_state_failure) // non-retryable error in Windows XP SP1 + { + return true; + } + break; + + case eap_type_mschapv2_state_failure_request: + if (new_state == eap_type_mschapv2_state_failure) + { + return true; + } + break; + + case eap_type_mschapv2_state_success_request: + if (new_state == eap_type_mschapv2_state_success) + { + return true; + } + break; + + case eap_type_mschapv2_state_change_password_request: + if (new_state == eap_type_mschapv2_state_success_request + || new_state == eap_type_mschapv2_state_failure_request + || new_state == eap_type_mschapv2_state_failure) // non-retryable error in Windows XP SP1 + { + return true; + } + break; + + case eap_type_mschapv2_state_success: + case eap_type_mschapv2_state_failure: + // Session is ended + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_mschapv2_state_c::is_valid_state(): returns false: this = 0x%08x, previous state %d, state %d, new state %d, new next state %d\n"), + this, + m_prev_state, + m_state, + new_state, + m_next_state)); + + return false; + + default: + ; + } + + } + + else // Server + { + switch (m_state) + { + case eap_type_mschapv2_state_none: + if (new_state == eap_type_mschapv2_state_identity_response) + { + return true; + } + break; + + case eap_type_mschapv2_state_identity_response: + if (new_state == eap_type_mschapv2_state_challenge_response) + { + return true; + } + break; + + case eap_type_mschapv2_state_challenge_response: + if (m_next_state == new_state) + { + return true; + } + break; + case eap_type_mschapv2_state_change_password_response: + if (m_next_state == new_state) + { + return true; + } + break; + + case eap_type_mschapv2_state_success_response: + case eap_type_mschapv2_state_failure_response: + // Session is ended + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_mschapv2_state_c::is_valid_state(): returns false: this = 0x%08x, previous state %d, state %d, new state %d, new next state %d\n"), + this, + m_prev_state, + m_state, + new_state, + m_next_state)); + + return false; + + default: + ; + } + } + return false; +} + +void eap_type_mschapv2_state_c::set_failure_message_received() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_state_c::set_failure_message_received(): this = 0x%08x, previous state %d, state %d, new next state %d\n"), + this, + m_prev_state, + m_state, + m_next_state)); + + m_failure_message_received = true; +} + +void eap_type_mschapv2_state_c::unset_failure_message_received() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_mschapv2_state_c::unset_failure_message_received(): this = 0x%08x, previous state %d, state %d, new next state %d\n"), + this, + m_prev_state, + m_state, + m_next_state)); + + m_failure_message_received = false; +} + +void eap_type_mschapv2_state_c::cancel_eap_failure_timer() +{ +} diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/core/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/core/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,24 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_mschapv2 + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/type/mschapv2/core/eap_type_mschapv2.cpp \ + $(WLAN_COMMON)/type/mschapv2/core/eap_type_mschapv2_client.cpp \ + $(WLAN_COMMON)/type/mschapv2/core/eap_type_mschapv2_credential_store.cpp \ + $(WLAN_COMMON)/type/mschapv2/core/eap_type_mschapv2_header.cpp \ + $(WLAN_COMMON)/type/mschapv2/core/eap_type_mschapv2_server.cpp \ + $(WLAN_COMMON)/type/mschapv2/core/eap_type_mschapv2_state.cpp \ + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_mschapv2_simulator.$(LIB) \ + -lstdc++ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/include/abs_eap_type_mschapv2_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/include/abs_eap_type_mschapv2_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,140 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#ifndef _ABS_MSCHAPV2_STATE_H_ +#define _ABS_MSCHAPV2_STATE_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_buffer.h" +#include "eap_base_type.h" +#include "eap_config.h" +#include "eap_type_mschapv2_types.h" + + +/// This class declares the functions eap_type_gsmsim_state_c +/// requires from the partner class. +class EAP_EXPORT abs_eap_type_mschapv2_state_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Constructor does nothing. + */ + virtual ~abs_eap_type_mschapv2_state_c() + { + } + + /** + * Desstructor does nothing. + */ + abs_eap_type_mschapv2_state_c() + { + } + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @see abs_eap_base_type_c::get_header_offset(). + */ + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + //-------------------------------------------------- +}; // class abs_eap_type_gsmsim_state_c + + + +#endif // _ABS_MSCHAPV2_STATE_H_ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,411 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _MSCHAPV2_CORE_H_ +#define _MSCHAPV2_CORE_H_ + +#include "eap_base_type.h" +#include "eap_crypto_api.h" +#include "eap_type_mschapv2_state.h" + +#include "eap_am_network_id.h" +#include "abs_eap_am_type_mschapv2.h" +#include "eap_am_type_mschapv2.h" +#include "eap_type_mschapv2_header.h" + + +/// This class is implementation of MS-CHAP-v2 EAP-type. +class EAP_EXPORT eap_type_mschapv2_c + : public abs_eap_am_type_mschapv2_c + , public eap_base_type_c +{ + +private: + + /// This is pointer to adaptation module of MS-Chap-v2 EAP type. + eap_am_type_mschapv2_c * const m_am_type_mschapv2; + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// When eap_session_core_c is used. Each EAP type object does handle only one session. + eap_type_mschapv2_state_c m_session; + + eap_am_network_id_c m_send_network_id; + + crypto_random_c m_rand; + + /// This is username and identity (UTF8) + eap_variable_data_c m_username_utf8; + + eap_variable_data_c m_password_utf8; + + eap_variable_data_c m_old_password_utf8; + + eap_variable_data_c m_password_hash; + + eap_variable_data_c m_password_hash_hash; + + +#if defined(USE_FAST_EAP_TYPE) + eap_variable_data_c m_client_EAP_FAST_challenge; + + eap_variable_data_c m_server_EAP_FAST_challenge; +#endif //#if defined(USE_FAST_EAP_TYPE) + + + u8_t m_authenticator_challenge[EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE]; + + u8_t m_peer_challenge[EAP_MSCHAPV2_PEER_CHALLENGE_SIZE]; + + u8_t m_nt_response[EAP_MSCHAPV2_NT_RESPONSE_SIZE]; + + u32_t m_offset; + + u32_t m_mtu_length; + + u32_t m_trailer_length; + + u32_t m_error_code; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + bool m_free_am_type_mschapv2; + + bool m_is_pending; + + bool m_identity_asked; + + bool m_wait_eap_success; + + bool m_wait_eap_success_packet; + + bool m_is_reauthentication; + + bool m_is_notification_sent; + + bool m_shutdown_was_called; + + bool m_password_prompt_enabled; + + u8_t m_identifier; + + u8_t m_mschapv2id; + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + bool m_use_implicit_challenge; +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +#if defined(EAP_MSCHAPV2_SERVER) + bool m_do_password_expiration_tests; + + bool m_password_expired; +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + bool m_do_wrong_password_tests; + + bool m_use_eap_expanded_type; + +#if defined(USE_FAST_EAP_TYPE) + + bool m_use_EAP_FAST_full_key; + + bool m_use_EAP_FAST_challenge; + +#endif //#if defined(USE_FAST_EAP_TYPE) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + void send_error_notification(const eap_status_e error); + + eap_status_e finish_successful_authentication(); + + eap_status_e finish_unsuccessful_authentication( + const bool authentication_cancelled); + + eap_status_e complete_eap_identity_query(); + + eap_status_e complete_failure_retry_response(); + + eap_status_e complete_change_password_query(); + + eap_status_e client_packet_process( + eap_header_wr_c * const eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + eap_status_e client_mschapv2_packet_process( + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length); + + eap_status_e client_handle_challenge_request(mschapv2_header_c &challenge_request); + + eap_status_e client_handle_success_request(mschapv2_header_c &success_request); + + eap_status_e client_handle_failure_request(mschapv2_header_c &success_request); + + eap_status_e client_send_challenge_response(); + + + /** + * This function processes the MS-CHAP-V2 packets. + */ + eap_status_e mschapv2_packet_process( + eap_header_wr_c * const eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + /** + * This function tells if the object is a client or a server.. + */ + bool get_is_client(); + + eap_buf_chain_wr_c * create_send_packet(u32_t length); + + eap_status_e packet_send( + eap_buf_chain_wr_c * const data, + const u32_t data_length); + + eap_status_e send_success_failure_response(bool is_success_response); + + eap_status_e mschapv2_convert_unicode_to_ascii(eap_variable_data_c & dest_ascii, const eap_variable_data_c & src_unicode); + + eap_status_e mschapv2_convert_ascii_to_unicode(eap_variable_data_c & dest_unicode, const eap_variable_data_c & src_ascii); + + /* From Ms-CHAP-v2 RFC */ + + eap_status_e generate_nt_response( + const u8_t * const authenticator_challenge, + const u8_t * const peer_challenge, + const u8_t * const username_utf8, + const u32_t username_size, + const eap_variable_data_c * const password_hash, + u8_t * const response); + + eap_status_e challenge_hash( + const u8_t * const peer_challenge, + const u8_t * const authenticator_challenge, + const u8_t * const username_utf8, + const u32_t username_size, + u8_t * const challenge); + + eap_status_e challenge_response( + const u8_t * const challenge, + const u8_t * const password_hash, + u8_t * const response); + + eap_status_e des_crypt( + const u8_t * const data_in, + const u8_t * const key, + u8_t * const data_out, + const bool is_encrypt); + + eap_status_e des_encrypt( + const u8_t * const clear, + const u8_t * const block, + u8_t * const cypher) + { + return des_crypt(clear, block, cypher, true); + } + + eap_status_e des_decrypt( + u8_t * const clear, + const u8_t * const block, + const u8_t * const cypher) + { + return des_crypt(cypher, block, clear, false); + } + + eap_status_e generate_authenticator_response( + const u8_t * const password_hash_hash, + const u8_t * const nt_response, + const u8_t * const peer_challenge, + const u8_t * const authenticator_challenge, + const u8_t * const username, + const u32_t username_size, + u8_t * const authenticator_response); + + eap_status_e check_authenticator_response( + const eap_variable_data_c * const password_hash_hash, + const u8_t * const nt_response, + const u8_t * const peer_challenge, + const u8_t * const authenticator_challenge, + const u8_t * const username, + const u32_t username_size, + const u8_t * const received_response, + bool & response_ok); + + eap_status_e new_password_encrypted_with_old_nt_password_hash( + const eap_variable_data_c * const new_password_utf8, + const eap_variable_data_c * const old_password_hash, + u8_t * encrypted_pw_block); + + eap_status_e encrypt_pw_block_with_password_hash( + const eap_variable_data_c * const new_password_utf8, + const u8_t * const password_hash, + u8_t * pw_block); + + eap_status_e rc4_encrypt( + const u8_t * const clear, + const u32_t clear_length, + const u8_t * const key, + const u32_t key_length, + u8_t * const cypher); + + eap_status_e old_nt_password_hash_encrypted_with_new_nt_password_hash( + const eap_variable_data_c * const new_password_hash, + const eap_variable_data_c * const old_password_hash, + eap_variable_data_c * const encrypted_password_hash); + + eap_status_e nt_password_hash_encrypted_with_block( + const eap_variable_data_c * const password_hash, + const eap_variable_data_c * const block, + eap_variable_data_c * const cypher); + + eap_status_e generate_session_key( + eap_master_session_key_c * const key); + + /***************************/ + +#if defined(EAP_MSCHAPV2_SERVER) + + eap_status_e server_packet_process( + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length); + + eap_status_e server_mschapv2_packet_process( + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length); + + bool check_expired_password(); + + eap_status_e server_handle_challenge_response(mschapv2_header_c &machapv2_packet); + + eap_status_e server_handle_success_response(); + + eap_status_e server_handle_failure_response(); + + eap_status_e server_handle_password_change(mschapv2_header_c &machapv2_packet); + + /** + * This function parses all payloads of the whole MSCHAPV2 EAP packet. + */ + eap_status_e parse_mschapv2_packet( + eap_header_wr_c * const eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + + eap_status_e parse_mschapv2_payload( + eap_header_wr_c * const eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + eap_status_e send_failure_request( + const bool retry_allowed, + const u8_t * const message, + const u32_t message_length); + + eap_status_e send_success_request( + const u8_t * const message, + const u32_t message_length); + + /** + * This function handles the received EAP-Response/Identity message and chenge challenge request to client. + */ + eap_status_e handle_identity_response_message(); + + eap_status_e rc4_decrypt( + const u8_t * const cypher, + const u32_t cypher_length, + const u8_t * const key, + const u32_t key_length, + u8_t * const clear); + +#endif //#if defined(EAP_MSCHAPV2_SERVER) + + /******************************/ + +protected: + +public: + + /** + * Destructor cancels all timers and deletes member attributes. + */ + EAP_FUNC_IMPORT virtual ~eap_type_mschapv2_c(); + + /** + * Constructor initializes all member attributes. + */ + EAP_FUNC_IMPORT eap_type_mschapv2_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + eap_am_type_mschapv2_c * const am_type_mschapv2, + const bool free_am_type_mschapv2, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + /** + * The partner class calls this function when EAP/MS-CHAP-v2 packet is received. + * see also eap_base_type_c::packet_process(). + */ + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + // This is commented in eap_base_type_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * This function resets the reused eap_type_mschapv2_c object. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT eap_status_e set_initial_eap_identifier( + const eap_am_network_id_c * const receive_network_id, + const u8_t initial_identifier); + + // This is commented in eap_base_type_c::eap_acknowledge(). + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is commented in eap_base_type_c::query_eap_identity(). + EAP_FUNC_IMPORT eap_status_e query_eap_identity( + const bool must_be_synchronous, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier); + +}; // class eap_type_mschap_c + +#endif // _MSCHAPV2_CORE_H_ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2_credential_store.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2_credential_store.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAP_TYPE_MSCHAPV2_CREDENTIAL_STORE_H +#define EAP_TYPE_MSCHAPV2_CREDENTIAL_STORE_H + +// INCLUDES +#include "eap_am_memory_store_data.h" +#include "eap_am_tools.h" +#include "eap_type_mschapv2.h" + +// CLASS DECLARATION + + +#endif // EAP_TYPE_MSCHAPV2_CREDENTIAL_STORE_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,374 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _MSCHAPV2_HEADER_H_ +#define _MSCHAPV2_HEADER_H_ + +#include "eap_am_tools.h" + +#include "eap_tools.h" +#include "eap_general_header_base.h" + +enum eap_mschapv2_version +{ + MSCHAPV2_ILLEGAL_VERSION = 0x0000, + MSCHAPV2_VERSION_1 = 0x0001, + MSCHAPV2_LAST_VERSION = 0x0001 ///< Keep this same as the last acceptable version. +}; + +enum mschapv2_opcode_e +{ + mschapv2_opcode_challenge = 1, + mschapv2_opcode_response = 2, + mschapv2_opcode_success = 3, + mschapv2_opcode_failure = 4, + mschapv2_opcode_change_password = 7, + mschapv2_opcode_unknown = 255 // Internal error +}; + +/// This class defines header of MS-CHAP-v2 EAP-type. +/** + * Here is a figure of header of MS-CHAP-v2 EAP-type. + * Data is m_eap_length - sizeof(mschapv2_header_c) data octets that follows mschapv2_header_c. + * @code + * + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Code | Identifier | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type=29 | OpCode | MS-CHAPv2-ID | MS-Length... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MS-Length | Data... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ +class EAP_EXPORT mschapv2_header_c +: public eap_general_header_base_c +{ +private: + + abs_eap_am_tools_c * const m_am_tools; + + u32_t m_length; + +protected: + + enum offsets + { + m_opcode_offset = 0ul, + m_mschapv2_id_offset = m_opcode_offset + sizeof(u8_t), + m_ms_length_offset = m_mschapv2_id_offset + sizeof(u8_t), + m_data_offset = m_ms_length_offset + sizeof(u16_t) + }; + +public: + + EAP_FUNC_IMPORT virtual ~mschapv2_header_c(); + + EAP_FUNC_IMPORT mschapv2_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT mschapv2_opcode_e get_opcode() const; + + EAP_FUNC_IMPORT void set_opcode(const mschapv2_opcode_e p_opcode); + + EAP_FUNC_IMPORT u8_t get_mschapv2_id() const; + + EAP_FUNC_IMPORT void set_mschapv2_id(u8_t p_id); + + EAP_FUNC_IMPORT u16_t get_ms_length() const; + + EAP_FUNC_IMPORT void set_ms_length(u16_t p_length); + + EAP_FUNC_IMPORT u8_t * get_data() const; + + EAP_FUNC_IMPORT u32_t get_data_length() const; + + EAP_FUNC_IMPORT eap_status_e check_header() const; + +}; // class mschapv2_header_c + +//-------------------------------------------------- + +/// This class defines Challenge payload of MS-CHAP-v2. +/** + * Here is a figure of Challenge payload of MS-CHAP-v2. + * @code + * + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Value Size | Challenge 16 octets | + * +-+-+-+-+-+-+-+-+-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+- -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | Name ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + */ +class EAP_EXPORT mschapv2_challenge_c +: public eap_general_header_base_c +{ +private: + + abs_eap_am_tools_c * const m_am_tools; + + u32_t m_length; + +protected: + + enum offsets + { + m_value_size_offset = 0ul, + m_challenge_offset = m_value_size_offset + sizeof(u8_t), + m_name_offset = m_challenge_offset + 16 * sizeof(u8_t), + }; + +public: + + EAP_FUNC_IMPORT virtual ~mschapv2_challenge_c(); + + EAP_FUNC_IMPORT mschapv2_challenge_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT static u32_t get_header_minimum_size(); + + EAP_FUNC_IMPORT eap_status_e check_header() const; + + EAP_FUNC_IMPORT void set_value_size(); + + EAP_FUNC_IMPORT const u8_t * get_challenge() const; + + EAP_FUNC_IMPORT void set_challenge(const u8_t * const p_challenge); + + EAP_FUNC_IMPORT const u8_t * get_name() const; + + EAP_FUNC_IMPORT u32_t get_name_length() const; + + EAP_FUNC_IMPORT void set_name(const u8_t * const p_name); +}; // class mschapv2_challenge_c + +//-------------------------------------------------- + +/// This class defines Change Password payload of MS-CHAP-v2. +/** + * Here is a figure of Change Password payload of MS-CHAP-v2. + * @code + * + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encrypted Block 516 octets | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * . . + * . . + * . . + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encrypted Hash 16 octets | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Peer Challenge 16 octets | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved 8 octets | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | NT Response 24 octets | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Flags | + * +-+-+-+-+-+-+-+-+ + * @endcode + */ +class EAP_EXPORT mschapv2_change_password_c +: public eap_general_header_base_c +{ +private: + + abs_eap_am_tools_c * const m_am_tools; + + u32_t m_length; + +protected: + + enum offsets + { + m_encrypted_pw_block_offset = 0ul, + m_encrypted_hash_offset = m_encrypted_pw_block_offset + 516 * sizeof(u8_t), + m_peer_challenge_offset = m_encrypted_hash_offset + 16 * sizeof(u8_t), + m_reserved_offset = m_peer_challenge_offset + 16 * sizeof(u8_t), + m_nt_response_offset = m_reserved_offset + 8 * sizeof(u8_t), + m_flags_offset = m_nt_response_offset + 24 * sizeof(u8_t), + }; + +public: + + EAP_FUNC_IMPORT virtual ~mschapv2_change_password_c(); + + EAP_FUNC_IMPORT mschapv2_change_password_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT static u32_t get_header_minimum_size(); + + EAP_FUNC_IMPORT eap_status_e check_header() const; + + EAP_FUNC_IMPORT const u8_t * get_encrypted_pw_block() const; + + EAP_FUNC_IMPORT void set_encrypted_pw_block(const u8_t * const p_encrypted_pw_block); + + EAP_FUNC_IMPORT const u8_t * get_encrypted_hash() const; + + EAP_FUNC_IMPORT void set_encrypted_hash(const u8_t * const p_encrypted_hash); + + EAP_FUNC_IMPORT const u8_t * get_peer_challenge() const; + + EAP_FUNC_IMPORT void set_peer_challenge(const u8_t * const p_peer_challenge); + + EAP_FUNC_IMPORT const u8_t * get_nt_response() const; + + EAP_FUNC_IMPORT void set_nt_response(const u8_t * const p_nt_response); + + EAP_FUNC_IMPORT eap_status_e set_constants(); +}; // class mschapv2_change_password_c + +//-------------------------------------------------- + +/// This class defines Response payload of MS-CHAP-v2. +/** + * Here is a figure of Response payload of MS-CHAP-v2. + * @code + * + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Value Size | Peer Challenge 16 octets | + * +-+-+-+-+-+-+-+-+-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+- -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | Reserved 8 octets | + * +-+-+-+-+-+-+-+-+-+-+- -+-+-+-+ + * | | + * +-+- -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | NT Response 24 octets | + * +-+-+-+-+-+-+-+-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+-+-+- -+-+-+-+ + * | | + * +-+- -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | Flags | Name ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- + * @endcode + */ +class EAP_EXPORT mschapv2_response_c +: public eap_general_header_base_c +{ +private: + + abs_eap_am_tools_c * const m_am_tools; + + u32_t m_length; + +protected: + + enum offsets + { + m_value_size_offset = 0ul, + m_peer_challenge_offset = m_value_size_offset + sizeof(u8_t), + m_reserved_offset = m_peer_challenge_offset + 16 * sizeof(u8_t), + m_nt_response_offset = m_reserved_offset + 8 * sizeof(u8_t), + m_flags_offset = m_nt_response_offset + 24 * sizeof(u8_t), + m_name_offset = m_flags_offset + sizeof(u8_t) + }; + +public: + + EAP_FUNC_IMPORT virtual ~mschapv2_response_c(); + + EAP_FUNC_IMPORT mschapv2_response_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT static u32_t get_header_minimum_size(); + + EAP_FUNC_IMPORT eap_status_e check_header() const; + + EAP_FUNC_IMPORT const u8_t * get_peer_challenge() const; + + EAP_FUNC_IMPORT void set_peer_challenge(const u8_t * const p_challenge); + + EAP_FUNC_IMPORT const u8_t * get_nt_response() const; + + EAP_FUNC_IMPORT void set_nt_response(const u8_t * const p_challenge); + + EAP_FUNC_IMPORT const u8_t * get_name() const; + + EAP_FUNC_IMPORT u32_t get_name_length() const; + + EAP_FUNC_IMPORT void set_name(const u8_t * const p_name); + + EAP_FUNC_IMPORT eap_status_e set_constants(); +}; // class mschapv2_response_c + +//-------------------------------------------------- + +#endif //_MSCHAPV2_HEADER_H_ + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2_payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2_payloads.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#ifndef _MSCHAPV2_PAYLOADS_H_ +#define _MSCHAPV2_PAYLOADS_H_ + +#include "eap_variable_data.h" + +class EAP_EXPORT mschapv2_data_c +{ +private: + + eap_variable_data_c m_username; // Ascii + eap_variable_data_c m_password; // Unicode + + eap_variable_data_c m_challenge; + eap_variable_data_c m_peer_challenge; + + u8_t m_identifier; + u8_t m_mschapv2id; + + u32_t m_error_code; + + // Client + eap_boolean_e m_password_prompt_enabled; + + eap_variable_data_c m_nt_response; + eap_variable_data_c m_new_password; + +protected: + +public: + + EAP_FUNC_IMPORT ~mschapv2_data_c(); + + EAP_FUNC_IMPORT mschapv2_data_c(abs_eap_am_tools_c * const tools); + + eap_boolean_e get_password_prompt_enabled() const; + + void set_password_prompt_enabled(eap_boolean_e is_enabled); + + eap_variable_data_c * const get_username(); + + eap_variable_data_c * const get_password(); + + eap_variable_data_c * const get_challenge(); + + eap_variable_data_c * const get_peer_challenge(); + + // Client + + eap_variable_data_c * const get_nt_response(); + + eap_variable_data_c * const get_new_password(); + + u8_t get_identifier() const; + + void set_identifier(u8_t identifier); + + u8_t get_mschapv2id() const; + + void set_mschapv2id(u8_t mschapv2id); + + u32_t get_error_code() const; + + void set_error_code(u32_t error_code); +}; + +#endif //_MSCHAPV2_PAYLOADS_H_ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#ifndef _MSCHAPV2_STATE_H_ +#define _MSCHAPV2_STATE_H_ + +#include "eap_am_export.h" +#include "abs_eap_am_tools.h" + +/** + * This is the internal state of the MSCHAPV2 EAP type. + */ +enum eap_type_mschapv2_state_variable_e +{ + // Common + eap_type_mschapv2_state_none, + + eap_type_mschapv2_state_success, + eap_type_mschapv2_state_failure, + + // Client + eap_type_mschapv2_state_identity_request, + eap_type_mschapv2_state_challenge_request, + eap_type_mschapv2_state_success_request, + eap_type_mschapv2_state_failure_request, + eap_type_mschapv2_state_change_password_request, + + // Server + eap_type_mschapv2_state_identity_response, + eap_type_mschapv2_state_challenge_response, + eap_type_mschapv2_state_success_response, + eap_type_mschapv2_state_failure_response, + eap_type_mschapv2_state_change_password_response +}; + +class EAP_EXPORT eap_type_mschapv2_state_c +{ + +private: + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + bool m_is_client; + eap_type_mschapv2_state_variable_e m_state; + eap_type_mschapv2_state_variable_e m_prev_state; + eap_type_mschapv2_state_variable_e m_next_state; + + bool m_failure_message_received; + +public: + eap_type_mschapv2_state_c(abs_eap_am_tools_c * const tools, const bool client); + + EAP_FUNC_IMPORT virtual ~eap_type_mschapv2_state_c(); + + eap_type_mschapv2_state_variable_e get_state() const; + + void set_state(const eap_type_mschapv2_state_variable_e new_state); + + void set_state(const eap_type_mschapv2_state_variable_e new_state, const eap_type_mschapv2_state_variable_e next_state); + + bool is_valid_state(const eap_type_mschapv2_state_variable_e new_state) const; + + void set_failure_message_received(); + + void unset_failure_message_received(); + + void cancel_eap_failure_timer(); +}; + + + + +#endif //_MSCHAPV2_STATE_H_ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/mschapv2/include/eap_type_mschapv2_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,212 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#ifndef _MSCHAPV2_TYPES_H_ +#define _MSCHAPV2_TYPES_H_ + +#include "eap_configuration_field.h" + +const u32_t EAP_MSCHAPV2_USERNAME_MAX_SIZE = 512; // 256 unicode-chars +const u32_t EAP_MSCHAPV2_PASSWORD_MAX_SIZE = 512; // 256 unicode-chars + +const u32_t EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE = 42; +const u32_t EAP_MSCHAPV2_CHALLENGE_HASH_SIZE = 8; +const u32_t EAP_MSCHAPV2_NT_RESPONSE_SIZE = 24; +const u32_t EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE = 16; +const u32_t EAP_MSCHAPV2_PEER_CHALLENGE_SIZE = 16; +const u32_t EAP_MSCHAPV2_IDENT_SIZE = 1; +const u32_t EAP_MSCHAPV2_FLAGS_SIZE = 1; +const u32_t EAP_MSCHAPV2_OPCODE_SIZE = 1; +const u32_t EAP_MSCHAPV2_CHANGE_PASSWORD_FLAGS_SIZE = 2; +const u32_t EAP_MSCHAPV2_RESERVED_RESPONSE_SIZE = 8; +const u32_t EAP_MSCHAPV2_MD4_DIGEST_SIZE = 16; +const u32_t EAP_MSCHAPV2_SHA1_DIGEST_SIZE = 20; +const u32_t EAP_MSCHAPV2_DES_KEY_SIZE = 8; +const u32_t EAP_MSCHAPV2_DES_BLOCK_SIZE = 8; + +const u32_t EAP_MSCHAPV2_RESPONSE_MESSAGE_SIZE + = EAP_MSCHAPV2_IDENT_SIZE + + EAP_MSCHAPV2_FLAGS_SIZE + + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE + + EAP_MSCHAPV2_RESERVED_RESPONSE_SIZE + + EAP_MSCHAPV2_NT_RESPONSE_SIZE; + +const u32_t EAP_MSCHAPV2_PEER_CHALLENGE_OFFSET + = EAP_MSCHAPV2_IDENT_SIZE + + EAP_MSCHAPV2_FLAGS_SIZE; + +const u32_t EAP_MSCHAPV2_NT_RESPONSE_OFFSET + = EAP_MSCHAPV2_PEER_CHALLENGE_OFFSET + + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE + + EAP_MSCHAPV2_RESERVED_RESPONSE_SIZE; + + +const u32_t EAP_MSCHAPV2_MASTER_KEY_SIZE = 16; + +const u32_t EAP_MSCHAPV2_SUCCESS_REQUEST_MESSAGE_MIN_LENGTH = 42;// "S=<40>" +const u32_t EAP_MSCHAPV2_FAILURE_MIN_SIZE = 48; +const u32_t EAP_MSCHAPV2_FAILURE_REQUEST_SIZE = 67; // "E=eeeeeeeeee R=r C=cccccccccccccccccccccccccccccccc V=vvvvvvvvvv M=" +const u32_t EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_PASSWORD_SIZE = 516; +const u32_t EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_HASH_SIZE = 16; +const u32_t EAP_MSCHAPV2_HEADER_SIZE = 4; // OpCode, MS-CHAPv2-ID and MS-Length + + +const u8_t EAP_MSCHAPV2_MESSAGE_PREFIX[] = " M="; +const u32_t EAP_MSCHAPV2_MESSAGE_PREFIX_SIZE = 3; + +const u8_t EAP_MSCHAPV2_IMPLICIT_CHALLENGE_HANDLE_KEY[] = "eap_type_mschapv2_c implicit challenge"; + +const u8_t EAP_MSCHAPV2_ZERO_CHALLENGE[] + = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; + +typedef struct +{ + u8_t password[EAP_MSCHAPV2_PASSWORD_MAX_SIZE]; // 256 unicode-chars + u32_t password_length; +} pw_block_s; + +enum eap_type_mschapv2_stored_e +{ + eap_type_mschapv2_stored_none, + eap_type_mschapv2_stored_username, + eap_type_mschapv2_stored_password, + eap_type_mschapv2_implicit_challenge, + eap_type_mschapv2_stored_password_expired_flag, +}; + + +const u32_t TRACE_FLAGS_MSCHAPV2_ERROR = eap_am_tools_c::eap_trace_mask_error; + +/** + * This is boolean configuration option. + * True value of this flag causes client return random + * identity on EAP-Response/Identity. + * False value causes client return real identity + * (IMSI, pseudonym or re-authentication identity) + * in EAP-Response/Identity. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_wait_eap_success_packet, + "EAP_MSCHAPV2_wait_eap_success_packet", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_password_prompt, + "EAP_MSCHAPV2_password_prompt", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_username, + "EAP_MSCHAPV2_username", + eap_configure_type_hex_data, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_password, + "EAP_MSCHAPV2_password", + eap_configure_type_hex_data, + true); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_use_implicit_challenge, + "EAP_MSCHAPV2_use_implicit_challenge", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_use_EAP_FAST_challenge, + "EAP_MSCHAPV2_use_EAP_FAST_challenge", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_client_EAP_FAST_challenge, + "EAP_MSCHAPV2_client_EAP_FAST_challenge", + eap_configure_type_hex_data, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_server_EAP_FAST_challenge, + "EAP_MSCHAPV2_server_EAP_FAST_challenge", + eap_configure_type_hex_data, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_use_EAP_FAST_full_key, + "EAP_MSCHAPV2_use_EAP_FAST_full_key", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_use_eap_expanded_type, + "EAP_MSCHAPV2_use_eap_expanded_type", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_do_password_expiration_tests, + "EAP_MSCHAPV2_do_password_expiration_tests", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_do_wrong_password_tests, + "EAP_MSCHAPV2_do_wrong_password_tests", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPV2_do_asyncronous_completition, + "EAP_MSCHAPV2_do_asyncronous_completition", + eap_configure_type_boolean, + false); + +/** + * This u32_t configuration value specifies the maximum session validity time in seconds. + * Default value is 12 hours in seconds, which is 43200 seconds. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_MSCHAPv2_max_session_validity_time, + "EAP_MSCHAPv2_max_session_validity_time", + eap_configure_type_u32_t, + false); + +/** @} */ // End of group MSCHAPV2_config_options. + +//-------------------------------------------------- + +/// Macro traces payload type and data. +#define EAP_MSCHAPV2_TRACE_PAYLOAD(prefix, payload) \ + { \ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("%s (0x%08x): current payload 0x%04x=%s, data length 0x%04x.\n"), \ + prefix, payload, payload->get_current_payload(), payload->get_payload_AT_string(), payload->get_data_length())); \ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("payload"), \ + payload, \ + payload->get_payload_length())); \ + } + +//-------------------------------------------------- + + +#endif //#if !defined(_MSCHAPV2_TYPES_H_) diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2304 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 104 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_radius.h" +#include "eap_radius_header.h" +#include "eap_radius_payloads.h" +#include "eap_radius_mac_attributes.h" +#include "abs_eap_am_radius.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" +#include "abs_eap_am_mutex.h" +#include "eap_automatic_variable.h" +#include "eapol_header.h" +#include "eap_diameter_avp_code.h" + + +/// This is pseudo Ethernet and EAPOL header. +/// This is used in trace of tunneled EAP-packet. +const u8_t EAP_PSEUDO_ETHERNET_HEADER[] = +{ + 0x50, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x88, 0x8e, 0x01, 0x00, + 0x00, 0x00 +}; + +const u32_t EAP_PSEUDO_EAPOL_HEADER_OFFSET = 14ul; + +//-------------------------------------------------- + +/** @file */ + +// +EAP_FUNC_EXPORT eap_radius_c::~eap_radius_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_c::~eap_radius_c(): this = 0x%08x => 0x%08x\n"), + this, + dynamic_cast(this))); + + EAP_ASSERT(m_shutdown_was_called == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +// +EAP_FUNC_EXPORT eap_radius_c::eap_radius_c( + abs_eap_am_tools_c * const tools, + abs_eap_radius_c * const partner, + eap_am_radius_c * const am_radius, + const bool free_am_radius, + const bool is_client_when_true) + : m_am_tools(tools) + , m_partner(partner) + , m_session_map(tools, this) + , m_pseudo_ethernet_header(tools) + , m_radius_header_offset(0ul) + , m_MTU(0ul) + , m_trailer_length(0ul) + , m_salt(0ul) + , m_shutdown_was_called(false) + , m_is_client(false) + , m_is_valid(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_c::eap_radius_c(): this = 0x%08x => 0x%08x, partner 0x%08x\n"), + this, + dynamic_cast(this), + partner)); + + eap_status_e status = m_pseudo_ethernet_header.set_copy_of_buffer( + EAP_PSEUDO_ETHERNET_HEADER, + sizeof(EAP_PSEUDO_ETHERNET_HEADER)); + if (status != eap_status_ok) + { + // Do not care of this error. + // User will check the validity of m_pseudo_ethernet_header. + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_radius_c::get_state_string(eap_radius_state_variable_e state) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_identity_request) + else EAP_IF_RETURN_STRING(state, eap_radius_state_pending_identity_query) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_start_request) + else EAP_IF_RETURN_STRING(state, eap_radius_state_imsi_waiting_for_start_request) + else EAP_IF_RETURN_STRING(state, eap_radius_state_pseydonym_waiting_for_start_request) + else EAP_IF_RETURN_STRING(state, eap_radius_state_analyse_start_request) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_challenge_request) + else EAP_IF_RETURN_STRING(state, eap_radius_state_analyses_challenge_request) + else EAP_IF_RETURN_STRING(state, eap_radius_state_pending_kc_sres_query) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_success) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_reauth_request) + else EAP_IF_RETURN_STRING(state, eap_radius_state_analyses_reauthentication_request) + else EAP_IF_RETURN_STRING(state, eap_radius_state_pending_pseudonym_decode_query) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_identity_response) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_start_response_with_at_permanent_identity) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_start_response_with_at_full_auth_identity) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_start_response_with_at_any_identity) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_start_response) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_challenge_response) + else EAP_IF_RETURN_STRING(state, eap_radius_state_pending_triplet_query) + else EAP_IF_RETURN_STRING(state, eap_radius_state_analyses_challenge_response) + else EAP_IF_RETURN_STRING(state, eap_radius_state_analyses_start_response) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_notification_request_success) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_notification_response_failure) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_notification_response_success) + else EAP_IF_RETURN_STRING(state, eap_radius_state_waiting_for_reauth_response) + else EAP_IF_RETURN_STRING(state, eap_radius_state_analyses_reauthentication_response) + else EAP_IF_RETURN_STRING(state, eap_radius_state_success) + else EAP_IF_RETURN_STRING(state, eap_radius_state_failure) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown RADIUS state"); + } +} + +//-------------------------------------------------- + +#if defined(USE_EAP_RADIUS_VERIFY_STATES) + +/** + * This function checks the valid states. + */ +bool eap_radius_c::verify_states( + const eap_radius_state_variable_e * const valid_states, + const u32_t count) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + for (u32_t ind = 0ul; ind < count; ind++) + { + if (m_state == valid_states[ind]) + { + return true; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; +} + +#endif //#if defined(USE_EAP_RADIUS_VERIFY_STATES) + +//-------------------------------------------------- + +static const u8_t DEFAULT_CALLED_STATION_ID[] = "000000"; +static const u32_t DEFAULT_CALLED_STATION_ID_LENGTH = sizeof(DEFAULT_CALLED_STATION_ID); + +static const u8_t DEFAULT_CALLING_STATION_ID[] = "111111"; +static const u32_t DEFAULT_CALLING_STATION_ID_LENGTH = sizeof(DEFAULT_CALLING_STATION_ID); + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::analyse_radius_packet( + const eap_am_network_id_c * const receive_network_id, + eap_radius_header_base_c * const received_radius, + const u32_t radius_packet_length, + eap_radius_payloads_c * const p_radius_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + if (m_is_client == true) + { + // Not supported yet. First priority is the server functionality. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + else + { + eap_variable_data_c called_station_id(m_am_tools); + + if (called_station_id.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (p_radius_payloads->get_payload(eap_diameter_avp_code_called_station_id) != 0) + { + status = called_station_id.add_data(p_radius_payloads->get_payload(eap_diameter_avp_code_called_station_id)->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = called_station_id.add_data(DEFAULT_CALLED_STATION_ID, DEFAULT_CALLED_STATION_ID_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_variable_data_c calling_station_id(m_am_tools); + + if (calling_station_id.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (p_radius_payloads->get_payload(eap_diameter_avp_code_calling_station_id) != 0) + { + status = calling_station_id.add_data(p_radius_payloads->get_payload(eap_diameter_avp_code_calling_station_id)->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = called_station_id.add_data(DEFAULT_CALLING_STATION_ID, DEFAULT_CALLING_STATION_ID_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + // Test the required attributes. + if (p_radius_payloads->get_payload(eap_diameter_avp_code_user_name) != 0 + && p_radius_payloads->get_payload(eap_diameter_avp_code_nas_ip_address) != 0 + && p_radius_payloads->get_payload(eap_diameter_avp_code_eap_message) != 0) + { + // Check the session. + eap_variable_data_c selector(m_am_tools); + + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = selector.add_data( + p_radius_payloads->get_payload( + eap_diameter_avp_code_user_name + )->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = selector.add_data( + p_radius_payloads->get_payload( + eap_diameter_avp_code_nas_ip_address + )->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = selector.add_data(&called_station_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = selector.add_data( + p_radius_payloads->get_payload( + eap_diameter_avp_code_calling_station_id + )->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RADIUS session"), + selector.get_data(), + selector.get_data_length())); + + eap_radius_session_c * session = m_session_map.get_handler(&selector); + + if (session == 0) + { + // Create a new session. + session = new eap_radius_session_c( + m_am_tools, + this, + false, + p_radius_payloads->get_payload(eap_diameter_avp_code_user_name), + p_radius_payloads->get_payload(eap_diameter_avp_code_nas_ip_address)); + + if (session == 0 + || session->get_is_valid() == false) + { + delete session; + session = 0; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = session->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_session_map.add_handler(&selector, session); + if (status != eap_status_ok) + { + session->shutdown(); + delete session; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (session != 0) + { + // Handle the received EAP-Response. + + status = session->save_request_data( + received_radius->get_authenticator(), + received_radius->get_authenticator_length(), + received_radius->get_identifier()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c * const eap_message + = p_radius_payloads->get_payload(eap_diameter_avp_code_eap_message) + ->get_payload_buffer(); + + eap_header_wr_c eap( + m_am_tools, + eap_message->get_data(), + eap_message->get_data_length()); + + trace_tunneled_packet(EAPL("-> TUNNELED packet server"), &eap); + + status = session->packet_process( + receive_network_id, + &eap, + eap_message->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::parse_radius_packet( + eap_radius_header_base_c * const radius, + const u32_t radius_packet_length, + eap_radius_payloads_c * const p_radius_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (radius->get_length() < radius->get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_payloads_c::parse_radius_packet(): ") + EAPL("RADIUS-header is corrupted. Buffer length and payload ") + EAPL("length does not match. RADIUS-header length %lu < minimum RADIUS-header length %lu.\n"), + radius->get_length(), + radius->get_header_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (radius->get_length() > radius_packet_length) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_payloads_c::parse_radius_packet(): ") + EAPL("RADIUS-header is corrupted. Buffer length and payload ") + EAPL("length does not match. RADIUS-header length %lu > packet length %lu\n"), + radius->get_length(), + radius_packet_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u32_t buffer_length = radius->get_length() - radius->get_header_length(); + + if (buffer_length == 0u) + { + // No payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + + eap_radius_attribute_header_c payload( + m_am_tools, + radius->get_data_offset(0ul, buffer_length), + buffer_length); + + if (payload.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: No eap_radius_attribute_header_c.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + eap_status_e status = p_radius_payloads->parse_radius_payload( + &payload, + &buffer_length); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (buffer_length != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_payloads_c::parse_radius_packet(): ") + EAPL("RADIUS-header is corrupted. Buffer length and payload ") + EAPL("length does not match. Illegal byte count %lu\n"), + buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::handle_radius_packet( + const eap_am_network_id_c * const receive_network_id, + eap_radius_header_base_c * const received_radius, + const u32_t radius_length, + eap_radius_payloads_c * const p_radius_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_header_corrupted); + + status = parse_radius_packet(received_radius, radius_length, p_radius_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = analyse_radius_packet( + receive_network_id, + received_radius, + radius_length, + p_radius_payloads); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +#if defined(USE_EAP_TRACE) + +// +EAP_FUNC_EXPORT void eap_radius_c::packet_trace( + eap_const_string prefix, + const eap_am_network_id_c * const /* receive_network_id */, + eap_radius_header_base_c * const eap_packet, + const u32_t /* eap_packet_length */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(prefix); + + if (eap_packet->get_length() > eap_radius_header_base_c::get_header_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s EAP_type_RADIUS: %s, (0x%08x), code=0x%02x=%s, ") + EAPL("identifier=0x%02x, length=0x%04x\n"), + prefix, + (m_is_client == true) ? "client": "server", + this, + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + eap_am_tools_c::eap_trace_mask_eap_messages, + (EAPL("\n\t%s\n\tcode = 0x%02x = %s\n\tidentifier = ") + EAPL("0x%02x\n\tlength = 0x%04x = %lu\n\n"), + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + eap_packet->get_length())); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s EAP_type_RADIUS: %s, (0x%08x), code=0x%02x=%s, ") + EAPL("identifier=0x%02x, length=0x%04x\n"), + prefix, + (m_is_client == true) ? "client": "server", + this, + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + eap_am_tools_c::eap_trace_mask_eap_messages, + (EAPL("\n\t%s\n\tcode = 0x%02x = %s\n\tidentifier = ") + EAPL("0x%02x\n\tlength = 0x%04x = %lu\n"), + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + eap_packet->get_length())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +#endif //#if defined(USE_EAP_TRACE) + +//-------------------------------------------------- + +#if defined(USE_EAP_TRACE) + +EAP_FUNC_EXPORT void eap_radius_c::trace_tunneled_packet( + eap_const_string prefix, + const eap_header_base_c * const eap_packet) +{ + if (eap_packet == 0 + || eap_packet->get_is_valid() == false) + { + // ERROR: Cannot trace invalid packet. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s: %s: Cannot trace invalid packet.\n"), + prefix, + (m_is_client == true) ? "client": "server")); + return; + } + + if ((m_am_tools->get_trace_mask() & TRACE_FLAGS_DEFAULT) + && m_pseudo_ethernet_header.get_is_valid_data() == true + && m_pseudo_ethernet_header.get_data_length() >= sizeof(EAP_PSEUDO_ETHERNET_HEADER)) + { + m_pseudo_ethernet_header.set_data_length(sizeof(EAP_PSEUDO_ETHERNET_HEADER)); + + u32_t eap_packet_length = eap_packet->get_length(); + if (eap_packet->get_header_buffer_length() < eap_packet_length) + { + eap_packet_length = eap_packet->get_header_buffer_length(); + } + + eap_status_e status = m_pseudo_ethernet_header.add_data_to_offset( + sizeof(EAP_PSEUDO_ETHERNET_HEADER), + eap_packet->get_header_buffer(eap_packet_length), + eap_packet_length); + + if (status == eap_status_ok) + { + m_pseudo_ethernet_header.set_data_length( + sizeof(EAP_PSEUDO_ETHERNET_HEADER) + eap_packet_length); + + // Sets the EAPOL packet data length. + eapol_header_wr_c eapol( + m_am_tools, + m_pseudo_ethernet_header.get_data_offset( + EAP_PSEUDO_EAPOL_HEADER_OFFSET, + m_pseudo_ethernet_header.get_data_length()-EAP_PSEUDO_EAPOL_HEADER_OFFSET), + m_pseudo_ethernet_header.get_data_length()-EAP_PSEUDO_EAPOL_HEADER_OFFSET); + + if (eapol.get_is_valid() == true) + { + eapol.set_data_length(static_cast(eap_packet_length)); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: %s: type=0x%08x, packet_length 0x%04x\n"), + prefix, + (m_is_client == true) ? "client": "server", + convert_eap_type_to_u32_t(eap_packet->get_type()), + eap_packet->get_length())); // NOTE, this will trace the values from the header of the EAP-packet. + + EAP_TRACE_DATA_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (prefix, + m_pseudo_ethernet_header.get_data(m_pseudo_ethernet_header.get_data_length()), + m_pseudo_ethernet_header.get_data_length())); + } + } + } +} + +#endif //#if defined(USE_EAP_TRACE) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_radius_c::get_is_client() +{ + return m_is_client; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_radius_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_radius_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_radius_header_base_c * const received_eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_RADIUS_PACKET_TRACE( + EAPL("->"), + receive_network_id, + received_eap, + eap_packet_length); + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_c::packet_process(): receive_network_id=0x%08x is invalid.\n"), + receive_network_id)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (received_eap == 0 + || received_eap->get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_c::packet_process(): received_eap 0x%08x is invalid.\n"), + received_eap)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (eap_packet_length < received_eap->get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_c::packet_process(): ") + EAPL("eap_packet_length=0x%04x < received_eap->get_length()=0x%04x.\n"), + eap_packet_length, received_eap->get_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (received_eap->get_length() < eap_header_base_c::get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_c::packet_process(): received_eap->get_length() ") + EAPL("< eap_header_base_c::get_header_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + + // NOTE: by disabling these calls throughput increases about 18%. + // Disabling also decreases random seeds. + m_am_tools->get_crypto()->add_rand_seed( + received_eap->get_header_buffer(eap_packet_length), + eap_packet_length); + m_am_tools->get_crypto()->add_rand_seed_hw_ticks(); + + + eap_status_e status = eap_status_process_general_error; + + if ((m_is_client == true + && received_eap->get_code() == eap_radius_code_access_challenge) + || (m_is_client == false + && received_eap->get_code() == eap_radius_code_access_request)) + { + eap_radius_header_base_c radius_header( + m_am_tools, + received_eap->get_header_buffer(received_eap->get_header_buffer_length()), + received_eap->get_header_buffer_length()); + + if (radius_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = radius_packet_process( + receive_network_id, + &radius_header, + eap_packet_length, + m_is_client); + + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(received_eap, false); + } + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_drop_packet_quietly + && status != eap_status_pending_request) + { + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: %s=%d eap_radius_c::radius_packet_process() failed\n"), + status_string.get_status_string(status), status)); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (m_is_client == true + && (received_eap->get_code() == eap_radius_code_access_accept + || received_eap->get_code() == eap_radius_code_access_reject)) + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (received_eap->get_code() == eap_radius_code_access_accept) + { + } + else if (received_eap->get_code() == eap_radius_code_access_reject) + { + // EAP is quite sloppy protocol. + // Somebody just send a EAP-failure message and authentication is terminated. + + // Save received failure. We do not change our state yet. + // The real correct EAP message could be received later if this failure was + // send by nasty attacker. + // We handle the EAP-Request/Failure message after a timeout. + + status = eap_status_ok; + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP code unknown: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, is client %d\n"), + received_eap->get_code(), received_eap->get_identifier(), + received_eap->get_length(), (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP code unknown: code=0x%02x, ") + EAPL("identifier=0x%02x, length=0x%04x, is client %d\n"), + received_eap->get_code(), received_eap->get_identifier(), + received_eap->get_length(), (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::radius_packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_radius_header_base_c * const received_radius, + const u32_t radius_packet_length, + const bool is_client_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_c::radius_packet_process(): ") + EAPL("receive_network_id=0x%08x is invalid.\n"), + receive_network_id)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (received_radius == 0 + || received_radius->get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_c::radius_packet_process(): ") + EAPL("received_radius 0x%08x is invalid.\n"), + received_radius)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (radius_packet_length < received_radius->get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_c::radius_packet_process(): ") + EAPL("radius_packet_length < received_radius->get_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + eap_status_e status = eap_status_process_general_error; + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("received: RADIUS packet"), + received_radius->get_header_buffer( + received_radius->get_header_length()+received_radius->get_data_length()), + received_radius->get_header_length()+received_radius->get_data_length())); + + + if (radius_packet_length < eap_radius_header_base_c::get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_c::radius_packet_process(): ") + EAPL("radius_packet_length < eap_radius_header_base_c::get_header_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = received_radius->check_header(); + if (status != eap_status_ok) + { + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: %s=%d eap_radius_c::radius_packet_process(): ") + EAPL("corrupted RADIUS-header.\n"), + status_string.get_status_string(status), status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_radius_payloads_c * const l_radius_payloads = new eap_radius_payloads_c(m_am_tools); + eap_automatic_variable_c l_radius_payloads_automatic( + m_am_tools, + l_radius_payloads); + + if (l_radius_payloads == 0 + || l_radius_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = handle_radius_packet( + receive_network_id, + received_radius, + radius_packet_length, + l_radius_payloads); + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_drop_packet_quietly + && status != eap_status_pending_request) + { + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: %s=%d eap_radius_c::radius_packet_process(): ") + EAPL("handle_radius_packet().\n"), + status_string.get_status_string(status), status)); + } + + if (status == eap_status_ok) + { + // Do nothing special. + } + else if (status == eap_status_drop_packet_quietly) + { + // We will drop this message quietly. + } + else if (status != eap_status_ok) + { + // EAP-Failure will be sent from shutdown(). + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_radius_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + *MTU = 1020; + *trailer_length = 0ul; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0ul; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::timer_expired( + const u32_t id, void *data) +{ + EAP_UNREFERENCED_PARAMETER(id); + EAP_UNREFERENCED_PARAMETER(data); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_radius_c::timer_expired(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + + eap_status_e status = eap_status_process_general_error; + + if (id == EAP_TYPE_RADIUS_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID elapsed.\n"), + (m_is_client == true) ? "client": "server")); + } + else if (id == EAP_TYPE_RADIUS_TIMER_DELAY_NOTIFICATION_MESSAGE_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID elapsed.\n"), + (m_is_client == true) ? "client": "server")); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::timer_delete_data( + const u32_t id, void *data) +{ + EAP_UNREFERENCED_PARAMETER(id); + EAP_UNREFERENCED_PARAMETER(data); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_radius_c::timer_delete_data(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + + if (id == EAP_TYPE_RADIUS_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID delete data.\n"), + (m_is_client == true) ? "client": "server")); + } + else if (id == EAP_TYPE_RADIUS_TIMER_DELAY_NOTIFICATION_MESSAGE_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID delete data.\n"), + (m_is_client == true) ? "client": "server")); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::add_user_name_attribute( + const eap_radius_variable_data_c * const user_name, + eap_radius_header_base_c * const radius_header, + u32_t * const radius_attribute_offset, + crypto_hmac_c * const hmac_message_auth, + crypto_md5_c * const md5_response_auth) +{ + const u32_t user_name_length + = eap_radius_attribute_header_c::get_header_length() + + user_name->get_data_length(); + + eap_radius_attribute_header_c user_name_attribute( + m_am_tools, + radius_header->get_data_offset( + *radius_attribute_offset, + user_name_length), + user_name_length); + if (user_name_attribute.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + user_name_attribute.reset_header( + static_cast(user_name_length + -eap_radius_attribute_header_c::get_header_length())); + + user_name_attribute.set_current_payload(eap_diameter_avp_code_user_name); + + u8_t * const data = user_name_attribute.get_data_offset( + 0ul, + user_name->get_data_length()); + if (data == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + data, + user_name->get_data(user_name->get_data_length()), + user_name->get_data_length()); + + eap_status_e status = hmac_message_auth->hmac_update( + user_name_attribute.get_header_buffer( + user_name_attribute.get_header_buffer_length()), + user_name_attribute.get_header_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5_response_auth->hash_update( + user_name_attribute.get_header_buffer( + user_name_attribute.get_header_buffer_length()), + user_name_attribute.get_header_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("User-Name"), + user_name_attribute.get_header_buffer( + user_name_attribute.get_header_buffer_length()), + user_name_attribute.get_header_buffer_length())); + + *radius_attribute_offset += user_name_length; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_c::xor_values( + u8_t * const plaintext, + const u32_t plaintext_length, + const eap_variable_data_c * const intermediate_value) +{ + u8_t * const intermediate_value_data = intermediate_value->get_data(plaintext_length); + + if (intermediate_value_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + for (u32_t ind = 0ul; ind < plaintext_length; ind++) + { + plaintext[ind] = plaintext[ind] ^ intermediate_value_data[ind]; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::encrypt_ms_mppe_key_attribute( + const eap_variable_data_c * const shared_secret, + const eap_variable_data_c * const request_authenticator, + const u8_t * salt, + const u32_t salt_length, + u8_t * const data, + const u32_t data_length) +{ + crypto_md5_c md5( + m_am_tools); + + eap_status_e status = md5.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5.hash_update( + shared_secret->get_data(), + shared_secret->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5.hash_update( + request_authenticator->get_data(), + request_authenticator->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5.hash_update( + salt, + salt_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + const u32_t block_size = md5.get_digest_length(); + const u32_t chunks_count = data_length/block_size; + + if ((data_length % block_size) != 0) + { + // ERROR + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + eap_variable_data_c intermediate_value(m_am_tools); + + status = intermediate_value.init(block_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = intermediate_value.set_data_length(block_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (u32_t ind = 0ul; ind < chunks_count; ind++) + { + status = md5.hash_final( + intermediate_value.get_data(block_size), + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + xor_values( + data+(ind*block_size), + block_size, + &intermediate_value); + + status = md5.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5.hash_update( + shared_secret->get_data(), + shared_secret->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = md5.hash_update( + data+(ind*block_size), + block_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } // for() + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::add_one_ms_mppe_key_attribute( + const eap_variable_data_c * const shared_secret, + const eap_variable_data_c * const request_authenticator, + eap_radius_header_base_c * const radius_header, + u32_t * const radius_attribute_offset, + const u8_t * const key, + const u32_t key_length, + const eap_diameter_avp_code_c mppe_key_type, + crypto_hmac_c * const hmac_message_auth, + crypto_md5_c * const md5_response_auth) +{ + const u32_t vendor_specific_length + = eap_radius_attribute_header_c::get_header_length() + + EAP_RADIUS_VENDOR_ID_LENGTH; + + const u32_t mppe_key_length + = eap_radius_attribute_header_c::get_header_length() + + EAP_RADIUS_MS_MPPE_KEY_DATA_LENGTH; + + const u32_t attribute_length + = vendor_specific_length + + mppe_key_length; + + eap_radius_attribute_header_c vendor_specific( + m_am_tools, + radius_header->get_data_offset( + *radius_attribute_offset, + attribute_length), + attribute_length); + if (vendor_specific.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + vendor_specific.reset_header( + static_cast(attribute_length + -eap_radius_attribute_header_c::get_header_length())); + + vendor_specific.set_current_payload(eap_diameter_avp_code_vendor_specific); + + u8_t * const vendor_id = vendor_specific.get_data_offset(0ul, sizeof(u32_t)); + if (vendor_id == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t vendor_id_data_offset = 0ul; + + eap_write_u32_t_network_order( + vendor_id, + sizeof(u32_t), + eap_diameter_vendor_id_of_microsoft); + + vendor_id_data_offset += sizeof(u32_t); + + *radius_attribute_offset += vendor_specific_length; + + + eap_radius_attribute_header_c mppe_key( + m_am_tools, + vendor_specific.get_data_offset( + vendor_id_data_offset, + mppe_key_length), + mppe_key_length); + if (mppe_key.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + mppe_key.reset_header( + static_cast(mppe_key_length + -eap_radius_attribute_header_c::get_header_length())); + mppe_key.set_current_payload(mppe_key_type); + + u8_t * const key_data = mppe_key.get_data_offset(0ul, EAP_RADIUS_MS_MPPE_KEY_DATA_LENGTH); + if (key_data == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t key_offset = 0ul; + + u16_t salt_field = 0x8000 | m_salt++; + + eap_write_u16_t_network_order( + key_data+key_offset, + sizeof(u16_t), + salt_field); + key_offset += sizeof(u16_t); + + u8_t * const encrypted_data = key_data+key_offset; + *(key_data+key_offset) = static_cast(key_length); + key_offset += sizeof(u8_t); + + m_am_tools->memmove(key_data+key_offset, key, key_length); + key_offset += key_length; + + u32_t encrypted_data_length = EAP_RADIUS_MS_MPPE_KEY_DATA_LENGTH-(sizeof(u16_t)); + + m_am_tools->memset(key_data+key_offset, 0, EAP_RADIUS_MS_MPPE_KEY_DATA_LENGTH-key_length); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Plain text MPPE key"), + vendor_specific.get_header_buffer(vendor_specific.get_header_buffer_length()), + vendor_specific.get_header_buffer_length())); + + eap_status_e status = encrypt_ms_mppe_key_attribute( + shared_secret, + request_authenticator, + key_data, //salt + sizeof(u16_t), // salt_length, + encrypted_data, + encrypted_data_length); + + *radius_attribute_offset += mppe_key_length; + + status = hmac_message_auth->hmac_update( + vendor_specific.get_header_buffer( + vendor_specific.get_header_buffer_length()), + vendor_specific.get_header_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5_response_auth->hash_update( + vendor_specific.get_header_buffer( + vendor_specific.get_header_buffer_length()), + vendor_specific.get_header_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("Encrypted MPPE key"), + vendor_specific.get_header_buffer(vendor_specific.get_header_buffer_length()), + vendor_specific.get_header_buffer_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::add_ms_mppe_key_attributes( + const eap_variable_data_c * const shared_secret, + const eap_variable_data_c * const master_session_key, + const eap_variable_data_c * const request_authenticator, + eap_radius_header_base_c * const radius_header, + u32_t * const radius_attribute_offset, + crypto_hmac_c * const hmac_message_auth, + crypto_md5_c * const md5_response_auth) +{ + eap_status_e status = add_one_ms_mppe_key_attribute( + shared_secret, + request_authenticator, + radius_header, + radius_attribute_offset, + master_session_key->get_data(EAP_RADIUS_MS_MPPE_KEY_LENGTH), + EAP_RADIUS_MS_MPPE_KEY_LENGTH, + eap_diameter_vendor_code_of_microsoft_ms_mppe_recv_key.get_code(), + hmac_message_auth, + md5_response_auth); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_one_ms_mppe_key_attribute( + shared_secret, + request_authenticator, + radius_header, + radius_attribute_offset, + master_session_key->get_data_offset( + EAP_RADIUS_MS_MPPE_KEY_LENGTH, + EAP_RADIUS_MS_MPPE_KEY_LENGTH), + EAP_RADIUS_MS_MPPE_KEY_LENGTH, + eap_diameter_vendor_code_of_microsoft_ms_mppe_send_key.get_code(), + hmac_message_auth, + md5_response_auth); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length, + eap_radius_session_c * const session) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_c::packet_send().\n"))); + + eap_header_rd_c eap( + m_am_tools, + sent_packet->get_data_offset( + header_offset, data_length), + data_length); + if (eap.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + trace_tunneled_packet(EAPL("<- TUNNELED packet server"), &eap); + + crypto_md5_c md5_message_auth( + m_am_tools); + + crypto_hmac_c hmac_message_auth( + m_am_tools, + &md5_message_auth, + false); + if (hmac_message_auth.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = hmac_message_auth.hmac_set_key(session->get_shared_secret()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + crypto_md5_c md5_response_auth( + m_am_tools); + + status = md5_response_auth.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u32_t fragment_count + = (1ul + + eap.get_length() + / eap_radius_attribute_header_c::get_max_attribute_data_length()); + + u32_t eap_payload_length + = eap.get_length() + + eap_radius_attribute_header_c::get_header_length() * fragment_count; + + u32_t packet_data_length + = eap_radius_header_base_c::get_header_length() + + eap_payload_length + + eap_radius_attribute_header_c::get_header_length() + + hmac_message_auth.get_digest_length(); + + if (session->get_state() == eap_state_authentication_finished_successfully) + { + // Successfully finished authentication. + // The keys must be added. + packet_data_length + += 2ul * (2ul * eap_radius_attribute_header_c::get_header_length() + + EAP_RADIUS_VENDOR_ID_LENGTH + + EAP_RADIUS_MS_MPPE_KEY_DATA_LENGTH) + + eap_radius_attribute_header_c::get_header_length() + + session->get_user_name()->get_data_length(); + } + + eap_buf_chain_wr_c challenge( + eap_write_buffer, + m_am_tools, + packet_data_length); + + if (challenge.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + eap_radius_header_base_c radius_header( + m_am_tools, + reinterpret_cast( + challenge.get_data_offset(0ul, packet_data_length)), + packet_data_length); + if (radius_header.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + radius_header.reset_header(static_cast(packet_data_length)); + + radius_header.set_identifier(session->get_identifier()); + + if (session->get_state() == eap_state_authentication_finished_successfully + /* && eap.get_code() == eap_code_success */) + { + // Successfully finished authentication. + radius_header.set_code(eap_radius_code_access_accept); + } + else if (session->get_state() == eap_state_authentication_terminated_unsuccessfully + && eap.get_code() == eap_code_failure) + { + // Failed authentication. + radius_header.set_code(eap_radius_code_access_reject); + } + else if (eap.get_code() == eap_code_request + || eap.get_code() == eap_code_response + || eap.get_code() == eap_code_success) + { + radius_header.set_code(eap_radius_code_access_challenge); + } + else + { + // Illegal combination. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Illegal combination eap.code %d, session.state %d.\n"), + eap.get_code(), + session->get_state())); + EAP_ASSERT_ANYWAY_TOOLS(m_am_tools); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); + } + + + { + // Type, Identifier and Length fields. + const u32_t hmac_fields_length = 4ul; + + { + status = hmac_message_auth.hmac_update( + radius_header.get_header_buffer(hmac_fields_length), + hmac_fields_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_message_auth.hmac_update( + session->get_request_authenticator()->get_data(), + session->get_request_authenticator()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + + { + status = md5_response_auth.hash_update( + radius_header.get_header_buffer(hmac_fields_length), + hmac_fields_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5_response_auth.hash_update( + session->get_request_authenticator()->get_data(), + session->get_request_authenticator()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + u32_t radius_attribute_offset(0ul); + + if (session->get_state() == eap_state_authentication_finished_successfully) + { + // Successfully finished authentication. + // The MPPE keys and User-Name must be added. + status = add_ms_mppe_key_attributes( + session->get_shared_secret(), + session->get_master_session_key(), + session->get_request_authenticator(), + &radius_header, + &radius_attribute_offset, + &hmac_message_auth, + &md5_response_auth); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_user_name_attribute( + session->get_user_name(), + &radius_header, + &radius_attribute_offset, + &hmac_message_auth, + &md5_response_auth); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + u32_t remaining_eap_data_length = eap.get_length(); + u8_t * eap_data = eap.get_header_buffer(remaining_eap_data_length); + if (eap_data == 0) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t max_data_length + = eap_radius_attribute_header_c::get_max_attribute_data_length() + - eap_radius_attribute_header_c::get_header_length(); + + for (u32_t ind = 0ul; ind < fragment_count; ind++) + { + u32_t fragment_length = remaining_eap_data_length; + if (fragment_length > max_data_length) + { + fragment_length = max_data_length; + } + + eap_radius_attribute_header_c fragment( + m_am_tools, + radius_header.get_data_offset( + radius_attribute_offset + + ind * eap_radius_attribute_header_c::get_max_attribute_data_length(), + fragment_length), + eap_radius_attribute_header_c::get_header_length()+fragment_length); + if (fragment.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + fragment.reset_header(static_cast(fragment_length)); + fragment.set_current_payload(eap_diameter_avp_code_eap_message); + + u8_t * const data = fragment.get_data_offset(0ul, fragment_length); + if (data == 0) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove(data, eap_data, fragment_length); + + status = hmac_message_auth.hmac_update( + fragment.get_header_buffer(fragment.get_length()), + fragment.get_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5_response_auth.hash_update( + fragment.get_header_buffer(fragment.get_length()), + fragment.get_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + remaining_eap_data_length -= fragment_length; + eap_data += fragment_length; + + } // for() + + + radius_attribute_offset += eap_payload_length; + + u32_t authenticator_length + = eap_radius_attribute_header_c::get_header_length() + + hmac_message_auth.get_digest_length(); + + eap_radius_attribute_header_c authenticator( + m_am_tools, + radius_header.get_data_offset( + radius_attribute_offset, + authenticator_length), + authenticator_length); + if (authenticator.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + authenticator.reset_header(static_cast(hmac_message_auth.get_digest_length())); + authenticator.set_current_payload(eap_diameter_avp_code_message_authenticator); + + { + u8_t * const signature + = authenticator.get_data_offset( + 0ul, + authenticator.get_data_length()); + + m_am_tools->memset(signature, 0, authenticator.get_data_length()); + + status = hmac_message_auth.hmac_update( + authenticator.get_header_buffer(authenticator.get_length()), + authenticator.get_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_message_auth.hmac_final( + signature, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5_response_auth.hash_update( + authenticator.get_header_buffer(authenticator.get_length()), + authenticator.get_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + { + status = md5_response_auth.hash_update( + session->get_shared_secret()->get_data(), + session->get_shared_secret()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5_response_auth.hash_final( + radius_header.get_authenticator(), + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + challenge.set_data_length(packet_data_length); + + EAP_RADIUS_PACKET_TRACE( + EAPL("<-"), + network_id, + &radius_header, + packet_data_length); + + status = m_partner->packet_send( + network_id, + &challenge, + header_offset, + packet_data_length, + challenge.get_buffer_length() + ); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (cf_str_EAP_CORE_send_eap_success_after_notification.get_field()->compare( + m_am_tools, + field) == true) + { + // In Radius server EAP-Success must be send after state notification. + u32_t send_eap_success_after_notification(true); + + const eap_status_e status = data->set_copy_of_buffer( + &send_eap_success_after_notification, + sizeof(send_eap_success_after_notification)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const eap_status_e status = m_partner->read_configure(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_partner->write_configure(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in eap_base_type_c::configure(). +EAP_FUNC_EXPORT eap_status_e eap_radius_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_c::configure(): this = 0x%08x => 0x%08x\n"), + this, + dynamic_cast(this))); + + m_radius_header_offset = m_partner->get_header_offset( + &m_MTU, &m_trailer_length); + + if (m_radius_header_offset+m_MTU+m_trailer_length + > EAP_TYPE_RADIUS_LOCAL_PACKET_BUFFER_LENGTH) + { + EAP_ASSERT_ALWAYS(EAP_TYPE_RADIUS_LOCAL_PACKET_BUFFER_LENGTH + >= (m_radius_header_offset+m_trailer_length)); + + m_MTU = EAP_TYPE_RADIUS_LOCAL_PACKET_BUFFER_LENGTH + - (m_radius_header_offset+m_trailer_length); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::shutdown_operation( + eap_radius_session_c * const session, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = session->shutdown(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in eap_base_type_c::shutdown(). +EAP_FUNC_EXPORT eap_status_e eap_radius_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_c::shutdown(): this = 0x%08x => 0x%08x\n"), + this, + dynamic_cast(this))); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + eap_status_e status = m_session_map.for_each(shutdown_operation, true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This function is to allow reuse of this object. +// The whole object state must be reset. +EAP_FUNC_EXPORT eap_status_e eap_radius_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RADIUS: %s: function: eap_radius_c::reset(): this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + eap_status_e status = eap_status_not_supported; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = m_partner->load_module( + type, + tunneling_type, + partner, + eap_type, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->unload_module(type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::restart_authentication( + const eap_am_network_id_c * const send_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eap_radius_c::asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_session_core_c::asynchronous_init_remove_eap_session(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_status_e status = eap_status_process_general_error; + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_c::check_is_valid_eap_type( + const eap_type_value_e eap_type) +{ + eap_status_e status = m_partner->check_is_valid_eap_type(eap_type); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + eap_status_e status = m_partner->get_eap_type_list(eap_type_list); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_partner->add_rogue_ap(rogue_ap_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::set_session_timeout( + const u32_t /* session_timeout_ms */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_attribute_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_attribute_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,222 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 102 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_radius_attribute_header.h" +#include "eap_header_string.h" + + +/** @file */ + + +// +EAP_FUNC_EXPORT eap_radius_attribute_header_c::~eap_radius_attribute_header_c() +{ +} + +// +EAP_FUNC_EXPORT eap_radius_attribute_header_c::eap_radius_attribute_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT eap_diameter_avp_code_c eap_radius_attribute_header_c::get_current_payload() const +{ + const u8_t * const payload_data = get_header_offset(m_type_offset, sizeof(u8_t)); + if (payload_data != 0) + { + eap_diameter_avp_code_c avp_code(static_cast(*payload_data)); + return avp_code; + } + else + { + return eap_diameter_avp_code_none; + } +} + +EAP_FUNC_EXPORT u16_t eap_radius_attribute_header_c::get_length() const +{ + const u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u8_t)); + if (length_data != 0) + { + return static_cast(*length_data); + } + else + { + return 0ul; + } +} + +EAP_FUNC_EXPORT u32_t eap_radius_attribute_header_c::get_data_length() const +{ + if (get_length() > get_header_length()) + return static_cast(get_length()-get_header_length()); + else + return 0; +} + +EAP_FUNC_EXPORT u16_t eap_radius_attribute_header_c::get_header_length() +{ + return m_data_offset; +} + +EAP_FUNC_EXPORT u16_t eap_radius_attribute_header_c::get_max_attribute_data_length() +{ + return static_cast((0xff & (~0)) - get_header_length()); +} + +EAP_FUNC_EXPORT u8_t * eap_radius_attribute_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + u32_t data_length = get_header_buffer_length() - get_header_length(); + + if (data_length >= offset+contignuous_bytes + && contignuous_bytes > 0) + { + u8_t * const data = get_header_offset(m_data_offset, contignuous_bytes); + if (data != 0) + { + return data+offset; // Data begins after the header. + } + else + { + return 0; + } + } + else + { + EAP_ASSERT( + data_length >= offset+contignuous_bytes + && contignuous_bytes > 0); + } + return 0; +} + +EAP_FUNC_EXPORT u8_t * eap_radius_attribute_header_c::get_next_header() const +{ + if (get_header_buffer_length() >= get_data_length()+2ul*get_header_length()) + { + return get_data_offset(get_data_length(), get_header_length()); + } + else + { + return 0; + } +} + +EAP_FUNC_EXPORT void eap_radius_attribute_header_c::set_current_payload( + const eap_diameter_avp_code_c p_current_payload) +{ + u8_t * const payload_type = get_header_offset(m_type_offset, sizeof(u8_t)); + + EAP_ASSERT(payload_type != 0); + + *payload_type = static_cast(p_current_payload.get_vendor_code()); +} + +EAP_FUNC_EXPORT void eap_radius_attribute_header_c::set_data_length(const u16_t p_data_length) +{ + u32_t total_length = p_data_length+eap_radius_attribute_header_c::get_header_length(); + + u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u8_t)); + + EAP_ASSERT(length_data != 0); + + *length_data = static_cast(total_length); +} + +EAP_FUNC_EXPORT void eap_radius_attribute_header_c::reset_header(const u16_t data_length) +{ + set_current_payload(eap_diameter_avp_code_none); + set_data_length(data_length); +} + +EAP_FUNC_EXPORT eap_const_string eap_radius_attribute_header_c::get_payload_type_string() const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + const eap_diameter_avp_code_c payload_type = get_current_payload(); + + EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_none) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_user_name) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_user_password) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_chap_password) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_nas_ip_address) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_nas_port) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_service_type) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_framed_protocol) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_framed_ip_address) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_framed_ip_netmask) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_framed_routing) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_filter_id) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_framed_mtu) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_framed_compression) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_login_ip_host) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_login_service) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_login_tcp_port) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_reply_message) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_callback_number) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_callback_id) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_framed_route) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_framed_ipx_network) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_state) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_class) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_vendor_specific) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_session_timeout) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_idle_timeout) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_termination_action) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_called_station_id) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_calling_station_id) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_nas_identifier) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_proxy_state) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_login_lat_service) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_login_lat_node) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_login_lat_group) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_framed_appletalk_link) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_framed_appletalk_network) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_framed_appletalk_zone) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_chap_challenge) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_nas_port_type) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_port_limit) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_login_lat_port) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_eap_message) + else EAP_IF_RETURN_STRING(payload_type, eap_diameter_avp_code_message_authenticator) +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown RADIUS payload AT"); + } +} + +EAP_FUNC_EXPORT eap_status_e eap_radius_attribute_header_c::check_header() const +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_client.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_client.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 103 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_radius.h" +#include "eap_radius_header.h" +#include "eap_radius_payloads.h" +#include "eap_radius_mac_attributes.h" +#include "abs_eap_am_radius.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" +#include "abs_eap_am_mutex.h" +#include "eap_automatic_variable.h" + + +//-------------------------------------------------- + +/** @file */ + +//-------------------------------------------------- + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,249 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 105 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_radius_header.h" +#include "eap_radius_header_string.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_radius_header_base_c::~eap_radius_header_base_c() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_radius_header_base_c::eap_radius_header_base_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_radius_header_base_c::get_header_length() +{ + return m_attributes_offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_radius_code_value_e eap_radius_header_base_c::get_code() const +{ + const u8_t * const code_data = get_header_offset(m_code_offset, sizeof(u8_t)); + if (code_data != 0) + { + return static_cast(*code_data); + } + else + { + return eap_radius_code_none; + } +} + +/// This function returns the authenticator field of RADIUS-header. +EAP_FUNC_EXPORT u8_t * eap_radius_header_base_c::get_authenticator() const +{ + u8_t * authenticator = get_header_offset( + m_authenticator_offset, + get_authenticator_length()); + if (authenticator != 0) + { + return authenticator; + } + else + { + return 0; + } +} + +/// This function returns the length of the authenticator field of RADIUS-header. +EAP_FUNC_EXPORT u32_t eap_radius_header_base_c::get_authenticator_length() const +{ + return EAP_RADIUS_AUTHENTICATOR_LENGTH*sizeof(u8_t); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t eap_radius_header_base_c::get_identifier() const +{ + const u8_t * const identifier_data = get_header_offset(m_identifier_offset, sizeof(u8_t)); + if (identifier_data != 0) + { + return *identifier_data; + } + else + { + return 0xff; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u16_t eap_radius_header_base_c::get_length() const +{ + const u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u16_t)); + if (length_data != 0) + { + return static_cast(static_cast(length_data[0]) << 8 + | static_cast(length_data[1])); + } + else + { + return 0ul; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u16_t eap_radius_header_base_c::get_data_length() const +{ + u32_t length = get_length(); + if (length >= get_header_length()) + { + return static_cast(length-get_header_length()); + } + else + { + return 0ul; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_radius_header_base_c::get_data_offset( + const u32_t p_offset, const u32_t p_continuous_bytes) const +{ + if (get_length() >= static_cast(get_header_length()+p_offset+p_continuous_bytes)) + { + u8_t * const data_begin = get_header_offset(m_attributes_offset, sizeof(u8_t)); + if (data_begin == 0) + { + return 0; + } + return &(data_begin[p_offset]); + } + else + { + return 0; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_radius_header_base_c::set_code(const eap_radius_code_value_e p_code) +{ + u8_t * const code_data = get_header_offset(m_code_offset, sizeof(u8_t)); + EAP_ASSERT(code_data != 0); + + *code_data = static_cast(p_code); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_radius_header_base_c::set_identifier(const u8_t p_identifier) +{ + u8_t * const identifier_data = get_header_offset(m_identifier_offset, sizeof(u8_t)); + EAP_ASSERT(identifier_data != 0); + + *identifier_data = p_identifier; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_radius_header_base_c::set_length(const u16_t p_length) +{ + u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u16_t)); + EAP_ASSERT(length_data != 0); + + length_data[0] = static_cast((p_length & 0xff00) >> 8); + length_data[1] = static_cast(p_length & 0x00ff); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_radius_header_base_c::set_data_length(const u16_t data_length) +{ + u16_t length = static_cast(data_length+get_header_length()); + + u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u16_t)); + EAP_ASSERT(length_data != 0); + + length_data[0] = static_cast((length & 0xff00) >> 8); + length_data[1] = static_cast(length & 0x00ff); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_radius_header_base_c::get_code_string() const +{ + return eap_radius_header_string_c::get_code_string(get_code()); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_header_base_c::check_header() const +{ + eap_status_e status = eap_status_process_general_error; + + if (get_code() > eap_radius_code_maximum_supported + || eap_radius_code_maximum_supported < get_code()) + { + status = eap_status_illegal_eap_code; + + EAP_TRACE_DEBUG( + get_am_tools(), + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eap_header_c::check_header(), illegal code field 0x%02x, eap_status_e %d\n"), + get_code(), + status)); + } + else + { + status = eap_status_ok; + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +/// This function resets the RADIUS-header. +/// The buffer_length parameter is the length of the RADISU-header and the following attribute data buffer. +EAP_FUNC_EXPORT void eap_radius_header_base_c::reset_header(u16_t buffer_length) +{ + set_code(eap_radius_code_none); + set_identifier(0u); + set_length(buffer_length); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_header_string.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_header_string.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 106 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +/** @file */ + +#include "eap_tools.h" +#include "eap_radius_header_string.h" + +//------------------------------------------------------------------------------ + +EAP_FUNC_EXPORT eap_radius_header_string_c::~eap_radius_header_string_c() +{ +} + +EAP_FUNC_EXPORT eap_radius_header_string_c::eap_radius_header_string_c() +{ +} + +EAP_FUNC_EXPORT eap_const_string eap_radius_header_string_c::get_code_string( + const eap_radius_code_value_e code) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(code, eap_radius_code_none) + else EAP_IF_RETURN_STRING(code, eap_radius_code_access_request) + else EAP_IF_RETURN_STRING(code, eap_radius_code_access_accept) + else EAP_IF_RETURN_STRING(code, eap_radius_code_access_reject) + else EAP_IF_RETURN_STRING(code, eap_radius_code_accounting_request) + else EAP_IF_RETURN_STRING(code, eap_radius_code_accounting_response) + else EAP_IF_RETURN_STRING(code, eap_radius_code_access_challenge) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown EAP-code"); + } +} + +//------------------------------------------------------------------------------ + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_initialized.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_initialized.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 107 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_radius_initialized.h" + + +// +eap_radius_initialized_c::~eap_radius_initialized_c() +{ +} + +// +eap_radius_initialized_c::eap_radius_initialized_c( + abs_eap_am_tools_c * const tools, + abs_eap_radius_state_c * const /*partner*/) + : m_am_tools(tools) + , m_counter(1u) +{ +} + +u32_t eap_radius_initialized_c::counter() +{ + return m_counter; +} + +void eap_radius_initialized_c::increment() +{ + ++m_counter; +} + +//-------------------------------------------------- + +void eap_radius_initialized_c::reset() +{ + m_counter = 0u; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_mac_attributes.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_mac_attributes.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 108 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_radius_mac_attributes.h" + + +//-------------------------------------------------- + +eap_radius_MAC_attributes_c::~eap_radius_MAC_attributes_c() +{ +} + +eap_radius_MAC_attributes_c::eap_radius_MAC_attributes_c() + : m_MAC(0) + , m_MAC_size(0) + , m_data(0) + , m_data_length(0u) +{ +} + +eap_radius_MAC_attributes_c::eap_radius_MAC_attributes_c( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length) + : m_MAC(MAC) + , m_MAC_size(MAC_size) + , m_data(EAP_data) + , m_data_length(EAP_data_length) +{ +} + +void eap_radius_MAC_attributes_c::init( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length) +{ + m_MAC = (MAC); + m_MAC_size = (MAC_size); + m_data = (EAP_data); + m_data_length = (EAP_data_length); +} + +u8_t * eap_radius_MAC_attributes_c::get_MAC() const +{ + return m_MAC; +} + +void eap_radius_MAC_attributes_c::set_MAC(u8_t * MAC) +{ + m_MAC = MAC; +} + +u32_t eap_radius_MAC_attributes_c::get_MAC_size() const +{ + return m_MAC_size; +} + +eap_radius_MAC_attributes_c * eap_radius_MAC_attributes_c::copy() const +{ + return new eap_radius_MAC_attributes_c( + m_MAC, + m_MAC_size, + m_data, + m_data_length); +} + +u8_t * eap_radius_MAC_attributes_c::get_data() const +{ + return m_data; +} + +u32_t eap_radius_MAC_attributes_c::get_data_length() +{ + return m_data_length; +} + +void eap_radius_MAC_attributes_c::set_data(u8_t * const data) +{ + m_data = data; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_payloads.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_payloads.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,433 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 109 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_radius_payloads.h" +#include "abs_eap_am_tools.h" +#include "eap_tools.h" + + + +EAP_FUNC_EXPORT eap_radius_variable_data_c::~eap_radius_variable_data_c() +{ +} + +EAP_FUNC_EXPORT eap_radius_variable_data_c::eap_radius_variable_data_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_data(tools) + , m_payload_type(eap_diameter_avp_code_none) +{ +} + +EAP_FUNC_EXPORT eap_status_e eap_radius_variable_data_c::set_buffer( + const eap_diameter_avp_code_c current_payload, + const u8_t * const buffer, + const u32_t buffer_length, + const bool free_buffer, + const bool is_writable) +{ + eap_status_e status = m_data.set_buffer( + buffer, + buffer_length, + free_buffer, + is_writable); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_payload_type = current_payload; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e eap_radius_variable_data_c::add_data( + const u8_t * const buffer, + const u32_t buffer_length) +{ + eap_status_e status = m_data.add_data( + buffer, + buffer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT u32_t eap_radius_variable_data_c::get_data_length() const +{ + return m_data.get_data_length(); +} + +EAP_FUNC_EXPORT u8_t * eap_radius_variable_data_c::get_data(const u32_t data_length) const +{ + return m_data.get_data(data_length); +} + +EAP_FUNC_EXPORT eap_variable_data_c * eap_radius_variable_data_c::get_payload_buffer() +{ + return &m_data; +} + +EAP_FUNC_EXPORT eap_diameter_avp_code_c eap_radius_variable_data_c::get_payload_type() const +{ + return m_payload_type; +} + +EAP_FUNC_EXPORT void eap_radius_variable_data_c::set_payload_type(const eap_diameter_avp_code_c type) +{ + m_payload_type = type; +} + +EAP_FUNC_EXPORT eap_radius_variable_data_c * eap_radius_variable_data_c::copy() const +{ + eap_radius_variable_data_c * new_data = new eap_radius_variable_data_c(m_am_tools); + + if (new_data != 0) + { + eap_status_e status = new_data->get_payload_buffer()->add_data(&m_data); + if (status != eap_status_ok) + { + delete new_data; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + new_data->set_payload_type(get_payload_type()); + } + + return new_data; +} + +EAP_FUNC_EXPORT void eap_radius_variable_data_c::object_increase_reference_count() +{ +} + + + +EAP_FUNC_EXPORT eap_radius_payloads_c::~eap_radius_payloads_c() +{ +} + +EAP_FUNC_EXPORT eap_radius_payloads_c::eap_radius_payloads_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_payload_map(tools, this) + , m_is_valid(false) +{ + m_is_valid = true; +} + +EAP_FUNC_EXPORT eap_radius_variable_data_c * eap_radius_payloads_c::get_payload( + const eap_diameter_avp_code_c current_payload) +{ + eap_variable_data_c selector(m_am_tools); + + selector.set_buffer( + ¤t_payload, + sizeof(current_payload), + false, + false); + + eap_radius_variable_data_c *payload = m_payload_map.get_handler(&selector); + + return payload; +} + + +EAP_FUNC_EXPORT eap_status_e eap_radius_payloads_c::add_payload( + const eap_diameter_avp_code_c current_payload, + const u8_t * const data, + const u32_t data_length, + const bool free_buffer, + const bool is_writable, + const bool fragments_allowed) +{ + eap_status_e status(eap_status_process_general_error); + + eap_radius_variable_data_c *payload = get_payload( + current_payload); + if (payload != 0) + { + if (fragments_allowed == true) + { + // Add fragment to the end of the existing payload. + status = payload->add_data(data, data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Caanot add fragment. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + else + { + eap_variable_data_c selector(m_am_tools); + + selector.set_buffer( + ¤t_payload, + sizeof(current_payload), + false, + false); + + eap_radius_variable_data_c *payload = new eap_radius_variable_data_c( + m_am_tools); + if (payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payload->set_buffer( + current_payload, + data, + data_length, + free_buffer, + is_writable); + if (status != eap_status_ok) + { + delete payload; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_payload_map.add_handler(&selector, payload); + if (status != eap_status_ok) + { + delete payload; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +EAP_FUNC_EXPORT bool eap_radius_payloads_c::get_is_valid() const +{ + return m_is_valid; +} + + +//-------------------------------------------------- + +//eap_radius_payloads_c +EAP_FUNC_EXPORT eap_status_e eap_radius_payloads_c::parse_generic_payload( + const eap_diameter_avp_code_c payload_type, + const eap_radius_attribute_header_c * const payload) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_RADIUS_TRACE_PAYLOAD("Parsing payload", payload); + + eap_status_e status(eap_status_process_general_error); + + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Type | Length | Data ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + if (payload->get_data_length() < eap_radius_attribute_header_c::get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_payloads_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%08x=%s, length 0x%04x, data length incorrect 0x%04x.\n"), + payload, + payload_type.get_vendor_code(), + payload->get_payload_type_string(), + payload->get_length(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u32_t data_length = payload->get_data_length(); + + u8_t * const data + = static_cast(payload->get_data_offset(0ul, data_length)); + + if (data == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_payloads_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%08x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, + payload_type.get_vendor_code(), + payload->get_payload_type_string(), + payload->get_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = add_payload( + payload_type, + data, + data_length, + false, + false, + true); // This can be fragmented. + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_payloads_c::parse_radius_payload( + const eap_radius_attribute_header_c * const p_payload, + u32_t * const buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_radius_attribute_header_c payload( + m_am_tools, + p_payload->get_header_buffer(*buffer_length), + *buffer_length); // Const correctness is gone. + + eap_diameter_avp_code_c current_payload = payload.get_current_payload(); + + eap_status_e status = eap_status_header_corrupted; + + if (payload.get_is_valid() == true + && current_payload != eap_diameter_avp_code_none) + { + if (*buffer_length < payload.get_header_length()+payload.get_data_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_payloads_c::parse_radius_payload(0x%08x): current payload 0x%08x=%s, data length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload.get_vendor_code(), + payload.get_payload_type_string(), + payload.get_data_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_payloads_c::parse_radius_payload(): RADIUS-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT_ALWAYS(*buffer_length >= payload.get_header_length()+payload.get_data_length()); + *buffer_length -= payload.get_header_length()+payload.get_data_length(); + + while(*buffer_length >= payload.get_header_length() + && payload.get_is_valid() == true + && payload.get_header_buffer_length() >= (payload.get_header_length()+payload.get_data_length())) + { + payload.set_header_buffer( + payload.get_next_header(), + payload.get_header_buffer_length()-(payload.get_header_length()+payload.get_data_length())); + if (payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + current_payload = payload.get_current_payload(); + + if (*buffer_length < payload.get_header_length()+payload.get_data_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_payloads_c::parse_radius_payload(0x%08x): current payload 0x%08x=%s, data length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload.get_vendor_code(), + payload.get_payload_type_string(), + payload.get_data_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_payloads_c::parse_radius_payload(): RADIUS-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_ASSERT_ALWAYS(*buffer_length >= payload.get_header_length()+payload.get_data_length()); + *buffer_length -= payload.get_header_length()+payload.get_data_length(); + } + } + + if (*buffer_length != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_RADIUS_ERROR, + (EAPL("ERROR: eap_radius_payloads_c::parse_radius_payload(): ") + EAPL("RADIUS-header is corrupted. Buffer length and payload length does not match. %lu illegal bytes.\n"), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_server.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_server.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 110 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#if defined(USE_EAP_TYPE_SERVER_RADIUS) + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_radius.h" +#include "eap_radius_header.h" +#include "eap_radius_payloads.h" +#include "eap_radius_mac_attributes.h" +#include "abs_eap_am_radius.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" +#include "eap_automatic_variable.h" + + +//-------------------------------------------------- + +/** @file */ + +//-------------------------------------------------- + + + +//-------------------------------------------------- + +#endif //#if defined(USE_EAP_TYPE_SERVER_RADIUS) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_session.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_session.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1236 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 111 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_radius_session.h" +#include "eap_state_notification.h" +#include "eap_network_id_selector.h" +#include "abs_eap_am_mutex.h" +#include "eap_config.h" +#include "eap_core.h" +#include "eap_buffer.h" +#include "eap_automatic_variable.h" + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_radius_session_c::~eap_radius_session_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_session_c::~eap_radius_session_c(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + EAP_ASSERT(m_shutdown_was_called == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +// +EAP_FUNC_EXPORT eap_radius_session_c::eap_radius_session_c( + abs_eap_am_tools_c * const tools, + abs_eap_radius_session_c * const partner, + const bool is_client_when_true, + const eap_radius_variable_data_c * const user_name, + const eap_radius_variable_data_c * const nas_ip_address) + : m_partner(partner) + , m_am_tools(tools) + , m_eap_core(0) + , m_master_session_key(tools, eap_type_none) + , m_request_authenticator(tools) + , m_shared_secret(tools) + , m_identifier(0ul) + , m_user_name(0) + , m_nas_ip_address(0) + , m_state(eap_state_none) + , m_remove_session_timeout(EAP_RADIUS_SESSION_REMOVE_SESSION_TIMEOUT) + , m_is_client(is_client_when_true) + , m_is_valid(false) + , m_shutdown_was_called(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_session_c::eap_radius_session_c(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + if (user_name == 0 + || nas_ip_address == 0) + { + return; + } + + m_user_name = user_name->copy(); + m_nas_ip_address = nas_ip_address->copy(); + + if (m_user_name == 0 + || m_nas_ip_address == 0) + { + return; + } + + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::save_request_data( + const void * const data, + const u32_t data_length, + const u8_t identifier) +{ + m_identifier = identifier; + + eap_status_e status = m_request_authenticator.set_copy_of_buffer( + data, + data_length); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u8_t eap_radius_session_c::get_identifier() +{ + return m_identifier; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const eap_variable_data_c * eap_radius_session_c::get_shared_secret() const +{ + return &m_shared_secret; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const eap_variable_data_c * eap_radius_session_c::get_request_authenticator() +{ + return &m_request_authenticator; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const eap_radius_variable_data_c * eap_radius_session_c::get_user_name() +{ + return m_user_name; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_state_variable_e eap_radius_session_c::get_state() +{ + return m_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eap_radius_session_c::get_master_session_key() +{ + return &m_master_session_key; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_radius_session_c::object_increase_reference_count() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_radius_session_c::object_decrease_reference_count() +{ + return 0u; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT abs_eap_radius_session_c * eap_radius_session_c::get_partner() +{ + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + return m_partner; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_radius_session_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_radius_session_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = m_partner->load_module( + type, + tunneling_type, + partner, + eap_type, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_core_c * eap_radius_session_c::create_new_session( + const eap_am_network_id_c * const receive_network_id) +{ + eap_status_e status = eap_status_process_general_error; + + if (m_eap_core != 0) + { + m_eap_core->shutdown(); + } + delete m_eap_core; + m_eap_core = 0; + + // Create a new session. + m_eap_core = new eap_core_c( + m_am_tools, + this, + m_is_client, + receive_network_id, + false); + + if (m_eap_core == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + if (m_eap_core->get_is_valid() == false) + { + m_eap_core->shutdown(); + delete m_eap_core; + m_eap_core = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + status = m_eap_core->configure(); + if (status != eap_status_ok) + { + m_eap_core->shutdown(); + delete m_eap_core; + m_eap_core = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return 0; + } + + return m_eap_core; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::reset() +{ + if (m_eap_core != 0) + { + m_eap_core->shutdown(); + } + delete m_eap_core; + m_eap_core = 0; + + m_master_session_key.reset(); + + m_request_authenticator.reset(); + + m_identifier = 0ul; + + m_state = eap_state_none; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + // Each EAP authentication session includes own eap_core_c object. + // EAP authentication sessions are separated by eap_am_network_id_c object. + + if (packet_data == 0 + || packet_length < eap_header_base_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_header_wr_c eap( + m_am_tools, + packet_data->get_header_buffer(packet_data->get_header_buffer_length()), + packet_data->get_header_buffer_length()); + + if (eap.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (packet_length < eap.get_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (eap.get_code() == eap_code_none) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("-> EAP_session: %s, code=0x%02x=%s, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x=%s, packet length 0x%04x\n"), + (m_is_client == true) ? "client": "server", + eap.get_code(), + eap.get_code_string(), + eap.get_identifier(), + eap.get_length(), + convert_eap_type_to_u32_t(eap.get_type()), + eap.get_type_string(), + packet_length)); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_eap_core != 0 + && m_eap_core->get_marked_removed() == true) + { + if (eap.get_code() == eap_code_request + || eap.get_code() == eap_code_response) + { + // Only EAP-Request or EAP-Response resets the session. + // This reset is delayed. + reset(); + } + } + + if (m_eap_core == 0) + { + // Create a new session. + m_eap_core = create_new_session(receive_network_id); + } + + if (m_eap_core != 0) + { + status = m_eap_core->packet_process( + receive_network_id, + &eap, + packet_length); + } + else + { + status = eap_status_illegal_eap_type; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_header_wr_c eap( + m_am_tools, + sent_packet->get_data_offset(header_offset, data_length), + data_length); + + if (eap.get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_ASSERT(header_offset < sent_packet->get_data_length()); + EAP_ASSERT(data_length <= sent_packet->get_data_length()); + EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("<- EAP_session: %s, code=0x%02x=%s, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x=%s, packet length 0x%04x\n"), + (m_is_client == true) ? "client": "server", + eap.get_code(), + eap.get_code_string(), + eap.get_identifier(), + eap.get_length(), + convert_eap_type_to_u32_t(eap.get_type()), + eap.get_type_string(), + data_length)); + + eap_status_e status = m_partner->packet_send( + send_network_id, + sent_packet, + header_offset, + data_length, + buffer_length, + this); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_radius_session_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const u32_t offset = m_partner->get_header_offset(MTU, trailer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return offset; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + + { + eap_configuration_field_c * const field + = cf_str_EAP_RADIUS_SERVER_shared_secret.get_field()->copy( + m_am_tools, + cf_str_EAP_RADIUS_SERVER_client.get_field(), + m_nas_ip_address->get_payload_buffer()); + + eap_automatic_variable_c + automatic_field(m_am_tools, field); + + eap_status_e status = read_configure( + field, + &m_shared_secret); + if (status == eap_status_ok + && m_shared_secret.get_is_valid_data() == true) + { + // OK shared secret is configured. + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: unknown radius client (IP)"), + m_nas_ip_address->get_payload_buffer()->get_data(), + m_nas_ip_address->get_payload_buffer()->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::shutdown_operation( + eap_core_c * const core, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = core->shutdown(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_session_c::shutdown(): this = 0x%08x => 0x%08x.\n"), + this, + dynamic_cast(this))); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + eap_status_e status = m_eap_core->shutdown(); + delete m_eap_core; + m_eap_core = 0; + + delete m_user_name; + m_user_name = 0; + + delete m_nas_ip_address; + m_nas_ip_address = 0; + + m_partner->cancel_timer(this, EAP_RADIUS_SESSION_REMOVE_SESSION_ID); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAP_RADIUS_SESSION_REMOVE_SESSION_ID cancelled, %s.\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->unload_module(type); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::eap_acknowledge( + const eap_am_network_id_c * const receive_network_id) +{ + // Any Network Protocol packet is accepted as a success indication. + // This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (receive_network_id == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_eap_core != 0) + { + status = m_eap_core->eap_acknowledge( + receive_network_id); + } + else + { + // Here we do not care of missing session. + // Acknowledge is meaningfull only for existing session. + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::restart_authentication( + const eap_am_network_id_c * const send_network_id, + const bool is_client_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + eap_network_id_selector_c selector( + m_am_tools, + send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_eap_core != 0) + { + status = m_eap_core->restart_authentication(send_network_id, is_client_when_true); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool /* is_client_when_true */, + const bool force_clean_restart, + const bool /* from_timer */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_eap_core == 0) + { + // Create a new session. + m_eap_core = create_new_session(receive_network_id); + } + + if (m_eap_core != 0) + { + status = m_partner->restart_authentication( + receive_network_id, + m_is_client, + force_clean_restart); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_CORE_SERVER) + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::send_eap_identity_request( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_session_c::send_eap_identity_request()\n"))); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_eap_core == 0) + { + // Create a new session. + m_eap_core = create_new_session(receive_network_id); + } + + if (m_eap_core != 0) + { + status = m_eap_core->send_eap_identity_request(receive_network_id); + (void) EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_CORE_SERVER) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_master_session_key.set_copy( + master_session_key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->read_configure(field, data); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->write_configure(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::timer_expired( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_radius_session_c::") + EAPL("timer_expired(id 0x%02x, data 0x%08x), %s.\n"), + this, + id, + data, + (m_is_client == true) ? "client": "server")); + + if (id == EAP_RADIUS_SESSION_REMOVE_SESSION_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: EAP_RADIUS_SESSION_REMOVE_SESSION_ID elapsed, %s.\n"), + (m_is_client == true) ? "client": "server")); + + reset(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::timer_delete_data( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_radius_session_c::") + EAPL("timer_delete_data(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::synchronous_remove_eap_session( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_network_id_selector_c selector( + m_am_tools, + &send_network_id); + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +eap_status_e eap_radius_session_c::asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_session_c::asynchronous_init_remove_eap_session(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + eap_network_id_selector_c state_selector( + m_am_tools, + send_network_id); + if (state_selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = asynchronous_init_remove_eap_session( + &state_selector); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eap_radius_session_c::asynchronous_init_remove_eap_session( + const eap_network_id_selector_c * const state_selector) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_session_c::asynchronous_init_remove_eap_session(): %s.\n"), + (m_is_client == true) ? "client": "server")); + + // NOTE: we cannot call directly synchronous_remove_eap_session(), because we will + // return from here to removed object. + + eap_status_e status = eap_status_process_general_error; + + if (m_eap_core != 0) + { + m_eap_core->set_marked_removed(); + + status = m_partner->set_timer( + this, + EAP_RADIUS_SESSION_REMOVE_SESSION_ID, + 0, + m_remove_session_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_radius_session_c::asynchronous_init_remove_eap_session()") + EAPL(": %s: EAP_RADIUS_SESSION_REMOVE_SESSION_ID timer set.\n"), + (m_is_client == true) ? "client": "server")); + } + else + { + // Not found, cannot remove. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eap_radius_session_c::asynchronous_init_remove_eap_session()") + EAPL(": %s: failed session not found.\n"), + (m_is_client == true) ? "client": "server")); + + status = eap_status_ok; + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_radius_session_c::state_notification( + const abs_eap_state_notification_c * const state) +{ + if (state->get_protocol_layer() == eap_protocol_layer_eap) + { + if (m_state == eap_state_authentication_terminated_unsuccessfully) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: session already failed.\n"))); + return; + } + + m_state = static_cast(state->get_current_state()); + + if (state->get_current_state() == eap_state_identity_response_received) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-Response/Identity received:\n"))); + } + else if (state->get_current_state() == eap_state_identity_request_received) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-Request/Identity received:\n"))); + } + else if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("radius_server_c::state_notification(): ") + EAPL("Protocol layer %d, EAP type 0x%02x, State transition from ") + EAPL("%d=%s to %d=%s, client %d when shutdown was called.\n"), + state->get_protocol_layer(), + state->get_protocol(), + state->get_previous_state(), + state->get_previous_state_string(), + state->get_current_state(), + state->get_current_state_string(), + state->get_is_client())); + } + else if (state->get_current_state() == eap_state_authentication_finished_successfully) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("radius_server_c::state_notification(): ") + EAPL("Protocol layer %d, EAP type 0x%02x, State transition from ") + EAPL("%d=%s to %d=%s, client %d when shutdown was called.\n"), + state->get_protocol_layer(), + state->get_protocol(), + state->get_previous_state(), + state->get_previous_state_string(), + state->get_current_state(), + state->get_current_state_string(), + state->get_is_client())); + } + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::check_is_valid_eap_type( + const eap_type_value_e eap_type) +{ + eap_status_e status = m_partner->check_is_valid_eap_type(eap_type); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + eap_status_e status = m_partner->get_eap_type_list(eap_type_list); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_partner->add_rogue_ap(rogue_ap_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_radius_session_c::set_session_timeout( + const u32_t /* session_timeout_ms */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_state.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_state.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 112 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_radius_header.h" +#include "eap_radius_types.h" +#include "eap_radius_payloads.h" +#include "abs_eap_radius_state.h" +#include "abs_eap_base_timer.h" +#include "eap_radius_state.h" +#include "eap_crypto_api.h" +#include "eap_state_notification.h" + +//-------------------------------------------------- + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_state_notification.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/eap_radius_state_notification.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,209 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 113 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_radius_state_notification.h" +#include "eap_radius_types.h" +#include "eap_tools.h" +#include "eap_radius.h" + + +EAP_FUNC_EXPORT eap_radius_state_notification_c::~eap_radius_state_notification_c() +{ +} + +EAP_FUNC_EXPORT eap_radius_state_notification_c::eap_radius_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : m_am_tools(tools) + , m_layer(layer) + , m_notification_string(tools) + , m_needs_confirmation_from_user(false) + , m_protocol(protocol) + , m_eap_type(eap_type_none) + , m_previous_state(previous_state) + , m_current_state(current_state) + , m_send_network_id(send_network_id) + , m_is_client(is_client) + , m_eap_identifier(eap_identifier) + , m_allow_send_eap_success(allow_send_eap_success) +{ +} + + +#if defined(USE_EAP_EXPANDED_TYPES) + +EAP_FUNC_EXPORT eap_radius_state_notification_c::eap_radius_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : m_am_tools(tools) + , m_layer(layer) + , m_notification_string(tools) + , m_needs_confirmation_from_user(false) + , m_protocol(0ul) + , m_eap_type(eap_type) + , m_previous_state(previous_state) + , m_current_state(current_state) + , m_send_network_id(send_network_id) + , m_is_client(is_client) + , m_eap_identifier(eap_identifier) + , m_allow_send_eap_success(allow_send_eap_success) +{ +} + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + +EAP_FUNC_EXPORT eap_radius_state_notification_c::eap_radius_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : m_am_tools(tools) + , m_layer(layer) + , m_notification_string(tools) + , m_needs_confirmation_from_user(false) + , m_protocol(0ul) + , m_eap_type(eap_type) + , m_previous_state(previous_state) + , m_current_state(current_state) + , m_send_network_id(send_network_id) + , m_is_client(is_client) + , m_eap_identifier(eap_identifier) + , m_allow_send_eap_success(allow_send_eap_success) +{ +} + +EAP_FUNC_EXPORT const eap_am_network_id_c * eap_radius_state_notification_c::get_send_network_id() const +{ + return m_send_network_id; +} + +EAP_FUNC_EXPORT eap_protocol_layer_e eap_radius_state_notification_c::get_protocol_layer() const +{ + return m_layer; +} + +EAP_FUNC_EXPORT u32_t eap_radius_state_notification_c::get_protocol() const +{ + return m_protocol; +} + +EAP_FUNC_EXPORT eap_type_value_e eap_radius_state_notification_c::get_eap_type() const +{ + return m_eap_type; +} + +EAP_FUNC_EXPORT u32_t eap_radius_state_notification_c::get_previous_state() const +{ + return m_previous_state; +} + +EAP_FUNC_EXPORT u32_t eap_radius_state_notification_c::get_current_state() const +{ + return m_current_state; +} + +EAP_FUNC_EXPORT eap_const_string eap_radius_state_notification_c::get_current_state_string() const +{ + // NOTE this is static function. + return eap_radius_c::get_state_string(static_cast(m_current_state)); +} + +EAP_FUNC_EXPORT eap_const_string eap_radius_state_notification_c::get_previous_state_string() const +{ + // NOTE this is static function. + return eap_radius_c::get_state_string(static_cast(m_previous_state)); +} + +EAP_FUNC_EXPORT bool eap_radius_state_notification_c::get_is_client() const +{ + return m_is_client; +} + +EAP_FUNC_EXPORT u8_t eap_radius_state_notification_c::get_eap_identifier() const +{ + return m_eap_identifier; +} + +EAP_FUNC_EXPORT bool eap_radius_state_notification_c::get_allow_send_eap_success() const +{ + return m_allow_send_eap_success; +} + +EAP_FUNC_EXPORT eap_status_e eap_radius_state_notification_c::set_notification_string( + const eap_variable_data_c * const notification_string, + const bool needs_confirmation_from_user) +{ + eap_status_e status = m_notification_string.set_copy_of_buffer(notification_string); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_needs_confirmation_from_user = needs_confirmation_from_user; + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT const eap_variable_data_c * eap_radius_state_notification_c::get_notification_string() const +{ + return &m_notification_string; +} + +EAP_FUNC_EXPORT bool eap_radius_state_notification_c::get_needs_confirmation_from_user() const +{ + return m_needs_confirmation_from_user; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/core/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/core/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,30 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_gsmsim + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_client.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_payloads.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_server.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_state.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_state_notification.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_header.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_initialized.cpp \ + $(WLAN_COMMON)/type/gsmsim/core/eap_type_gsmsim_mac_attributes.cpp + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_gsmsim_simulator.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_testing_tools.$(LIB) \ + -lstdc++ + +# $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_dummy_sim.$(LIB) \ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/abs_eap_radius.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/abs_eap_radius.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,285 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_RADIUS_H_) +#define _ABS_EAP_RADIUS_H_ + +#include "eap_am_export.h" +#include "eap_header.h" +#include "eap_array.h" + +class eap_base_type_c; +class eap_am_network_id_c; +class eap_network_id_selector_c; +class eap_configuration_field_c; +class abs_eap_state_notification_c; +class eap_rogue_ap_entry_c; + + +/// The class is the interface to partner class of the eap_base_type class. +/// This declares the pure virtual member functions EAP-type class could call. +class EAP_EXPORT abs_eap_radius_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_eap_radius_c class does nothing special. + */ + virtual ~abs_eap_radius_c() + { + } + + /** + * The constructor of the abs_eap_radius_c class does nothing special. + */ + abs_eap_radius_c() + { + } + + /** + * The derived class could send packets to partner class with this function. + * @param network_id carries the addresses (network identity) and type of the packet. + * @param sent_packet includes the buffer for the whole packet and initialized + * EAP-packet in correct offset. + * @param header_offset is offset of the EAP-header within the sent_packet. + * @param data_length is length in bytes of the EAP-packet. + * @param buffer_length is length in bytes of the whole packet buffer. + * + * Now some ascii graphics follows. + * @code + * + * +---------------------+-----+---------------------------------------+-------------+ + * | | EAP | data | | + * +---------------------+-----+---------------------------------------+-------------+ + * | | | | + * |<---header_offset--->|<-------------data_length------------------->|<--trailer-->| + * | | + * |<------------------------buffer_length------------------------------------------>| + * + * trailer is the free space in the end of the packet buffer. + * @endcode + * + */ + virtual eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) = 0; + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @param MTU_length is pointer to variable to store the maximum transfer unit (MTU). + * MTU is the maximum EAP-packet length in bytes + * @param trailer_length is pointer to the variable to store length + * of trailer needed by lower levels. + * @return Function returns the offset of EAP-header. + * + * The needed buffer length is ((offset) + (EAP-packet length) + (trailer)) bytes. + * Each layer adds the length of the header to offset. + * Each layer removes the length of the header and trailer from MTU. + * + * Now some ascii graphics follows. + * @code + * |<-------------------------buffer length----------------------------------------->| + * | | + * | +-----+---------------------------------------+ | + * | | EAP | data | | + * | +-----+---------------------------------------+ | + * |<----offset--------->|<----MTU------------------------------------>|<--trailer-->| + * | | | | + * | +-------+---------------------------------------------+ | + * | | EAPOL | data | | + * | +-------+---------------------------------------------+ | + * |<--offset--->|<----MTU-------------------------------------------->|<--trailer-->| + * | | | | + * +-------------+-----------------------------------------------------+-------------+ + * | ETHERNET | data | trailer | + * +-------------+-----------------------------------------------------+-------------+ + * |<----MTU------------------------------------------------------------------------>| + * @endcode + * + */ + virtual u32_t get_header_offset( + u32_t * const MTU_length, + u32_t * const trailer_length) = 0; + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @param master_session_key is pointer to the first byte of the master session key. + * @param master_session_length is count of bytes in the master session key. + */ + virtual eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + * + * EAP-type should store it's parameters to an own database. The own database should be accessed + * through adaptation module of EAP-type. See eap_am_type_gsmsim_simulator_c::type_configure_read. + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + * + * EAP-type should store it's parameters to an own database. The own database should be accessed + * through adaptation module of EAP-type. See eap_am_type_gsmsim_simulator_c::type_configure_write. + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. EAP-type MUST send these + * two notifications to lower layer. + * These two notifications are sent using EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + * See also eap_state_notification_c. + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * @param time_ms is the time of timer in milli seconds. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * @param initializer is pointer to object which set the cancelled timer. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + /** + * This is needed by PEAP type. + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + * @param receive_network_id includes the addresses (network identity) and packet type. + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + /** + * This is needed by PEAP type. + * The unload_module() function unloads the module of a EAP-type. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e unload_module(const eap_type_value_e eap_type) = 0; + + /** + * This is needed by PEAP type. + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + virtual eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list) = 0; + + //-------------------------------------------------- +}; // class abs_eap_radius_c + +#endif //#if !defined(_ABS_EAP_RADIUS_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/abs_eap_radius_session.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/abs_eap_radius_session.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,231 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAP_RADIUS_SESSION_H_) +#define _ABS_EAP_RADIUS_SESSION_H_ + +#include "eap_header.h" +#include "eap_array.h" + +class eap_am_network_id_c; +class eap_buf_chain_wr_c; +class eap_configuration_field_c; +class eap_variable_data_c; +class abs_eap_base_type_c; +class abs_eap_state_notification_c; +class eap_base_type_c; +class eap_rogue_ap_entry_c; +class eap_radius_session_c; + + +/// This class defines the interface the eap_core_c class +/// will use with the partner class (lower layer). +class EAP_EXPORT abs_eap_radius_session_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_eap_core class does nothing special. + */ + virtual ~abs_eap_radius_session_c() + { + } + + /** + * The constructor of the abs_eap_core class does nothing special. + */ + abs_eap_radius_session_c() + { + } + + /** + * The derived class could send packets to partner class with this function. + * @see abs_eap_base_type_c::packet_send(). + */ + virtual eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length, + eap_radius_session_c * const session + ) = 0; + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @see abs_eap_base_type_c::get_header_offset(). + */ + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + /** + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + * @param receive_network_id includes the addresses (network identity) and packet type. + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + /** + * The unload_module() function unloads the module of a EAP-type. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e unload_module(const eap_type_value_e eap_type) = 0; + + /** + * The session calls the restart_authentication() function + * when EAP-authentication is needed with another peer. + * This is also used when session restarts authentication. + * @param receive_network_id includes the addresses (network identity) and packet type. + * @param is_client_when_true indicates whether the EAP-type should act as a client or server, + * in terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + * @param force_clean_restart this selects whether the server removes this session (true) or not (false). + * @param from_timer tells whether the timer calls this function (true) or not (false). + */ + virtual eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer = false) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This function tells lower layer to remove EAP session object asyncronously. + * @param eap_type is pointer to selector that identifies the removed EAP session. + */ + virtual eap_status_e asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * @param time_ms is the time of timer in milli seconds. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * @param initializer is pointer to object which set the cancelled timer. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + /** + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + virtual eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list) = 0; + + /** + * The set_session_timeout() function changes the session timeout timer to be elapsed after session_timeout_ms milliseconds. + */ + virtual eap_status_e set_session_timeout( + const u32_t session_timeout_ms) = 0; + + //-------------------------------------------------- +}; // class abs_eap_radius_session_c + +#endif //#if !defined(_ABS_EAP_RADIUS_SESSION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/abs_eap_radius_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/abs_eap_radius_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_RADIUS_STATE_H_) +#define _ABS_RADIUS_STATE_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_buffer.h" +#include "eap_base_type.h" +#include "eap_config.h" +#include "eap_radius_types.h" + + +/// This class declares the functions eap_radius_state_c +/// requires from the partner class. +class EAP_EXPORT abs_eap_radius_state_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Constructor does nothing. + */ + virtual ~abs_eap_radius_state_c() + { + } + + /** + * Desstructor does nothing. + */ + abs_eap_radius_state_c() + { + } + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @see abs_eap_base_type_c::get_header_offset(). + */ + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + //-------------------------------------------------- +}; // class abs_eap_radius_state_c + + + +#endif //#if !defined(_ABS_RADIUS_STATE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/eap_radius.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/eap_radius.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,427 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_RADIUS_CORE_H_) +#define _RADIUS_CORE_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_radius_header.h" +#include "eap_radius_types.h" +#include "eap_radius_payloads.h" +#include "eap_radius_state.h" +#include "eap_radius_initialized.h" +#include "abs_eap_base_timer.h" +#include "abs_eap_am_radius.h" +#include "eap_am_radius.h" +#include "eap_crypto_api.h" +#include "eap_radius_session.h" +#include "abs_eap_radius.h" +#include "abs_eap_radius_session.h" +#include "eap_radius_session.h" +#include "eap_diameter_avp_code.h" + +class eap_radius_MAC_attributes_c; +class eap_radius_header_base_c; + +//-------------------------------------------------- + + +/// This class is implementation of RADIUS EAP-type. +class EAP_EXPORT eap_radius_c +: public abs_eap_radius_session_c +, public abs_eap_radius_state_c +, public abs_eap_base_timer_c +, public abs_eap_core_map_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + abs_eap_radius_c * const m_partner; + + /// This stores objects using eap_variable_data selector. + eap_core_map_c m_session_map; + + eap_variable_data_c m_pseudo_ethernet_header; + + /// This is offset in bytes of the EAP-type header in the packet buffer. + /// Offset is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_radius_header_offset; + + /// This is maximum transfer unit in bytes. + /// MTU is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_MTU; + + /// This is length of the trailer in bytes. + /// Trailer length is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_trailer_length; + + u16_t m_salt; + + /// This flag is set true when shutdown() function is called. + bool m_shutdown_was_called; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) + /// or EAP-authenticator (false). + bool m_is_client; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + //-------------------------------------------------- + + + /** + * This function sends and traces all messages. + */ + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length, + eap_radius_session_c * const session + ); + +#if defined(USE_EAP_TRACE) + + /** + * This function traces the EAP packet. + */ + EAP_FUNC_IMPORT void packet_trace( + eap_const_string prefix, + const eap_am_network_id_c * const receive_network_id, + eap_radius_header_base_c * const received_eap, + const u32_t eap_packet_length); + + #define EAP_RADIUS_PACKET_TRACE(prefix, receive_network_id, \ + received_eap, eap_packet_length) \ + packet_trace((prefix), (receive_network_id), (received_eap), (eap_packet_length)) + +#else + + #define EAP_RADIUS_PACKET_TRACE(prefix, receive_network_id, \ + received_eap, eap_packet_length) + +#endif //#if !defined(USE_EAP_TRACE) + + + /** + * This function processes the RADIUS packets. + */ + EAP_FUNC_IMPORT eap_status_e radius_packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_radius_header_base_c * const received_radius, ///< This is pointer to EAP header including RADIUS fields. + const u32_t radius_packet_length, ///< This is length of received RADIUS EAP packet. + const bool is_client_when_true ///< Indicates whether this is client (true) or server (false). + ); + + EAP_FUNC_IMPORT eap_status_e cancel_error_message_delay_timer(); + + EAP_FUNC_IMPORT eap_status_e set_error_message_delay_timer(); + + EAP_FUNC_IMPORT eap_status_e handle_error_packet(); + + EAP_FUNC_IMPORT bool random_selection(); + + EAP_FUNC_IMPORT eap_status_e add_ms_mppe_key_attributes( + const eap_variable_data_c * const shared_secret, + const eap_variable_data_c * const master_session_key, + const eap_variable_data_c * const request_authenticator, + eap_radius_header_base_c * const radius_header, + u32_t * const attribute_offset, + crypto_hmac_c * const hmac_message_auth, + crypto_md5_c * const md5_response_auth); + + + EAP_FUNC_IMPORT eap_status_e add_user_name_attribute( + const eap_radius_variable_data_c * const user_name, + eap_radius_header_base_c * const radius_header, + u32_t * const radius_attribute_offset, + crypto_hmac_c * const hmac_message_auth, + crypto_md5_c * const md5_response_auth); + + EAP_FUNC_IMPORT eap_status_e xor_values( + u8_t * const plaintext, + const u32_t plaintext_length, + const eap_variable_data_c * const intermediate_value); + + EAP_FUNC_IMPORT eap_status_e encrypt_ms_mppe_key_attribute( + const eap_variable_data_c * const shared_secret, + const eap_variable_data_c * const request_authenticator, + const u8_t * salt, + const u32_t salt_length, + u8_t * const data, + const u32_t data_length); + + EAP_FUNC_IMPORT eap_status_e add_one_ms_mppe_key_attribute( + const eap_variable_data_c * const shared_secret, + const eap_variable_data_c * const request_authenticator, + eap_radius_header_base_c * const radius_header, + u32_t * const attribute_offset, + const u8_t * const key, + const u32_t key_length, + const eap_diameter_avp_code_c mppe_key_type, + crypto_hmac_c * const hmac_message_auth, + crypto_md5_c * const md5_response_auth); + + EAP_FUNC_IMPORT static eap_status_e shutdown_operation( + eap_radius_session_c * const session, + abs_eap_am_tools_c * const m_am_tools); + + /** + * This function parses all payloads of the whole RADIUS EAP packet. + * Payloads are stored to p_radius_payloads. + * @see parse_radius_payload(). + */ + EAP_FUNC_IMPORT eap_status_e parse_radius_packet( + eap_radius_header_base_c * const radius, ///< This is pointer to EAP header including RADIUS fields. + const u32_t radius_packet_length, ///< This is length of received RADIUS EAP packet. + eap_radius_payloads_c * const p_radius_payloads); + + /** + * This function handles the received RADIUS EAP packet. + * + * First is checked the valid massage is received in valid state. + * See also eap_radius_state_c::check_valid_state(). + * + * Second is parsed the payloads and checked syntax of the received RADIUS EAP packet. + * See also parse_radius_packet(). + * + * Third is analysed the RADIUS EAP packet. This includes the payload and values of each payload. + * See also analyse_radius_packet(). + */ + EAP_FUNC_IMPORT eap_status_e handle_radius_packet( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_radius_header_base_c * const radius, ///< This is pointer to EAP header including RADIUS fields. + const u32_t radius_length, ///< This is length of received RADIUS EAP packet. + eap_radius_payloads_c * const p_radius_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + /** + * This function analyses the received RADIUS EAP packet. + * Each sub-type is handled in separate function. + * @see Client messages are handled in handle_start_request_message() and handle_challenge_request_message(). + * @see Server messages are handled in handle_start_response_message() and handle_challenge_response_message(). + */ + EAP_FUNC_IMPORT eap_status_e analyse_radius_packet( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_radius_header_base_c * const received_radius, ///< This is pointer to EAP header including RADIUS fields. + const u32_t radius_packet_length, ///< This is length of received RADIUS EAP packet. + eap_radius_payloads_c * const p_radius_payloads ///< This is pointer to all payloads of the received EAP packet. + ); + + EAP_FUNC_IMPORT void trace_tunneled_packet( + eap_const_string prefix, + const eap_header_base_c * const eap_packet); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor cancels all timers and deletes member attributes. + */ + EAP_FUNC_IMPORT virtual ~eap_radius_c(); + + /** + * Constructor initializes all member attributes. + */ + EAP_FUNC_IMPORT eap_radius_c( + abs_eap_am_tools_c * const tools, ///< This is pointer to the tools AM of current platform. + abs_eap_radius_c * const partner, ///< This is back pointer to object which created this object. + eap_am_radius_c * const am_radius, ///< This is pointer to adaptation module of RADIUS EAP type. + const bool free_am_radius, ///< True value means m_am_radius is allocated within eap_radius_c and m_am_radius must be freed in destructor. + const bool is_client_when_true ///< Indicates whether this is client (true) or server (false). + ); + + /** + * This function returns string of the state. This is for trace purposes. + * NOTE this is static member function. + */ + EAP_FUNC_IMPORT static eap_const_string get_state_string(eap_radius_state_variable_e state); + + /** + * This function tells if the object is a client or a server.. + */ + EAP_FUNC_IMPORT bool get_is_client(); + + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT eap_status_e unload_module(const eap_type_value_e eap_type); + + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer = false); + + EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id); + + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + EAP_FUNC_IMPORT eap_status_e add_rogue_ap( + eap_array_c & rogue_ap_list); + + EAP_FUNC_IMPORT eap_status_e set_session_timeout( + const u32_t session_timeout_ms); + + /** + * The partner class calls this function when EAP/RADIUS packet is received. + * see also eap_base_type_c::packet_process(). + */ + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_radius_header_base_c * const radius, ///< This is pointer to RADIUS header and data. + const u32_t radius_packet_length ///< This is length of received RADIUS packet. + ); + + /** + * This function obtains header offset, MTU and trailer length. + * See also abs_eap_base_type_c::get_header_offset(). + */ + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length + ); + + /** + * This function creates a message authentication code (MAC) + */ + EAP_FUNC_IMPORT eap_status_e create_message_authentication_code( + eap_radius_MAC_attributes_c *MAC_attributes, ///< This includes required parameters. + const eap_radius_code_value_e code, + const eap_variable_data_c * const authentication_key + ); + + // This is commented in abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data + ); + + // This is commented in abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data + ); + + // This is commented in eap_base_type_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + + // This is commented in eap_base_type_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + // This is commented in eap_base_type_c::configure(). + /** + * EAP-type RADIUS reads configuration. + */ + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is commented in eap_base_type_c::shutdown(). + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + EAP_FUNC_IMPORT eap_status_e shutdown(); + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ); + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ); + + // This is commented in eap_base_type_c::eap_acknowledge(). + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function must reset the state of object to same as + * state was after the configure() function call. + * If object reset succeeds this function must return eap_status_ok. + * If object reset fails this function must return corresponding error status. + * @return This function returns the status of reset operation. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + // + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + // + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + //-------------------------------------------------- +}; // class eap_radius_c + +#endif //#if !defined(_RADIUS_CORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_attribute_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_attribute_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,147 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_RADIUS_PAYLOAD_HEADER_H_) +#define _EAP_RADIUS_PAYLOAD_HEADER_H_ + +#include "eap_tools.h" +#include "eap_header.h" +#include "eap_radius_types.h" +#include "eap_diameter_avp_code.h" + +/** @file */ + +const u32_t TRACE_FLAGS_RADIUS_ERROR = eap_am_tools_c::eap_trace_mask_error; + + +const u32_t EAP_RADIUS_VENDOR_ID_LENGTH = 4ul*sizeof(u8_t); + +const u32_t EAP_RADIUS_VENDOR_ID_MS = 311ul; + +const u32_t EAP_RADIUS_MS_MPPE_KEY_LENGTH = 32u; +const u32_t EAP_RADIUS_MS_MPPE_KEY_DATA_LENGTH = 50ul; + +//---------------------------------------------------------------------------- + + +/// This class defines the attribute payload header of RADIUS EAP-type. +/** + * Here is a figure of attribute payload header of RADIUS EAP-type. + * Attribute payload data is (m_length)-sizeof(eap_radius_attribute_header_c) + * data octets that follows eap_radius_attribute_header_c. + * @code + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Length | Value ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + * + */ +class EAP_EXPORT eap_radius_attribute_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + enum offsets + { + m_type_offset = 0ul, + m_length_offset = m_type_offset+sizeof(u8_t), + m_data_offset = m_length_offset+sizeof(u8_t), + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~eap_radius_attribute_header_c(); + + // + EAP_FUNC_IMPORT eap_radius_attribute_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT eap_diameter_avp_code_c get_current_payload() const; + + EAP_FUNC_IMPORT u16_t get_length() const; + + EAP_FUNC_IMPORT u32_t get_data_length() const; + + EAP_FUNC_IMPORT static u16_t get_header_length(); + + EAP_FUNC_IMPORT static u16_t get_max_attribute_data_length(); + + EAP_FUNC_IMPORT u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + EAP_FUNC_IMPORT u8_t * get_next_header() const; + + + EAP_FUNC_IMPORT void set_current_payload(const eap_diameter_avp_code_c p_current_payload); + + EAP_FUNC_IMPORT void set_data_length(const u16_t p_data_length); + + EAP_FUNC_IMPORT void reset_header(const u16_t data_length); + + EAP_FUNC_IMPORT eap_const_string get_payload_type_string() const; + + EAP_FUNC_IMPORT eap_status_e check_header() const; + + // + //-------------------------------------------------- +}; // class eap_radius_attribute_header_c + + +//-------------------------------------------------- + +/// Macro traces payload type and data. +#define EAP_RADIUS_TRACE_PAYLOAD(prefix, payload) \ + { \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("%s (0x%08x): current payload 0x%08x=%s, data length 0x%04x.\n"), \ + prefix, \ + (payload)->get_header_buffer((payload)->get_length()), \ + (payload)->get_current_payload().get_vendor_code(), \ + (payload)->get_payload_type_string(), \ + (payload)->get_data_length())); \ + EAP_TRACE_DATA_DEBUG(m_am_tools, \ + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("payload"), \ + (payload)->get_header_buffer((payload)->get_length()), \ + (payload)->get_length())); \ + } + +//-------------------------------------------------- + +#endif //#if !defined(_EAP_RADIUS_PAYLOAD_HEADER_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,171 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined(_EAP_RADIUS_HEADER_H_) +#define _EAP_RADIUS_HEADER_H_ + + +#include "eap_general_header_base.h" +#include "eap_am_types.h" + + +/** @file */ + +//----------------------------------------------------------------------------------------- + +/// Enumeration of the RADIUS-Code values. +enum eap_radius_code_value_e +{ + eap_radius_code_none = 0, ///< This is internal value for no type case. + eap_radius_code_access_request = 1, ///< + eap_radius_code_access_accept = 2, ///< + eap_radius_code_access_reject = 3, ///< + eap_radius_code_accounting_request = 4, ///< + eap_radius_code_accounting_response = 5, ///< + eap_radius_code_access_challenge = 11, ///< + eap_radius_code_maximum_supported = eap_radius_code_access_challenge, ///< Keep this the last one. +}; + +const u32_t EAP_RADIUS_AUTHENTICATOR_LENGTH = 16ul; + +//----------------------------------------------------------------------------------------- + +/** This is base class defining the RADIUS-packet header. + * @code + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Code | Identifier | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Authenticator | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Attributes ... + * +-+-+-+-+-+-+-+-+-+-+-+-+- + * @endcode + */ +class EAP_EXPORT eap_radius_header_base_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * This enumeration defines the offsets of the RADIUS-header fields. + */ + enum offsets + { + m_code_offset = 0ul, ///< This is offset to code field. + m_identifier_offset = m_code_offset+sizeof(u8_t), ///< This is offset to identifier field. + m_length_offset = m_identifier_offset+sizeof(u8_t), ///< This is offset to length field. + + m_authenticator_offset = m_length_offset+sizeof(u16_t), + ///< This is offset to authenticator field. + + m_attributes_offset = m_authenticator_offset+EAP_RADIUS_AUTHENTICATOR_LENGTH*sizeof(u8_t), + ///< This is offset to optional attributes fields. + }; + + /// Destructor does nothing special. + EAP_FUNC_IMPORT virtual ~eap_radius_header_base_c(); + + /// Constructor does nothing special. + /// The tools parameter is pointer to tools object. + /// The header_buffer parameter is pointer to buffer of RADIUS-packet including header and data. + /// The header_buffer_length parameter is length of the header_buffer. + EAP_FUNC_IMPORT eap_radius_header_base_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + /// This function returns the header length of the RADIUS-packet. + EAP_FUNC_IMPORT static u32_t get_header_length(); + + /// This function returns the code field of RADIUS-header. + EAP_FUNC_IMPORT eap_radius_code_value_e get_code() const; + + /// This function returns the authenticator field of RADIUS-header. + EAP_FUNC_IMPORT u8_t * get_authenticator() const; + + /// This function returns the length of the authenticator field of RADIUS-header. + EAP_FUNC_IMPORT u32_t get_authenticator_length() const; + + /// This function returns the identifier field of RADIUS-header. + EAP_FUNC_IMPORT u8_t get_identifier() const; + + /// This function returns the length field of RADIUS-header. + EAP_FUNC_IMPORT u16_t get_length() const; + + /// This function returns the length of the attribute data of RADIUS-header. + EAP_FUNC_IMPORT u16_t get_data_length() const; + + /// This function returns the pointer to the offset of the attribute field of RADIUS-packet. + /// Data field includes type field. + EAP_FUNC_IMPORT u8_t * get_data_offset( + const u32_t p_offset, const u32_t p_continuous_bytes) const; + + + /// This function sets the code field of the RADIUS-header. + EAP_FUNC_IMPORT void set_code(const eap_radius_code_value_e p_code); + + /// This function sets the identifier field of the RADIUS-header. + EAP_FUNC_IMPORT void set_identifier(const u8_t p_identifier); + + /// This function sets the length field of the RADIUS-header. + EAP_FUNC_IMPORT void set_length(const u16_t p_length); + + /// This function sets the length field of the RADIUS-header + /// based on attribute data length. + EAP_FUNC_IMPORT void set_data_length(const u16_t p_length); + + + /// This function returns debug string of the code of the RADIUS-packet. + EAP_FUNC_IMPORT eap_const_string get_code_string() const; + + /// This function checks the validity of RADIUS-header. + EAP_FUNC_IMPORT eap_status_e check_header() const; + + + /// This function resets the RADIUS-header. + /// The buffer_length parameter is the length of the RADISU-header and the following attribute data buffer. + EAP_FUNC_IMPORT void reset_header(u16_t buffer_length); + + // + //-------------------------------------------------- +}; // class eap_header_c + + +#endif //#if !defined(_EAP_RADIUS_HEADER_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_header_string.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_header_string.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_RADIUS_HEADER_STRING_H_ ) +#define _EAP_RADIUS_HEADER_STRING_H_ + +/** @file */ + +#include "eap_variable_data.h" +#include "eap_status.h" +#include "eap_am_export.h" +#include "eap_radius_header.h" + +/// This class includes the debug strings of the eap_header_base_c. +class EAP_EXPORT eap_radius_header_string_c +{ +public: + + EAP_FUNC_IMPORT virtual ~eap_radius_header_string_c(); + + EAP_FUNC_IMPORT eap_radius_header_string_c(); + + /** + * Function returns string of eap_code_value_e. + * @param code is the queried string. + */ + EAP_FUNC_IMPORT static eap_const_string get_code_string(const eap_radius_code_value_e code); + +}; + + +#endif //#if !defined( _EAP_RADIUS_HEADER_STRING_H_ ) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_initialized.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_initialized.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_RADIUS_INITIALIZED_H_) +#define _RADIUS_INITIALIZED_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_radius_header.h" +#include "eap_radius_types.h" +#include "eap_radius_payloads.h" +#include "abs_eap_radius_state.h" +#include "abs_eap_am_tools.h" + + +const u32_t RADIUS_MAX_OFFER_COUNT = 3; + + +class EAP_EXPORT eap_radius_initialized_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + u32_t m_counter; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~eap_radius_initialized_c(); + + // + eap_radius_initialized_c( + abs_eap_am_tools_c * const tools, + abs_eap_radius_state_c * const /*partner*/); + + u32_t counter(); + + void increment(); + + void reset(); + +}; + + +#endif //#if !defined(_RADIUS_INITIALIZED_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_mac_attributes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_mac_attributes.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TYPE_RADIUS_MAC_ATTRIBUTES_H_) +#define _EAP_TYPE_RADIUS_MAC_ATTRIBUTES_H_ + +#include "eap_radius_header.h" +#include "eap_type_all_types.h" + +//-------------------------------------------------- + +/// These are the stored attributes for message authentication calculations. +class eap_radius_MAC_attributes_c +{ +private: + //-------------------------------------------------- + + u8_t * m_MAC; ///< This is the pointer to MAC. + u32_t m_MAC_size; ///< This is the size of the MAC. + u8_t *m_data; ///< This is the pointer to the authenticated data. + u32_t m_data_length; ///< This the length of the authenticated data. + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + virtual ~eap_radius_MAC_attributes_c(); + + eap_radius_MAC_attributes_c(); + + eap_radius_MAC_attributes_c( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length); + + void init( + u8_t * MAC, + u32_t MAC_size, + u8_t * const EAP_data, + u32_t EAP_data_length); + + u8_t * get_MAC() const; + + void set_MAC(u8_t * MAC); + + u32_t get_MAC_size() const; + + eap_radius_MAC_attributes_c * copy() const; + + u8_t * get_data() const; + + u32_t get_data_length(); + + void set_data(u8_t * const data); + + //-------------------------------------------------- +}; + + +#endif //#if !defined(_EAP_TYPE_RADIUS_MAC_ATTRIBUTES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_payloads.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,160 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_RADIUS_RESULT_H_) +#define _EAP_RADIUS_RESULT_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_radius_header.h" +#include "eap_radius_attribute_header.h" +#include "eap_core_map.h" + + +class EAP_EXPORT eap_radius_variable_data_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + eap_variable_data_c m_data; + + eap_diameter_avp_code_c m_payload_type; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~eap_radius_variable_data_c(); + + EAP_FUNC_IMPORT eap_radius_variable_data_c(abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT eap_status_e set_buffer( + const eap_diameter_avp_code_c current_payload, + const u8_t * const buffer, + const u32_t buffer_length, + const bool free_buffer, + const bool is_writable); + + EAP_FUNC_IMPORT eap_status_e add_data( + const u8_t * const buffer, + const u32_t buffer_length); + + EAP_FUNC_IMPORT u32_t get_data_length() const; + + EAP_FUNC_IMPORT u8_t * get_data(const u32_t data_length) const; + + EAP_FUNC_IMPORT eap_variable_data_c * get_payload_buffer(); + + EAP_FUNC_IMPORT eap_diameter_avp_code_c get_payload_type() const; + + EAP_FUNC_IMPORT void set_payload_type(const eap_diameter_avp_code_c type); + + EAP_FUNC_IMPORT eap_radius_variable_data_c * copy() const; + + EAP_FUNC_IMPORT void object_increase_reference_count(); + + //-------------------------------------------------- +}; // class eap_radius_variable_data_c + + +//-------------------------------------------------- + + +// +class EAP_EXPORT eap_radius_payloads_c +: public abs_eap_core_map_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + /// This stores objects using eap_variable_data selector. + eap_core_map_c m_payload_map; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~eap_radius_payloads_c(); + + EAP_FUNC_IMPORT eap_radius_payloads_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT eap_radius_variable_data_c * get_payload( + const eap_diameter_avp_code_c current_payload); + + EAP_FUNC_IMPORT eap_status_e add_payload( + const eap_diameter_avp_code_c current_payload, + const u8_t * const data, + const u32_t data_length, + const bool free_buffer, + const bool is_writable, + const bool fragments_allowed); + + /** + * This function parses the payloads starting from specified payload (p_payload). + * Function parses all payloads from the buffer. + * Payloads are stored to p_radius_payloads. + * @return If the length of the buffer and sum of the length of all payloads does not match + * function returns eap_status_header_corrupted. + * Also error is returned when illegal payload attribute is recognised. + */ + EAP_FUNC_IMPORT eap_status_e parse_radius_payload( + const eap_radius_attribute_header_c * const p_payload, ///< This is the start of the buffer and the first parsed payload. + u32_t * const buffer_length ///< This is the length of the buffer. This must match with the length of all payloads. + ); + + /** + * This function parses each payload attributes. + * @return If payload attribute is illegal function returns eap_status_header_corrupted. + * If payload attribute is unknown function returns eap_status_unsupported_payload. + */ + EAP_FUNC_IMPORT eap_status_e parse_generic_payload( + const eap_diameter_avp_code_c current_payload, ///< This is the type of current payload attribute. + const eap_radius_attribute_header_c * const payload ///< This is the current parsed payload. + ); + + + EAP_FUNC_IMPORT bool get_is_valid() const; + + //-------------------------------------------------- +}; // class eap_radius_payloads_c + + +#endif //#if !defined(_EAP_RADIUS_RESULT_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_session.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_session.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,398 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_RADIUS_SESSION_H_) +#define _EAP_RADIUS_SESSION_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_core.h" +#include "eap_core_map.h" +#include "abs_eap_stack_interface.h" +#include "eap_core.h" +#include "eap_radius_payloads.h" +#include "abs_eap_radius_session.h" +#include "eap_protocol_layer.h" +#include "eap_master_session_key.h" + + +class eap_core_c; +class eap_network_id_selector_c; + + +/** + * This is the timer ID used with abs_eap_am_tools_c::set_timer() and abs_eap_am_tools_c::cancel_timer(). + */ +enum eap_radius_session_timer_id +{ + EAP_RADIUS_SESSION_REMOVE_SESSION_ID, ///< See EAP_RADIUS_SESSION_REMOVE_SESSION_TIMEOUT. +}; + +/** + * This is time after a EAP session is removed. This must be zero. + */ +const u32_t EAP_RADIUS_SESSION_REMOVE_SESSION_TIMEOUT = 0u; + + +/// A eap_radius_session_c class implements mapping of EAP authentication sessions. +/// Network identity separates parallel EAP authentication sessions. +class EAP_EXPORT eap_radius_session_c +: public abs_eap_core_c +, public abs_eap_core_map_c +, public abs_eap_base_timer_c +, public abs_eap_stack_interface_c +{ +private: + //-------------------------------------------------- + + /// This is back pointer to object which created this object. + /// Packets are sent to the partner. + abs_eap_radius_session_c * const m_partner; + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is EAP core for this session. + eap_core_c * m_eap_core; + + /// m_master_session_key includes also EAP-type. + /// Note the LEAP type uses different key than other EAP-types. + eap_master_session_key_c m_master_session_key; + + eap_variable_data_c m_request_authenticator; + + eap_variable_data_c m_shared_secret; + + u8_t m_identifier; + + eap_radius_variable_data_c * m_user_name; + + eap_radius_variable_data_c * m_nas_ip_address; + + eap_state_variable_e m_state; + + u32_t m_remove_session_timeout; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + bool m_shutdown_was_called; + + + /** + * Function creates a new session. + */ + EAP_FUNC_IMPORT eap_core_c * create_new_session( + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT static eap_status_e shutdown_operation( + eap_core_c * const core, + abs_eap_am_tools_c * const m_am_tools); + + EAP_FUNC_IMPORT eap_status_e reset(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_core class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_radius_session_c(); + + /** + * The constructor initializes member attributes using parameters passed to it. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + * @param partner is back pointer to object which created this object. + * @param is_client_when_true indicates whether the network entity should act + * as a client (true) or server (false), in terms of EAP-protocol + * whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + */ + EAP_FUNC_IMPORT eap_radius_session_c( + abs_eap_am_tools_c * const tools, + abs_eap_radius_session_c * const partner, + const bool is_client_when_true, + const eap_radius_variable_data_c * const user_name, + const eap_radius_variable_data_c * const nas_ip_address); + + EAP_FUNC_IMPORT eap_status_e save_request_data( + const void * const data, + const u32_t data_length, + const u8_t identifier); + + EAP_FUNC_IMPORT u8_t get_identifier(); + + EAP_FUNC_IMPORT const eap_variable_data_c * get_shared_secret() const; + + EAP_FUNC_IMPORT const eap_variable_data_c * get_request_authenticator(); + + EAP_FUNC_IMPORT const eap_radius_variable_data_c * get_user_name(); + + EAP_FUNC_IMPORT eap_state_variable_e get_state(); + + EAP_FUNC_IMPORT eap_variable_data_c * get_master_session_key(); + + // This is documented in abs_eap_stack_interface_c::packet_process(). + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, + eap_general_header_base_c * const packet_data, + const u32_t packet_length); + + /** + * The class could send packets to partner class with this function. + * @param send_network_id carries the addresses (network identity) and type of the packet. + * @param sent_packet includes the buffer for the whole packet and initialized + * EAP-packet in correct offset. + * @param header_offset is offset of the EAP-header within the sent_packet. + * @param data_length is length in bytes of the EAP-packet. + * @param buffer_length is length in bytes of the whole packet buffer. + */ + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + EAP_FUNC_IMPORT void object_increase_reference_count(); + + EAP_FUNC_IMPORT u32_t object_decrease_reference_count(); + + /** + * The get_partner() function returns pointer to partner class. + */ + EAP_FUNC_IMPORT abs_eap_radius_session_c * get_partner(); + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @param MTU_length is pointer to variable to store the maximum transfer unit (MTU). + * MTU is the maximum EAP-packet length in bytes + * @param trailer_length is pointer to the variable to store length + * of trailer needed by lower levels. + * @return Function returns the offset of EAP-header. + * @see abs_eap_base_type_c::get_header_offset(). + */ + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + /** + * The unload_module() function initializes un-load of desired EAP-type. + * After the EAP-type is not needed this function should be called. + */ + EAP_FUNC_IMPORT eap_status_e unload_module( + const eap_type_value_e type); + + /** + * The adaptation module calls the eap_acknowledge() function after + * any Network Protocol packet is received. This is used as a success indication. + * This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + * @param connection_handle separates the context of the acknowledged session. + * Mostly there is only one session in the client. + * The server does not need eap_acknowledge() function because + * server (EAP-authenticator) sends the EAP-success message. + */ + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function restarts authentication using current object. + * This is used for testing. + */ + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const send_network_id, + const bool is_client_when_true); + +#if defined(USE_EAP_CORE_SERVER) + /** + * The EAP Core calls the send_eap_identity_request() function + * when EAP-authentication is needed with another peer. + * @param network_id includes the addresses (network identity) and packet type. + */ + EAP_FUNC_IMPORT eap_status_e send_eap_identity_request( + const eap_am_network_id_c * const network_id); +#endif //#if defined(USE_EAP_CORE_SERVER) + + /** + * The EAP Core calls the send_eap_nak_response() function + * when EAP-authentication with requested EAP type is not possible. + * @param network_id includes the addresses (network identity) and packet type. + * @param eap_identifier is the EAP-Identifier to be used with EAP-Nak message. + * @param preferred_eap_type is the acceptable EAP-Type to be informed with an other peer. + */ + EAP_FUNC_IMPORT eap_status_e send_eap_nak_response( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const eap_type_value_e preferred_eap_type); + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @param authentication_key is pointer to the first byte of the authentication key. + * @param auth_key_length is count of bytes in the authentication key. + * @param encryption_key is pointer to the first byte of the encryption key. + * @param encr_key_length is count of bytes in the encryption key. + */ + EAP_FUNC_IMPORT eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ); + + // This is documented in abs_eap_stack_interface_c::configure(). + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is documented in abs_eap_stack_interface_c::shutdown(). + EAP_FUNC_IMPORT eap_status_e shutdown(); + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // This is documented in abs_eap_stack_interface_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + + // This is documented in abs_eap_stack_interface_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + // See abs_eap_base_type_c::state_notification(). + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state); + + // See abs_eap_base_timer_c::timer_expired(). + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data); + + // See abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data); + + /** + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @see abs_eap_core_c::load_module(). + */ + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + /** + * The adaptation module calls the restart_authentication() function + * when EAP-authentication is needed with another peer. + * @see abs_eap_core_c::restart_authentication(). + */ + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer = false); + + /** + * This function removes EAP session object synchronously. + * @param receive_network_id identifies the removed EAP session. + */ + EAP_FUNC_IMPORT eap_status_e synchronous_remove_eap_session( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function removes EAP session object asynchronously. + * @param send_network_id identifies the removed EAP session. + */ + eap_status_e asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id); + + /** + * This function tells lower layer to remove EAP session object asynchronously. + * @param eap_type is pointer to selector that identifies the removed EAP session. + */ + EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_eap_session( + const eap_network_id_selector_c * const state_selector); + + // + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + // + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + // + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + /// @see abs_eap_core_c::get_eap_type_list(). + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + /// @see abs_eap_core_c::add_rogue_ap(). + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + // This is documented in abs_eap_core_c::set_session_timeout(). + EAP_FUNC_IMPORT eap_status_e set_session_timeout( + const u32_t session_timeout_ms); + + //-------------------------------------------------- +}; // class eap_radius_session_c + +#endif //#if !defined(_EAP_RADIUS_SESSION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_RADIUS_STATE_H_) +#define _RADIUS_STATE_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_radius_header.h" +#include "eap_radius_types.h" +#include "eap_radius_payloads.h" +#include "abs_eap_radius_state.h" +#include "abs_eap_base_timer.h" +#if defined(USE_EAP_TYPE_SERVER_RADIUS) + #include "eap_sim_triplets.h" +#endif //#if defined(USE_EAP_TYPE_SERVER_RADIUS) +#include "eap_radius_state_notification.h" +#include "eap_am_network_id.h" + + +#endif //#if !defined(_RADIUS_STATE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_state_notification.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_state_notification.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,175 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_RADIUS_STATE_NOTIFICATION_H_) +#define _EAP_RADIUS_STATE_NOTIFICATION_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_protocol_layer.h" +#include "abs_eap_state_notification.h" + + +/// A eap_radius_state_notification_c class. +/// This is used for debugging and protocol testing. +class EAP_EXPORT eap_radius_state_notification_c +: public abs_eap_state_notification_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; ///< This is pointer to the tools class. @see abs_eap_am_tools_c. + + eap_protocol_layer_e m_layer; ///< Here is the protocol layer (EAP type). + + eap_variable_data_c m_notification_string; ///< Here is the notification string. + + bool m_needs_confirmation_from_user; ///< This flag tells whether user interaction is required. + + u32_t m_protocol; ///< Here are other protocols than EAP-types. + + eap_type_value_e m_eap_type; ///< Here is the EAP type. This is needed for extented EAP-types. + + u32_t m_previous_state; ///< Here is the previous state of the EAP type. + + u32_t m_current_state; ///< Here is the current state of the EAP type. + + const eap_am_network_id_c *m_send_network_id; + + bool m_is_client; + + u8_t m_eap_identifier; + + bool m_allow_send_eap_success; + + EAP_FUNC_IMPORT eap_const_string get_state_string(const u32_t state) const; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_radius_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_radius_state_notification_c(); + + /** + * The constructor of the eap_radius_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT eap_radius_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + + +#if defined(USE_EAP_EXPANDED_TYPES) + + EAP_FUNC_IMPORT eap_radius_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + + EAP_FUNC_IMPORT eap_radius_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + + // This is commented in abs_eap_state_notification_c::get_send_network_id(). + EAP_FUNC_IMPORT const eap_am_network_id_c * get_send_network_id() const; + + // This is commented in abs_eap_state_notification_c::get_protocol_layer(). + EAP_FUNC_IMPORT eap_protocol_layer_e get_protocol_layer() const; + + // This is commented in abs_eap_state_notification_c::get_protocol(). + EAP_FUNC_IMPORT u32_t get_protocol() const; + + // This is commented in abs_eap_state_notification_c::get_eap_type(). + EAP_FUNC_IMPORT eap_type_value_e get_eap_type() const; + + // This is commented in abs_eap_state_notification_c::get_previous_state(). + EAP_FUNC_IMPORT u32_t get_previous_state() const; + + // This is commented in abs_eap_state_notification_c::get_previous_state_string(). + EAP_FUNC_IMPORT eap_const_string get_previous_state_string() const; + + // This is commented in abs_eap_state_notification_c::get_current_state(). + EAP_FUNC_IMPORT u32_t get_current_state() const; + + // This is commented in abs_eap_state_notification_c::get_current_state_string(). + EAP_FUNC_IMPORT eap_const_string get_current_state_string() const; + + // This is commented in abs_eap_state_notification_c::get_is_client(). + EAP_FUNC_IMPORT bool get_is_client() const; + + // This is commented in abs_eap_state_notification_c::get_eap_identifier(). + EAP_FUNC_IMPORT u8_t get_eap_identifier() const; + + // This is commented in abs_eap_state_notification_c::get_allow_send_eap_success(). + EAP_FUNC_IMPORT bool get_allow_send_eap_success() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT eap_status_e set_notification_string( + const eap_variable_data_c * const notification_string, + const bool needs_confirmation_from_user); + + // This is commented in abs_eap_state_notification_c::get_notification_string(). + EAP_FUNC_IMPORT const eap_variable_data_c * get_notification_string() const; + + // This is commented in abs_eap_state_notification_c::get_needs_confirmation_from_user(). + EAP_FUNC_IMPORT bool get_needs_confirmation_from_user() const; + + //-------------------------------------------------- +}; // class eap_radius_state_notification_c + +#endif //#if !defined(_EAP_RADIUS_STATE_NOTIFICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/radius/include/eap_radius_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,243 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_RADIUS_TYPES_H_) +#define _RADIUS_TYPES_H_ + +#include "eap_type_all_types.h" +#include "eap_configuration_field.h" + +/** @file eap_radius_types.h + * @brief This file defines the constants of the RADIUS EAP type. + */ + +const u32_t RADIUS_FIRST_SEQUENCE = 1u; +const u32_t RADIUS_PAYLOAD_LENGTH_ALIGN = 4u; +const u32_t RADIUS_PAYLOAD_ZERO_DATA_LENGTH = 0u; +const u8_t RADIUS_NAI_AT_BYTE = '@'; + +enum eap_radius_protocol_e +{ + eap_radius_protocol, +}; + + +/** + * This is the internal state of the RADIUS EAP type. + */ +enum eap_radius_state_variable_e +{ + eap_radius_state_none , ///< This is the initial state + eap_radius_state_waiting_for_identity_request , ///< Client state waiting_for_identity_request + eap_radius_state_pending_identity_query , ///< Client state pending_identity_query + eap_radius_state_waiting_for_start_request , ///< Client state imsi_waiting_for_start_request + eap_radius_state_imsi_waiting_for_start_request , ///< Client state imsi_waiting_for_start_request + eap_radius_state_pseydonym_waiting_for_start_request , ///< Client state pseydonym_waiting_for_start_request + eap_radius_state_analyse_start_request , ///< Client state analyse_start_request + eap_radius_state_waiting_for_challenge_request , ///< Client state waiting_for_challenge_request + eap_radius_state_analyses_challenge_request , ///< Client state analyses_challenge_request + eap_radius_state_pending_kc_sres_query , ///< Client state pending_kc_sres_query + eap_radius_state_waiting_for_notification_request_success , ///< Client state waiting_for_notification_request_success + eap_radius_state_waiting_for_success , ///< Client state waiting_for_success + eap_radius_state_waiting_for_reauth_request , ///< Client state waiting_for_reauth_request + eap_radius_state_analyses_reauthentication_request , ///< Client state analyses_reauthentication_request + + eap_radius_state_pending_pseudonym_decode_query , ///< Server state pending_pseudonym_decode_query + eap_radius_state_waiting_for_identity_response , ///< Server state waiting_for_identity_response + eap_radius_state_waiting_for_start_response_with_at_permanent_identity , ///< Server state waiting_for_start_response_with_at_permanen_identity + eap_radius_state_waiting_for_start_response_with_at_full_auth_identity , ///< Server state waiting_for_start_response_with_at_identity + eap_radius_state_waiting_for_start_response_with_at_any_identity , ///< Server state waiting_for_start_response_with_at_identity + eap_radius_state_waiting_for_start_response , ///< Server state waiting_for_start_response + eap_radius_state_waiting_for_challenge_response , ///< Server state waiting_for_challenge_response + eap_radius_state_pending_triplet_query , ///< Server state pending_triplet_query + eap_radius_state_analyses_challenge_response , ///< Server state analyses_challenge_response + eap_radius_state_analyses_start_response , ///< Server state analyses_start_response + eap_radius_state_waiting_for_notification_response_failure , ///< Server state waiting_for_notification_response, authentication failed + eap_radius_state_waiting_for_notification_response_success , ///< Server state waiting_for_notification_response, authentication success + eap_radius_state_waiting_for_reauth_response , ///< Server state waiting_for_reauth_response + eap_radius_state_analyses_reauthentication_response , ///< Server state analyses_reauthentication_response + + eap_radius_state_success , ///< State state_success + eap_radius_state_failure , ///< State state_failure + + eap_radius_state_last_value ///< Keep this enum the last one. +}; + + +/** + * This is the required completion after a asyncronous call. + */ +enum eap_radius_complete_e +{ + eap_radius_complete_none, ///< No completion required + eap_radius_complete_start_request, ///< RADIUS start request must be completed + eap_radius_complete_query_eap_identity, ///< RADIUS EAP-identity query must be completed + eap_radius_complete_handle_imsi_from_username, + eap_radius_complete_handle_start_response_message_completion, +}; + + +/** + * This is the status of the triplet. + */ +enum eap_radius_triplet_status_e +{ + eap_radius_triplet_status_ok = 0, + eap_radius_triplet_status_no_roaming_agreement = 1024, ///< No roaming agreement. + eap_radius_triplet_status_users_calls_are_barred = 1026, ///< User's calls are barred. + eap_radius_triplet_status_user_has_not_subscribed_to_the_requested_service = 1031, ///< User has not subrcibed to the requested service. +}; + + +enum eap_radius_notification_codes_e +{ + eap_radius_notification_no_F_no_P_general_failure = 0, ///< General failure. (implies failure, used after successful authentication) + eap_radius_notification_no_F_P_set_general_failure = 16384, ///< General failure. (implies failure, used before authentication) + eap_radius_notification_F_set_no_P_user_authenticated = 32768, ///< User has been successfully authenticated. (does not imply failure, used after successful authentication). The usage of this code is discussed in Section 4.4.2. + eap_radius_notification_no_F_no_P_users_calls_are_barred = 1026, ///< User has been temporarily denied access to the requested service. (Implies failure, used after successful authentication) + eap_radius_notification_no_F_no_P_user_has_not_subscribed_to_the_requested_service = 1031, ///< User has not subscribed to the requested service (implies failure, used after successful authentication) + eap_radius_notification_none = 0xffff, ///< No code. +}; + + +enum radius_notification_code_bits_e +{ + radius_notification_code_bit_f = 0x8000, + radius_notification_code_bit_p = 0x4000, +}; + + +/** See eap_radius_triplet_status_e. */ +const u8_t EAP_RADIUS_NOTIFICATION_NO_ROAMING_AGREEMENT[] + = "1024 Visited network does not have a roaming agreement with user's home operator"; +/** See eap_radius_triplet_status_e. */ +const u8_t EAP_RADIUS_NOTIFICATION_USERS_CALLS_ARE_BARRED[] + = "1026 User's calls are barred"; +/** See eap_radius_triplet_status_e. */ +const u8_t EAP_RADIUS_NOTIFICATION_USER_HAS_NOT_SUBSCRIBED_TO_THE_REQUESTED_SERVICE[] + = "1031 User has not subscribed to the requested service"; + +/** + * This is the type of the RADIUS identity. + */ +enum eap_radius_identity_type +{ + RADIUS_IDENTITY_TYPE_NONE, + RADIUS_IDENTITY_TYPE_IMSI_ID, + RADIUS_IDENTITY_TYPE_PSEUDONYM_ID, + RADIUS_IDENTITY_TYPE_RE_AUTH_ID, +}; + +enum eap_radius_authentication_type_e +{ + RADIUS_AUTHENTICATION_TYPE_NONE, + RADIUS_AUTHENTICATION_TYPE_FULL_AUTH, + RADIUS_AUTHENTICATION_TYPE_REAUTHENTICATION, +}; + +const u8_t RADIUS_IMSI_PREFIX_CHARACTER[] = "1"; + +const u8_t RADIUS_AT_CHARACTER[] = "@"; + +const u8_t RADIUS_OWLAN_ORG_PREFIX_STRING[] = "wlan"; +const u32_t RADIUS_OWLAN_ORG_PREFIX_STRING_LENGTH = sizeof(RADIUS_OWLAN_ORG_PREFIX_STRING)-1ul; + +const u8_t RADIUS_UMA_PREFIX_STRING[] = "wlan"; +const u32_t RADIUS_UMA_PREFIX_STRING_LENGTH = sizeof(RADIUS_UMA_PREFIX_STRING)-1ul; + +const u8_t RADIUS_OWLAN_MNC_STRING[] = "mnc"; +const u32_t RADIUS_OWLAN_MNC_STRING_LENGTH = sizeof(RADIUS_OWLAN_MNC_STRING)-1ul; + +const u8_t RADIUS_OWLAN_DOT_STRING[] = "."; +const u32_t RADIUS_OWLAN_DOT_STRING_LENGTH = sizeof(RADIUS_OWLAN_DOT_STRING)-1ul; + +const u8_t RADIUS_OWLAN_MCC_STRING[] = "mcc"; +const u32_t RADIUS_OWLAN_MCC_STRING_LENGTH = sizeof(RADIUS_OWLAN_MCC_STRING)-1ul; + +const u8_t RADIUS_OWLAN_ORG_STRING[] = "3gppnetwork.org"; +const u32_t RADIUS_OWLAN_ORG_STRING_LENGTH = sizeof(RADIUS_OWLAN_ORG_STRING)-1ul; + + +enum eap_radius_constants_e +{ + EAP_TYPE_RADIUS_NONCE_MT_SIZE = 16u, ///< bytes = 128 bits + EAP_TYPE_RADIUS_MAC_SIZE = 16u, ///< bytes = 128 bits + EAP_TYPE_RADIUS_KEYMAT_SIZE = 20u, ///< bytes = 160 bits + EAP_TYPE_RADIUS_MASTER_SESSION_KEY_SIZE = 4u*32u, ///< bytes + EAP_TYPE_RADIUS_MAX_NAI_LENGTH = 255u, ///< bytes + EAP_TYPE_RADIUS_MAX_USER_NAI_LENGTH = 255u, ///< bytes + EAP_TYPE_RADIUS_DEFAULT_MINIMUM_RAND_COUNT = 2ul, ///< count + EAP_TYPE_RADIUS_LOCAL_PACKET_BUFFER_LENGTH = 512u, ///< This is the size of the local send buffer. + EAP_TYPE_RADIUS_PADDING_MODULUS = 4ul, ///< Padding length is always mudulus of 4. + EAP_TYPE_RADIUS_PADDING_MAX_VALUE = 12ul, ///< Maximum padding length is 12 bytes. + EAP_TYPE_RADIUS_INITIAL_REAUTH_COUNTER = 1ul, +}; + +enum eap_radius_timer_id_e +{ + EAP_TYPE_RADIUS_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID, + EAP_TYPE_RADIUS_TIMER_DELAY_NOTIFICATION_MESSAGE_ID, +}; + +enum eap_radius_timer_timeout_value_e +{ + EAP_TYPE_RADIUS_TIMER_TIMEOUT_VALUE_DELAY_FAILURE_MESSAGE_SENT = 0ul, ///< This is the default value. Zero means error message is handled immediately. +}; + + +/** + * @defgroup RADIUS_config_options Configuration options of RADIUS. + * The following configuration options are read through abs_eap_base_type_c::read_configure() function. + * @{ + */ + + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_RADIUS_SERVER_client, + "EAP_RADIUS_SERVER_client", + eap_configure_type_section, + false); + +/** + * This string configuration option is the username part of EAP-type RADIUS identity. + * Default value is empty string. That will cause use of automatic username. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_RADIUS_SERVER_shared_secret, + "EAP_RADIUS_SERVER_shared_secret", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_RADIUS_SERVER_test_time, + "EAP_RADIUS_SERVER_test_time", + eap_configure_type_u32_t, + false); + + +/** @} */ // End of group RADIUS_config_options. + +#endif //#if !defined(_RADIUS_TYPES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/securid/core/eap_type_securid.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/securid/core/eap_type_securid.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,806 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 115 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "eap_am_memory.h" +#include "eap_state_notification.h" +#include "eap_memory_store_variable_data.h" +#include "eap_type_securid.h" +#include "eap_type_securid_types.h" +#include "eap_buffer.h" +#include "eap_master_session_key.h" +#include "eap_config.h" + +static const u32_t EAP_SECURID_EAP_HEADER_SIZE = 5; + +/** +* Constructor initializes all member attributes. +*/ + +EAP_FUNC_EXPORT eap_type_securid_c::eap_type_securid_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + eap_am_type_securid_c * const am_type_securid, + const bool free_am_type_securid, + const eap_type_value_e current_eap_type, ///< This the current EAP-type (GTC or SecurID). + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) + : eap_base_type_c(tools, partner) + , m_am_type_securid(am_type_securid) + , m_is_valid(false) + , m_is_client(is_client_when_true) + , m_eap_type(current_eap_type) + , m_free_am_type_securid(free_am_type_securid) + , m_use_EAP_FAST_response(false) + , m_am_tools(tools) + , m_send_network_id(tools) + , m_identity(tools) + , m_passcode(tools) + , m_pincode(tools) + , m_is_first_passcode_query(true) + , m_is_first_pincode_query(true) + , m_identity_asked(false) + , m_is_pending(false) + , m_state(is_client_when_true) + , m_is_reauthentication(false) + , m_use_eap_expanded_type(false) +#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) + , m_skip_user_interactions(false) +#endif //#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_securid_c::eap_type_securid_c(): this = 0x%08x, ") + EAPL("partner 0x%08x, type partner 0x%08x, compiled %s %s\n"), + this, + partner, + get_type_partner(), + __DATE__, + __TIME__)); + + m_am_type_securid->set_am_partner(this); + + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + eap_status_e status = m_send_network_id.set_copy_of_network_id(&send_network_id); + + if (status != eap_status_ok + || m_send_network_id.get_is_valid_data() == false) + { + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_securid_c::~eap_type_securid_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_securid_c::~eap_type_securid_c(): this = 0x%08x\n"), + this)); + + if (m_free_am_type_securid == true) + { + delete m_am_type_securid; + } + + m_free_am_type_securid = false; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_securid_c::shutdown(): this = 0x%08x\n"), + this)); + + m_am_type_securid->shutdown(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_securid_c::shutdown(): this = 0x%08x returns\n"), + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::eap_acknowledge( + const eap_am_network_id_c * const /* receive_network_id */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::set_initial_eap_identifier( + const eap_am_network_id_c * const /*receive_network_id*/, + const u8_t /*initial_identifier*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_type_securid_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_is_valid = true; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_securid_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_securid_c::get_is_client() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_client; +} + +//-------------------------------------------------- + +eap_buf_chain_wr_c * eap_type_securid_c::create_send_packet(u32_t length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_buf_chain_wr_c * packet = new eap_buf_chain_wr_c( + eap_write_buffer, + m_am_tools, + length + m_offset + m_trailer_length); + if (!packet) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + if (packet->get_is_valid() == false) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + packet->set_data_length(length + m_offset); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return packet; +} + +//-------------------------------------------------- + +eap_status_e eap_type_securid_c::packet_send( + eap_buf_chain_wr_c * const data, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (m_mtu_length < data->get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (data->get_is_valid_data() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = get_type_partner()->packet_send( + &m_send_network_id, + data, + m_offset, + data_length, + data->get_buffer_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::finish_successful_authentication() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SECURID: function: finish_successful_authentication(), EAP-SUCCESS\n"))); + + eap_master_session_key_c empty_key( + m_am_tools, + m_eap_type); + u8_t key[1] = ""; + + eap_status_e status = empty_key.set_buffer( + key, + 0ul, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This needed in PEAPv2. Just an empty key is given to PEAPv2. + status = get_type_partner()->packet_data_crypto_keys( + &m_send_network_id, + &empty_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_eap_type, + eap_state_none, + eap_state_authentication_finished_successfully, + m_identifier, + true); + get_type_partner()->state_notification(¬ification); + + // Store úsername for reauthentication (client only) + if (m_is_client) + { + eap_variable_data_c key(m_am_tools); + status = m_am_type_securid->get_memory_store_key(&key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_tlv_message_data_c tlv_data(m_am_tools); + + status = tlv_data.add_message_data( + eap_type_gtc_stored_identity, + m_identity.get_data_length(), + m_identity.get_data()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_am_tools->memory_store_add_data( + &key, + &tlv_data, + eap_type_default_credential_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SECURID: function: finish_successful_authentication(): cannot store credentials\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_GTC: function: finish_successful_authentication(): ") + EAPL("username stored if no errors\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::finish_unsuccessful_authentication( + const bool authentication_cancelled) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SECURID: function: finish_unsuccessful_authentication()\n"))); + + if (authentication_cancelled == true) + { + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, // This must be used with eap_general_state_authentication_cancelled. + m_eap_type, + eap_state_none, + eap_general_state_authentication_cancelled, + m_identifier, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + get_type_partner()->state_notification(¬ification); + } + else + { + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + m_identifier, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + if (m_is_client == true) + { + eap_variable_data_c string(m_am_tools); + eap_status_e status = m_am_type_securid->read_auth_failure_string(&string); + if (status == eap_status_ok) + { + notification.set_notification_string(&string, true); + } + } + get_type_partner()->state_notification(¬ification); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::packet_process( + const eap_am_network_id_c * const /*receive_network_id*/, + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + if (eap_packet_length < EAP_SECURID_EAP_HEADER_SIZE - 1) // Without type code + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + if (eap_packet_length > received_eap->get_header_buffer_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + if (received_eap->get_type() == eap_type_notification) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + +#ifdef EAP_SECURID_SERVER + if (m_is_client) // Client + { +#endif + + status = client_packet_process( + received_eap, + eap_packet_length); + +#ifdef EAP_SECURID_SERVER + } + else // Server + { + status = server_packet_process( + received_eap, + eap_packet_length); + } +#endif + + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(received_eap, false); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::remove_username_store() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_securid_c::remove_username_store: Start\n"))); + + eap_status_e status = eap_status_process_general_error; + + eap_variable_data_c key(m_am_tools); + status = m_am_type_securid->get_memory_store_key(&key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_tlv_message_data_c tlv_data(m_am_tools); + + status = m_am_tools->memory_store_get_data( + &key, + &tlv_data); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SECURID: function: remove_username_store(): cannot get credentials, status=%d\n"), + status)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SECURID: function: remove_username_store(): credentials found\n"))); + + // Parse read data. + eap_array_c tlv_blocks(m_am_tools); + + status = tlv_data.parse_message_data(&tlv_blocks); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (u32_t ind = 0ul; ind < tlv_blocks.get_object_count(); ind++) + { + eap_tlv_header_c * const tlv = tlv_blocks.get_object(ind); + if (tlv != 0) + { + if (tlv->get_type() == eap_type_gtc_stored_identity) + { + status = m_identity.set_copy_of_buffer( + tlv->get_value(tlv->get_value_length()), + tlv->get_value_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SECURID: function: unknown credential type %d, length %d\n"), + tlv->get_type(), + tlv->get_value_length())); + } + } + } + + status = m_am_tools->memory_store_remove_data(&key); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SECURID: function: remove_username_store(): credentials removed from eapol\n"))); + + m_is_reauthentication = true; + m_identity_asked = true; + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_securid_c::configure(): this = 0x%08x\n"), + this)); + + eap_status_e status = eap_status_process_general_error; + + status = m_am_type_securid->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_offset = get_type_partner()->get_header_offset(&m_mtu_length, &m_trailer_length); + + // Check if the case is reauthentication (client only) + if (m_is_client) + { + remove_username_store(); + } + + // read configures + if (m_eap_type == eap_type_securid) + { + (void) m_am_type_securid->type_configure_read( + cf_str_EAP_SECURID_identity.get_field(), + &m_identity); + // Status does not matter. + + if (m_is_client == false) + { + (void) m_am_type_securid->type_configure_read( + cf_str_EAP_SECURID_passcode.get_field(), + &m_pincode); + } + } + else + { + (void) m_am_type_securid->type_configure_read( + cf_str_EAP_GTC_identity.get_field(), + &m_identity); + // Status does not matter. + + if (m_is_client == false) + { + (void) m_am_type_securid->type_configure_read( + cf_str_EAP_GTC_passcode.get_field(), + &m_passcode); + } + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_EXPANDED_TYPES) + { + eap_variable_data_c use_eap_expanded_type(m_am_tools); + eap_status_e status(eap_status_process_general_error); + + if (m_eap_type == eap_type_securid) + { + status = m_am_type_securid->type_configure_read( + cf_str_EAP_SECURID_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + } + else + { + status = m_am_type_securid->type_configure_read( + cf_str_EAP_GTC_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + } + + if (status != eap_status_ok) + { + status = m_am_type_securid->type_configure_read( + cf_str_EAP_CORE_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + } + + if (status == eap_status_ok + && use_eap_expanded_type.get_data_length() == sizeof(u32_t) + && use_eap_expanded_type.get_data() != 0) + { + u32_t *flag = reinterpret_cast(use_eap_expanded_type.get_data(use_eap_expanded_type.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_use_eap_expanded_type = true; + } + else + { + m_use_eap_expanded_type = false; + } + } + } + } +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + + //---------------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + + { + eap_variable_data_c use_EAP_FAST_response(m_am_tools); + + status = m_am_type_securid->type_configure_read( + cf_str_EAP_GTC_use_EAP_FAST_response.get_field(), + &use_EAP_FAST_response); + if (status == eap_status_ok) + { + const u32_t * const flag = reinterpret_cast( + use_EAP_FAST_response.get_data(sizeof(u32_t))); + if (flag != 0 && *flag != 0) + { + m_use_EAP_FAST_response = true; + } + else + { + m_use_EAP_FAST_response = false; + } + } + } + +#endif //#if defined(USE_FAST_EAP_TYPE) + + //---------------------------------------------------------- + +#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) + { + eap_variable_data_c skip_user_interactions(m_am_tools); + + status = m_am_type_securid->type_configure_read( + cf_str_EAP_skip_user_interactions_for_testing_purposes.get_field(), + &skip_user_interactions); + if (status == eap_status_ok + && skip_user_interactions.get_is_valid_data() == true) + { + u32_t *skip_user_interactions_flag = reinterpret_cast( + skip_user_interactions.get_data(sizeof(u32_t))); + if (skip_user_interactions_flag != 0) + { + if (*skip_user_interactions_flag != 0) + { + m_skip_user_interactions = true; + } + else + { + m_skip_user_interactions = false; + } + } + } + } + + if (m_skip_user_interactions == true) + { + (void) m_am_type_securid->type_configure_read( + cf_str_EAP_GTC_passcode.get_field(), + &m_passcode); + } +#endif //#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) + + //---------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// This function is to allow reuse of this object. +// The whole object state must be reset. +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_securid_c::reset(): m_is_client=%d, m_eap_type=%d\n"), + m_is_client, + convert_eap_type_to_u32_t(m_eap_type))); + + if (m_is_client) + { + remove_username_store(); + } + + // read configures + if (m_eap_type == eap_type_securid) + { + m_am_type_securid->type_configure_read( + cf_str_EAP_SECURID_identity.get_field(), + &m_identity); + // Status does not matter. + } + else + { + m_am_type_securid->type_configure_read( + cf_str_EAP_GTC_identity.get_field(), + &m_identity); + // Status does not matter. + } + + m_state.set_state(eap_type_securid_state_none); + m_identity_asked = false; + m_is_pending = false; + + eap_status_e status = m_am_type_securid->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/securid/core/eap_type_securid_client.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/securid/core/eap_type_securid_client.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,612 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 114 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "eap_am_memory.h" +#include "eap_state_notification.h" +#include "eap_type_securid.h" +#include "eap_type_securid_types.h" +#include "eap_buffer.h" + +const u8_t EAP_SECURID_PIN_STRING[] = "pin"; +const u8_t EAP_SECURID_PASSCODE_STRING[] = "passcode"; + + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::query_eap_identity( + const bool /*must_be_synchronous*/, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + m_identifier = eap_identifier; + + eap_status_e status; + + if (m_identity.get_is_valid_data() == false + || m_identity.get_data_length() == 0) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_type_securid_c::query_eap_identity(): Identity (username) is empty or invalid\n"))); + + // Ask identity + if (m_is_pending == false) + { + m_is_pending = true; + status = m_am_type_securid->show_identity_query_dialog(m_eap_type, &m_identity); + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_type_securid_c::query_eap_identity(): show_identity_query_dialog returns %d\n"), + status)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); + } + } + else + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_type_securid_c::query_eap_identity(): m_identity (identity or username) is valid.\n"))); + + status = identity->set_copy_of_buffer(&m_identity); + + m_state.set_state(eap_type_securid_state_identity_query); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::complete_eap_identity_query( + const eap_variable_data_c * const identity_utf8) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_GTC: function: complete_eap_identity_query, identity:"), + m_identity.get_data(m_identity.get_data_length()), + m_identity.get_data_length())); + + eap_status_e status = get_type_partner()->complete_eap_identity_query( + &m_send_network_id, + identity_utf8, + m_identifier); + + if (status == eap_status_ok) + { + m_state.set_state(eap_type_securid_state_identity_query); + } + + m_identity_asked = true; + m_is_pending = false; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_type_securid_c::client_packet_process( + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_drop_packet_quietly; + + m_identifier = received_eap->get_identifier(); + + if (received_eap->get_type() == eap_type_identity) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + if (received_eap->get_code() == eap_code_failure) + { + if (m_state.is_valid_state(eap_type_securid_state_failure) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + status = finish_unsuccessful_authentication(false); + + m_state.set_state(eap_type_securid_state_failure); + } + else if (received_eap->get_code() == eap_code_success) + { + if (m_state.is_valid_state(eap_type_securid_state_success) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + status = finish_successful_authentication(); + + m_state.set_state(eap_type_securid_state_success); + } + else if (received_eap->get_type() != m_eap_type) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else if (received_eap->get_code() == eap_code_request) // Request + { + // Securid + if (m_eap_type == eap_type_securid) + { + status = client_securid_packet_process( + received_eap, + eap_packet_length); + } + // GTC + else if (m_eap_type == eap_type_generic_token_card) + { + status = client_gtc_packet_process( + received_eap, + eap_packet_length); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_type_securid_c::client_securid_packet_process( + eap_header_wr_c * const eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_drop_packet_quietly; + + if (eap_packet_length < eap->get_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + u32_t type_data_length = eap->get_data_length(); + + if (type_data_length == 0) + { + // Passcode query + if (m_is_pending == false) + { + m_is_pending = true; + m_am_type_securid->show_passcode_query_dialog(&m_passcode, true); + if (status != eap_status_pending_request) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + u8_t * data = eap->get_type_data(type_data_length); + if (data == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (type_data_length < 4) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else if (type_data_length >= 4) + { + if (m_am_tools->memcmp(data, EAP_SECURID_PIN_STRING, 3) == 0 + && data[3] == 0x00) + { + // Pincode query + if (m_is_pending == false) + { + m_is_pending = true; + m_am_type_securid->show_pincode_query_dialog(&m_passcode, &m_pincode, true); + if (status != eap_status_pending_request) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (type_data_length == 9 + && m_am_tools->memcmp(data, EAP_SECURID_PASSCODE_STRING, 8) == 0 + && data[8] == 0x00) + { + // Additional passcode query + if (m_is_pending == false) + { + m_is_pending = true; + m_am_type_securid->show_passcode_query_dialog(&m_passcode, false); + if (status != eap_status_pending_request) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + } + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_type_securid_c::client_gtc_packet_process( + eap_header_wr_c * const eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_drop_packet_quietly; + + if (eap_packet_length < eap->get_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + u32_t type_data_length = eap->get_type_data_length(); + if (type_data_length > 1020) + { + type_data_length = 1020; // Magic + } + + // Passcode query + if (m_is_pending == false) + { + m_is_pending = true; + +#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) + if (m_skip_user_interactions == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: EAP-GTC: eap_type_securid_c::client_gtc_packet_process(): skips user interactions\n"))); + + status = client_gtc_complete_user_input_query(&m_passcode); + } + else +#endif //#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) + { + eap_variable_data_c message(m_am_tools); + status = message.set_copy_of_buffer(eap->get_type_data(type_data_length), type_data_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_am_type_securid->show_gtc_query_dialog( + &m_passcode, + message.get_data(), + message.get_data_length(), + true); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::client_securid_complete_passcode_query( + const eap_variable_data_c * const passcode_utf8) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Send passcode + u32_t packet_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + passcode_utf8->get_data_length() + 2 + 1; + + eap_buf_chain_wr_c * packet = create_send_packet(packet_length); + if (!packet) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_base_c eap_header( + m_am_tools, + packet->get_data_offset(m_offset, packet_length), + packet_length); + if (eap_header.get_is_valid() == false) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + eap_header.set_code(eap_code_response); + eap_header.set_identifier(m_identifier); + eap_header.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + eap_header.set_type( + m_eap_type, + m_use_eap_expanded_type); + + u8_t * type_data = const_cast (eap_header.get_type_data_offset(0, eap_header.get_type_data_length())); + if (type_data == 0) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + m_am_tools->memset(type_data, 0x00, 2); + type_data += 2; + m_am_tools->memmove( + type_data, + passcode_utf8->get_data(passcode_utf8->get_data_length()), + passcode_utf8->get_data_length()); + type_data += passcode_utf8->get_data_length(); + type_data[0] = 0x00; + } + + eap_status_e status = packet_send(packet, packet_length); + delete packet; + + m_is_pending = false; + + m_state.set_state(eap_type_securid_state_passcode_query); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::client_securid_complete_pincode_query( + const eap_variable_data_c * const pincode, + const eap_variable_data_c * const passcode) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_first_pincode_query = false; + + // Send pincode + u32_t packet_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + passcode->get_data_length() + 2 + 1 + pincode->get_data_length() + 1; + eap_buf_chain_wr_c * packet = create_send_packet(packet_length); + if (!packet) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_base_c eap_header( + m_am_tools, + packet->get_data_offset(m_offset, packet_length), + packet_length); + if (eap_header.get_is_valid() == false) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + eap_header.set_code(eap_code_response); + eap_header.set_identifier(m_identifier); + eap_header.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + eap_header.set_type( + m_eap_type, + m_use_eap_expanded_type); + + u8_t * type_data = const_cast (eap_header.get_type_data_offset(0, eap_header.get_type_data_length())); + if (type_data == 0) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memset(type_data, 0x00, 2); + type_data += 2; + // identity + m_am_tools->memmove( + type_data, + passcode->get_data(passcode->get_data_length()), + passcode->get_data_length()); + type_data += passcode->get_data_length(); + type_data[0] = 0x00; + type_data++; + m_am_tools->memmove( + type_data, + pincode->get_data(pincode->get_data_length()), + pincode->get_data_length()); + type_data += pincode->get_data_length(); + type_data[0] = 0x00; + + eap_status_e status = packet_send(packet, packet_length); + delete packet; + + m_is_pending = false; + + m_state.set_state(eap_type_securid_state_pincode_query); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::client_gtc_complete_user_input_query( + const eap_variable_data_c * const response_utf8) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Send response + u32_t packet_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + response_utf8->get_data_length(); + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_response == true) + { + packet_length += EAP_FAST_EAP_GTC_RESPONSE_PREFIX_LENGTH + m_identity.get_data_length() + EAP_FAST_EAP_GTC_RESPONSE_SEPARATOR_LENGTH; + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + eap_buf_chain_wr_c * packet = create_send_packet(packet_length); + if (!packet) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_base_c eap_header( + m_am_tools, + packet->get_data_offset(m_offset, packet_length), + packet_length); + if (eap_header.get_is_valid() == false) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + eap_header.set_code(eap_code_response); + eap_header.set_identifier(m_identifier); + eap_header.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + eap_header.set_type( + m_eap_type, + m_use_eap_expanded_type); + + if (response_utf8->get_data_length() > 0UL) + { + u8_t * type_data = const_cast (eap_header.get_type_data_offset(0, eap_header.get_type_data_length())); + if (type_data == 0) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_response == true) + { + eap_variable_data_c eap_fast_response(m_am_tools); + if (eap_fast_response.get_is_valid() == false) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_fast_response.set_copy_of_buffer(EAP_FAST_EAP_GTC_RESPONSE_PREFIX, EAP_FAST_EAP_GTC_RESPONSE_PREFIX_LENGTH); + if (status != eap_status_ok) + { + delete packet; + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_fast_response.add_data(&m_identity); + if (status != eap_status_ok) + { + delete packet; + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_fast_response.add_data(EAP_FAST_EAP_GTC_RESPONSE_SEPARATOR, EAP_FAST_EAP_GTC_RESPONSE_SEPARATOR_LENGTH); + if (status != eap_status_ok) + { + delete packet; + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_fast_response.add_data(response_utf8); + if (status != eap_status_ok) + { + delete packet; + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_am_tools->memmove( + type_data, + eap_fast_response.get_data(), + eap_fast_response.get_data_length()); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + m_am_tools->memmove( + type_data, + response_utf8->get_data(response_utf8->get_data_length()), + response_utf8->get_data_length()); + } + } + + eap_status_e status = packet_send(packet, packet_length); + delete packet; + + m_is_pending = false; + + m_state.set_state(eap_type_securid_state_gtc_user_input_query); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/securid/core/eap_type_securid_server.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/securid/core/eap_type_securid_server.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,194 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 116 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "eap_am_memory.h" +#include "eap_state_notification.h" +#include "eap_type_securid.h" +#include "eap_type_securid_types.h" +#include "eap_buffer.h" + +static const u8_t EAP_SECURID_PASSCODE_STRING[] = "passcode"; + + +#ifdef EAP_SECURID_SERVER + +eap_status_e eap_type_securid_c::server_packet_process( + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_header_corrupted; + + if (eap_packet_length < received_eap->get_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + + if (received_eap->get_type() == eap_type_identity) + { + m_identifier = static_cast (received_eap->get_identifier() + 1); + + // Send request + + const u8_t * const message = EAP_SECURID_PASSCODE_STRING; + u32_t message_length = m_am_tools->strlen(reinterpret_cast(message)); + + u32_t packet_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + message_length; // Remove null termination + + eap_buf_chain_wr_c * packet = create_send_packet(packet_length); + if (!packet) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_base_c eap_header( + m_am_tools, + packet->get_data_offset(m_offset, packet_length), + packet_length); + if (eap_header.get_is_valid() == false) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + eap_header.set_code(eap_code_request); + eap_header.set_identifier(++m_identifier); + eap_header.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + eap_header.set_type( + m_eap_type, + m_use_eap_expanded_type); + + u8_t * type_data = const_cast (eap_header.get_type_data_offset(0, eap_header.get_type_data_length())); + if (type_data == 0) + { + delete packet; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove(type_data, message, message_length); + + eap_status_e status = packet_send(packet, packet_length); + delete packet; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (received_eap->get_type() == eap_type_securid) + { + // Verify passcode response. + u8_t * type_data = const_cast(received_eap->get_type_data(received_eap->get_type_data_length())); + if (type_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (received_eap->get_type_data_length() != m_pincode.get_data_length() + || m_am_tools->memcmp( + type_data, + m_pincode.get_data(m_pincode.get_data_length()), + m_pincode.get_data_length()) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + else if (received_eap->get_type() == eap_type_generic_token_card) + { + // Verify passcode response. + u8_t * type_data = const_cast(received_eap->get_type_data(received_eap->get_type_data_length())); + if (type_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_use_EAP_FAST_response == true) + { + const u32_t passcode_offset(EAP_FAST_EAP_GTC_RESPONSE_PREFIX_LENGTH + m_identity.get_data_length() + EAP_FAST_EAP_GTC_RESPONSE_SEPARATOR_LENGTH); + + if (received_eap->get_type_data_length() < passcode_offset+m_passcode.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + type_data += passcode_offset; + + if (m_am_tools->memcmp( + type_data, + m_passcode.get_data(m_passcode.get_data_length()), + m_passcode.get_data_length()) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + if (received_eap->get_type_data_length() != m_passcode.get_data_length() + || m_am_tools->memcmp( + type_data, + m_passcode.get_data(m_passcode.get_data_length()), + m_passcode.get_data_length()) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + m_identifier++; + + status = finish_successful_authentication(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + +} + +#endif //#ifdef EAP_SECURID_SERVER + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/securid/core/eap_type_securid_state.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/securid/core/eap_type_securid_state.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,192 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 117 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include "eap_type_securid_state.h" + +eap_type_securid_state_c::eap_type_securid_state_c(const bool client) +{ + m_is_client = client; + + if (m_is_client) + { + m_state = eap_type_securid_state_none; + m_prev_state = eap_type_securid_state_none; + m_next_state = eap_type_securid_state_identity_query; + } + else + { + m_state = eap_type_securid_state_none; + m_prev_state = eap_type_securid_state_none; + m_next_state = eap_type_securid_state_identity_response; + } +} + +eap_type_securid_state_c::~eap_type_securid_state_c() +{ +} + +eap_type_securid_state_variable_e eap_type_securid_state_c::get_state() const +{ + return m_state; +} + +void eap_type_securid_state_c::set_state(const eap_type_securid_state_variable_e new_state) +{ + set_state(new_state, eap_type_securid_state_none); +} + +void eap_type_securid_state_c::set_state( + const eap_type_securid_state_variable_e new_state, + const eap_type_securid_state_variable_e new_next_state) + +{ + m_prev_state = m_state; + m_state = new_state; + m_next_state = new_next_state; +} + +bool eap_type_securid_state_c::is_valid_state(const eap_type_securid_state_variable_e new_state) const +{ + if (m_is_client) // Client + { + if (new_state == eap_type_securid_state_identity_query) + { + return true; + } + + // Check validity against (current) state. + // If it fails then against previous state (in case of resending) + + switch (m_state) + { + case eap_type_securid_state_none: + if (new_state == eap_type_securid_state_identity_query + || new_state == eap_type_securid_state_gtc_user_input_query) + { + return true; + } + break; + + case eap_type_securid_state_identity_query: + if (new_state == eap_type_securid_state_passcode_query) + { + return true; + } + break; + + case eap_type_securid_state_passcode_query: + if (new_state == eap_type_securid_state_success + || new_state == eap_type_securid_state_failure) + { + return true; + } + break; + + case eap_type_securid_state_gtc_user_input_query: + if (new_state == eap_type_securid_state_gtc_user_input_query + || new_state == eap_type_securid_state_success + || new_state == eap_type_securid_state_failure) + { + return true; + } + break; + + case eap_type_securid_state_success: + case eap_type_securid_state_failure: + // Session is ended + return false; + + default: + ; + } + + } + + else // Server + { + if (new_state == eap_type_securid_state_identity_response) + { + return true; + } + + switch (m_state) + { + case eap_type_securid_state_none: + //if (new_state == eap_type_securid_state_identity_response) See 8 lines up. + //{ + // return true; + //} + break; + + case eap_type_securid_state_identity_response: + if (new_state == eap_type_securid_state_passcode_response + || new_state == eap_type_securid_state_gtc_response) + { + return true; + } + break; + + case eap_type_securid_state_passcode_response: + if (m_next_state == new_state) + { + return true; + } + if (m_next_state == eap_type_securid_state_passcode_response) + { + return true; + } + break; + + case eap_type_securid_state_gtc_response: + if (new_state == eap_type_securid_state_gtc_response) + { + return true; + } + break; + + default: + ; + } + } + return false; +} + +void eap_type_securid_state_c::set_failure_message_received() +{ +} + +void eap_type_securid_state_c::unset_failure_message_received() +{ +} + +void eap_type_securid_state_c::cancel_eap_failure_timer() +{ +} + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/securid/core/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/securid/core/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,22 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_securid + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/type/securid/core/eap_type_securid_client.cpp \ + $(WLAN_COMMON)/type/securid/core/eap_type_securid.cpp \ + $(WLAN_COMMON)/type/securid/core/eap_type_securid_server.cpp \ + $(WLAN_COMMON)/type/securid/core/eap_type_securid_state.cpp \ + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_securid_simulator.$(LIB) \ + -lstdc++ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/securid/include/abs_eap_type_securid_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/securid/include/abs_eap_type_securid_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,142 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#ifndef _ABS_MSCHAPV2_STATE_H_ +#define _ABS_MSCHAPV2_STATE_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_buffer.h" +#include "eap_base_type.h" +#include "eap_config.h" +#include "eap_type_mschapv2_types.h" + + +/// This class declares the functions eap_type_gsmsim_state_c +/// requires from the partner class. +class EAP_EXPORT abs_eap_type_mschapv2_state_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Constructor does nothing. + */ + virtual ~abs_eap_type_mschapv2_state_c() + { + } + + /** + * Desstructor does nothing. + */ + abs_eap_type_mschapv2_state_c() + { + } + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @see abs_eap_base_type_c::get_header_offset(). + */ + virtual const u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual const eap_status_e read_configure( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual const eap_status_e write_configure( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * + * Adaptation module internally implements the timer. + */ + virtual const eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * + * Adaptation module internally implements the timer. + */ + virtual const eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual const eap_status_e cancel_all_timers() = 0; + + //-------------------------------------------------- +}; // class abs_eap_type_gsmsim_state_c + + + +#endif // _ABS_MSCHAPV2_STATE_H_ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/securid/include/eap_type_securid.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/securid/include/eap_type_securid.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,213 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef EAP_TYPE_SECURID_H +#define EAP_TYPE_SECURID_H + +#include "eap_base_type.h" + +#include "abs_eap_am_type_securid.h" +#include "eap_am_type_securid.h" +#include "eap_am_network_id.h" + +#include "eap_type_securid_state.h" + +/// This class is implementation of SecurID EAP-type. +class EAP_EXPORT eap_type_securid_c +: public abs_eap_am_type_securid_c +, public eap_base_type_c +{ + +private: + + /// This is pointer to adaptation module of SecurID EAP type. + eap_am_type_securid_c * const m_am_type_securid; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + eap_type_value_e m_eap_type; + + bool m_free_am_type_securid; + + bool m_use_EAP_FAST_response; + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + eap_am_network_id_c m_send_network_id; + + u8_t m_identifier; + + eap_variable_data_c m_identity; + + // Server only: + eap_variable_data_c m_passcode; + eap_variable_data_c m_pincode; + + bool m_is_first_passcode_query; + bool m_is_first_pincode_query; + + bool m_identity_asked; + bool m_is_pending; + + eap_type_securid_state_c m_state; + + bool m_is_reauthentication; + + u32_t m_offset, m_mtu_length, m_trailer_length; + + bool m_use_eap_expanded_type; + +#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) + bool m_skip_user_interactions; +#endif //#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) + + + EAP_FUNC_IMPORT eap_status_e finish_successful_authentication(); + + EAP_FUNC_IMPORT eap_status_e finish_unsuccessful_authentication( + const bool authentication_cancelled); + + EAP_FUNC_IMPORT eap_status_e complete_eap_identity_query( + const eap_variable_data_c * const identity); + + EAP_FUNC_IMPORT eap_status_e client_securid_complete_passcode_query( + const eap_variable_data_c * const passcode); + + EAP_FUNC_IMPORT eap_status_e client_securid_complete_pincode_query( + const eap_variable_data_c * const pincode, + const eap_variable_data_c * const passcode); + + EAP_FUNC_IMPORT eap_status_e client_gtc_complete_user_input_query( + const eap_variable_data_c * const input); + + EAP_FUNC_IMPORT eap_status_e remove_username_store(); + + /** + * This function processes the SecurID packets. + */ + EAP_FUNC_IMPORT eap_status_e securid_packet_process( + eap_header_wr_c * const eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + /** + * This function tells if the object is a client or a server.. + */ + EAP_FUNC_IMPORT bool get_is_client(); + + eap_buf_chain_wr_c * create_send_packet(u32_t length); + + eap_status_e packet_send( + eap_buf_chain_wr_c * const data, + const u32_t data_length); + + eap_status_e client_packet_process( + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length); + + eap_status_e client_securid_packet_process( + eap_header_wr_c * const eap, + const u32_t eap_packet_length); + + eap_status_e client_gtc_packet_process( + eap_header_wr_c * const eap, + const u32_t eap_packet_length); + +#ifdef EAP_SECURID_SERVER + + eap_status_e server_packet_process( + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length); + +#endif + +protected: + +public: + + /** + * Destructor cancels all timers and deletes member attributes. + */ + EAP_FUNC_IMPORT virtual ~eap_type_securid_c(); + + /** + * Constructor initializes all member attributes. + */ + EAP_FUNC_IMPORT eap_type_securid_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + eap_am_type_securid_c * const am_type_securid, + const bool free_am_type_securid, + const eap_type_value_e current_eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + /** + * The partner class calls this function when EAP/SecurID packet is received. + * see also eap_base_type_c::packet_process(). + */ + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + + // This is commented in eap_base_type_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT void set_is_valid(); + + /** + * This function resets the reused eap_type_securid_c object. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is commented in eap_base_type_c::query_eap_identity(). + EAP_FUNC_IMPORT eap_status_e query_eap_identity( + const bool must_be_synchronous, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier); + + EAP_FUNC_IMPORT eap_status_e set_initial_eap_identifier( + const eap_am_network_id_c * const receive_network_id, + const u8_t initial_identifier); + + // This is commented in eap_base_type_c::eap_acknowledge(). + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + +}; // class eap_type_securid_c + +#endif // EAP_TYPE_SECURID_H + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/securid/include/eap_type_securid_state.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/securid/include/eap_type_securid_state.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#ifndef EAP_TYPE_SECURID_STATE_H +#define EAP_TYPE_SECURID_STATE_H + +#include "eap_am_export.h" + +/** + * This is the internal state of the SecurId and GTC EAP type. + */ +enum eap_type_securid_state_variable_e +{ + eap_type_securid_state_none, + eap_type_securid_state_identity_query, + + eap_type_securid_state_passcode_query, + eap_type_securid_state_pincode_query, + eap_type_securid_state_success, + eap_type_securid_state_failure, + + eap_type_securid_state_gtc_user_input_query, + + eap_type_securid_state_identity_response, + eap_type_securid_state_passcode_response, + + eap_type_securid_state_gtc_response +}; + + +class EAP_EXPORT eap_type_securid_state_c +{ +private: + + bool m_is_client; + eap_type_securid_state_variable_e m_state; + eap_type_securid_state_variable_e m_next_state; + eap_type_securid_state_variable_e m_prev_state; + +public: + eap_type_securid_state_c(const bool client); + + virtual ~eap_type_securid_state_c(); + + eap_type_securid_state_variable_e get_state() const; + + void set_state(const eap_type_securid_state_variable_e new_state); + + void set_state(const eap_type_securid_state_variable_e new_state, const eap_type_securid_state_variable_e next_state); + + bool is_valid_state(const eap_type_securid_state_variable_e new_state) const; + + void set_failure_message_received(); + + void unset_failure_message_received(); + + void cancel_eap_failure_timer(); +}; + + +#endif // EAP_TYPE_SECURID_STATE_H + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/securid/include/eap_type_securid_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/securid/include/eap_type_securid_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,119 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef SECURID_TYPES_H +#define SECURID_TYPES_H + +#include "eap_configuration_field.h" + + +const u32_t TRACE_FLAGS_SECURID_ERROR = eap_am_tools_c::eap_trace_mask_error; + + +enum eap_type_gtc_stored_e +{ + eap_type_gtc_stored_none, + eap_type_gtc_stored_identity, +}; + + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SECURID_identity, + "EAP_SECURID_identity", + eap_configure_type_hex_data, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SECURID_passcode, + "EAP_SECURID_passcode", + eap_configure_type_hex_data, + true); + + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GTC_identity, + "EAP_GTC_identity", + eap_configure_type_hex_data, + false); + + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GTC_passcode, + "EAP_GTC_passcode", + eap_configure_type_hex_data, + false); + + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SECURID_use_eap_expanded_type, + "EAP_SECURID_use_eap_expanded_type", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GTC_use_eap_expanded_type, + "EAP_GTC_use_eap_expanded_type", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GTC_use_EAP_FAST_response, + "EAP_GTC_use_EAP_FAST_response", + eap_configure_type_boolean, + false); + +/** + * This u32_t configuration value specifies the maximum session validity time in seconds. + * Default value is 12 hours in seconds, which is 43200 seconds. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_GTC_max_session_validity_time, + "EAP_GTC_max_session_validity_time", + eap_configure_type_u32_t, + false); + + +const u8_t EAP_FAST_EAP_GTC_RESPONSE_PREFIX[] = "RESPONSE="; +const u32_t EAP_FAST_EAP_GTC_RESPONSE_PREFIX_LENGTH = sizeof(EAP_FAST_EAP_GTC_RESPONSE_PREFIX)-1ul; + +const u8_t EAP_FAST_EAP_GTC_RESPONSE_SEPARATOR[] = { 0x00 }; +const u32_t EAP_FAST_EAP_GTC_RESPONSE_SEPARATOR_LENGTH = sizeof(EAP_FAST_EAP_GTC_RESPONSE_SEPARATOR); + +/** @} */ // End of group SECURID_config_options. + +//-------------------------------------------------- + +/// Macro traces payload type and data. +#define EAP_SECURID_TRACE_PAYLOAD(prefix, payload) \ + { \ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT | TRACE_TEST_VECTORS, (EAPL("%s (0x%08x): current payload 0x%04x=%s, data length 0x%04x.\n"), \ + prefix, payload, payload->get_current_payload(), payload->get_payload_AT_string(), payload->get_data_length())); \ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT | TRACE_TEST_VECTORS, (EAPL("payload"), \ + payload, \ + payload->get_payload_length())); \ + } + +//-------------------------------------------------- + +#endif //SECURID_TYPES_H + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/eap/include/eap_type_simple_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/eap/include/eap_type_simple_config.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,660 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TYPE_SIMPLE_CONFIG_H_) +#define _EAP_TYPE_SIMPLE_CONFIG_H_ + +#if defined(USE_EAP_SIMPLE_CONFIG) + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_am_type_simple_config.h" +#include "eap_am_network_id.h" +#include "abs_eap_base_type.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "abs_eap_base_timer.h" +#include "eap_crypto_api.h" +#include "eap_protocol_layer.h" +#include "eap_type_simple_config_types.h" +#include "abs_simple_config_base_record.h" +#include "eap_master_session_key.h" +#include "simple_config_types.h" + +class eap_simple_config_header_c; +class abs_eap_am_tools_c; +class abs_eap_base_type_c; +class eap_am_type_simple_config_c; +class simple_config_base_record_c; + +//-------------------------------------------------- + + +/// This class is implementation of SIMPLE_CONFIG type. See more detailed design and architecture document EAP_SIMPLE_CONFIG.doc. +class EAP_EXPORT eap_type_simple_config_c +: public abs_eap_base_timer_c +, public eap_base_type_c +, public abs_eap_am_type_simple_config_c +, public abs_simple_config_base_record_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to adaptation module of SIMPLE_CONFIG type. + eap_am_type_simple_config_c * m_am_type_simple_config; + + /// This is pointer to SIMPLE_CONFIG implementation. + simple_config_base_record_c * m_simple_config_record; + + /// This is the realm part of NAI of the authenticator. + /// Client uses this as a realm part on the NAI. + eap_variable_data_c m_nai_realm; + + /// This is the full NAI of the client. + eap_variable_data_c m_NAI; + + /// This is network identity of the sent packet from this authentication session. + eap_am_network_id_c m_send_network_id; + + /// This is offset in bytes of the EAP-type header in the packet buffer. + /// Offset is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_simple_config_header_offset; + + /// This is maximum transfer unit in bytes. + /// MTU is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_MTU; + + /// This is length of the trailer in bytes. + /// Trailer length is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_trailer_length; + + /// This is the state of this authentication session. + eap_type_simple_config_state_variable_e m_state; + + /// This is the saved previous state of this authentication session. + eap_type_simple_config_state_variable_e m_saved_previous_state; + + /// This is the state of reassembly. + eap_type_simple_config_reassembly_state_e m_reassembly_state; + + /// This is the saved previous state of reassembly. + eap_type_simple_config_reassembly_state_e m_saved_previous_reassembly_state; + + /// This is the offset of next fragment to be send from m_simple_config_message_buffer. + u32_t m_simple_config_message_send_offset; + + /// This is the buffer for SIMPLE_CONFIG-message reassembly and fragmentation. + eap_variable_data_c m_simple_config_message_buffer; + + u8_t m_first_fragment_eap_identifier; + + bool m_free_am_type_simple_config; + + bool m_free_simple_config_record; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + /// True value of this flag indicates the identifier of the EAP-Response/Identity must be checked. + /// This is not possible cases where identifier of the EAP-Request/Identity is generated by other network entities. + bool m_check_identifier_of_eap_identity_response; + + + /// True value means this is a test version of SIMPLE_CONFIG. + bool m_simple_config_test_version; + + /// This flag forces check of NAI realm. Realm must be the same as given in EAP_SIMPLE_CONFIG_manual_realm configuration option. + /// Default value is false, check is not done by default. + bool m_check_nai_realm; + + /// This flag indicates whether the EAP-Failure was received. + /// On successfull authentication bogus EAP-Failure is ignored. + bool m_failure_message_received; + + /// This variable is set true when authentication finished successfully. + bool m_authentication_finished_successfully; + + /// This variable stores the last used EAP-Identifier. + /// Client will always send EAP-Response with this identifier. + /// Server will always send EAP-Request with this identifier increased by one. + /// Server increase this identifier after successfull packet send. + u8_t m_last_eap_identifier; + + /// This flag is set true when shutdown is called. + /// This is for internal sanity check. + bool m_shutdown_was_called; + + // This variable contains the type of the WSC message (fragment) being sent. + simple_config_Message_Type_e m_simple_config_message_type; + + //-------------------------------------------------- + + /** + * This function returns the domain name, realm part of NAI. + */ + EAP_FUNC_IMPORT eap_variable_data_c * get_nai_realm(); + + /** + * This function returns the full NAI. + */ + EAP_FUNC_IMPORT eap_variable_data_c * get_NAI(); + + /** + * This is the situation before the update_buffer_indexes() call. + * @code + * + * |<---------buffer_offset-------->|<----------buffer_free----------------->| + * | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * This is the situation after the update_buffer_indexes() call. + * @code + * + * |<-----------------buffer_offset--------------------->|<---buffer_free--->| + * | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * Note maximum_buffer_size could be larger than (m_simple_config_header_offset + m_MTU + m_trailer_length). + */ + EAP_FUNC_IMPORT void update_buffer_indexes( + const u32_t maximum_buffer_size, + const u32_t payload_size, + u32_t * const buffer_offset, + u32_t * const buffer_free); + + /** + * This is the situation before the update_payload_indexes() call. + * @code + * + * |<---------buffer_offset-------->|<----------buffer_free----------------->| + * | | | + * | |<-data_offset->|<--------data_free--------------------->| + * | | | | + * | | |<---payload_size--->| | + * | | | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * This is the situation after the update_payload_indexes() call. + * @code + * + * |<-----------------buffer_offset--------------------->|<---buffer_free--->| + * | | | + * | |<----------data_offset------------->|<----data_free---->| + * | | | | + * | | |<---payload_size--->| | + * | | | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * Note maximum_buffer_size could be larger than (m_simple_config_header_offset + m_MTU + m_trailer_length). + */ + EAP_FUNC_IMPORT void update_payload_indexes( + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + const u32_t payload_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_offset, + u32_t * const buffer_free); + + /** + * This function reads the identity payload. Identity is stored to handler->get_identity(). + */ + EAP_FUNC_IMPORT eap_status_e parse_identity( + const u8_t * const identity, ///< This is pointer to received EAP-Identity buffer. + const u32_t identity_length ///< This is length of received EAP-Identity buffer. + ); + + /** + * This function chechs NAI. + */ + EAP_FUNC_IMPORT eap_status_e check_NAI( + const u8_t * const identity, + const u32_t identity_length, + const u8_t * const at_character); + + /** + * This function traces the EAP packet. + */ + EAP_FUNC_IMPORT void packet_trace( + eap_const_string prefix, + const eap_am_network_id_c * const receive_network_id, + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length); + + /** + * This function finishes the successfull authentication. + * Generated keys are offered to lower layer. + * Connection handle is initialised. + */ + EAP_FUNC_IMPORT eap_status_e finish_successful_authentication(); + + /** + * This function sends a notification of possible failed authentication + * to lower layer. + */ + EAP_FUNC_IMPORT eap_status_e send_final_notification(); + + + /** + * This function returns the state of this authentication session. + */ + EAP_FUNC_IMPORT eap_type_simple_config_state_variable_e get_state() const; + + /** + * This function sets the new state and notifies the lower layer of this change. + */ + EAP_FUNC_IMPORT void set_state(const eap_type_simple_config_state_variable_e state); + + /** + * This function saves the current m_state to m_saved_previous_state. + * The saved state is restored in error case. + */ + EAP_FUNC_IMPORT void save_current_state(); + + /** + * This function restores the saved state. + */ + EAP_FUNC_IMPORT void restore_saved_previous_state(); + + + /** + * This function returns the state of reassembly. + */ + EAP_FUNC_IMPORT eap_type_simple_config_reassembly_state_e get_reassembly_state() const; + + /** + * This function sets the new reassembly state. + */ + EAP_FUNC_IMPORT void set_reassembly_state(const eap_type_simple_config_reassembly_state_e state); + + /** + * This function saves the current m_reassembly_state to m_saved_previous_reassembly_state. + * The saved state is restored in error case. + */ + EAP_FUNC_IMPORT void save_current_reassembly_state(); + + /** + * This function restores the saved reassembly state. + */ + EAP_FUNC_IMPORT void restore_saved_reassembly_state(); + + + /** + * This function returns the send network identity of this session. + */ + EAP_FUNC_IMPORT eap_am_network_id_c * get_send_network_id(); + + /** + * This function stores the last EAP-Identifier. + */ + EAP_FUNC_IMPORT void set_last_eap_identifier(const u8_t last_eap_identifier); + + /** + * This function returns the last stored EAP-Identifier. + */ + EAP_FUNC_IMPORT u8_t get_last_eap_identifier() const; + + eap_status_e check_received_eap_identifier( + const eap_header_wr_c * const eap_header); + + + /** + * This function returns string of the current state. This is for trace purposes. + */ + EAP_FUNC_IMPORT eap_const_string get_state_string() const; + + /** + * This function returns string of the current state. This is for trace purposes. + */ + EAP_FUNC_IMPORT eap_const_string get_saved_previous_state_string() const; + + /** + * This function returns string of the current reassembly state. This is for trace purposes. + */ + EAP_FUNC_IMPORT eap_const_string get_reassembly_state_string() const; + + + /** + * This function sets the m_failure_message_received flag true. + */ + EAP_FUNC_IMPORT void set_failure_message_received(); + + /** + * This function sets the m_failure_message_received flag false. + */ + EAP_FUNC_IMPORT void unset_failure_message_received(); + + /** + * This function returns the m_failure_message_received flag. + */ + EAP_FUNC_IMPORT bool get_failure_message_received() const; + + /** + * This function sends an simple config fragment acknowledge. + */ + EAP_FUNC_IMPORT eap_status_e send_sc_frag_ack(); + + /** + * This function sends EAP-SIMPLE_CONFIG Start message. + */ + EAP_FUNC_IMPORT eap_status_e send_simple_config_start_message( + const u8_t next_eap_identifier ///< This is EAP-Identifier of next EAP packet. + ); + + /** + * This function sends starts EAP-SIMPLE_CONFIG after a start message is received. + */ + EAP_FUNC_IMPORT eap_status_e start_simple_config_authentication( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + const eap_variable_data_c * const NAI ///< This is the full NAI of the client. + ); + + /** + * This function extracts the SIMPLE_CONFIG-record message from m_simple_config_message_buffer and forwards it to simple_config_base_record_c object. + */ + EAP_FUNC_IMPORT eap_status_e simple_config_message_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_simple_config_header_c * const received_simple_config, ///< This is pointer to EAP header including EAP-SIMPLE_CONFIG fields. + const u32_t simple_config_packet_length ///< This is length of received EAP-SIMPLE_CONFIG packet. + ); + + /** + * This function sends the EAP-SIMPLE_CONFIG message from rm_simple_config_reassembly_buffer. + */ + EAP_FUNC_IMPORT eap_status_e eap_simple_config_fragment_send(); + + EAP_FUNC_IMPORT eap_status_e handle_eap_identity_query( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const bool use_manual_username, + const eap_variable_data_c * const manual_username, + const bool use_manual_realm, + const eap_variable_data_c * const manual_realm + ); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor cancels all timers and deletes member attributes. + */ + EAP_FUNC_IMPORT virtual ~eap_type_simple_config_c(); + + /** + * Constructor initializes all member attributes. + */ + EAP_FUNC_IMPORT eap_type_simple_config_c( + abs_eap_am_tools_c * const tools, ///< This is pointer to the tools AM of current platform. + abs_eap_base_type_c * const partner, ///< This is back pointer to object which created this object. + eap_am_type_simple_config_c * const am_type_simple_config, ///< This is pointer to adaptation module of EAP-SIMPLE_CONFIG type. + const bool free_am_type_simple_config, + simple_config_base_record_c * const simple_config_record, /// This is pointer to SIMPLE_CONFIG implementation. + const bool free_simple_config_record, + const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false). + const eap_type_value_e current_eap_type, ///< This the current EAP-type (SIMPLE_CONFIG or PEAP). + const eap_am_network_id_c * const receive_network_id ///< The network id used for this session. + ); + + /** + * This function creates reassembly state string. + */ + EAP_FUNC_IMPORT static eap_const_string get_reassembly_state_string(eap_type_simple_config_reassembly_state_e state); + + /** + * This function creates state string. + */ + EAP_FUNC_IMPORT static eap_const_string get_state_string(eap_type_simple_config_state_variable_e state); + + + /** + * This function tells if the object is a client or a server.. + */ + EAP_FUNC_IMPORT bool get_is_client(); + + // This is commented in abs_eap_am_type_simple_config_c::complete_eap_identity_query(). + EAP_FUNC_IMPORT eap_status_e complete_eap_identity_query( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const eap_status_e completion_status, + const bool use_manual_username, + const eap_variable_data_c * const manual_username, + const bool use_manual_realm, + const eap_variable_data_c * const manual_realm + ); + + /** + * The partner class calls this function when EAP-SIMPLE_CONFIG packet is received. + * see also eap_base_type_c::packet_process(). + */ + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + /** + * This function processes the EAP-Response/Identity. + */ + EAP_FUNC_IMPORT eap_status_e eap_identity_response_packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const received_eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + /** + * This function processes the EAP-SIMPLE_CONFIG packets. + */ + EAP_FUNC_IMPORT eap_status_e simple_config_packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_simple_config_header_c * const received_simple_config, ///< This is pointer to EAP header including EAP-SIMPLE_CONFIG fields. + const u32_t simple_config_packet_length ///< This is length of received EAP-SIMPLE_CONFIG packet. + ); + + // This is commented in abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data + ); + + // This is commented in abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data + ); + + // This is commented in eap_base_type_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + + // This is commented in eap_base_type_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + // This is commented in eap_base_type_c::configure(). + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is commented in eap_base_type_c::shutdown(). + EAP_FUNC_IMPORT eap_status_e shutdown(); + + // This is commented in eap_base_type_c::query_eap_identity(). + EAP_FUNC_IMPORT eap_status_e query_eap_identity( + const bool must_be_synchronous, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier); + + // This is commented in eap_base_type_c::query_eap_identity(). + EAP_FUNC_IMPORT eap_status_e set_initial_eap_identifier( + const eap_am_network_id_c * const receive_network_id, + const u8_t initial_identifier); + + // This is commented in eap_base_type_c::eap_acknowledge(). + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function must reset the state of object to same as + * state was after the configure() function call. + * If object reset succeeds this function must return eap_status_ok. + * If object reset fails this function must return corresponding error status. + * @return This function returns the status of reset operation. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + /// @see abs_simple_config_base_record_c::state_notification(). + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state + ); + + /// @see abs_simple_config_base_record_c::packet_send(). + EAP_FUNC_IMPORT eap_status_e simple_config_packet_send( + eap_buf_chain_wr_c * const sent_packet, + const simple_config_Message_Type_e message_type); + + /// @see abs_simple_config_base_record_c::packet_send(). + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + /// @see abs_simple_config_base_record_c::get_header_offset(). + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length + ); + + /// @see abs_simple_config_base_record_c::restart_authentication(). + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer); + + /// @see abs_simple_config_base_record_c::read_configure(). + EAP_FUNC_IMPORT virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ); + + /// @see abs_simple_config_base_record_c::write_configure(). + EAP_FUNC_IMPORT virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ); + + /// @see abs_simple_config_base_record_c::set_timer(). + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + /// @see abs_simple_config_base_record_c::cancel_timer(). + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + /// @see abs_simple_config_base_record_c::cancel_all_timers(). + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + /// @see abs_simple_config_base_record_c::load_module(). + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + /// @see abs_simple_config_base_record_c::unload_module(). + EAP_FUNC_IMPORT eap_status_e unload_module(const eap_type_value_e type); + + /// @see abs_simple_config_base_record_c::packet_data_crypto_keys(). + EAP_FUNC_IMPORT eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key); + + /// @see abs_simple_config_base_record_c::check_is_valid_eap_type(). + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + /// @see abs_simple_config_base_record_c::get_eap_type_list(). + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + /// @see abs_simple_config_base_record_c::set_session_timeout(). + EAP_FUNC_IMPORT eap_status_e set_session_timeout( + const u32_t session_timeout_ms); + + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + //-------------------------------------------------- +}; // class eap_type_simple_config_c + +#endif //#if defined(USE_EAP_SIMPLE_CONFIG) + +#endif //#if !defined(_EAP_TYPE_SIMPLE_CONFIG_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/eap/include/eap_type_simple_config_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/eap/include/eap_type_simple_config_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,248 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_SIMPLE_CONFIG_HEADER_H_) +#define _EAP_SIMPLE_CONFIG_HEADER_H_ + +#if defined(USE_EAP_SIMPLE_CONFIG) + +#include "eap_tools.h" +#include "eap_header.h" +#include "simple_config_types.h" + +/** @file */ + +const u8_t SIMPLE_CONFIG_NAI_AT_BYTE = '@'; + +#if !defined(USE_EAP_EXPANDED_TYPES) + #error You MUST define USE_EAP_EXPANDED_TYPES compiler flag. WFA Simple Config uses that. +#endif //#if !defined(USE_EAP_EXPANDED_TYPES) + +//---------------------------------------------------------------------------- + + +/// This class defines header of SIMPLE_CONFIG EAP-type. +/** + * Here is a figure of header of SIMPLE_CONFIG EAP-type. + * Subtype-Data is m_length-sizeof(eap_simple_config_header_c) data octets that follows eap_simple_config_header_c. + * @code + * EAP/SIMPLE_CONFIG-header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Code | Identifier | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Vendor-Id | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Vendor-Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Op-Code | Flags | Message Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message Data... + * +-+-+-+-+-+-+-+-+-+ + * @endcode + * + */ +class EAP_EXPORT eap_simple_config_header_c +: public eap_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + enum message_fields + { + SIMPLE_CONFIG_MESSAGE_LENGTH_FIELD_SIZE = 2u, + }; + + enum bit_shifts + { + m_flag_shift_reserved = 0x02, + }; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + enum delta_offsets + { + m_op_code_delta_offset = 0, + m_flag_delta_offset = m_op_code_delta_offset+sizeof(u8_t), + m_data_or_message_length_delta_offset = m_flag_delta_offset+sizeof(u8_t), + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + enum bit_masks + { + m_flag_mask_more_fragments = 0x01, + m_flag_mask_simple_config_length_included = 0x02, + m_flag_mask_reserved = 0xfc, + }; + + enum op_code_e + { + op_code_none = 0x00, + op_code_WSC_Start = 0x01, + op_code_WSC_ACK = 0x02, + op_code_WSC_NACK = 0x03, + op_code_WSC_MSG = 0x04, + op_code_WSC_Done = 0x05, + op_code_FRAG_ACK = 0x06, + }; + + + EAP_FUNC_IMPORT virtual ~eap_simple_config_header_c(); + + // + EAP_FUNC_IMPORT eap_simple_config_header_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_begin, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT eap_code_value_e get_eap_code() const; + + EAP_FUNC_IMPORT u8_t get_eap_identifier() const; + + EAP_FUNC_IMPORT u16_t get_eap_length() const; + + EAP_FUNC_IMPORT eap_type_value_e get_eap_type() const; + + EAP_FUNC_IMPORT u16_t get_data_length() const; + + EAP_FUNC_IMPORT u32_t get_simple_config_min_header_length() const; + + EAP_FUNC_IMPORT static u32_t get_simple_config_max_header_length(); + + EAP_FUNC_IMPORT u32_t get_header_length() const; + + EAP_FUNC_IMPORT u32_t get_start_offset_of_data() const; + + EAP_FUNC_IMPORT u8_t * get_data_offset( + abs_eap_am_tools_c * const m_am_tools, + const u32_t offset, + const u32_t contignuous_bytes) const; + + + EAP_FUNC_IMPORT u8_t * get_data( + abs_eap_am_tools_c * const m_am_tools, + const u32_t contignuous_bytes) const; + + + EAP_FUNC_IMPORT u32_t get_sc_op_code_offset() const; + + EAP_FUNC_IMPORT u32_t get_sc_flags_offset() const; + + EAP_FUNC_IMPORT u32_t get_sc_length_offset() const; + + + EAP_FUNC_IMPORT op_code_e get_sc_op_code() const; + + + EAP_FUNC_IMPORT u8_t * get_simple_config_flags() const; + + EAP_FUNC_IMPORT bool get_simple_config_flag_bit( + const u32_t mask) const; + + EAP_FUNC_IMPORT u8_t get_simple_config_flag_value( + const u32_t mask, + const u32_t shift) const; + + EAP_FUNC_IMPORT bool get_flag_simple_config_length_included() const; + + EAP_FUNC_IMPORT bool get_flag_more_fragments() const; + + EAP_FUNC_IMPORT u8_t get_flag_reserved() const; + + EAP_FUNC_IMPORT eap_status_e get_simple_config_message_length( + u32_t * const simple_config_length) const; + + + EAP_FUNC_IMPORT eap_status_e check_header( + abs_eap_am_tools_c * const tools, + const bool is_client_when_true) const; + + EAP_FUNC_IMPORT eap_const_string get_code_string() const; + + EAP_FUNC_IMPORT eap_const_string get_eap_type_string() const; + + EAP_FUNC_IMPORT eap_const_string get_sc_op_code_string() const; + + + EAP_FUNC_IMPORT void set_eap_code(const eap_code_value_e p_code); + + EAP_FUNC_IMPORT void set_eap_identifier(const u8_t p_identifier); + + EAP_FUNC_IMPORT void set_eap_length( + const u16_t p_length, + const bool expanded_type_when_true); + + EAP_FUNC_IMPORT void set_eap_type( + const eap_type_value_e p_type, + const bool expanded_type_when_true); + + + EAP_FUNC_IMPORT void set_sc_op_code(const op_code_e op_code); + + + EAP_FUNC_IMPORT void set_simple_config_flag_value( + const u8_t value, + const u32_t mask, + const u32_t shift) const; + + EAP_FUNC_IMPORT void set_simple_config_flag_bit(const bool flag, u32_t mask) const; + + EAP_FUNC_IMPORT void set_flag_reserved(const u8_t reserved); + + EAP_FUNC_IMPORT void set_flag_simple_config_length_included(const bool simple_config_length_included); + + EAP_FUNC_IMPORT void set_flag_more_fragments(const bool more_fragments); + + + EAP_FUNC_IMPORT void set_data_length( + const u32_t p_data_length, + const bool expanded_type_when_true); + + EAP_FUNC_IMPORT void set_simple_config_message_length(const u32_t simple_config_length); + + + EAP_FUNC_IMPORT void reset_header( + abs_eap_am_tools_c * const m_am_tools, + const u32_t buffer_length, + const bool expanded_type_when_true); + + // + //-------------------------------------------------- +}; // class eap_simple_config_header_c + + +//-------------------------------------------------- + +#endif //#if defined(USE_EAP_SIMPLE_CONFIG) + +#endif //#if !defined(_EAP_SIMPLE_CONFIG_HEADER_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/eap/include/eap_type_simple_config_state_notification.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/eap/include/eap_type_simple_config_state_notification.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,106 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_SIMPLE_CONFIG_STATE_NOTIFICATION_H_) +#define _EAP_SIMPLE_CONFIG_STATE_NOTIFICATION_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_protocol_layer.h" +#include "eap_state_notification.h" + + +/// A eap_type_simple_config_state_notification_c class. +/// This is used for debugging and protocol testing. +class EAP_EXPORT eap_type_simple_config_state_notification_c +: public eap_state_notification_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_type_simple_config_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_type_simple_config_state_notification_c(); + + /** + * The constructor of the eap_type_simple_config_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT eap_type_simple_config_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + + +#if defined(USE_EAP_EXPANDED_TYPES) + + EAP_FUNC_IMPORT eap_type_simple_config_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + + EAP_FUNC_IMPORT eap_type_simple_config_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + + + //-------------------------------------------------- +}; // class eap_type_simple_config_state_notification_c + +#endif //#if !defined(_EAP_SIMPLE_CONFIG_STATE_NOTIFICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/eap/include/eap_type_simple_config_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/eap/include/eap_type_simple_config_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,369 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TYPE_SIMPLE_CONFIG_TYPES_H_) +#define _EAP_TYPE_SIMPLE_CONFIG_TYPES_H_ + +#include "eap_buffer.h" +#include "eap_type_all_types.h" +#include "simple_config_types.h" +#include "eap_configuration_field.h" + +/** @file eap_type_simple_config_types.h + * @brief This file defines the constants of the SIMPLE_CONFIG EAP type. + */ + +/** + * This is the internal state of the SIMPLE_CONFIG EAP type. + */ +enum eap_type_simple_config_state_variable_e +{ + eap_type_simple_config_state_waiting_for_identity_request , ///< Client state waiting_for_identity_request + eap_type_simple_config_state_pending_identity_query , ///< Client state pending_identity_query + eap_type_simple_config_state_waiting_for_simple_config_start , ///< Client state waiting_for_eap_start + eap_type_simple_config_state_process_simple_config_start , ///< Client state process_simple_config_start + eap_type_simple_config_state_waiting_for_request , ///< Client state waiting_for_request + + eap_type_simple_config_state_waiting_for_identity_response , ///< Server state waiting_for_identity_response + eap_type_simple_config_state_waiting_for_response , ///< Server state waiting_for_response + + eap_type_simple_config_state_process_simple_config_message , ///< Client or server state process_simple_config_message + + eap_type_simple_config_state_success , ///< State state_success + eap_type_simple_config_state_failure , ///< State state_failure + + eap_type_simple_config_state_last_value , ///< Keep this enum the last one. +}; + + +enum eap_type_simple_config_reassembly_state_e +{ + eap_type_simple_config_reassembly_state_none, + eap_type_simple_config_reassembly_state_wait_first_message, + eap_type_simple_config_reassembly_state_wait_last_fragment, + eap_type_simple_config_reassembly_state_message_reassembled, +}; + + +/** + * This is the type of the SIMPLE_CONFIG authentication. + */ +enum eap_simple_config_authentication_type_e +{ + SIMPLE_CONFIG_AUTHENTICATION_TYPE_NONE, + SIMPLE_CONFIG_AUTHENTICATION_TYPE_SIMPLE_CONFIG, +}; + +enum eap_type_simple_config_stored_e +{ + eap_type_simple_config_stored_none, + eap_type_simple_config_stored_session_id, + eap_type_simple_config_stored_master_secret, + eap_type_simple_config_stored_used_cipher_suite, + eap_type_simple_config_stored_count_of_session_resumes, + eap_type_simple_config_stored_test_every_cipher_suite_counter, +}; + +/** + * This is the size of the local send buffer. + */ +const u32_t EAP_SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH = EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH; + +/** + * This is the at character used in NAI. + */ +const u8_t EAP_SIMPLE_CONFIG_AT_CHARACTER = '@'; + + +/** + * This is the identity of Enrollee. + */ +const u8_t EAP_SIMPLE_CONFIG_ENROLLEE_IDENTITY[] = "WFA-SimpleConfig-Enrollee-1-0"; + +/** + * This is the length of identity of Enrollee. + */ +const u32_t EAP_SIMPLE_CONFIG_ENROLLEE_IDENTITY_LENGTH = sizeof(EAP_SIMPLE_CONFIG_ENROLLEE_IDENTITY)-1; + + +/** + * This is the maximum size of the EAP-SIMPLE_CONFIG message. + * This value limits the maximum size of the received EAP-SIMPLE_CONFIG message. + */ +const u32_t EAP_SIMPLE_CONFIG_MAX_MESSAGE_LENGTH = 65536ul; + + +/** + * @defgroup EAP_SIMPLE_CONFIG_config_options Configuration options of EAP-SIMPLE_CONFIG. + * The following configuration options are read through abs_eap_base_type_c::read_configure() function. + * @{ + */ + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_use_manual_username, + "EAP_SIMPLE_CONFIG_use_manual_username", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_manual_username, + "EAP_SIMPLE_CONFIG_manual_username", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_use_manual_realm, + "EAP_SIMPLE_CONFIG_use_manual_realm", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_manual_realm, + "EAP_SIMPLE_CONFIG_manual_realm", + eap_configure_type_string, + false); + +/** + * This is boolean configuration option. + * True value means on EAP-type SIMPLE_CONFIG must check identifier of EAP-Response/Identity message. + * False value means on EAP-type SIMPLE_CONFIG does not check identifier of EAP-Response/Identity message. + * This is not possible in cases where identifier of the EAP-Request/Identity is generated by other network entities. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_check_identifier_of_eap_identity_response, + "EAP_SIMPLE_CONFIG_check_identifier_of_eap_identity_response", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag activates NAI realm check. Default value is false. + * When active NAI realm muts be the same as realm given by EAP_SIMPLE_CONFIG_manual_realm option. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_check_nai_realm, + "EAP_SIMPLE_CONFIG_check_nai_realm", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is for testing. + * True value means on test version of EAP-type SIMPLE_CONFIG is used. + * Test version tries to make as many authentications as it is possible. + * False value means on real version of EAP-type SIMPLE_CONFIG is used. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_test_version, + "EAP_SIMPLE_CONFIG_test_version", + eap_configure_type_boolean, + false); + + +/** + * This u32_t configuration option is the timeout in milli seconds after + * the erroneus message is processed. + * Default value is 15000 ms = 15 seconds. + */ +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_error_message_received_timeout, + "SIMPLE_CONFIG_error_message_received_timeout", + eap_configure_type_u32_t, + false); + +/** + * This hex data configuration option is the device password. + * Default value is empty. This must be configured in adaptation module. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_device_password, + "EAP_SIMPLE_CONFIG_device_password", + eap_configure_type_hex_data, + true); + + +/** + * This hex data configuration option is the server device password. + * Default value is empty. This is optional value for testing purposes. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_server_device_password, + "EAP_SIMPLE_CONFIG_server_device_password", + eap_configure_type_hex_data, + true); + + +/** + * This hex data configuration option is the new password on the Enrollee. + * Default value is empty. This is optional. + */ +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_new_password, + "SIMPLE_CONFIG_new_password", + eap_configure_type_hex_data, + true); + + +/** + * This is boolean configuration option. + * True value of this flag causes client return random + * identity on EAP-Response/Identity. + * False value causes client return real identity + * (IMSI, pseudonym or re-authentication identity) + * in EAP-Response/Identity. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_use_random_identity_on_eap_identity_response, + "EAP_SIMPLE_CONFIG_use_random_identity_on_eap_identity_response", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means queries to AM are completed asyncronous. + * False value means queries to AM are completed syncronous. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_do_asyncronous_completions, + "EAP_SIMPLE_CONFIG_do_asyncronous_completions", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means queries to AM are randomly completed asyncronous. + * False value means queries to AM are randomly completed syncronous. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_do_asyncronous_completions_randomly, + "EAP_SIMPLE_CONFIG_do_asyncronous_completions_randomly", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means queries to AM are randomly failed. + * False value means queries to AM are randomly failed. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_fail_registration_randomly, + "EAP_SIMPLE_CONFIG_fail_registration_randomly", + eap_configure_type_boolean, + false); + +/** + * This is u32_t configuration option. + * This is used in simulator testing. + * Value is the maximum completion time (ms) when completitions are + * completed randomly. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_SIMPLE_CONFIG_max_simple_config_completion_time, + "EAP_SIMPLE_CONFIG_max_simple_config_completion_time", + eap_configure_type_u32_t, + false); + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/** + * This hex data configuration option is the Network Key on the Enrollee. + * Default value is empty. This is optional. + */ +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_network_key, + "SIMPLE_CONFIG_network_key", + eap_configure_type_hex_data, + true); + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/** + * This hex data configuration option is the Authentication Type on the Enrollee. + * Default value is empty. This is optional. + */ +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_authentication_type, + "SIMPLE_CONFIG_authentication_type", + eap_configure_type_string, + true); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_authentication_type_None, + "None", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_authentication_type_Open, + "Open", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_authentication_type_WPAPSK, + "WPAPSK", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_authentication_type_Shared, + "Shared", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_authentication_type_WPA, + "WPA", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_authentication_type_WPA2, + "WPA2", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_authentication_type_WPA2PSK, + "WPA2PSK", + eap_configure_type_string, + false); + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/** @} */ // End of group EAP_SIMPLE_CONFIG_config_options. + +//-------------------------------------------------- + + +#endif //#if !defined(_EAP_TYPE_SIMPLE_CONFIG_TYPES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/eap/src/eap_type_simple_config.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/eap/src/eap_type_simple_config.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3782 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 590 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#if defined(USE_EAP_SIMPLE_CONFIG) + +#include "eap_am_memory.h" +#include "eap_type_simple_config_types.h" +#include "eap_type_simple_config.h" +#include "eap_type_simple_config_header.h" +#include "eap_type_simple_config_state_notification.h" +#include "eap_am_type_simple_config.h" +#include "eap_state_notification.h" +#include "simple_config_tlv_header.h" +#include "simple_config_base_record.h" +#include "eap_config.h" +#include "eap_header_string.h" + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_type_simple_config_c::~eap_type_simple_config_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: function: eap_type_simple_config_c::~eap_type_simple_config_c(): this = 0x%08x => 0x%08x,") + EAPL(" m_am_type_simple_config = 0x%08x (validity %d).\n"), + (m_is_client == true ? "client": "server"), + this, + dynamic_cast(this), + m_am_type_simple_config, + m_am_type_simple_config->get_is_valid())); + + EAP_ASSERT(m_shutdown_was_called == true); + + if (m_free_simple_config_record == true) + { + delete m_simple_config_record; + m_simple_config_record = 0; + } + + if (m_free_am_type_simple_config == true) + { + delete m_am_type_simple_config; + m_am_type_simple_config = 0; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_type_simple_config_c::eap_type_simple_config_c( + abs_eap_am_tools_c * const tools, ///< This is pointer to the tools AM of current platform. + abs_eap_base_type_c * const partner, ///< This is back pointer to object which created this object. + eap_am_type_simple_config_c * const am_type_simple_config, ///< This is pointer to adaptation module of EAP-SIMPLE_CONFIG type. + const bool free_am_type_simple_config, + simple_config_base_record_c * const simple_config_record, /// This is pointer to SIMPLE_CONFIG implementation. + const bool free_simple_config_record, + const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false). + const eap_type_value_e current_eap_type, ///< This the current EAP-type (SIMPLE_CONFIG or PEAP). + const eap_am_network_id_c * const receive_network_id) + : eap_base_type_c(tools, partner) + , m_am_tools(tools) + , m_am_type_simple_config(am_type_simple_config) + , m_simple_config_record(simple_config_record) + , m_nai_realm(tools) + , m_NAI(tools) + , m_send_network_id(tools) + , m_simple_config_header_offset(0u) + , m_MTU(0u) + , m_trailer_length(0u) + , m_state(eap_type_simple_config_state_waiting_for_identity_request) + , m_saved_previous_state(eap_type_simple_config_state_waiting_for_identity_request) + , m_reassembly_state(eap_type_simple_config_reassembly_state_wait_first_message) + , m_saved_previous_reassembly_state(eap_type_simple_config_reassembly_state_wait_first_message) + , m_simple_config_message_send_offset(0ul) + , m_simple_config_message_buffer(tools) + , m_first_fragment_eap_identifier(0ul) + , m_free_am_type_simple_config(free_am_type_simple_config) + , m_free_simple_config_record(free_simple_config_record) + , m_is_valid(false) + , m_is_client(is_client_when_true) + , m_check_identifier_of_eap_identity_response(false) + , m_simple_config_test_version(false) + , m_check_nai_realm(false) + , m_failure_message_received(false) + , m_authentication_finished_successfully(false) + , m_last_eap_identifier(0ul) + , m_shutdown_was_called(false) + , m_simple_config_message_type(simple_config_Message_Type_None) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: function: eap_type_simple_config_c::eap_type_simple_config_c(): ") + EAPL("this = 0x%08x => 0x%08x, compiled %s %s\n"), + (m_is_client == true ? "client": "server"), + this, + dynamic_cast(this), + __DATE__, + __TIME__)); + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + // No need to delete anything here because it is done in destructor. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (simple_config_record == 0) + { + // No need to delete anything here because it is done in destructor. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + m_simple_config_record->set_type_partner(this); + + if (m_am_type_simple_config == 0) + { + // Something wrong with AM. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + m_am_type_simple_config->set_am_partner(this); + + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + eap_status_e status = get_send_network_id()->set_copy_of_network_id( + &send_network_id); + if (status != eap_status_ok) + { + EAP_UNREFERENCED_PARAMETER(current_eap_type); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (m_is_client == false) + { + // Server waits EAP-Response/Identity. + m_state = eap_type_simple_config_state_waiting_for_identity_response; + m_saved_previous_state + = eap_type_simple_config_state_waiting_for_identity_response; + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::save_current_state() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_saved_previous_state = m_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::restore_saved_previous_state() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + set_state(m_saved_previous_state); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::set_state( + const eap_type_simple_config_state_variable_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_type_simple_config_state_variable_e previous_state = m_state; + EAP_UNREFERENCED_PARAMETER(previous_state); // This is used only for debugging. + + if (m_state != eap_type_simple_config_state_failure) + { + m_state = state; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_simple_config_c::set_state(): ") + EAPL("%s: Previous state %d=%s, new state %d=%s.\n"), + (m_is_client == true ? "client": "server"), + previous_state, + get_state_string(previous_state), + m_state, + get_state_string(m_state))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_type_simple_config_reassembly_state_e eap_type_simple_config_c::get_reassembly_state() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_reassembly_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::set_reassembly_state( + const eap_type_simple_config_reassembly_state_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_reassembly_state = state; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::save_current_reassembly_state() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_saved_previous_reassembly_state = m_reassembly_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::restore_saved_reassembly_state() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_reassembly_state = m_saved_previous_reassembly_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_network_id_c * eap_type_simple_config_c::get_send_network_id() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_send_network_id; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::set_last_eap_identifier(const u8_t last_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_last_eap_identifier = last_eap_identifier; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_simple_config_c::set_last_eap_identifier():") + EAPL("%s, saved EAP-identifier %d, state %s\n"), + (m_is_client == true ? "client": "server"), + m_last_eap_identifier, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u8_t eap_type_simple_config_c::get_last_eap_identifier() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_simple_config_c::get_last_eap_identifier():") + EAPL("%s, saved EAP-identifier %d, state %s\n"), + (m_is_client == true ? "client": "server"), + m_last_eap_identifier, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_last_eap_identifier; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_const_string eap_type_simple_config_c::get_state_string( + eap_type_simple_config_state_variable_e state) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_waiting_for_identity_request) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_pending_identity_query) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_waiting_for_simple_config_start) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_process_simple_config_start) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_waiting_for_request) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_waiting_for_identity_response) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_waiting_for_response) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_process_simple_config_message) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_success) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_failure) + else +#else + EAP_UNREFERENCED_PARAMETER(state); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown EAP-SIMPLE_CONFIG state"); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_const_string eap_type_simple_config_c::get_reassembly_state_string( + eap_type_simple_config_reassembly_state_e state) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(state, eap_type_simple_config_reassembly_state_none) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_reassembly_state_wait_first_message) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_reassembly_state_wait_last_fragment) + else EAP_IF_RETURN_STRING(state, eap_type_simple_config_reassembly_state_message_reassembled) + else +#else + EAP_UNREFERENCED_PARAMETER(state); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown SIMPLE_CONFIG reassembly state"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_simple_config_c::get_state_string() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return get_state_string(m_state); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_simple_config_c::get_reassembly_state_string() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return get_reassembly_state_string(m_reassembly_state); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_simple_config_c::get_saved_previous_state_string() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return get_state_string(m_saved_previous_state); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_type_simple_config_c::set_failure_message_received() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_failure_message_received = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_type_simple_config_c::unset_failure_message_received() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_failure_message_received = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_simple_config_c::get_failure_message_received() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_failure_message_received; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_simple_config_state_variable_e eap_type_simple_config_c::get_state() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_simple_config_c::get_nai_realm() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_nai_realm; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_simple_config_c::get_NAI() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_NAI; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::update_buffer_indexes( + const u32_t maximum_buffer_size, + const u32_t payload_size, + u32_t * const buffer_offset, + u32_t * const buffer_free) +{ + EAP_UNREFERENCED_PARAMETER(maximum_buffer_size); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length); + EAP_ASSERT_ALWAYS(*buffer_free >= payload_size); + EAP_ASSERT_ALWAYS(m_simple_config_header_offset+m_MTU == *buffer_offset + *buffer_free); + + *buffer_free -= payload_size; + *buffer_offset += payload_size; + + EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length); + EAP_ASSERT_ALWAYS(*buffer_offset <= m_simple_config_header_offset+m_MTU); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::update_payload_indexes( + const u32_t /*maximum_buffer_size*/, + const u32_t /*eap_header_size*/, + const u32_t /*payload_size*/, + u32_t * const /*data_offset*/, + u32_t * const /*data_free*/, + u32_t * const /*buffer_offset*/, + u32_t * const /*buffer_free*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::parse_identity( + const u8_t * const identity, ///< This is pointer to received EAP-Identity buffer. + const u32_t identity_length ///< This is length of received EAP-Identity buffer. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (identity_length < 1u) + { + // Anonymous identity. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + const u8_t *at_character = reinterpret_cast( + m_am_tools->memchr( + identity, + EAP_SIMPLE_CONFIG_AT_CHARACTER, + identity_length)); + if (at_character == 0) + { + // No realm. + // This is allowed. + } + + eap_status_e status = check_NAI(identity, identity_length, at_character); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_process_general_error; + + status = get_NAI()->set_copy_of_buffer(identity, identity_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("SIMPLE_CONFIG received EAP-identity NAI"), + get_NAI()->get_data(get_NAI()->get_data_length()), + get_NAI()->get_data_length())); + + if (get_NAI()->get_data_length() != EAP_SIMPLE_CONFIG_ENROLLEE_IDENTITY_LENGTH + || m_am_tools->memcmp( + get_NAI()->get_data(), + EAP_SIMPLE_CONFIG_ENROLLEE_IDENTITY, + EAP_SIMPLE_CONFIG_ENROLLEE_IDENTITY_LENGTH) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::simple_config_packet_send( + eap_buf_chain_wr_c * const sent_packet, + const simple_config_Message_Type_e message_type + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: %s: function: simple_config_packet_send()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eap_status_not_supported; + + if ((m_is_client == true + && get_state() == eap_type_simple_config_state_process_simple_config_start) + || get_state() == eap_type_simple_config_state_process_simple_config_message + || get_state() == eap_type_simple_config_state_waiting_for_request // This state is needed to send messages from asyncronous completions. + || get_state() == eap_type_simple_config_state_waiting_for_response // This state is needed to send messages from asyncronous completions. + || get_state() == eap_type_simple_config_state_success // This state is needed to send the WCS_Done message. + || get_state() == eap_type_simple_config_state_failure // This state is needed to send failure messages. + || (m_is_client == false + && get_state() == eap_type_simple_config_state_success) + ) + { + status = m_simple_config_message_buffer.set_copy_of_buffer( + sent_packet->get_data(sent_packet->get_data_length()), + sent_packet->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This will start the packet send from begin of the message. + m_simple_config_message_send_offset = 0ul; + + // Save the type of the message for fragmentation + m_simple_config_message_type = message_type; + + status = eap_simple_config_fragment_send(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_send(): ") + EAPL("Cannot send EAP-SIMPLE_CONFIG message in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: %s: function: packet_send()\n"), + (m_is_client == true ? "client": "server"))); + + eap_header_wr_c eap( + m_am_tools, + sent_packet->get_data_offset( + header_offset, data_length), + data_length); + if (eap.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + packet_trace( + EAPL("<-"), + network_id, + &eap, + data_length); + + eap_status_e status = get_type_partner()->packet_send( + network_id, + sent_packet, + header_offset, + data_length, + buffer_length + ); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::check_NAI( + const u8_t * const identity, + const u32_t identity_length, + const u8_t * const at_character) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + bool includes_at = false; + bool includes_dot = false; + u32_t username_length = 0u; + u32_t realm_length = 0u; + + for (u32_t ind = 0; ind < identity_length; ind++) + { + const u8_t character = identity[ind]; + + if (includes_at == false) + { + if (character != EAP_SIMPLE_CONFIG_AT_CHARACTER) + { + ++username_length; + } + } + else + { + ++realm_length; + } + + + if ('0' <= character && character <= '9') + { + // OK. + } + else if ('a' <= character && character <= 'z') + { + // OK. + } + else if ('A' <= character && character <= 'Z') + { + // OK. + } + else if (character == EAP_SIMPLE_CONFIG_AT_CHARACTER) + { + if (includes_at == false) + { + includes_at = true; + } + else + { + // Second at ('@'). + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Illegal NAI, includes second at \'@\' character."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + else if (character == '.') + { + if (includes_at == true) + { + // OK. + includes_dot = true; + } + else + { + // dot ('.') within username + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Illegal NAI, dot \'.\' within username."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + else if (character == '<' + || character == '>' + || character == '(' + || character == ')' + || character == '[' + || character == ']' + || character == '\\' + || character == '.' + || character == ',' + || character == ';' + || character == ':' + || character == EAP_SIMPLE_CONFIG_AT_CHARACTER + || character == ' ' // space + || character <= 0x1f // Ctrl + || character >= 0x7f) // extented characters + { + // Illegal character. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: Illegal NAI, includes illegal character 0x%02x=%c.\n"), + character, + character)); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Illegal NAI, includes illegal character."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + else + { + // All other ascii values are OK. + } + } + + // Note the username could be zero length. + if ((realm_length == 1u && includes_at == true) // one at ('@') is illegal. + || (realm_length == 2u && includes_at == true && includes_dot == true)) // one at ('@') and one dot is illegal. + { + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Illegal NAI."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + + if (m_check_nai_realm == true) + { + if (at_character == 0 + && realm_length == 0 + && get_nai_realm()->get_data_length() == 0) + { + // OK, no realm. + } + else if (at_character == 0 + || realm_length != get_nai_realm()->get_data_length() + || m_am_tools->memcmp( + at_character+1u, + get_nai_realm()->get_data(get_nai_realm()->get_data_length()), + get_nai_realm()->get_data_length()) != 0) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Illegal NAI, realm unknown."), + identity, + identity_length)); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("NAI should be"), + get_nai_realm()->get_data(get_nai_realm()->get_data_length()), + get_nai_realm()->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::packet_trace( + eap_const_string prefix, + const eap_am_network_id_c * const /*receive_network_id*/, + eap_header_wr_c * const eap_packet, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(prefix); // in release + + if (eap_packet_length > eap_header_base_c::get_header_length() + && eap_packet->get_type() == eap_expanded_type_simple_config.get_type()) + { + eap_simple_config_header_c * const received_simple_config + = reinterpret_cast(eap_packet); + + const u8_t * const p_simple_config_flags = received_simple_config->get_simple_config_flags(); + u8_t simple_config_flags = 0u; + EAP_UNREFERENCED_PARAMETER(simple_config_flags); // in release + if (p_simple_config_flags != 0) + { + simple_config_flags = *p_simple_config_flags; + } + + u32_t simple_config_message_length = 0ul; + if (received_simple_config->get_simple_config_message_length(&simple_config_message_length) != eap_status_ok) + { + simple_config_message_length = 0ul; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s EAP-SIMPLE_CONFIG header %s: code=0x%02x=%s, identifier=0x%02x=%d, ") + EAPL("length=0x%04x=%d, ") + EAPL("type=0x%08x=%s, OP-Code=0x%02x=%s, SIMPLE_CONFIG-flags=0x%02x %s%s, SIMPLE_CONFIG-length=0x%08x=%d.\n"), + prefix, + (m_is_client == true) ? "client": "server", + received_simple_config->get_code(), + received_simple_config->get_code_string(), + received_simple_config->get_identifier(), + received_simple_config->get_identifier(), + received_simple_config->get_length(), + received_simple_config->get_length(), + convert_eap_type_to_u32_t(received_simple_config->get_type()), + received_simple_config->get_eap_type_string(), + received_simple_config->get_sc_op_code(), + received_simple_config->get_sc_op_code_string(), + simple_config_flags, + (simple_config_flags & eap_simple_config_header_c::m_flag_mask_simple_config_length_included) ? "L": " ", + (simple_config_flags & eap_simple_config_header_c::m_flag_mask_more_fragments) ? "M": " ", + simple_config_message_length, + simple_config_message_length)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s EAP header %s: code=0x%02x=%s, identifier=0x%02x, length=0x%04x=%d, ") + EAPL("type=0x%08x=%s\n"), + prefix, + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + eap_packet->get_length(), + convert_eap_type_to_u32_t(eap_packet->get_type()), + eap_packet->get_type_string())); + + EAP_TRACE_DEBUG( + m_am_tools, + eap_am_tools_c::eap_trace_mask_eap_messages, + (EAPL("\n\t%s\n\tcode = 0x%02x = %s\n\tidentifier = 0x%02x\n\t") + EAPL("length = 0x%04x = %lu\n\ttype = 0x%08x = %s\n"), + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + eap_packet->get_length(), + convert_eap_type_to_u32_t(eap_packet->get_type()), + eap_packet->get_type_string())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::finish_successful_authentication() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: %s: function: finish_successful_authentication()\n"), + (m_is_client == true ? "client": "server"))); + + eap_simple_config_trace_string_c simple_config_trace; + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_SIMPLE_CONFIG: %s, EAP-type %s EAP-SUCCESS\n"), + ((m_is_client == true) ? "client": "server"), + eap_header_string_c::get_eap_type_string(eap_expanded_type_simple_config.get_type()))); + + set_state(eap_type_simple_config_state_success); + + // Note, authentication is always terminated unsuccessfully. + // Server will send EAP-Failure always. + // Client should accept EAP-Failure quietly. + { + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_expanded_type_simple_config.get_type(), + eap_state_none, + eap_state_use_eap_failure_in_termination, + get_last_eap_identifier(), // Note the EAP-Failure uses the same EAP-Identifier as the last EAP-Request. + false); + get_type_partner()->state_notification(¬ification); + } + + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_expanded_type_simple_config.get_type(), + eap_state_none, + eap_state_authentication_finished_successfully, + get_last_eap_identifier(), // Note the EAP-Success uses the same EAP-Identifier as the last EAP-Request. + false); + get_type_partner()->state_notification(¬ification); + + // Indicate EAP-SIMPLE_CONFIG AM authentication finished successfully. + m_am_type_simple_config->authentication_finished(true, false); + + m_authentication_finished_successfully = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_success); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::send_final_notification() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: %s: function: send_final_notification()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_is_valid == true + && m_authentication_finished_successfully == false) + { + eap_simple_config_trace_string_c simple_config_trace; + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_SIMPLE_CONFIG: %s, EAP-type %s FAILED\n"), + ((m_is_client == true) ? "client": "server"), + eap_header_string_c::get_eap_type_string(eap_expanded_type_simple_config.get_type()))); + + set_state(eap_type_simple_config_state_failure); + + // Notifies the lower level of unsuccessfull authentication. + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_expanded_type_simple_config.get_type(), + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + get_last_eap_identifier(), + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + get_type_partner()->state_notification(¬ification); + + // Indicate EAP-SIMPLE_CONFIG AM authentication terminated unsuccessfully. + m_am_type_simple_config->authentication_finished(false, false); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_type_simple_config_c::get_is_client() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_client; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::handle_eap_identity_query( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const bool use_manual_username, + const eap_variable_data_c * const manual_username, + const bool use_manual_realm, + const eap_variable_data_c * const manual_realm + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + eap_variable_data_c local_identity(m_am_tools); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (use_manual_username == true + && manual_username != 0 + && manual_username->get_is_valid() == true + && use_manual_realm == true + && manual_realm != 0 + && manual_realm->get_is_valid() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: %s: eap_type_simple_config_c::handle_eap_identity_query(): manual username and manual realm.\n"), + (m_is_client == true ? "client": "server"))); + + // Here manual username could be zero or more bytes in length. + status = local_identity.set_copy_of_buffer(manual_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (manual_realm->get_data_length() > 0ul) + { + // When manual realm is one or more bytes in length + // we add @ and manual realm to the identity. + u8_t at_char = EAP_SIMPLE_CONFIG_AT_CHARACTER; + status = local_identity.add_data(&at_char, sizeof(at_char)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = local_identity.add_data(manual_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (use_manual_username == true + && manual_username != 0 + && manual_username->get_is_valid() == true + && use_manual_realm == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: %s: eap_type_simple_config_c::handle_eap_identity_query(): manual username.\n"), + (m_is_client == true ? "client": "server"))); + + status = local_identity.set_copy_of_buffer(manual_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: %s: eap_type_simple_config_c::handle_eap_identity_query(): no identity.\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + status = get_NAI()->set_copy_of_buffer(&local_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_simple_config_c::handle_eap_identity_query(): identity"), + local_identity.get_data(), + local_identity.get_data_length())); + + + status = get_type_partner()->complete_eap_identity_query( + &send_network_id, + &local_identity, + eap_identifier); + if (status == eap_status_ok) + { + set_state(eap_type_simple_config_state_waiting_for_simple_config_start); + } + else + { + get_NAI()->reset(); + restore_saved_previous_state(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::complete_eap_identity_query( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const eap_status_e completion_status, + const bool use_manual_username, + const eap_variable_data_c * const manual_username, + const bool use_manual_realm, + const eap_variable_data_c * const manual_realm + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_state == eap_type_simple_config_state_pending_identity_query) + { + if (completion_status != eap_status_ok) + { + set_state(eap_type_simple_config_state_failure); + + // The completion_status error value is more important + // than return value of set_session_timeout(). + get_type_partner()->set_session_timeout(0ul); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, completion_status); + } + + eap_status_e status = handle_eap_identity_query( + receive_network_id, + eap_identifier, + use_manual_username, + manual_username, + use_manual_realm, + manual_realm); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::complete_eap_identity_query(): ") + EAPL("Illegal EAP-Identity query completion in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } +} + +//-------------------------------------------------- + +// +eap_status_e eap_type_simple_config_c::check_received_eap_identifier( + const eap_header_wr_c * const eap_header) +{ + if (m_is_client == false + && eap_header->get_type() == eap_type_identity + && eap_header->get_code() == eap_code_response + && m_check_identifier_of_eap_identity_response == true + && eap_header->get_identifier() != get_last_eap_identifier()) + { + eap_status_e status(eap_status_unexpected_message); + + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::packet_process() failed,") + EAPL("status %d=%s, received EAP-type 0x%08x, received EAP-code %d, ") + EAPL("received EAP-identifier %d, current EAP-identifier %d, state %s\n"), + status, + status_string.get_status_string(status), + convert_eap_type_to_u32_t(eap_header->get_type()), + eap_header->get_code(), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_is_client == false + && eap_header->get_type() == eap_expanded_type_simple_config.get_type() + && eap_header->get_identifier() != get_last_eap_identifier()) + { + eap_status_e status(eap_status_unexpected_message); + + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::packet_process() failed,") + EAPL("status %d=%s, received EAP-identifier %d, ") + EAPL("current EAP-identifier %d, state %s\n"), + status, + status_string.get_status_string(status), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_is_client == true + && eap_header->get_identifier() == get_last_eap_identifier()) + { + // Client have received this packet already. + eap_status_e status(eap_status_drop_packet_quietly); + + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_simple_config_c::packet_process() failed,") + EAPL("status %d=%s, drops already received EAP-identifier %d, ") + EAPL("current EAP-identifier %d, state %s\n"), + status, + status_string.get_status_string(status), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const eap_header, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: %s: function: packet_process()\n"), + (m_is_client == true ? "client": "server"))); + + packet_trace( + EAPL("->"), + receive_network_id, + eap_header, + eap_packet_length); + + if (eap_packet_length < eap_header->get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_packet_length=0x%04x < eap_header->get_length()=0x%04x.\n"), + eap_packet_length, eap_header->get_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (eap_header->get_length() < eap_header_base_c::get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::packet_process(): ") + EAPL("eap_header->get_length() < eap_header_base_c::get_header_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + + // NOTE: by disabling these calls throughput increases about 18%. + // Disabling also decreases random seeds. + m_am_tools->get_crypto()->add_rand_seed( + eap_header->get_header_buffer(eap_packet_length), + eap_packet_length); + m_am_tools->get_crypto()->add_rand_seed_hw_ticks(); + + eap_status_e status = eap_status_process_general_error; + + if ((m_is_client == true + && eap_header->get_code() == eap_code_request) + || (m_is_client == false + && eap_header->get_code() == eap_code_response)) + { + if (eap_header->get_type() == eap_type_identity + || eap_header->get_type() == eap_expanded_type_simple_config.get_type()) + { + eap_simple_config_header_c simple_config_header( + m_am_tools, + eap_header->get_header_buffer(eap_packet_length), + eap_packet_length); + + if (eap_header->get_type() == eap_type_identity + && eap_header->get_code() == eap_code_request) + { + // EAP-Request/Identity is handled in eap_core_c. + status = eap_status_unexpected_message; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (eap_header->get_type() == eap_type_identity + && eap_header->get_code() == eap_code_response + && eap_header->get_length() <= eap_header_base_c::get_header_length()) + { + status = eap_status_header_corrupted; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (eap_header->get_type() == eap_expanded_type_simple_config.get_type() + && eap_header->get_length() < simple_config_header.get_simple_config_min_header_length()) + { + status = eap_status_header_corrupted; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (check_received_eap_identifier(eap_header) != eap_status_ok) + { + status = eap_status_unexpected_message; + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::packet_process() failed,") + EAPL("status %d=%s, received EAP-type 0x%08x, received EAP-code %d, ") + EAPL("received EAP-identifier %d, current EAP-identifier %d, state %s\n"), + status, + status_string.get_status_string(status), + convert_eap_type_to_u32_t(eap_header->get_type()), + eap_header->get_code(), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + if (m_is_client == true) + { + // Client saves the received EAP-Identifier. + set_last_eap_identifier(eap_header->get_identifier()); + } + + if (eap_header->get_type() == eap_type_identity) + { + status = eap_identity_response_packet_process( + receive_network_id, + eap_header, + eap_packet_length); + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_drop_packet_quietly) + { + eap_status_string_c status_string; + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::") + EAPL("eap_identity_response_packet_process() failed, status %d=%s\n"), + status, status_string.get_status_string(status))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false); + + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + eap_expanded_type_simple_config.get_type(), + eap_state_none, + eap_state_identity_response_received, + get_last_eap_identifier(), + false); + get_type_partner()->state_notification(¬ification); + } + } + else + { + status = simple_config_packet_process( + receive_network_id, + &simple_config_header, + eap_packet_length); + + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false); + } + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_pending_request + && status != eap_status_drop_packet_quietly) + { + eap_status_string_c status_string; + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process() ") + EAPL("failed, status %d=%s\n"), + status, status_string.get_status_string(status))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (eap_header->get_type() == eap_type_notification) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP type notification: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + convert_eap_type_to_u32_t(eap_header->get_type()))); + + status = eap_status_illegal_eap_type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP type unknown: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + convert_eap_type_to_u32_t(eap_header->get_type()))); + + status = eap_status_illegal_eap_type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (eap_header->get_code() == eap_code_success + || eap_header->get_code() == eap_code_failure) + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (eap_header->get_code() == eap_code_success) + { + if (get_state() == eap_type_simple_config_state_success) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("quietly dropped EAP-Success: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, state %d=%s, is client %d\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + get_state(), + get_state_string(), + (m_is_client == true))); + status = eap_status_drop_packet_quietly; + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP-Success: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, state %d=%s, is client %d\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + get_state(), + get_state_string(), + (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + } + else if (eap_header->get_code() == eap_code_failure) + { + // EAP is quite sloppy protocol. + // Somebody just send a EAP-failure message and authentication is terminated. + + // Save received failure. We do not change our state yet. + // The real correct EAP message could be received later if this failure was + // send by nasty attacker. + set_failure_message_received(); + // We handle the EAP-Request/Failure message after a timeout. + + status = eap_status_ok; + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP code unknown: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, is client %d\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP code unknown: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, is client %d\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::send_sc_frag_ack() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_buf_chain_wr_c eap_fragment_acknowledge_packet( + eap_write_buffer, + m_am_tools, + SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_fragment_acknowledge_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT_ALWAYS(SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH + >= (m_simple_config_header_offset+m_trailer_length)); + u32_t packet_buffer_free = SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_simple_config_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_simple_config_header_offset+m_MTU; + } + + eap_simple_config_header_c fragment_acknowledge( + m_am_tools, + eap_fragment_acknowledge_packet.get_data_offset( + m_simple_config_header_offset, + (packet_buffer_free-m_simple_config_header_offset)), + (packet_buffer_free-m_simple_config_header_offset)); + + if (fragment_acknowledge.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + fragment_acknowledge.reset_header( + m_am_tools, + static_cast(packet_buffer_free-m_simple_config_header_offset), + true); + + fragment_acknowledge.set_eap_length( + static_cast(packet_buffer_free-m_simple_config_header_offset), + true); + + if (m_is_client == true) + { + fragment_acknowledge.set_eap_code(eap_code_response); + fragment_acknowledge.set_eap_identifier(static_cast(get_last_eap_identifier())); + } + else // if (m_is_client == false) + { + fragment_acknowledge.set_eap_code(eap_code_request); + fragment_acknowledge.set_eap_identifier(static_cast(get_last_eap_identifier()+1u)); + } + + fragment_acknowledge.set_eap_type( + eap_expanded_type_simple_config.get_type(), + true); + + fragment_acknowledge.set_sc_op_code(eap_simple_config_header_c::op_code_FRAG_ACK); + + u32_t simple_config_data_offset = 0u; + + update_buffer_indexes( + SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH, + m_simple_config_header_offset+fragment_acknowledge.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + // No payloads. + + fragment_acknowledge.set_data_length( + simple_config_data_offset, + true); + eap_fragment_acknowledge_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_simple_config_header_offset + +fragment_acknowledge.get_header_length() + +fragment_acknowledge.get_data_length() + == packet_buffer_offset); + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_is_client == true) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: EAP-Response/SIMPLE_CONFIG/Acknowledge packet"), + fragment_acknowledge.get_header_buffer(fragment_acknowledge.get_eap_length()), + fragment_acknowledge.get_eap_length())); + } + else // if (m_is_client == false) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: EAP-Request/SIMPLE_CONFIG/Acknowledge packet"), + fragment_acknowledge.get_header_buffer(fragment_acknowledge.get_eap_length()), + fragment_acknowledge.get_eap_length())); + } + + status = packet_send( + get_send_network_id(), + &eap_fragment_acknowledge_packet, + m_simple_config_header_offset, + fragment_acknowledge.get_eap_length(), + SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + if (m_is_client == false) + { + // Server saves the sent EAP-Identifier. + set_last_eap_identifier(static_cast(get_last_eap_identifier()+1ul)); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::send_simple_config_start_message( + const u8_t next_eap_identifier ///< This is EAP-Identifier of next EAP packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_buf_chain_wr_c eap_simple_config_start_packet( + eap_write_buffer, + m_am_tools, + SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_simple_config_start_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT_ALWAYS(SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH + >= (m_simple_config_header_offset+m_trailer_length)); + u32_t packet_buffer_free = SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_simple_config_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_simple_config_header_offset+m_MTU; + } + + eap_simple_config_header_c simple_config_start_packet( + m_am_tools, + eap_simple_config_start_packet.get_data_offset( + m_simple_config_header_offset, + (packet_buffer_free-m_simple_config_header_offset)), + (packet_buffer_free-m_simple_config_header_offset)); + + if (simple_config_start_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + simple_config_start_packet.reset_header( + m_am_tools, + static_cast(packet_buffer_free-m_simple_config_header_offset), + true); + + simple_config_start_packet.set_flag_simple_config_length_included(false); + + simple_config_start_packet.set_eap_length( + static_cast( + packet_buffer_free-m_simple_config_header_offset), + true); + + simple_config_start_packet.set_eap_code(eap_code_request); + simple_config_start_packet.set_eap_identifier(next_eap_identifier); + simple_config_start_packet.set_eap_type( + eap_expanded_type_simple_config.get_type(), + true); + simple_config_start_packet.set_sc_op_code(eap_simple_config_header_c::op_code_WSC_Start); + + update_buffer_indexes( + SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH, + m_simple_config_header_offset+simple_config_start_packet.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + simple_config_start_packet.set_data_length( + 0ul, + true); + eap_simple_config_start_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_simple_config_header_offset+simple_config_start_packet.get_header_length() + +simple_config_start_packet.get_data_length() + == packet_buffer_offset); + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: EAP-Request/SIMPLE_CONFIG/Start packet"), + simple_config_start_packet.get_header_buffer(simple_config_start_packet.get_eap_length()), + simple_config_start_packet.get_eap_length())); + + status = packet_send( + get_send_network_id(), + &eap_simple_config_start_packet, + m_simple_config_header_offset, + simple_config_start_packet.get_eap_length(), + SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + if (m_is_client == false) + { + // Server saves the sent EAP-Identifier. + set_last_eap_identifier(next_eap_identifier); + + set_state(eap_type_simple_config_state_waiting_for_response); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::start_simple_config_authentication( + const eap_am_network_id_c * const /*receive_network_id*/, ///< This is the network identity of the received EAP packet. + const eap_variable_data_c * const NAI ///< This is the full NAI of the client. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_simple_config_record->start_simple_config_authentication(NAI); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::eap_simple_config_fragment_send() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_not_supported; + + if (m_simple_config_message_send_offset == 0ul + && m_simple_config_message_buffer.get_data_length() + < simple_config_tlv_header_c::get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_simple_config_fragment_send(): ") + EAPL("packet buffer too short, %d bytes.\n"), + m_simple_config_message_buffer.get_data_length())); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (m_simple_config_message_buffer.get_data_length() + < m_simple_config_message_send_offset) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_simple_config_fragment_send(): ") + EAPL("packet buffer %d shorter than ") + EAPL("m_simple_config_message_send_offset %d.\n"), + m_simple_config_message_buffer.get_data_length(), + m_simple_config_message_send_offset)); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + eap_buf_chain_wr_c eap_simple_config_fragment( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_simple_config_fragment.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT_ALWAYS(EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH + >= (m_simple_config_header_offset+m_trailer_length)); + u32_t packet_buffer_free + = EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_simple_config_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_simple_config_header_offset+m_MTU; + } + + u32_t packet_eap_data_free + = packet_buffer_free + - m_simple_config_header_offset + - eap_simple_config_header_c::get_simple_config_max_header_length(); + + eap_simple_config_header_c eap_simple_config_packet( + m_am_tools, + eap_simple_config_fragment.get_data_offset( + m_simple_config_header_offset, + packet_eap_data_free), + packet_eap_data_free); + + if (eap_simple_config_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_simple_config_packet.reset_header( + m_am_tools, + static_cast(packet_eap_data_free), + true); + if (m_simple_config_message_send_offset == 0) + { + // This is the first fragment. + eap_simple_config_packet.set_flag_simple_config_length_included(true); + eap_simple_config_packet.set_simple_config_message_length( + m_simple_config_message_buffer.get_data_length()); + } + + eap_simple_config_packet.set_eap_length( + static_cast(packet_eap_data_free), + true); + + if (m_is_client == true) + { + eap_simple_config_packet.set_eap_code(eap_code_response); + eap_simple_config_packet.set_eap_identifier(get_last_eap_identifier()); + } + else + { + eap_simple_config_packet.set_eap_code(eap_code_request); + eap_simple_config_packet.set_eap_identifier( + static_cast(get_last_eap_identifier()+1ul)); + } + + // -------------------------------------------------------------------- + + eap_simple_config_trace_string_c message_string; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_simple_config_fragment_send: %s: message type: %s\n"), + (m_is_client == true ? "client": "server"), + message_string.get_message_type_string(m_simple_config_message_type))); + + EAP_UNREFERENCED_PARAMETER(message_string); // for release + + // Set Op-Code based on the message type + if( m_simple_config_message_type == simple_config_Message_Type_None + || m_simple_config_message_type == simple_config_Message_Type_Beacon + || m_simple_config_message_type == simple_config_Message_Type_Probe_Request + || m_simple_config_message_type == simple_config_Message_Type_Probe_Response + || m_simple_config_message_type > simple_config_Message_keep_this_last ) + { + // Something is wrong + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_simple_config_fragment_send: invalid message type, cannot set Op-Code correctly.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + else if( m_simple_config_message_type == simple_config_Message_Type_WSC_ACK ) + { + eap_simple_config_packet.set_sc_op_code(eap_simple_config_header_c::op_code_WSC_ACK); + } + else if( m_simple_config_message_type == simple_config_Message_Type_WSC_NACK ) + { + eap_simple_config_packet.set_sc_op_code(eap_simple_config_header_c::op_code_WSC_NACK); + } + else if( m_simple_config_message_type == simple_config_Message_Type_WSC_DONE ) + { + eap_simple_config_packet.set_sc_op_code(eap_simple_config_header_c::op_code_WSC_Done); + } + else + { + // In other cases this is a WSC message + eap_simple_config_packet.set_sc_op_code(eap_simple_config_header_c::op_code_WSC_MSG); + } + + // -------------------------------------------------------------------- + + eap_simple_config_packet.set_eap_type( + eap_expanded_type_simple_config.get_type(), + true); + + + u32_t fragment_length + = m_MTU + - eap_simple_config_header_c::get_simple_config_max_header_length(); + u32_t pending_message_length + = m_simple_config_message_buffer.get_data_length() + - m_simple_config_message_send_offset; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-SIMPLE_CONFIG fragment: packet_eap_data_free %d, ") + EAPL("fragment_length %d, pending_message_length %d, ") + EAPL("EAP-header length %d, buffer length %d\n"), + packet_eap_data_free, + fragment_length, + pending_message_length, + eap_simple_config_packet.get_header_length(), + eap_simple_config_fragment.get_buffer_length())); + + if (packet_eap_data_free >= pending_message_length) + { + // Message data is less than the buffer length, + // so the fragment is only length of the message data. + fragment_length = pending_message_length; + + // SIMPLE_CONFIG-message length is not included, + // because no fragmentation is used. + eap_simple_config_packet.set_flag_simple_config_length_included(false); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-SIMPLE_CONFIG fragment: packet_eap_data_free %d, ") + EAPL("fragment_length %d, pending_message_length %d, ") + EAPL("EAP-header length %d\n"), + packet_eap_data_free, + fragment_length, + pending_message_length, + eap_simple_config_packet.get_header_length())); + } + + if (fragment_length < pending_message_length) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-SIMPLE_CONFIG fragment: more fragments follow. ") + EAPL("fragment_length %d, pending_message_length %d, ") + EAPL("EAP-header length %d\n"), + fragment_length, + pending_message_length, + eap_simple_config_packet.get_header_length())); + + if (m_simple_config_message_send_offset == 0) + { + // SIMPLE_CONFIG-message length is included, + eap_simple_config_packet.set_flag_simple_config_length_included(true); + } + + eap_simple_config_packet.set_flag_more_fragments(true); + } + + + update_buffer_indexes( + SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH, + m_simple_config_header_offset+eap_simple_config_packet.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + status = eap_simple_config_fragment.set_data_length(packet_buffer_offset); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + // Payload is SIMPLE_CONFIG-message fragment. + + status = eap_simple_config_fragment.add_data_to_offset( + packet_buffer_offset, + m_simple_config_message_buffer.get_data_offset( + m_simple_config_message_send_offset, fragment_length), + fragment_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + update_buffer_indexes( + SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH, + fragment_length, + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_simple_config_packet.set_data_length( + fragment_length, + true); + + status = eap_simple_config_fragment.set_data_length(packet_buffer_offset); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_simple_config_fragment_send(): m_simple_config_header_offset %d ") + EAPL("+ eap_simple_config_packet.get_header_length()") + EAPL("%d + eap_simple_config_packet.get_data_length() ") + EAPL("%d = %d == packet_buffer_offset %d.\n"), + m_simple_config_header_offset, + eap_simple_config_packet.get_header_length(), + eap_simple_config_packet.get_data_length(), + (m_simple_config_header_offset + + eap_simple_config_packet.get_header_length() + + eap_simple_config_packet.get_data_length()), + packet_buffer_offset)); + + EAP_ASSERT_ALWAYS( + m_simple_config_header_offset + +eap_simple_config_packet.get_header_length() + +eap_simple_config_packet.get_data_length() + == packet_buffer_offset); + + status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = packet_send( + get_send_network_id(), + &eap_simple_config_fragment, + m_simple_config_header_offset, + eap_simple_config_packet.get_eap_length(), + SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + m_simple_config_message_send_offset += fragment_length; + + if (m_is_client == false) + { + // Server saves the sent EAP-Identifier. + set_last_eap_identifier( + static_cast(get_last_eap_identifier()+1ul)); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::simple_config_message_process( + const eap_am_network_id_c * const /*receive_network_id*/, ///< This is the network identity of the received EAP packet. + eap_simple_config_header_c * const received_simple_config, ///< This is pointer to EAP header including EAP-SIMPLE_CONFIG fields. + const u32_t /*simple_config_packet_length*/ ///< This is length of received EAP-SIMPLE_CONFIG packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_simple_config_message_buffer.get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("simple_config_message_process: packet buffer invalid.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (m_simple_config_message_buffer.get_data_length() + < simple_config_tlv_header_c::get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("simple_config_message_process: packet buffer too short, %d bytes.\n"), + m_simple_config_message_buffer.get_data_length())); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + save_current_state(); + set_state(eap_type_simple_config_state_process_simple_config_message); + + eap_status_e status = m_simple_config_record->packet_process( + &m_simple_config_message_buffer, + received_simple_config->get_eap_identifier()); + + if (status == eap_status_ok) + { + // Do nothing. + } + else if (status == eap_status_pending_request) + { + // Asyncronous operation is pending. + // Do nothing. + } + else if (status == eap_status_success) + { + // Authentication OK. + // Do nothing. + } + else if (status == eap_status_drop_packet_quietly) + { + // Dropped packet. + // Do nothing. + } + else + { + // All other return values are ERROR. Authentication is failed. + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: simple_config_message_process: Authentication failed.\n"), + (m_is_client == true) ? "client": "server")); + + restore_saved_previous_state(); + set_state(eap_type_simple_config_state_failure); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::eap_identity_response_packet_process( + const eap_am_network_id_c * const /*receive_network_id*/, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const eap_header, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: %s: function: eap_identity_response_packet_process()\n"), + (m_is_client == true ? "client": "server"))); + + if (eap_header->check_header() != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (eap_header->get_length() > eap_packet_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + if (m_check_identifier_of_eap_identity_response == true) + { + if (m_state == eap_type_simple_config_state_waiting_for_identity_response + && eap_header->get_identifier() != get_last_eap_identifier()) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + else if (m_simple_config_test_version == true + && m_state == eap_type_simple_config_state_success) // This one is for testing purposes. + { + // NOTE here we can not check the EAP-identifier. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_simple_config_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is not checked in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"), + eap_header->get_identifier(), + get_state(), + get_state_string())); + } + } + + + if (m_state == eap_type_simple_config_state_waiting_for_identity_response + || (m_simple_config_test_version == true + // In test version new authentication could start from this state. + && m_state == eap_type_simple_config_state_success)) + { + // EAP-Response/Identity is accepted only as a very first message. + + eap_status_e status = eap_status_process_general_error; + + save_current_state(); + + // In test version new authentication could start from this state. + if (m_simple_config_test_version == true + && m_state == eap_type_simple_config_state_success) // This one is for testing purposes. + { + // NOTE here we can not check the EAP-identifier. + set_state(eap_type_simple_config_state_waiting_for_identity_response); + } + + u8_t next_eap_identifier = static_cast(eap_header->get_identifier()+1u); + + status = parse_identity( + eap_header->get_type_data( + eap_header->get_type_data_length()), + eap_header->get_type_data_length()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = send_simple_config_start_message(next_eap_identifier); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_last_eap_identifier(next_eap_identifier); + set_state(eap_type_simple_config_state_waiting_for_response); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eap_type_simple_config_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x in eap_type_simple_config_state_variable_e %d=%s. ") + EAPL("EAP-Response/Identity is accepted only in ") + EAPL("eap_type_simple_config_state_waiting_for_identity_response.\n"), + eap_header->get_identifier(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::simple_config_packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_simple_config_header_c * const received_simple_config, ///< This is pointer to EAP header including EAP-SIMPLE_CONFIG fields. + const u32_t simple_config_packet_length ///< This is length of received EAP-SIMPLE_CONFIG packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: %s: function: simple_config_packet_process()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_simple_config_test_version == true + && get_state() == eap_type_simple_config_state_failure) + { + // This is for testing. + if (m_is_client == false + && received_simple_config->get_eap_code() == eap_code_response + && received_simple_config->get_eap_type() == eap_type_identity) + { + set_state(eap_type_simple_config_state_waiting_for_identity_response); + } + else if (m_is_client == true + && received_simple_config->get_sc_op_code() == eap_simple_config_header_c::op_code_WSC_Start) + { + set_state(eap_type_simple_config_state_waiting_for_simple_config_start); + } + } + + if (received_simple_config->check_header( + m_am_tools, + m_is_client) != eap_status_ok) + { + // ERROR: EAP-SIMPLE_CONFIG header is corrupted. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ") + EAPL("EAP-SIMPLE_CONFIG header is corrupted in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (received_simple_config->get_eap_length() > simple_config_packet_length) + { + // ERROR: EAP-Lenght field value is larger than actual received packet. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ") + EAPL("EAP-Lenght field %d value is larger than actual received ") + EAPL("packet %d in eap_type_simple_config_state_variable_e %d=%s.\n"), + received_simple_config->get_eap_length(), + simple_config_packet_length, + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (m_is_client == false + && received_simple_config->get_sc_op_code() == eap_simple_config_header_c::op_code_WSC_Start) + { + // ERROR: Server cannot receive EAP-SIMPLE_CONFIG Start message. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ") + EAPL("Server cannot receive EAP-SIMPLE_CONFIG Start message. ") + EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + else if (m_is_client == true + && (get_state() != eap_type_simple_config_state_waiting_for_request + && get_state() != eap_type_simple_config_state_waiting_for_identity_request + // EAP-SIMPLE_CONFIG could start without EAP-Request/Identity message. + && get_state() != eap_type_simple_config_state_waiting_for_simple_config_start + )) + { + // ERROR: Client cannot receive EAP-SIMPLE_CONFIG message in other states. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_simple_config_c::simple_config_packet_process(): ") + EAPL("Client cannot receive EAP-SIMPLE_CONFIG message in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else if (m_is_client == false + && get_state() != eap_type_simple_config_state_waiting_for_response + ) + { + // WARNING: Server cannot receive EAP-SIMPLE_CONFIG message in other states. + // This packet is dropped quietly. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_simple_config_c::simple_config_packet_process(): ") + EAPL("Server cannot receive EAP-SIMPLE_CONFIG message in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else if (received_simple_config->get_sc_op_code() == eap_simple_config_header_c::op_code_WSC_Start + && get_state() != eap_type_simple_config_state_waiting_for_simple_config_start + && get_state() != eap_type_simple_config_state_waiting_for_identity_request) + // EAP-SIMPLE_CONFIG could start without EAP-Request/Identity message. + { + // ERROR: EAP-SIMPLE_CONFIG Start message is accepted only in + // eap_type_simple_config_state_waiting_for_simple_config_start. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ") + EAPL("EAP-SIMPLE_CONFIG Start message is NOT accepted in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + // EAP-SIMPLE_CONFIG and PEAP fragmentation support: + // + // Flags include the Length included (L), More fragments (M), and EAP-SIMPLE_CONFIG Start (S) bits. + // + // The L flag is set to indicate the presence of the four octet SIMPLE_CONFIG Message + // Length field, and MUST be set for the first fragment of a fragmented + // SIMPLE_CONFIG message or set of messages. + // + // The M flag is set on all but the last fragment. + // + // The S flag is set only within the EAP-SIMPLE_CONFIG start message + // sent from the EAP server to the peer. This differentiates + // the EAP-SIMPLE_CONFIG Start message from a fragment acknowledgement. + // + // The SIMPLE_CONFIG Message Length field is four octets, and provides + // the total length of the SIMPLE_CONFIG message or set of messages + // that is being fragmented. This simplifies buffer allocation. + + eap_status_e status = eap_status_process_general_error; + + save_current_reassembly_state(); + + if (get_reassembly_state() == eap_type_simple_config_reassembly_state_wait_first_message) + { + if (received_simple_config->get_flag_more_fragments() == true + && received_simple_config->get_flag_simple_config_length_included() == false) + { + // The first fragmented message must include SIMPLE_CONFIG-length field. + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + bool first_fragment = false; + u32_t simple_config_message_length = 0ul; + + if (received_simple_config->get_flag_simple_config_length_included() == true) + { + // This is the first fragment and SIMPLE_CONFIG message length is included. + // We must allocate buffer for the fragments. + + status = received_simple_config->get_simple_config_message_length(&simple_config_message_length); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + first_fragment = true; + } + else if (received_simple_config->get_flag_more_fragments() == false + && received_simple_config->get_sc_op_code() != eap_simple_config_header_c::op_code_WSC_Start + && received_simple_config->get_data_length() > 0ul) + { + // This is the individual message and SIMPLE_CONFIG message length is not included. + // We must allocate buffer for the message. + + simple_config_message_length = received_simple_config->get_data_length(); + + first_fragment = true; + } + + + if (first_fragment == true) + { + m_simple_config_message_buffer.reset(); + + if (simple_config_message_length > 0ul) + { + if (simple_config_message_length > EAP_SIMPLE_CONFIG_MAX_MESSAGE_LENGTH) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + // Next allocate buffer for reassembled SIMPLE_CONFIG-message. + status = m_simple_config_message_buffer.set_buffer_length(simple_config_message_length); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Copy first fragment to the reassembly buffer. + status = m_simple_config_message_buffer.add_data( + received_simple_config->get_data(m_am_tools, received_simple_config->get_data_length()), + received_simple_config->get_data_length()); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_first_fragment_eap_identifier = received_simple_config->get_eap_identifier(); + } + } + + + if (received_simple_config->get_flag_more_fragments() == true) + { + // This is NOT the last fragment. + + // Send fragment acknowledge message. + status = send_sc_frag_ack(); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Change reassembly state. + set_reassembly_state(eap_type_simple_config_reassembly_state_wait_last_fragment); + } + else + { + // This is the last fragment or non fragmented message. + // Change reassembly state. + set_reassembly_state(eap_type_simple_config_reassembly_state_message_reassembled); + + if (received_simple_config->get_sc_op_code() == eap_simple_config_header_c::op_code_FRAG_ACK) + { + // This is EAP-SIMPLE_CONFIG fragment acknowledge. + if (m_simple_config_message_buffer.get_is_valid_data() == true + && m_simple_config_message_send_offset < m_simple_config_message_buffer.get_data_length()) + { + // We can send next fragment. + + save_current_state(); + set_state(eap_type_simple_config_state_process_simple_config_message); + + status = eap_simple_config_fragment_send(); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_is_client == true) + { + set_state(eap_type_simple_config_state_waiting_for_request); + } + else + { + set_state(eap_type_simple_config_state_waiting_for_response); + } + } + else + { + // No fragment available. Drop this packet. + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (received_simple_config->get_sc_op_code() == eap_simple_config_header_c::op_code_WSC_Start) + { + if (get_state() == eap_type_simple_config_state_waiting_for_simple_config_start) + { + // This is EAP-SIMPLE_CONFIG Start message. + save_current_state(); + set_state(eap_type_simple_config_state_process_simple_config_start); + + if (get_NAI()->get_is_valid_data() == false) + { + status = get_type_partner()->get_saved_eap_identity(get_NAI()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = start_simple_config_authentication(receive_network_id, get_NAI()); + if (status == eap_status_pending_request) + { + // Do nothing. + } + else if (status != eap_status_ok) + { + restore_saved_previous_state(); + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // OK. + set_reassembly_state(eap_type_simple_config_reassembly_state_wait_first_message); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ") + EAPL("Cannot receive EAP-SIMPLE_CONFIG message in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s, ") + EAPL("eap_type_simple_config_reassembly_state_e %d=%s.\n"), + get_state(), + get_state_string(), + get_reassembly_state(), + get_reassembly_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + } + else + { + status = received_simple_config->check_header( + m_am_tools, + m_is_client); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Process the reassembled SIMPLE_CONFIG message. + status = simple_config_message_process( + receive_network_id, + received_simple_config, + simple_config_packet_length); + + if (status != eap_status_ok + && status != eap_status_pending_request + && status != eap_status_success) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + set_reassembly_state(eap_type_simple_config_reassembly_state_wait_first_message); + } + } + else if (get_reassembly_state() == eap_type_simple_config_reassembly_state_wait_last_fragment) + { + // SIMPLE_CONFIG message length field may or may not be included. + + EAP_ASSERT_ALWAYS(received_simple_config->get_sc_op_code() != eap_simple_config_header_c::op_code_WSC_Start); + + // Concatenate fragment to the reassembly buffer. + status = m_simple_config_message_buffer.add_data( + received_simple_config->get_data(m_am_tools, received_simple_config->get_data_length()), + received_simple_config->get_data_length()); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (received_simple_config->get_flag_more_fragments() == true) + { + // This is NOT the last fragment. + + // Send fragment acknowledge message. + status = send_sc_frag_ack(); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // This is the last fragment. + // Change reassembly state. + set_reassembly_state(eap_type_simple_config_reassembly_state_message_reassembled); + + // Process the reassembled SIMPLE_CONFIG message. + status = simple_config_message_process( + receive_network_id, + received_simple_config, + simple_config_packet_length); + + if (status != eap_status_ok + && status != eap_status_pending_request + && status != eap_status_success) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_reassembly_state(eap_type_simple_config_reassembly_state_wait_first_message); + } + } + else if (get_reassembly_state() == eap_type_simple_config_reassembly_state_message_reassembled) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ") + EAPL("Cannot receive EAP-SIMPLE_CONFIG message in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s, ") + EAPL("eap_type_simple_config_reassembly_state_e %d=%s.\n"), + get_state(), + get_state_string(), + get_reassembly_state(), + get_reassembly_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ") + EAPL("Cannot receive EAP-SIMPLE_CONFIG message in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s, ") + EAPL("eap_type_simple_config_reassembly_state_e %d=%s.\n"), + get_state(), + get_state_string(), + get_reassembly_state(), + get_reassembly_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_type_simple_config_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Note, EAP-SIMPLE_CONFIG and PEAP supports fragmentation. + // Here we could tell the MTU is big enough, the maximum memory buffer size is perfect. + + if (MTU != 0) + { + *MTU = EAP_SIMPLE_CONFIG_MAX_MESSAGE_LENGTH; + } + + if (trailer_length != 0) + { + *trailer_length = 0ul; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0ul; // This is the header offset of the SIMPLE_CONFIG-record header. +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::timer_expired( + const u32_t /*id*/, void * /*data*/ + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::timer_delete_data( + const u32_t /*id*/, void * /*data*/ + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_type_simple_config_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + status = m_am_type_simple_config->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_simple_config_record->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + //---------------------------------------------------------- + + { + eap_variable_data_c check_identifier_of_eap_identity_response(m_am_tools); + + status = read_configure( + cf_str_EAP_SIMPLE_CONFIG_check_identifier_of_eap_identity_response.get_field(), + &check_identifier_of_eap_identity_response); + + if (status == eap_status_ok + && check_identifier_of_eap_identity_response.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast( + check_identifier_of_eap_identity_response.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_check_identifier_of_eap_identity_response = false; + } + else + { + m_check_identifier_of_eap_identity_response = true; + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_SIMPLE_CONFIG_check_identifier_of_eap_identity_response + .get_field()->get_field())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_SIMPLE_CONFIG_check_nai_realm(m_am_tools); + + status = read_configure( + cf_str_EAP_SIMPLE_CONFIG_check_nai_realm.get_field(), + &EAP_SIMPLE_CONFIG_check_nai_realm); + if (status == eap_status_ok + && EAP_SIMPLE_CONFIG_check_nai_realm.get_is_valid_data() == true) + { + u32_t *check_nai_realm = reinterpret_cast( + EAP_SIMPLE_CONFIG_check_nai_realm.get_data(sizeof(u32_t))); + if (check_nai_realm != 0 + && *check_nai_realm != 0) + { + m_check_nai_realm = true; + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c test_version(m_am_tools); + + status = read_configure( + cf_str_EAP_SIMPLE_CONFIG_test_version.get_field(), + &test_version); + if (status == eap_status_ok + && test_version.get_is_valid_data() == true + && test_version.get_data_length() == sizeof(u32_t) + && test_version.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(test_version.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_simple_config_test_version = false; + } + else + { + m_simple_config_test_version = true; + } + } + } + } + + //---------------------------------------------------------- + + m_simple_config_header_offset = get_type_partner()->get_header_offset( + &m_MTU, &m_trailer_length); + + if (m_simple_config_header_offset+m_MTU+m_trailer_length > SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH) + { + EAP_ASSERT_ALWAYS(SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH + >= (m_simple_config_header_offset+m_trailer_length)); + + m_MTU = SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH + - (m_simple_config_header_offset+m_trailer_length); + } + + //---------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: function: eap_type_simple_config_c::shutdown(): this = 0x%08x => 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this, + dynamic_cast(this))); + + if (m_shutdown_was_called == true) + { + // Shutdown was already called (this prevents looping forever) + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + m_shutdown_was_called = true; + + send_final_notification(); + + // Here we ignore return value. Both shutdown() calls must be done. + eap_status_e status = m_simple_config_record->shutdown(); + + status = m_am_type_simple_config->shutdown(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE this will be read from AM of EAP-SIMPLE_CONFIG type. + eap_status_e status = m_am_type_simple_config->type_configure_read(field, data); + if (status != eap_status_ok) + { + // EAP-SIMPLE_CONFIG AM did not have configuration parameter. + // Let's try the global configuration. + status = get_type_partner()->read_configure(field, data); + if (status != eap_status_ok) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_simple_config_c::read_configure(): ") + EAPL("unknown configuration parameter"), + field->get_field(), + field->get_field_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE this will be read from AM of EAP-SIMPLE_CONFIG type. + const eap_status_e status = m_am_type_simple_config->type_configure_write(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_simple_config_c::state_notification( + const abs_eap_state_notification_c * const state + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (state->get_protocol_layer() == eap_protocol_layer_general) + { + // Just forward these notifications to lower layers. + + if (state->get_eap_type() == eap_type_none) + { + // NOTE, here we set the EAP-type. + eap_state_notification_c notification( + m_am_tools, + state->get_send_network_id(), + state->get_is_client(), + eap_state_notification_eap, + state->get_protocol_layer(), + eap_expanded_type_simple_config.get_type(), + state->get_previous_state(), + state->get_current_state(), + state->get_eap_identifier(), + false); + + notification.set_authentication_error(state->get_authentication_error()); + + get_type_partner()->state_notification(¬ification); + } + else + { + get_type_partner()->state_notification(state); + } + + return; + } + + + if (state->get_protocol_layer() == eap_protocol_layer_eap) + { + if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s: eap_type_simple_config_c::state_notification(): ") + EAPL("authentication failed: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(eap_expanded_type_simple_config.get_type()))); + + // Here we must change the EAP-type of the notification. + { + eap_state_notification_c notification( + m_am_tools, + state->get_send_network_id(), + state->get_is_client(), + eap_state_notification_eap, + state->get_protocol_layer(), + eap_expanded_type_simple_config.get_type(), + state->get_previous_state(), + eap_state_authentication_terminated_unsuccessfully, + state->get_eap_identifier(), + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + get_type_partner()->state_notification(¬ification); + } + } + else if (state->get_current_state() == eap_state_authentication_finished_successfully) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_simple_config_c::state_notification(): ") + EAPL("authentication EAP-SUCCESS: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(eap_expanded_type_simple_config.get_type()))); + + (void) finish_successful_authentication(); + } + } + else if (state->get_protocol_layer() == eap_protocol_layer_internal_type) + { + eap_simple_config_trace_string_c simple_config_trace; + + if (state->get_current_state() == simple_config_state_failure) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_simple_config_c::state_notification(): SIMPLE_CONFIG tunneled ") + EAPL("authentication failed: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(eap_expanded_type_simple_config.get_type()))); + + set_state(eap_type_simple_config_state_failure); + } + else if (state->get_current_state() == simple_config_state_simple_config_success) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_simple_config_c::state_notification(): ") + EAPL("SIMPLE_CONFIG authentication ") + EAPL("EAP-SUCCESS: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(eap_expanded_type_simple_config.get_type()))); + } + else if (state->get_current_state() == simple_config_state_pending_simple_config_messages_processed) + { + if (get_state() == eap_type_simple_config_state_process_simple_config_message + || get_state() == eap_type_simple_config_state_process_simple_config_start) + { + if (m_is_client == true) + { + set_state(eap_type_simple_config_state_waiting_for_request); + } + else + { + set_state(eap_type_simple_config_state_waiting_for_response); + } + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::query_eap_identity( + const bool /* must_be_synchronous */, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_simple_config_c::query_eap_identity() ") + EAPL("in eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + if (m_simple_config_test_version == true + && get_state() == eap_type_simple_config_state_failure) + { + // This is for testing. + if (m_is_client == false) + { + set_state(eap_type_simple_config_state_waiting_for_identity_response); + } + else if (m_is_client == true) + { + set_state(eap_type_simple_config_state_waiting_for_simple_config_start); + } + } + + + bool use_manual_username(false); + eap_variable_data_c manual_username(m_am_tools); + bool use_manual_realm(false); + eap_variable_data_c manual_realm(m_am_tools); + + + if (m_state == eap_type_simple_config_state_waiting_for_identity_request + || (m_simple_config_test_version == true // This one is for testing purposes. + && m_state == eap_type_simple_config_state_success)) + { + save_current_state(); + set_state(eap_type_simple_config_state_pending_identity_query); + + eap_status_e status = eap_status_process_general_error; + + status = m_am_type_simple_config->query_eap_identity( + receive_network_id, + eap_identifier, + &use_manual_username, + &manual_username, + &use_manual_realm, + &manual_realm); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_eap_identity_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_eap_identity_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok + && status != eap_status_success) + { + // This is an error case. + restore_saved_previous_state(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + status = handle_eap_identity_query( + receive_network_id, + eap_identifier, + use_manual_username, + &manual_username, + use_manual_realm, + &manual_realm); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_state == eap_type_simple_config_state_waiting_for_simple_config_start) + { + // This is re-transmission request. We do not change our state. + // Just send EAP-Identity again. + if (get_NAI()->get_is_valid_data() == true) + { + eap_status_e status = identity->set_copy_of_buffer(get_NAI()); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_simple_config_c::query_eap_identity() ") + EAPL("returns already obtained NAI in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::query_eap_identity(): ") + EAPL("EAP-Request/Identity cannot be completed, identity (NAI) ") + EAPL("is missing. in eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (m_state == eap_type_simple_config_state_pending_identity_query) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_simple_config_c::query_eap_identity(): ") + EAPL("Already pending EAP-Identity query in ") + EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: eap_type_simple_config_c::query_eap_identity(): ") + EAPL("Illegal EAP-Identity query in eap_type_simple_config_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::set_initial_eap_identifier( + const eap_am_network_id_c * const /*receive_network_id*/, + const u8_t /*initial_identifier*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::eap_acknowledge( + const eap_am_network_id_c * const /* receive_network_id */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_simple_config_c::reset(): this = 0x%08x: %d=%s.\n"), + (m_is_client == true) ? "client": "server", + this, + get_state(), + get_state_string())); + + get_NAI()->reset(); + + if (m_is_client == true) + { + // Client waits EAP-Request/Identity. + m_state = eap_type_simple_config_state_waiting_for_identity_request; + m_saved_previous_state = eap_type_simple_config_state_waiting_for_identity_request; + } + else if (m_is_client == false) + { + // Server waits EAP-Response/Identity. + m_state = eap_type_simple_config_state_waiting_for_identity_response; + m_saved_previous_state = eap_type_simple_config_state_waiting_for_identity_response; + } + + m_reassembly_state = eap_type_simple_config_reassembly_state_wait_first_message; + + m_saved_previous_reassembly_state = eap_type_simple_config_reassembly_state_wait_first_message; + + m_simple_config_message_send_offset = 0ul; + + m_simple_config_message_buffer.reset(); + + eap_status_e status = m_simple_config_record->reset(); + + m_failure_message_received = false; + m_authentication_finished_successfully = false; + m_last_eap_identifier = 0ul; + + m_first_fragment_eap_identifier = 0ul; + + m_am_type_simple_config->reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_simple_config_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // This call is forwarded to EAPOL AM module because it handles all the + // tunneled EAP type handlings for PEAP. + const eap_status_e status = get_type_partner()->load_module( + type, + tunneling_type, + partner, + eap_type, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_simple_config_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // This call is forwarded to EAPOL AM module because it handles all the + // tunneled EAP type handlings for PEAP. + const eap_status_e status = get_type_partner()->unload_module(type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_simple_config_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool /*force_clean_restart*/, + const bool /*from_timer*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + const eap_status_e status = get_type_partner()->restart_authentication( + &send_network_id, + is_client_when_true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_simple_config_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::packet_data_crypto_keys( + const eap_am_network_id_c * const /*send_network_id*/, + const eap_master_session_key_c * const /*master_session_key*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE we do NOT forward keys to lower layer. + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// This is commented in abs_simple_config_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::check_is_valid_eap_type( + const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // This call is forwarded to SIMPLE_CONFIG AM module because it handles all the + // tunneled EAP type handlings for PEAP. + const eap_status_e status = m_am_type_simple_config->check_is_valid_eap_type(eap_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_simple_config_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_am_type_simple_config->get_eap_type_list(eap_type_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::set_session_timeout( + const u32_t session_timeout_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = get_type_partner()->set_session_timeout(session_timeout_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = get_type_partner()->add_rogue_ap(rogue_ap_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + +#endif //#if defined(USE_EAP_SIMPLE_CONFIG) + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/eap/src/eap_type_simple_config_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/eap/src/eap_type_simple_config_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,554 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 591 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#if defined(USE_EAP_SIMPLE_CONFIG) + + +#include "eap_am_memory.h" +#include "eap_type_simple_config_header.h" +#include "eap_header_string.h" + + +/** @file */ + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_simple_config_header_c::~eap_simple_config_header_c() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_simple_config_header_c::eap_simple_config_header_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_begin, + const u32_t header_buffer_length) + : eap_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_code_value_e eap_simple_config_header_c::get_eap_code() const +{ + return eap_header_base_c::get_code(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t eap_simple_config_header_c::get_eap_identifier() const +{ + return eap_header_base_c::get_identifier(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u16_t eap_simple_config_header_c::get_eap_length() const +{ + return eap_header_base_c::get_length(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_value_e eap_simple_config_header_c::get_eap_type() const +{ + return eap_header_base_c::get_type(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_simple_config_header_c::get_sc_op_code_offset() const +{ + return eap_header_base_c::get_header_length() + eap_header_base_c::get_type_field_length() + m_op_code_delta_offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_simple_config_header_c::get_sc_flags_offset() const +{ + return eap_header_base_c::get_header_length() + eap_header_base_c::get_type_field_length() + m_flag_delta_offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_simple_config_header_c::get_sc_length_offset() const +{ + return eap_header_base_c::get_header_length() + eap_header_base_c::get_type_field_length() + m_data_or_message_length_delta_offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_simple_config_header_c::op_code_e eap_simple_config_header_c::get_sc_op_code() const +{ + u32_t op_code_offset(get_sc_op_code_offset()); + + u8_t * const op_code = get_header_offset(op_code_offset, sizeof(u8_t)); + if (op_code != 0) + { + return static_cast(*op_code); + } + else + { + return eap_simple_config_header_c::op_code_none; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_sc_op_code(const eap_simple_config_header_c::op_code_e op_code) +{ + u32_t op_code_offset(get_sc_op_code_offset()); + + u8_t * const p_op_code = get_header_offset(op_code_offset, sizeof(u8_t)); + if (p_op_code != 0) + { + *p_op_code = static_cast(op_code); + } + else + { + EAP_ASSERT(p_op_code != 0); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u16_t eap_simple_config_header_c::get_data_length() const +{ + if (get_flag_simple_config_length_included() == true + && get_eap_length() > static_cast(get_header_length())) + { + return static_cast(get_eap_length()-static_cast(get_header_length())); + } + else if (get_flag_simple_config_length_included() == false + && get_eap_length() > static_cast(get_header_length())) + { + return static_cast(get_eap_length()-static_cast(get_header_length())); + } + else + { + return 0; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_simple_config_header_c::get_simple_config_min_header_length() const +{ + return eap_header_base_c::get_header_length() + + eap_header_base_c::get_type_field_length() + + m_data_or_message_length_delta_offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_simple_config_header_c::get_simple_config_max_header_length() +{ + return eap_header_base_c::get_header_length() + + eap_header_base_c::get_expanded_type_field_length() + + m_data_or_message_length_delta_offset + + SIMPLE_CONFIG_MESSAGE_LENGTH_FIELD_SIZE; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_simple_config_header_c::get_header_length() const +{ + u32_t length = get_simple_config_min_header_length(); + + if (get_flag_simple_config_length_included() == true) + { + return length+SIMPLE_CONFIG_MESSAGE_LENGTH_FIELD_SIZE; + } + else + { + return length; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_simple_config_header_c::get_start_offset_of_data() const +{ + return get_header_length(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_simple_config_header_c::get_data_offset( + abs_eap_am_tools_c * const m_am_tools, + const u32_t offset, + const u32_t contignuous_bytes) const +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + u32_t data_length = get_data_length(); // Here is removed optional SIMPLE_CONFIG message length. + + if (data_length >= offset+contignuous_bytes) + { + // get_header_length() handles optional SIMPLE_CONFIG message length field. + u32_t offset_of_data = get_start_offset_of_data(); + u8_t * const data = get_header_offset(offset_of_data, offset+contignuous_bytes); + if (data != 0) + { + return data+offset; // Data begins after the header. + } + else + { + return 0; + } + } + else + { + EAP_ASSERT_ALWAYS(get_data_length() > 0u); + } + return 0; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_simple_config_header_c::get_data( + abs_eap_am_tools_c * const m_am_tools, + const u32_t contignuous_bytes) const +{ + return get_data_offset(m_am_tools, 0u, contignuous_bytes); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * eap_simple_config_header_c::get_simple_config_flags() const +{ + u32_t flag_offset(get_sc_flags_offset()); + + return get_header_offset(flag_offset, sizeof(u8_t)); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_simple_config_header_c::get_simple_config_flag_bit(const u32_t mask) const +{ + const u8_t * const flag = get_simple_config_flags(); + + if (flag != 0 + && ((*flag) & mask)) + { + return true; + } + return false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t eap_simple_config_header_c::get_simple_config_flag_value(const u32_t mask, const u32_t shift) const +{ + const u8_t * const flag = get_simple_config_flags(); + + if (flag != 0) + { + return static_cast(((*flag) & mask) >> shift); + } + else + { + return 0; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_simple_config_header_c::get_flag_simple_config_length_included() const +{ + return get_simple_config_flag_bit(m_flag_mask_simple_config_length_included); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_simple_config_header_c::get_flag_more_fragments() const +{ + return get_simple_config_flag_bit(m_flag_mask_more_fragments); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t eap_simple_config_header_c::get_flag_reserved() const +{ + return get_simple_config_flag_value(m_flag_mask_reserved, m_flag_shift_reserved); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_simple_config_header_c::get_simple_config_message_length(u32_t * const simple_config_length) const +{ + if (get_flag_simple_config_length_included() == false) + { + // SIMPLE_CONFIG data length is NOT included. + *simple_config_length = 0u; + return eap_status_ok; + } + + u8_t * const data = get_header_offset(get_sc_length_offset(), sizeof(u32_t)); + if (data != 0) + { + u32_t simple_config_message_length = + eap_read_u32_t_network_order(data, sizeof(u32_t)); + + *simple_config_length = simple_config_message_length; + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_simple_config_header_c::check_header( + abs_eap_am_tools_c * const /* tools */, + const bool is_client_when_true) const +{ + eap_status_e status = eap_status_ok; + + if (get_flag_reserved() != static_cast(0ul)) + { + status = EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (status != eap_status_ok) + { + EAP_UNREFERENCED_PARAMETER(is_client_when_true); + + // In version negotiation this check will fail. + // Do not add error traces here. + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("WARNING: EAP_type_SIMPLE_CONFIG: check_header(): failed, %s, ") + EAPL("get_eap_type() 0x%08x, get_op_code() %d, get_flag_reserved() %d, status %s\n"), + (is_client_when_true == true) ? "client": "server", + convert_eap_type_to_u32_t(get_eap_type()), + get_sc_op_code(), + get_flag_reserved(), + status_string.get_status_string(status))); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_simple_config_header_c::get_code_string() const +{ + return eap_header_string_c::get_eap_code_string(get_eap_code()); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_simple_config_header_c::get_eap_type_string() const +{ + if (get_eap_length() <= eap_header_base_c::get_header_length()) + { + return EAPL("No EAP-type"); + } + + return eap_header_string_c::get_eap_type_string(get_eap_type()); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_simple_config_header_c::get_sc_op_code_string() const +{ + const op_code_e op_code(get_sc_op_code()); + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(op_code, op_code_none) + else EAP_IF_RETURN_STRING(op_code, op_code_WSC_Start) + else EAP_IF_RETURN_STRING(op_code, op_code_WSC_ACK) + else EAP_IF_RETURN_STRING(op_code, op_code_WSC_NACK) + else EAP_IF_RETURN_STRING(op_code, op_code_WSC_MSG) + else EAP_IF_RETURN_STRING(op_code, op_code_WSC_Done) + else EAP_IF_RETURN_STRING(op_code, op_code_FRAG_ACK) +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(op_code); + return EAPL("Unknown SIMPLE CONFIG Op-Code"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_eap_code(const eap_code_value_e p_code) +{ + eap_header_base_c::set_code(p_code); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_eap_identifier(const u8_t p_identifier) +{ + eap_header_base_c::set_identifier(p_identifier); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_eap_length( + const u16_t p_length, + const bool expanded_type_when_true) +{ + eap_header_base_c::set_length( + p_length, + expanded_type_when_true); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_eap_type( + const eap_type_value_e p_type, + const bool expanded_type_when_true) +{ + eap_header_base_c::set_type(p_type, expanded_type_when_true); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_simple_config_flag_value(const u8_t value, const u32_t mask, const u32_t shift) const +{ + u8_t *flag = get_simple_config_flags(); + + if (flag != 0) + { + (*flag) = static_cast(((*flag) & ~mask) | ((value << shift) & mask)); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_simple_config_flag_bit(const bool flag, u32_t mask) const +{ + u8_t *p_flag = get_simple_config_flags(); + + if (p_flag != 0) + { + if (flag == true) + { + (*p_flag) = static_cast((*p_flag) | mask); + } + else + { + (*p_flag) = static_cast((*p_flag) & ~mask); + } + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_flag_reserved(const u8_t reserved) +{ + set_simple_config_flag_value(reserved, m_flag_mask_reserved, m_flag_shift_reserved); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_flag_simple_config_length_included(const bool simple_config_length_included) +{ + set_simple_config_flag_bit(simple_config_length_included, m_flag_mask_simple_config_length_included); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_flag_more_fragments(const bool more_fragments) +{ + set_simple_config_flag_bit(more_fragments, m_flag_mask_more_fragments); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_data_length( + const u32_t p_data_length, + const bool expanded_type_when_true) +{ + EAP_ASSERT_ALWAYS(p_data_length+get_header_length() <= 0xffff); + + set_eap_length( + static_cast(p_data_length+get_header_length()), + expanded_type_when_true); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::set_simple_config_message_length(const u32_t simple_config_length) +{ + EAP_ASSERT_ALWAYS(get_flag_simple_config_length_included() == true); + + u32_t message_length_offset(get_sc_length_offset()); + + u8_t * const data = get_header_offset(message_length_offset, sizeof(u32_t)); + + EAP_ASSERT(data != 0); + + data[0] = static_cast((simple_config_length & 0xff000000) >> 24); + data[1] = static_cast((simple_config_length & 0x00ff0000) >> 16); + data[2] = static_cast((simple_config_length & 0x0000ff00) >> 8); + data[3] = static_cast((simple_config_length & 0x000000ff) >> 0); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_simple_config_header_c::reset_header( + abs_eap_am_tools_c * const m_am_tools, + const u32_t buffer_length, + const bool expanded_type_when_true) +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + eap_header_base_c::set_length( + static_cast(buffer_length), + expanded_type_when_true); + + set_eap_code(eap_code_none); + + set_eap_type( + eap_type_none, + true); + + set_flag_simple_config_length_included(false); + set_flag_more_fragments(false); + set_sc_op_code(op_code_none); + + set_flag_reserved(0u); + + set_eap_identifier(0u); +} + +//-------------------------------------------------- + +#endif //#if defined(USE_EAP_SIMPLE_CONFIG) + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/eap/src/eap_type_simple_config_state_notification.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/eap/src/eap_type_simple_config_state_notification.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 592 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_type_simple_config_state_notification.h" +#include "eap_type_simple_config.h" +#include "eap_tools.h" + + +EAP_FUNC_EXPORT eap_type_simple_config_state_notification_c::~eap_type_simple_config_state_notification_c() +{ +} + +EAP_FUNC_EXPORT eap_type_simple_config_state_notification_c::eap_type_simple_config_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e type, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + protocol, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + + +#if defined(USE_EAP_EXPANDED_TYPES) + +EAP_FUNC_EXPORT eap_type_simple_config_state_notification_c::eap_type_simple_config_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e type, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + eap_type, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + +EAP_FUNC_EXPORT eap_type_simple_config_state_notification_c::eap_type_simple_config_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e type, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + eap_type, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/eap/src/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/eap/src/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,20 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_simple_config + +SRC_FILES_CPP = $(WLAN_COMMON)/type/simple_config/eap/src/eap_type_simple_config.cpp \ + $(WLAN_COMMON)/type/simple_config/eap/src/eap_type_simple_config_state_notification.cpp \ + $(WLAN_COMMON)/type/simple_config/eap/src/eap_type_simple_config_header.cpp + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_simple_config.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \ + -lstdc++ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/abs_simple_config_apply_cipher_spec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/abs_simple_config_apply_cipher_spec.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_SIMPLE_CONFIG_MESSAGE_RECORD_PROCESS_H_) +#define _ABS_SIMPLE_CONFIG_MESSAGE_RECORD_PROCESS_H_ + +#include "eap_am_export.h" + +/// This class declares the functions message classes of SIMPLE_CONFIG +/// requires from the SIMPLE_CONFIG. +class EAP_EXPORT abs_simple_config_apply_cipher_spec_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing. + virtual ~abs_simple_config_apply_cipher_spec_c() + { + } + + /// Constructor does nothing. + + abs_simple_config_apply_cipher_spec_c() + { + } + + /** + * This function applies the send cipher suite to record message. + * @param simple_config_record_message_buffer includes the buffer of the whole SIMPLE_CONFIG-record. + */ + virtual eap_status_e apply_send_cipher_suite( + eap_variable_data_c * const simple_config_record_message_buffer) = 0; + + //-------------------------------------------------- +}; // class abs_simple_config_apply_cipher_spec_c + +#endif //#if !defined(_ABS_SIMPLE_CONFIG_MESSAGE_RECORD_PROCESS_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/abs_simple_config_base_record.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/abs_simple_config_base_record.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,288 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_SIMPLE_CONFIG_BASE_RECORD_H_) +#define _ABS_SIMPLE_CONFIG_BASE_RECORD_H_ + +#include "eap_header.h" +#include "simple_config_types.h" + +class eap_buf_chain_wr_c; +class eap_variable_data_c; +class abs_eap_state_notification_c; +class abs_eap_base_timer_c; +class abs_eap_base_type_c; +class eap_base_type_c; +class eap_network_id_selector_c; +class eap_am_network_id_c; +class eap_rogue_ap_entry_c; +class eap_master_session_key_c; + + +/// The class is the interface to partner class of the simple_config_base_record_c class. +/// This declares the pure virtual member functions simple_config_base_record_c class could call. +class EAP_EXPORT abs_simple_config_base_record_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_simple_config_base_record_c class does nothing special. + */ + virtual ~abs_simple_config_base_record_c() + { + } + + /** + * The constructor of the abs_simple_config_base_record_c class does nothing special. + */ + abs_simple_config_base_record_c() + { + } + + /** + * The derived class could send packets to partner class with this function. + * @param sent_packet includes the buffer for the whole packet and initialized + * SIMPLE_CONFIG-packet in correct offset. + * @param message_type is the type of the SIMPLE_CONFIG message indicated by the higher layer. + */ + virtual eap_status_e simple_config_packet_send( + eap_buf_chain_wr_c * const sent_packet, + const simple_config_Message_Type_e message_type) = 0; + + /** + * The get_header_offset() function obtains the header offset of SIMPLE_CONFIG-packet. + * @param MTU_length is pointer to variable to store the maximum transfer unit (MTU). + * MTU is the maximum SIMPLE_CONFIG-packet length in bytes + * @param trailer_length is pointer to the variable to store length + * of trailer needed by lower levels. + * @return Function returns the offset of SIMPLE_CONFIG-header. + * + * The needed buffer length is ((offset) + (SIMPLE_CONFIG-packet length) + (trailer)) bytes. + * Each layer adds the length of the header to offset. + * Each layer removes the length of the header and trailer from MTU. + * + * Now some ascii graphics follows. + * @code + * |<-------------------------buffer length----------------------------------------->| + * | | + * | +-----+---------------------------------+ | + * | | SIMPLE_CONFIG | data | | + * | +-----+---------------------------------+ | + * |<----offset--------------->|<----MTU------------------------------>|<--trailer-->| + * | | | | + * | | | | + * | +-----+---------------------------------------+ | + * | | EAP | data | | + * | +-----+---------------------------------------+ | + * |<----offset--------->|<----MTU------------------------------------>|<--trailer-->| + * | | | | + * | +-------+---------------------------------------------+ | + * | | EAPOL | data | | + * | +-------+---------------------------------------------+ | + * |<--offset--->|<----MTU-------------------------------------------->|<--trailer-->| + * | | | | + * +-------------+-----------------------------------------------------+-------------+ + * | ETHERNET | data | trailer | + * +-------------+-----------------------------------------------------+-------------+ + * |<----MTU------------------------------------------------------------------------>| + * @endcode + * + */ + virtual u32_t get_header_offset( + u32_t * const MTU_length, + u32_t * const trailer_length) = 0; + + /** + * This function restarts authentication to send_network_id. + * @param receive_network_id is network identity of source. + * @param is_client_when_true indicates whether this object should act as a client (true) + * or server (false), in terms of EAP-protocol whether this network entity is EAP-supplicant (true) + * or EAP-authenticator (false). + * @param force_clean_restart causes authentication restart even the current authentication is on going. + * @param from_timer indicates whether this was called from timer (true). + */ + virtual eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + * + * EAP-type should store it's parameters to an own database. The own database should be accessed + * through adaptation module of EAP-type. See eap_am_type_simple_config_simulator_c::type_configure_read. + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + * + * EAP-type should store it's parameters to an own database. The own database should be accessed + * through adaptation module of EAP-type. See eap_am_type_simple_config_simulator_c::type_configure_write. + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. EAP-type MUST send these + * two notifications to lower layer. + * These two notifications are sent using EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + * See also eap_state_notification_c. + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + /** + * This is needed by PEAP type. + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + /** + * This is needed by PEAP type. + * The unload_module() function unloads the module of a EAP-type. + * @param type is the requested EAP-type. + */ + virtual eap_status_e unload_module(const eap_type_value_e type) = 0; + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @param master_session_key is pointer to the first byte of the master session key. + * @param master_session_length is count of bytes in the master session key. + */ + virtual eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) = 0; + + /** + * This is needed by PEAP type. + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + /** + * The set_session_timeout() function changes the session timeout timer to be elapsed after session_timeout_ms milliseconds. + */ + virtual eap_status_e set_session_timeout( + const u32_t session_timeout_ms) = 0; + + virtual eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list) = 0; + + //-------------------------------------------------- +}; // class abs_simple_config_base_record_c + +#endif //#if !defined(_ABS_SIMPLE_CONFIG_BASE_RECORD_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/abs_simple_config_message_hash.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/abs_simple_config_message_hash.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_SIMPLE_CONFIG_MESSAGE_HASH_H_) +#define _ABS_SIMPLE_CONFIG_MESSAGE_HASH_H_ + +#include "eap_am_export.h" + +/// This class declares the functions message classes of SIMPLE_CONFIG +/// requires from the SIMPLE_CONFIG. +class EAP_EXPORT abs_simple_config_message_hash_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing. + virtual ~abs_simple_config_message_hash_c() + { + } + + /// Constructor does nothing. + abs_simple_config_message_hash_c() + { + } + + /** + * This function saves MD5 and SHA hashes for certificate verify message to + * member attributes m_message_hash_md5_certificate_verify and m_message_hash_sha1_certificate_verify. + */ + virtual eap_status_e message_hash_save_certificate_verify() = 0; + + /** + * This function saves MD5 and SHA hashes for finished message to + * member attributes message_hash_md5_finished and message_hash_sha1_finished. + */ + virtual eap_status_e message_hash_save_finished( + const bool client_originated) = 0; + + /** + * This function creates finished message hash. + * @param signed_message_hash is pointer to buffer of the message hash. + */ + virtual eap_status_e message_hash_create_finished( + const bool client_originated_message, + eap_variable_data_c * const signed_message_hash) = 0; + + //-------------------------------------------------- +}; // class abs_simple_config_message_hash_c + +#endif //#if !defined(_ABS_SIMPLE_CONFIG_MESSAGE_HASH_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_attribute_type.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_attribute_type.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_SIMPLE_CONFIG_ATTRIBUTE_TYPE_H_) +#define _SIMPLE_CONFIG_ATTRIBUTE_TYPE_H_ + +/** @file */ + +//---------------------------------------------------------------------------- + +/** + * This is enumeration of Simple Config Type-Length-Value (TLV) types. + */ +enum simple_config_Attribute_Type_e +{ + simple_config_Attribute_Type_None = 0x0000, ///< This is initialization value. + + simple_config_Attribute_Type_AP_Channel = 0x1001, + simple_config_Attribute_Type_First_Correct_Value = simple_config_Attribute_Type_AP_Channel, + + simple_config_Attribute_Type_Association_State = 0x1002, + simple_config_Attribute_Type_Authentication_Type = 0x1003, + simple_config_Attribute_Type_Authentication_Type_Flags = 0x1004, + simple_config_Attribute_Type_Authenticator = 0x1005, + simple_config_Attribute_Type_Config_Methods = 0x1008, + simple_config_Attribute_Type_Configuration_Error = 0x1009, + simple_config_Attribute_Type_Confirmation_URL4 = 0x100A, + simple_config_Attribute_Type_Confirmation_URL6 = 0x100B, + simple_config_Attribute_Type_Connection_Type = 0X100C, + simple_config_Attribute_Type_Connection_Type_Flags = 0X100D, + simple_config_Attribute_Type_Credential = 0X100E, + simple_config_Attribute_Type_Device_Name = 0x1011, + simple_config_Attribute_Type_Device_Password_ID = 0x1012, + simple_config_Attribute_Type_E_Hash1 = 0x1014, + simple_config_Attribute_Type_E_Hash2 = 0x1015, + simple_config_Attribute_Type_E_SNonce1 = 0x1016, + simple_config_Attribute_Type_E_SNonce2 = 0x1017, + simple_config_Attribute_Type_Encrypted_Settings = 0x1018, + simple_config_Attribute_Type_Encryption_Type = 0X100F, + simple_config_Attribute_Type_Encryption_Type_Flags = 0x1010, + simple_config_Attribute_Type_Enrollee_Nonce = 0x101A, + simple_config_Attribute_Type_Feature_ID = 0x101B, + simple_config_Attribute_Type_Identity = 0X101C, + simple_config_Attribute_Type_Identity_Proof = 0X101D, + simple_config_Attribute_Type_Key_Wrap_Authenticator = 0x101E, + simple_config_Attribute_Type_Key_Identifier = 0X101F, + simple_config_Attribute_Type_MAC_Address = 0x1020, + simple_config_Attribute_Type_Manufacturer = 0x1021, + simple_config_Attribute_Type_Message_Type = 0x1022, + simple_config_Attribute_Type_Model_Name = 0x1023, + simple_config_Attribute_Type_Model_Number = 0x1024, + simple_config_Attribute_Type_Network_Index = 0x1026, + simple_config_Attribute_Type_Network_Key = 0x1027, + simple_config_Attribute_Type_Network_Key_Index = 0x1028, + simple_config_Attribute_Type_New_Device_Name = 0x1029, + simple_config_Attribute_Type_New_Password = 0x102A, + simple_config_Attribute_Type_OOB_Device_Password = 0X102C, + simple_config_Attribute_Type_OS_Version = 0X102D, + simple_config_Attribute_Type_Power_Level = 0X102F, + simple_config_Attribute_Type_PSK_Current = 0x1030, + simple_config_Attribute_Type_PSK_Max = 0x1031, + simple_config_Attribute_Type_Public_Key = 0x1032, + simple_config_Attribute_Type_Radio_Enabled = 0x1033, + simple_config_Attribute_Type_Reboot = 0x1034, + simple_config_Attribute_Type_Registrar_Current = 0x1035, + simple_config_Attribute_Type_Registrar_Established = 0x1036, + simple_config_Attribute_Type_Registrar_List = 0x1037, + simple_config_Attribute_Type_Registrar_Max = 0x1038, + simple_config_Attribute_Type_Registrar_Nonce = 0x1039, + simple_config_Attribute_Type_Request_Type = 0x103A, + simple_config_Attribute_Type_Response_Type = 0x103B, + simple_config_Attribute_Type_RF_Band = 0X103C, + simple_config_Attribute_Type_R_Hash1 = 0X103D, + simple_config_Attribute_Type_R_Hash2 = 0X103E, + simple_config_Attribute_Type_R_SNonce1 = 0X103F, + simple_config_Attribute_Type_R_SNonce2 = 0x1040, + simple_config_Attribute_Type_Selected_Registrar = 0x1041, + simple_config_Attribute_Type_Serial_Number = 0x1042, + simple_config_Attribute_Type_Simple_Config_State = 0x1044, + simple_config_Attribute_Type_SSID = 0x1045, + simple_config_Attribute_Type_Total_Networks = 0x1046, + simple_config_Attribute_Type_UUID_E = 0x1047, + simple_config_Attribute_Type_UUID_R = 0x1048, + simple_config_Attribute_Type_Vendor_Extension = 0x1049, + simple_config_Attribute_Type_Version = 0x104A, + simple_config_Attribute_Type_X_509_Certificate_Request = 0x104B, + simple_config_Attribute_Type_X_509_Certificate = 0x104C, + simple_config_Attribute_Type_EAP_Identity = 0x104D, + simple_config_Attribute_Type_Message_Counter = 0x104E, + simple_config_Attribute_Type_Public_Key_Hash = 0x104F, + simple_config_Attribute_Type_Rekey_Key = 0x1050, + simple_config_Attribute_Type_Key_Lifetime = 0x1051, + simple_config_Attribute_Type_Permitted_Config_Methods = 0x1052, + simple_config_Attribute_Type_Selected_Registrar_Config_Methods = 0x1053, + simple_config_Attribute_Type_Primary_Device_Type = 0x1054, + simple_config_Attribute_Type_Secondary_Device_Type_List = 0x1055, + simple_config_Attribute_Type_Portable_Device = 0x1056, + simple_config_Attribute_Type_AP_Setup_Locked = 0x1057, + simple_config_Attribute_Type_Application_List = 0x1058, + simple_config_Attribute_Type_EAP_Type = 0x1059, + simple_config_Attribute_Type_Initialization_Vector = 0x1060, + simple_config_Attribute_Type_Key_Provided_Automatically = 0x1061, + simple_config_Attribute_Type_802_1X_Enabled = 0x1062, + simple_config_Attribute_Type_Last_Correct_Value = simple_config_Attribute_Type_802_1X_Enabled, +}; + + +//---------------------------------------------------------------------------- + +#endif //#if !defined(_SIMPLE_CONFIG_ATTRIBUTE_TYPE_H_) + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_base_record.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_base_record.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,143 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_SIMPLE_CONFIG_BASE_RECORD_H_) +#define _SIMPLE_CONFIG_BASE_RECORD_H_ + + +#include "simple_config_types.h" +#include "eap_array.h" +#include "eap_header.h" + +class abs_simple_config_base_record_c; +class abs_eap_am_tools_c; +class eap_am_network_id_c; +class simple_config_record_header_c; +class eap_rogue_ap_entry_c; + + +/// The simple_config_base_record_c class declares pure virtual functions +/// a user class of SIMPLE_CONFIG-record class could call. +class EAP_EXPORT simple_config_base_record_c +{ +private: + //-------------------------------------------------- + + /// This is back pointer to object which created this object. + /// The simple_config_base_record_c object sends packets to the network using m_type_partner object. + /// @see abs_simple_config_base_record_c. + abs_simple_config_base_record_c *m_type_partner; + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the simple_config_base_record_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~simple_config_base_record_c(); + + /** + * The constructor of the simple_config_base_record_c class simply initializes the attributes. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + * @param partner is back pointer to object which created this object. + * The simple_config_base_record_c object sends packets to the network using m_type_partner object. + */ + EAP_FUNC_IMPORT simple_config_base_record_c( + abs_eap_am_tools_c * const tools); + + /** + * Type partner is object below the simple_config_base_record_c object. + * @return The get_type_partner() function returns the pointer to the partner class. + */ + EAP_FUNC_IMPORT abs_simple_config_base_record_c * get_type_partner(); + + EAP_FUNC_IMPORT void set_type_partner(abs_simple_config_base_record_c * const partner); + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + */ + virtual eap_status_e configure() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + /** + * This function sets the NAI realm. + */ + virtual eap_status_e set_nai_realm(const eap_variable_data_c * const NAI_realm) = 0; + + /** + * This function sends starts EAP-SIMPLE_CONFIG/PEAP after a start message is received. + */ + virtual eap_status_e start_simple_config_authentication( + const eap_variable_data_c * const NAI ///< This is the full NAI of the client. + ) = 0; + + /** + * This function processes the received packet. + * @param simple_config_packet points to the buffer of the whole reassembled SIMPLE_CONFIG-packet. + */ + virtual eap_status_e packet_process( + eap_variable_data_c * const simple_config_packet, + const u8_t received_eap_identifier) = 0; + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + virtual bool get_is_valid() = 0; + + /** + * This function resets the reused simple_config_base_record_c object. + */ + virtual eap_status_e reset() = 0; + + //-------------------------------------------------- +}; // class simple_config_base_record_c + +#endif //#if !defined(_SIMPLE_CONFIG_BASE_RECORD_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_completion.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_completion.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,117 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_SIMPLE_CONFIG_COMPLETION_H_) +#define _SIMPLE_CONFIG_COMPLETION_H_ + +#include "eap_tools.h" +#include "eap_array.h" +//#include "simple_config_record_message.h" +#include "abs_simple_config_message_hash.h" + +/** @file */ + +/** + * This is enumeration of SIMPLE_CONFIG competion actions. + */ +enum simple_config_completion_action_e +{ + simple_config_completion_action_none, ///< Initialization value means no action. + simple_config_completion_action_process_simple_config_attributes, ///< process_simple_config_attributes +}; + +//---------------------------------------------------------------------------- + + +/// This class defines one SIMPLE_CONFIG completion action. +class EAP_EXPORT simple_config_completion_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This variable stores the completion action. + simple_config_completion_action_e m_completion_action; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~simple_config_completion_c(); + + /** + * Constructor initializes object. + */ + EAP_FUNC_IMPORT simple_config_completion_c( + abs_eap_am_tools_c * const tools, + simple_config_completion_action_e completion_action); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function sets the completion action type. + */ + EAP_FUNC_IMPORT void set_completion_action(simple_config_completion_action_e completion_action); + + /** + * This function gets the completion action type. + */ + EAP_FUNC_IMPORT simple_config_completion_action_e get_completion_action() const; + + /** + * This function gets the debug string of the completion action type. + */ + EAP_FUNC_IMPORT eap_const_string get_completion_action_string() const; + + // + //-------------------------------------------------- +}; // class simple_config_completion_c + + +//-------------------------------------------------- + +#endif //#if !defined(_SIMPLE_CONFIG_COMPLETION_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_credential.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_credential.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,104 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_SIMPLE_CONFIG_CREDENTIAL_H_) +#define _SIMPLE_CONFIG_CREDENTIAL_H_ + +#include "eap_tools.h" +#include "simple_config_attribute_type.h" +#include "simple_config_types.h" +#include "eap_array_algorithms.h" + +/** @file */ + + +//---------------------------------------------------------------------------- + + +/// This class defines Credential attributes. +class EAP_EXPORT simple_config_credential_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + u8_t m_network_index; + + eap_variable_data_c m_SSID; + + simple_config_Authentication_Type_e m_Authentication_Type; + + simple_config_Encryption_Type_e m_Encryption_Type; + + eap_array_c m_network_keys; + + eap_variable_data_c m_MAC_address; + + bool m_is_valid; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the simple_config_credential_c class does nothing. + */ + EAP_FUNC_IMPORT virtual ~simple_config_credential_c(); + + /** + * The constructor of the simple_config_credential_c class simply initializes the attributes. + */ + EAP_FUNC_IMPORT simple_config_credential_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT void set_network_index(const u8_t index); + + EAP_FUNC_IMPORT u8_t get_network_index(); + + EAP_FUNC_IMPORT eap_variable_data_c * get_SSID(); + + EAP_FUNC_IMPORT simple_config_Authentication_Type_e get_Authentication_Type(); + + EAP_FUNC_IMPORT void set_Authentication_Type(const simple_config_Authentication_Type_e Authentication_Type); + + EAP_FUNC_IMPORT simple_config_Encryption_Type_e get_Encryption_Type(); + + EAP_FUNC_IMPORT void set_Encryption_Type(const simple_config_Encryption_Type_e Encryption_Type); + + EAP_FUNC_IMPORT eap_array_c * get_network_keys(); + + EAP_FUNC_IMPORT eap_variable_data_c * get_MAC_address(); + + EAP_FUNC_IMPORT bool get_is_valid(); + + // + //-------------------------------------------------- +}; // class simple_config_credential_c + + +//-------------------------------------------------- + +#endif //#if !defined(_SIMPLE_CONFIG_CREDENTIAL_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_message.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_message.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_SIMPLE_CONFIG_MESSAGE_H_) +#define _SIMPLE_CONFIG_MESSAGE_H_ + +#include "eap_tools.h" +#include "eap_array.h" +#include "abs_simple_config_apply_cipher_spec.h" + +/** @file */ + + +//---------------------------------------------------------------------------- + + +/// This class defines one SIMPLE_CONFIG-message. One SIMPLE_CONFIG message could include many SIMPLE_CONFIG-records. +/** + * This class defined one SIMPLE_CONFIG-message. + * Parse and analyse of SIMPLE_CONFIG-message is asyncronous. + * m_analyse_index tells the index of message where asyncronous + * analyse of SIMPLE_CONFIG-message must continue. + * Analysed messages are skipped during the asyncronous + * analyse of messages. Asyncronous analyse is needed + * because of the PKI functions are asyncronous in + * Symbian. + */ +class EAP_EXPORT simple_config_message_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This buffer includes copy of the whole received SIMPLE_CONFIG-message data. + eap_variable_data_c m_simple_config_message_data; + + /// This is EAP-identifier of the EAP-packet that includes SIMPLE_CONFIG-message. This is needed in XP-PEAP. + u8_t m_received_eap_identifier; + + + /// This indicates whether this object is client (true) or server (false). This is mostly for traces. + const bool m_is_client; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the simple_config_message_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~simple_config_message_c(); + + /** + * The constructor of the simple_config_message_c class simply initializes the attributes. + */ + EAP_FUNC_IMPORT simple_config_message_c( + abs_eap_am_tools_c * const tools, + const bool is_client); + + /** + * This function resets this object. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + /** + * This function copies the received SIMPLE_CONFIG-message data and EAP-identifier. + * EAP-identifier is needed in XP PEAPv0. That stupid version uses + * same EAP-identifier with PEAP header and tunneled EAP-header. + */ + EAP_FUNC_IMPORT eap_status_e set_simple_config_message_data( + eap_variable_data_c * const simple_config_message_data, + const u8_t received_eap_identifier); + + /** + * This function returns the SIMPLE_CONFIG-message data. + */ + EAP_FUNC_IMPORT eap_variable_data_c * get_simple_config_message_data(); + + /** + * This function returns the EAP-identifier. + */ + EAP_FUNC_IMPORT u8_t get_received_eap_identifier(); + + /** + * Function adds padding for block size if it is needed. + */ + EAP_FUNC_IMPORT eap_status_e add_padding(const u32_t block_size); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + // + //-------------------------------------------------- +}; // class simple_config_message_c + + +//-------------------------------------------------- + +#endif //#if !defined(_SIMPLE_CONFIG_MESSAGE_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_payloads.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,287 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_SIMPLE_CONFIG_PAYLOADS_H_) +#define _SIMPLE_CONFIG_PAYLOADS_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "simple_config_tlv_header.h" +#include "simple_config_attribute_type.h" +#include "eap_core_map.h" +#include "eap_array.h" + +class simple_config_message_c; +class crypto_hmac_c; + +class EAP_EXPORT simple_config_variable_data_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + eap_variable_data_c m_data; + + simple_config_tlv_header_c m_header; + + /// This is pointer to the next payload that have same attribute type. + /// This link is used when multiple instances of the same attribute types are included to a message. + simple_config_variable_data_c * m_next_payload_with_same_attribute_type; + + bool m_is_mandatory; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~simple_config_variable_data_c(); + + EAP_FUNC_IMPORT simple_config_variable_data_c(abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT bool get_is_valid() const; + + EAP_FUNC_IMPORT eap_status_e set_copy_of_buffer( + const simple_config_Attribute_Type_e current_payload_code, + const bool is_mandatory, + const void * const buffer, + const u32_t buffer_length); + + EAP_FUNC_IMPORT eap_status_e add_data( + const void * const buffer, + const u32_t buffer_length); + + EAP_FUNC_IMPORT u32_t get_data_length() const; + + EAP_FUNC_IMPORT u8_t * get_data(const u32_t data_length) const; + + simple_config_tlv_header_c * get_header(); + + EAP_FUNC_IMPORT eap_variable_data_c * get_full_attribute_buffer(); + + EAP_FUNC_IMPORT simple_config_Attribute_Type_e get_attribute_type() const; + + EAP_FUNC_IMPORT bool get_is_mandatory() const; + + EAP_FUNC_IMPORT void set_attribute_type(const simple_config_Attribute_Type_e type); + + EAP_FUNC_IMPORT void add_next_payload_with_same_attribute_type(simple_config_variable_data_c * const attribute); + + EAP_FUNC_IMPORT void set_next_payload_with_same_attribute_type(simple_config_variable_data_c * attribute); + + EAP_FUNC_IMPORT simple_config_variable_data_c * get_next_payload_with_same_attribute_type(); + + EAP_FUNC_IMPORT simple_config_variable_data_c * copy() const; + + EAP_FUNC_IMPORT void object_increase_reference_count(); + + EAP_FUNC_IMPORT eap_status_e check_header() const; + + //-------------------------------------------------- +}; // class simple_config_variable_data_c + + +//-------------------------------------------------- + + +// +class EAP_EXPORT simple_config_payloads_c +: public abs_eap_core_map_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + /// This stores the simple_config_variable_data_c objects using eap_variable_data selector. + eap_core_map_c m_payload_map; + + /// This stores the same simple_config_variable_data_c objects to array. + /// This is to speed the sequential check of all payloads. + eap_array_c m_read_payloads; + + /// This index is used when payloads are retrieved in order. + u32_t m_payload_index; + + bool m_is_valid; + + eap_status_e verify_padding( + const u8_t * const possible_padding, + const u32_t possible_padding_length); + + eap_status_e get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + void * const data, + const u32_t data_length) const; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~simple_config_payloads_c(); + + EAP_FUNC_IMPORT simple_config_payloads_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT simple_config_variable_data_c * get_attribute_pointer( + const simple_config_Attribute_Type_e current_payload, + u32_t index) const; + + EAP_FUNC_IMPORT simple_config_variable_data_c * get_attribute_pointer( + const simple_config_Attribute_Type_e current_payload) const; + + + EAP_FUNC_IMPORT u32_t get_attribute_count() const; + + EAP_FUNC_IMPORT simple_config_variable_data_c * get_attribute(const u32_t attribute_index) const; + + /** + * This function adds new_payload object to payloads. + * NOTE the data is NOT copied. + */ + EAP_FUNC_IMPORT eap_status_e add_attribute( + simple_config_variable_data_c *new_payload); + + /** + * This function copies the selected attribute from source to payloads. + */ + EAP_FUNC_IMPORT eap_status_e copy_attribute( + const simple_config_payloads_c * const source, + const simple_config_Attribute_Type_e attribute); + + /** + * This function copies the attribute data to payloads. + */ + EAP_FUNC_IMPORT eap_status_e copy_attribute_data( + const simple_config_Attribute_Type_e current_payload, + const bool is_mandatory, + const void * const data, + const u32_t data_length); + + /** + * Function retrieves data of attribute type to data object. + */ + EAP_FUNC_IMPORT eap_status_e get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + eap_variable_data_c * const data) const; + + /** + * Function retrieves data of attribute type to data object. + */ + EAP_FUNC_IMPORT eap_status_e get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + u8_t * const data) const; + + /** + * Function retrieves data of attribute type to data object. + */ + EAP_FUNC_IMPORT eap_status_e get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + u16_t * const data) const; + + /** + * Function retrieves data of attribute type to data object. + */ + EAP_FUNC_IMPORT eap_status_e get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + u32_t * const data) const; + + /** + * Function retrieves data of attribute type to data object. + */ + EAP_FUNC_IMPORT eap_status_e get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + u64_t * const data) const; + + /** + * This function parses the payloads starting from specified payload (p_payload). + * Function parses all payloads from the buffer. + * Payloads are stored to member variables. + * @return If the length of the buffer and sum of the length of all payloads does not match + * function returns eap_status_header_corrupted. + * Also error is returned when illegal payload attribute is recognised. + */ + EAP_FUNC_IMPORT eap_status_e parse_simple_config_payloads( + void * const message_buffer, ///< This is the start of the message buffer. + u32_t * const buffer_length, ///< This is the length of the buffer. This must match with the length of all payloads. + u32_t * const padding_length ///< Length of possible padding is set to this variable. + ); + + /** + * This function parses each payload attributes. + * @return If payload attribute is illegal function returns eap_status_header_corrupted. + * If payload attribute is unknown function returns eap_status_unsupported_payload. + */ + EAP_FUNC_IMPORT eap_status_e parse_generic_payload( + const simple_config_Attribute_Type_e current_payload, ///< This is the type of current payload attribute. + const simple_config_tlv_header_c * const payload ///< This is the current parsed payload. + ); + + EAP_FUNC_IMPORT eap_status_e check_payloads_existense( + const simple_config_Attribute_Type_e * const needed_payloads, + const u32_t count_of_needed_payloads) const; + + /** + * This function checks all mandatory AVPs are used. + */ + EAP_FUNC_IMPORT eap_status_e check_mandatory_payloads( + EAP_TEMPLATE_CONST eap_array_c * const used_payloads) const; + + /** + * This function checks all required AVPs are received. + */ + EAP_FUNC_IMPORT eap_status_e check_payloads_existense( + EAP_TEMPLATE_CONST eap_array_c * const needed_payloads) const; + + EAP_FUNC_IMPORT bool get_is_valid() const; + + EAP_FUNC_IMPORT eap_status_e create_simple_config_message( + simple_config_message_c * const new_simple_config_message_data, + const bool add_payloads) const; + + EAP_FUNC_IMPORT eap_status_e add_payloads_to_simple_config_authenticator( + crypto_hmac_c * const hmac_sha_256, + const bool include_authenticator_attribute) const; + + EAP_FUNC_IMPORT eap_status_e reset(); + + EAP_FUNC_IMPORT simple_config_payloads_c * copy() const; + + //-------------------------------------------------- +}; // class simple_config_payloads_c + + +#endif //#if !defined(_SIMPLE_CONFIG_PAYLOADS_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_record.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_record.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,685 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_SIMPLE_CONFIG_RECORD_H_) +#define _SIMPLE_CONFIG_RECORD_H_ + + +#include "abs_simple_config_am_services.h" +#include "simple_config_base_record.h" +#include "eap_array_algorithms.h" +#include "simple_config_types.h" +#include "simple_config_completion.h" +#include "simple_config_types.h" +#include "simple_config_attribute_type.h" +#include "simple_config_payloads.h" +#include "simple_config_message.h" +#include "eap_am_network_id.h" +#include "eap_automatic_variable.h" +#include "eap_master_session_key.h" +#include "abs_eap_base_timer.h" + + +class abs_simple_config_base_record_c; +class abs_eap_am_tools_c; +class eap_am_network_id_c; +class simple_config_record_header_c; +class simple_config_am_services_c; +class abs_crypto_cbc_block_algorithm_c; +class abs_crypto_block_algorithm_c; +class abs_crypto_stream_algorithm_c; + +//-------------------------------------------------------------------- + +/** + * This is the timer ID used with abs_eap_am_tools_c::set_timer() and abs_eap_am_tools_c::cancel_timer(). + */ +enum simple_config_record_timer_id_e +{ + SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID, ///< This is timer ID after a Failure message is handled. + SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID, ///< This is timer ID after a M2D messages are used. +}; + + +enum simple_config_record_timer_timeouts_e +{ + /** + * This is time after a Failure message is handled. + */ + SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_TIMEOUT = 15000ul, +}; + + +//-------------------------------------------------------------------- + + +/** + * The simple_config_record_c class implements simple_config_base_record_c. + * See more detailed design and architecture document EAP_SIMPLE_CONFIG.doc + * and RFC 2246. + */ +class EAP_EXPORT simple_config_record_c +: public simple_config_base_record_c +, public abs_simple_config_am_services_c +, public abs_eap_base_timer_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to adaptation module of SIMPLE_CONFIG. + simple_config_am_services_c * m_am_simple_config_services; + + /// This flag tells whether the m_am_simple_config_services must be freed in destructor. + const bool m_free_am_simple_config_services; + + + /// This object includes pending asyncronous actions or it may be empty. + /// The check_sent_simple_config_message() function call will check and complete pending actions. + eap_array_c m_completion_queue; + + + /// This object stores all received M2D payloads. If nothing else is received + /// adaptation layer could show this information to user. + eap_array_c m_M2D_payloads; + + + /// This object includes received message. + simple_config_message_c m_received_simple_config_message; + + /// This object includes all received payloads. + simple_config_payloads_c m_received_payloads; + + + /// This object includes the previous sent message. + /// The send message will be generated from this. + simple_config_message_c m_previous_simple_config_message; + + /// This object includes the new created message. + /// The send message will be generated from this. + simple_config_message_c m_new_simple_config_message; + + /// This object cotains the type of the new message. + /// The type will be indicated to the lower layer for adding correct Op-Code. + simple_config_Message_Type_e m_current_simple_config_message_type; + + /// This object includes Enrollee Nonce. + eap_variable_data_c m_enrollee_nonce; + + /// This object includes Enrollee MAC. + eap_variable_data_c m_enrollee_mac; + + /// This object includes Registrar Nonce. + eap_variable_data_c m_registrar_nonce; + + + /// This object is the Simple Config device password. + eap_variable_data_c m_device_password; + + /// This object is the Simple Config PSK1. + eap_variable_data_c m_PSK1; + + /// This object is the Simple Config PSK2. + eap_variable_data_c m_PSK2; + + + /// This object is the Simple Config E-SNonce1 (E-S1). + eap_variable_data_c m_E_SNonce1; + + /// This object is the Simple Config E-SNonce2 (E-S2). + eap_variable_data_c m_E_SNonce2; + + /// This object is the Simple Config E-Hash1. + eap_variable_data_c m_EHash1; + + /// This object is the Simple Config E-Hash1. + eap_variable_data_c m_EHash2; + + + /// This object is the Simple Config R-SNonce1 (R-S1). + eap_variable_data_c m_R_SNonce1; + + /// This object is the Simple Config R-SNonce2 (R-S2). + eap_variable_data_c m_R_SNonce2; + + /// This object is the Simple Config R-Hash1. + eap_variable_data_c m_RHash1; + + /// This object is the Simple Config R-Hash1. + eap_variable_data_c m_RHash2; + + + /// This object includes Diffie-Hellman private key of this SIMPLE_CONFIG end point. + eap_variable_data_c m_own_private_dhe_key; + + /// This object includes Diffie-Hellman public key of this SIMPLE_CONFIG end point. + eap_variable_data_c m_own_public_dhe_key; + + /// This object includes Diffie-Hellman public key of other SIMPLE_CONFIG end point. + eap_variable_data_c m_peer_public_dhe_key; + + /// This object includes Diffie-Hellman shared key of the SIMPLE_CONFIG session. + eap_variable_data_c m_shared_dh_key; + + /// This object includes Diffie-Hellman prime of the SIMPLE_CONFIG session. + eap_variable_data_c m_dhe_prime; + + /// This object includes Diffie-Hellman group generator of the SIMPLE_CONFIG session. + eap_variable_data_c m_dhe_group_generator; + + /// This object includes Simple Config KDK. + eap_variable_data_c m_kdk; + + /// These are the additional keys of Simple Config. + eap_variable_data_c m_auth_key; + eap_variable_data_c m_key_wrap_key; + eap_variable_data_c m_EMSK; + + eap_variable_data_c m_SSID; + + /// This object includes signed HASH. This is needed to store asyncronously completed signature creation. + eap_variable_data_c m_signed_message_hash; + + /// This is the full NAI of the client. + eap_variable_data_c m_NAI; + + /// This is the realm part of the NAI of the client. + eap_variable_data_c m_NAI_realm; + + /// This is network identity of the sent packet from this authentication session. + eap_am_network_id_c m_send_network_id; + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + eap_variable_data_c m_network_key; + simple_config_Authentication_Type_e m_authentication_type; +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + /// This variable stored the internal state of SIMPLE_CONFIG-session. See simple_config_state_e. + simple_config_state_e m_simple_config_state; + + /// This variable stores the first error on handshake. + eap_status_e m_handshake_error; + + /// This object stores the universally unique identifier of Enrollee. + eap_variable_data_c m_UUID_E; + + /// This object stores the universally unique identifier of Registrar. + eap_variable_data_c m_UUID_R; + + /// These are the RF-Bands this entity supports. + simple_config_RF_Bands_e m_Rf_Bands; + + /// This object includes the MAC address of the new configuration. + eap_variable_data_c m_MAC_address; + + /// This variable stores the Device Password ID that this entity uses. + simple_config_Device_Password_ID_e m_local_Device_Password_ID; + + /// This variable stores the Device Password ID that other entity uses. + simple_config_Device_Password_ID_e m_received_Device_Password_ID; + + /// This object stores the new password the Enrollee should use. This is optional. + eap_variable_data_c m_new_password; + + /// This object stores the new Device Password ID the Enrollee should use. This is optional. + simple_config_Device_Password_ID_e m_new_Device_Password_ID; + + /// This is the timeout in milli seconds after the error message is processed. + /// This allows correct message to be processed before session is terminated. + u32_t m_error_message_received_timeout; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This indicates whether this object is client (true) or server (false). + const bool m_is_client; + + /// This flag tells whether messages could be send in the check_sent_simple_config_message() function. + bool m_allow_message_send; + + /// This flag prevents recursive calls of the completion_action_check() function. + bool m_already_in_completion_action_check; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_query_network_and_device_parameters; + + /// This flag tells whether this instance is test version (true) or real version (false). + /// Test version allows many subsequent SIMPLE_CONFIG-sessions. + bool m_simple_config_test_version; + + /// The flag prevents multiple call of generate_key_material() function. + bool m_key_material_generated; + + /// This flag tells whether the check_sent_simple_config_message() must send SIMPLE_CONFIG-alert message (true) or not (false). + /// This flag is set after the SIMPLE_CONFIG-alert message is generated. This flag forses send of the SIMPLE_CONFIG-alert message. + bool m_force_simple_config_message_send; + + /// This flag tells whether the shutdown() function was called (true) or not (false). + bool m_shutdown_was_called; + + /// This flag tells whether the SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID timeout is active (true) or not (false). + bool m_M2D_received_timeout_active; + + //-------------------------------------------------- + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + + EAP_FUNC_IMPORT eap_status_e add_common_attributes( + simple_config_payloads_c * const payloads, + const simple_config_Message_Type_e message_type, + const bool add_enrollee_nonce, + const bool add_registrar_nonce); + + + EAP_FUNC_IMPORT eap_status_e send_M1( + const simple_config_payloads_c * const network_and_device_parameters); + + EAP_FUNC_IMPORT eap_status_e send_M3(); + + EAP_FUNC_IMPORT eap_status_e send_M5(); + + EAP_FUNC_IMPORT eap_status_e send_M7(); + + EAP_FUNC_IMPORT eap_status_e send_WSC_ACK(); + + EAP_FUNC_IMPORT eap_status_e send_WSC_NACK(); + + EAP_FUNC_IMPORT eap_status_e send_WSC_Done(); + + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + EAP_FUNC_IMPORT eap_status_e send_M2( + const simple_config_payloads_c * const network_and_device_parameters); + + EAP_FUNC_IMPORT eap_status_e send_M2D( + const simple_config_payloads_c * const network_and_device_parameters); + + EAP_FUNC_IMPORT eap_status_e send_M4(); + + EAP_FUNC_IMPORT eap_status_e send_M6(); + + EAP_FUNC_IMPORT eap_status_e send_M8(); + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + + EAP_FUNC_IMPORT eap_status_e process_M2( + const simple_config_payloads_c * const payloads); + + EAP_FUNC_IMPORT eap_status_e process_M2D( + const simple_config_payloads_c * const payloads); + + EAP_FUNC_IMPORT eap_status_e process_M4( + const simple_config_payloads_c * const payloads); + + EAP_FUNC_IMPORT eap_status_e process_M6( + const simple_config_payloads_c * const payloads); + + EAP_FUNC_IMPORT eap_status_e process_M8( + const simple_config_payloads_c * const payloads); + + EAP_FUNC_IMPORT eap_status_e process_WSC_ACK( + const simple_config_payloads_c * const payloads); + + EAP_FUNC_IMPORT eap_status_e process_WSC_NACK( + const simple_config_payloads_c * const payloads); + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + EAP_FUNC_IMPORT eap_status_e process_M1( + const simple_config_payloads_c * const payloads); + + EAP_FUNC_IMPORT eap_status_e process_M3( + const simple_config_payloads_c * const payloads); + + EAP_FUNC_IMPORT eap_status_e process_M5( + const simple_config_payloads_c * const payloads); + + EAP_FUNC_IMPORT eap_status_e process_M7( + const simple_config_payloads_c * const payloads); + + EAP_FUNC_IMPORT eap_status_e process_WSC_DONE( + const simple_config_payloads_c * const payloads); + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + EAP_FUNC_IMPORT void send_error_notification(const eap_status_e error); + + + /** + * This function processes received SIMPLE_CONFIG attributes. + */ + EAP_FUNC_IMPORT eap_status_e process_simple_config_attributes( + const simple_config_payloads_c * const payloads); + + /** + * This function processes received SIMPLE_CONFIG message. + */ + EAP_FUNC_IMPORT eap_status_e process_simple_config_message(); + + + /** + * This function initialises timeout for received erroneous message. + * If no correct message is received before this timeout the authentication + * is terminated. + */ + EAP_FUNC_IMPORT eap_status_e initalize_error_message_timeout(); + + /** + * This function cancels timeout for received erroneous message. + */ + EAP_FUNC_IMPORT eap_status_e cancel_error_message_timeout(); + + + EAP_FUNC_IMPORT eap_status_e initialize_M2D_received_timeout(); + + EAP_FUNC_IMPORT eap_status_e cancel_M2D_received_timeout(); + + + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, + void * data); + + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, + void * data); + + /** + * This function verifies the Authenticator of received SIMPLE_CONFIG message. + */ + EAP_FUNC_IMPORT eap_status_e verify_nonces_and_authenticator( + const eap_variable_data_c * const auth_key, + const eap_variable_data_c * const registrar_nonce, + const eap_variable_data_c * const enrollee_nonce, + const simple_config_payloads_c * const payloads, + const bool check_enrollee_nonce, + const bool check_registrar_nonce, + const bool check_authenticator); + + /** + * This function checks whether all pending queries are completed. + */ + EAP_FUNC_IMPORT eap_status_e are_pending_queries_completed(); + + /** + * This function indicates state to lower layer. + */ + EAP_FUNC_IMPORT eap_status_e indicate_state_to_lower_layer( + const simple_config_state_e indicated_state); + + /** + * This function indicates all message processed to lower layer. + */ + EAP_FUNC_IMPORT eap_status_e indicate_messages_processed(); + + /** + * This function combines SIMPLE_CONFIG-protocols data to a buffer and sends SIMPLE_CONFIG-message. + */ + EAP_FUNC_IMPORT eap_status_e send_simple_config_message(); + + /** + * This function checks all queries are completed. + * If all queries are completed this function send the pending LS-messages. + */ + EAP_FUNC_IMPORT eap_status_e check_sent_simple_config_message(); + + /** + * This function generates ephemeral Diffie-Hellman keys. + * Keys are stored to m_own_private_dhe_key and m_own_public_dhe_key. + */ + EAP_FUNC_IMPORT eap_status_e generate_dhe_keys(); + + /** + * This function generates ephemeral Diffie-Hellman shared secret. + * Shared secret is stored to dhe_shared_secret. + */ + EAP_FUNC_IMPORT eap_status_e generate_dhe_shared_secret( + const eap_variable_data_c * const registrar_public_key_data, + eap_variable_data_c * const dhe_shared_secret); + + EAP_FUNC_IMPORT eap_status_e generate_nonce( + eap_variable_data_c * const nonce, + const u32_t nonce_length); + + EAP_FUNC_IMPORT eap_status_e generate_erhash( + const bool verify, + const eap_variable_data_c * const half_of_device_password, + const eap_variable_data_c * const PKE, + const eap_variable_data_c * const PKR, + eap_variable_data_c * const PSKn, + eap_variable_data_c * const ERSn, + eap_variable_data_c * const ERHash); + + EAP_FUNC_IMPORT eap_status_e generate_er_hashs( + const bool verify, + const eap_variable_data_c * const device_password, + const eap_variable_data_c * const PKE, + const eap_variable_data_c * const PKR, + eap_variable_data_c * const PSK1, + eap_variable_data_c * const ER_S1, + eap_variable_data_c * const ER_Hash1, + eap_variable_data_c * const PSK2, + eap_variable_data_c * const ER_S2, + eap_variable_data_c * const ER_Hash2); + + + EAP_FUNC_IMPORT eap_status_e keyed_hmac( + const eap_variable_data_c * const key, + const eap_variable_data_c * const input, + eap_variable_data_c * const output); + + /** + * This function generates KDK of Simple Config. + */ + EAP_FUNC_IMPORT eap_status_e generate_kdk( + const eap_variable_data_c * const dhe_shared_secret, + const eap_variable_data_c * const nonce_1, + const eap_variable_data_c * const enrollee_mac, + const eap_variable_data_c * const nonce_2, + eap_variable_data_c * const kdk); + + /** + * This is key derivation function of Simple Config. + */ + EAP_FUNC_IMPORT eap_status_e key_derivation_function( + const eap_variable_data_c * const key, + const eap_variable_data_c * const personalization_string, + const u32_t total_key_bits, + eap_variable_data_c * const result); + + /** + * This function derives additional keys of Simple Config. + */ + EAP_FUNC_IMPORT eap_status_e derive_additional_keys( + const eap_variable_data_c * const kdk, + eap_variable_data_c * const auth_key, + eap_variable_data_c * const key_wrap_key, + eap_variable_data_c * const EMSK); + + EAP_FUNC_IMPORT eap_status_e generate_authenticator( + const eap_variable_data_c * const received_simple_config_message, + const eap_variable_data_c * const new_simple_config_message_data, + eap_variable_data_c * const authenticator); + + EAP_FUNC_IMPORT eap_status_e add_authenticator_attribute( + simple_config_message_c * const received_simple_config_message, + simple_config_message_c * const new_simple_config_message); + + EAP_FUNC_IMPORT eap_status_e encrypt_payloads( + const eap_variable_data_c * const auth_key, + const eap_variable_data_c * const key_wrap_key, + simple_config_payloads_c * const plaintext_payloads, + simple_config_variable_data_c * const encrypted_settings); + + EAP_FUNC_IMPORT eap_status_e decrypt_payloads( + const eap_variable_data_c * const auth_key, + const eap_variable_data_c * const key_wrap_key, + simple_config_variable_data_c * const encrypted_settings, + simple_config_payloads_c * const plaintext_payloads); + + /** + * This function adds new completion action to the end of the m_completion_queue. + */ + EAP_FUNC_IMPORT eap_status_e completion_action_add( + simple_config_completion_action_e action); + + /** + * This function verifies all completion actions are completed. + */ + EAP_FUNC_IMPORT eap_status_e completion_action_clenup(); + + /** + * This function checks and completes completion actions. + * This function could return eap_status_pending_request if the + * first completion action cannot be completed yet. + */ + EAP_FUNC_IMPORT eap_status_e completion_action_check(); + + /** + * This function sets the state of SIMPLE_CONFIG. + */ + EAP_FUNC_IMPORT simple_config_state_e get_state() const; + + /** + * This function gets the state of SIMPLE_CONFIG. + */ + EAP_FUNC_IMPORT void set_state(const simple_config_state_e state); + + /** + * This function verified the current state of SIMPLE_CONFIG and parameter state are equal. + */ + EAP_FUNC_IMPORT bool verify_state(const simple_config_state_e state); + + eap_status_e fix_incorrect_network_key( + eap_variable_data_c * const network_key, + const simple_config_Authentication_Type_e authentication_type); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the simple_config_record_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~simple_config_record_c(); + + /** + * The constructor of the simple_config_record_c class simply initializes the attributes. + * The simple_config_record_c object sends packets to the network using simple_config_base_record_c::get_type_partner() object. + */ + EAP_FUNC_IMPORT simple_config_record_c( + abs_eap_am_tools_c * const tools, ///< tools is pointer to the tools class. @see abs_eap_am_tools_c. + simple_config_am_services_c * const am_simple_config_services, ///< This is pointer to adaoptation module of SIMPLE_CONFIG. + const bool free_am_simple_config_services, + const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false). + const eap_am_network_id_c * const receive_network_id); + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + */ + EAP_FUNC_IMPORT eap_status_e configure(); + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + EAP_FUNC_IMPORT eap_status_e shutdown(); + + /** + * This function sets the NAI realm. + */ + EAP_FUNC_IMPORT eap_status_e set_nai_realm( + const eap_variable_data_c * const NAI_realm ///< This is the full NAI realm. + ); + + // This is commented in abs_simple_config_base_application_c. + EAP_FUNC_IMPORT eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // This is commented in abs_simple_config_base_application_c. + EAP_FUNC_IMPORT eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /** + * This function sends starts EAP-SIMPLE_CONFIG/PEAP after a start message is received. + */ + EAP_FUNC_IMPORT eap_status_e start_simple_config_authentication( + const eap_variable_data_c * const NAI ///< This is the full NAI of the client. + ); + + /** + * This function processes the received packet. + * @param simple_config_packet includes the buffer of the whole reassembled SIMPLE_CONFIG-packet. + */ + EAP_FUNC_IMPORT eap_status_e packet_process( + eap_variable_data_c * const simple_config_packet, + const u8_t received_eap_identifier); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function must reset the state of object to same as + * state was after the configure() function call. + * If object reset succeeds this function must return eap_status_ok. + * If object reset fails this function must return corresponding error status. + * @return This function returns the status of reset operation. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + // This is commented in abs_simple_config_am_services_c::complete_query_network_and_device_parameters(). + EAP_FUNC_IMPORT eap_status_e complete_query_network_and_device_parameters( + const simple_config_state_e state, + simple_config_payloads_c * const network_and_device_parameters, + const eap_status_e completion_status); + + //-------------------------------------------------- +}; // class simple_config_record_c + +#endif //#if !defined(_SIMPLE_CONFIG_RECORD_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_tlv_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_tlv_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,198 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_SIMPLE_CONFIG_TLV_HEADER_H_) +#define _SIMPLE_CONFIG_TLV_HEADER_H_ + +#include "eap_tools.h" +#include "eap_general_header_base.h" +#include "simple_config_attribute_type.h" + +/** @file */ + + +//---------------------------------------------------------------------------- + + +/// This class defines header of Attribute-Value Pairs. +/** + * Here is a figure of header of Attribute-Value Pairs. + * Value data follows simple_config_tlv_header_c. + * @code + * TLV-header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Attribute Type | Data Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Data ... + * +-+-+-+-+-+-+-+-+-+- + * @endcode + * + * @code + * The fields of this header are: + * 16-bits Attribute Type This is a TLV type. + * 16-bits Data Length; This is a length field, the length (in bytes) of the following Data. + * @endcode + */ +class EAP_EXPORT simple_config_tlv_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + /// This is enumeration of offsets to data fields. + enum offsets + { + m_tlv_type_offset = 0ul, ///< This is offset to fags and tlv type 16-bit field. + m_length_offset = m_tlv_type_offset+sizeof(u16_t), ///< This is offset to length 16-bit field. + m_data_offset = m_length_offset+sizeof(u16_t), ///< This is offset to data field. + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the simple_config_tlv_header_c class does nothing. + */ + virtual ~simple_config_tlv_header_c(); + + /** + * The constructor of the simple_config_tlv_header_c class simply initializes the attributes. + */ + simple_config_tlv_header_c( + abs_eap_am_tools_c * const tools); + + /** + * The constructor of the simple_config_tlv_header_c class simply initializes the attributes. + */ + simple_config_tlv_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length); + + /** + * This function returns the TLV type flag. + */ + simple_config_Attribute_Type_e get_tlv_type() const; + + /** + * This function returns the length of TLV (header+data). + */ + u32_t get_length() const; + + /** + * This function returns the data length of TLV. + */ + u16_t get_data_length() const; + + /** + * This function returns the header length of TLV. + */ + static u32_t get_header_length(); + + /** + * This function returns pointer to the offset of data of TLV. + * @param offset is the offset of queried data in bytes. + * @param contignuous_bytes is the length of queried data in bytes. + */ + u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + + /** + * This function returns pointer to the offset of data of TLV. + * @param contignuous_bytes is the length of queried data in bytes. + */ + u8_t * get_data(const u32_t contignuous_bytes) const; + + + /** + * This function return pointer to the next TLV header in the same buffer. + */ + u8_t * get_next_header() const; + + + /** + * This function checks the header is valid. + */ + eap_status_e check_header() const; + + /** + * This function returns debug strings of the TLV type. + */ + eap_const_string get_tlv_type_string() const; + + /** + * This function sets the TLV type flag. + */ + void set_tlv_type(simple_config_Attribute_Type_e type); + + /** + * This function sets the TLV data length. + */ + void set_data_length(const u16_t p_length); + + /** + * This function resets the TLV header. + */ + void reset_header(const u16_t buffer_length); + + // + //-------------------------------------------------- +}; // class simple_config_tlv_header_c + + +//-------------------------------------------------- + +/// Macro traces payload type and data. +#define SIMPLE_CONFIG_TLV_TRACE_PAYLOAD(prefix, payload) \ + { \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n"))); \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- %s (0x%08x): TLV type 0x%08x=%s, data length 0x%04x.\n"), \ + prefix, (payload)->get_header_buffer((payload)->get_length()), \ + (payload)->get_tlv_type(), \ + (payload)->get_tlv_type_string(), (payload)->get_data_length())); \ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- data"), (payload)->get_data((payload)->get_data_length()), \ + (payload)->get_data_length())); \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n"))); \ + } + +//-------------------------------------------------- + +#endif //#if !defined(_SIMPLE_CONFIG_TLV_HEADER_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/include/simple_config_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,439 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_SIMPLE_CONFIG_TYPES_H_) +#define _SIMPLE_CONFIG_TYPES_H_ + +#include "eap_buffer.h" +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "eap_type_all_types.h" +#include "eap_configuration_field.h" +#include "simple_config_attribute_type.h" + +/** @file simple_config_types.h + * @brief This file defines the constants of the SIMPLE_CONFIG. + */ + +//-------------------------------------------------- + +enum simple_config_Authentication_Type_e +{ + simple_config_Authentication_Type_None = 0x0000, + simple_config_Authentication_Type_Open = 0x0001, + simple_config_Authentication_Type_WPAPSK = 0x0002, + simple_config_Authentication_Type_Shared = 0x0004, + simple_config_Authentication_Type_WPA = 0x0008, + simple_config_Authentication_Type_WPA2 = 0x0010, + simple_config_Authentication_Type_WPA2PSK = 0x0020, +}; + +enum simple_config_Encryption_Type_e +{ + simple_config_Encryption_Type_None = 0x0001, + simple_config_Encryption_Type_WEP = 0x0002, + simple_config_Encryption_Type_TKIP = 0x0004, + simple_config_Encryption_Type_AES = 0x0008, +}; + +enum simple_config_Connection_Type_e +{ + simple_config_Connection_Type_ESS = 0x0001, + simple_config_Connection_Type_IBSS = 0x0002, +}; + +enum simple_config_Config_Methods_e +{ + simple_config_Config_Methods_USBA = 0x0001, + simple_config_Config_Methods_Ethernet = 0x0002, + simple_config_Config_Methods_Label = 0x0004, + simple_config_Config_Methods_Display = 0x0008, + simple_config_Config_Methods_External_NFC_Token = 0x0010, + simple_config_Config_Methods_Integrated_NFC_Token = 0x0020, + simple_config_Config_Methods_NFC_Interface = 0x0040, + simple_config_Config_Methods_PushButton = 0x0080, + simple_config_Config_Methods_Keypad = 0x0100, +}; + +enum simple_config_State_e +{ + simple_config_State_Not_Configured = 0x0001, + simple_config_State_Configured = 0x0002, +}; + +enum simple_config_RF_Bands_e +{ + simple_config_RF_Bands_2_4_GHz = 1, + simple_config_RF_Bands_5_0_GHz = 2, +}; + +enum simple_config_Association_State_e +{ + simple_config_Association_State_Not_Associated = 0, + simple_config_Association_State_Connection_Success = 1, + simple_config_Association_State_Configuration_Failure = 2, + simple_config_Association_State_Association_Failure = 3, + simple_config_Association_State_IP_Failure = 4, +}; + +enum simple_config_Device_Password_ID_e +{ + simple_config_Device_Password_ID_Default_PIN = 0, + simple_config_Device_Password_ID_User_specified = 1, + simple_config_Device_Password_ID_Machine_specified = 2, + simple_config_Device_Password_ID_Rekey = 3, + simple_config_Device_Password_ID_PushButton = 4, + simple_config_Device_Password_ID_Registrar_specified = 5, +}; + +enum simple_config_Configuration_Error_e +{ + simple_config_Configuration_Error_No_Error = 0, + simple_config_Configuration_Error_OOB_Interface_Read_Error = 1, + simple_config_Configuration_Error_Decryption_CRC_Failure = 2, + simple_config_Configuration_Error_2_4_channel_not_supported = 3, + simple_config_Configuration_Error_5_0_channel_not_supported = 4, + simple_config_Configuration_Error_Signal_too_weak = 5, + simple_config_Configuration_Error_Network_auth_failure = 6, + simple_config_Configuration_Error_Network_association_failure = 7, + simple_config_Configuration_Error_No_DHCP_response = 8, + simple_config_Configuration_Error_Failed_DHCP_config = 9, + simple_config_Configuration_Error_IP_address_conflict = 10, + simple_config_Configuration_Error_Couldnt_connect_to_Registrar = 11, + simple_config_Configuration_Error_Multiple_PBC_sessions_detected = 12, + simple_config_Configuration_Error_Rogue_activity_suspected = 13, + simple_config_Configuration_Error_Device_busy = 14, + simple_config_Configuration_Error_Setup_locked = 15, + simple_config_Configuration_Error_Message_Timeout = 16, + simple_config_Configuration_Error_Registration_Session_Timeout = 17, + simple_config_Configuration_Error_Device_Password_Auth_Failure = 18, +}; + +enum simple_config_Message_Type_e +{ + simple_config_Message_Type_None = 0x00, + simple_config_Message_Type_Beacon = 0x01, + simple_config_Message_Type_Probe_Request = 0x02, + simple_config_Message_Type_Probe_Response = 0x03, + simple_config_Message_Type_M1 = 0x04, + simple_config_Message_Type_M2 = 0x05, + simple_config_Message_Type_M2D = 0x06, + simple_config_Message_Type_M3 = 0x07, + simple_config_Message_Type_M4 = 0x08, + simple_config_Message_Type_M5 = 0x09, + simple_config_Message_Type_M6 = 0x0A, + simple_config_Message_Type_M7 = 0x0B, + simple_config_Message_Type_M8 = 0x0C, + simple_config_Message_Type_WSC_ACK = 0x0D, + simple_config_Message_Type_WSC_NACK = 0x0E, + simple_config_Message_Type_WSC_DONE = 0x0F, + simple_config_Message_keep_this_last = simple_config_Message_Type_WSC_DONE, +}; + +//-------------------------------------------------- + +/// Macro traces payload type and data. +#define EAP_SIMPLE_CONFIG_TRACE_PAYLOAD(prefix, payload) \ + { \ + EAP_TRACE_DEBUG( \ + m_am_tools, \ + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("%s (0x%08x): current payload 0x%04x=%s, data length 0x%04x.\n"), \ + prefix, (payload), (payload)->get_flag_tlv_type(), \ + (payload)->get_tlv_type_string(), (payload)->get_data_length())); \ + EAP_TRACE_DATA_DEBUG( \ + m_am_tools, \ + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("payload"), \ + (payload)->get_header_buffer( \ + (payload)->get_header_length()+(payload)->get_data_length()), \ + (payload)->get_header_length()+(payload)->get_data_length())); \ + } + +//-------------------------------------------------- + +/** + * This is the size of the local send buffer. + */ + +/** + * This is the default trace mask for SIMPLE_CONFIG and PEAP. + */ +const u32_t TRACE_FLAGS_SIMPLE_CONFIG_ERROR = eap_am_tools_c::eap_trace_mask_error; + + +enum simple_config_protocol_field_size_e +{ + SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH = EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH, + SIMPLE_CONFIG_ENROLLEE_NONCE_SIZE = 16UL * sizeof(u8_t), + SIMPLE_CONFIG_REGISTRAR_NONCE_SIZE = SIMPLE_CONFIG_ENROLLEE_NONCE_SIZE, + SIMPLE_CONFIG_AUTH_KEY_BITS = 256ul, + SIMPLE_CONFIG_KEY_WRAP_KEY_BITS = 128ul, + SIMPLE_CONFIG_EMSK_BITS = 256ul, + SIMPLE_CONFIG_AUTHENTICATOR_LENGTH = 8ul, + SIMPLE_CONFIG_PSKn_LENGTH = 16ul, + SIMPLE_CONFIG_ESn_LENGTH = 16ul, + SIMPLE_CONFIG_KEY_WRAP_IV_SIZE = 16ul, +}; + +/** + * This is the Diffie Hellman Prime of the SIMPLE_CONFIG. + */ +const u8_t SIMPLE_CONFIG_DIFFIE_HELLMAN_PRIME[] + = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + + }; + +/** + * This is the Diffie Hellman Prime of the SIMPLE_CONFIG. + */ +const u8_t SIMPLE_CONFIG_DIFFIE_HELLMAN_GROUP_GENERATOR[] + = { 0x02 }; + + +const u8_t SIMPLE_CONFIG_VERSION = 0x10; + +const u8_t SIMPLE_CONFIG_DEFAULT_NETWORK_KEY_INDEX = 1ul; + +/** + * This is the label of the SIMPLE_CONFIG-premaster secret. + * See Chapter "8.1. Computing the master secret" in RFC 2246. + */ +const u8_t SIMPLE_CONFIG_SECURE_KEY_DERIVATION_LABEL[] = "Wi-Fi Easy and Secure Key Derivation"; + +/** + * This is the length of the label of the SIMPLE_CONFIG-premaster secret. + */ +const u32_t SIMPLE_CONFIG_SECURE_KEY_DERIVATION_LABEL_LENGTH = sizeof(SIMPLE_CONFIG_SECURE_KEY_DERIVATION_LABEL)-1ul; + + +const u32_t EAP_SIMPLE_CONFIG_MASTER_SESSION_KEY_SIZE = 128ul; + + +/** + * This is the PCB device password PIN used in PushButton mode. + */ +const u8_t SIMPLE_CONFIG_PBC_DEVICE_PASSWORD_PIN[] + = { + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + }; + +/** + * This is the size of the PCB device password PIN used in PushButton mode. + */ +const u32_t SIMPLE_CONFIG_PBC_DEVICE_PASSWORD_PIN_SIZE = sizeof(SIMPLE_CONFIG_PBC_DEVICE_PASSWORD_PIN); + + +/** + * This is the length of the RC4 key used in SIMPLE_CONFIG. + */ +const u32_t SIMPLE_CONFIG_RC4_128_KEY_LENGTH = 16ul; + +/** + * This is the length of the RC4 initialization vector used in SIMPLE_CONFIG. + */ +const u32_t SIMPLE_CONFIG_RC4_128_IV_LENGTH = 0ul; + + +/** + * These are the internal SIMPLE_CONFIG-states. + */ +enum simple_config_state_e +{ + simple_config_state_none, ///< Initialization value. + simple_config_state_wait_simple_config_start, ///< Waits start of SIMPLE_CONFIG. + simple_config_state_process_simple_config_start, + simple_config_state_wait_M1, + simple_config_state_process_M1, + simple_config_state_wait_M2, + simple_config_state_wait_M3, + simple_config_state_wait_M4, + simple_config_state_wait_M5, + simple_config_state_wait_M6, + simple_config_state_wait_M7, + simple_config_state_wait_M8, + simple_config_state_wait_WSC_ACK, + simple_config_state_wait_WSC_NACK, + simple_config_state_wait_WSC_DONE, + simple_config_state_pending_simple_config_messages_processed, ///< This is indication to lower layer that pending SIMPLE_CONFIG-messages are processed, new messages could be accepted.. + simple_config_state_simple_config_success, ///< SIMPLE_CONFIG authentication success. + simple_config_state_failure, ///< Authentication failure. +}; + +//---------------------------------------------------------------------------- + +class EAP_EXPORT network_key_and_index_c +{ + +private: + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + u8_t m_network_key_index; + + eap_variable_data_c m_network_key; + + bool m_is_valid; + +public: + + EAP_FUNC_IMPORT virtual ~network_key_and_index_c(); + + EAP_FUNC_IMPORT network_key_and_index_c( + abs_eap_am_tools_c * const m_am_tools); + + EAP_FUNC_IMPORT u8_t get_network_key_index(); + + EAP_FUNC_IMPORT void set_network_key_index(u8_t index); + + EAP_FUNC_IMPORT eap_variable_data_c * get_network_key(); + + EAP_FUNC_IMPORT network_key_and_index_c * copy(); + + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT bool get_is_valid_data(); +}; + +//---------------------------------------------------------------------------- + +/** + * @defgroup SIMPLE_CONFIG_config_options Configuration options of SIMPLE_CONFIG. + * The following configuration options are read through abs_eap_base_type_c::read_configure() function. + * @{ + */ + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_UUID_E, + "SIMPLE_CONFIG_UUID_E", + eap_configure_type_hex_data, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_UUID_R, + "SIMPLE_CONFIG_UUID_R", + eap_configure_type_hex_data, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_SSID, + "SIMPLE_CONFIG_SSID", + eap_configure_type_hex_data, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_MAC_address, + "SIMPLE_CONFIG_MAC_address", + eap_configure_type_hex_data, + false); + + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_Device_Password_ID, + "SIMPLE_CONFIG_Device_Password_ID", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_server_Device_Password_ID, + "SIMPLE_CONFIG_server_Device_Password_ID", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_Device_Password_ID_PIN, + "PIN", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_SIMPLE_CONFIG_Device_Password_ID_PushButton, + "PushButton", + eap_configure_type_string, + false); + +/** @} */ // End of group SIMPLE_CONFIG_config_options. +//-------------------------------------------------------------------- + + +/// This class includes the debug strings of the simple_config_cipher_suites_e, simple_config_certificate_type_e and simple_config_compression_method_e. +class EAP_EXPORT eap_simple_config_trace_string_c +{ +public: + + EAP_FUNC_IMPORT virtual ~eap_simple_config_trace_string_c(); + + EAP_FUNC_IMPORT eap_simple_config_trace_string_c(); + + /** + * Function returns string of simple_config_state_e. + * @param state is the queried string. + */ + EAP_FUNC_IMPORT eap_const_string get_state_string(const simple_config_state_e state) const; + + /** + * Function returns string of simple_config_Message_Type_e. + * @param type is the queried string. + */ + EAP_FUNC_IMPORT eap_const_string get_message_type_string(const simple_config_Message_Type_e type) const; + + /** + * Function returns string of simple_config_Attribute_Type_e. + * @param type is the queried string. + */ + EAP_FUNC_IMPORT eap_const_string get_attribute_type_string(const simple_config_Attribute_Type_e type) const; + +}; + + +//-------------------------------------------------- + +#endif //#if !defined(_SIMPLE_CONFIG_TYPES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,26 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_simple_config + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_base_record.cpp \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_completion.cpp \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_credential.cpp \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_message.cpp \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_payloads.cpp \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_record.cpp \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_tlv_header.cpp \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_types.cpp \ + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_simple_config_tools.$(LIB) \ + -lstdc++ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_base_record.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_base_record.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 594 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "simple_config_base_record.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_base_record_c::~simple_config_base_record_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + // Does nothing. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_base_record_c::simple_config_base_record_c( + abs_eap_am_tools_c * const tools) + : m_type_partner(0) + , m_am_tools(tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + // Does nothing. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_base_record_c::set_type_partner(abs_simple_config_base_record_c * const partner) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_type_partner = partner; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT abs_simple_config_base_record_c * simple_config_base_record_c::get_type_partner() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_type_partner; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_completion.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_completion.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,121 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 595 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_tools.h" +#include "eap_array.h" +#include "simple_config_completion.h" +#include "simple_config_types.h" + +/** @file */ + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_completion_c::~simple_config_completion_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_completion_c::simple_config_completion_c( + abs_eap_am_tools_c * const tools, + simple_config_completion_action_e completion_action) +: m_am_tools(tools) +, m_completion_action(completion_action) +, m_is_valid(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_completion_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool simple_config_completion_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_completion_c::set_completion_action(simple_config_completion_action_e completion_action) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_completion_action = completion_action; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_completion_action_e simple_config_completion_c::get_completion_action() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_completion_action; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string simple_config_completion_c::get_completion_action_string() const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(m_completion_action, simple_config_completion_action_none) + else EAP_IF_RETURN_STRING(m_completion_action, simple_config_completion_action_process_simple_config_attributes) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown completion_action"); + } +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_credential.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_credential.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#include "eap_tools.h" +#include "simple_config_credential.h" + +/** @file */ + + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_credential_c::~simple_config_credential_c() +{ +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_credential_c::simple_config_credential_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_network_index(1ul) + , m_SSID(tools) + , m_Authentication_Type(simple_config_Authentication_Type_None) + , m_Encryption_Type(simple_config_Encryption_Type_None) + , m_network_keys(tools) + , m_MAC_address(tools) + , m_is_valid(false) +{ + if (m_SSID.get_is_valid() == false) + { + return; + } + + if (m_MAC_address.get_is_valid() == false) + { + return; + } + + m_is_valid = true; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_credential_c::set_network_index(const u8_t index) +{ + m_network_index = index; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT u8_t simple_config_credential_c::get_network_index() +{ + return m_network_index; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * simple_config_credential_c::get_SSID() +{ + return &m_SSID; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_Authentication_Type_e simple_config_credential_c::get_Authentication_Type() +{ + return m_Authentication_Type; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_credential_c::set_Authentication_Type(const simple_config_Authentication_Type_e Authentication_Type) +{ + m_Authentication_Type = Authentication_Type; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_Encryption_Type_e simple_config_credential_c::get_Encryption_Type() +{ + return m_Encryption_Type; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_credential_c::set_Encryption_Type(const simple_config_Encryption_Type_e Encryption_Type) +{ + m_Encryption_Type = Encryption_Type; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_array_c * simple_config_credential_c::get_network_keys() +{ + return &m_network_keys; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * simple_config_credential_c::get_MAC_address() +{ + return &m_MAC_address; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT bool simple_config_credential_c::get_is_valid() +{ + return m_is_valid; +} + +//---------------------------------------------------------------------------- +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_message.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_message.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,158 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 596 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_array.h" +#include "simple_config_message.h" +#include "simple_config_types.h" + +/** @file */ + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_message_c::~simple_config_message_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_message_c::simple_config_message_c( + abs_eap_am_tools_c * const tools, + const bool is_client) + : m_am_tools(tools) + , m_simple_config_message_data(tools) + , m_received_eap_identifier(0ul) + , m_is_client(is_client) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_message_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_received_eap_identifier = 0ul; + + eap_status_e status = m_simple_config_message_data.reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_message_c::set_simple_config_message_data( + eap_variable_data_c * const simple_config_message_data, + u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_simple_config_message_data.set_copy_of_buffer(simple_config_message_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_received_eap_identifier = received_eap_identifier; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * simple_config_message_c::get_simple_config_message_data() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_simple_config_message_data; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_message_c::add_padding(const u32_t block_size) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; + + u32_t data_length = m_simple_config_message_data.get_data_length(); + u32_t remaining_bytes = data_length % block_size; + + { + const u32_t padding_length = block_size - remaining_bytes; + + status = m_simple_config_message_data.set_buffer_length(data_length + padding_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_simple_config_message_data.set_data_length(data_length + padding_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u8_t padding_byte = static_cast(padding_length); + + m_am_tools->memset(m_simple_config_message_data.get_data_offset(data_length, padding_length), padding_byte, padding_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_message_c::add_padding(): %d bytes\n"), + (m_is_client == true ? "client": "server"), + padding_length)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool simple_config_message_c::get_is_valid() +{ + return m_simple_config_message_data.get_is_valid(); +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_payloads.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_payloads.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1361 @@ +/* +* Copyright (c) 2001-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 589 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "simple_config_payloads.h" +#include "simple_config_tlv_header.h" +#include "simple_config_message.h" +#include "abs_eap_am_tools.h" +#include "eap_tools.h" +#include "eap_array_algorithms.h" +#include "eap_automatic_variable.h" +#include "eap_crypto_api.h" + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_variable_data_c::~simple_config_variable_data_c() +{ + delete m_next_payload_with_same_attribute_type; + m_next_payload_with_same_attribute_type = 0; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_variable_data_c::simple_config_variable_data_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_data(tools) + , m_header(tools, 0, 0ul) + , m_next_payload_with_same_attribute_type(0) + , m_is_mandatory(false) + , m_is_valid(false) +{ + if (m_data.get_is_valid() == false) + { + return; + } + + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool simple_config_variable_data_c::get_is_valid() const +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_variable_data_c::set_copy_of_buffer( + const simple_config_Attribute_Type_e current_payload, + const bool is_mandatory, + const void * const buffer, + const u32_t buffer_length) +{ + eap_status_e status = m_data.set_buffer_length( + simple_config_tlv_header_c::get_header_length() + buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_data.set_data_length( + simple_config_tlv_header_c::get_header_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_header.set_header_buffer( + m_data.get_buffer(m_data.get_buffer_length()), + m_data.get_buffer_length()); + + m_header.set_tlv_type(current_payload); + + if (buffer_length > 0xffff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + m_header.set_data_length(static_cast(buffer_length)); + + status = m_data.add_data(buffer, buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_is_mandatory = is_mandatory; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_variable_data_c::add_data( + const void * const buffer, + const u32_t buffer_length) +{ + const simple_config_Attribute_Type_e current_payload = m_header.get_tlv_type(); + + eap_status_e status = m_data.add_data( + buffer, + buffer_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_header.set_header_buffer( + m_data.get_buffer(m_data.get_buffer_length()), + m_data.get_buffer_length()); + + m_header.set_tlv_type(current_payload); + + if ((m_header.get_data_length() + buffer_length) > 0xffff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + m_header.set_data_length(static_cast(m_header.get_data_length() + buffer_length)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t simple_config_variable_data_c::get_data_length() const +{ + return m_header.get_data_length(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t * simple_config_variable_data_c::get_data( + const u32_t data_length) const +{ + return m_header.get_data(data_length); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * simple_config_variable_data_c::get_full_attribute_buffer() +{ + return &m_data; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_tlv_header_c * simple_config_variable_data_c::get_header() +{ + return &m_header; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_Attribute_Type_e simple_config_variable_data_c::get_attribute_type() const +{ + return m_header.get_tlv_type(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool simple_config_variable_data_c::get_is_mandatory() const +{ + return m_is_mandatory; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_variable_data_c::set_attribute_type( + const simple_config_Attribute_Type_e type) +{ + m_header.set_tlv_type(type); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_variable_data_c::set_next_payload_with_same_attribute_type( + simple_config_variable_data_c * const attribute) +{ + m_next_payload_with_same_attribute_type = attribute; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_variable_data_c * simple_config_variable_data_c::get_next_payload_with_same_attribute_type() +{ + return m_next_payload_with_same_attribute_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_variable_data_c::add_next_payload_with_same_attribute_type( + simple_config_variable_data_c * const attribute) +{ + simple_config_variable_data_c *payload = get_next_payload_with_same_attribute_type(); + simple_config_variable_data_c *prev_payload = this; + + while (payload != 0) + { + prev_payload = payload; + payload = payload->get_next_payload_with_same_attribute_type(); + } + + if (prev_payload != 0) + { + prev_payload->set_next_payload_with_same_attribute_type(attribute); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_variable_data_c * simple_config_variable_data_c::copy() const +{ + simple_config_variable_data_c * new_data = new simple_config_variable_data_c(m_am_tools); + + if (new_data != 0) + { + eap_status_e status = new_data->set_copy_of_buffer( + get_attribute_type(), + get_is_mandatory(), + get_data(get_data_length()), + get_data_length()); + if (status != eap_status_ok) + { + delete new_data; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + } + + return new_data; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_variable_data_c::object_increase_reference_count() +{ +} + + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + + +EAP_FUNC_EXPORT simple_config_payloads_c::~simple_config_payloads_c() +{ +} + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +EAP_FUNC_EXPORT simple_config_payloads_c::simple_config_payloads_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_payload_map(tools, this) + , m_read_payloads(tools) + , m_payload_index(0ul) + , m_is_valid(false) +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_variable_data_c * simple_config_payloads_c::get_attribute_pointer( + const simple_config_Attribute_Type_e current_payload, + u32_t index) const +{ + eap_variable_data_c selector(m_am_tools); + + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return 0; + } + + selector.set_buffer( + ¤t_payload, + sizeof(current_payload), + false, + false); + + simple_config_variable_data_c *payload = m_payload_map.get_handler(&selector); + + while (index != 0ul && payload != 0) + { + --index; + payload = payload->get_next_payload_with_same_attribute_type(); + } + + return payload; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_variable_data_c * simple_config_payloads_c::get_attribute_pointer( + const simple_config_Attribute_Type_e current_payload) const +{ + return get_attribute_pointer(current_payload, 0ul); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t simple_config_payloads_c::get_attribute_count() const +{ + return m_read_payloads.get_object_count(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_variable_data_c * simple_config_payloads_c::get_attribute( + const u32_t attribute_index) const +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::get_attribute(index %d, max %d)\n"), + attribute_index, + m_read_payloads.get_object_count())); + + simple_config_variable_data_c *payload = m_read_payloads.get_object(attribute_index); + + return payload; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::check_payloads_existense( + const simple_config_Attribute_Type_e * const needed_payloads, + const u32_t count_of_needed_payloads) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::check_payloads_existense()\n"))); + + for (u32_t ind = 0ul; ind < count_of_needed_payloads; ind++) + { + const simple_config_Attribute_Type_e required_avp_code = needed_payloads[ind]; + if (required_avp_code == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (get_attribute_pointer(required_avp_code) == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("not received TLV 0x%08x.\n"), + required_avp_code)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::check_payloads_existense( + EAP_TEMPLATE_CONST eap_array_c * const needed_payloads) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::check_payloads_existense()\n"))); + + for (u32_t ind = 0ul; ind < needed_payloads->get_object_count(); ind++) + { + const simple_config_Attribute_Type_e * const required_avp_code = needed_payloads->get_object(ind); + if (required_avp_code == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (get_attribute_pointer(*required_avp_code) == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("not received TLV 0x%08x.\n"), + *required_avp_code)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::check_mandatory_payloads( + EAP_TEMPLATE_CONST eap_array_c * const used_payloads) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::check_mandatory_payloads()\n"))); + + for (u32_t ind = 0ul; ind < m_read_payloads.get_object_count(); ind++) + { + const simple_config_variable_data_c * const read_payload = m_read_payloads.get_object(ind); + if (read_payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (read_payload->get_is_mandatory() == true) + { + simple_config_Attribute_Type_e attribute_type = read_payload->get_attribute_type(); + + i32_t index = find_simple( + used_payloads, + &attribute_type, + m_am_tools); + if (index < 0ul) + { + // ERROR: not used mandatory TLV. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("ERROR: not used mandatory TLV 0x%08x.\n"), + attribute_type)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unsupported_payload); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::copy_attribute( + const simple_config_payloads_c * const source, + const simple_config_Attribute_Type_e attribute) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::copy_attribute(TLV 0x%08x)\n"), + attribute)); + + const simple_config_variable_data_c * const payload + = source->get_attribute_pointer(attribute, 0ul); + if (payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + eap_status_e status = add_attribute( + payload->copy()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::add_attribute( + simple_config_variable_data_c * const new_payload) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::add_attribute()\n"))); + + if (new_payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status(eap_status_process_general_error); + + eap_automatic_variable_c + automatic_new_payload(m_am_tools, new_payload); + + const simple_config_Attribute_Type_e new_payload_type(new_payload->get_attribute_type()); + + simple_config_variable_data_c *old_payload = get_attribute_pointer( + new_payload_type); + + { + eap_variable_data_c selector(m_am_tools); + + if (selector.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = selector.set_copy_of_buffer( + &new_payload_type, + sizeof(new_payload_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (old_payload == 0) + { + status = m_payload_map.add_handler(&selector, new_payload); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Cannot add dublicate payload to m_payload_map. + // Instead we add apointer to the next payload with the same attribute type. + old_payload->add_next_payload_with_same_attribute_type(new_payload); + } + + automatic_new_payload.do_not_free_variable(); + + // Note the same payload object is added to m_read_payloads as to m_payload_map. + status = m_read_payloads.add_object(new_payload, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::copy_attribute_data( + const simple_config_Attribute_Type_e current_payload, + const bool is_mandatory, + const void * const data, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::copy_attribute_data(TLV 0x%08x)\n"), + current_payload)); + + eap_status_e status(eap_status_process_general_error); + + simple_config_variable_data_c *new_payload = new simple_config_variable_data_c( + m_am_tools); + if (new_payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_automatic_variable_c + automatic_new_payload(m_am_tools, new_payload); + + status = new_payload->set_copy_of_buffer( + current_payload, + is_mandatory, + data, + data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + automatic_new_payload.do_not_free_variable(); + + status = add_attribute(new_payload); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + eap_variable_data_c * const data) const +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::get_attribute_data(eap_variable_data_c *)\n"))); + + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + simple_config_variable_data_c * const found_attribute = get_attribute_pointer( + copied_attribute_type); + if (found_attribute == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + u32_t attribute_data_length = found_attribute->get_header()->get_data_length(); + + if (attribute_data_length > 0ul) + { + const u8_t * const attribute_data = found_attribute->get_header()->get_data(attribute_data_length); + if (attribute_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + eap_status_e status = data->set_copy_of_buffer(attribute_data, attribute_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + data->reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + void * const data, + const u32_t data_length) const +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::get_attribute_data(void *)\n"))); + + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + simple_config_variable_data_c * const found_attribute = get_attribute_pointer( + copied_attribute_type); + if (found_attribute == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + u32_t attribute_data_length = found_attribute->get_header()->get_data_length(); + + if (attribute_data_length == data_length) + { + const u8_t * const attribute_data = found_attribute->get_header()->get_data(attribute_data_length); + if (attribute_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + m_am_tools->memmove(data, attribute_data, attribute_data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + m_am_tools->memset(data, 0, data_length); + + if (attribute_data_length < data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + u8_t * const data) const +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::get_attribute_data(u8_t *)\n"))); + + return get_attribute_data( + copied_attribute_type, + data, + sizeof(u8_t)); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + u16_t * const data) const +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::get_attribute_data(u16_t *)\n"))); + + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u16_t data_in_network_order(0ul); + + eap_status_e status = get_attribute_data( + copied_attribute_type, + &data_in_network_order, + sizeof(data_in_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *data = eap_ntohs(data_in_network_order); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + u32_t * const data) const +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::get_attribute_data(u32_t *)\n"))); + + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t data_in_network_order(0ul); + + eap_status_e status = get_attribute_data( + copied_attribute_type, + &data_in_network_order, + sizeof(data_in_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *data = eap_ntohl(data_in_network_order); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::get_attribute_data( + const simple_config_Attribute_Type_e copied_attribute_type, + u64_t * const data) const +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::get_attribute_data(u64_t *)\n"))); + + if (data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u64_t data_in_network_order(0ul); + + eap_status_e status = get_attribute_data( + copied_attribute_type, + &data_in_network_order, + sizeof(data_in_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *data = eap_ntohll(data_in_network_order); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool simple_config_payloads_c::get_is_valid() const +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::parse_generic_payload( + const simple_config_Attribute_Type_e attribute_type, + const simple_config_tlv_header_c * const header) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + SIMPLE_CONFIG_TLV_TRACE_PAYLOAD("Parsing attribute", header); + + eap_status_e status(eap_status_process_general_error); + + /* + * TLV-header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Attribute Type | Data Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Data ... + * +-+-+-+-+-+-+-+-+-+- + */ + if (header->get_header_buffer_length() < header->get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("ERROR: simple_config_payloads_c::parse_generic_payload(0x%08x): ") + EAPL("current header 0x%08x=%s, required length 0x%08x, packet length too less 0x%08x.\n"), + header, + attribute_type, + header->get_tlv_type_string(), + header->get_header_length(), + header->get_header_buffer_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u32_t data_length = header->get_data_length(); + + u8_t * const data + = static_cast(header->get_data_offset(0ul, data_length)); + + if (data == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("ERROR: simple_config_payloads_c::parse_generic_payload(0x%08x): ") + EAPL("current header 0x%08x=%s, length 0x%04x, data buffer incorrect.\n"), + header, + attribute_type, + header->get_tlv_type_string(), + header->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = copy_attribute_data( + attribute_type, + true, + data, + data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::verify_padding( + const u8_t * const possible_padding, + const u32_t possible_padding_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::verify_padding()\n"))); + + const u8_t padding_byte = static_cast(possible_padding_length); + + for (u32_t ind = 0ul; ind < possible_padding_length; ind++) + { + if (possible_padding[ind] != padding_byte) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::parse_simple_config_payloads( + void * const message_buffer, + u32_t * const buffer_length, + u32_t * const padding_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::parse_simple_config_payloads()\n"))); + + *padding_length = 0ul; + + simple_config_tlv_header_c payload( + m_am_tools, + message_buffer, + *buffer_length); // Const correctness is gone. + + simple_config_Attribute_Type_e current_payload = payload.get_tlv_type(); + + eap_status_e status = eap_status_header_corrupted; + + if (payload.get_is_valid() == true + && current_payload != simple_config_Attribute_Type_None) + { + if (*buffer_length < payload.get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("ERROR: simple_config_payloads_c::parse_simple_config_payloads(0x%08x): ") + EAPL("current payload 0x%08x=%s, data length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload, + payload.get_tlv_type_string(), + payload.get_data_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("ERROR: simple_config_payloads_c::parse_simple_config_payloads(): ") + EAPL("SIMPLE_CONFIG-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t prev_avp_length = payload.get_length(); + if (*buffer_length < prev_avp_length) + { + // We do have only the current payload. So not padding is included. + prev_avp_length = payload.get_length(); + } + + EAP_ASSERT_ALWAYS(*buffer_length >= prev_avp_length); + *buffer_length -= prev_avp_length; + + u32_t remaining_data_length(0ul); + + remaining_data_length = payload.get_header_buffer_length() - prev_avp_length; + + payload.set_header_buffer( + payload.get_header_offset(prev_avp_length, remaining_data_length), + remaining_data_length); + if (payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + while(*buffer_length >= payload.get_header_length() + && payload.get_is_valid() == true + && payload.get_header_buffer_length() >= payload.get_length()) + { + current_payload = payload.get_tlv_type(); + if (current_payload == simple_config_Attribute_Type_None) + { + // This might be padding in the end of the message. + break; + } + + if (*buffer_length < payload.get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("ERROR: simple_config_payloads_c::parse_simple_config_payloads(0x%08x): ") + EAPL("current payload 0x%08x=%s, payload data length 0x%04x, payload length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload, + payload.get_tlv_type_string(), + payload.get_data_length(), + payload.get_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("ERROR: simple_config_payloads_c::parse_simple_config_payloads(): ") + EAPL("SIMPLE_CONFIG-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + prev_avp_length = payload.get_length(); + if (*buffer_length < prev_avp_length) + { + // We do have only the current payload. So not padding is included. + prev_avp_length = payload.get_length(); + } + + EAP_ASSERT_ALWAYS(*buffer_length >= prev_avp_length); + *buffer_length -= prev_avp_length; + + remaining_data_length = payload.get_header_buffer_length() - prev_avp_length; + + payload.set_header_buffer( + payload.get_header_offset(prev_avp_length, remaining_data_length), + remaining_data_length); + } // while() + + if (*buffer_length != 0u) + { + const u8_t * const possible_padding = payload.get_header_buffer(remaining_data_length); + + // First check is this padding + if (possible_padding == 0 + || remaining_data_length != *buffer_length + || verify_padding(possible_padding, remaining_data_length) != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("ERROR: simple_config_payloads_c::parse_simple_config_payloads(): ") + EAPL("SIMPLE_CONFIG-header is corrupted. Buffer length and payload ") + EAPL("length does not match. %lu illegal bytes.\n"), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else + { + // OK, we get correct padding. + *padding_length = remaining_data_length; + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::create_simple_config_message( + simple_config_message_c * const new_simple_config_message_data, + const bool add_payloads) const +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::create_simple_config_message()\n"))); + + eap_status_e status(eap_status_process_general_error); + + if (add_payloads == false) + { + status = new_simple_config_message_data->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + const u32_t attribute_count(get_attribute_count()); + u32_t attribute_index(0ul); + + while (attribute_index < attribute_count) + { + simple_config_variable_data_c * attribute = get_attribute(attribute_index); + if (attribute == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = new_simple_config_message_data->get_simple_config_message_data()->add_data(attribute->get_full_attribute_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + SIMPLE_CONFIG_TLV_TRACE_PAYLOAD("Added attribute", attribute->get_header()); + + ++attribute_index; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::create_simple_config_message(): index %d\n"), + attribute_index)); + + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::create_simple_config_message() returns\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::add_payloads_to_simple_config_authenticator( + crypto_hmac_c * const hmac_sha_256, + const bool include_authenticator_attribute) const +{ + eap_status_e status(eap_status_process_general_error); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::add_payloads_to_simple_config_authenticator()\n"))); + + const u32_t attribute_count(get_attribute_count()); + u32_t attribute_index(0ul); + + while (attribute_index < attribute_count) + { + simple_config_variable_data_c * attribute = get_attribute(attribute_index); + if (attribute == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + if (include_authenticator_attribute == false + && attribute->get_header()->get_tlv_type() == simple_config_Attribute_Type_Authenticator) + { + break; + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("SIMPLE_CONFIG authenticator data"), + attribute->get_full_attribute_buffer()->get_data(), + attribute->get_full_attribute_buffer()->get_data_length())); + + status = hmac_sha_256->hmac_update( + attribute->get_full_attribute_buffer()->get_data(), + attribute->get_full_attribute_buffer()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + ++attribute_index; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_payloads_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_payload_map.reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_read_payloads.reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +simple_config_payloads_c * simple_config_payloads_c::copy() const +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: message_function: simple_config_payloads_c::copy()\n"))); + + simple_config_payloads_c * copy_payloads = new simple_config_payloads_c(m_am_tools); + + if (copy_payloads == 0 + || copy_payloads->get_is_valid() == false) + { + delete copy_payloads; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + eap_status_e status(eap_status_process_general_error); + + const u32_t attribute_count(get_attribute_count()); + u32_t attribute_index(0ul); + + while (attribute_index < attribute_count) + { + simple_config_variable_data_c * attribute = get_attribute(attribute_index); + if (attribute == 0) + { + delete copy_payloads; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + status = copy_payloads->add_attribute( + attribute->copy()); + + if (status != eap_status_ok) + { + delete copy_payloads; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + ++attribute_index; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return copy_payloads; +} + +//-------------------------------------------------- +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_record.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_record.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,8230 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 601 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#if defined(USE_EAP_SIMPLE_CONFIG) + +#include "eap_am_memory.h" +#include "eap_am_export.h" +#include "eap_am_tools.h" +#include "eap_tools.h" +#include "eap_crypto_api.h" +#include "abs_simple_config_base_record.h" +#include "simple_config_base_record.h" +#include "simple_config_record.h" +#include "simple_config_am_services.h" +#include "simple_config_types.h" +#include "simple_config_message.h" +#include "eap_automatic_variable.h" +#include "eap_state_notification.h" +#include "eap_type_simple_config_types.h" +#include "eap_header_string.h" +#include "abs_eap_am_mutex.h" +#include "simple_config_credential.h" +#include "eapol_key_types.h" + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT simple_config_record_c::~simple_config_record_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("%s: function: simple_config_record_c::~simple_config_record_c(): this = 0x%08x, m_am_simple_config_services") + EAPL(" = 0x%08x (validity %d).\n"), + (m_is_client == true ? "client": "server"), + this, + m_am_simple_config_services, + m_am_simple_config_services->get_is_valid())); + + EAP_ASSERT(m_shutdown_was_called == true); + + completion_action_clenup(); + + if (m_free_am_simple_config_services == true) + { + delete m_am_simple_config_services; + } + m_am_simple_config_services = 0; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +EAP_FUNC_EXPORT simple_config_record_c::simple_config_record_c( + abs_eap_am_tools_c * const tools, ///< tools is pointer to the tools class. @see abs_eap_am_tools_c. + simple_config_am_services_c * const am_simple_config_services, ///< This is pointer to adaptation module of SIMPLE_CONFIG. + const bool free_am_simple_config_services, + const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false). + const eap_am_network_id_c * const receive_network_id) + : simple_config_base_record_c(tools /*, partner */) + , m_am_tools(tools) + , m_am_simple_config_services(am_simple_config_services) + , m_free_am_simple_config_services(free_am_simple_config_services) + , m_completion_queue(tools) + , m_M2D_payloads(tools) + , m_received_simple_config_message(tools, is_client_when_true) + , m_received_payloads(tools) + , m_previous_simple_config_message(tools, is_client_when_true) + , m_new_simple_config_message(tools, is_client_when_true) + , m_current_simple_config_message_type(simple_config_Message_Type_None) + , m_enrollee_nonce(tools) + , m_enrollee_mac(tools) + , m_registrar_nonce(tools) + , m_device_password(tools) + , m_PSK1(tools) + , m_PSK2(tools) + , m_E_SNonce1(tools) + , m_E_SNonce2(tools) + , m_EHash1(tools) + , m_EHash2(tools) + , m_R_SNonce1(tools) + , m_R_SNonce2(tools) + , m_RHash1(tools) + , m_RHash2(tools) + , m_own_private_dhe_key(tools) + , m_own_public_dhe_key(tools) + , m_peer_public_dhe_key(tools) + , m_shared_dh_key(tools) + , m_dhe_prime(tools) + , m_dhe_group_generator(tools) + , m_kdk(tools) + , m_auth_key(tools) + , m_key_wrap_key(tools) + , m_EMSK(tools) + , m_SSID(tools) + , m_signed_message_hash(tools) + , m_NAI(tools) + , m_NAI_realm(tools) + , m_send_network_id(tools) +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + , m_network_key(tools) + , m_authentication_type(simple_config_Authentication_Type_None) +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + , m_simple_config_state(simple_config_state_wait_simple_config_start) + , m_handshake_error(eap_status_ok) + , m_UUID_E(tools) + , m_UUID_R(tools) + , m_Rf_Bands(simple_config_RF_Bands_2_4_GHz) + , m_MAC_address(tools) + , m_local_Device_Password_ID(simple_config_Device_Password_ID_Default_PIN) + , m_received_Device_Password_ID(simple_config_Device_Password_ID_Default_PIN) + , m_new_password(tools) + , m_new_Device_Password_ID(simple_config_Device_Password_ID_Default_PIN) + , m_error_message_received_timeout(SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_TIMEOUT) + , m_is_valid(false) + , m_is_client(is_client_when_true) + , m_allow_message_send(true) + , m_already_in_completion_action_check(false) + , m_pending_query_network_and_device_parameters(false) + , m_simple_config_test_version(false) + , m_key_material_generated(false) + , m_force_simple_config_message_send(false) + , m_shutdown_was_called(false) + , m_M2D_received_timeout_active(false) +{ + if (m_am_tools == 0 + || m_am_tools->get_is_valid() == false) + { + // No need to delete anything here because it is done in destructor. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: simple_config_record_c::simple_config_record_c(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + // No need to delete anything here because it is done in destructor. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (m_am_simple_config_services == 0 + || m_am_simple_config_services->get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_SIMPLE_CONFIG_ERROR, + (EAPL("ERROR: %s: function: simple_config_record_c::simple_config_record_c() failed,") + EAPL(" m_am_simple_config_services = 0x%08x (validity %d) is invalid.\n"), + (m_is_client == true ? "client": "server"), + m_am_simple_config_services, (m_am_simple_config_services != 0) ? m_am_simple_config_services->get_is_valid(): false)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + m_am_simple_config_services->set_simple_config_am_partner(this); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (send_network_id.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (m_send_network_id.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + eap_status_e status = m_send_network_id.set_copy_of_network_id(&send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (m_send_network_id.get_is_valid() == false + || m_received_simple_config_message.get_is_valid() == false + || m_received_payloads.get_is_valid() == false + || m_previous_simple_config_message.get_is_valid() == false + || m_new_simple_config_message.get_is_valid() == false + || m_enrollee_nonce.get_is_valid() == false + || m_enrollee_mac.get_is_valid() == false + || m_registrar_nonce.get_is_valid() == false + || m_device_password.get_is_valid() == false + || m_PSK1.get_is_valid() == false + || m_PSK2.get_is_valid() == false + || m_E_SNonce1.get_is_valid() == false + || m_E_SNonce2.get_is_valid() == false + || m_EHash1.get_is_valid() == false + || m_EHash2.get_is_valid() == false + || m_R_SNonce1.get_is_valid() == false + || m_R_SNonce2.get_is_valid() == false + || m_RHash1.get_is_valid() == false + || m_RHash2.get_is_valid() == false + || m_own_private_dhe_key.get_is_valid() == false + || m_own_public_dhe_key.get_is_valid() == false + || m_peer_public_dhe_key.get_is_valid() == false + || m_shared_dh_key.get_is_valid() == false + || m_dhe_prime.get_is_valid() == false + || m_dhe_group_generator.get_is_valid() == false + || m_kdk.get_is_valid() == false + || m_auth_key.get_is_valid() == false + || m_key_wrap_key.get_is_valid() == false + || m_EMSK.get_is_valid() == false + || m_SSID.get_is_valid() == false + || m_signed_message_hash.get_is_valid() == false + || m_NAI.get_is_valid() == false + || m_NAI_realm.get_is_valid() == false + || m_send_network_id.get_is_valid() == false + || m_UUID_E.get_is_valid() == false + || m_UUID_R.get_is_valid() == false + || m_MAC_address.get_is_valid() == false + || m_new_password.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + if (m_is_client == false) + { + set_state(simple_config_state_wait_M1); + } +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_record_c::set_state(const simple_config_state_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_simple_config_trace_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: state_function: set_state() from %s to %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_state_string(m_simple_config_state), + state_string.get_state_string(state))); + + if (m_simple_config_state != simple_config_state_failure) + { + m_simple_config_state = state; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT simple_config_state_e simple_config_record_c::get_state() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_simple_config_state; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool simple_config_record_c::verify_state(const simple_config_state_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_simple_config_trace_string_c state_string; + + if (m_simple_config_state == state) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: state_function: verify_state(): current state %s == %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_state_string(m_simple_config_state), + state_string.get_state_string(state))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return true; + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: SIMPLE_CONFIG: %s: state_function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_state_string(m_simple_config_state), + state_string.get_state_string(state))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_record_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: simple_config_record_c::configure(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + eap_status_e status = m_am_simple_config_services->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (get_type_partner() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_is_client == true) + { + // Creates Enrollee Nonce. + status = generate_nonce( + &m_enrollee_nonce, + SIMPLE_CONFIG_ENROLLEE_NONCE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Creates Registrar Nonce. + status = generate_nonce( + &m_registrar_nonce, + SIMPLE_CONFIG_REGISTRAR_NONCE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = generate_dhe_keys(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + //---------------------------------------------------------- + + { + status = get_type_partner()->read_configure( + cf_str_EAP_SIMPLE_CONFIG_device_password.get_field(), + &m_device_password); + if (status != eap_status_ok + || m_device_password.get_is_valid_data() == false) + { + // This is mandatory value. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: SIMPLE_CONFIG: %s: simple_config_record_c::configure(): Missing device password.\n"), + (m_is_client == true ? "client": "server"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_password); + } + } + + if (m_is_client == false) + { + (void) get_type_partner()->read_configure( + cf_str_EAP_SIMPLE_CONFIG_server_device_password.get_field(), + &m_device_password); + } + + //---------------------------------------------------------- + + { + eap_variable_data_c test_version(m_am_tools); + + if (test_version.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = get_type_partner()->read_configure( + cf_str_EAP_SIMPLE_CONFIG_test_version.get_field(), + &test_version); + if (status == eap_status_ok + && test_version.get_is_valid_data() == true + && test_version.get_data_length() == sizeof(u32_t) + && test_version.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(test_version.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_simple_config_test_version = false; + } + else + { + m_simple_config_test_version = true; + } + } + } + + status = eap_status_ok; + } + + //---------------------------------------------------------- + + { + eap_variable_data_c error_message_received_timeout(m_am_tools); + + if (error_message_received_timeout.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = read_configure( + cf_str_SIMPLE_CONFIG_error_message_received_timeout.get_field(), + &error_message_received_timeout); + if (status == eap_status_ok + && error_message_received_timeout.get_is_valid_data() == true) + { + u32_t *error_message_received_timeout_value = reinterpret_cast( + error_message_received_timeout.get_data(sizeof(u32_t))); + if (error_message_received_timeout_value != 0) + { + m_error_message_received_timeout = *error_message_received_timeout_value; + } + } + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + if (m_is_client == false) + { + { + // This is optional. + (void) read_configure( + cf_str_SIMPLE_CONFIG_new_password.get_field(), + &m_new_password); + } + + { + // This is optional. + (void) read_configure( + cf_str_SIMPLE_CONFIG_network_key.get_field(), + &m_network_key); + } + + { + eap_variable_data_c authentication_type(m_am_tools); + + eap_status_e status = read_configure( + cf_str_SIMPLE_CONFIG_authentication_type.get_field(), + &authentication_type); + if (status == eap_status_ok + && authentication_type.get_is_valid() == true + && authentication_type.get_data_length() > 0ul + && authentication_type.get_data( + authentication_type.get_data_length()) != 0) + { + + if (cf_str_SIMPLE_CONFIG_authentication_type_None.get_field() + ->compare( + m_am_tools, + &authentication_type) == true) + { + m_authentication_type + = simple_config_Authentication_Type_None; + } + else if (cf_str_SIMPLE_CONFIG_authentication_type_Open.get_field() + ->compare( + m_am_tools, + &authentication_type) == true) + { + m_authentication_type + = simple_config_Authentication_Type_Open; + } + else if (cf_str_SIMPLE_CONFIG_authentication_type_WPAPSK.get_field() + ->compare( + m_am_tools, + &authentication_type) == true) + { + m_authentication_type + = simple_config_Authentication_Type_WPAPSK; + } + else if (cf_str_SIMPLE_CONFIG_authentication_type_Shared.get_field() + ->compare( + m_am_tools, + &authentication_type) == true) + { + m_authentication_type + = simple_config_Authentication_Type_Shared; + } + else if (cf_str_SIMPLE_CONFIG_authentication_type_WPA.get_field() + ->compare( + m_am_tools, + &authentication_type) == true) + { + m_authentication_type + = simple_config_Authentication_Type_WPA; + } + else if (cf_str_SIMPLE_CONFIG_authentication_type_WPA2.get_field() + ->compare( + m_am_tools, + &authentication_type) == true) + { + m_authentication_type + = simple_config_Authentication_Type_WPA2; + } + else if (cf_str_SIMPLE_CONFIG_authentication_type_WPA2PSK.get_field() + ->compare( + m_am_tools, + &authentication_type) == true) + { + m_authentication_type + = simple_config_Authentication_Type_WPA2PSK; + } + } + } + } +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + //---------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: simple_config_record_c::shutdown(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + + // Cancel all timers. + cancel_error_message_timeout(); + cancel_M2D_received_timeout(); + + + if (get_state() != simple_config_state_simple_config_success) + { + set_state(simple_config_state_failure); + } + + eap_status_e status = eap_status_ok; + + if (m_pending_query_network_and_device_parameters == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: function: simple_config_record_c::shutdown(): calls cancel_query_dh_parameters()\n"))); + + m_am_simple_config_services->cancel_query_network_and_device_parameters(); + m_pending_query_network_and_device_parameters = false; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::set_nai_realm( + const eap_variable_data_c * const NAI_realm) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_NAI_realm.set_copy_of_buffer(NAI_realm); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::completion_action_add( + simple_config_completion_action_e action) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + simple_config_completion_c *completion_action = new simple_config_completion_c( + m_am_tools, + action); + + if (completion_action == 0 + || completion_action->get_is_valid() == false) + { + delete completion_action; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // add_object() will delete completion_action if operation fails. + eap_status_e status = m_completion_queue.add_object(completion_action, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: send_function: completion_action_add(): action %s\n"), + (m_is_client == true ? "client": "server"), + completion_action->get_completion_action_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::completion_action_clenup() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: send_function: completion_action_clenup()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e final_status = eap_status_ok; + u32_t counter(0ul); + + while(m_completion_queue.get_object_count() > 0ul) + { + simple_config_completion_c * const completion_action = m_completion_queue.get_object(0ul); + EAP_UNREFERENCED_PARAMETER(completion_action); // Not referenced without trace. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: SIMPLE_CONFIG: %s: send_function: completion_action_clenup(): ") + EAPL("action[%u] %s not completed.\n"), + (m_is_client == true ? "client": "server"), + counter, + completion_action->get_completion_action_string())); + + final_status = m_completion_queue.remove_object(0ul); + if (final_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, final_status); + } + + ++counter; + + } // while() + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, final_status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::completion_action_check() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: send_function: completion_action_check()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_already_in_completion_action_check == true) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + // This is recursive call of completion_action_check(). + // This MUST return eap_status_ok. Other return values will skip + // further prosessing of completion action list. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_already_in_completion_action_check = true; + + eap_automatic_simple_value_c restore_already_in_completion_action_check( + m_am_tools, + &m_already_in_completion_action_check, + false); + + eap_status_e status = eap_status_ok; + bool continue_with_next_action = true; + u32_t counter = 0ul; + + while(continue_with_next_action == true + && m_completion_queue.get_object_count() > 0ul) + { + simple_config_completion_c * const completion_action = m_completion_queue.get_object(0ul); + EAP_UNREFERENCED_PARAMETER(completion_action); // Not referenced without trace. + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: send_function: completion_action_check(): action[%u] %s\n"), + (m_is_client == true ? "client": "server"), + counter, + completion_action->get_completion_action_string())); + + if (continue_with_next_action == true) + { + status = m_completion_queue.remove_object(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + ++counter; + + } // while() + + if (continue_with_next_action == false) + { + status = eap_status_pending_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_simple_config_base_application_c. +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return get_type_partner()->read_configure( + field, + data); +} + +//-------------------------------------------------- + +// This is commented in abs_simple_config_base_application_c. +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return get_type_partner()->write_configure( + field, + data); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::add_common_attributes( + simple_config_payloads_c * const payloads, + const simple_config_Message_Type_e message_type, + const bool add_enrollee_nonce, + const bool add_registrar_nonce) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::add_common_attributes()\n"), + (m_is_client == true ? "client": "server"))); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (message_type > simple_config_Message_keep_this_last) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_process_general_error); + + { + u8_t Version[] + = { SIMPLE_CONFIG_VERSION }; + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_Version, + true, + Version, + sizeof(Version)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + { + u8_t Message_type(static_cast(message_type)); + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_Message_Type, + true, + &Message_type, + sizeof(Message_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save the type for indicating it to the lower layer in transmission + m_current_simple_config_message_type = message_type; + } + + if (add_enrollee_nonce == true) + { + if (m_enrollee_nonce.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_Enrollee_Nonce, + true, + m_enrollee_nonce.get_data(), + m_enrollee_nonce.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (add_registrar_nonce == true) + { + if (m_registrar_nonce.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_Registrar_Nonce, + true, + m_registrar_nonce.get_data(), + m_registrar_nonce.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M1( + const simple_config_payloads_c * const network_and_device_parameters) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M1()\n"), + (m_is_client == true ? "client": "server"))); + + if (network_and_device_parameters == 0 + || network_and_device_parameters->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_process_general_error); + + + { + // Save Enrollee MAC. + status = m_enrollee_mac.set_copy_of_buffer( + m_send_network_id.get_source_id()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_common_attributes( + payloads, + simple_config_Message_Type_M1, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_UUID_E); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + if (m_enrollee_mac.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_MAC_Address, + true, + m_enrollee_mac.get_data(), + m_enrollee_mac.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + { + if (m_enrollee_nonce.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_Enrollee_Nonce, + true, + m_enrollee_nonce.get_data(), + m_enrollee_nonce.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + { + if (m_own_public_dhe_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_Public_Key, + true, + m_own_public_dhe_key.get_data(), + m_own_public_dhe_key.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Authentication_Type_Flags); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Encryption_Type_Flags); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Connection_Type_Flags); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Config_Methods); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Simple_Config_State); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Manufacturer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Model_Name); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Model_Number); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Serial_Number); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Primary_Device_Type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Device_Name); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_RF_Band); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Association_State); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Device_Password_ID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (payloads->get_attribute_pointer( + simple_config_Attribute_Type_Configuration_Error) != 0) + { + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Configuration_Error); + } + else + { + status = eap_status_not_found; + } + + if (status != eap_status_ok) + { + simple_config_Configuration_Error_e Configuration_Error(simple_config_Configuration_Error_No_Error); + u16_t network_order_Configuration_Error(eap_htons(static_cast(Configuration_Error))); + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_Configuration_Error, + true, + &network_order_Configuration_Error, + sizeof(network_order_Configuration_Error)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_OS_Version); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + set_state(simple_config_state_wait_M2); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M2( + const simple_config_payloads_c * const network_and_device_parameters) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M2()\n"), + (m_is_client == true ? "client": "server"))); + + if (network_and_device_parameters == 0 + || network_and_device_parameters->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_process_general_error); + + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_common_attributes( + payloads, + simple_config_Message_Type_M2, + true, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_UUID_R); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_Public_Key, + true, + m_own_public_dhe_key.get_data(), + m_own_public_dhe_key.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Authentication_Type_Flags); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Encryption_Type_Flags); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Connection_Type_Flags); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Config_Methods); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Manufacturer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Model_Name); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Model_Number); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Serial_Number); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Primary_Device_Type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Device_Name); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_RF_Band); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Association_State); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (payloads->get_attribute_pointer( + simple_config_Attribute_Type_Configuration_Error) != 0) + { + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Configuration_Error); + } + else + { + status = eap_status_missing_payload; + } + + if (status != eap_status_ok) + { + // Because the Configuration_Error is missing there is no error. + simple_config_Configuration_Error_e Configuration_Error(simple_config_Configuration_Error_No_Error); + u16_t network_order_Configuration_Error(eap_htons(static_cast(Configuration_Error))); + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_Configuration_Error, + true, + &network_order_Configuration_Error, + sizeof(network_order_Configuration_Error)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Device_Password_ID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_OS_Version); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_authenticator_attribute( + &m_received_simple_config_message, + &m_new_simple_config_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(simple_config_state_wait_M3); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M2D( + const simple_config_payloads_c * const network_and_device_parameters) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M2D()\n"), + (m_is_client == true ? "client": "server"))); + + if (network_and_device_parameters == 0 + || network_and_device_parameters->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_process_general_error); + + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_common_attributes( + payloads, + simple_config_Message_Type_M2D, + true, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_UUID_R); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Authentication_Type_Flags); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Encryption_Type_Flags); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Connection_Type_Flags); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Config_Methods); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Manufacturer); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Model_Name); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Model_Number); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Serial_Number); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Primary_Device_Type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Device_Name); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_RF_Band); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Association_State); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (network_and_device_parameters->get_attribute_pointer( + simple_config_Attribute_Type_Configuration_Error) != 0) + { + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_Configuration_Error); + } + else + { + status = eap_status_missing_payload; + } + + if (status != eap_status_ok) + { + simple_config_Configuration_Error_e Configuration_Error(simple_config_Configuration_Error_No_Error); + u16_t network_order_Configuration_Error(eap_htons(static_cast(Configuration_Error))); + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_Configuration_Error, + true, + &network_order_Configuration_Error, + sizeof(network_order_Configuration_Error)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = payloads->copy_attribute( + network_and_device_parameters, + simple_config_Attribute_Type_OS_Version); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(simple_config_state_wait_WSC_ACK); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M3() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M3()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Create HASHs + status = generate_er_hashs( + false, + &m_device_password, + &m_own_public_dhe_key, + &m_peer_public_dhe_key, + &m_PSK1, + &m_E_SNonce1, + &m_EHash1, + &m_PSK2, + &m_E_SNonce2, + &m_EHash2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_common_attributes( + payloads, + simple_config_Message_Type_M3, + false, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_E_Hash1, + true, + m_EHash1.get_data(), + m_EHash1.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_E_Hash2, + true, + m_EHash2.get_data(), + m_EHash2.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_authenticator_attribute( + &m_received_simple_config_message, + &m_new_simple_config_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(simple_config_state_wait_M4); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M4() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M4()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Create HASHs + status = generate_er_hashs( + false, + &m_device_password, + &m_peer_public_dhe_key, + &m_own_public_dhe_key, + &m_PSK1, + &m_R_SNonce1, + &m_RHash1, + &m_PSK2, + &m_R_SNonce2, + &m_RHash2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_common_attributes( + payloads, + simple_config_Message_Type_M4, + true, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_R_Hash1, + true, + m_RHash1.get_data(), + m_RHash1.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->copy_attribute_data( + simple_config_Attribute_Type_R_Hash2, + true, + m_RHash2.get_data(), + m_RHash2.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + simple_config_variable_data_c * encrypted_settings = new simple_config_variable_data_c(m_am_tools); + eap_automatic_variable_c automatic_encrypted_settings(m_am_tools, encrypted_settings); + + if (encrypted_settings == 0 + || encrypted_settings->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + // Create Encrypted Settings. + // This one includes R-SNonce1 (R-S1). + simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_plaintext_payloads(m_am_tools, plaintext_payloads); + + if (plaintext_payloads == 0 + || plaintext_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = plaintext_payloads->copy_attribute_data( + simple_config_Attribute_Type_R_SNonce1, + true, + m_R_SNonce1.get_data(), + m_R_SNonce1.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = encrypt_payloads( + &m_auth_key, + &m_key_wrap_key, + plaintext_payloads, + encrypted_settings); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + automatic_encrypted_settings.do_not_free_variable(); + + status = payloads->add_attribute( + encrypted_settings); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_authenticator_attribute( + &m_received_simple_config_message, + &m_new_simple_config_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(simple_config_state_wait_M5); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M5() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls add_common_attributes()\n"), + (m_is_client == true ? "client": "server"))); + + status = add_common_attributes( + payloads, + simple_config_Message_Type_M5, + false, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + simple_config_variable_data_c * encrypted_settings = new simple_config_variable_data_c(m_am_tools); + eap_automatic_variable_c automatic_encrypted_settings(m_am_tools, encrypted_settings); + + if (encrypted_settings == 0 + || encrypted_settings->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + // Create Encrypted Settings. + // This one includes E-SNonce1 (E-S1). + simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_plaintext_payloads(m_am_tools, plaintext_payloads); + + if (plaintext_payloads == 0 + || plaintext_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls copy_attribute_data()\n"), + (m_is_client == true ? "client": "server"))); + + status = plaintext_payloads->copy_attribute_data( + simple_config_Attribute_Type_E_SNonce1, + true, + m_E_SNonce1.get_data(), + m_E_SNonce1.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls encrypt_payloads()\n"), + (m_is_client == true ? "client": "server"))); + + status = encrypt_payloads( + &m_auth_key, + &m_key_wrap_key, + plaintext_payloads, + encrypted_settings); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls payloads.add_attribute()\n"), + (m_is_client == true ? "client": "server"))); + + automatic_encrypted_settings.do_not_free_variable(); + + status = payloads->add_attribute( + encrypted_settings); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls payloads.create_simple_config_message()\n"), + (m_is_client == true ? "client": "server"))); + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls m_received_simple_config_message.get_is_valid()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_received_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls m_new_simple_config_message.get_is_valid()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls add_authenticator_attribute()\n"), + (m_is_client == true ? "client": "server"))); + + status = add_authenticator_attribute( + &m_received_simple_config_message, + &m_new_simple_config_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(simple_config_state_wait_M6); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): returns\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M6() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M6()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_common_attributes( + payloads, + simple_config_Message_Type_M6, + true, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + simple_config_variable_data_c * encrypted_settings = new simple_config_variable_data_c(m_am_tools); + eap_automatic_variable_c automatic_encrypted_settings(m_am_tools, encrypted_settings); + + if (encrypted_settings == 0 + || encrypted_settings->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + // Create Encrypted Settings. + // This one includes R-SNonce2 (R-S2). + simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_plaintext_payloads(m_am_tools, plaintext_payloads); + + if (plaintext_payloads == 0 + || plaintext_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = plaintext_payloads->copy_attribute_data( + simple_config_Attribute_Type_R_SNonce2, + true, + m_R_SNonce2.get_data(), + m_R_SNonce2.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = encrypt_payloads( + &m_auth_key, + &m_key_wrap_key, + plaintext_payloads, + encrypted_settings); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + automatic_encrypted_settings.do_not_free_variable(); + + status = payloads->add_attribute( + encrypted_settings); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_authenticator_attribute( + &m_received_simple_config_message, + &m_new_simple_config_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(simple_config_state_wait_M7); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M7() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M7()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_common_attributes( + payloads, + simple_config_Message_Type_M7, + false, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + simple_config_variable_data_c * encrypted_settings = new simple_config_variable_data_c(m_am_tools); + eap_automatic_variable_c automatic_encrypted_settings(m_am_tools, encrypted_settings); + + if (encrypted_settings == 0 + || encrypted_settings->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + { + // Create Encrypted Settings. + // This one includes E-SNonce2 (E-S2). + simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_plaintext_payloads(m_am_tools, plaintext_payloads); + + if (plaintext_payloads == 0 + || plaintext_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = plaintext_payloads->copy_attribute_data( + simple_config_Attribute_Type_E_SNonce2, + true, + m_E_SNonce2.get_data(), + m_E_SNonce2.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = encrypt_payloads( + &m_auth_key, + &m_key_wrap_key, + plaintext_payloads, + encrypted_settings); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + automatic_encrypted_settings.do_not_free_variable(); + + status = payloads->add_attribute( + encrypted_settings); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_authenticator_attribute( + &m_received_simple_config_message, + &m_new_simple_config_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(simple_config_state_wait_M8); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M8() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M8()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_common_attributes( + payloads, + simple_config_Message_Type_M8, + true, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + simple_config_variable_data_c * encrypted_settings = new simple_config_variable_data_c(m_am_tools); + eap_automatic_variable_c automatic_encrypted_settings(m_am_tools, encrypted_settings); + + if (encrypted_settings == 0 + || encrypted_settings->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Create Encrypted Settings. + { + simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_plaintext_payloads(m_am_tools, plaintext_payloads); + + if (plaintext_payloads == 0 + || plaintext_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Create Credential attribute + { + u32_t SIMPLE_CONFIG_TEST_CREDENTIAL_COUNT = 2ul; + + for (u32_t ind = 0ul; ind < SIMPLE_CONFIG_TEST_CREDENTIAL_COUNT; ind++) + { + simple_config_payloads_c * credential_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_credential_payloads(m_am_tools, credential_payloads); + + if (credential_payloads == 0 + || credential_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + { + u8_t network_index(static_cast(ind+SIMPLE_CONFIG_DEFAULT_NETWORK_KEY_INDEX)); + + status = credential_payloads->copy_attribute_data( + simple_config_Attribute_Type_Network_Index, + true, + &network_index, + sizeof(network_index)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = credential_payloads->copy_attribute_data( + simple_config_Attribute_Type_SSID, + true, + m_SSID.get_data(), + m_SSID.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u16_t network_order_Authentication_Type(eap_htons(static_cast(m_authentication_type))); + + status = credential_payloads->copy_attribute_data( + simple_config_Attribute_Type_Authentication_Type, + true, + &network_order_Authentication_Type, + sizeof(network_order_Authentication_Type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + { + u16_t network_order_Encryption_Type(eap_htons(static_cast(simple_config_Encryption_Type_AES))); + + status = credential_payloads->copy_attribute_data( + simple_config_Attribute_Type_Encryption_Type, + true, + &network_order_Encryption_Type, + sizeof(network_order_Encryption_Type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + // Creates some test data. + eap_array_c * network_keys = new eap_array_c(m_am_tools); + eap_automatic_variable_c > automatic_network_keys(m_am_tools, network_keys); + + if (network_keys == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + const u32_t MAX_COUNT_OF_KEYS = 3ul; + + for (u32_t ind = 0ul; ind < MAX_COUNT_OF_KEYS; ++ind) + { + network_key_and_index_c * const obj = new network_key_and_index_c(m_am_tools); + + if (obj != 0) + { + u8_t network_key_index(static_cast(ind)); + + obj->set_network_key_index(network_key_index); + + status = obj->get_network_key()->set_copy_of_buffer( + &m_network_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = network_keys->add_object(obj, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + + { + for (u32_t ind = 0ul; ind < network_keys->get_object_count(); ++ind) + { + network_key_and_index_c * const obj = network_keys->get_object(ind); + + if (obj != 0) + { + u8_t network_key_index(obj->get_network_key_index()); + + status = credential_payloads->copy_attribute_data( + simple_config_Attribute_Type_Network_Key_Index, + true, + &network_key_index, + sizeof(network_key_index)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = credential_payloads->copy_attribute_data( + simple_config_Attribute_Type_Network_Key, + true, + obj->get_network_key()->get_data(), + obj->get_network_key()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + + status = credential_payloads->copy_attribute_data( + simple_config_Attribute_Type_MAC_Address, + true, + m_MAC_address.get_data(), + m_MAC_address.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + + simple_config_message_c * credential_data = new simple_config_message_c(m_am_tools, m_is_client); + eap_automatic_variable_c automatic_credential_data(m_am_tools, credential_data); + + if (credential_data == 0 + || credential_data->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + status = credential_payloads->create_simple_config_message( + credential_data, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = plaintext_payloads->copy_attribute_data( + simple_config_Attribute_Type_Credential, + true, + credential_data->get_simple_config_message_data()->get_data(), + credential_data->get_simple_config_message_data()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Add other optional encrypted attributes. + + if (m_new_password.get_is_valid_data() == true) + { + status = plaintext_payloads->copy_attribute_data( + simple_config_Attribute_Type_New_Password, + true, + m_new_password.get_data(), + m_new_password.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u16_t device_password_id(static_cast(simple_config_Device_Password_ID_Default_PIN)); + u16_t network_order_device_password_id(eap_htons(device_password_id)); + + status = plaintext_payloads->copy_attribute_data( + simple_config_Attribute_Type_Device_Password_ID, + true, + &network_order_device_password_id, + sizeof(network_order_device_password_id)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + } + + status = encrypt_payloads( + &m_auth_key, + &m_key_wrap_key, + plaintext_payloads, + encrypted_settings); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + automatic_encrypted_settings.do_not_free_variable(); + + status = payloads->add_attribute( + encrypted_settings); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_authenticator_attribute( + &m_received_simple_config_message, + &m_new_simple_config_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(simple_config_state_wait_WSC_DONE); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_WSC_ACK() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_WSC_ACK()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_common_attributes( + payloads, + simple_config_Message_Type_WSC_ACK, + true, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(simple_config_state_failure); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_WSC_NACK() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_WSC_NACK()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_common_attributes( + payloads, + simple_config_Message_Type_WSC_NACK, + true, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(simple_config_state_failure); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_WSC_Done() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_WSC_Done()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, payloads); + + if (payloads == 0 + || payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = add_common_attributes( + payloads, + simple_config_Message_Type_WSC_DONE, + true, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_new_simple_config_message.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->create_simple_config_message( + &m_new_simple_config_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(simple_config_state_simple_config_success); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void simple_config_record_c::send_error_notification(const eap_status_e error) +{ + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("simple_config_record_c::send_error_notification, error=%d\n"), + error)); + + // Notifies the lower level of an authentication error. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_general, + eap_type_none, + eap_state_none, + eap_general_state_authentication_error, + 0, + false); + + notification.set_authentication_error(error); + + get_type_partner()->state_notification(¬ification); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::initalize_error_message_timeout() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + cancel_error_message_timeout(); + + eap_status_e status = get_type_partner()->set_timer( + this, + SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID, + 0, + m_error_message_received_timeout); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID set %d ms, this = 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + m_error_message_received_timeout, + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::cancel_error_message_timeout() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->cancel_timer( + this, + SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID); + + EAP_UNREFERENCED_PARAMETER(status); // in release + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s, SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID cancelled status %d, this = 0x%08x.\n"), + (m_is_client == true ? "client": "server"), + status, + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::initialize_M2D_received_timeout() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + if (m_M2D_received_timeout_active == false) + { + cancel_M2D_received_timeout(); + + status = get_type_partner()->set_timer( + this, + SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID, + 0, + m_error_message_received_timeout); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID set %d ms, this = 0x%08x.\n"), + (m_is_client == true) ? "client": "server", + m_error_message_received_timeout, + this)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID already set.\n"), + (m_is_client == true) ? "client": "server")); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::cancel_M2D_received_timeout() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->cancel_timer( + this, + SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID); + + m_M2D_received_timeout_active = false; + + EAP_UNREFERENCED_PARAMETER(status); // in release + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s, SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID cancelled status %d, this = 0x%08x.\n"), + (m_is_client == true ? "client": "server"), + status, + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::timer_expired( + const u32_t id, + void * data + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(data); // Only trace uses this. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->simple_config_record_c::timer_expired(id 0x%02x, data 0x%08x)\n"), + this, + id, + data)); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + if (id == SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: %s: SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID elapsed.\n"), + (m_is_client == true ? "client": "server") + )); + + status = send_WSC_NACK(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = check_sent_simple_config_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + (void) send_error_notification(m_handshake_error); + + } + else if (id == SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID) + { + (void) m_am_simple_config_services->received_registrar_information(&m_M2D_payloads); + + (void) send_error_notification(m_handshake_error); + + m_M2D_received_timeout_active = false; + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TIMER: %s: unknown timer elapsed.\n"), + (m_is_client == true ? "client": "server") + )); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::timer_delete_data( + const u32_t /*id*/, + void * /*data*/ + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::verify_nonces_and_authenticator( + const eap_variable_data_c * const auth_key, + const eap_variable_data_c * const enrollee_nonce, + const eap_variable_data_c * const registrar_nonce, + const simple_config_payloads_c * const payloads, + const bool check_enrollee_nonce, + const bool check_registrar_nonce, + const bool check_authenticator) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::verify_authenticator()\n"), + (m_is_client == true ? "client": "server"))); + + if (check_enrollee_nonce == true) + { + // Verify Enrollee Nonce. + + simple_config_variable_data_c * const enrollee_nonce_attribute + = payloads->get_attribute_pointer(simple_config_Attribute_Type_Enrollee_Nonce); + if (enrollee_nonce_attribute == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + if (enrollee_nonce->compare( + enrollee_nonce_attribute->get_data(enrollee_nonce_attribute->get_data_length()), + enrollee_nonce_attribute->get_data_length()) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + + if (check_registrar_nonce == true) + { + // Verify Registrar Nonce. + + simple_config_variable_data_c * const registrar_nonce_attribute + = payloads->get_attribute_pointer(simple_config_Attribute_Type_Registrar_Nonce); + if (registrar_nonce_attribute == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + if (registrar_nonce->compare( + registrar_nonce_attribute->get_data(registrar_nonce_attribute->get_data_length()), + registrar_nonce_attribute->get_data_length()) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + + if (check_authenticator == true) + { + // Verify Authenticator. + crypto_sha_256_c sha_256(m_am_tools); + if (sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + crypto_hmac_c hmac_sha_256( + m_am_tools, + &sha_256, + false); + if (hmac_sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG authenticator auth_key"), + auth_key->get_data(), + auth_key->get_data_length())); + + eap_status_e status = hmac_sha_256.hmac_set_key(auth_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG authenticator data"), + m_previous_simple_config_message.get_simple_config_message_data()->get_data(), + m_previous_simple_config_message.get_simple_config_message_data()->get_data_length())); + + status = hmac_sha_256.hmac_update( + m_previous_simple_config_message.get_simple_config_message_data()->get_data(), + m_previous_simple_config_message.get_simple_config_message_data()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->add_payloads_to_simple_config_authenticator( + &hmac_sha_256, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + eap_variable_data_c authenticator(m_am_tools); + + if (authenticator.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = authenticator.set_buffer_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = authenticator.set_data_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t md_length(hmac_sha_256.get_digest_length()); + + status = hmac_sha_256.hmac_final( + authenticator.get_data(hmac_sha_256.get_digest_length()), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG authenticator"), + authenticator.get_data(), + authenticator.get_data_length())); + + status = authenticator.set_data_length(SIMPLE_CONFIG_AUTHENTICATOR_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + simple_config_variable_data_c * const received_authenticator + = payloads->get_attribute_pointer(simple_config_Attribute_Type_Authenticator); + if (received_authenticator == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + if (authenticator.compare( + received_authenticator->get_data(received_authenticator->get_data_length()), + received_authenticator->get_data_length()) != 0) + { + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG local authenticator"), + authenticator.get_data(), + authenticator.get_data_length())); + + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG received authenticator"), + received_authenticator->get_data(received_authenticator->get_data_length()), + received_authenticator->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::verify_authenticator(): Authenticator OK\n"), + (m_is_client == true ? "client": "server"))); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::start_simple_config_authentication( + const eap_variable_data_c * const NAI ///< This is the full NAI of the client. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: start_simple_config_authentication()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_simple_config_start) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + set_state(simple_config_state_process_simple_config_start); + + if (NAI == 0 + || NAI->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + eap_status_e status = m_NAI.set_copy_of_buffer(NAI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_allow_message_send = false; + + status = m_am_simple_config_services->query_network_and_device_parameters(get_state()); + + m_allow_message_send = true; + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_query_network_and_device_parameters() call. + m_pending_query_network_and_device_parameters = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_query_network_and_device_parameters() call. + + status = check_sent_simple_config_message(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +static const simple_config_Attribute_Type_e needed_payloads_of_M1[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + simple_config_Attribute_Type_UUID_E, + simple_config_Attribute_Type_MAC_Address, + simple_config_Attribute_Type_Enrollee_Nonce, + simple_config_Attribute_Type_Public_Key, + simple_config_Attribute_Type_Authentication_Type_Flags, + simple_config_Attribute_Type_Encryption_Type_Flags, + simple_config_Attribute_Type_Connection_Type_Flags, + simple_config_Attribute_Type_Config_Methods, + simple_config_Attribute_Type_Simple_Config_State, + simple_config_Attribute_Type_Manufacturer, + simple_config_Attribute_Type_Model_Name, + simple_config_Attribute_Type_Model_Number, + simple_config_Attribute_Type_Serial_Number, + simple_config_Attribute_Type_Primary_Device_Type, + simple_config_Attribute_Type_Device_Name, + simple_config_Attribute_Type_RF_Band, + simple_config_Attribute_Type_Association_State, + simple_config_Attribute_Type_Device_Password_ID, + simple_config_Attribute_Type_Configuration_Error, + simple_config_Attribute_Type_OS_Version, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M1( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M1()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_M1) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + set_state(simple_config_state_process_M1); + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_M1, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_M1)/sizeof(needed_payloads_of_M1[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save Enrollee Nonce. + status = payloads->get_attribute_data( + simple_config_Attribute_Type_Enrollee_Nonce, + &m_enrollee_nonce); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save Enrollee MAC. + status = payloads->get_attribute_data( + simple_config_Attribute_Type_MAC_Address, + &m_enrollee_mac); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save Public Key. + status = payloads->get_attribute_data( + simple_config_Attribute_Type_Public_Key, + &m_peer_public_dhe_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u16_t data(0ul); + + status = payloads->get_attribute_data( + simple_config_Attribute_Type_Device_Password_ID, + &data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_received_Device_Password_ID = static_cast(data); + } + + eap_variable_data_c dhe_shared_secret(m_am_tools); + + if (dhe_shared_secret.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = generate_dhe_shared_secret(&m_peer_public_dhe_key, &dhe_shared_secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = generate_kdk( + &dhe_shared_secret, + &m_enrollee_nonce, + &m_enrollee_mac, + &m_registrar_nonce, + &m_kdk); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = derive_additional_keys( + &m_kdk, + &m_auth_key, + &m_key_wrap_key, + &m_EMSK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_allow_message_send = false; + + status = m_am_simple_config_services->query_network_and_device_parameters(get_state()); + + m_allow_message_send = true; + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_query_network_and_device_parameters() call. + m_pending_query_network_and_device_parameters = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_query_network_and_device_parameters() call. + + status = check_sent_simple_config_message(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +//-------------------------------------------------- + +static const simple_config_Attribute_Type_e needed_payloads_of_M2[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + simple_config_Attribute_Type_Enrollee_Nonce, + simple_config_Attribute_Type_Registrar_Nonce, + simple_config_Attribute_Type_UUID_R, + simple_config_Attribute_Type_Public_Key, + simple_config_Attribute_Type_Authentication_Type_Flags, + simple_config_Attribute_Type_Encryption_Type_Flags, + simple_config_Attribute_Type_Connection_Type_Flags, + simple_config_Attribute_Type_Config_Methods, + simple_config_Attribute_Type_Manufacturer, + simple_config_Attribute_Type_Model_Name, + simple_config_Attribute_Type_Model_Number, + simple_config_Attribute_Type_Serial_Number, + simple_config_Attribute_Type_Primary_Device_Type, + simple_config_Attribute_Type_Device_Name, + simple_config_Attribute_Type_RF_Band, + simple_config_Attribute_Type_Association_State, + simple_config_Attribute_Type_Configuration_Error, + simple_config_Attribute_Type_Device_Password_ID, + simple_config_Attribute_Type_OS_Version, + simple_config_Attribute_Type_Authenticator, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M2( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M2()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_M2) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_M2, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_M2)/sizeof(needed_payloads_of_M2[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // Verify Enrollee Nonce. + simple_config_variable_data_c * const enrollee_nonce + = payloads->get_attribute_pointer(simple_config_Attribute_Type_Enrollee_Nonce); + if (enrollee_nonce == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + if (m_enrollee_nonce.compare( + enrollee_nonce->get_data(enrollee_nonce->get_data_length()), + enrollee_nonce->get_data_length()) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + + + eap_variable_data_c registrar_nonce_data(m_am_tools); + + if (registrar_nonce_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = payloads->get_attribute_data( + simple_config_Attribute_Type_Registrar_Nonce, + ®istrar_nonce_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_variable_data_c registrar_public_key_data(m_am_tools); + + if (registrar_public_key_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c auth_key(m_am_tools); + + if (auth_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c key_wrap_key(m_am_tools); + + if (key_wrap_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c EMSK(m_am_tools); + + if (EMSK.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + // Save Registrar Public Key. + status = payloads->get_attribute_data( + simple_config_Attribute_Type_Public_Key, + ®istrar_public_key_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_variable_data_c dhe_shared_secret(m_am_tools); + + if (dhe_shared_secret.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = generate_dhe_shared_secret(®istrar_public_key_data, &dhe_shared_secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c kdk(m_am_tools); + + if (kdk.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = generate_kdk( + &dhe_shared_secret, + &m_enrollee_nonce, + &m_enrollee_mac, + ®istrar_nonce_data, + &kdk); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = derive_additional_keys( + &kdk, + &auth_key, + &key_wrap_key, + &EMSK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = verify_nonces_and_authenticator( + &auth_key, + &m_enrollee_nonce, + ®istrar_nonce_data, + payloads, + false, // No Enrolle Nonce + true, // Check Registrar Nonce + true); // Check Authenticator + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Check Device Password ID. + + { + u16_t data(0ul); + + status = payloads->get_attribute_data( + simple_config_Attribute_Type_Device_Password_ID, + &data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_received_Device_Password_ID = static_cast(data); + +#if 0 // This is done to bypass some external registrar. We do not test Device Password ID. + if (m_received_Device_Password_ID != m_local_Device_Password_ID) + { + // No matching Device Password ID. + if (m_local_Device_Password_ID == simple_config_Device_Password_ID_Default_PIN) + { + m_handshake_error = eap_status_pin_code_authentication_not_supported; + } + else if (m_local_Device_Password_ID == simple_config_Device_Password_ID_PushButton) + { + m_handshake_error = eap_status_push_button_authentication_not_supported; + } + else + { + m_handshake_error = eap_status_network_authentication_failure; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_handshake_error); + } +#endif + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Save Registrar Nonce. + status = m_registrar_nonce.set_copy_of_buffer(®istrar_nonce_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save Registrar Public Key. + status = m_peer_public_dhe_key.set_copy_of_buffer(®istrar_public_key_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save Authentication Key. + status = m_auth_key.set_copy_of_buffer(&auth_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save Key Wrap Key. + status = m_key_wrap_key.set_copy_of_buffer(&key_wrap_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save EMSK. + status = m_EMSK.set_copy_of_buffer(&EMSK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = cancel_M2D_received_timeout(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = send_M3(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +static const simple_config_Attribute_Type_e needed_payloads_of_M2D[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + simple_config_Attribute_Type_Enrollee_Nonce, + simple_config_Attribute_Type_Registrar_Nonce, + simple_config_Attribute_Type_UUID_R, + simple_config_Attribute_Type_Authentication_Type_Flags, + simple_config_Attribute_Type_Encryption_Type_Flags, + simple_config_Attribute_Type_Connection_Type_Flags, + simple_config_Attribute_Type_Config_Methods, + simple_config_Attribute_Type_Manufacturer, + simple_config_Attribute_Type_Model_Name, + simple_config_Attribute_Type_Model_Number, + simple_config_Attribute_Type_Serial_Number, + simple_config_Attribute_Type_Primary_Device_Type, + simple_config_Attribute_Type_Device_Name, + simple_config_Attribute_Type_RF_Band, + simple_config_Attribute_Type_Association_State, + simple_config_Attribute_Type_Configuration_Error, + simple_config_Attribute_Type_OS_Version, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M2D( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M2D()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_M2) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_M2D, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_M2D)/sizeof(needed_payloads_of_M2D[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save Registrar Nonce. + status = payloads->get_attribute_data( + simple_config_Attribute_Type_Registrar_Nonce, + &m_registrar_nonce); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_handshake_error == eap_status_ok + || m_handshake_error == eap_status_authentication_failure) + { + u8_t RF_Band(simple_config_RF_Bands_2_4_GHz); + + status = payloads->get_attribute_data( + simple_config_Attribute_Type_RF_Band, + &RF_Band); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + simple_config_RF_Bands_e received_bands = static_cast(RF_Band); + + if ((received_bands & m_Rf_Bands) == 0) + { + // No matching RF Band. + if ((m_Rf_Bands & simple_config_RF_Bands_2_4_GHz) != 0) + { + m_handshake_error = eap_status_rf_band_2_4_ghz_not_supported; + } + else if ((m_Rf_Bands & simple_config_RF_Bands_5_0_GHz) != 0) + { + m_handshake_error = eap_status_rf_band_5_0_ghz_not_supported; + } + } + + } + + if (m_handshake_error == eap_status_ok + || m_handshake_error == eap_status_authentication_failure) + { + u16_t error(0ul); + + status = payloads->get_attribute_data( + simple_config_Attribute_Type_Configuration_Error, + &error); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + simple_config_Configuration_Error_e received_error = static_cast(error); + + if (received_error != simple_config_Configuration_Error_No_Error) + { + if (received_error == simple_config_Configuration_Error_OOB_Interface_Read_Error) + { + m_handshake_error = eap_status_oob_interface_read_error; + } + else if (received_error == simple_config_Configuration_Error_Decryption_CRC_Failure) + { + m_handshake_error = eap_status_decryption_crc_failure; + } + else if (received_error == simple_config_Configuration_Error_2_4_channel_not_supported) + { + m_handshake_error = eap_status_rf_band_2_4_ghz_not_supported; + } + else if (received_error == simple_config_Configuration_Error_5_0_channel_not_supported) + { + m_handshake_error = eap_status_rf_band_5_0_ghz_not_supported; + } + else if (received_error == simple_config_Configuration_Error_Signal_too_weak) + { + m_handshake_error = eap_status_signal_too_weak; + } + else if (received_error == simple_config_Configuration_Error_Network_auth_failure) + { + m_handshake_error = eap_status_network_authentication_failure; + } + else if (received_error == simple_config_Configuration_Error_Network_association_failure) + { + m_handshake_error = eap_status_network_association_failure; + } + else if (received_error == simple_config_Configuration_Error_No_DHCP_response) + { + m_handshake_error = eap_status_no_dhcp_response; + } + else if (received_error == simple_config_Configuration_Error_Failed_DHCP_config) + { + m_handshake_error = eap_status_failed_dhcp_configure; + } + else if (received_error == simple_config_Configuration_Error_IP_address_conflict) + { + m_handshake_error = eap_status_ip_address_conflict; + } + else if (received_error == simple_config_Configuration_Error_Couldnt_connect_to_Registrar) + { + m_handshake_error = eap_status_could_not_connect_to_registrar; + } + else if (received_error == simple_config_Configuration_Error_Multiple_PBC_sessions_detected) + { + m_handshake_error = eap_status_multiple_pbc_sessions_detected; + } + else if (received_error == simple_config_Configuration_Error_Rogue_activity_suspected) + { + m_handshake_error = eap_status_rogue_activity_suspected; + } + else if (received_error == simple_config_Configuration_Error_Device_busy) + { + m_handshake_error = eap_status_device_busy; + } + else if (received_error == simple_config_Configuration_Error_Setup_locked) + { + m_handshake_error = eap_status_setup_locked; + } + else if (received_error == simple_config_Configuration_Error_Message_Timeout) + { + m_handshake_error = eap_status_message_timeout; + } + else if (received_error == simple_config_Configuration_Error_Registration_Session_Timeout) + { + m_handshake_error = eap_status_registration_session_timeout; + } + else if (received_error == simple_config_Configuration_Error_Device_Password_Auth_Failure) + { + m_handshake_error = eap_status_device_password_authentication_failure; + } + } + + } + + if (m_handshake_error == eap_status_ok) + { + m_handshake_error = eap_status_authentication_failure; + } + + status = initialize_M2D_received_timeout(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + simple_config_payloads_c * const copied_payloads = payloads->copy(); + + if (copied_payloads == 0 + || copied_payloads->get_is_valid() == false) + { + delete copied_payloads; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_M2D_payloads.add_object(copied_payloads, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = send_WSC_ACK(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +static const simple_config_Attribute_Type_e needed_payloads_of_M3[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + simple_config_Attribute_Type_Registrar_Nonce, + simple_config_Attribute_Type_E_Hash1, + simple_config_Attribute_Type_E_Hash2, + simple_config_Attribute_Type_Authenticator, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M3( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M3()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_M3) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_M3, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_M3)/sizeof(needed_payloads_of_M3[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Save E-Hash1 and E-Hash2 + + status = payloads->get_attribute_data( + simple_config_Attribute_Type_E_Hash1, + &m_EHash1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->get_attribute_data( + simple_config_Attribute_Type_E_Hash2, + &m_EHash2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = send_M4(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +//-------------------------------------------------- + +static const simple_config_Attribute_Type_e needed_payloads_of_M4[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + simple_config_Attribute_Type_Enrollee_Nonce, + simple_config_Attribute_Type_R_Hash1, + simple_config_Attribute_Type_R_Hash2, + simple_config_Attribute_Type_Encrypted_Settings, + simple_config_Attribute_Type_Authenticator, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M4( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M4()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_M4) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_M4, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_M4)/sizeof(needed_payloads_of_M4[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Save R-Hash1 and R-Hash2 + + status = payloads->get_attribute_data( + simple_config_Attribute_Type_R_Hash1, + &m_RHash1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = payloads->get_attribute_data( + simple_config_Attribute_Type_R_Hash2, + &m_RHash2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // Decrypt Encrypted Settings. + simple_config_variable_data_c * const Encrypted_Settings + = payloads->get_attribute_pointer(simple_config_Attribute_Type_Encrypted_Settings); + if (Encrypted_Settings == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_plaintext_payloads(m_am_tools, plaintext_payloads); + + if (plaintext_payloads == 0 + || plaintext_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = decrypt_payloads( + &m_auth_key, + &m_key_wrap_key, + Encrypted_Settings, + plaintext_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = plaintext_payloads->get_attribute_data( + simple_config_Attribute_Type_R_SNonce1, + &m_R_SNonce1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + eap_variable_data_c local_RHash1(m_am_tools); + + if (local_RHash1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Verify m_R_SNonce1 and m_RHash1. + status = generate_er_hashs( + true, + &m_device_password, + &m_own_public_dhe_key, + &m_peer_public_dhe_key, + &m_PSK1, + &m_R_SNonce1, + &local_RHash1, + 0, + 0, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Compare RHash1. + if (local_RHash1.compare(&m_RHash1) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_device_password_authentication_failure); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = send_M5(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +static const simple_config_Attribute_Type_e needed_payloads_of_M5[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + simple_config_Attribute_Type_Registrar_Nonce, + simple_config_Attribute_Type_Encrypted_Settings, + simple_config_Attribute_Type_Authenticator, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M5( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M5()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_M5) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_M5, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_M5)/sizeof(needed_payloads_of_M5[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // Decrypt Encrypted Settings. + simple_config_variable_data_c * const Encrypted_Settings + = payloads->get_attribute_pointer(simple_config_Attribute_Type_Encrypted_Settings); + if (Encrypted_Settings == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_plaintext_payloads(m_am_tools, plaintext_payloads); + + if (plaintext_payloads == 0 + || plaintext_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = decrypt_payloads( + &m_auth_key, + &m_key_wrap_key, + Encrypted_Settings, + plaintext_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = plaintext_payloads->get_attribute_data( + simple_config_Attribute_Type_E_SNonce1, + &m_E_SNonce1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + eap_variable_data_c local_EHash1(m_am_tools); + + if (local_EHash1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Verify m_E_SNonce1 and m_EHash1. + status = generate_er_hashs( + true, + &m_device_password, + &m_peer_public_dhe_key, + &m_own_public_dhe_key, + &m_PSK1, + &m_E_SNonce1, + &local_EHash1, + 0, + 0, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Compare EHash1. + if (local_EHash1.compare(&m_EHash1) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_device_password_authentication_failure); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = send_M6(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +//-------------------------------------------------- + +static const simple_config_Attribute_Type_e needed_payloads_of_M6[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + simple_config_Attribute_Type_Enrollee_Nonce, + simple_config_Attribute_Type_Encrypted_Settings, + simple_config_Attribute_Type_Authenticator, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M6( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M6()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_M6) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_M6, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_M6)/sizeof(needed_payloads_of_M6[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // Decrypt Encrypted Settings. + simple_config_variable_data_c * const Encrypted_Settings + = payloads->get_attribute_pointer(simple_config_Attribute_Type_Encrypted_Settings); + if (Encrypted_Settings == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_plaintext_payloads(m_am_tools, plaintext_payloads); + + if (plaintext_payloads == 0 + || plaintext_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = decrypt_payloads( + &m_auth_key, + &m_key_wrap_key, + Encrypted_Settings, + plaintext_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = plaintext_payloads->get_attribute_data( + simple_config_Attribute_Type_R_SNonce2, + &m_R_SNonce2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + eap_variable_data_c local_RHash2(m_am_tools); + + if (local_RHash2.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Verify m_R_SNonce2 and m_RHash2. + status = generate_er_hashs( + true, + &m_device_password, + &m_own_public_dhe_key, + &m_peer_public_dhe_key, + 0, + 0, + 0, + &m_PSK2, + &m_R_SNonce2, + &local_RHash2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Compare RHash2. + if (local_RHash2.compare(&m_RHash2) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_device_password_authentication_failure); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = send_M7(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +static const simple_config_Attribute_Type_e needed_payloads_of_M7[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + simple_config_Attribute_Type_Registrar_Nonce, + simple_config_Attribute_Type_Encrypted_Settings, + simple_config_Attribute_Type_Authenticator, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M7( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M7()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_M7) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_M7, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_M7)/sizeof(needed_payloads_of_M7[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // Decrypt Encrypted Settings. + simple_config_variable_data_c * const Encrypted_Settings + = payloads->get_attribute_pointer(simple_config_Attribute_Type_Encrypted_Settings); + if (Encrypted_Settings == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_plaintext_payloads(m_am_tools, plaintext_payloads); + + if (plaintext_payloads == 0 + || plaintext_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = decrypt_payloads( + &m_auth_key, + &m_key_wrap_key, + Encrypted_Settings, + plaintext_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = plaintext_payloads->get_attribute_data( + simple_config_Attribute_Type_E_SNonce2, + &m_E_SNonce2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + eap_variable_data_c local_EHash2(m_am_tools); + + if (local_EHash2.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Verify m_E_SNonce2 and m_EHash2. + status = generate_er_hashs( + true, + &m_device_password, + &m_peer_public_dhe_key, + &m_own_public_dhe_key, + 0, + 0, + 0, + &m_PSK2, + &m_E_SNonce2, + &local_EHash2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Compare RHash2. + if (local_EHash2.compare(&m_EHash2) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_device_password_authentication_failure); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = send_M8(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +//-------------------------------------------------- + +eap_status_e simple_config_record_c::fix_incorrect_network_key( + eap_variable_data_c * const network_key, + const simple_config_Authentication_Type_e authentication_type) +{ + if (authentication_type == simple_config_Authentication_Type_WPAPSK + || authentication_type == simple_config_Authentication_Type_WPA2PSK) + { + // For example, Vista External Registar sends incorrect WPA(2)PSK that includes terminating NULL. + // Check the PSK is passphrase <= 64 bytes in length and the last byte is 0x00. + const u32_t ONE_CHARACTER_LENGTH = 1ul; + const u8_t STRING_TERMINATING_NULL = 0x00; + + if (network_key->get_data_length() > 0ul) + { + if (network_key->get_data_offset(network_key->get_data_length()-1ul, ONE_CHARACTER_LENGTH) != 0 + && *(network_key->get_data_offset(network_key->get_data_length()-1ul, ONE_CHARACTER_LENGTH)) == STRING_TERMINATING_NULL) + { + // Check for passphrase characters. If it includes only passphrase characters and the last byte is NULL + // we assume it is broken passphrase. + + bool remove_terminating_null = true; + + if (network_key->get_data_length() == 2ul*EAPOL_WPA_PSK_LENGTH_BYTES) + { + for (u32_t ind = 0; ind < network_key->get_data_length()-1ul; ind++) + { + u8_t * const character = network_key->get_data_offset(ind, 1); + if (character == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + if((*character < 32) || (126 < *character)) + { + // This is not passphrase. + remove_terminating_null = false; + break; + } + } + } + else + { + // Because the length is less than 64 bytes, this is passprase, and we remove the terminating NULL. + } + + if (remove_terminating_null == true) + { + network_key->set_data_length(network_key->get_data_length()-1ul); + } + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +static const simple_config_Attribute_Type_e needed_payloads_of_M8[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M8( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M8()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_M8) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_M8, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_M8)/sizeof(needed_payloads_of_M8[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + simple_config_payloads_c * other_configuration = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_other_configuration(m_am_tools, other_configuration); + + if (other_configuration == 0 + || other_configuration->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_array_c * credential_array = new eap_array_c(m_am_tools); + eap_automatic_variable_c > automatic_credential_array(m_am_tools, credential_array); + + if (credential_array == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + // Decrypt Encrypted Settings. + simple_config_variable_data_c * const Encrypted_Settings + = payloads->get_attribute_pointer(simple_config_Attribute_Type_Encrypted_Settings); + if (Encrypted_Settings == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_plaintext_payloads(m_am_tools, plaintext_payloads); + + if (plaintext_payloads == 0 + || plaintext_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = decrypt_payloads( + &m_auth_key, + &m_key_wrap_key, + Encrypted_Settings, + plaintext_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + simple_config_variable_data_c * Credential_Attribute + = plaintext_payloads->get_attribute_pointer(simple_config_Attribute_Type_Credential); + if (Credential_Attribute == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + do + { + simple_config_credential_c * credential = new simple_config_credential_c(m_am_tools); + + eap_automatic_variable_c automatic_credential(m_am_tools, credential); + + if (credential == 0 + || credential->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + simple_config_payloads_c * Credential_payloads = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_Credential_payloads(m_am_tools, Credential_payloads); + + if (Credential_payloads == 0 + || Credential_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t payload_length(Credential_Attribute->get_data_length()); + u32_t padding_length(0ul); + + status = Credential_payloads->parse_simple_config_payloads( + Credential_Attribute->get_data(Credential_Attribute->get_data_length()), + &payload_length, + &padding_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u8_t network_index(0ul); + + status = Credential_payloads->get_attribute_data( + simple_config_Attribute_Type_Network_Index, + &network_index); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + credential->set_network_index(network_index); + } + + status = Credential_payloads->get_attribute_data( + simple_config_Attribute_Type_SSID, + credential->get_SSID()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u16_t data(0ul); + + status = Credential_payloads->get_attribute_data( + simple_config_Attribute_Type_Authentication_Type, + &data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + credential->set_Authentication_Type(static_cast(data)); + } + + { + u16_t data(0ul); + + status = Credential_payloads->get_attribute_data( + simple_config_Attribute_Type_Encryption_Type, + &data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + credential->set_Encryption_Type(static_cast(data)); + } + + { + simple_config_variable_data_c * Network_Key_Index + = Credential_payloads->get_attribute_pointer(simple_config_Attribute_Type_Network_Key_Index); + // NOTE, this is optional. Omitted Network_Key_Index defaults to 1. + + simple_config_variable_data_c * Network_Key + = Credential_payloads->get_attribute_pointer(simple_config_Attribute_Type_Network_Key); + + + if ( Network_Key == 0 + && (credential->get_Authentication_Type() != simple_config_Authentication_Type_Open + || credential->get_Encryption_Type() != simple_config_Encryption_Type_None) ) + { + // We fail since the required Network Key TLV is missing in a non-open mode. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + else if ( Network_Key == 0 ) + { + // This is implemented for IOP reasons. The AP does not send the + // Network Key TLV (required TLV in the spec) in the Open security mode so we do not + // require it. The TLV in Open mode would be empty anyway (length would be zero). + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("simple_config_record_c::process_M8(): Network Key TLV missing but Open network. This is ok.\n"))); + + // Just add empty parameters + network_key_and_index_c * const obj = new network_key_and_index_c(m_am_tools); + if(obj != 0) + { + status = credential->get_network_keys()->add_object(obj, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + } + else + { + // Normal case, i.e Network Key TLV exists + do + { + network_key_and_index_c * const obj = new network_key_and_index_c(m_am_tools); + + if (obj != 0) + { + if (Network_Key_Index != 0) + { + const u8_t * const network_key_index = Network_Key_Index->get_header()->get_data(sizeof(u8_t)); + if (network_key_index == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + obj->set_network_key_index(*network_key_index); + } + else + { + obj->set_network_key_index(SIMPLE_CONFIG_DEFAULT_NETWORK_KEY_INDEX); + } + + status = obj->get_network_key()->set_copy_of_buffer( + Network_Key->get_header()->get_data( + Network_Key->get_header()->get_data_length()), + Network_Key->get_header()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // For example, Vista External Registar sends incorrect WPA(2)PSK that includes terminating NULL. + status = fix_incorrect_network_key(obj->get_network_key(), credential->get_Authentication_Type()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = credential->get_network_keys()->add_object(obj, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (Network_Key_Index != 0) + { + Network_Key_Index = Network_Key_Index->get_next_payload_with_same_attribute_type(); + } + + Network_Key = Network_Key->get_next_payload_with_same_attribute_type(); + } + while(Network_Key != 0); + } + } + + status = Credential_payloads->get_attribute_data( + simple_config_Attribute_Type_MAC_Address, + credential->get_MAC_address()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + automatic_credential.do_not_free_variable(); + + status = credential_array->add_object(credential, true); + + Credential_Attribute = Credential_Attribute->get_next_payload_with_same_attribute_type(); + } + while (Credential_Attribute != 0); + + // This is optional attribute. + if (plaintext_payloads->get_attribute_pointer( + simple_config_Attribute_Type_New_Password) != 0) + { + status = plaintext_payloads->get_attribute_data( + simple_config_Attribute_Type_New_Password, + &m_new_password); + if (status != eap_status_ok + && status != eap_status_missing_payload) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (plaintext_payloads->get_attribute_pointer( + simple_config_Attribute_Type_Device_Password_ID) != 0) + { + u16_t data(0ul); + + // This is optional attribute. + status = plaintext_payloads->get_attribute_data( + simple_config_Attribute_Type_Device_Password_ID, + &data); + if (status != eap_status_ok + && status != eap_status_missing_payload) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (status == eap_status_ok) + { + m_new_Device_Password_ID = static_cast(data); + } + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_am_simple_config_services->save_simple_config_session( + simple_config_state_simple_config_success, + credential_array, + &m_new_password, + m_new_Device_Password_ID, + other_configuration); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = send_WSC_Done(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +static const simple_config_Attribute_Type_e needed_payloads_of_WSC_ACK[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_WSC_ACK( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_WSC_ACK()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_WSC_ACK) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_WSC_ACK, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_WSC_ACK)/sizeof(needed_payloads_of_WSC_ACK[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +static const simple_config_Attribute_Type_e needed_payloads_of_WSC_NACK[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_WSC_NACK( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_WSC_NACK()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_WSC_NACK, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_WSC_NACK)/sizeof(needed_payloads_of_WSC_NACK[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_handshake_error != eap_status_ok) + { + (void) send_error_notification(m_handshake_error); + } + + set_state(simple_config_state_failure); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +static const simple_config_Attribute_Type_e needed_payloads_of_WSC_DONE[] + = { + simple_config_Attribute_Type_Version, + simple_config_Attribute_Type_Message_Type, + }; + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_WSC_DONE( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_WSC_DONE()\n"), + (m_is_client == true ? "client": "server"))); + + if (verify_state(simple_config_state_wait_WSC_DONE) == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + eap_status_e status = payloads->check_payloads_existense( + needed_payloads_of_WSC_DONE, // const simple_config_Attribute_Type_e * const needed_payloads, + sizeof(needed_payloads_of_WSC_DONE)/sizeof(needed_payloads_of_WSC_DONE[0])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(simple_config_state_simple_config_success); + + { + // Send state notification to lower layer. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eap, + eap_type_none, + eap_state_none, + eap_state_authentication_finished_successfully, + 0ul, + false); + get_type_partner()->state_notification(¬ification); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_simple_config_attributes( + const simple_config_payloads_c * const payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_simple_config_attributes()\n"), + (m_is_client == true ? "client": "server"))); + + simple_config_variable_data_c * const message_type_payload + = payloads->get_attribute_pointer(simple_config_Attribute_Type_Message_Type); + if (message_type_payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + u8_t * const Message_type_data = message_type_payload->get_header()->get_data(sizeof(u8_t)); + if (Message_type_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + const simple_config_Message_Type_e Message_type(static_cast(*Message_type_data)); + + eap_status_e status(eap_status_process_general_error); + + + { + eap_simple_config_trace_string_c trace_string; + EAP_UNREFERENCED_PARAMETER(trace_string); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_simple_config_attributes(): Received message %s=%d\n"), + (m_is_client == true ? "client": "server"), + trace_string.get_message_type_string(Message_type), + Message_type)); + } + + + switch(Message_type) + { + case simple_config_Message_Type_M1: + case simple_config_Message_Type_M2: + case simple_config_Message_Type_M2D: + // Check is done later inside correcponding function. + break; + case simple_config_Message_Type_M3: + case simple_config_Message_Type_M5: + case simple_config_Message_Type_M7: + + status = verify_nonces_and_authenticator( + &m_auth_key, + &m_enrollee_nonce, + &m_registrar_nonce, + payloads, + false, // No Enrolle Nonce + true, // Check Registrar Nonce + true); // Check Authenticator + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + break; + case simple_config_Message_Type_M4: + case simple_config_Message_Type_M6: + case simple_config_Message_Type_M8: + status = verify_nonces_and_authenticator( + &m_auth_key, + &m_enrollee_nonce, + &m_registrar_nonce, + payloads, + true, // Check Enrolle Nonce + false, // No Registrar Nonce + true); // Check Authenticator + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + break; + case simple_config_Message_Type_WSC_ACK: + case simple_config_Message_Type_WSC_NACK: + case simple_config_Message_Type_WSC_DONE: + { + bool check_enrollee_nonce(true); + bool check_registrar_nonce(true); + + if (get_state() == simple_config_state_wait_M1) + { + check_enrollee_nonce = false; + check_registrar_nonce = false; + } + + if (get_state() == simple_config_state_wait_M2) + { + check_registrar_nonce = false; + } + + status = verify_nonces_and_authenticator( + &m_auth_key, + &m_enrollee_nonce, + &m_registrar_nonce, + payloads, + check_enrollee_nonce, + check_registrar_nonce, + false); // No Authenticator + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + break; + default: + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + }; + + + switch(Message_type) + { + + case simple_config_Message_Type_M2: + status = process_M2(payloads); + break; + case simple_config_Message_Type_M2D: + status = process_M2D(payloads); + break; + case simple_config_Message_Type_M4: + status = process_M4(payloads); + break; + case simple_config_Message_Type_M6: + status = process_M6(payloads); + break; + case simple_config_Message_Type_M8: + status = process_M8(payloads); + break; + case simple_config_Message_Type_WSC_ACK: + status = process_WSC_ACK(payloads); + break; + case simple_config_Message_Type_WSC_NACK: + status = process_WSC_NACK(payloads); + break; + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + case simple_config_Message_Type_M1: + status = process_M1(payloads); + break; + case simple_config_Message_Type_M3: + status = process_M3(payloads); + break; + case simple_config_Message_Type_M5: + status = process_M5(payloads); + break; + case simple_config_Message_Type_M7: + status = process_M7(payloads); + break; + case simple_config_Message_Type_WSC_DONE: + status = process_WSC_DONE(payloads); + break; + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + default: + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: SIMPLE_CONFIG: %s: parse_function: process_simple_config_attributes(): Unknown message 0x%08x\n"), + (m_is_client == true ? "client": "server"), + Message_type)); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + }; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_simple_config_message() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_simple_config_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG-message"), + m_received_simple_config_message.get_simple_config_message_data()->get_data( + m_received_simple_config_message.get_simple_config_message_data()->get_data_length()), + m_received_simple_config_message.get_simple_config_message_data()->get_data_length())); + + u32_t next_start_offset = 0ul; + u32_t simple_config_packet_length = m_received_simple_config_message.get_simple_config_message_data()->get_data_length(); + + m_received_payloads.reset(); + + u32_t padding_length(0ul); + + eap_status_e status = m_received_payloads.parse_simple_config_payloads( + m_received_simple_config_message.get_simple_config_message_data()->get_data( + m_received_simple_config_message.get_simple_config_message_data()->get_data_length()), + &simple_config_packet_length, + &padding_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (next_start_offset != simple_config_packet_length) + { + // Parsed packet length does not match with received packet length. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN( + m_am_tools, + eap_status_process_illegal_packet_error); + } + + + status = process_simple_config_attributes(&m_received_payloads); + + if (status == eap_status_ok) + { + status = cancel_error_message_timeout(); + } + else + { + if (m_handshake_error == eap_status_ok) + { + // Save the first error. + m_handshake_error = status; + } + + status = initalize_error_message_timeout(); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::are_pending_queries_completed() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_pending_request; + + if (m_pending_query_network_and_device_parameters == false) + { + status = eap_status_ok; + } + + eap_status_string_c status_string; + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: pending_function: are_pending_queries_completed(): %s\n"), + (m_is_client == true ? "client": "server"), + status_string.get_status_string(status))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::indicate_state_to_lower_layer( + const simple_config_state_e indicated_state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Notify lower layer the state of SIMPLE_CONFIG. + + eap_simple_config_trace_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: state_function: indicate_state_to_lower_layer(): %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_state_string(indicated_state))); + + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_internal_type, + eap_type_none, + simple_config_state_none, + indicated_state, + 0, + false); + get_type_partner()->state_notification(¬ification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::indicate_messages_processed() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Notify lower layer that SIMPLE_CONFIG-messages are processed. + + eap_simple_config_trace_string_c state_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: state_function: indicate_messages_processed(): %s\n"), + (m_is_client == true ? "client": "server"), + state_string.get_state_string(m_simple_config_state))); + + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_internal_type, + eap_type_none, + simple_config_state_none, + simple_config_state_pending_simple_config_messages_processed, + 0, + false); + get_type_partner()->state_notification(¬ification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_simple_config_message() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: send_function: simple_config_record_c::send_simple_config_message()\n"), + (m_is_client == true ? "client": "server"))); + + eap_variable_data_c simple_config_message_buffer(m_am_tools); + + if (simple_config_message_buffer.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // -------------------------------------------------------------------- + + eap_buf_chain_wr_c sent_packet( + eap_write_buffer, + m_am_tools, + m_new_simple_config_message.get_simple_config_message_data()->get_data(simple_config_message_buffer.get_data_length()), + m_new_simple_config_message.get_simple_config_message_data()->get_data_length(), + false, + false, + 0ul); + if (sent_packet.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send SIMPLE_CONFIG-message"), + sent_packet.get_data(sent_packet.get_data_length()), + sent_packet.get_data_length())); + + // -------------------------------------------------------------------- + + // Send message + eap_status_e status = get_type_partner()->simple_config_packet_send( + &sent_packet, + m_current_simple_config_message_type); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_previous_simple_config_message.get_simple_config_message_data()->set_copy_of_buffer( + m_new_simple_config_message.get_simple_config_message_data()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_new_simple_config_message.reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::check_sent_simple_config_message() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: send_function: simple_config_record_c::check_sent_simple_config_message()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e msg_status = eap_status_authentication_failure; + + if (m_already_in_completion_action_check == true) + { + // This is recursive call. Do not process yet. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + if (m_force_simple_config_message_send == true) + { + // There may be an alert message pending. + msg_status = send_simple_config_message(); + } + else + { + msg_status = are_pending_queries_completed(); + if (msg_status == eap_status_ok) + { + eap_status_e compl_status = completion_action_check(); + + if (compl_status == eap_status_pending_request) + { + // Some asyncronous query is still pending. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, compl_status); + } + else if (compl_status != eap_status_ok) + { + // There may be Alert message to be sent. + msg_status = compl_status; + } + + + if (m_allow_message_send == true) + { + if (msg_status == eap_status_ok + && m_new_simple_config_message.get_simple_config_message_data()->get_is_valid_data() == true) + { + // We could send the pending SIMPLE_CONFIG-messages. + msg_status = send_simple_config_message(); + } + else if (m_force_simple_config_message_send == true // There may be Alert message to be sent. + && m_new_simple_config_message.get_simple_config_message_data()->get_is_valid_data() == true) + { + // We could send the pending SIMPLE_CONFIG-messages. + send_simple_config_message(); + } + else + { + // No message to sent. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: send_function: simple_config_record_c::check_sent_simple_config_message(), ") + EAPL("No message to sent.\n"), + (m_is_client == true ? "client": "server"))); + } + } + + if (msg_status == eap_status_ok + && m_allow_message_send == true) + { + eap_status_e indication_status = indicate_messages_processed(); + if (indication_status != eap_status_ok) + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, indication_status); + } + } + } + } + + if (get_state() == simple_config_state_simple_config_success) + { + // Notify lower layer that SIMPLE_CONFIG/PEAP ended successfully + + eap_simple_config_trace_string_c simple_config_trace; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: SIMPLE_CONFIG/PEAP authentication ") + EAPL("SUCCESS: EAP-type %s\n"), + (m_is_client == true ? "client": "server"), + eap_header_string_c::get_eap_type_string(eap_expanded_type_simple_config.get_type()))); + + eap_status_e notification_status = indicate_state_to_lower_layer(get_state()); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } + else if (get_state() == simple_config_state_failure) + { + eap_simple_config_trace_string_c simple_config_trace; + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: SIMPLE_CONFIG/PEAP authentication ") + EAPL("FAILED: EAP-type %s\n"), + (m_is_client == true ? "client": "server"), + eap_header_string_c::get_eap_type_string(eap_expanded_type_simple_config.get_type()))); + + eap_status_e notification_status = indicate_state_to_lower_layer(get_state()); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, msg_status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::packet_process( + eap_variable_data_c * const simple_config_packet, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_simple_config_trace_string_c state_trace; + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: packet_process(): state %s\n"), + (m_is_client == true ? "client": "server"), + state_trace.get_state_string(get_state()))); + + m_received_simple_config_message.reset(); + + eap_status_e status = m_received_simple_config_message.set_simple_config_message_data( + simple_config_packet, + received_eap_identifier); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_automatic_simple_value_c restore_allow_message_send( + m_am_tools, + &m_allow_message_send, + true); + + // Packet send is delayed until after the process_simple_config_message() function returns. + m_allow_message_send = false; + + status = process_simple_config_message(); + + m_allow_message_send = true; + + + if (status != eap_status_pending_request) + { + // Note this call will return eap_status_pending_request if any asyncronous call is pending. + eap_status_e send_status = check_sent_simple_config_message(); + if (send_status != eap_status_ok) + { + status = send_status; + } + } + + if (get_state() == simple_config_state_simple_config_success) + { + // Send state notification to lower layer. + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_eap, + eap_type_none, + eap_state_none, + eap_state_authentication_finished_successfully, + 0ul, + false); + get_type_partner()->state_notification(¬ification); + } + + + if (status == eap_status_success + && get_state() != simple_config_state_simple_config_success) + { + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool simple_config_record_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: simple_config_record_c::reset(): this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + completion_action_clenup(); + + m_M2D_payloads.reset(); + + m_handshake_error = eap_status_ok; + m_Rf_Bands = simple_config_RF_Bands_2_4_GHz; + + m_received_simple_config_message.reset(); + m_new_simple_config_message.reset(); + m_own_private_dhe_key.reset(); + m_own_public_dhe_key.reset(); + m_peer_public_dhe_key.reset(); + m_shared_dh_key.reset(); + m_dhe_prime.reset(); + m_dhe_group_generator.reset(); + m_signed_message_hash.reset(); + m_NAI.reset(); + m_NAI_realm.reset(); + + m_completion_queue.reset(); + + m_key_material_generated = false; + + m_force_simple_config_message_send = false; + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + if (m_is_client == false) + { + // Server + // NOTE: set_state() function cannot reset state. + m_simple_config_state = simple_config_state_wait_M1; + } + else +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + { + // Client + // NOTE: set_state() function cannot reset state. + m_simple_config_state = simple_config_state_wait_simple_config_start; + } + + eap_status_e status = generate_dhe_keys(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_dhe_keys() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: generate_dhe_keys()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eap_status_not_supported; + + { + m_dhe_prime.reset(); + + status = m_dhe_prime.add_data(SIMPLE_CONFIG_DIFFIE_HELLMAN_PRIME, sizeof(SIMPLE_CONFIG_DIFFIE_HELLMAN_PRIME)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_dhe_group_generator.reset(); + + status = m_dhe_group_generator.add_data(SIMPLE_CONFIG_DIFFIE_HELLMAN_GROUP_GENERATOR, sizeof(SIMPLE_CONFIG_DIFFIE_HELLMAN_GROUP_GENERATOR)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + crypto_ephemeral_diffie_hellman_c dhe(m_am_tools); + + if (dhe.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: dhe.generate_diffie_hellman_keys()\n"), + (m_is_client == true ? "client": "server"))); + + status = dhe.generate_diffie_hellman_keys( + &m_own_private_dhe_key, + &m_own_public_dhe_key, + m_dhe_prime.get_data(m_dhe_prime.get_data_length()), + m_dhe_prime.get_data_length(), + m_dhe_group_generator.get_data(m_dhe_group_generator.get_data_length()), + m_dhe_group_generator.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_dhe_shared_secret( + const eap_variable_data_c * const peer_public_key_data, + eap_variable_data_c * const dhe_shared_secret) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: generate_dhe_shared_secret()\n"), + (m_is_client == true ? "client": "server"))); + + + if (m_dhe_prime.get_is_valid_data() == false + || m_dhe_group_generator.get_is_valid_data() == false + || m_own_private_dhe_key.get_is_valid_data() == false + || peer_public_key_data->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + crypto_ephemeral_diffie_hellman_c dhe(m_am_tools); + + if (dhe.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: dhe.generate_g_power_to_xy()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = dhe.generate_g_power_to_xy( + &m_own_private_dhe_key, + peer_public_key_data, + dhe_shared_secret, + m_dhe_prime.get_data(), + m_dhe_prime.get_data_length(), + m_dhe_group_generator.get_data(), + m_dhe_group_generator.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("SIMPLE_CONFIG: dhe_shared_secret"), + dhe_shared_secret->get_data(dhe_shared_secret->get_data_length()), + dhe_shared_secret->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_nonce( + eap_variable_data_c * const nonce, + const u32_t nonce_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: generate_nonce()\n"), + (m_is_client == true ? "client": "server"))); + + // Creates a Nonce. + crypto_random_c rand(m_am_tools); + + eap_status_e status = nonce->set_buffer_length(nonce_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = nonce->set_data_length(nonce->get_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rand.get_rand_bytes(nonce->get_data(), nonce->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_erhash( + const bool verify, + const eap_variable_data_c * const half_of_device_password, + const eap_variable_data_c * const PKE, + const eap_variable_data_c * const PKR, + eap_variable_data_c * const PSKn, + eap_variable_data_c * const ERSn, + eap_variable_data_c * const ERHash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: generate_erhash()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: PKE"), + PKE->get_data(), + PKE->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: PKR"), + PKR->get_data(), + PKR->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: half_of_device_password"), + half_of_device_password->get_data(), + half_of_device_password->get_data_length())); + + eap_status_e status = keyed_hmac(&m_auth_key, half_of_device_password, PSKn); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = PSKn->set_data_length(SIMPLE_CONFIG_PSKn_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: PSKn"), + PSKn->get_data(), + PSKn->get_data_length())); + + if (verify == false) + { + status = generate_nonce( + ERSn, + SIMPLE_CONFIG_ESn_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: generate_erhash(): No new nonce is generated,\n"), + (m_is_client == true ? "client": "server"))); + EAP_ASSERT(ERSn != 0 && ERSn->get_is_valid_data() == true); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: ERSn"), + ERSn->get_data(), + ERSn->get_data_length())); + + { + eap_variable_data_c hmac_input(m_am_tools); + + if (hmac_input.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = hmac_input.add_data(ERSn); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_input.add_data(PSKn); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_input.add_data(PKE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_input.add_data(PKR); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = keyed_hmac(&m_auth_key, &hmac_input, ERHash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: ERHash"), + ERHash->get_data(), + ERHash->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_er_hashs( + const bool verify, + const eap_variable_data_c * const device_password, + const eap_variable_data_c * const PKE, + const eap_variable_data_c * const PKR, + eap_variable_data_c * const PSK1, + eap_variable_data_c * const ER_S1, + eap_variable_data_c * const ER_Hash1, + eap_variable_data_c * const PSK2, + eap_variable_data_c * const ER_S2, + eap_variable_data_c * const ER_Hash2) +{ + + eap_variable_data_c first_half_of_device_password(m_am_tools); + + if (first_half_of_device_password.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = first_half_of_device_password.set_buffer(device_password); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = first_half_of_device_password.set_data_length((device_password->get_data_length() + 1ul) / 2ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (ER_Hash1 != 0) + { + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Create E/R-Hash1. + + status = generate_erhash( + verify, + &first_half_of_device_password, + PKE, + PKR, + PSK1, + ER_S1, + ER_Hash1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: ER_Hash1"), + ER_Hash1->get_data(), + ER_Hash1->get_data_length())); + } + + if (ER_Hash2 != 0) + { + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Create E/R-Hash2. + + eap_variable_data_c second_half_of_device_password(m_am_tools); + + if (second_half_of_device_password.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t second_half_length(device_password->get_data_length() / 2ul); + + eap_status_e status = second_half_of_device_password.set_buffer( + device_password->get_data_offset(first_half_of_device_password.get_data_length(), second_half_length), + second_half_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = generate_erhash( + verify, + &second_half_of_device_password, + PKE, + PKR, + PSK2, + ER_S2, + ER_Hash2); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: ER_Hash2"), + ER_Hash2->get_data(), + ER_Hash2->get_data_length())); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::keyed_hmac( + const eap_variable_data_c * const key, + const eap_variable_data_c * const input, + eap_variable_data_c * const output) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: keyed_hmac()\n"), + (m_is_client == true ? "client": "server"))); + + crypto_sha_256_c sha_256(m_am_tools); + if (sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + crypto_hmac_c hmac_sha_256( + m_am_tools, + &sha_256, + false); + if (hmac_sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: key"), + key->get_data(), + key->get_data_length())); + + eap_status_e status = hmac_sha_256.hmac_set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_sha_256.hmac_update( + input->get_data(), + input->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = output->set_buffer_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = output->set_data_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t md_length(hmac_sha_256.get_digest_length()); + + status = hmac_sha_256.hmac_final( + output->get_data(hmac_sha_256.get_digest_length()), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_kdk( + const eap_variable_data_c * const dhe_shared_secret, + const eap_variable_data_c * const nonce_1, + const eap_variable_data_c * const enrollee_mac, + const eap_variable_data_c * const nonce_2, + eap_variable_data_c * const kdk + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: generate_kdk()\n"), + (m_is_client == true ? "client": "server"))); + + crypto_sha_256_c sha_256(m_am_tools); + if (sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = sha_256.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: simple_config_record_c::generate_kdk(): dhe_shared_secret"), + dhe_shared_secret->get_data(), + dhe_shared_secret->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: simple_config_record_c::generate_kdk(): nonce_1"), + nonce_1->get_data(), + nonce_1->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: simple_config_record_c::generate_kdk(): enrollee_mac"), + enrollee_mac->get_data(), + enrollee_mac->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: simple_config_record_c::generate_kdk(): nonce_2"), + nonce_2->get_data(), + nonce_2->get_data_length())); + + status = sha_256.hash_update( + dhe_shared_secret->get_data(), + dhe_shared_secret->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c dh_key(m_am_tools); + if (dh_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = dh_key.set_buffer_length(sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = dh_key.set_data_length(sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u32_t md_length(sha_256.get_digest_length()); + + status = sha_256.hash_final( + dh_key.get_data(sha_256.get_digest_length()), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: dh_key"), + dh_key.get_data(), + dh_key.get_data_length())); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + sha_256.hash_cleanup(); + if (sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + crypto_hmac_c hmac_sha_256( + m_am_tools, + &sha_256, + false); + if (hmac_sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = hmac_sha_256.hmac_set_key(&dh_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_sha_256.hmac_update( + nonce_1->get_data(), + nonce_1->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_sha_256.hmac_update( + enrollee_mac->get_data(), + enrollee_mac->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_sha_256.hmac_update( + nonce_2->get_data(), + nonce_2->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = kdk->set_buffer_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = kdk->set_data_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u32_t md_length(hmac_sha_256.get_digest_length()); + + status = hmac_sha_256.hmac_final( + kdk->get_data(hmac_sha_256.get_digest_length()), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: simple_config_record_c::generate_kdk(): kdk"), + kdk->get_data(), + kdk->get_data_length())); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::key_derivation_function( + const eap_variable_data_c * const key, + const eap_variable_data_c * const personalization_string, + const u32_t total_key_bits, + eap_variable_data_c * const result + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: key_derivation_function()\n"), + (m_is_client == true ? "client": "server"))); + + result->reset(); + + crypto_sha_256_c sha_256(m_am_tools); + if (sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + crypto_hmac_c hmac_sha_256( + m_am_tools, + &sha_256, + false); + if (hmac_sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: key"), + key->get_data(), + key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: personalization_string"), + personalization_string->get_data(), + personalization_string->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: total_key_bits %d\n"), + total_key_bits)); + + u32_t prf_digest_size(hmac_sha_256.get_digest_length()*8ul); + u32_t iterations((total_key_bits + prf_digest_size - 1) / prf_digest_size); + + eap_status_e status = result->set_buffer_length(iterations * hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = result->set_data_length(iterations * hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (u32_t ind = 0ul; ind != iterations; ++ind) + { + status = hmac_sha_256.hmac_set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u32_t ind_network_order(eap_htonl(ind+1ul)); + status = hmac_sha_256.hmac_update( + &ind_network_order, + sizeof(ind_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = hmac_sha_256.hmac_update( + personalization_string->get_data(), + personalization_string->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u32_t total_key_bits_network_order(eap_htonl(total_key_bits)); + status = hmac_sha_256.hmac_update( + &total_key_bits_network_order, + sizeof(total_key_bits_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + u32_t md_length(hmac_sha_256.get_digest_length()); + + status = hmac_sha_256.hmac_final( + result->get_data_offset(ind*hmac_sha_256.get_digest_length(), hmac_sha_256.get_digest_length()), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::derive_additional_keys( + const eap_variable_data_c * const kdk, + eap_variable_data_c * const auth_key, + eap_variable_data_c * const key_wrap_key, + eap_variable_data_c * const EMSK + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: derive_additional_keys()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG simple_config_record_c::derive_additional_keys(): kdk"), + kdk->get_data(), + kdk->get_data_length())); + + + eap_variable_data_c personalization_string(m_am_tools); + + if (personalization_string.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = personalization_string.set_buffer( + SIMPLE_CONFIG_SECURE_KEY_DERIVATION_LABEL, + SIMPLE_CONFIG_SECURE_KEY_DERIVATION_LABEL_LENGTH, + false, + false); + if (personalization_string.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c key_expansion(m_am_tools); + + if (key_expansion.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t key_bits(SIMPLE_CONFIG_AUTH_KEY_BITS + SIMPLE_CONFIG_KEY_WRAP_KEY_BITS + SIMPLE_CONFIG_EMSK_BITS); + u32_t key_bytes((key_bits+7)/8); + + status = key_derivation_function( + kdk, + &personalization_string, + key_bits, + &key_expansion); + + if (key_expansion.get_is_valid_data() == false + || key_expansion.get_data_length() < key_bytes) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + u32_t key_offset(0ul); + + u32_t key_length(SIMPLE_CONFIG_AUTH_KEY_BITS/8ul); + + status = auth_key->set_copy_of_buffer( + key_expansion.get_data_offset(key_offset, key_length), + key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_offset += key_length; + + key_length = SIMPLE_CONFIG_KEY_WRAP_KEY_BITS/8ul; + + status = key_wrap_key->set_copy_of_buffer( + key_expansion.get_data_offset(key_offset, key_length), + key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_offset += key_length; + + key_length = SIMPLE_CONFIG_EMSK_BITS/8ul; + + status = EMSK->set_copy_of_buffer( + key_expansion.get_data_offset(key_offset, key_length), + key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_offset += key_length; + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: simple_config_record_c::derive_additional_keys(): auth_key"), + auth_key->get_data(), + auth_key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: simple_config_record_c::derive_additional_keys(): key_wrap_key"), + key_wrap_key->get_data(), + key_wrap_key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: simple_config_record_c::derive_additional_keys(): EMSK"), + EMSK->get_data(), + EMSK->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_authenticator( + const eap_variable_data_c * const received_simple_config_message, + const eap_variable_data_c * const new_simple_config_message_data_without_authenticator, + eap_variable_data_c * const authenticator) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: generate_authenticator()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eap_status_not_supported; + + crypto_sha_256_c sha_256(m_am_tools); + if (sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + crypto_hmac_c hmac_sha_256( + m_am_tools, + &sha_256, + false); + if (hmac_sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG authenticator m_auth_key"), + m_auth_key.get_data(), + m_auth_key.get_data_length())); + + status = hmac_sha_256.hmac_set_key(&m_auth_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG authenticator data"), + received_simple_config_message->get_data(), + received_simple_config_message->get_data_length())); + + status = hmac_sha_256.hmac_update( + received_simple_config_message->get_data(), + received_simple_config_message->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG authenticator data"), + new_simple_config_message_data_without_authenticator->get_data(), + new_simple_config_message_data_without_authenticator->get_data_length())); + + status = hmac_sha_256.hmac_update( + new_simple_config_message_data_without_authenticator->get_data(), + new_simple_config_message_data_without_authenticator->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = authenticator->set_buffer_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = authenticator->set_data_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u32_t md_length(hmac_sha_256.get_digest_length()); + + status = hmac_sha_256.hmac_final( + authenticator->get_data(hmac_sha_256.get_digest_length()), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG authenticator"), + authenticator->get_data(), + authenticator->get_data_length())); + + status = authenticator->set_data_length(SIMPLE_CONFIG_AUTHENTICATOR_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: key_function: generate_authenticator(): returns\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::add_authenticator_attribute( + simple_config_message_c * const received_simple_config_message, + simple_config_message_c * const new_simple_config_message) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: add_authenticator_attribute()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + simple_config_payloads_c * authenticator_payload = new simple_config_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_payloads(m_am_tools, authenticator_payload); + + if (authenticator_payload == 0 + || authenticator_payload->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + eap_variable_data_c authenticator(m_am_tools); + + if (authenticator.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = generate_authenticator( + received_simple_config_message->get_simple_config_message_data(), + new_simple_config_message->get_simple_config_message_data(), + &authenticator); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = authenticator_payload->copy_attribute_data( + simple_config_Attribute_Type_Authenticator, + true, + authenticator.get_data(), + authenticator.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // Adds Authenticator attribute to the end of the message. + status = authenticator_payload->create_simple_config_message( + new_simple_config_message, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: add_authenticator_attribute(): returns\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::encrypt_payloads( + const eap_variable_data_c * const auth_key, + const eap_variable_data_c * const key_wrap_key, + simple_config_payloads_c * const plaintext_payloads, + simple_config_variable_data_c * const encrypted_settings) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: pki_function: encrypt_payloads()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + simple_config_message_c plaintext_data( + m_am_tools, + m_is_client); + + status = plaintext_payloads->create_simple_config_message( + &plaintext_data, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_variable_data_c KWA(m_am_tools); + + if (KWA.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + crypto_sha_256_c sha_256(m_am_tools); + if (sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + crypto_hmac_c hmac_sha_256( + m_am_tools, + &sha_256, + false); + if (hmac_sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG auth_key"), + auth_key->get_data(), + auth_key->get_data_length())); + + status = hmac_sha_256.hmac_set_key(auth_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG plaintext_data"), + plaintext_data.get_simple_config_message_data()->get_data(), + plaintext_data.get_simple_config_message_data()->get_data_length())); + + status = hmac_sha_256.hmac_update( + plaintext_data.get_simple_config_message_data()->get_data(), + plaintext_data.get_simple_config_message_data()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = KWA.set_buffer_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = KWA.set_data_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u32_t md_length(hmac_sha_256.get_digest_length()); + + status = hmac_sha_256.hmac_final( + KWA.get_data(hmac_sha_256.get_digest_length()), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG KWA"), + KWA.get_data(), + KWA.get_data_length())); + + status = KWA.set_data_length(SIMPLE_CONFIG_AUTHENTICATOR_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + { + status = plaintext_payloads->copy_attribute_data( + simple_config_Attribute_Type_Key_Wrap_Authenticator, + true, + KWA.get_data(), + KWA.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = plaintext_payloads->create_simple_config_message( + &plaintext_data, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_variable_data_c IV(m_am_tools); + + if (IV.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + { + // Creates Enrollee Nonce. + status = generate_nonce( + &IV, + SIMPLE_CONFIG_KEY_WRAP_IV_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + { + crypto_aes_c aes(m_am_tools); + + crypto_cbc_c aes_cbc( + m_am_tools, + &aes, + false); + + if (aes_cbc.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG key_wrap_key"), + key_wrap_key->get_data(), + key_wrap_key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG IV"), + IV.get_data(), + IV.get_data_length())); + + status = aes_cbc.set_encryption_key( + IV.get_data(), + IV.get_data_length(), + key_wrap_key->get_data(), + key_wrap_key->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = plaintext_data.add_padding(aes_cbc.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG plaintext data"), + plaintext_data.get_simple_config_message_data()->get_data(), + plaintext_data.get_simple_config_message_data()->get_data_length())); + + status = aes_cbc.update_non_aligned( + plaintext_data.get_simple_config_message_data()->get_data(), + plaintext_data.get_simple_config_message_data()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = aes_cbc.finalize_non_aligned(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG encrypted data"), + plaintext_data.get_simple_config_message_data()->get_data(), + plaintext_data.get_simple_config_message_data()->get_data_length())); + + + status = encrypted_settings->set_copy_of_buffer( + simple_config_Attribute_Type_Encrypted_Settings, + true, + IV.get_data(), + IV.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = encrypted_settings->add_data( + plaintext_data.get_simple_config_message_data()->get_data(), + plaintext_data.get_simple_config_message_data()->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: pki_function: encrypt_payloads(): returns\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::decrypt_payloads( + const eap_variable_data_c * const auth_key, + const eap_variable_data_c * const key_wrap_key, + simple_config_variable_data_c * const encrypted_settings, + simple_config_payloads_c * const plaintext_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: pki_function: decrypt_payloads()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + eap_variable_data_c data_payload(m_am_tools); + + if (data_payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = data_payload.set_buffer( + encrypted_settings->get_data(encrypted_settings->get_data_length()), + encrypted_settings->get_data_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (data_payload.get_data_length() <= SIMPLE_CONFIG_KEY_WRAP_IV_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + + eap_variable_data_c IV(m_am_tools); + + if (IV.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = IV.set_buffer( + data_payload.get_data(SIMPLE_CONFIG_KEY_WRAP_IV_SIZE), + SIMPLE_CONFIG_KEY_WRAP_IV_SIZE, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_variable_data_c decrypted_data(m_am_tools); + + if (decrypted_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + const u32_t encrypted_data_length( + data_payload.get_data_length() + - SIMPLE_CONFIG_KEY_WRAP_IV_SIZE); + + status = decrypted_data.set_buffer( + data_payload.get_data_offset( + SIMPLE_CONFIG_KEY_WRAP_IV_SIZE, + encrypted_data_length), + encrypted_data_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG key_wrap_key"), + key_wrap_key->get_data(), + key_wrap_key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG IV"), + IV.get_data(), + IV.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG encrypted data"), + decrypted_data.get_data(), + decrypted_data.get_data_length())); + + { + crypto_aes_c aes(m_am_tools); + + crypto_cbc_c aes_cbc( + m_am_tools, + &aes, + false); + + if (aes_cbc.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = aes_cbc.set_decryption_key( + IV.get_data(), + IV.get_data_length(), + key_wrap_key->get_data(), + key_wrap_key->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = aes_cbc.update_non_aligned( + decrypted_data.get_data(), + decrypted_data.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = aes_cbc.finalize_non_aligned(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG plaintext data"), + decrypted_data.get_data(), + decrypted_data.get_data_length())); + } + + + u32_t data_length(decrypted_data.get_data_length()); + u32_t padding_length(0ul); + + status = plaintext_payloads->parse_simple_config_payloads( + decrypted_data.get_data(), + &data_length, + &padding_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + simple_config_variable_data_c * const received_KWA + = plaintext_payloads->get_attribute_pointer(simple_config_Attribute_Type_Key_Wrap_Authenticator); + if (received_KWA == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG received_KWA"), + received_KWA->get_data(received_KWA->get_data_length()), + received_KWA->get_data_length())); + + + eap_variable_data_c plaintext_data(m_am_tools); + + if (plaintext_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (decrypted_data.get_data_length() < (received_KWA->get_header()->get_length()+padding_length)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + const u32_t plaintext_data_length( + decrypted_data.get_data_length() + - (received_KWA->get_header()->get_length()+padding_length)); + + status = plaintext_data.set_buffer( + decrypted_data.get_data(plaintext_data_length), + plaintext_data_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG plaintext_data"), + plaintext_data.get_data(), + plaintext_data.get_data_length())); + + + { + crypto_sha_256_c sha_256(m_am_tools); + if (sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + crypto_hmac_c hmac_sha_256( + m_am_tools, + &sha_256, + false); + if (hmac_sha_256.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG authenticator auth_key"), + auth_key->get_data(), + auth_key->get_data_length())); + + status = hmac_sha_256.hmac_set_key(auth_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hmac_sha_256.hmac_update( + plaintext_data.get_data(), + plaintext_data.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c local_KWA(m_am_tools); + + if (local_KWA.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = local_KWA.set_buffer_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = local_KWA.set_data_length(hmac_sha_256.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u32_t md_length(hmac_sha_256.get_digest_length()); + + status = hmac_sha_256.hmac_final( + local_KWA.get_data(hmac_sha_256.get_digest_length()), + &md_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG local_KWA"), + local_KWA.get_data(), + local_KWA.get_data_length())); + + status = local_KWA.set_data_length(SIMPLE_CONFIG_AUTHENTICATOR_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (local_KWA.compare( + received_KWA->get_data(received_KWA->get_data_length()), + received_KWA->get_data_length()) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e simple_config_record_c::complete_query_network_and_device_parameters( + const simple_config_state_e state, + simple_config_payloads_c * const network_and_device_parameters, + const eap_status_e p_completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: pki_function: complete_query_network_and_device_parameters()\n"), + (m_is_client == true ? "client": "server"))); + + m_pending_query_network_and_device_parameters = false; + + if (network_and_device_parameters == 0 + || network_and_device_parameters->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e local_completion_status(p_completion_status); + eap_status_e status(eap_status_process_general_error); + + + { + if (m_simple_config_state == simple_config_state_process_simple_config_start) + { + status = network_and_device_parameters->get_attribute_data( + simple_config_Attribute_Type_UUID_E, + &m_UUID_E); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u16_t data(0ul); + + status = network_and_device_parameters->get_attribute_data( + simple_config_Attribute_Type_Device_Password_ID, + &data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_local_Device_Password_ID = static_cast(data); + } + + { + u8_t RF_Band(simple_config_RF_Bands_2_4_GHz); + + status = network_and_device_parameters->get_attribute_data( + simple_config_Attribute_Type_RF_Band, + &RF_Band); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_Rf_Bands = static_cast(RF_Band); + } + } + else if (m_simple_config_state == simple_config_state_process_M1) + { + status = network_and_device_parameters->get_attribute_data( + simple_config_Attribute_Type_UUID_R, + &m_UUID_R); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = network_and_device_parameters->get_attribute_data( + simple_config_Attribute_Type_SSID, + &m_SSID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = network_and_device_parameters->get_attribute_data( + simple_config_Attribute_Type_MAC_Address, + &m_MAC_address); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + u16_t data(0ul); + + status = network_and_device_parameters->get_attribute_data( + simple_config_Attribute_Type_Device_Password_ID, + &data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (status == eap_status_ok) + { + m_local_Device_Password_ID = static_cast(data); + } + + if (m_received_Device_Password_ID != m_local_Device_Password_ID) + { + // Registrar requires different Device_Password_ID. + local_completion_status = eap_status_user_has_not_subscribed_to_the_requested_service; + + bool add_new_attribute(false); + + // Change the error attribute to simple_config_Configuration_Error_Network_auth_failure. + simple_config_variable_data_c * Configuration_Error + = network_and_device_parameters->get_attribute_pointer(simple_config_Attribute_Type_Configuration_Error); + if (Configuration_Error == 0) + { + // Add a new simple_config_Attribute_Type_Configuration_Error attribute. + Configuration_Error = new simple_config_variable_data_c(m_am_tools); + + if (Configuration_Error != 0) + { + add_new_attribute = true; + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + if (Configuration_Error != 0) + { + u16_t error(simple_config_Configuration_Error_Network_auth_failure); + u16_t network_order_error(eap_htons(error)); + + status = Configuration_Error->set_copy_of_buffer( + simple_config_Attribute_Type_Configuration_Error, + true, + &network_order_error, + sizeof(network_order_error)); + if (status != eap_status_ok) + { + if (add_new_attribute == true) + { + delete Configuration_Error; + Configuration_Error = 0; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (add_new_attribute == true) + { + // Only the new object is added. + status = network_and_device_parameters->add_attribute(Configuration_Error); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload); + } + } + } + } + } + + + if (m_local_Device_Password_ID == simple_config_Device_Password_ID_PushButton) + { + // Set m_device_password to all ascii zeroes SIMPLE_CONFIG_PBC_DEVICE_PASSWORD_PIN. + status = m_device_password.set_copy_of_buffer( + SIMPLE_CONFIG_PBC_DEVICE_PASSWORD_PIN, + SIMPLE_CONFIG_PBC_DEVICE_PASSWORD_PIN_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + if (local_completion_status == eap_status_ok) + { + switch (state) + { + + case simple_config_state_process_simple_config_start: + status = send_M1(network_and_device_parameters); + break; + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + case simple_config_state_process_M1: + status = send_M2(network_and_device_parameters); + break; + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + default: + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + + } // switch (state) + } + else if (local_completion_status == eap_status_user_has_not_subscribed_to_the_requested_service) + { + switch (state) + { + + case simple_config_state_process_simple_config_start: + status = send_WSC_NACK(); + break; + +#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + case simple_config_state_process_M1: + status = send_M2D(network_and_device_parameters); + break; + +#endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG) + + default: + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + + } // switch(state) + } + + if (status == eap_status_ok) + { + status = check_sent_simple_config_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#endif //#if defined(USE_EAP_SIMPLE_CONFIG) + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_tlv_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_tlv_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,234 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 598 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "simple_config_tlv_header.h" +#include "simple_config_types.h" + + +/** @file */ + + +/** + * The destructor of the simple_config_tlv_header_c class does nothing. + */ +simple_config_tlv_header_c::~simple_config_tlv_header_c() +{ +} + +/** + * The constructor of the simple_config_tlv_header_c class simply initializes the attributes. + */ +simple_config_tlv_header_c::simple_config_tlv_header_c( + abs_eap_am_tools_c * const tools) + : eap_general_header_base_c(tools, 0, 0ul) + , m_am_tools(tools) +{ +} + +/** + * The constructor of the simple_config_tlv_header_c class simply initializes the attributes. + */ +simple_config_tlv_header_c::simple_config_tlv_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) +{ +} + +/** + * This function returns the TLV type flag. + */ +simple_config_Attribute_Type_e simple_config_tlv_header_c::get_tlv_type() const +{ + const u8_t * const flag_tlv_type_data = get_header_offset(m_tlv_type_offset, sizeof(u16_t)); + if (flag_tlv_type_data != 0) + { + return static_cast( + (static_cast(flag_tlv_type_data[0] << 8) + | (static_cast(flag_tlv_type_data[1])))); + } + else + { + return simple_config_Attribute_Type_None; + } +} + +/** + * This function returns the data length of TLV. + */ +u32_t simple_config_tlv_header_c::get_length() const +{ + return get_header_length() + get_data_length(); +} + +/** + * This function returns the data length of TLV. + */ +u16_t simple_config_tlv_header_c::get_data_length() const +{ + const u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u16_t)); + if (length_data != 0) + { + return eap_read_u16_t_network_order(length_data, sizeof(u16_t)); + } + else + { + return 0ul; + } +} + +/** + * This function returns the header length of TLV. + */ +u32_t simple_config_tlv_header_c::get_header_length() +{ + return m_data_offset; +} + +/** + * This function returns pointer to the offset of data of TLV. + * @param offset is the offset of queried data in bytes. + * @param contignuous_bytes is the length of queried data in bytes. + */ +u8_t * simple_config_tlv_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + u32_t data_length = get_data_length(); // Here is removed optional SIMPLE_CONFIG message length. + + if (data_length >= offset+contignuous_bytes) + { + u8_t * const data = get_header_offset(m_data_offset, offset+contignuous_bytes); + if (data != 0) + { + return &data[offset]; + } + else + { + return 0; + } + } + else + { + EAP_ASSERT_ALWAYS(data_length >= offset+contignuous_bytes); + } + return 0; +} + + +/** + * This function returns pointer to the offset of data of TLV. + * @param contignuous_bytes is the length of queried data in bytes. + */ +u8_t * simple_config_tlv_header_c::get_data(const u32_t contignuous_bytes) const +{ + return get_data_offset(0u, contignuous_bytes); +} + + +/** + * This function return pointer to the next TLV header in the same buffer. + */ +u8_t * simple_config_tlv_header_c::get_next_header() const +{ + if (get_header_buffer_length() >= 2ul*get_header_length()+get_data_length()) + { + return get_data_offset(get_data_length(), get_header_length()); + } + else + { + return 0; + } +} + + +/** + * This function checks the header is valid. + */ +eap_status_e simple_config_tlv_header_c::check_header() const +{ + if (get_tlv_type() < simple_config_Attribute_Type_First_Correct_Value + || get_tlv_type() > simple_config_Attribute_Type_Last_Correct_Value) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +/** + * This function returns debug strings of the TLV type. + */ +eap_const_string simple_config_tlv_header_c::get_tlv_type_string() const +{ + eap_simple_config_trace_string_c debug_string; + + return debug_string.get_attribute_type_string(get_tlv_type()); +} + +/** + * This function sets the TLV type flag. + */ +void simple_config_tlv_header_c::set_tlv_type(simple_config_Attribute_Type_e type) +{ + u8_t * const flag_tlv_type_data = get_header_offset(m_tlv_type_offset, sizeof(u16_t)); + + EAP_ASSERT(flag_tlv_type_data != 0); + + flag_tlv_type_data[0] = static_cast((type & 0xff00) >> 8); + flag_tlv_type_data[1] = static_cast(type & 0x00ff); +} + +/** + * This function sets the TLV data length. + */ +void simple_config_tlv_header_c::set_data_length(const u16_t p_length) +{ + u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u16_t)); + + EAP_ASSERT(length_data != 0); + + length_data[0] = static_cast((p_length & 0xff00) >> 8); + length_data[1] = static_cast((p_length & 0x00ff)); +} + +/** + * This function resets the TLV header. + */ +void simple_config_tlv_header_c::reset_header(const u16_t buffer_length) +{ + set_tlv_type(simple_config_Attribute_Type_None); + set_data_length(buffer_length); +} + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_tools/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_tools/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,22 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_simple_config_tools + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_payloads.cpp \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_tlv_header.cpp \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_credential.cpp \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_message.cpp \ + $(WLAN_COMMON)/type/simple_config/simple_config/src/simple_config_types.cpp \ + $(WLAN_COMMON)/core/eapol_rsna_key_header.cpp \ + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + -lstdc++ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_types.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_types.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,295 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 600 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "simple_config_types.h" + + +/** @file simple_config_types.cpp + */ + +//-------------------------------------------------- + +EAP_FUNC_EXPORT network_key_and_index_c::~network_key_and_index_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT network_key_and_index_c::network_key_and_index_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_network_key_index(0ul) + , m_network_key(tools) + , m_is_valid(false) +{ + if (m_network_key.get_is_valid() == false) + { + return; + } + + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t network_key_and_index_c::get_network_key_index() +{ + return m_network_key_index; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void network_key_and_index_c::set_network_key_index(u8_t index) +{ + m_network_key_index = index; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * network_key_and_index_c::get_network_key() +{ + return &m_network_key; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT network_key_and_index_c * network_key_and_index_c::copy() +{ + network_key_and_index_c * const copy_object = new network_key_and_index_c(m_am_tools); + if (copy_object == 0 + || copy_object->get_is_valid() == false) + { + delete copy_object; + return 0; + } + + copy_object->set_network_key_index(get_network_key_index()); + + eap_status_e status = copy_object->get_network_key()->set_copy_of_buffer(get_network_key()); + if (status != eap_status_ok) + { + delete copy_object; + return 0; + } + + return copy_object; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool network_key_and_index_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool network_key_and_index_c::get_is_valid_data() +{ + return get_is_valid() && get_network_key()->get_is_valid_data(); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_simple_config_trace_string_c::~eap_simple_config_trace_string_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_simple_config_trace_string_c::eap_simple_config_trace_string_c() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_simple_config_trace_string_c::get_state_string(const simple_config_state_e state) const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(state, simple_config_state_none) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_simple_config_start) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_M1) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_M2) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_M3) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_M4) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_M5) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_M6) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_M7) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_M8) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_WSC_ACK) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_WSC_NACK) + else EAP_IF_RETURN_STRING(state, simple_config_state_wait_WSC_DONE) + else EAP_IF_RETURN_STRING(state, simple_config_state_pending_simple_config_messages_processed) + else EAP_IF_RETURN_STRING(state, simple_config_state_simple_config_success) + else EAP_IF_RETURN_STRING(state, simple_config_state_failure) + else +#else +EAP_UNREFERENCED_PARAMETER(state); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown SIMPLE_CONFIG-state"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_simple_config_trace_string_c::get_message_type_string(const simple_config_Message_Type_e type) const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(type, simple_config_Message_Type_None) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_Beacon) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_Probe_Request) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_Probe_Response) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_M1) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_M2) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_M2D) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_M3) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_M4) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_M5) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_M6) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_M7) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_M8) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_WSC_ACK) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_WSC_NACK) + else EAP_IF_RETURN_STRING(type, simple_config_Message_Type_WSC_DONE) + else +#else + EAP_UNREFERENCED_PARAMETER(type); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown SIMPLE_CONFIG-message"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_simple_config_trace_string_c::get_attribute_type_string(const simple_config_Attribute_Type_e type) const +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_None) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_AP_Channel) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Association_State) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Authentication_Type) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Authentication_Type_Flags) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Authenticator) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Config_Methods) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Configuration_Error) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Confirmation_URL4) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Confirmation_URL6) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Connection_Type) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Connection_Type_Flags) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Credential) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Device_Name) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Device_Password_ID) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_E_Hash1) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_E_Hash2) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_E_SNonce1) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_E_SNonce2) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Encrypted_Settings) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Encryption_Type) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Encryption_Type_Flags) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Enrollee_Nonce) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Feature_ID) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Identity) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Identity_Proof) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Key_Wrap_Authenticator) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Key_Identifier) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_MAC_Address) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Manufacturer) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Message_Type) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Model_Name) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Model_Number) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Network_Index) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Network_Key) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Network_Key_Index) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_New_Device_Name) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_New_Password) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_OOB_Device_Password) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_OS_Version) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Power_Level) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_PSK_Current) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_PSK_Max) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Public_Key) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Radio_Enabled) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Reboot) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Registrar_Current) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Registrar_Established) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Registrar_List) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Registrar_Max) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Registrar_Nonce) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Request_Type) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Response_Type) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_RF_Band) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_R_Hash1) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_R_Hash2) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_R_SNonce1) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_R_SNonce2) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Selected_Registrar) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Serial_Number) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Simple_Config_State) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_SSID) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Total_Networks) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_UUID_E) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_UUID_R) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Vendor_Extension) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Version) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_X_509_Certificate_Request) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_X_509_Certificate) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_EAP_Identity) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Message_Counter) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Public_Key_Hash) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Rekey_Key) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Key_Lifetime) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Permitted_Config_Methods) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Selected_Registrar_Config_Methods) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Primary_Device_Type) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Secondary_Device_Type_List) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Portable_Device) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_AP_Setup_Locked) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Application_List) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_EAP_Type) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Initialization_Vector) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_Key_Provided_Automatically) + else EAP_IF_RETURN_STRING(type, simple_config_Attribute_Type_802_1X_Enabled) + else +#else + EAP_UNREFERENCED_PARAMETER(type); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown Attribute Type"); + } +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/eap/include/eap_tls_peap_state_notification.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/eap/include/eap_tls_peap_state_notification.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,131 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TLS_PEAP_STATE_NOTIFICATION_H_) +#define _EAP_TLS_PEAP_STATE_NOTIFICATION_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_protocol_layer.h" +#include "abs_eap_state_notification.h" + + +/// A eap_tls_peap_state_notification_c class. +/// This is used for debugging and protocol testing. +class EAP_EXPORT eap_tls_peap_state_notification_c +: public abs_eap_state_notification_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; ///< This is pointer to the tools class. @see abs_eap_am_tools_c. + + eap_protocol_layer_e m_layer; ///< Here is the protocol layer (EAP type). + + eap_variable_data_c m_notification_string; ///< Here is the notification string. + + eap_boolean_e m_needs_confirmation_from_user; ///< This flag tells whether user interaction is required. + + u32_t m_protocol; ///< Here is the EAP type. + + u32_t m_previous_state; ///< Here is the previous state of the EAP type. + + u32_t m_current_state; ///< Here is the current state of the EAP type. + + const eap_am_network_id_c *m_send_network_id; + + eap_boolean_e m_is_client; + + u8_t m_eap_identifier; + + eap_boolean_e m_allow_send_eap_success; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_tls_peap_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_tls_peap_state_notification_c(); + + /** + * The constructor of the eap_tls_peap_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT eap_tls_peap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + eap_boolean_e is_client, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + eap_boolean_e allow_send_eap_success); + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT const eap_am_network_id_c * const get_send_network_id() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT const eap_protocol_layer_e get_protocol_layer() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT const u32_t get_protocol() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT const u32_t get_previous_state() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT const u32_t get_current_state() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT eap_const_string get_current_state_string() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT eap_const_string get_previous_state_string() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT const eap_boolean_e get_is_client() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT const u8_t get_eap_identifier() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT eap_boolean_e get_allow_send_eap_success() const; + + // This is commented in abs_eap_state_notification_c::set_notification_string(). + EAP_FUNC_IMPORT const eap_status_e set_notification_string( + const eap_variable_data_c * const notification_string, + const eap_boolean_e needs_confirmation_from_user); + + //-------------------------------------------------- +}; // class eap_tls_peap_state_notification_c + +#endif //#if !defined(_EAP_TLS_PEAP_STATE_NOTIFICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/eap/include/eap_type_tls_peap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/eap/include/eap_type_tls_peap.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,821 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TYPE_TLS_PEAP_H_) +#define _EAP_TYPE_TLS_PEAP_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_am_type_tls_peap.h" +#include "eap_am_network_id.h" +#include "abs_eap_base_type.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "abs_eap_base_timer.h" +#include "eap_crypto_api.h" +#include "eap_protocol_layer.h" +#include "eap_type_tls_peap_types.h" +#include "abs_tls_base_record.h" +#include "tls_record_header.h" +#include "eap_master_session_key.h" + +class eap_tls_peap_header_c; +class abs_eap_am_tools_c; +class abs_eap_base_type_c; +class eap_am_type_tls_peap_c; +class tls_base_record_c; + +//-------------------------------------------------- + + +/// This class is implementation of TLS/PEAP EAP type. See more detailed design and architecture document EAP_TLS_PEAP.doc. +class EAP_EXPORT eap_type_tls_peap_c +: public abs_eap_base_timer_c +, public eap_base_type_c +, public abs_eap_am_type_tls_peap_c +, public abs_tls_base_record_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to adaptation module of TLS/PEAP EAP type. + eap_am_type_tls_peap_c * m_am_type_tls_peap; + + /// This is pointer to TLS implementation. + tls_base_record_c * m_tls_record; + + /// This is the realm part of NAI of the authenticator. + /// Client uses this as a realm part on the NAI. + eap_variable_data_c m_nai_realm; + + /// This is the full NAI of the client. + eap_variable_data_c m_NAI; + + /// This is the identity used in EAP-Identity. + eap_variable_data_c m_current_identity; + + /// This is network identity of the sent packet from this authentication session. + eap_am_network_id_c m_send_network_id; + + /// This is offset in bytes of the EAP-type header in the packet buffer. + /// Offset is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_tls_peap_header_offset; + + /// This is maximum transfer unit in bytes. + /// MTU is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_MTU; + + /// This is length of the trailer in bytes. + /// Trailer length is described in abs_eap_base_type_c::get_header_offset(). + u32_t m_trailer_length; + + /// This is the state of this authentication session. + eap_type_tls_peap_state_variable_e m_state; + + /// This is the saved previous state of this authentication session. + eap_type_tls_peap_state_variable_e m_saved_previous_state; + + /// This is the state of reassembly. + eap_type_tls_peap_reassembly_state_e m_reassembly_state; + + /// This is the saved previous state of reassembly. + eap_type_tls_peap_reassembly_state_e m_saved_previous_reassembly_state; + + /// This is the offset of next fragment to be send from m_tls_message_buffer. + u32_t m_tls_message_send_offset; + + /// This is the buffer for TLS-message reassembly and fragmentation. + eap_variable_data_c m_tls_message_buffer; + + /// m_master_session_key. + eap_master_session_key_c m_master_session_key; + + /// This is u32_t array of accepted PEAP versions. + eap_variable_data_c m_accepted_PEAP_versions; + + /// This the current EAP-type (TLS, PEAP or TTLS). + const eap_type_value_e m_current_eap_type; + + /// This separates different PEAP versions. + /// This is the configured default PEAP version. + peap_version_e m_configured_peap_version; + + /// This separates different PEAP versions. + /// This is the current active PEAP version. + peap_version_e m_current_peap_version; + + u8_t m_first_fragment_eap_identifier; + + tls_session_type_e m_tls_session_type; + + bool m_tunneled_eap_type_active; + + eap_state_variable_e m_tunneled_eap_type_authentication_state; + + + bool m_free_am_type_tls_peap; + + bool m_free_tls_record; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + /// True value of this flag indicates the EAP-Success packet must be received + /// in successfull authentication of clien. + /// This value is configured with EAP_TLS_PEAP_wait_eap_success_packet. + bool m_wait_eap_success_packet; + + /// True value of this flag indicates the identifier of the EAP-Response/Identity must be checked. + /// This is not possible cases where identifier of the EAP-Request/Identity is generated by other network entities. + bool m_check_identifier_of_eap_identity_response; + + + /// True value means this is a test version of TLS/PEAP. + bool m_tls_peap_test_version; + + /// This flag forces check of NAI realm. Realm must be the same as given in EAP_TLS_PEAP_manual_realm configuration option. + /// Default value is false, check is not done by default. + bool m_check_nai_realm; + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + /// Flag causes TLS to use identity privacy. + bool m_tls_use_identity_privacy; +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + + /// This flag indicates whether the EAP-Failure was received. + /// On successfull authentication bogus EAP-Failure is ignored. + bool m_failure_message_received; + + /// This variable is set true when authentication finished successfully. + bool m_authentication_finished_successfully; + + /// This variable stores the last used EAP-Identifier. + /// Client will always send EAP-Response with this identifier. + /// Server will always send EAP-Request with this identifier increased by one. + /// Server increase this identifier after successfull packet send. + u8_t m_last_eap_identifier; + + /// This flag is set true when shutdown is called. + /// This is for internal sanity check. + bool m_shutdown_was_called; + + /// This configurable option selects whether the TLS/PEAP version of Tppd + /// is used, the length field is added to all message fragments + /// even the message fits to one fragment except EAP-TLS-start, EAP-TLS-Acknowledge and + /// PEAP-application data. The client acknowledges tunneled EAP-Success message + /// with empty PEAP message. + bool m_use_tppd_tls_peap; + + /// On fast session resume server does not send tunneled EAP-Success. + /// Instead it sends plain EAP-Success. + /// True value of this flag allows this plain EAP-Success. + bool m_use_tppd_peapv1_acknowledge_hack; + + /// This flag tells the send message includes TLS-Handshake message. + /// Note the received messages are not marked. + /// This information is needed in some PEAP versions. + /// All messages including TLS-Handshake message must have PEAP L bit and four octet TLS message length field. + bool m_includes_tls_handshake_message; + + bool m_use_eap_expanded_type; + + //-------------------------------------------------- + + EAP_FUNC_IMPORT eap_status_e select_peap_version(const u32_t proposed_peap_version); + + /** + * This function generates a new NAI from domain and identity. + */ + EAP_FUNC_IMPORT eap_status_e generate_nai( + eap_variable_data_c * const new_nai, ///< This is the new generated NAI. + const eap_variable_data_c * const domain, ///< This is the domain part of the NAI. + const eap_variable_data_c * const identity ///< This is identity. + ); + + /** + * This function handles the received TLS/PEAP EAP packet. + * + * First is checked the valid massage is received in valid state. + * + * Second is parsed the payloads and checked syntax of the received TLS/PEAP EAP packet. + * See also parse_tls_peap_packet(). + * + * Third is analysed the TLS/PEAP EAP packet. This includes the payload and values of each payload. + * See also analyse_tls_peap_packet(). + */ + EAP_FUNC_IMPORT eap_status_e handle_tls_peap_packet( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_tls_peap_header_c * const tls_peap, ///< This is pointer to EAP header including EAP-TLS/PEAP fields. + const u32_t tls_peap_length ///< This is length of received TLS/PEAP EAP packet. + ); + + /** + * This function analyses the received TLS/PEAP EAP packet. + * Each sub-type is handled in separate function. + * @see Client messages are handled in handle_start_request_message() and handle_challenge_request_message(). + * @see Server messages are handled in handle_start_response_message() and handle_challenge_response_message(). + */ + EAP_FUNC_IMPORT eap_status_e analyse_tls_peap_packet( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_tls_peap_header_c * const received_tls_peap, ///< This is pointer to EAP header including EAP-TLS/PEAP fields. + const u32_t tls_peap_packet_length ///< This is length of received TLS/PEAP EAP packet. + ); + + /** + * This function parses the payloads starting from specified payload (p_payload). + * Function parses all payloads from the buffer. + * Payloads are stored to p_tls_peap_payloads. + * @return If the length of the buffer and sum of the length of all payloads does not match + * function returns eap_status_header_corrupted. + * Also error is returned when illegal payload attribute is recognised. + */ + EAP_FUNC_IMPORT eap_status_e parse_tls_peap_payload( + u32_t * const buffer_length ///< This is the length of the buffer. This must match with the length of all payloads. + ); + + /** + * This function checks the version list payload of the TLS/PEAP EAP packet is correct. + */ + EAP_FUNC_IMPORT eap_status_e check_version_list( + const u16_t version_list_length, + u8_t * version_list); + + /** + * This function parses all payloads of the whole TLS/PEAP EAP packet. + * Payloads are stored to p_tls_peap_payloads. + * @see parse_tls_peap_payload(). + */ + EAP_FUNC_IMPORT eap_status_e parse_tls_peap_packet( + eap_tls_peap_header_c * const tls_peap, ///< This is pointer to EAP header including EAP-TLS/PEAP fields. + const u32_t tls_peap_packet_length ///< This is length of received TLS/PEAP EAP packet. + ); + + //-------------------------------------------------- + + /** + * This function returns the domain name, realm part of NAI. + */ + EAP_FUNC_IMPORT eap_variable_data_c * get_nai_realm(); + + /** + * This function returns the full NAI. + */ + EAP_FUNC_IMPORT eap_variable_data_c * get_NAI(); + + /** + * This is the situation before the update_buffer_indexes() call. + * @code + * + * |<---------buffer_offset-------->|<----------buffer_free----------------->| + * | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * This is the situation after the update_buffer_indexes() call. + * @code + * + * |<-----------------buffer_offset--------------------->|<---buffer_free--->| + * | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * Note maximum_buffer_size could be larger than (m_tls_peap_header_offset + m_MTU + m_trailer_length). + */ + EAP_FUNC_IMPORT void update_buffer_indexes( + const u32_t maximum_buffer_size, + const u32_t payload_size, + u32_t * const buffer_offset, + u32_t * const buffer_free); + + /** + * This is the situation before the update_payload_indexes() call. + * @code + * + * |<---------buffer_offset-------->|<----------buffer_free----------------->| + * | | | + * | |<-data_offset->|<--------data_free--------------------->| + * | | | | + * | | |<---payload_size--->| | + * | | | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * This is the situation after the update_payload_indexes() call. + * @code + * + * |<-----------------buffer_offset--------------------->|<---buffer_free--->| + * | | | + * | |<----------data_offset------------->|<----data_free---->| + * | | | | + * | | |<---payload_size--->| | + * | | | | | + * | +-----+---------------+--------------------+ | + * | | EAP | data | new payload | | + * | +-----+---------------+--------------------+ | + * | | | + * |<-offset->|<----MTU----------------------------------------------------->|<-trailer->| + * | | + * |<-----------------------maximum_buffer_size----------------------------------------->| + * + * @endcode + * + * Note maximum_buffer_size could be larger than (m_tls_peap_header_offset + m_MTU + m_trailer_length). + */ + EAP_FUNC_IMPORT void update_payload_indexes( + const u32_t maximum_buffer_size, + const u32_t eap_header_size, + const u32_t payload_size, + u32_t * const data_offset, + u32_t * const data_free, + u32_t * const buffer_offset, + u32_t * const buffer_free); + + /** + * This function reads the identity payload. Identity is stored to handler->get_identity(). + */ + EAP_FUNC_IMPORT eap_status_e parse_identity( + const u8_t * const identity, ///< This is pointer to received EAP-Identity buffer. + const u32_t identity_length ///< This is length of received EAP-Identity buffer. + ); + + /** + * This function handles the received EAP-Response/Identity message. + * First function parses the identity. + * The send_start_request_message() function will send the EAP-Request/SIM/Start message. + */ + EAP_FUNC_IMPORT eap_status_e handle_identity_response_message( + eap_header_rd_c * const eap_header, ///< This is the received EAP-Identity packet, pointer points to the header. + const u32_t tls_peap_packet_length ///< This is length of received TLS/PEAP EAP packet. + ); + + /** + * This function chechs NAI. + */ + EAP_FUNC_IMPORT eap_status_e check_NAI( + const u8_t * const identity, + const u32_t identity_length, + const u8_t * const at_character); + + /** + * This function traces the EAP packet. + */ + EAP_FUNC_IMPORT void packet_trace( + eap_const_string prefix, + const eap_am_network_id_c * const receive_network_id, + eap_header_wr_c * const received_eap, + const u32_t eap_packet_length); + + /** + * This function returns m_master_session_key. + */ + eap_master_session_key_c * get_master_session_key(); + + /** + * This function finishes the successfull authentication. + * Generated keys are offered to lower layer. + * Connection handle is initialised. + */ + EAP_FUNC_IMPORT eap_status_e finish_successful_authentication( + const bool send_tppd_peapv1_empty_acknowledge, + const bool do_quiet_finish, + const bool do_send_empty_acknowledge); + + /** + * This function sends a notification of possible failed authentication + * to lower layer. + */ + EAP_FUNC_IMPORT eap_status_e send_final_notification(); + + + /** + * This function returns the state of this authentication session. + */ + EAP_FUNC_IMPORT eap_type_tls_peap_state_variable_e get_state() const; + + /** + * This function sets the new state and notifies the lower layer of this change. + */ + EAP_FUNC_IMPORT void set_state(const eap_type_tls_peap_state_variable_e state); + + /** + * This function saves the current m_state to m_saved_previous_state. + * The saved state is restored in error case. + */ + EAP_FUNC_IMPORT void save_current_state(); + + /** + * This function restores the saved state. + */ + EAP_FUNC_IMPORT void restore_saved_previous_state(); + + + /** + * This function returns the state of reassembly. + */ + EAP_FUNC_IMPORT eap_type_tls_peap_reassembly_state_e get_reassembly_state() const; + + /** + * This function sets the new reassembly state. + */ + EAP_FUNC_IMPORT void set_reassembly_state(const eap_type_tls_peap_reassembly_state_e state); + + /** + * This function saves the current m_reassembly_state to m_saved_previous_reassembly_state. + * The saved state is restored in error case. + */ + EAP_FUNC_IMPORT void save_current_reassembly_state(); + + /** + * This function restores the saved reassembly state. + */ + EAP_FUNC_IMPORT void restore_saved_reassembly_state(); + + + /** + * This function returns the send network identity of this session. + */ + EAP_FUNC_IMPORT eap_am_network_id_c * get_send_network_id(); + + /** + * This function stores the last EAP-Identifier. + */ + EAP_FUNC_IMPORT void set_last_eap_identifier(const u8_t last_eap_identifier); + + /** + * This function returns the last stored EAP-Identifier. + */ + EAP_FUNC_IMPORT u8_t get_last_eap_identifier() const; + + eap_status_e check_received_eap_identifier( + const eap_header_wr_c * const eap_header); + + + /** + * This function returns string of the current state. This is for trace purposes. + */ + EAP_FUNC_IMPORT eap_const_string get_state_string() const; + + /** + * This function returns string of the current state. This is for trace purposes. + */ + EAP_FUNC_IMPORT eap_const_string get_saved_previous_state_string() const; + + /** + * This function returns string of the current reassembly state. This is for trace purposes. + */ + EAP_FUNC_IMPORT eap_const_string get_reassembly_state_string() const; + + + /** + * This function sets the m_failure_message_received flag true. + */ + EAP_FUNC_IMPORT void set_failure_message_received(); + + /** + * This function sets the m_failure_message_received flag false. + */ + EAP_FUNC_IMPORT void unset_failure_message_received(); + + /** + * This function returns the m_failure_message_received flag. + */ + EAP_FUNC_IMPORT bool get_failure_message_received() const; + + /** + * This function sends an empty EAP-packet. + */ + EAP_FUNC_IMPORT eap_status_e send_empty_eap_ack(); + + /** + * This function sends EAP-TLS/PEAP start message. + */ + EAP_FUNC_IMPORT eap_status_e send_tls_peap_start_message( + const u8_t next_eap_identifier, ///< This is EAP-Identifier of next EAP packet. + const eap_variable_data_c * const authority_identity_payload + ); + + /** + * This function sends starts EAP-TLS/PEAP after a start message is received. + */ + EAP_FUNC_IMPORT eap_status_e start_tls_peap_authentication( + const eap_variable_data_c * const received_authority_identity_payload + ); + + /** + * This function extracts the TLS-record message from m_tls_message_buffer and forwards it to tls_base_record_c object. + */ + EAP_FUNC_IMPORT eap_status_e tls_message_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_tls_peap_header_c * const received_tls_peap, ///< This is pointer to EAP header including EAP-TLS/PEAP fields. + const u32_t tls_peap_packet_length ///< This is length of received TLS/PEAP EAP packet. + ); + + /** + * This function sends the EAP-TLS/PEAP message from rm_tls_reassembly_buffer. + */ + EAP_FUNC_IMPORT eap_status_e eap_tls_peap_fragment_send(); + + EAP_FUNC_IMPORT eap_status_e create_random_eap_identity( + eap_variable_data_c * const local_identity); + + EAP_FUNC_IMPORT eap_status_e create_eap_fast_mac_identity( + const eap_am_network_id_c * const send_network_id, + eap_variable_data_c * const mac_identity); + + EAP_FUNC_IMPORT eap_status_e handle_eap_identity_query( + const eap_variable_data_c * const user_certificate_identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const bool use_manual_username, + const eap_variable_data_c * const manual_username, + const bool use_manual_realm, + const eap_variable_data_c * const manual_realm + ); + + EAP_FUNC_IMPORT tls_session_type_e get_tls_session_type(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor cancels all timers and deletes member attributes. + */ + EAP_FUNC_IMPORT virtual ~eap_type_tls_peap_c(); + + /** + * Constructor initializes all member attributes. + */ + EAP_FUNC_IMPORT eap_type_tls_peap_c( + abs_eap_am_tools_c * const tools, ///< This is pointer to the tools AM of current platform. + abs_eap_base_type_c * const partner, ///< This is back pointer to object which created this object. + eap_am_type_tls_peap_c * const am_type_tls_peap, ///< This is pointer to adaptation module of TLS/PEAP EAP type. + const bool free_am_type_tls_peap, + tls_base_record_c * const tls_record, /// This is pointer to TLS implementation. + const bool free_tls_record, + const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false). + const eap_type_value_e current_eap_type, ///< This the current EAP-type (TLS or PEAP). + const eap_am_network_id_c * const receive_network_id ///< The network id used for this session. + ); + + /** + * This function creates reassembly state string. + */ + EAP_FUNC_IMPORT static eap_const_string get_reassembly_state_string(eap_type_tls_peap_reassembly_state_e state); + + /** + * This function creates state string. + */ + EAP_FUNC_IMPORT static eap_const_string get_state_string(eap_type_tls_peap_state_variable_e state); + + + /** + * This function tells if the object is a client or a server.. + */ + EAP_FUNC_IMPORT bool get_is_client(); + + // This is commented in abs_eap_am_type_tls_peap_c::complete_eap_identity_query(). + EAP_FUNC_IMPORT eap_status_e complete_eap_identity_query( + const eap_variable_data_c * const user_certificate_identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const eap_status_e completion_status, + const bool use_manual_username, + const eap_variable_data_c * const manual_username, + const bool use_manual_realm, + const eap_variable_data_c * const manual_realm + ); + + /** + * The partner class calls this function when EAP/TLS/PEAP packet is received. + * see also eap_base_type_c::packet_process(). + */ + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + /** + * This function processes the EAP-Response/Identity. + */ + EAP_FUNC_IMPORT eap_status_e eap_identity_response_packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const received_eap, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ); + + /** + * This function processes the TLS/PEAP packets. + */ + EAP_FUNC_IMPORT eap_status_e tls_peap_packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_tls_peap_header_c * const received_tls_peap, ///< This is pointer to EAP header including EAP-TLS/PEAP fields. + const u32_t tls_peap_packet_length ///< This is length of received TLS/PEAP EAP packet. + ); + + // This is commented in abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data + ); + + // This is commented in abs_eap_base_timer_c::timer_delete_data(). + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data + ); + + // This is commented in eap_base_type_c::set_is_valid(). + EAP_FUNC_IMPORT void set_is_valid(); + + // This is commented in eap_base_type_c::get_is_valid(). + EAP_FUNC_IMPORT bool get_is_valid(); + + // This is commented in eap_base_type_c::configure(). + EAP_FUNC_IMPORT eap_status_e configure(); + + // This is commented in eap_base_type_c::shutdown(). + EAP_FUNC_IMPORT eap_status_e shutdown(); + + // This is commented in eap_base_type_c::query_eap_identity(). + EAP_FUNC_IMPORT eap_status_e query_eap_identity( + const bool must_be_synchronous, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier); + + // This is commented in eap_base_type_c::query_eap_identity(). + EAP_FUNC_IMPORT eap_status_e set_initial_eap_identifier( + const eap_am_network_id_c * const receive_network_id, + const u8_t initial_identifier); + + // This is commented in eap_base_type_c::eap_acknowledge(). + EAP_FUNC_IMPORT eap_status_e eap_acknowledge( + const eap_am_network_id_c * const receive_network_id); + + /** + * This function must reset the state of object to same as + * state was after the configure() function call. + * If object reset succeeds this function must return eap_status_ok. + * If object reset fails this function must return corresponding error status. + * @return This function returns the status of reset operation. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + EAP_FUNC_IMPORT eap_status_e set_tls_master_secret( + const eap_variable_data_c * const eap_tls_master_session_key); + + /// @see abs_tls_base_record_c::state_notification(). + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state + ); + + /// @see abs_tls_base_record_c::packet_send(). + EAP_FUNC_IMPORT eap_status_e tls_peap_packet_send( + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length, + const bool includes_tls_handshake_message); + + /// @see abs_tls_base_record_c::packet_send(). + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + /// @see abs_tls_base_record_c::get_header_offset(). + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length + ); + + /// @see abs_tls_base_record_c::restart_authentication(). + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer); + + /// @see abs_tls_base_record_c::read_configure(). + EAP_FUNC_IMPORT virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ); + + /// @see abs_tls_base_record_c::write_configure(). + EAP_FUNC_IMPORT virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ); + + /// @see abs_tls_base_record_c::set_timer(). + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + /// @see abs_tls_base_record_c::cancel_timer(). + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + /// @see abs_tls_base_record_c::cancel_all_timers(). + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + /// @see abs_tls_base_record_c::load_module(). + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + /// @see abs_tls_base_record_c::unload_module(). + EAP_FUNC_IMPORT eap_status_e unload_module(const eap_type_value_e type); + + /// @see abs_tls_base_record_c::packet_data_crypto_keys(). + EAP_FUNC_IMPORT eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key); + + /// @see abs_tls_base_record_c::check_is_valid_eap_type(). + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + /// @see abs_tls_base_record_c::get_eap_type_list(). + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + /// @see abs_tls_base_record_c::set_session_timeout(). + EAP_FUNC_IMPORT eap_status_e set_session_timeout( + const u32_t session_timeout_ms); + + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + EAP_FUNC_IMPORT eap_status_e peap_tunnel_ready(); + + EAP_FUNC_IMPORT eap_status_e set_tls_session_type(const tls_session_type_e tls_session_type); + + //-------------------------------------------------- +}; // class eap_type_tls_peap_c + +#endif //#if !defined(_EAP_TYPE_TLS_PEAP_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/eap/include/eap_type_tls_peap_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/eap/include/eap_type_tls_peap_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,241 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TLS_PEAP_HEADER_H_) +#define _EAP_TLS_PEAP_HEADER_H_ + +#include "eap_tools.h" +#include "eap_header.h" +#include "tls_peap_types.h" + +/** @file */ + +const u32_t TLS_PEAP_FIRST_SEQUENCE = 1u; +const u8_t TLS_PEAP_NAI_AT_BYTE = '@'; + + +//---------------------------------------------------------------------------- + + +/// This class defines header of TLS_PEAP EAP-type. +/** + * Here is a figure of header of TLS_PEAP EAP-type. + * Subtype-Data is m_length-sizeof(eap_tls_peap_header_c) data octets that follows eap_tls_peap_header_c. + * @code + * EAP/TLS-header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Code | Identifier | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Flags | TLS Message Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TLS Message Length | TLS Data... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * PEAP-header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Code | Identifier | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Flags |Ver| TLS Message Length opt. | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TLS Message Length opt. | TLS Data... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + * + */ +class EAP_EXPORT eap_tls_peap_header_c +: public eap_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + enum message_fields + { + TLS_MESSAGE_LENGTH_FIELD_SIZE = 4u, + }; + + enum bit_shifts + { + m_flag_shift_reserved = 0x02, + m_flag_shift_version = 0x00, + }; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + enum delta_offsets + { + m_flag_delta_offset = 0ul, + m_tls_length_delta_offset = m_flag_delta_offset+sizeof(u8_t), + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + enum bit_masks + { + m_flag_mask_tls_length_included = 0x80, + m_flag_mask_more_fragments = 0x40, + m_flag_mask_start = 0x20, + m_flag_mask_reserved = 0x1c, + m_flag_mask_version = 0x03, + }; + + + EAP_FUNC_IMPORT virtual ~eap_tls_peap_header_c(); + + // + EAP_FUNC_IMPORT eap_tls_peap_header_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_begin, + const u32_t header_buffer_length); + + EAP_FUNC_IMPORT eap_code_value_e get_eap_code() const; + + EAP_FUNC_IMPORT u8_t get_eap_identifier() const; + + EAP_FUNC_IMPORT u16_t get_eap_length() const; + + EAP_FUNC_IMPORT eap_type_value_e get_eap_type() const; + + EAP_FUNC_IMPORT u16_t get_data_length() const; + + EAP_FUNC_IMPORT u32_t get_tls_min_header_length() const; + + EAP_FUNC_IMPORT static u32_t get_tls_max_header_length(); + + EAP_FUNC_IMPORT u32_t get_header_length() const; + + EAP_FUNC_IMPORT u32_t get_tls_flags_offset() const; + + EAP_FUNC_IMPORT u32_t get_tls_length_offset() const; + + EAP_FUNC_IMPORT u32_t get_start_offset_of_data() const; + + EAP_FUNC_IMPORT u8_t * get_data_offset( + abs_eap_am_tools_c * const m_am_tools, + const u32_t offset, + const u32_t contignuous_bytes) const; + + + EAP_FUNC_IMPORT u8_t * get_data( + abs_eap_am_tools_c * const m_am_tools, + const u32_t contignuous_bytes) const; + + + EAP_FUNC_IMPORT u8_t * get_tls_flags() const; + + EAP_FUNC_IMPORT bool get_tls_flag_bit( + const u32_t mask) const; + + EAP_FUNC_IMPORT u8_t get_tls_flag_value( + const u32_t mask, + const u32_t shift) const; + + EAP_FUNC_IMPORT bool get_flag_tls_length_included() const; + + EAP_FUNC_IMPORT bool get_flag_more_fragments() const; + + EAP_FUNC_IMPORT bool get_flag_start() const; + + EAP_FUNC_IMPORT u8_t get_flag_reserved() const; + + EAP_FUNC_IMPORT u8_t get_flag_version() const; + + EAP_FUNC_IMPORT eap_status_e get_tls_message_length( + u32_t * const tls_length) const; + + + EAP_FUNC_IMPORT eap_status_e check_header( + abs_eap_am_tools_c * const tools, + const eap_type_value_e required_eap_type, + const bool is_client_when_true, + const peap_version_e peap_version, + const bool check_peap_version_when_true) const; + + EAP_FUNC_IMPORT eap_const_string get_code_string() const; + + EAP_FUNC_IMPORT eap_const_string get_eap_type_string() const; + + EAP_FUNC_IMPORT void set_eap_code(const eap_code_value_e p_code); + + EAP_FUNC_IMPORT void set_eap_identifier(const u8_t p_identifier); + + EAP_FUNC_IMPORT void set_eap_length( + const u16_t p_length, + const bool expanded_type_when_true); + + EAP_FUNC_IMPORT void set_eap_type( + const eap_type_value_e p_type, + const bool expanded_type_when_true); + + + EAP_FUNC_IMPORT void set_tls_flag_value( + const u8_t value, + const u32_t mask, + const u32_t shift) const; + + EAP_FUNC_IMPORT void set_tls_flag_bit(const bool flag, u32_t mask) const; + + EAP_FUNC_IMPORT void set_flag_reserved(const u8_t reserved); + + EAP_FUNC_IMPORT void set_flag_version(const u8_t version); + + EAP_FUNC_IMPORT void set_flag_tls_length_included(const bool tls_length_included); + + EAP_FUNC_IMPORT void set_flag_more_fragments(const bool more_fragments); + + EAP_FUNC_IMPORT void set_flag_start(const bool start); + + + EAP_FUNC_IMPORT void set_data_length( + const u32_t p_data_length, + const bool expanded_type_when_true); + + EAP_FUNC_IMPORT void set_tls_message_length(const u32_t tls_length); + + + EAP_FUNC_IMPORT void reset_header( + abs_eap_am_tools_c * const m_am_tools, + const eap_type_value_e required_eap_type, + const u32_t buffer_length, + const peap_version_e peap_version, + const bool expanded_type_when_true); + + // + //-------------------------------------------------- +}; // class eap_tls_peap_header_c + + +//-------------------------------------------------- + +#endif //#if !defined(_EAP_TLS_PEAP_HEADER_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/eap/include/eap_type_tls_peap_state_notification.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/eap/include/eap_type_tls_peap_state_notification.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,106 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TLS_PEAP_STATE_NOTIFICATION_H_) +#define _EAP_TLS_PEAP_STATE_NOTIFICATION_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_protocol_layer.h" +#include "eap_state_notification.h" + + +/// A eap_type_tls_peap_state_notification_c class. +/// This is used for debugging and protocol testing. +class EAP_EXPORT eap_type_tls_peap_state_notification_c +: public eap_state_notification_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the eap_type_tls_peap_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_type_tls_peap_state_notification_c(); + + /** + * The constructor of the eap_type_tls_peap_state_notification_c class does nothing special. + */ + EAP_FUNC_IMPORT eap_type_tls_peap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + + +#if defined(USE_EAP_EXPANDED_TYPES) + + EAP_FUNC_IMPORT eap_type_tls_peap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + + EAP_FUNC_IMPORT eap_type_tls_peap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success); + + + //-------------------------------------------------- +}; // class eap_type_tls_peap_state_notification_c + +#endif //#if !defined(_EAP_TLS_PEAP_STATE_NOTIFICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/eap/include/eap_type_tls_peap_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/eap/include/eap_type_tls_peap_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1116 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_TYPE_TLS_PEAP_TYPES_H_) +#define _EAP_TYPE_TLS_PEAP_TYPES_H_ + +#include "eap_buffer.h" +#include "eap_type_all_types.h" +#include "tls_peap_types.h" +#include "eap_configuration_field.h" + +/** @file eap_type_tls_peap_types.h + * @brief This file defines the constants of the TLS_PEAP EAP type. + */ + +/** + * This is the internal state of the TLS_PEAP EAP type. + */ +enum eap_type_tls_peap_state_variable_e +{ + eap_type_tls_peap_state_waiting_for_identity_request , ///< Client state waiting_for_identity_request + eap_type_tls_peap_state_pending_identity_query , ///< Client state pending_identity_query + eap_type_tls_peap_state_waiting_for_tls_start , ///< Client state waiting_for_eap_start + eap_type_tls_peap_state_process_tls_start , ///< Client state process_tls_start + eap_type_tls_peap_state_waiting_for_request , ///< Client state waiting_for_request + eap_type_tls_peap_state_waiting_for_success , ///< Client state waiting_for_success + eap_type_tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet , ///< Client state PEAPv1 waits EAP-Success or tunneled packet. + + eap_type_tls_peap_state_waiting_for_identity_response , ///< Server state waiting_for_identity_response + eap_type_tls_peap_state_waiting_for_first_response , ///< Server state waiting_for_first_response, This is needed in PEAP version negotiation. + eap_type_tls_peap_state_waiting_for_response , ///< Server state waiting_for_response + eap_type_tls_peap_state_waiting_for_empty_response , ///< Server state waiting_for_empty_response + eap_type_tls_peap_state_waiting_for_empty_tppd_peap_v1_acknowledge , ///< Server state waiting_for_empty_tppd_peap_v1_response + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + eap_type_tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack , ///< This is state notification to server to wait empty TTLS/plain MsChapv2 Ack. +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + eap_type_tls_peap_state_process_tls_message , ///< Client or server state process_tls_message + + eap_type_tls_peap_state_success , ///< State state_success + eap_type_tls_peap_state_failure , ///< State state_failure + + eap_type_tls_peap_state_last_value , ///< Keep this enum the last one. +}; + + +enum eap_type_tls_peap_reassembly_state_e +{ + eap_type_tls_peap_reassembly_state_none, + eap_type_tls_peap_reassembly_state_wait_first_message, + eap_type_tls_peap_reassembly_state_wait_last_fragment, + eap_type_tls_peap_reassembly_state_message_reassembled, +}; + + +/** + * This is the type of the TLS_PEAP authentication. + */ +enum eap_tls_peap_authentication_type_e +{ + TLS_PEAP_AUTHENTICATION_TYPE_NONE, + TLS_PEAP_AUTHENTICATION_TYPE_TLS, + TLS_PEAP_AUTHENTICATION_TYPE_PEAP, +}; + +enum eap_type_tls_peap_stored_e +{ + eap_type_tls_peap_stored_none, + eap_type_tls_peap_stored_session_id, + eap_type_tls_peap_stored_master_secret, + eap_type_tls_peap_stored_used_cipher_suite, + eap_type_tls_peap_stored_count_of_session_resumes, + eap_type_tls_peap_stored_test_every_cipher_suite_counter, +#if defined(USE_EAP_TLS_SESSION_TICKET) + eap_type_tls_peap_stored_session_ticket_encryption_key, + eap_type_tls_peap_stored_session_ticket_authentication_key, + eap_type_tls_peap_stored_session_ticket_lifetime_hint, + eap_type_tls_peap_stored_session_ticket_data, +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) +#if defined(USE_FAST_EAP_TYPE) + eap_type_tls_peap_stored_tunnel_pac_is_fresh, + eap_type_tls_peap_stored_tunnel_pac, + eap_type_tls_peap_stored_user_authorization_pac, + eap_type_tls_peap_stored_provisioning_successfull, + eap_type_tls_peap_stored_provisioning_mode, + eap_type_tls_peap_stored_provisioning_pac_type, + eap_type_tls_peap_stored_tls_session_type, +#endif //#if defined(USE_FAST_EAP_TYPE) +}; + +/** + * This is the size of the local send buffer. + */ +const u32_t EAP_TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH = EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH; + +/** + * This is the at character used in NAI. + */ +const u8_t EAP_TLS_PEAP_AT_CHARACTER = '@'; + + +/** + * This is the maximum size of the EAP-TLS/PEAP message. + * This value limits the maximum size of the received EAP-TLS/PEAP message. + */ +const u32_t EAP_TLS_PEAP_MAX_MESSAGE_LENGTH = 65536ul; + + +/** + * @defgroup EAP_TLS_PEAP_config_options Configuration options of EAP-TLS/PEAP. + * The following configuration options are read through abs_eap_base_type_c::read_configure() function. + * @{ + */ + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_use_manual_username, + "EAP_TLS_PEAP_use_manual_username", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_manual_username, + "EAP_TLS_PEAP_manual_username", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_use_manual_realm, + "EAP_TLS_PEAP_use_manual_realm", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_manual_realm, + "EAP_TLS_PEAP_manual_realm", + eap_configure_type_string, + false); + +#if defined(USE_EAP_TLS_SESSION_TICKET) +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_use_session_ticket, + "EAP_TLS_PEAP_use_session_ticket", + eap_configure_type_boolean, + false); +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + + +#if defined(USE_EAP_TLS_SESSION_TICKET) +EAP_CONFIGURATION_FIELD( + cf_str_TLS_fail_with_illegal_session_ticket_or_pac, + "TLS_fail_with_illegal_session_ticket_or_pac", + eap_configure_type_boolean, + false); +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_disable_certificates, + "EAP_TLS_PEAP_disable_certificates", + eap_configure_type_boolean, + false); + + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt, + "EAP_TLS_PEAP_ttls_pap_password_prompt", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_ttls_pap_username, + "EAP_TLS_PEAP_ttls_pap_username", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_ttls_pap_password, + "EAP_TLS_PEAP_ttls_pap_password", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time, + "EAP_TLS_PEAP_ttls_pap_max_session_validity_time", + eap_configure_type_u32_t, + false); + + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_ttls_pap_randomly_fail_password, + "EAP_TLS_PEAP_ttls_pap_randomly_fail_password", + eap_configure_type_boolean, + false); + + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_authority_identity, + "EAP_FAST_authority_identity", + eap_configure_type_string, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_authority_identity_hex_data, + "EAP_FAST_authority_identity", + eap_configure_type_hex_data, + false); + +/** + * This is boolean configuration option. + * True value means every cipher suite is tested during test run. + * False value means only selected cipher suite is tested. See EAP_TLS_PEAP_cipher_suite. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_test_every_cipher_suite, + "EAP_TLS_PEAP_test_every_cipher_suite", + eap_configure_type_boolean, + false); + +/** + * This u32_t configuration option is the cipher suite. + * Default value is 19 = 0x0013 (TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA). + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_cipher_suite, + "EAP_TLS_PEAP_cipher_suite", + eap_configure_type_u32_t, + false); + +/** + * This u32array_t configuration option is the array of accepted cipher suites. + * Default value is 19 = 0x0013 (TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA). + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_allowed_cipher_suites, + "EAP_TLS_PEAP_allowed_cipher_suites", + eap_configure_type_u32array, + false); + +/** + * This u32_t configuration option is the maximum count of session resumes. + * Default value is 0. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_max_count_of_session_resumes, + "EAP_TLS_PEAP_max_count_of_session_resumes", + eap_configure_type_u32_t, + false); + +/** + * This u32_t configuration option is the count of session resumes. + * Default value is 0. + */ +#if defined(USE_EAP_FIXED_DATABASE_FIELDS) +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_count_of_session_resumes, + "EAP_TLS_PEAP_count_of_session_resumes", + eap_configure_type_u32_t, + false); +#else +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_count_of_session_resumes, + "session_resume_count", + eap_configure_type_u32_t, + false); +#endif + + +/** + * This hex data configuration option is the saved session ID. + * Default value is 0. + */ +#if defined(USE_EAP_FIXED_DATABASE_FIELDS) +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_saved_session_id, + "EAP_TLS_PEAP_saved_session_id", + eap_configure_type_hex_data, + false); +#else +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_saved_session_id, + "session_id", + eap_configure_type_hex_data, + false); +#endif + +/** + * This hex data or u32array configuration option value is list of EAP-types client accepts inside PEAP. + * Values in the u32array are type of u32_t. + * This is used in simulator testing. + */ +#if defined(USE_EAP_FIXED_DATABASE_FIELDS) +EAP_CONFIGURATION_FIELD( + cf_str_PEAP_accepted_tunneled_client_types_hex_data, + "PEAP_accepted_tunneled_client_types", + eap_configure_type_hex_data, + false); +EAP_CONFIGURATION_FIELD( + cf_str_PEAP_accepted_tunneled_client_types_u32array, + "PEAP_accepted_tunneled_client_types", + eap_configure_type_u32array, + false); +EAP_CONFIGURATION_FIELD( + cf_str_PEAP_unaccepted_tunneled_client_types_hex_data, + "PEAP_unaccepted_tunneled_client_types", + eap_configure_type_hex_data, + false); +EAP_CONFIGURATION_FIELD( + cf_str_PEAP_unaccepted_tunneled_client_types_u32array, + "PEAP_unaccepted_tunneled_client_types", + eap_configure_type_u32array, + false); +#else +EAP_CONFIGURATION_FIELD( + cf_str_PEAP_accepted_tunneled_client_types_hex_data, + "PEAP_tunneled_types", + eap_configure_type_hex_data, + false); +EAP_CONFIGURATION_FIELD( + cf_str_PEAP_accepted_tunneled_client_types_u32array, + "PEAP_tunneled_types", + eap_configure_type_u32array, + false); + +#endif + +/** + * This hex data or u32array configuration option value is list of EAP-types server accepts inside PEAP. + * Values in the array are type of u32_t. + * This is used in simulator testing. + */ +EAP_CONFIGURATION_FIELD( + cf_str_PEAP_accepted_tunneled_server_types_hex_data, + "PEAP_accepted_tunneled_server_types", + eap_configure_type_hex_data, + false); +EAP_CONFIGURATION_FIELD( + cf_str_PEAP_accepted_tunneled_server_types_u32array, + "PEAP_accepted_tunneled_server_types", + eap_configure_type_u32array, + false); + +/** + * This boolean configuration option value true allows PEAP restore tunneled session. + * This means PEAP does not run the tunneled EAP-type when + * PEAP session is resumed successfully. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_PEAP_allow_tunneled_session_resumption, + "PEAP_allow_tunneled_session_resumption", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option value true allows PEAP server restore tunneled session. + * This means PEAP version 0 does not run the tunneled EAP-type when + * PEAP session is resumed successfully. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_PEAP_server_allow_tunneled_session_resumption, + "PEAP_server_allow_tunneled_session_resumption", + eap_configure_type_boolean, + false); + +/** + * This boolean configuration option value true commands PEAPv1 server use tunneled Extensions Request message. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_PEAPv1_server_use_extensions_request, + "PEAPv1_server_use_extensions_request", + eap_configure_type_boolean, + false); + +/** + * This hex data configuration option is the saved master secret. + * Default value is 0. + */ +#if defined(USE_EAP_FIXED_DATABASE_FIELDS) +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_saved_master_secret, + "EAP_TLS_PEAP_saved_master_secret", + eap_configure_type_hex_data, + true); +#else +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_saved_master_secret, + "master_secret", + eap_configure_type_hex_data, + true); +#endif + +/** + * This u32_t configuration option is the saved cipher suite. + * Default value is 0. + */ +#if defined(USE_EAP_FIXED_DATABASE_FIELDS) +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_saved_cipher_suite, + "EAP_TLS_PEAP_saved_cipher_suite", + eap_configure_type_u32_t, + false); +#else +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_saved_cipher_suite, + "saved_cipher_suite", + eap_configure_type_u32_t, + false); +#endif + + +/** + * This string configuration option is the filename for the client DSA certificate used + * in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_DSA_client_certificate_file, + "EAP_TLS_PEAP_DSA_client_certificate_file", + eap_configure_type_string, + false); + +/** + * This string configuration option is the filename for the client DSA private key used + * in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_DSA_client_private_key_file, + "EAP_TLS_PEAP_DSA_client_private_key_file", + eap_configure_type_string, + false); + +/** + * This string configuration option is the filename for the server DSA certificate used + * in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_DSA_server_certificate_file, + "EAP_TLS_PEAP_DSA_server_certificate_file", + eap_configure_type_string, + false); + +/** + * This string configuration option is the filename for the server DSA private key used + * in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_DSA_server_private_key_file, + "EAP_TLS_PEAP_DSA_server_private_key_file", + eap_configure_type_string, + false); + +/** + * This string configuration option is the filename for the client's CA + * DSA certificate used for verifying server's identity in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_DSA_client_ca_certificate_file, + "EAP_TLS_PEAP_DSA_client_ca_certificate_file", + eap_configure_type_string, + false); + +/** + * This string configuration option is the filename for the server's CA + * DSA certificate used for verifying client's identity in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_DSA_server_ca_certificate_file, + "EAP_TLS_PEAP_DSA_server_ca_certificate_file", + eap_configure_type_string, + false); + + +/** + * This string configuration option is the filename for the client RSA certificate used + * in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_RSA_client_certificate_file, + "EAP_TLS_PEAP_RSA_client_certificate_file", + eap_configure_type_string, + false); + +/** + * This string configuration option is the filename for the client RSA private key used + * in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_RSA_client_private_key_file, + "EAP_TLS_PEAP_RSA_client_private_key_file", + eap_configure_type_string, + false); + +/** + * This string configuration option is the filename for the server RSA certificate used + * in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_RSA_server_certificate_file, + "EAP_TLS_PEAP_RSA_server_certificate_file", + eap_configure_type_string, + false); + +/** + * This string configuration option is the filename for the server RSA private key used + * in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_RSA_server_private_key_file, + "EAP_TLS_PEAP_RSA_server_private_key_file", + eap_configure_type_string, + false); + +/** + * This string configuration option is the filename for the client's CA + * RSA certificate used for verifying server's identity in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_RSA_client_ca_certificate_file, + "EAP_TLS_PEAP_RSA_client_ca_certificate_file", + eap_configure_type_string, + false); + +/** + * This string configuration option is the filename for the server's CA + * RSA certificate used for verifying client's identity in EAP-type TLS_PEAP. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_RSA_server_ca_certificate_file, + "EAP_TLS_PEAP_RSA_server_ca_certificate_file", + eap_configure_type_string, + false); + + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) +/** + * This is boolean configuration option. + * True value means on TLS client uses privacy. + * False value means on TLS client does not use privacy. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_use_identity_privacy, + "EAP_TLS_PEAP_use_identity_privacy", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means on TLS server uses privacy. + * False value means on TLS server does not use privacy. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_use_identity_privacy_server, + "EAP_TLS_PEAP_use_identity_privacy_server", + eap_configure_type_boolean, + false); +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + +/** + * This is boolean configuration option. + * True value means EAP-FAST server sends piggypacked EAP-Identity/Request. + * False value means EAP-FAST server does not send piggypacked EAP-Identity/Request, instead it waits empty Ack-message from client. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_send_piggypacked_eap_identity_request, + "EAP_FAST_send_piggypacked_eap_identity_request", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means EAP-FAST can run server unauthenticated provisioning. + * False value means no EAP-FAST server unauthenticated provisioning is allowed. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP, + "EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means EAP-FAST can run server authenticated provisioning. + * False value means no EAP-FAST server authenticated provisioning is allowed. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode, + "EAP_FAST_allow_server_authenticated_provisioning_mode", + eap_configure_type_boolean, + false); + + +/** + * This is boolean configuration option. + * True value means EAP-FAST client can provisioning User Authorization PAC. + * False value means EAP-FAST client can not provisioning User Authorization PAC. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_allow_user_authorization_pac_provisioning, + "EAP_FAST_allow_user_authorization_pac_provisioning", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means EAP-FAST server randomly refuses provisioning User Authorization PAC. + * False value means EAP-FAST server does provisioning User Authorization PAC. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_randomly_does_not_provision_user_authorization_pac, + "EAP_FAST_randomly_does_not_provision_user_authorization_pac", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means EAP-FAST server randomly fail successfull authentication with EAP-Failure. + * False value means EAP-FAST server does not ramdomly fail authentication. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_server_randomly_fail_authentication, + "EAP_FAST_server_randomly_fail_authentication", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means EAP-FAST client accepts A-ID. + * False value means no EAP-FAST client does not accept A-ID. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_accept_a_id, + "EAP_TLS_PEAP_accept_a_id", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means EAP-FAST server fail check of User Authorization PAC randomly. + * False value means no EAP-FAST server does not fail check of User Authorization PAC randomly. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_test_fail_user_authorization_pac_randomly, + "EAP_FAST_test_fail_user_authorization_pac_randomly", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means EAP-FAST server fail check of Tunnel PAC randomly. + * False value means no EAP-FAST server does not fail check of Tunnel PAC randomly. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_test_fail_tunnel_pac_randomly, + "EAP_FAST_test_fail_tunnel_pac_randomly", + eap_configure_type_boolean, + false); + +/** + * This string configuration option is the password of PAC store. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_PAC_store_password, + "EAP_FAST_PAC_store_password", + eap_configure_type_string, + false); + +/** + * This string configuration option is the password of PAC file. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_tppds_PAC_file_password, + "EAP_FAST_tppds_PAC_file_password", + eap_configure_type_string, + false); + +/** + * This string configuration option is the device seed of PAC store password. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_PAC_store_device_seed, + "EAP_FAST_PAC_store_device_seed", + eap_configure_type_string, + false); + + +/** + * This string configuration option is the directory path to PAC store. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_PAC_store_path, + "EAP_FAST_PAC_store_path", + eap_configure_type_string, + false); + + +/** + * This string configuration option is the directory path of import directory of PAC store. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_import_path, + "EAP_FAST_import_path", + eap_configure_type_string, + false); + + +/** + * This hex data configuration option is the encryption key server uses with PAC. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_PAC_encryption_key, + "EAP_FAST_PAC_encryption_key", + eap_configure_type_hex_data, + false); + +/** + * This hex data configuration option is the authentication key server uses with PAC. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_PAC_authentication_key, + "EAP_FAST_PAC_authentication_key", + eap_configure_type_hex_data, + false); + +/** + * This hex data configuration option is the IAP reference the client uses. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_IAP_reference, + "EAP_FAST_IAP_reference", + eap_configure_type_hex_data, + false); + +/** + * This hex data configuration option is the Group reference the client uses. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_Group_reference, + "EAP_FAST_Group_reference", + eap_configure_type_hex_data, + false); + + +/** + * This u32_t data configuration option is the timeout of the PAC store key. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_PAC_store_key_timeout_ms, + "EAP_FAST_PAC_store_key_timeout_ms", + eap_configure_type_u32_t, + false); + + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_test_remove_IAP_reference, + "EAP_FAST_test_remove_IAP_reference", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_test_add_imported_PAC_file, + "EAP_FAST_test_add_imported_PAC_file", + eap_configure_type_boolean, + false); + + +/** + * This u32_t data configuration option is the timeout before finish successfull authentication. This is leave time for UI. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_delay_successfull_finish_timeout, + "EAP_FAST_delay_successfull_finish_timeout", + eap_configure_type_u32_t, + false); + +/** + * This boolean data configuration option activate prompt to warn for ADHP auto-provisioning when + * there is no PAC that matches the A-ID sent by server. EAP-FAST specific. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_warn_ADHP_no_matching_PAC, + "EAP_FAST_warn_ADHP_no_matching_PAC", + eap_configure_type_boolean, + false); + +/** + * This boolean data configuration option activate prompt to warn for ADHP (Authenticated Diffie-Hellman Protocol) + * auto-provisioning when there is no PAC at all. EAP-FAST specific. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_warn_ADHP_no_PAC, + "EAP_FAST_warn_ADHP_no_PAC", + eap_configure_type_boolean, + false); + +/** + * This boolean data configuration option activate prompt to warn when client encouters a server that has provisioned + * the client with a PAC before but is not currently selected as the default server. EAP-FAST specific. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_warn_ADHP_not_default_server, + "EAP_FAST_warn_ADHP_not_default_server", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means on successfull authentication EAP-type TLS_PEAP waits the EAP-Success message. + * False value means on successfull authentication EAP-type TLS_PEAP does NOT wait the EAP-Success message. + * NOTE: True value is needed in Windows RAS. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_wait_eap_success_packet, + "EAP_TLS_PEAP_wait_eap_success_packet", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value means on EAP-type TLS_PEAP must check identifier of EAP-Response/Identity message. + * False value means on EAP-type TLS_PEAP does not check identifier of EAP-Response/Identity message. + * This is not possible in cases where identifier of the EAP-Request/Identity is generated by other network entities. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_check_identifier_of_eap_identity_response, + "EAP_TLS_PEAP_check_identifier_of_eap_identity_response", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag activates NAI realm check. Default value is false. + * When active NAI realm muts be the same as realm given by EAP_TLS_PEAP_manual_realm option. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_check_nai_realm, + "EAP_TLS_PEAP_check_nai_realm", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is for testing. + * True value means on test version of EAP-type TLS_PEAP is used. + * Test version tries to make as many authentications as it is possible. + * False value means on real version of EAP-type TLS_PEAP is used. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_test_version, + "EAP_TLS_test_version", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * True value of this flag causes client return random + * identity on EAP-Response/Identity. + * False value causes client return real identity + * (IMSI, pseudonym or re-authentication identity) + * in EAP-Response/Identity. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_use_random_identity_on_eap_identity_response, + "EAP_TLS_PEAP_use_random_identity_on_eap_identity_response", + eap_configure_type_boolean, + false); + +/** + * This is u32_t configuration option. + * Server selects the proposed PEAP version with this option. + * Possible values are 2, 1 and 0. + * See: PEAPv0 draft-kamath-pppext-peapv0-00.txt + * PEAPv1 draft-josefsson-pppext-eap-tls-eap-05.txt + * PEAPv2 draft-josefsson-pppext-eap-tls-eap-XX.txt + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_used_PEAP_version, + "EAP_TLS_PEAP_used_PEAP_version", + eap_configure_type_u32_t, + false); + +/** + * This is u32array configuration option. + * Client and server accepts and selects the PEAP version with this option. + * Possible values are 2, 1 and 0. + * See: PEAPv0 draft-kamath-pppext-peapv0-00.txt + * PEAPv1 draft-josefsson-pppext-eap-tls-eap-05.txt + * PEAPv2 draft-josefsson-pppext-eap-tls-eap-XX.txt + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_accepted_PEAP_versions, + "EAP_TLS_PEAP_accepted_PEAP_versions", + eap_configure_type_u32array, + false); + +/** + * This is u32array configuration option. + * Server accepts and selects the PEAP version with this option. + * Possible values are 2, 1 and 0. + * See: PEAPv0 draft-kamath-pppext-peapv0-00.txt + * PEAPv1 draft-josefsson-pppext-eap-tls-eap-05.txt + * PEAPv2 draft-josefsson-pppext-eap-tls-eap-XX.txt + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_server_accepted_PEAP_versions, + "EAP_TLS_PEAP_server_accepted_PEAP_versions", + eap_configure_type_u32array, + false); + +/** + * This is boolean configuration option. + * This will select whether the different TLS and PEAP version is used. + * Different TLS and PEAP versions use TLS message length in all first message fragments + * even the message fits to one fragment except EAP-TLS-start, EAP-TLS-Acknowledge and + * PEAP-application data. The client acknowledges tunneled EAP-Success message + * with empty PEAP message. + * Microsoft's and other's TLS and PEAP does use TLS message only + * in the first fragmented TLS message. + * True value means TLS message length is included (different style). + * False value means TLS message length is NOT included (normal style). + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_use_tppd_tls_peap, + "EAP_TLS_PEAP_use_tppd_tls_peap", + eap_configure_type_boolean, + false); + +/** + * On fast session resume Tppd's server does not send tunneled EAP-Success. + * Instead it sends plain EAP-Success. + * This configuration flag when set true allows this functionality in client and server. + * False value disables this functionality in client and server. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_use_tppd_peapv1_acknowledge_hack, + "EAP_TLS_use_tppd_peapv1_acknowledge_hack", + eap_configure_type_boolean, + false); + +/** + * This is for server only. + * On fast session resume Tppd's server does not send tunneled EAP-Success. + * Instead it sends plain EAP-Success. + * This configuration flag when set true allows this functionality in server. + * False value disables this functionality in server. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_server_use_tppd_peapv1_acknowledge_hack, + "EAP_TLS_server_use_tppd_peapv1_acknowledge_hack", + eap_configure_type_boolean, + false); + + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means queries to AM are completed asyncronous. + * False value means queries to AM are completed syncronous. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_do_asyncronous_completions, + "EAP_TLS_PEAP_do_asyncronous_completions", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This is used in simulator testing. + * True value means queries to AM are randomly completed asyncronous. + * False value means queries to AM are randomly completed syncronous. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_do_asyncronous_completions_randomly, + "EAP_TLS_PEAP_do_asyncronous_completions_randomly", + eap_configure_type_boolean, + false); + +/** + * This is u32_t configuration option. + * This is used in simulator testing. + * Value is the maximum completion time (ms) when completitions are + * completed randomly. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_max_tls_completion_time, + "EAP_TLS_PEAP_max_tls_completion_time", + eap_configure_type_u32_t, + false); + +/** + * This is boolean configuration option. + * This is used in client simulator testing. + * True value means query_certificate_chain() to AM fails always automatically in client. + * False value means query_certificate_chain() to AM works normally in client. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_fail_query_certificate_chain, + "EAP_TLS_PEAP_fail_query_certificate_chain", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag activates NAI realm check of certificate. + * Both client and server will check this. + * When this is active *server* checks the NAI realm of EAP-response/Identity is + * the same as realm given in the certificate of the client. + * When this is active *client* checks the NAI realm of EAP-response/Identity is + * the same as realm given in the certificate of the server. + * Default value is true. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_verify_certificate_realm, + "EAP_TLS_PEAP_verify_certificate_realm", + eap_configure_type_boolean, + false); + +/** + * This is boolean configuration option. + * This flag activates "relaxed" NAI realm check of certificate. Realm does not have to + * match exactly in this mode. For example server.eapsim.foo and eapsim.foo are considered + * to be the same realm. + * Only client will check this. + * Default value is false. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_allow_subdomain_matching, + "EAP_TLS_PEAP_allow_subdomain_matching", + eap_configure_type_boolean, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_PEAP_use_eap_expanded_type, + "EAP_TLS_PEAP_use_eap_expanded_type", + eap_configure_type_boolean, + false); + +/** + * This u32_t configuration value specifies the maximum session validity time in seconds. + * Default value is 12 hours in seconds, which is 43200 seconds. + */ +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TLS_max_session_validity_time, + "EAP_TLS_max_session_validity_time", + eap_configure_type_u32_t, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_PEAP_max_session_validity_time, + "EAP_PEAP_max_session_validity_time", + eap_configure_type_u32_t, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_TTLS_max_session_validity_time, + "EAP_TTLS_max_session_validity_time", + eap_configure_type_u32_t, + false); + +EAP_CONFIGURATION_FIELD( + cf_str_EAP_FAST_max_session_validity_time, + "EAP_FAST_max_session_validity_time", + eap_configure_type_u32_t, + false); + +/** @} */ // End of group EAP_TLS_PEAP_config_options. + +//-------------------------------------------------- + + +#endif //#if !defined(_EAP_TYPE_TLS_PEAP_TYPES_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/eap_tls_peap_state_notification.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/eap_tls_peap_state_notification.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 118 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_tls_peap_state_notification.h" +#include "eap_type_tls_peap.h" +#include "eap_tools.h" + + +EAP_FUNC_EXPORT eap_tls_peap_state_notification_c::~eap_tls_peap_state_notification_c() +{ +} + +EAP_FUNC_EXPORT eap_tls_peap_state_notification_c::eap_tls_peap_state_notification_c( + const eap_am_network_id_c * const send_network_id, + eap_boolean_e is_client, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + eap_boolean_e allow_send_eap_success) + : m_layer(layer) + , m_protocol(protocol) + , m_previous_state(previous_state) + , m_current_state(current_state) + , m_send_network_id(send_network_id) + , m_is_client(is_client) + , m_eap_identifier(eap_identifier) + , m_allow_send_eap_success(allow_send_eap_success) +{ +} + +EAP_FUNC_EXPORT const eap_am_network_id_c * const eap_tls_peap_state_notification_c::get_send_network_id() const +{ + return m_send_network_id; +} + +EAP_FUNC_EXPORT const eap_protocol_layer_e eap_tls_peap_state_notification_c::get_protocol_layer() const +{ + return m_layer; +} + +EAP_FUNC_EXPORT const u32_t eap_tls_peap_state_notification_c::get_protocol() const +{ + return m_protocol; +} + +EAP_FUNC_EXPORT const u32_t eap_tls_peap_state_notification_c::get_previous_state() const +{ + return m_previous_state; +} + +EAP_FUNC_EXPORT const u32_t eap_tls_peap_state_notification_c::get_current_state() const +{ + return m_current_state; +} + +EAP_FUNC_EXPORT eap_const_string eap_tls_peap_state_notification_c::get_current_state_string() const +{ + // NOTE this is static function. + return eap_type_tls_peap_c::get_state_string((eap_type_tls_peap_state_variable_e)m_current_state); +} + +EAP_FUNC_EXPORT eap_const_string eap_tls_peap_state_notification_c::get_previous_state_string() const +{ + // NOTE this is static function. + return eap_type_tls_peap_c::get_state_string((eap_type_tls_peap_state_variable_e)m_previous_state); +} + +EAP_FUNC_EXPORT const eap_boolean_e eap_tls_peap_state_notification_c::get_is_client() const +{ + return m_is_client; +} + +EAP_FUNC_EXPORT const u8_t eap_tls_peap_state_notification_c::get_eap_identifier() const +{ + return m_eap_identifier; +} + +EAP_FUNC_EXPORT eap_boolean_e eap_tls_peap_state_notification_c::get_allow_send_eap_success() const +{ + return m_allow_send_eap_success; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/eap_type_tls_peap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/eap_type_tls_peap.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,6404 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 119 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_type_tls_peap_types.h" +#include "eap_type_tls_peap.h" +#include "eap_type_tls_peap_header.h" +#include "eap_type_tls_peap_state_notification.h" +#include "eap_am_type_tls_peap.h" +#include "eap_state_notification.h" +#include "tls_record_header.h" +#include "tls_base_record.h" +#include "eap_config.h" +#include "eap_header_string.h" +#include "eap_automatic_variable.h" + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_type_tls_peap_c::~eap_type_tls_peap_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x => 0x%08x, %s: function: eap_type_tls_peap_c::~eap_type_tls_peap_c():,") + EAPL(" m_am_type_tls_peap = 0x%08x (validity %d).\n"), + this, + dynamic_cast(this), + (m_is_client == true ? "client": "server"), + m_am_type_tls_peap, + m_am_type_tls_peap->get_is_valid())); + + EAP_ASSERT(m_shutdown_was_called == true); + + if (m_free_tls_record == true) + { + delete m_tls_record; + m_tls_record = 0; + } + + if (m_free_am_type_tls_peap == true) + { + delete m_am_type_tls_peap; + m_am_type_tls_peap = 0; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_type_tls_peap_c::eap_type_tls_peap_c( + abs_eap_am_tools_c * const tools, ///< This is pointer to the tools AM of current platform. + abs_eap_base_type_c * const partner, ///< This is back pointer to object which created this object. + eap_am_type_tls_peap_c * const am_type_tls_peap, ///< This is pointer to adaptation module of TLS/PEAP EAP type. + const bool free_am_type_tls_peap, + tls_base_record_c * const tls_record, /// This is pointer to TLS implementation. + const bool free_tls_record, + const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false). + const eap_type_value_e current_eap_type, ///< This the current EAP-type (TLS or PEAP). + const eap_am_network_id_c * const receive_network_id) + : eap_base_type_c(tools, partner) + , m_am_tools(tools) + , m_am_type_tls_peap(am_type_tls_peap) + , m_tls_record(tls_record) + , m_nai_realm(tools) + , m_NAI(tools) + , m_current_identity(tools) + , m_send_network_id(tools) + , m_tls_peap_header_offset(0u) + , m_MTU(0u) + , m_trailer_length(0u) + , m_state(eap_type_tls_peap_state_waiting_for_identity_request) + , m_saved_previous_state(eap_type_tls_peap_state_waiting_for_identity_request) + , m_reassembly_state(eap_type_tls_peap_reassembly_state_wait_first_message) + , m_saved_previous_reassembly_state(eap_type_tls_peap_reassembly_state_wait_first_message) + , m_tls_message_send_offset(0ul) + , m_tls_message_buffer(tools) + , m_master_session_key(tools, current_eap_type) + , m_accepted_PEAP_versions(tools) + , m_current_eap_type(current_eap_type) + , m_configured_peap_version(peap_version_none) + , m_current_peap_version(peap_version_none) + , m_first_fragment_eap_identifier(0ul) + , m_tls_session_type(tls_session_type_none) + , m_tunneled_eap_type_active(false) + , m_tunneled_eap_type_authentication_state(eap_state_none) + , m_free_am_type_tls_peap(free_am_type_tls_peap) + , m_free_tls_record(free_tls_record) + , m_is_valid(false) + , m_is_client(is_client_when_true) + , m_wait_eap_success_packet(true) + , m_check_identifier_of_eap_identity_response(false) + , m_tls_peap_test_version(false) + , m_check_nai_realm(false) +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + , m_tls_use_identity_privacy(false) +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + , m_failure_message_received(false) + , m_authentication_finished_successfully(false) + , m_last_eap_identifier(0ul) + , m_shutdown_was_called(false) + , m_use_tppd_tls_peap(true) + , m_use_tppd_peapv1_acknowledge_hack(true) + , m_includes_tls_handshake_message(false) + , m_use_eap_expanded_type(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x => 0x%08x, %s: function: eap_type_tls_peap_c::eap_type_tls_peap_c(): compiled %s %s\n"), + this, + dynamic_cast(this), + (m_is_client == true ? "client": "server"), + __DATE__, + __TIME__)); + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + // No need to delete anything here because it is done in destructor. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (tls_record == 0) + { + // No need to delete anything here because it is done in destructor. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + m_tls_record->set_type_partner(this); + + if (m_am_type_tls_peap == 0) + { + // Something wrong with AM. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + m_am_type_tls_peap->set_am_partner(this); + + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + eap_status_e status = get_send_network_id()->set_copy_of_network_id( + &send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (m_is_client == false) + { + // Server waits EAP-Response/Identity. + m_state = eap_type_tls_peap_state_waiting_for_identity_response; + m_saved_previous_state + = eap_type_tls_peap_state_waiting_for_identity_response; + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::save_current_state() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_saved_previous_state = m_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::restore_saved_previous_state() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + set_state(m_saved_previous_state); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::set_state( + const eap_type_tls_peap_state_variable_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_type_tls_peap_state_variable_e previous_state = m_state; + + if (m_state != eap_type_tls_peap_state_failure) + { + m_state = state; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x, %s, %s: eap_type_tls_peap_c::set_state(): ") + EAPL(" Previous state %d=%s, new state %d=%s.\n"), + this, + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"), + previous_state, + get_state_string(previous_state), + m_state, + get_state_string(m_state))); + + eap_type_tls_peap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap_type, + m_current_eap_type, + previous_state, + state, + m_last_eap_identifier, + false); + get_type_partner()->state_notification(¬ification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_type_tls_peap_reassembly_state_e eap_type_tls_peap_c::get_reassembly_state() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_reassembly_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::set_reassembly_state( + const eap_type_tls_peap_reassembly_state_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_reassembly_state = state; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::save_current_reassembly_state() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_saved_previous_reassembly_state = m_reassembly_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::restore_saved_reassembly_state() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_reassembly_state = m_saved_previous_reassembly_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_network_id_c * eap_type_tls_peap_c::get_send_network_id() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_send_network_id; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::set_last_eap_identifier(const u8_t last_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_last_eap_identifier = last_eap_identifier; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x, %s, %s, eap_type_tls_peap_c::set_last_eap_identifier():") + EAPL(" saved EAP-identifier %d, state %s\n"), + this, + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"), + m_last_eap_identifier, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u8_t eap_type_tls_peap_c::get_last_eap_identifier() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x, eap_type_tls_peap_c::get_last_eap_identifier():") + EAPL("%s, saved EAP-identifier %d, state %s\n"), + this, + (m_is_client == true ? "client": "server"), + m_last_eap_identifier, + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_last_eap_identifier; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_const_string eap_type_tls_peap_c::get_state_string( + eap_type_tls_peap_state_variable_e state) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_waiting_for_identity_request) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_pending_identity_query) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_waiting_for_tls_start) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_process_tls_start) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_waiting_for_request) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_waiting_for_success) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_waiting_for_identity_response) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_waiting_for_first_response) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_waiting_for_response) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_waiting_for_empty_response) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_process_tls_message) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_success) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_state_failure) + else +#else +EAP_UNREFERENCED_PARAMETER(state); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown EAP-TLS/PEAP state"); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_const_string eap_type_tls_peap_c::get_reassembly_state_string( + eap_type_tls_peap_reassembly_state_e state) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(state, eap_type_tls_peap_reassembly_state_none) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_reassembly_state_wait_first_message) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_reassembly_state_wait_last_fragment) + else EAP_IF_RETURN_STRING(state, eap_type_tls_peap_reassembly_state_message_reassembled) + else +#else +EAP_UNREFERENCED_PARAMETER(state); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown TLS_PEAP reassembly state"); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_tls_peap_c::get_state_string() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return get_state_string(m_state); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_tls_peap_c::get_reassembly_state_string() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return get_reassembly_state_string(m_reassembly_state); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string eap_type_tls_peap_c::get_saved_previous_state_string() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return get_state_string(m_saved_previous_state); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_type_tls_peap_c::set_failure_message_received() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_failure_message_received = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_type_tls_peap_c::unset_failure_message_received() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_failure_message_received = false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_type_tls_peap_c::get_failure_message_received() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_failure_message_received; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_type_tls_peap_state_variable_e eap_type_tls_peap_c::get_state() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_state; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::generate_nai( + eap_variable_data_c * const /*new_nai*/, ///< This is the new generated NAI. + const eap_variable_data_c * const /*domain*/, ///< This is the domain part of the NAI. + const eap_variable_data_c * const /*identity*/ ///< This is identity. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::handle_tls_peap_packet( + const eap_am_network_id_c * const /*receive_network_id*/, ///< This is the network identity of the received EAP packet. + eap_tls_peap_header_c * const /*tls_peap*/, ///< This is pointer to EAP header including EAP-TLS/PEAP fields. + const u32_t /*tls_peap_length*/ ///< This is length of received TLS/PEAP EAP packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::analyse_tls_peap_packet( + const eap_am_network_id_c * const /*receive_network_id*/, ///< This is the network identity of the received EAP packet. + eap_tls_peap_header_c * const /*received_tls_peap*/, ///< This is pointer to EAP header including EAP-TLS/PEAP fields. + const u32_t /*tls_peap_packet_length*/ ///< This is length of received TLS/PEAP EAP packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::parse_tls_peap_payload( + u32_t * const /*buffer_length*/ ///< This is the length of the buffer. This must match with the length of all payloads. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::check_version_list( + const u16_t /*version_list_length*/, + u8_t * /*version_list*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::parse_tls_peap_packet( + eap_tls_peap_header_c * const /*tls_peap*/, ///< This is pointer to EAP header including EAP-TLS/PEAP fields. + const u32_t /*tls_peap_packet_length*/ ///< This is length of received TLS/PEAP EAP packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_tls_peap_c::get_nai_realm() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_nai_realm; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_variable_data_c * eap_type_tls_peap_c::get_NAI() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_NAI; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::update_buffer_indexes( + const u32_t maximum_buffer_size, + const u32_t payload_size, + u32_t * const buffer_offset, + u32_t * const buffer_free) +{ + EAP_UNREFERENCED_PARAMETER(maximum_buffer_size); + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length); + EAP_ASSERT_ALWAYS(*buffer_free >= payload_size); + EAP_ASSERT_ALWAYS(m_tls_peap_header_offset+m_MTU == *buffer_offset + *buffer_free); + + *buffer_free -= payload_size; + *buffer_offset += payload_size; + + EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length); + EAP_ASSERT_ALWAYS(*buffer_offset <= m_tls_peap_header_offset+m_MTU); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::update_payload_indexes( + const u32_t /*maximum_buffer_size*/, + const u32_t /*eap_header_size*/, + const u32_t /*payload_size*/, + u32_t * const /*data_offset*/, + u32_t * const /*data_free*/, + u32_t * const /*buffer_offset*/, + u32_t * const /*buffer_free*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::parse_identity( + const u8_t * const identity, ///< This is pointer to received EAP-Identity buffer. + const u32_t identity_length ///< This is length of received EAP-Identity buffer. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (identity_length < 1u) + { + // Anonymous identity. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + const u8_t *at_character = reinterpret_cast( + m_am_tools->memchr( + identity, + EAP_TLS_PEAP_AT_CHARACTER, + identity_length)); + if (at_character == 0) + { + // No realm. + // This is allowed. + } + + eap_status_e status = check_NAI(identity, identity_length, at_character); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_process_general_error; + + u32_t username_length = identity_length; + if (at_character != 0) + { + username_length = static_cast(at_character-identity); + } + + status = m_current_identity.set_copy_of_buffer( + identity, + username_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_NAI()->set_copy_of_buffer(identity, identity_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS/PEAP received EAP-identity NAI"), + get_NAI()->get_data(get_NAI()->get_data_length()), + get_NAI()->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::handle_identity_response_message( + eap_header_rd_c * const /*eap_header*/, ///< This is the received EAP-Identity packet, pointer points to the header. + const u32_t /*tls_peap_packet_length*/ ///< This is length of received TLS/PEAP EAP packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::tls_peap_packet_send( + eap_buf_chain_wr_c * const sent_packet, + const u32_t /*header_offset*/, + const u32_t /*data_length*/, + const u32_t /*buffer_length*/, + const bool includes_tls_handshake_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: function: eap_type_tls_peap_c::tls_peap_packet_send()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eap_status_not_supported; + + if ((m_is_client == true + && get_state() == eap_type_tls_peap_state_process_tls_start) + || get_state() == eap_type_tls_peap_state_process_tls_message + || get_state() == eap_type_tls_peap_state_waiting_for_request // This state is needed to send messages from asyncronous completions. + || get_state() == eap_type_tls_peap_state_waiting_for_response + || get_state() == eap_type_tls_peap_state_failure // This state is needed to send failure messages. + || get_state() == eap_type_tls_peap_state_waiting_for_empty_response + || get_state() == eap_type_tls_peap_state_waiting_for_success + || get_state() == eap_type_tls_peap_state_success +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + || get_state() == eap_type_tls_peap_state_waiting_for_empty_tppd_peap_v1_acknowledge + || (m_is_client == true + && m_current_eap_type == eap_type_peap + && m_current_peap_version == peap_version_1 + && m_use_tppd_tls_peap == true + && m_use_tppd_peapv1_acknowledge_hack == true + && (get_tls_session_type() == tls_session_type_original_session_resumption + || get_tls_session_type() == tls_session_type_stateless_session_resumption) + && (get_state() == eap_type_tls_peap_state_success + || get_state() == eap_type_tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet)) +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + || get_state() == eap_type_tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + ) + { + status = m_tls_message_buffer.set_copy_of_buffer( + sent_packet->get_data(sent_packet->get_data_length()), + sent_packet->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This will start the packet send from begin of the message. + m_tls_message_send_offset = 0ul; + + m_includes_tls_handshake_message = includes_tls_handshake_message; + + status = eap_tls_peap_fragment_send(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: this = 0x%08x, eap_type_tls_peap_c::tls_peap_packet_send(): ") + EAPL("Cannot send EAP-TLS/PEAP message in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + this, + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s, %s: function: eap_type_tls_peap_c::packet_send()\n"), + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + eap_header_wr_c eap( + m_am_tools, + sent_packet->get_data_offset( + header_offset, data_length), + data_length); + if (eap.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + packet_trace( + EAPL("<-"), + network_id, + &eap, + data_length); + + eap_status_e status = get_type_partner()->packet_send( + network_id, + sent_packet, + header_offset, + data_length, + buffer_length + ); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::check_NAI( + const u8_t * const identity, + const u32_t identity_length, + const u8_t * const at_character) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + bool includes_at = false; + bool includes_dot = false; + u32_t username_length = 0u; + u32_t realm_length = 0u; + + for (u32_t ind = 0; ind < identity_length; ind++) + { + const u8_t character = identity[ind]; + + if (includes_at == false) + { + if (character != EAP_TLS_PEAP_AT_CHARACTER) + { + ++username_length; + } + } + else + { + ++realm_length; + } + + + if ('0' <= character && character <= '9') + { + // OK. + } + else if ('a' <= character && character <= 'z') + { + // OK. + } + else if ('A' <= character && character <= 'Z') + { + // OK. + } + else if (character == EAP_TLS_PEAP_AT_CHARACTER) + { + if (includes_at == false) + { + includes_at = true; + } + else + { + // Second at ('@'). + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Illegal NAI, includes second at \'@\' character."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + else if (character == '.') + { + if (includes_at == true) + { + // OK. + includes_dot = true; + } + else + { + // dot ('.') within username + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Illegal NAI, dot \'.\' within username."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + else if (character == '<' + || character == '>' + || character == '(' + || character == ')' + || character == '[' + || character == ']' + || character == '\\' + || character == '.' + || character == ',' + || character == ';' + || character == ':' + || character == EAP_TLS_PEAP_AT_CHARACTER + || character == ' ' // space + || character <= 0x1f // Ctrl + || character >= 0x7f) // extented characters + { + // Illegal character. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: Illegal NAI, includes illegal character 0x%02x=%c.\n"), + character, + character)); + EAP_TRACE_DATA_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Illegal NAI, includes illegal character."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + else + { + // All other ascii values are OK. + } + } + + // Note the username could be zero length. + if ((realm_length == 1u && includes_at == true) // one at ('@') is illegal. + || (realm_length == 2u && includes_at == true && includes_dot == true)) // one at ('@') and one dot is illegal. + { + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Illegal NAI."), + identity, + identity_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + + if (m_check_nai_realm == true) + { + if (at_character == 0 + && realm_length == 0 + && get_nai_realm()->get_data_length() == 0) + { + // OK, no realm. + } + else if (at_character == 0 + || realm_length != get_nai_realm()->get_data_length() + || m_am_tools->memcmp( + at_character+1u, + get_nai_realm()->get_data(get_nai_realm()->get_data_length()), + get_nai_realm()->get_data_length()) != 0) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Illegal NAI, realm unknown."), + identity, + identity_length)); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("NAI should be"), + get_nai_realm()->get_data(get_nai_realm()->get_data_length()), + get_nai_realm()->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); + } + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::packet_trace( + eap_const_string prefix, + const eap_am_network_id_c * const /*receive_network_id*/, + eap_header_wr_c * const eap_packet, + const u32_t eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(prefix); // in release + + if (eap_packet_length > eap_header_base_c::get_header_length() + && eap_packet->get_type() == m_current_eap_type) + { + eap_tls_peap_header_c * const received_tls_peap + = reinterpret_cast(eap_packet); + + const u8_t * const p_tls_flags = received_tls_peap->get_tls_flags(); + u8_t tls_flags = 0u; + EAP_UNREFERENCED_PARAMETER(tls_flags); // in release + if (p_tls_flags != 0) + { + tls_flags = *p_tls_flags; + } + + u32_t tls_message_length = 0ul; + if (received_tls_peap->get_tls_message_length(&tls_message_length) != eap_status_ok) + { + tls_message_length = 0ul; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s EAP-TLS/PEAP header %s: code=0x%02x=%s, identifier=0x%02x=%d, ") + EAPL("length=0x%04x=%d, ") + EAPL("type=0x%08x=%s, TLS-flags=0x%02x %s%s%s, TLS-length=0x%08x=%d.\n"), + prefix, + (m_is_client == true) ? "client": "server", + received_tls_peap->get_code(), + received_tls_peap->get_code_string(), + received_tls_peap->get_identifier(), + received_tls_peap->get_identifier(), + received_tls_peap->get_length(), + received_tls_peap->get_length(), + convert_eap_type_to_u32_t(received_tls_peap->get_type()), + received_tls_peap->get_eap_type_string(), + tls_flags, + (tls_flags & eap_tls_peap_header_c::m_flag_mask_tls_length_included) ? "L": " ", + (tls_flags & eap_tls_peap_header_c::m_flag_mask_more_fragments) ? "M": " ", + (tls_flags & eap_tls_peap_header_c::m_flag_mask_start) ? "S": " ", + tls_message_length, + tls_message_length)); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s EAP header %s: code=0x%02x=%s, identifier=0x%02x, length=0x%04x=%d, ") + EAPL("type=0x%08x=%s\n"), + prefix, + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + eap_packet->get_length(), + convert_eap_type_to_u32_t(eap_packet->get_type()), + eap_packet->get_type_string())); + + EAP_TRACE_DEBUG( + m_am_tools, + eap_am_tools_c::eap_trace_mask_eap_messages, + (EAPL("\n\t%s\n\tcode = 0x%02x = %s\n\tidentifier = 0x%02x\n\t") + EAPL("length = 0x%04x = %lu\n\ttype = 0x%08x = %s\n"), + (m_is_client == true) ? "client": "server", + eap_packet->get_code(), + eap_packet->get_code_string(), + eap_packet->get_identifier(), + eap_packet->get_length(), + eap_packet->get_length(), + convert_eap_type_to_u32_t(eap_packet->get_type()), + eap_packet->get_type_string())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +eap_master_session_key_c * eap_type_tls_peap_c::get_master_session_key() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_master_session_key; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::finish_successful_authentication( + const bool send_tppd_peapv1_empty_acknowledge, + const bool do_quiet_finish, + const bool do_send_empty_acknowledge) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(send_tppd_peapv1_empty_acknowledge); // Not used if USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES defined. + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: function: eap_type_tls_peap_c::finish_successful_authentication()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_TLS_PEAP: %s, EAP-type %s EAP-SUCCESS, m_tls_session_type=%d=%s, PEAP version %s\n"), + ((m_is_client == true) ? "client": "server"), + eap_header_string_c::get_eap_type_string(m_current_eap_type), + get_tls_session_type(), + eap_tls_trace_string_c::get_tls_session_type_string(get_tls_session_type()), + eap_tls_trace_string_c::get_peap_version_string(m_current_peap_version))); + + eap_status_e status(eap_status_process_general_error); + + if (do_quiet_finish == false) + { + if (get_master_session_key()->get_is_valid_data() == false + || get_master_session_key()->get_data_length() == 0u) + { + set_state(eap_type_tls_peap_state_failure); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + eap_status_e status = get_type_partner()->packet_data_crypto_keys( + get_send_network_id(), + get_master_session_key()); + if (status != eap_status_ok) + { + set_state(eap_type_tls_peap_state_failure); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + bool send_eap_success = true; +#if !defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + if (m_is_client == true + || (m_current_eap_type == eap_type_peap + && m_current_peap_version == peap_version_1)) + { + send_eap_success = false; + } +#endif //#if !defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_authentication_finished_successfully, + get_last_eap_identifier(), // Note the EAP-Success uses the same EAP-Identifier as the last EAP-Request. + send_eap_success); + get_type_partner()->state_notification(¬ification); + + if (do_send_empty_acknowledge == true + && m_is_client == true + && m_current_eap_type == eap_type_peap + && m_current_peap_version == peap_version_1 +#if !defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + && m_use_tppd_tls_peap == true + && (m_use_tppd_peapv1_acknowledge_hack == false + || get_tls_session_type() == tls_session_type_full_authentication + || send_tppd_peapv1_empty_acknowledge == true) +#endif //#if !defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + ) + { + // Send empty acknowledge message. + status = send_empty_eap_ack(); + if (status != eap_status_ok) + { + set_state(eap_type_tls_peap_state_failure); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + set_state(eap_type_tls_peap_state_success); + + // Indicate EAP-TLS/PEAP AM authentication finished successfully. + m_am_type_tls_peap->authentication_finished(true, get_tls_session_type()); + + m_authentication_finished_successfully = true; + status = eap_status_success; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::send_final_notification() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: function: eap_type_tls_peap_c::send_final_notification(): m_is_valid=%d, m_authentication_finished_successfully=%d\n"), + (m_is_client == true ? "client": "server"), + m_is_valid, + m_authentication_finished_successfully)); + + if (m_is_valid == true + && m_authentication_finished_successfully == false) + { + eap_tls_trace_string_c tls_trace; + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("EAP_type_TLS_PEAP: %s, EAP-type %s FAILED, m_tls_session_type=%d=%s, PEAP version %s, state=%s\n"), + ((m_is_client == true) ? "client": "server"), + eap_header_string_c::get_eap_type_string(m_current_eap_type), + get_tls_session_type(), + eap_tls_trace_string_c::get_tls_session_type_string(get_tls_session_type()), + tls_trace.get_peap_version_string(m_current_peap_version), + get_state_string())); + + if (m_is_client == false + && get_state() == eap_type_tls_peap_state_waiting_for_identity_response) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: function: send_final_notification(): Does not send notiication.\n"), + (m_is_client == true ? "client": "server"))); + } + else + { + set_state(eap_type_tls_peap_state_failure); + + // Notifies the lower level of unsuccessfull authentication. + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + get_last_eap_identifier(), + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + get_type_partner()->state_notification(¬ification); + + // Indicate EAP-TLS/PEAP AM authentication terminated unsuccessfully. + m_am_type_tls_peap->authentication_finished(false, get_tls_session_type()); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_type_tls_peap_c::get_is_client() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_client; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::create_random_eap_identity( + eap_variable_data_c * const local_identity) +{ + // Generates random username. + + if (local_identity == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH = 16; + eap_variable_data_c random_username(m_am_tools); + eap_variable_data_c random_bytes(m_am_tools); + + eap_status_e status = random_bytes.init(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + random_bytes.set_is_valid(); + random_bytes.set_data_length(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH); + + status = m_am_tools->get_crypto()->get_rand_bytes( + random_bytes.get_data(random_bytes.get_data_length()), + random_bytes.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t EAP_GSMSIM_RANDOM_IDENTITY_BUFFER_LENGTH + = 3ul+(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH+1u)*4u/3u; + + status = random_username.init(EAP_GSMSIM_RANDOM_IDENTITY_BUFFER_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + random_username.set_is_valid(); + random_username.set_data_length(EAP_GSMSIM_RANDOM_IDENTITY_BUFFER_LENGTH); + + u32_t random_identity_length = random_username.get_data_length(); + + status = m_am_tools->convert_bytes_to_ascii_armor( + random_bytes.get_data_offset(0u, random_bytes.get_data_length()), + random_bytes.get_data_length(), + random_username.get_data_offset(0u, random_username.get_data_length()), + &random_identity_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + random_username.set_data_length(random_identity_length); + + status = local_identity->set_copy_of_buffer(&random_username); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::create_eap_fast_mac_identity( + const eap_am_network_id_c * const send_network_id, + eap_variable_data_c * const mac_identity) +{ + // EAP-FAST sends special username. + const u8_t EAP_FAST_PREFIX[] = "PEAP-"; + + eap_status_e status = mac_identity->set_copy_of_buffer(EAP_FAST_PREFIX, sizeof(EAP_FAST_PREFIX)-1ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c mac_string(m_am_tools); + if (mac_string.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = mac_string.set_buffer_length(2ul*send_network_id->get_source_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = mac_string.set_data_length(2ul*send_network_id->get_source_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + u32_t target_length(2ul*send_network_id->get_source_length()); + + status = m_am_tools->convert_bytes_to_hex_ascii( + send_network_id->get_source(), + send_network_id->get_source_length(), + mac_string.get_data(2ul*send_network_id->get_source_length()), + &target_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t TWO_CHARS(2ul); + + for (u32_t ind = 0ul; ind < mac_string.get_data_length(); ind += TWO_CHARS) + { + const u8_t dash('-'); + + status = mac_identity->add_data(mac_string.get_data_offset(ind, TWO_CHARS), TWO_CHARS); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if ((ind+TWO_CHARS) < mac_string.get_data_length()) + { + status = mac_identity->add_data(&dash, sizeof(dash)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + status = m_am_tools->convert_ascii_to_uppercase( + mac_identity->get_data(), + mac_identity->get_data_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::handle_eap_identity_query( + const eap_variable_data_c * const user_certificate_identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const bool use_manual_username, + const eap_variable_data_c * const manual_username, + const bool use_manual_realm, + const eap_variable_data_c * const manual_realm + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + eap_variable_data_c local_identity(m_am_tools); + if (local_identity.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (use_manual_username == true + && manual_username != 0 + && manual_username->get_is_valid() == true + && use_manual_realm == true + && manual_realm != 0 + && manual_realm->get_is_valid() == true) + { +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (m_tls_use_identity_privacy == true) + { + +#if defined(USE_FAST_EAP_TYPE) + if (m_current_eap_type == eap_type_fast) + { + // EAP-FAST sends special username. + status = create_eap_fast_mac_identity( + &send_network_id, + &local_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: this = 0x%08x, %s: eap_type_tls_peap_c::handle_eap_identity_query(): random username and manual realm.\n"), + this, + (m_is_client == true ? "client": "server"))); + + // TLS identity privacy uses random username. + status = create_random_eap_identity(&local_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: this = 0x%08x, %s: eap_type_tls_peap_c::handle_eap_identity_query(): manual username and manual realm.\n"), + this, + (m_is_client == true ? "client": "server"))); + + // Here manual username could be zero or more bytes in length. + status = local_identity.set_copy_of_buffer(manual_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (manual_realm->get_data_length() > 0ul) + { + // When manual realm is one or more bytes in length + // we add @ and manual realm to the identity. + u8_t at_char = EAP_TLS_PEAP_AT_CHARACTER; + status = local_identity.add_data(&at_char, sizeof(at_char)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = local_identity.add_data(manual_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (use_manual_username == true + && manual_username != 0 + && manual_username->get_is_valid() == true + && use_manual_realm == false) + { +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (m_tls_use_identity_privacy == true) + { +#if defined(USE_FAST_EAP_TYPE) + if (m_current_eap_type == eap_type_fast) + { + // EAP-FAST sends special username. + status = create_eap_fast_mac_identity( + &send_network_id, + &local_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: eap_type_tls_peap_c::handle_eap_identity_query(): random username and realm from certificate.\n"), + (m_is_client == true ? "client": "server"))); + + // TLS identity privacy uses random username. + status = create_random_eap_identity(&local_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: eap_type_tls_peap_c::handle_eap_identity_query(): manual username and realm from certificate.\n"), + (m_is_client == true ? "client": "server"))); + + status = local_identity.set_copy_of_buffer(manual_username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (user_certificate_identity != 0 + && user_certificate_identity->get_is_valid() == true) + { + eap_variable_data_c username(m_am_tools); + eap_variable_data_c realm(m_am_tools); + + status = m_am_tools->parse_nai( + user_certificate_identity, + &username, + &realm); + if (status == eap_status_ok) + { + if (realm.get_is_valid_data() == true) + { + u8_t at_char = EAP_TLS_PEAP_AT_CHARACTER; + status = local_identity.add_data(&at_char, sizeof(at_char)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = local_identity.add_data(&realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + else + { + // No realm. + } + } + else if ((use_manual_username == false + && use_manual_realm == true + && manual_realm != 0 + && manual_realm->get_is_valid() == true) +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + || m_tls_use_identity_privacy == true +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + ) + { +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (m_tls_use_identity_privacy == true) + { +#if defined(USE_FAST_EAP_TYPE) + if (m_current_eap_type == eap_type_fast) + { + // EAP-FAST sends special username. + status = create_eap_fast_mac_identity( + &send_network_id, + &local_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: eap_type_tls_peap_c::handle_eap_identity_query(): random username and manual realm.\n"), + (m_is_client == true ? "client": "server"))); + + // TLS identity privacy uses random username. + status = create_random_eap_identity(&local_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (user_certificate_identity != 0 + && user_certificate_identity->get_is_valid() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: eap_type_tls_peap_c::handle_eap_identity_query(): username from certificate and manual realm.\n"), + (m_is_client == true ? "client": "server"))); + + eap_variable_data_c username(m_am_tools); + eap_variable_data_c realm(m_am_tools); + + status = m_am_tools->parse_nai( + user_certificate_identity, + &username, + &realm); + if (status == eap_status_ok) + { + if (username.get_is_valid_data() == true) + { + status = local_identity.set_copy_of_buffer(&username); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: eap_type_tls_peap_c::handle_eap_identity_query(): random username and manual realm.\n"), + (m_is_client == true ? "client": "server"))); + +#if defined(USE_FAST_EAP_TYPE) + if (m_current_eap_type == eap_type_fast) + { + // EAP-FAST sends special username. + status = create_eap_fast_mac_identity( + &send_network_id, + &local_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + status = create_random_eap_identity(&local_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + if (manual_realm != 0 + && manual_realm->get_data_length() > 0ul) + { + u8_t at_char = EAP_TLS_PEAP_AT_CHARACTER; + status = local_identity.add_data(&at_char, sizeof(at_char)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = local_identity.add_data(manual_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // No realm. + } + } + else if (user_certificate_identity != 0 + && user_certificate_identity->get_is_valid() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: eap_type_tls_peap_c::handle_eap_identity_query(): username from certificate and realm from certificate.\n"), + (m_is_client == true ? "client": "server"))); + + // Uses NAI from certificate. + status = local_identity.set_copy_of_buffer(user_certificate_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: eap_type_tls_peap_c::handle_eap_identity_query(): no identity.\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + status = m_current_identity.set_copy_of_buffer(&local_identity); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_NAI()->set_copy_of_buffer(&local_identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_tls_peap_c::handle_eap_identity_query(): identity"), + local_identity.get_data(), + local_identity.get_data_length())); + + + status = get_type_partner()->complete_eap_identity_query( + &send_network_id, + &local_identity, + eap_identifier); + if (status == eap_status_ok) + { + set_state(eap_type_tls_peap_state_waiting_for_tls_start); + } + else + { + m_current_identity.reset(); + get_NAI()->reset(); + restore_saved_previous_state(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::complete_eap_identity_query( + const eap_variable_data_c * const user_certificate_identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + const eap_status_e completion_status, + const bool use_manual_username, + const eap_variable_data_c * const manual_username, + const bool use_manual_realm, + const eap_variable_data_c * const manual_realm + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_state == eap_type_tls_peap_state_pending_identity_query) + { + if (completion_status != eap_status_ok) + { + set_state(eap_type_tls_peap_state_failure); + + // The completion_status error value is more important + // than return value of set_session_timeout(). + get_type_partner()->set_session_timeout(0ul); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, completion_status); + } + + eap_status_e status = handle_eap_identity_query( + user_certificate_identity, + receive_network_id, + eap_identifier, + use_manual_username, + manual_username, + use_manual_realm, + manual_realm); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::complete_eap_identity_query(): ") + EAPL("Illegal EAP-Identity query completion in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } +} + +//-------------------------------------------------- + +// +eap_status_e eap_type_tls_peap_c::check_received_eap_identifier( + const eap_header_wr_c * const eap_header) +{ + if (m_is_client == false + && get_type_partner()->get_is_tunneled_eap() == true + && m_check_identifier_of_eap_identity_response == false) + { + // Server cannot exactly verify EAP-Identifier value because of fragmentation. + if (eap_header->get_identifier() < get_last_eap_identifier()) + { + eap_status_e status(eap_status_unexpected_message); + + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::check_received_eap_identifier() failed,") + EAPL("status %d=%s, received EAP-type 0x%08x, received EAP-code %d, ") + EAPL("received EAP-identifier %d, current EAP-identifier %d, state %s\n"), + status, + status_string.get_status_string(status), + convert_eap_type_to_u32_t(eap_header->get_type()), + eap_header->get_code(), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + if (m_is_client == false + && eap_header->get_type() == eap_type_identity + && eap_header->get_code() == eap_code_response + && m_check_identifier_of_eap_identity_response == true + && eap_header->get_identifier() != get_last_eap_identifier()) + { + eap_status_e status(eap_status_unexpected_message); + + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::check_received_eap_identifier() failed,") + EAPL("status %d=%s, received EAP-type 0x%08x, received EAP-code %d, ") + EAPL("received EAP-identifier %d, current EAP-identifier %d, state %s\n"), + status, + status_string.get_status_string(status), + convert_eap_type_to_u32_t(eap_header->get_type()), + eap_header->get_code(), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_is_client == false + && eap_header->get_type() == m_current_eap_type + && eap_header->get_identifier() != get_last_eap_identifier()) + { + eap_status_e status(eap_status_unexpected_message); + + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::check_received_eap_identifier() failed,") + EAPL("status %d=%s, received EAP-identifier %d, ") + EAPL("current EAP-identifier %d, state %s\n"), + status, + status_string.get_status_string(status), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_is_client == true + && eap_header->get_identifier() == get_last_eap_identifier()) + { + // Client have received this packet already. + eap_status_e status(eap_status_drop_packet_quietly); + + eap_status_string_c status_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_tls_peap_c::check_received_eap_identifier() failed,") + EAPL("status %d=%s, drops already received EAP-identifier %d, ") + EAPL("current EAP-identifier %d, state %s\n"), + status, + status_string.get_status_string(status), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const eap_header, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s, %s: function: eap_type_tls_peap_c::packet_process()\n"), + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_tls_peap_c::packet_process()"); + + packet_trace( + EAPL("->"), + receive_network_id, + eap_header, + eap_packet_length); + + if (eap_packet_length < eap_header->get_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_packet_length=0x%04x < eap_header->get_length()=0x%04x.\n"), + eap_packet_length, eap_header->get_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + if (eap_header->get_length() < eap_header_base_c::get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::packet_process(): ") + EAPL("eap_header->get_length() < eap_header_base_c::get_header_length().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + + // NOTE: by disabling these calls throughput increases about 18%. + // Disabling also decreases random seeds. + m_am_tools->get_crypto()->add_rand_seed( + eap_header->get_header_buffer(eap_packet_length), + eap_packet_length); + m_am_tools->get_crypto()->add_rand_seed_hw_ticks(); + + eap_status_e status = eap_status_process_general_error; + + eap_tls_peap_header_c tls_peap_header( + m_am_tools, + eap_header->get_header_buffer(eap_packet_length), + eap_packet_length); + + if ((m_is_client == true + && eap_header->get_code() == eap_code_request) + || (m_is_client == false + && eap_header->get_code() == eap_code_response)) + { + if (eap_header->get_type() == eap_type_identity + || eap_header->get_type() == m_current_eap_type) + { + if (eap_header->get_type() == eap_type_identity + && eap_header->get_code() == eap_code_request) + { + // EAP-Request/Identity is handled in eap_core_c. + status = eap_status_unexpected_message; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (eap_header->get_type() == eap_type_identity + && eap_header->get_code() == eap_code_response + && eap_header->get_length() <= eap_header_base_c::get_header_length()) + { + status = eap_status_header_corrupted; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (eap_header->get_type() == m_current_eap_type + && eap_header->get_length() < tls_peap_header.get_tls_min_header_length()) + { + status = eap_status_header_corrupted; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (check_received_eap_identifier(eap_header) != eap_status_ok) + { + status = eap_status_unexpected_message; + eap_status_string_c status_string; + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::packet_process() failed,") + EAPL("status %d=%s, received EAP-type 0x%08x, received EAP-code %d, ") + EAPL("received EAP-identifier %d, current EAP-identifier %d, state %s\n"), + status, + status_string.get_status_string(status), + convert_eap_type_to_u32_t(eap_header->get_type()), + eap_header->get_code(), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + if (m_is_client == true) + { + // Client saves the received EAP-Identifier. + set_last_eap_identifier(eap_header->get_identifier()); + } + + if (eap_header->get_type() == eap_type_identity) + { + status = eap_identity_response_packet_process( + receive_network_id, + eap_header, + eap_packet_length); + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_drop_packet_quietly) + { + eap_status_string_c status_string; + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::") + EAPL("eap_identity_response_packet_process() failed, status %d=%s\n"), + status, status_string.get_status_string(status))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false); + + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + eap_state_identity_response_received, + get_last_eap_identifier(), + false); + get_type_partner()->state_notification(¬ification); + } + } + else + { + status = tls_peap_packet_process( + receive_network_id, + &tls_peap_header, + eap_packet_length); + + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false); + } + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_pending_request + && status != eap_status_drop_packet_quietly) + { + eap_status_string_c status_string; + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::tls_peap_packet_process() ") + EAPL("failed, status %d=%s\n"), + status, status_string.get_status_string(status))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (eap_header->get_type() == eap_type_notification) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP type notification: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + convert_eap_type_to_u32_t(eap_header->get_type()))); + + status = eap_status_illegal_eap_type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP type unknown: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, type=0x%08x\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + convert_eap_type_to_u32_t(eap_header->get_type()))); + + status = eap_status_illegal_eap_type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (eap_header->get_code() == eap_code_success + || eap_header->get_code() == eap_code_failure) + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (eap_header->get_code() == eap_code_success) + { +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + if (get_state() + == eap_type_tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet + && m_current_eap_type == eap_type_peap + && m_current_peap_version == peap_version_1 + && m_use_tppd_tls_peap == true + && m_use_tppd_peapv1_acknowledge_hack == true + && (get_tls_session_type() == tls_session_type_original_session_resumption + || get_tls_session_type() == tls_session_type_stateless_session_resumption)) + { + // EAP-PEAPv1 original session resumption finishes with plain text EAP-SUCCESS. + // We must forward this to the tunneled EAP-type. + status = m_tls_record->plain_eap_success_failure_packet_received( + receive_network_id, + eap_header->get_code(), + eap_header->get_identifier()); + + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false); + } + + status = finish_successful_authentication(false, false, true); + if (status != eap_status_success) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + if (m_current_eap_type == eap_type_ttls + && get_state() == eap_type_tls_peap_state_waiting_for_request) + { + // EAP-TTLS finishes with plain text EAP-SUCCESS. + // We must forward this to the tunneled EAP-type. + status = m_tls_record->plain_eap_success_failure_packet_received( + receive_network_id, + eap_header->get_code(), + eap_header->get_identifier()); + + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false); + } + + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_pending_request + && status != eap_status_drop_packet_quietly) + { + eap_status_string_c status_string; + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::tls_peap_packet_process() ") + EAPL("failed, status %d=%s\n"), + status, status_string.get_status_string(status))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_current_eap_type == eap_type_fast) + { + // In some cases EAP-FAST finishes only with plain text EAP-SUCCESS. + // We must forward this to the tunneled EAP-type. + status = m_tls_record->plain_eap_success_failure_packet_received( + receive_network_id, + eap_header->get_code(), + eap_header->get_identifier()); + + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + else if (get_state() == eap_type_tls_peap_state_waiting_for_success) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false); + + if (m_wait_eap_success_packet == false) + { + /** + * @{ check right functionality. + * Here we return eap_status_ok, eap_status_success was + * returned after successfull + * EAP-Request/SIM/Challenge. This may change after EAP, + * 802.1X and 802.11i specifications are ready. } + */ + status = eap_status_ok; + } + else + { + if (m_current_eap_type == eap_type_tls) + { + status = finish_successful_authentication(false, false, true); + if (status != eap_status_success) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // We must forward this to the tunneled EAP-type. + + status = m_tls_record->plain_eap_success_failure_packet_received( + receive_network_id, + eap_header->get_code(), + eap_header->get_identifier()); + + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false); + } + } + } + } + else if (get_state() == eap_type_tls_peap_state_success) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("quietly dropped EAP-Success: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, state %d=%s, is client %d\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + get_state(), + get_state_string(), + (m_is_client == true))); + status = eap_status_drop_packet_quietly; + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP-Success: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, state %d=%s, is client %d\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + get_state(), + get_state_string(), + (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + } + else if (eap_header->get_code() == eap_code_failure) + { + // EAP is quite sloppy protocol. + // Somebody just send a EAP-failure message and authentication is terminated. + + // Save received failure. We do not change our state yet. + // The real correct EAP message could be received later if this failure was + // send by nasty attacker. + set_failure_message_received(); + // We handle the EAP-Request/Failure message after a timeout. + +#if defined(USE_FAST_EAP_TYPE) + if (m_current_eap_type == eap_type_fast) + { + // In some cases EAP-FAST finishes only with plain text EAP-SUCCESS. + // We must forward this to the tunneled EAP-type. + status = m_tls_record->plain_eap_success_failure_packet_received( + receive_network_id, + eap_header->get_code(), + eap_header->get_identifier()); + + if (status == eap_status_ok) + { + EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + status = eap_status_ok; + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP code unknown: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, is client %d\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("dropped EAP code unknown: code=0x%02x, identifier=0x%02x, ") + EAPL("length=0x%04x, is client %d\n"), + eap_header->get_code(), + eap_header->get_identifier(), + eap_header->get_length(), + (m_is_client == true))); + status = eap_status_illegal_eap_code; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::send_empty_eap_ack() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s, %s: function: eap_type_tls_peap_c::send_empty_eap_ack()\n"), + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_tls_peap_c::send_empty_eap_ack()"); + + eap_buf_chain_wr_c eap_fragment_acknowledge_packet( + eap_write_buffer, + m_am_tools, + TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_fragment_acknowledge_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT_ALWAYS(TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH + >= (m_tls_peap_header_offset+m_trailer_length)); + u32_t packet_buffer_free = TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_tls_peap_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_tls_peap_header_offset+m_MTU; + } + + eap_tls_peap_header_c fragment_acknowledge( + m_am_tools, + eap_fragment_acknowledge_packet.get_data_offset( + m_tls_peap_header_offset, + (packet_buffer_free-m_tls_peap_header_offset)), + (packet_buffer_free-m_tls_peap_header_offset)); + + if (fragment_acknowledge.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + fragment_acknowledge.reset_header( + m_am_tools, + m_current_eap_type, + static_cast(packet_buffer_free-m_tls_peap_header_offset), + m_current_peap_version, + m_use_eap_expanded_type); + + fragment_acknowledge.set_eap_length( + static_cast(packet_buffer_free-m_tls_peap_header_offset), + m_use_eap_expanded_type); + + if (m_is_client == true) + { + fragment_acknowledge.set_eap_code(eap_code_response); + fragment_acknowledge.set_eap_identifier(static_cast(get_last_eap_identifier())); + } + else // if (m_is_client == false) + { + fragment_acknowledge.set_eap_code(eap_code_request); + fragment_acknowledge.set_eap_identifier(static_cast(get_last_eap_identifier()+1u)); + } + fragment_acknowledge.set_eap_type( + m_current_eap_type, + m_use_eap_expanded_type); + + u32_t tls_peap_data_offset = 0u; + + update_buffer_indexes( + TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH, + m_tls_peap_header_offset+fragment_acknowledge.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + // No payloads. + + fragment_acknowledge.set_data_length( + tls_peap_data_offset, + m_use_eap_expanded_type); + eap_fragment_acknowledge_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_tls_peap_header_offset + +fragment_acknowledge.get_header_length() + +fragment_acknowledge.get_data_length() + == packet_buffer_offset); + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_is_client == true) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: EAP-Response/TLS_PEAP/Acknowledge packet"), + fragment_acknowledge.get_header_buffer(fragment_acknowledge.get_eap_length()), + fragment_acknowledge.get_eap_length())); + } + else // if (m_is_client == false) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: EAP-Request/TLS_PEAP/Acknowledge packet"), + fragment_acknowledge.get_header_buffer(fragment_acknowledge.get_eap_length()), + fragment_acknowledge.get_eap_length())); + } + + status = packet_send( + get_send_network_id(), + &eap_fragment_acknowledge_packet, + m_tls_peap_header_offset, + fragment_acknowledge.get_eap_length(), + TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + if (m_is_client == false) + { + // Server saves the sent EAP-Identifier. + set_last_eap_identifier(static_cast(get_last_eap_identifier()+1ul)); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::send_tls_peap_start_message( + const u8_t next_eap_identifier, ///< This is EAP-Identifier of next EAP packet. + const eap_variable_data_c * const authority_identity_payload + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s, %s: function: eap_type_tls_peap_c::send_tls_peap_start_message()\n"), + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_tls_peap_c::send_tls_peap_start_message()"); + + eap_buf_chain_wr_c eap_tls_start_packet( + eap_write_buffer, + m_am_tools, + TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_tls_start_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT_ALWAYS(TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH + >= (m_tls_peap_header_offset+m_trailer_length)); + u32_t packet_buffer_free = TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_tls_peap_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_tls_peap_header_offset+m_MTU; + } + + eap_tls_peap_header_c eap_tls_start_header( + m_am_tools, + eap_tls_start_packet.get_data_offset( + m_tls_peap_header_offset, + (packet_buffer_free-m_tls_peap_header_offset)), + (packet_buffer_free-m_tls_peap_header_offset)); + + if (eap_tls_start_header.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_tls_start_header.reset_header( + m_am_tools, + m_current_eap_type, + static_cast(packet_buffer_free-m_tls_peap_header_offset), + m_current_peap_version, + m_use_eap_expanded_type); + + eap_tls_start_header.set_flag_start(true); + eap_tls_start_header.set_flag_tls_length_included(false); + + eap_tls_start_header.set_eap_length( + static_cast( + packet_buffer_free-m_tls_peap_header_offset), + m_use_eap_expanded_type); + + eap_tls_start_header.set_eap_code(eap_code_request); + eap_tls_start_header.set_eap_identifier(next_eap_identifier); + eap_tls_start_header.set_eap_type( + m_current_eap_type, + m_use_eap_expanded_type); + + update_buffer_indexes( + TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH, + m_tls_peap_header_offset+eap_tls_start_header.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_tls_start_header.set_data_length( + 0ul, + m_use_eap_expanded_type); + eap_tls_start_packet.set_data_length(packet_buffer_offset); + + EAP_ASSERT_ALWAYS( + m_tls_peap_header_offset+eap_tls_start_header.get_header_length() + +eap_tls_start_header.get_data_length() + == packet_buffer_offset); + + eap_status_e status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + // Payload is optional authority identity (A-ID) that is used in EAP-FAST. + + if (authority_identity_payload->get_data_length() > 0ul) + { + status = eap_tls_start_packet.add_data_to_offset( + packet_buffer_offset, + authority_identity_payload->get_data(), + authority_identity_payload->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + update_buffer_indexes( + TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH, + authority_identity_payload->get_data_length(), + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_tls_start_header.set_data_length( + authority_identity_payload->get_data_length(), + m_use_eap_expanded_type); + + status = eap_tls_start_packet.set_data_length(packet_buffer_offset); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_tls_peap_start_message(): m_tls_peap_header_offset %d ") + EAPL("+ eap_tls_start_header.get_header_length()") + EAPL("%d + eap_tls_start_header.get_data_length() ") + EAPL("%d = %d packet_buffer_offset %d.\n"), + m_tls_peap_header_offset, + eap_tls_start_header.get_header_length(), + eap_tls_start_header.get_data_length(), + (m_tls_peap_header_offset + + eap_tls_start_header.get_header_length() + + eap_tls_start_header.get_data_length()), + packet_buffer_offset)); + + EAP_ASSERT_ALWAYS( + m_tls_peap_header_offset + +eap_tls_start_header.get_header_length() + +eap_tls_start_header.get_data_length() + == packet_buffer_offset); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: EAP-Request/TLS_PEAP/Start packet"), + eap_tls_start_header.get_header_buffer(eap_tls_start_header.get_eap_length()), + eap_tls_start_header.get_eap_length())); + + status = packet_send( + get_send_network_id(), + &eap_tls_start_packet, + m_tls_peap_header_offset, + eap_tls_start_header.get_eap_length(), + TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + if (m_is_client == false) + { + // Server saves the sent EAP-Identifier. + set_last_eap_identifier(next_eap_identifier); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::start_tls_peap_authentication( + const eap_variable_data_c * const received_authority_identity_payload + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s, %s: function: eap_type_tls_peap_c::start_tls_peap_authentication()\n"), + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_tls_peap_c::start_tls_peap_authentication()"); + + eap_status_e status = m_tls_record->start_tls_peap_authentication(received_authority_identity_payload); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::eap_tls_peap_fragment_send() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s, %s: function: eap_type_tls_peap_c::eap_tls_peap_fragment_send()\n"), + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_tls_peap_c::eap_tls_peap_fragment_send()"); + + eap_status_e status = eap_status_not_supported; + + if (m_tls_message_send_offset == 0ul + && m_tls_message_buffer.get_data_length() + < tls_record_header_c::get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_tls_peap_fragment_send(): ") + EAPL("packet buffer too short, %d bytes.\n"), + m_tls_message_buffer.get_data_length())); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (m_tls_message_buffer.get_data_length() + < m_tls_message_send_offset) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_tls_peap_fragment_send(): ") + EAPL("packet buffer %d shorter than ") + EAPL("m_tls_message_send_offset %d.\n"), + m_tls_message_buffer.get_data_length(), + m_tls_message_send_offset)); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + eap_buf_chain_wr_c eap_tls_peap_fragment( + eap_write_buffer, + m_am_tools, + EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); + + if (eap_tls_peap_fragment.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT_ALWAYS(EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH + >= (m_tls_peap_header_offset+m_trailer_length)); + u32_t packet_buffer_free + = EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; + u32_t packet_buffer_offset = 0u; + + if (m_tls_peap_header_offset+m_MTU < packet_buffer_free) + { + packet_buffer_free = m_tls_peap_header_offset+m_MTU; + } + + u32_t packet_eap_data_free + = packet_buffer_free + - m_tls_peap_header_offset + - eap_tls_peap_header_c::get_tls_max_header_length(); + + eap_tls_peap_header_c eap_tls_packet( + m_am_tools, + eap_tls_peap_fragment.get_data_offset( + m_tls_peap_header_offset, + packet_eap_data_free), + packet_eap_data_free); + + if (eap_tls_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_tls_packet.reset_header( + m_am_tools, + m_current_eap_type, + static_cast(packet_eap_data_free), + m_current_peap_version, + m_use_eap_expanded_type); + if (m_tls_message_send_offset == 0) + { + // This is the first fragment. + eap_tls_packet.set_flag_tls_length_included(true); + eap_tls_packet.set_tls_message_length( + m_tls_message_buffer.get_data_length()); + } + + eap_tls_packet.set_eap_length( + static_cast(packet_eap_data_free), + m_use_eap_expanded_type); + + if (m_is_client == true) + { + eap_tls_packet.set_eap_code(eap_code_response); + eap_tls_packet.set_eap_identifier(get_last_eap_identifier()); + } + else + { + eap_tls_packet.set_eap_code(eap_code_request); + eap_tls_packet.set_eap_identifier( + static_cast(get_last_eap_identifier()+1ul)); + } + eap_tls_packet.set_eap_type( + m_current_eap_type, + m_use_eap_expanded_type); + + + u32_t fragment_length + = m_MTU + - eap_tls_peap_header_c::get_tls_max_header_length(); + u32_t pending_message_length + = m_tls_message_buffer.get_data_length() + - m_tls_message_send_offset; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-TLS fragment: packet_eap_data_free %d, ") + EAPL("fragment_length %d, pending_message_length %d, ") + EAPL("EAP-header length %d, buffer length %d\n"), + packet_eap_data_free, + fragment_length, + pending_message_length, + eap_tls_packet.get_header_length(), + eap_tls_peap_fragment.get_buffer_length())); + + if (packet_eap_data_free >= pending_message_length) + { + // Message data is less than the buffer length, + // so the fragment is only length of the message data. + fragment_length = pending_message_length; + + if (m_tls_message_send_offset == 0 + && m_use_tppd_tls_peap == true + && m_includes_tls_handshake_message == true +#if defined(USE_FAST_EAP_TYPE) + && m_current_eap_type != eap_type_fast +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + // TLS-message length is included, + // even no fragmentation is used. + eap_tls_packet.set_flag_tls_length_included(true); + } + else + { + // TLS-message length is not included, + // because no fragmentation is used. + eap_tls_packet.set_flag_tls_length_included(false); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-TLS fragment: packet_eap_data_free %d, ") + EAPL("fragment_length %d, pending_message_length %d, ") + EAPL("EAP-header length %d\n"), + packet_eap_data_free, + fragment_length, + pending_message_length, + eap_tls_packet.get_header_length())); + } + + if (fragment_length < pending_message_length) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-TLS fragment: more fragments follow. ") + EAPL("fragment_length %d, pending_message_length %d, ") + EAPL("EAP-header length %d\n"), + fragment_length, + pending_message_length, + eap_tls_packet.get_header_length())); + + eap_tls_packet.set_flag_more_fragments(true); + } + + + update_buffer_indexes( + TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH, + m_tls_peap_header_offset+eap_tls_packet.get_header_length(), + &packet_buffer_offset, + &packet_buffer_free); + + status = eap_tls_peap_fragment.set_data_length(packet_buffer_offset); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + // Payload is TLS-message fragment. + + status = eap_tls_peap_fragment.add_data_to_offset( + packet_buffer_offset, + m_tls_message_buffer.get_data_offset( + m_tls_message_send_offset, fragment_length), + fragment_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + update_buffer_indexes( + TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH, + fragment_length, + &packet_buffer_offset, + &packet_buffer_free); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_tls_packet.set_data_length( + fragment_length, + m_use_eap_expanded_type); + + status = eap_tls_peap_fragment.set_data_length(packet_buffer_offset); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_tls_peap_fragment_send(): m_tls_peap_header_offset %d ") + EAPL("+ eap_tls_packet.get_header_length()") + EAPL("%d + eap_tls_packet.get_data_length() ") + EAPL("%d = %d == packet_buffer_offset %d.\n"), + m_tls_peap_header_offset, + eap_tls_packet.get_header_length(), + eap_tls_packet.get_data_length(), + (m_tls_peap_header_offset + + eap_tls_packet.get_header_length() + + eap_tls_packet.get_data_length()), + packet_buffer_offset)); + + EAP_ASSERT_ALWAYS( + m_tls_peap_header_offset + +eap_tls_packet.get_header_length() + +eap_tls_packet.get_data_length() + == packet_buffer_offset); + + status = eap_status_process_general_error; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + status = packet_send( + get_send_network_id(), + &eap_tls_peap_fragment, + m_tls_peap_header_offset, + eap_tls_packet.get_eap_length(), + TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH + ); + + if (status == eap_status_ok) + { + m_tls_message_send_offset += fragment_length; + + if (m_is_client == false) + { + // Server saves the sent EAP-Identifier. + set_last_eap_identifier( + static_cast(get_last_eap_identifier()+1ul)); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::tls_message_process( + const eap_am_network_id_c * const /*receive_network_id*/, ///< This is the network identity of the received EAP packet. + eap_tls_peap_header_c * const received_tls_peap, ///< This is pointer to EAP header including EAP-TLS/PEAP fields. + const u32_t /*tls_peap_packet_length*/ ///< This is length of received TLS/PEAP EAP packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s, %s: function: eap_type_tls_peap_c::tls_message_process()\n"), + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_tls_peap_c::tls_message_process()"); + + if (m_tls_message_buffer.get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_message_process: packet buffer invalid.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (m_tls_message_buffer.get_data_length() < tls_record_header_c::get_header_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_message_process: packet buffer too short, %d bytes.\n"), + m_tls_message_buffer.get_data_length())); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + save_current_state(); + set_state(eap_type_tls_peap_state_process_tls_message); + + eap_status_e status = m_tls_record->packet_process( + &m_tls_message_buffer, + received_tls_peap->get_eap_identifier()); + + if (status == eap_status_ok) + { + // Do nothing. + } + else if (status == eap_status_pending_request) + { + // Asyncronous operation is pending. + // Do nothing. + } + else if (status == eap_status_success) + { + // Authentication OK. + // Do nothing. + } + else if (status == eap_status_drop_packet_quietly) + { + // Dropped packet. + // Do nothing. + } + else + { + // All other return values are ERROR. Authentication is failed. + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: tls_message_process: Authentication failed.\n"), + (m_is_client == true) ? "client": "server")); + + restore_saved_previous_state(); + set_state(eap_type_tls_peap_state_failure); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::eap_identity_response_packet_process( + const eap_am_network_id_c * const /*receive_network_id*/, ///< This is the network identity of the received EAP packet. + eap_header_wr_c * const eap_header, ///< This is pointer to EAP header and data. + const u32_t eap_packet_length ///< This is length of received EAP packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s: function: eap_type_tls_peap_c::eap_identity_response_packet_process()\n"), + (m_is_client == true ? "client": "server"))); + + if (eap_header->check_header() != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (eap_header->get_length() > eap_packet_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + if (m_check_identifier_of_eap_identity_response == true) + { + if (m_state == eap_type_tls_peap_state_waiting_for_identity_response + && eap_header->get_identifier() != get_last_eap_identifier()) + { + // Wrong EAP-Identifier in this state. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + eap_header->get_identifier(), + get_last_eap_identifier(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + else if (m_tls_peap_test_version == true + && m_state == eap_type_tls_peap_state_success) // This one is for testing purposes. + { + // NOTE here we can not check the EAP-identifier. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_tls_peap_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x is not checked in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + eap_header->get_identifier(), + get_state(), + get_state_string())); + } + } + + + if ((m_state == eap_type_tls_peap_state_waiting_for_identity_response + || m_state == eap_type_tls_peap_state_waiting_for_first_response) + || (m_tls_peap_test_version == true + // In test version new authentication could start from this state. + && m_state == eap_type_tls_peap_state_success)) + { + // EAP-Response/Identity is accepted only as a very first message. + + eap_status_e status = eap_status_process_general_error; + + save_current_state(); + + // In test version new authentication could start from this state. + if (m_tls_peap_test_version == true + && m_state == eap_type_tls_peap_state_success) // This one is for testing purposes. + { + // NOTE here we can not check the EAP-identifier. + set_state(eap_type_tls_peap_state_waiting_for_identity_response); + } + + u8_t next_eap_identifier = static_cast(eap_header->get_identifier()+1u); + + status = parse_identity( + eap_header->get_type_data( + eap_header->get_type_data_length()), + eap_header->get_type_data_length()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c authority_identity_payload(m_am_tools); + if (authority_identity_payload.get_is_valid() == false) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_current_eap_type == eap_type_fast) + { + // Read the authority identity (A-ID). + status = m_tls_record->read_authority_identity(&authority_identity_payload); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + status = send_tls_peap_start_message(next_eap_identifier, &authority_identity_payload); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_last_eap_identifier(next_eap_identifier); + set_state(eap_type_tls_peap_state_waiting_for_first_response); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eap_type_tls_peap_c::handle_identity_response_message(): ") + EAPL("EAP-Identifier 0x%02x in eap_type_tls_peap_state_variable_e %d=%s. ") + EAPL("EAP-Response/Identity is accepted only in ") + EAPL("eap_type_tls_peap_state_waiting_for_identity_response.\n"), + eap_header->get_identifier(), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::select_peap_version( + const u32_t proposed_peap_version) +{ + u32_t version_count = m_accepted_PEAP_versions.get_data_length() / sizeof(u32_t); + + eap_tls_trace_string_c tls_trace; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x, eap_type_tls_peap_c::select_peap_version(): ") + EAPL("%s: Current PEAP version %d=%s, proposed PEAP version %d=%s.\n"), + this, + (m_is_client == true ? "client": "server"), + m_current_peap_version, + tls_trace.get_peap_version_string(m_current_peap_version), + proposed_peap_version, + tls_trace.get_peap_version_string(static_cast(proposed_peap_version)))); + + // Note some PEAP version was set before PEAP actually starts. + // Here we disable the default selection. + m_current_peap_version = peap_version_none; + + u32_t *p_accepted_peap_versions + = reinterpret_cast(m_accepted_PEAP_versions.get_data( + m_accepted_PEAP_versions.get_data_length())); + if (p_accepted_peap_versions == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + u32_t highest_supported_version = peap_version_none; + + for (u32_t ind = 0; ind < version_count; ind++) + { + if (highest_supported_version == peap_version_none + || highest_supported_version < p_accepted_peap_versions[ind]) + { + highest_supported_version = p_accepted_peap_versions[ind]; + } + + if (proposed_peap_version == p_accepted_peap_versions[ind]) + { + m_current_peap_version = static_cast(proposed_peap_version); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_tls_peap_c::select_peap_version(): ") + EAPL("%s: Accepted PEAP version %d=%s.\n"), + (m_is_client == true ? "client": "server"), + m_current_peap_version, + tls_trace.get_peap_version_string(m_current_peap_version))); + break; + } + } // for() + + // Because no matching PEAP version was not found, + // we must use the highest version version we support. + if (m_current_peap_version != peap_version_none) + { + // OK, proposed version accepted. + } + else if (highest_supported_version != peap_version_none) + { + m_current_peap_version = static_cast(highest_supported_version); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_tls_peap_c::select_peap_version(): ") + EAPL("%s: Highest supported PEAP version %d=%s.\n"), + (m_is_client == true ? "client": "server"), + m_current_peap_version, + tls_trace.get_peap_version_string(m_current_peap_version))); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + m_tls_record->set_peap_version( + m_current_peap_version, + m_use_tppd_tls_peap, + m_use_tppd_peapv1_acknowledge_hack); + + if (m_is_client == false + && static_cast(proposed_peap_version) != m_current_peap_version) + { + // Server does not accept PEAP version client proposes. + // Server terminates the session immediately. + get_type_partner()->set_session_timeout(0ul); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::tls_peap_packet_process( + const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet. + eap_tls_peap_header_c * const received_tls_peap, ///< This is pointer to EAP header including EAP-TLS/PEAP fields. + const u32_t tls_peap_packet_length ///< This is length of received TLS/PEAP EAP packet. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: this = 0x%08x, %s, %s, function: eap_type_tls_peap_c::tls_peap_packet_process()\n"), + this, + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_tls_peap_c::tls_peap_packet_process()"); + + if (m_tls_peap_test_version == true + && get_state() == eap_type_tls_peap_state_failure) + { + // This is for testing. + if (m_is_client == false + && received_tls_peap->get_eap_code() == eap_code_response + && received_tls_peap->get_eap_type() == eap_type_identity) + { + set_state(eap_type_tls_peap_state_waiting_for_identity_response); + } + else if (m_is_client == true + && received_tls_peap->get_flag_start() == true) + { + set_state(eap_type_tls_peap_state_waiting_for_tls_start); + } + } + + if (received_tls_peap->check_header( + m_am_tools, + m_current_eap_type, + m_is_client, + peap_version_0_xp, + true) != eap_status_ok + && received_tls_peap->check_header( + m_am_tools, + m_current_eap_type, + m_is_client, + peap_version_1, + true) != eap_status_ok + && received_tls_peap->check_header( + m_am_tools, + m_current_eap_type, + m_is_client, + peap_version_2, + true) != eap_status_ok) + { + // ERROR: EAP-TLS/PEAP header is corrupted. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::tls_peap_packet_process(): ") + EAPL("EAP-TLS/PEAP header is corrupted in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (received_tls_peap->get_eap_length() > tls_peap_packet_length) + { + // ERROR: EAP-Lenght field value is larger than actual received packet. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::tls_peap_packet_process(): ") + EAPL("EAP-Lenght field %d value is larger than actual received ") + EAPL("packet %d in eap_type_tls_peap_state_variable_e %d=%s.\n"), + received_tls_peap->get_eap_length(), + tls_peap_packet_length, + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (m_is_client == false + && received_tls_peap->get_flag_start() == true) + { + // ERROR: Server cannot receive EAP-TLS/PEAP Start message. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::tls_peap_packet_process(): ") + EAPL("Server cannot receive EAP-TLS/PEAP Start message. ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + else if (m_is_client == true + && (get_state() != eap_type_tls_peap_state_waiting_for_request + && get_state() != eap_type_tls_peap_state_waiting_for_identity_request + // EAP-TLS could start without EAP-Request/Identity message. + && get_state() != eap_type_tls_peap_state_waiting_for_tls_start + && get_state() + != eap_type_tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet + )) + { + // ERROR: Client cannot receive EAP-TLS/PEAP message in other states. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_tls_peap_c::tls_peap_packet_process(): ") + EAPL("Client cannot receive EAP-TLS/PEAP message in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else if (m_is_client == false + && get_state() != eap_type_tls_peap_state_waiting_for_response + && get_state() != eap_type_tls_peap_state_waiting_for_first_response + && get_state() != eap_type_tls_peap_state_waiting_for_empty_response + && get_state() != eap_type_tls_peap_state_waiting_for_empty_tppd_peap_v1_acknowledge +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + && get_state() != eap_type_tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + ) + { + // WARNING: Server cannot receive EAP-TLS/PEAP message in other states. + // This packet is dropped quietly. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_tls_peap_c::tls_peap_packet_process(): ") + EAPL("Server cannot receive EAP-TLS/PEAP message in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else if (received_tls_peap->get_flag_start() == true + && get_state() != eap_type_tls_peap_state_waiting_for_tls_start + && get_state() != eap_type_tls_peap_state_waiting_for_identity_request) + // EAP-TLS could start without EAP-Request/Identity message. + { + // ERROR: EAP-TLS/PEAP Start message is accepted only in + // eap_type_tls_peap_state_waiting_for_tls_start. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::tls_peap_packet_process(): ") + EAPL("EAP-TLS/PEAP Start message is NOT accepted in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + // EAP-TLS and PEAP fragmentation support: + // + // Flags include the Length included (L), More fragments (M), and EAP-TLS Start (S) bits. + // + // The L flag is set to indicate the presence of the four octet TLS Message + // Length field, and MUST be set for the first fragment of a fragmented + // TLS message or set of messages. + // + // The M flag is set on all but the last fragment. + // + // The S flag is set only within the EAP-TLS start message + // sent from the EAP server to the peer. This differentiates + // the EAP-TLS Start message from a fragment acknowledgement. + // + // The TLS Message Length field is four octets, and provides + // the total length of the TLS message or set of messages + // that is being fragmented, this simplifies buffer allocation. + + eap_status_e status = eap_status_process_general_error; + + save_current_reassembly_state(); + + if (get_reassembly_state() == eap_type_tls_peap_reassembly_state_wait_first_message) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: this = 0x%08x, %s, %s, function: eap_type_tls_peap_c::tls_peap_packet_process(): waits first fragment.\n"), + this, + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + if (received_tls_peap->get_flag_more_fragments() == true + && received_tls_peap->get_flag_tls_length_included() == false) + { + // The first fragmented message must include TLS-length field. + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + bool first_fragment = false; + u32_t tls_message_length = 0ul; + + if (received_tls_peap->get_flag_tls_length_included() == true) + { + // This is the first fragment and TLS message length is included. + // We must allocate buffer for the fragments. + + status = received_tls_peap->get_tls_message_length(&tls_message_length); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + first_fragment = true; + } + else if (received_tls_peap->get_flag_more_fragments() == false + && received_tls_peap->get_flag_start() == false + && received_tls_peap->get_data_length() > 0ul) + { + // This is the individual message and TLS message length is not included. + // We must allocate buffer for the message. + + tls_message_length = received_tls_peap->get_data_length(); + + first_fragment = true; + } + + + if (first_fragment == true) + { + m_tls_message_buffer.reset(); + + if (tls_message_length > 0ul) + { + if (tls_message_length > EAP_TLS_PEAP_MAX_MESSAGE_LENGTH) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + // Next allocate buffer for reassembled TLS-message. + status = m_tls_message_buffer.set_buffer_length(tls_message_length); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Copy first fragment to the reassembly buffer. + status = m_tls_message_buffer.add_data( + received_tls_peap->get_data(m_am_tools, received_tls_peap->get_data_length()), + received_tls_peap->get_data_length()); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_first_fragment_eap_identifier = received_tls_peap->get_eap_identifier(); + } + } + + + if (received_tls_peap->get_flag_more_fragments() == true) + { + // This is NOT the last fragment. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: this = 0x%08x, %s, %s, function: eap_type_tls_peap_c::tls_peap_packet_process(): waits first fragment, not last fragment.\n"), + this, + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + // Send fragment acknowledge message. + status = send_empty_eap_ack(); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Change reassembly state. + set_reassembly_state(eap_type_tls_peap_reassembly_state_wait_last_fragment); + } + else + { + // This is the last fragment or non fragmented message. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: this = 0x%08x, %s, %s, function: eap_type_tls_peap_c::tls_peap_packet_process(): waits first fragment, the last fragment, start flag %d, data length %d.\n"), + this, + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"), + received_tls_peap->get_flag_start(), + received_tls_peap->get_data_length())); + + // Change reassembly state. + set_reassembly_state(eap_type_tls_peap_reassembly_state_message_reassembled); + + if (received_tls_peap->get_flag_start() == true) + { + // This is EAP-TLS/PEAP Start message. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: this = 0x%08x, %s, %s, function: eap_type_tls_peap_c::tls_peap_packet_process(): waits first fragment, EAP-TLS/PEAP Start message.\n"), + this, + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + save_current_state(); + set_state(eap_type_tls_peap_state_process_tls_start); + + if (m_current_eap_type == eap_type_peap) + { + status = select_peap_version(received_tls_peap->get_flag_version()); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN( + m_am_tools, + eap_status_no_matching_protocol_version); + } + } + + if (m_NAI.get_is_valid_data() == false) + { + // Do not care of the error. Some times there are no NAI at all. + (void) get_type_partner()->get_saved_eap_identity(&m_NAI); + } + + eap_variable_data_c received_authority_identity_payload(m_am_tools); + if (received_authority_identity_payload.get_is_valid() == false) + { + restore_saved_previous_state(); + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_current_eap_type == eap_type_fast) + { + // Read the received authority identity (A-ID). + status = received_authority_identity_payload.set_buffer( + received_tls_peap->get_data(m_am_tools, received_tls_peap->get_data_length()), + received_tls_peap->get_data_length(), + false, + false); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + status = start_tls_peap_authentication(&received_authority_identity_payload); + if (status == eap_status_pending_request) + { + // Do nothing. + } + else if (status != eap_status_ok) + { + restore_saved_previous_state(); + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // OK. + set_state(eap_type_tls_peap_state_waiting_for_request); + } + } + else if (received_tls_peap->get_flag_start() == false + && received_tls_peap->get_data_length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: this = 0x%08x, %s, %s, function: eap_type_tls_peap_c::tls_peap_packet_process(): waits first fragment, empty EAP-TLS/PEAP message.\n"), + this, + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + // Real TLS-tunnel type can be checked here. + status = received_tls_peap->check_header( + m_am_tools, + m_current_eap_type, + m_is_client, + m_current_peap_version, + true); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_EAP_CORE_SERVER) + if (m_is_client == false + && get_state() + == eap_type_tls_peap_state_waiting_for_empty_tppd_peap_v1_acknowledge) + { + // Server wait empty PEAP v1 acknowledge + status = finish_successful_authentication(false, false, true); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else if (m_is_client == false + && get_state() == eap_type_tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_tls_peap_c::tls_peap_packet_process(): ") + EAPL("received EAP-TTLS/PEAP empty Ack message in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s, ") + EAPL("eap_type_tls_peap_reassembly_state_e %d=%s.\n"), + get_state(), + get_state_string(), + get_reassembly_state(), + get_reassembly_state_string())); + + status = m_tls_record->empty_ack_packet_received( + receive_network_id, + received_tls_peap->get_identifier()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else if (m_is_client == false + && get_state() == eap_type_tls_peap_state_waiting_for_empty_response) + { + // Server waits the client sends an empty response. + + if (received_tls_peap->get_data_length() != 0ul) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN( + m_am_tools, + eap_status_process_illegal_packet_error); + } + else + { + if (m_current_eap_type == eap_type_tls + || (m_current_eap_type == eap_type_peap + && (get_tls_session_type() == tls_session_type_original_session_resumption + || get_tls_session_type() == tls_session_type_stateless_session_resumption))) + { + // OK, successfull authentication. + status = finish_successful_authentication(false, false, true); + if (status != eap_status_success) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (m_current_eap_type == eap_type_peap + || m_current_eap_type == eap_type_ttls +#if defined(USE_FAST_EAP_TYPE) + || (m_current_eap_type == eap_type_fast + && (get_tls_session_type() == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP + || get_tls_session_type() == tls_session_type_full_authentication)) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + save_current_state(); + set_state(eap_type_tls_peap_state_process_tls_message); + + // Now we must start the tunneled EAP-type. + status = m_tls_record->start_peap_tunneled_authentication( + receive_network_id, + received_tls_peap->get_eap_identifier(), + get_tls_session_type()); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_tunneled_eap_type_active = true; + set_state(eap_type_tls_peap_state_waiting_for_response); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_TLS_PEAP: %s, unknown EAP-type 0x%08x\n"), + (m_is_client == true) ? "client": "server", + convert_eap_type_to_u32_t(m_current_eap_type))); + + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else +#endif //#if defined(USE_EAP_CORE_SERVER) + { + // This is EAP-TLS/PEAP fragment acknowledge. + if (m_tls_message_buffer.get_is_valid_data() == true + && m_tls_message_send_offset < m_tls_message_buffer.get_data_length()) + { + // We can send next fragment. + + save_current_state(); + set_state(eap_type_tls_peap_state_process_tls_message); + + status = eap_tls_peap_fragment_send(); + if (status != eap_status_ok) + { + restore_saved_previous_state(); + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_is_client == true) + { + set_state(eap_type_tls_peap_state_waiting_for_request); + } + else + { + set_state(eap_type_tls_peap_state_waiting_for_response); + } + } + else + { + // No fragment available. Drop this packet. + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: this = 0x%08x, %s, %s, function: eap_type_tls_peap_c::tls_peap_packet_process(): waits first fragment, non empty EAP-TLS/PEAP message.\n"), + this, + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"))); + + +#if defined(USE_EAP_CORE_SERVER) + if (m_is_client == false + && get_state() == eap_type_tls_peap_state_waiting_for_empty_response + && received_tls_peap->get_data_length() != 0ul) + { + // Server waits the client sends an empty response. + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN( + m_am_tools, + eap_status_process_illegal_packet_error); + } + else if (m_is_client == false + && m_current_eap_type == eap_type_peap + && get_state() == eap_type_tls_peap_state_waiting_for_first_response) + { + // Note PEAP version is NOT checked here. + status = received_tls_peap->check_header( + m_am_tools, + m_current_eap_type, + m_is_client, + m_current_peap_version, + false); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Check the PEAP version client selected. + status = select_peap_version(received_tls_peap->get_flag_version()); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + restore_saved_previous_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + + // NOTE, PEAP version is checked here. + status = received_tls_peap->check_header( + m_am_tools, + m_current_eap_type, + m_is_client, + m_current_peap_version, + true); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Process the reassembled TLS message. + status = tls_message_process( + receive_network_id, + received_tls_peap, + tls_peap_packet_length); + + if (status != eap_status_ok + && status != eap_status_pending_request + && status != eap_status_success) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + set_reassembly_state(eap_type_tls_peap_reassembly_state_wait_first_message); + } + } + else if (get_reassembly_state() == eap_type_tls_peap_reassembly_state_wait_last_fragment) + { + // TLS message length field may or may not be included. + + EAP_ASSERT_ALWAYS(received_tls_peap->get_flag_start() == false); + + // Concatenate fragment to the reassembly buffer. + status = m_tls_message_buffer.add_data( + received_tls_peap->get_data(m_am_tools, received_tls_peap->get_data_length()), + received_tls_peap->get_data_length()); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (received_tls_peap->get_flag_more_fragments() == true) + { + // This is NOT the last fragment. + + // Send fragment acknowledge message. + status = send_empty_eap_ack(); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // This is the last fragment. + // Change reassembly state. + set_reassembly_state(eap_type_tls_peap_reassembly_state_message_reassembled); + + // Process the reassembled TLS message. + status = tls_message_process( + receive_network_id, + received_tls_peap, + tls_peap_packet_length); + + if (status != eap_status_ok + && status != eap_status_pending_request + && status != eap_status_success) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_reassembly_state(eap_type_tls_peap_reassembly_state_wait_first_message); + } + } + else if (get_reassembly_state() == eap_type_tls_peap_reassembly_state_message_reassembled) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::tls_peap_packet_process(): ") + EAPL("Cannot receive EAP-TLS/PEAP message in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s, ") + EAPL("eap_type_tls_peap_reassembly_state_e %d=%s.\n"), + get_state(), + get_state_string(), + get_reassembly_state(), + get_reassembly_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::tls_peap_packet_process(): ") + EAPL("Cannot receive EAP-TLS/PEAP message in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s, ") + EAPL("eap_type_tls_peap_reassembly_state_e %d=%s.\n"), + get_state(), + get_state_string(), + get_reassembly_state(), + get_reassembly_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_type_tls_peap_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Note, EAP-TLS and PEAP supports fragmentation. + // Here we could tell the MTU is big enough, the maximum memory buffer size is perfect. + + if (m_current_eap_type == eap_type_peap + && m_current_peap_version == peap_version_0_xp) + { + // PEAPv0 cannot use long tunneled EAP-packets, + // bacause of the inner EAP-packets does not + // have own EAP-header. Long inner EAP-packets will be + // fragmented in outer PEAPv0 application data and that will cause + // wrong EAP-identifier values after reassembly. + u32_t offset = get_type_partner()->get_header_offset( + MTU, + trailer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return offset; + } + else + { + if (MTU != 0) + { + *MTU = EAP_TLS_PEAP_MAX_MESSAGE_LENGTH; + } + + if (trailer_length != 0) + { + *trailer_length = 0ul; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0ul; // This is the header offset of the TLS-record header. + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::timer_expired( + const u32_t /*id*/, void * /*data*/ + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::timer_delete_data( + const u32_t /*id*/, void * /*data*/ + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_type_tls_peap_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + status = m_am_type_tls_peap->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_tls_record->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + { + eap_variable_data_c tls_use_privacy(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_EAP_TLS_PEAP_use_identity_privacy.get_field(), + &tls_use_privacy); + if (status == eap_status_ok + && tls_use_privacy.get_is_valid_data() == true + && tls_use_privacy.get_data_length() == sizeof(u32_t) + && tls_use_privacy.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + tls_use_privacy.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_tls_use_identity_privacy = false; + } + else + { + m_tls_use_identity_privacy = true; + } + } + } + + status = eap_status_ok; + } + + if (m_is_client == false) + { + eap_variable_data_c tls_server_use_privacy(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_EAP_TLS_PEAP_use_identity_privacy_server.get_field(), + &tls_server_use_privacy); + if (status == eap_status_ok + && tls_server_use_privacy.get_is_valid_data() == true + && tls_server_use_privacy.get_data_length() == sizeof(u32_t) + && tls_server_use_privacy.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + tls_server_use_privacy.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_tls_use_identity_privacy = false; + } + else + { + m_tls_use_identity_privacy = true; + } + } + } + + status = eap_status_ok; + } + +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + //---------------------------------------------------------- + + { + eap_variable_data_c wait_eap_success_packet(m_am_tools); + + status = read_configure( + cf_str_EAP_TLS_PEAP_wait_eap_success_packet.get_field(), + &wait_eap_success_packet); + + if (status == eap_status_ok + && wait_eap_success_packet.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast( + wait_eap_success_packet.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_wait_eap_success_packet = false; + } + else + { + // NOTE: when plain PEAP is used no EAP-success is sent + // in plain text and this option will be set to false. + m_wait_eap_success_packet = true; + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_TLS_PEAP_wait_eap_success_packet.get_field()->get_field())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c check_identifier_of_eap_identity_response(m_am_tools); + + status = read_configure( + cf_str_EAP_TLS_PEAP_check_identifier_of_eap_identity_response.get_field(), + &check_identifier_of_eap_identity_response); + + if (status == eap_status_ok + && check_identifier_of_eap_identity_response.get_is_valid_data() == true) + { + u32_t *flag = reinterpret_cast( + check_identifier_of_eap_identity_response.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_check_identifier_of_eap_identity_response = false; + } + else + { + m_check_identifier_of_eap_identity_response = true; + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_TLS_PEAP_check_identifier_of_eap_identity_response + .get_field()->get_field())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TLS_PEAP_check_nai_realm(m_am_tools); + + status = read_configure( + cf_str_EAP_TLS_PEAP_check_nai_realm.get_field(), + &EAP_TLS_PEAP_check_nai_realm); + if (status == eap_status_ok + && EAP_TLS_PEAP_check_nai_realm.get_is_valid_data() == true) + { + u32_t *check_nai_realm = reinterpret_cast( + EAP_TLS_PEAP_check_nai_realm.get_data(sizeof(u32_t))); + if (check_nai_realm != 0 + && *check_nai_realm != 0) + { + m_check_nai_realm = true; + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c test_version(m_am_tools); + + status = read_configure( + cf_str_EAP_TLS_test_version.get_field(), + &test_version); + if (status == eap_status_ok + && test_version.get_is_valid_data() == true + && test_version.get_data_length() == sizeof(u32_t) + && test_version.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(test_version.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_tls_peap_test_version = false; + } + else + { + m_tls_peap_test_version = true; + } + } + } + } + + //---------------------------------------------------------- + + if (m_current_eap_type == eap_type_peap) + { + { + eap_variable_data_c use_tppd_peapv1_acknowledge_hack(m_am_tools); + + status = read_configure( + cf_str_EAP_TLS_use_tppd_peapv1_acknowledge_hack.get_field(), + &use_tppd_peapv1_acknowledge_hack); + if (status == eap_status_ok + && use_tppd_peapv1_acknowledge_hack.get_is_valid_data() == true + && use_tppd_peapv1_acknowledge_hack.get_data_length() == sizeof(u32_t) + && use_tppd_peapv1_acknowledge_hack.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + use_tppd_peapv1_acknowledge_hack.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_use_tppd_peapv1_acknowledge_hack = false; + } + else + { + m_use_tppd_peapv1_acknowledge_hack = true; + } + } + } + } + + + if (m_is_client == false) + { + // Server + + eap_variable_data_c used_peap_version(m_am_tools); + + status = read_configure( + cf_str_EAP_TLS_PEAP_used_PEAP_version.get_field(), + &used_peap_version); + if (status == eap_status_ok + && used_peap_version.get_is_valid_data() == true) + { + u32_t *p_used_peap_version = reinterpret_cast( + used_peap_version.get_data(sizeof(u32_t))); + + if (p_used_peap_version == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_TLS_PEAP_used_PEAP_version.get_field()->get_field())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + else if (*p_used_peap_version > peap_version_2) + { + // Not supported PEAP version. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: Not supported PEAP version configuration %s: %d\n"), + cf_str_EAP_TLS_PEAP_used_PEAP_version.get_field()->get_field(), + *p_used_peap_version)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + else + { + m_configured_peap_version = static_cast( + *p_used_peap_version); + m_current_peap_version = m_configured_peap_version; + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_tppd_peapv1_acknowledge_hack(m_am_tools); + + status = read_configure( + cf_str_EAP_TLS_server_use_tppd_peapv1_acknowledge_hack.get_field(), + &use_tppd_peapv1_acknowledge_hack); + if (status == eap_status_ok + && use_tppd_peapv1_acknowledge_hack.get_is_valid_data() == true + && use_tppd_peapv1_acknowledge_hack.get_data_length() == sizeof(u32_t) + && use_tppd_peapv1_acknowledge_hack.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + use_tppd_peapv1_acknowledge_hack.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_use_tppd_peapv1_acknowledge_hack = false; + } + else + { + m_use_tppd_peapv1_acknowledge_hack = true; + } + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c accepted_peap_versions(m_am_tools); + + status = read_configure( + cf_str_EAP_TLS_PEAP_accepted_PEAP_versions.get_field(), + &accepted_peap_versions); + if (status == eap_status_ok + && accepted_peap_versions.get_is_valid_data() == true + && accepted_peap_versions.get_data_length() >= sizeof(u32_t)) + { + u32_t *p_accepted_peap_versions + = reinterpret_cast(accepted_peap_versions.get_data( + accepted_peap_versions.get_data_length())); + + if (p_accepted_peap_versions == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_TLS_PEAP_accepted_PEAP_versions.get_field()->get_field())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + else + { + u32_t version_count = accepted_peap_versions.get_data_length() + / sizeof(u32_t); + + for (u32_t ind = 0ul; ind < version_count; ind++) + { + if (p_accepted_peap_versions[ind] > peap_version_2) + { + // Not supported PEAP version. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: Not supported PEAP version configuration %s: %d\n"), + cf_str_EAP_TLS_PEAP_accepted_PEAP_versions + .get_field()->get_field(), + *p_accepted_peap_versions)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN( + m_am_tools, + eap_status_illegal_configure_field); + } + + status = m_accepted_PEAP_versions.add_data( + &(p_accepted_peap_versions[ind]), + sizeof(p_accepted_peap_versions[ind])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + else + { + // Not configured. + // Accept only version 0. + u32_t accepted_peap_version = peap_version_0_xp; + + m_accepted_PEAP_versions.reset(); + + status = m_accepted_PEAP_versions.add_data( + &accepted_peap_version, + sizeof(accepted_peap_version)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + //---------------------------------------------------------- + + if (m_is_client == false) + { + // Server could use it's own configuration. + + eap_variable_data_c accepted_peap_versions(m_am_tools); + + status = read_configure( + cf_str_EAP_TLS_PEAP_server_accepted_PEAP_versions.get_field(), + &accepted_peap_versions); + if (status == eap_status_ok + && accepted_peap_versions.get_is_valid_data() == true + && accepted_peap_versions.get_data_length() >= sizeof(u32_t)) + { + // Server uses own configuration. + m_accepted_PEAP_versions.reset(); + + u32_t *p_accepted_peap_versions + = reinterpret_cast(accepted_peap_versions.get_data( + accepted_peap_versions.get_data_length())); + + if (p_accepted_peap_versions == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_TLS_PEAP_accepted_PEAP_versions.get_field()->get_field())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + else + { + u32_t version_count = accepted_peap_versions.get_data_length() + / sizeof(u32_t); + + for (u32_t ind = 0ul; ind < version_count; ind++) + { + if (p_accepted_peap_versions[ind] > peap_version_2) + { + // Not supported PEAP version. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: Not supported PEAP version configuration %s: %d\n"), + cf_str_EAP_TLS_PEAP_accepted_PEAP_versions + .get_field()->get_field(), + *p_accepted_peap_versions)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN( + m_am_tools, + eap_status_illegal_configure_field); + } + + status = m_accepted_PEAP_versions.add_data( + &(p_accepted_peap_versions[ind]), + sizeof(p_accepted_peap_versions[ind])); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + else + { + // Not configured. + // Accept only version 0. + u32_t accepted_peap_version = peap_version_0_xp; + + m_accepted_PEAP_versions.reset(); + + status = m_accepted_PEAP_versions.add_data( + &accepted_peap_version, + sizeof(accepted_peap_version)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_tppd_tls_peap(m_am_tools); + + status = read_configure( + cf_str_EAP_TLS_PEAP_use_tppd_tls_peap.get_field(), + &use_tppd_tls_peap); + if (status == eap_status_ok + && use_tppd_tls_peap.get_is_valid_data() == true) + { + u32_t *use_tppd_tls_peap_flag = reinterpret_cast( + use_tppd_tls_peap.get_data(sizeof(u32_t))); + if (use_tppd_tls_peap_flag != 0) + { + if (*use_tppd_tls_peap_flag != 0) + { + m_use_tppd_tls_peap = true; + } + else + { + m_use_tppd_tls_peap = false; + } + } + } + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_EXPANDED_TYPES) + { + eap_variable_data_c use_eap_expanded_type(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TLS_PEAP_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + + if (status != eap_status_ok) + { + status = read_configure( + cf_str_EAP_CORE_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + } + + if (status == eap_status_ok + && use_eap_expanded_type.get_data_length() == sizeof(u32_t) + && use_eap_expanded_type.get_data() != 0) + { + u32_t *flag = reinterpret_cast(use_eap_expanded_type.get_data(use_eap_expanded_type.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_use_eap_expanded_type = true; + } + else + { + m_use_eap_expanded_type = false; + } + } + } + } +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + //---------------------------------------------------------- + + m_tls_peap_header_offset = get_type_partner()->get_header_offset( + &m_MTU, &m_trailer_length); + + if (m_tls_peap_header_offset+m_MTU+m_trailer_length > TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH) + { + EAP_ASSERT_ALWAYS(TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH + >= (m_tls_peap_header_offset+m_trailer_length)); + + m_MTU = TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH + - (m_tls_peap_header_offset+m_trailer_length); + } + + //---------------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + if (m_current_eap_type == eap_type_fast) + { + m_configured_peap_version = peap_version_1; + m_current_peap_version = peap_version_1; + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + if (m_current_eap_type == eap_type_tls) + { + m_configured_peap_version = peap_version_none; + m_current_peap_version = peap_version_none; + } + else if (m_current_eap_type == eap_type_peap) + { + if (m_current_peap_version == peap_version_none) + { + // This is the default tunnel type. + // Default tunnel type is needed if TLS-alert is sent before PEAP-starts. + m_configured_peap_version = peap_version_2; + m_current_peap_version = m_configured_peap_version; + } + } + + if (m_current_eap_type == eap_type_peap + && m_current_peap_version == peap_version_1) + { + m_wait_eap_success_packet = false; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: %s: because plain PEAP is used ") + EAPL("m_wait_eap_success_packet is set to false, type 0x%08x.\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + } + else if (m_current_eap_type == eap_type_ttls) + { + m_wait_eap_success_packet = true; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: %s: because plain TTLS is used ") + EAPL("m_wait_eap_success_packet is set to true, type 0x%08x.\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + } + + + m_tls_record->set_peap_version( + m_current_peap_version, + m_use_tppd_tls_peap, + m_use_tppd_peapv1_acknowledge_hack); + + + if (get_type_partner()->get_is_tunneled_eap() == true) + { + m_wait_eap_success_packet = true; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: %s: because this is tunneled session ") + EAPL("m_wait_eap_success_packet is set to true, type 0x%08x.\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + } + + //---------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x => 0x%08x, %s: function: eap_type_tls_peap_c::shutdown()\n"), + this, + dynamic_cast(this), + (m_is_client == true ? "client": "server"))); + + if (m_shutdown_was_called == true) + { + // Shutdown was already called (this prevents looping forever) + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + m_shutdown_was_called = true; + + send_final_notification(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_tls_peap_c::shutdown() calls m_tls_record->shutdown()\n"))); + + // Here we ignore return value. Both shutdown() calls must be done. + eap_status_e status = m_tls_record->shutdown(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_tls_peap_c::shutdown() calls m_am_type_tls_peap->shutdown()\n"))); + + status = m_am_type_tls_peap->shutdown(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x => 0x%08x, %s: function: eap_type_tls_peap_c::shutdown() returns\n"), + this, + dynamic_cast(this), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::set_tls_master_secret( + const eap_variable_data_c * const eap_tls_master_session_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x => 0x%08x, %s: function: eap_type_tls_peap_c::set_tls_master_secret()\n"), + this, + dynamic_cast(this), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_tls_peap_c::set_tls_master_secret():"), + eap_tls_master_session_key->get_data(eap_tls_master_session_key->get_data_length()), + eap_tls_master_session_key->get_data_length())); + + eap_status_e status = get_master_session_key()->set_copy_of_buffer(eap_tls_master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE this will be read from AM of EAP-TLS/PEAP type. + eap_status_e status = m_am_type_tls_peap->type_configure_read(field, data); + if (status != eap_status_ok) + { + // EAP-TLS/PEAP AM did not have configuration parameter. + // Let's try the global configuration. + status = get_type_partner()->read_configure(field, data); + if (status != eap_status_ok) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_tls_peap_c::read_configure(): ") + EAPL("unknown configuration parameter"), + field->get_field(), + field->get_field_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE this will be read from AM of EAP-TLS/PEAP type. + const eap_status_e status = m_am_type_tls_peap->type_configure_write(field, data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_type_tls_peap_c::state_notification( + const abs_eap_state_notification_c * const state + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLS_PEAP: %s, %s: eap_type_tls_peap_c::state_notification(): ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s, notification state=%s.\n"), + (m_is_client == true ? "client": "server"), + (get_type_partner()->get_is_tunneled_eap() == true ? "tunneled" : "outer most"), + get_state(), + get_state_string(), + eap_state_notification_c::get_state_string(state->get_protocol_layer(), state->get_current_state()))); + + + if (state->get_protocol_layer() == eap_protocol_layer_general) + { + // Just forward these notifications to lower layers. + get_type_partner()->state_notification(state); + return; + } + + + eap_tls_trace_string_c tls_trace; + + + if (state->get_protocol_layer() == eap_protocol_layer_eap) + { + if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + || state->get_current_state() == eap_state_authentication_terminated_unsuccessfully_peapv1_extension +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + ) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s: eap_type_tls_peap_c::state_notification(): ") + EAPL("authentication failed: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + + // Here we must change the EAP-type of the notification. + { + eap_state_notification_c * notification = new eap_state_notification_c( + m_am_tools, + state->get_send_network_id(), + state->get_is_client(), + eap_state_notification_eap, + state->get_protocol_layer(), + m_current_eap_type, + state->get_previous_state(), + eap_state_authentication_terminated_unsuccessfully, + state->get_eap_identifier(), + false); + + eap_automatic_variable_c automatic_notification(m_am_tools, notification); + + if (notification == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + set_state(eap_type_tls_peap_state_failure); + return; + } + + notification->set_authentication_error(eap_status_authentication_failure); + + get_type_partner()->state_notification(notification); + } + } +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + else if (state->get_current_state() + == eap_state_tppd_peapv1_authentication_finished_successfully_with_tunneled_eap_success) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("PEAPv1 authentication tunneled EAP-SUCCESS: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + + m_tunneled_eap_type_authentication_state + = static_cast(state->get_current_state()); + + (void) finish_successful_authentication(true, false, true); + } +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + else if (state->get_current_state() == eap_state_authentication_finished_successfully +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + || state->get_current_state() == eap_state_authentication_finished_successfully_peapv1_extension +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + ) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("authentication EAP-SUCCESS: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + + m_tunneled_eap_type_authentication_state + = eap_state_authentication_finished_successfully; + +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + if (m_current_eap_type == eap_type_peap + && m_current_peap_version == peap_version_1 + && m_use_tppd_tls_peap == true) + { + if (m_is_client == true) + { +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + if (state->get_current_state() == eap_state_authentication_finished_successfully_peapv1_extension) + { + // In this case Server does wait + // the client send tunneled Extension Response. + // Here we do not send empty EAP-TLS/PEAP response. + (void) finish_successful_authentication(false, false, false); + } + else +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + { + // In this case Server does not wait + // the client send empty EAP-TLS/PEAP response. + (void) finish_successful_authentication(false, false, true); + } + } + else + { +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + if (state->get_current_state() == eap_state_authentication_finished_successfully_peapv1_extension) + { + // In this case Server does not wait + // the client send empty EAP-TLS/PEAP response. + (void) finish_successful_authentication(false, false, true); + } + else +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + if (m_use_tppd_peapv1_acknowledge_hack == false + || get_tls_session_type() == tls_session_type_full_authentication) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("Waits empty final acknowledge: EAP-type ") + EAPL("0x%08x, tunnel type %s\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type), + tls_trace.get_peap_version_string(m_current_peap_version))); + + // Server waits the client send empty EAP-TLS/PEAP response. + set_state(eap_type_tls_peap_state_waiting_for_empty_tppd_peap_v1_acknowledge); + } + else + { +#if !defined(USE_EAP_PEAPV1_EXTENSIONS) + // In this case Server does not wait + // the client send empty EAP-TLS/PEAP response. + (void) finish_successful_authentication(false, false, true); +#else + EAP_ASSERT_ANYWAY_TOOLS(m_am_tools); +#endif //#if !defined(USE_EAP_PEAPV1_EXTENSIONS) + } + } + } + else +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + if (m_current_eap_type == eap_type_ttls) + { + if (m_is_client == true) + { + // In EAP-TTLS case client finishes immediately. + (void) finish_successful_authentication(false, false, true); + } +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else if (m_is_client == false + && get_state() == eap_type_tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack) + { + // EAP-TTLS server finishes immediately if plain MsChapv2 + // was run inside tunnel. + (void) finish_successful_authentication(false, false, true); + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else if (m_is_client == false) + { + (void) finish_successful_authentication(false, false, true); + } + } + else if (m_current_eap_type == eap_type_peap + && (m_current_peap_version == peap_version_0_xp + || m_current_peap_version == peap_version_1 + || m_current_peap_version == peap_version_2)) + { + if (m_is_client == true) + { + (void) finish_successful_authentication(false, false, true); + } + else + { + // Server + if (m_current_peap_version == peap_version_1 + && m_use_tppd_tls_peap == true) + { + // Server waits the client send empty EAP-TLS/PEAP response. + set_state(eap_type_tls_peap_state_waiting_for_empty_tppd_peap_v1_acknowledge); + } + else + { + (void) finish_successful_authentication(false, false, true); + } + } + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_current_eap_type == eap_type_fast) + { + if (m_is_client == true) + { + (void) finish_successful_authentication(false, false, true); + } + else + { + // Server + (void) finish_successful_authentication(false, false, true); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + } + else if (state->get_current_state() == eap_state_wait_plain_eap_success) + { + m_wait_eap_success_packet = true; + set_state(eap_type_tls_peap_state_waiting_for_success); + } + else if (state->get_current_state() == eap_state_authentication_wait_tppd_peapv1_empty_acknowledge) + { + if (m_is_client == false) + { + // Send plain EAP-Success. + get_type_partner()->state_notification(state); + + // Server waits the client send empty EAP-TLS/PEAP response. + set_state(eap_type_tls_peap_state_waiting_for_empty_response); + } + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_is_client == false + && m_current_eap_type == eap_type_fast + && state->get_current_state() == eap_state_authentication_wait_eap_fast_empty_acknowledge) + { + // Server waits an empty EAP-FAST acknowledge. + set_state(eap_type_tls_peap_state_waiting_for_empty_response); + } + else if (m_current_eap_type == eap_type_fast + && state->get_current_state() == eap_state_use_eap_failure_in_termination) + { + (void) finish_successful_authentication(false, true, true); + + eap_state_notification_c notification( + m_am_tools, + get_send_network_id(), + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_current_eap_type, + eap_state_none, + state->get_current_state(), + get_last_eap_identifier(), // Note the EAP-Success uses the same EAP-Identifier as the last EAP-Request. + false); + + get_type_partner()->state_notification(¬ification); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + } + else if (state->get_protocol_layer() == eap_protocol_layer_internal_type) + { + if (state->get_current_state() == tls_peap_state_failure) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): TLS tunneled ") + EAPL("authentication failed: EAP-type 0x%08x, tunnel type %s\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type), + tls_trace.get_peap_version_string(m_current_peap_version))); + + set_state(eap_type_tls_peap_state_failure); + } + else if (state->get_current_state() == tls_peap_state_tls_success) + { + + if (get_state() != eap_type_tls_peap_state_success + && get_state() != eap_type_tls_peap_state_waiting_for_success) + { + eap_status_e status = eap_status_process_general_error; + + if (m_tunneled_eap_type_active == true) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("TLS tunneled authentication ") + EAPL("EAP-SUCCESS: EAP-type 0x%08x, tunnel type %s, style %d\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type), + tls_trace.get_peap_version_string(m_current_peap_version), + m_use_tppd_tls_peap)); + + if (m_tunneled_eap_type_authentication_state + == eap_state_authentication_finished_successfully) + { + // Tunneled EAP-type finished successfully. + if (m_is_client == true) + { + // Client + status = finish_successful_authentication(false, false, true); + } + else + { + // Server + if (m_current_eap_type == eap_type_peap + && m_current_peap_version == peap_version_1 + && m_use_tppd_tls_peap == true) + { + // Server waits the client send empty EAP-TLS/PEAP response. + set_state(eap_type_tls_peap_state_waiting_for_empty_tppd_peap_v1_acknowledge); + status = eap_status_ok; + } + else + { + status = finish_successful_authentication(false, false, true); + } + } + } + else + { + set_state(eap_type_tls_peap_state_failure); + } + } + else if (get_tls_session_type() == tls_session_type_original_session_resumption + || get_tls_session_type() == tls_session_type_stateless_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("TLS resumed session authentication ") + EAPL("EAP-SUCCESS: EAP-type 0x%08x, m_tls_session_type=%d=%s, tunnel type %s\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type), + get_tls_session_type(), + eap_tls_trace_string_c::get_tls_session_type_string(get_tls_session_type()), + tls_trace.get_peap_version_string(m_current_peap_version))); + + // Saved previous session was resumed. + m_tunneled_eap_type_authentication_state + = eap_state_authentication_finished_successfully; + + if (m_is_client == true) + { + if (m_wait_eap_success_packet == true) + { + set_state(eap_type_tls_peap_state_waiting_for_success); + } + else + { + status = finish_successful_authentication(false, false, true); + } + } + else + { + // Server + status = finish_successful_authentication(false, false, true); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("plain TLS authentication EAP-SUCCESS: EAP-type 0x%08x, tunnel type %s\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type), + tls_trace.get_peap_version_string(m_current_peap_version))); + + // Plain TLS. + if (m_is_client == true) + { + + if (get_tls_session_type() == tls_session_type_full_authentication) + { + // Client must send a empty response message to server. + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + get_send_network_id()->get_destination_id(), + get_send_network_id()->get_source_id(), + get_send_network_id()->get_type()); + + status = send_empty_eap_ack(); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + + if (m_current_eap_type == eap_type_tls + || m_current_eap_type == eap_type_peap) // This is session resumption case. + { + if (m_wait_eap_success_packet == true) + { + set_state(eap_type_tls_peap_state_waiting_for_success); + } + else + { + status = finish_successful_authentication(false, false, true); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_TLS_PEAP: %s, unknown EAP-type 0x%08x\n"), + (m_is_client == true) ? "client": "server", + convert_eap_type_to_u32_t(m_current_eap_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + set_state(eap_type_tls_peap_state_failure); + return; + } + } + else + { + // Server waits the client send empty EAP-TLS/PEAP response. + set_state(eap_type_tls_peap_state_waiting_for_empty_response); + status = eap_status_ok; + } + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_type_tls_peap_c::state_notification(): ") + EAPL("duplicate success notification ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s, notification state %d=%s.\n"), + get_state(), + get_state_string(), + state->get_current_state(), + state->get_current_state_string())); + } + } + else if (state->get_current_state() == tls_peap_state_full_authentication) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("full TLS authentication: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + } + else if (state->get_current_state() == tls_peap_state_original_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("TLS session resumption: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + } +#if defined(USE_EAP_TLS_SESSION_TICKET) + else if (state->get_current_state() == tls_peap_state_stateless_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("TLS stateless session resumption: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + } +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + else if (state->get_current_state() + == tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("PEAPv1 waits EAP-Success or tunneled packet: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + + set_state(eap_type_tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet); + } +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else if (state->get_current_state() == tls_peap_state_client_send_ttls_plain_ms_chap_v2_empty_ack) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("sends TTLS/plain MsChapv2 empty Ack: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + + // Send empty acknowledge message. + eap_status_e status = send_empty_eap_ack(); + if (status != eap_status_ok) + { + set_state(eap_type_tls_peap_state_failure); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else if (state->get_current_state() == tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("waits TTLS/plain MsChapv2 empty Ack: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + + set_state(eap_type_tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack); + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else if (state->get_current_state() == tls_peap_state_peap_tunnel_ready) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("TLS tunnel ready: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + + if (m_is_client == true) + { + eap_status_e status = eap_status_process_general_error; + + if (m_current_eap_type == eap_type_tls + //|| m_current_eap_type == eap_type_ttls TTLS does not send empty ack. + || (m_current_eap_type == eap_type_peap + && m_current_peap_version < peap_version_2)) + { + if (get_tls_session_type() == tls_session_type_full_authentication) + { + // Client must sent an empty EAP-response ONLY in full authentication. + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id( + m_am_tools, + get_send_network_id()->get_destination_id(), + get_send_network_id()->get_source_id(), + get_send_network_id()->get_type()); + + status = send_empty_eap_ack(); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + } + + if (m_current_eap_type == eap_type_tls) + { + if (m_wait_eap_success_packet == true) + { + set_state(eap_type_tls_peap_state_waiting_for_success); + } + else + { + status = finish_successful_authentication(false, false, true); + } + } + else if (m_current_eap_type == eap_type_ttls) + { + m_tunneled_eap_type_active = true; + + set_state(eap_type_tls_peap_state_waiting_for_request); + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_current_eap_type == eap_type_fast) + { + m_tunneled_eap_type_active = true; + + if (get_tls_session_type() == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP) + { + // Client must sent an empty EAP-response ONLY in unauthenticated provisioning mode. + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id( + m_am_tools, + get_send_network_id()->get_destination_id(), + get_send_network_id()->get_source_id(), + get_send_network_id()->get_type()); + + status = send_empty_eap_ack(); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + set_state(eap_type_tls_peap_state_waiting_for_request); + } + else + { + set_state(eap_type_tls_peap_state_waiting_for_success); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + else if (m_current_eap_type == eap_type_peap) + { + m_tunneled_eap_type_active = true; + + if (m_current_peap_version < peap_version_2) + { + +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + if (m_is_client == true + && m_current_eap_type == eap_type_peap + && m_current_peap_version == peap_version_1 + && m_use_tppd_tls_peap == true + && m_use_tppd_peapv1_acknowledge_hack == true + && (get_tls_session_type() == tls_session_type_original_session_resumption + || get_tls_session_type() == tls_session_type_stateless_session_resumption) + && get_state() + == eap_type_tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet) + { + // Do not change state here. + } + else +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + { + set_state(eap_type_tls_peap_state_waiting_for_request); + } + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("ERROR: EAP_type_TLS_PEAP: %s, unknown EAP-type 0x%08x\n"), + (m_is_client == true) ? "client": "server", + convert_eap_type_to_u32_t(m_current_eap_type))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + set_state(eap_type_tls_peap_state_failure); + return; + } + } + else + { + if (m_current_eap_type == eap_type_peap) + { + if (m_current_peap_version == peap_version_2) + { + // Server waits the client send EAP-TLS/PEAP response. + m_tunneled_eap_type_active = true; + set_state(eap_type_tls_peap_state_waiting_for_response); + } + else + { + // Server waits the client send empty EAP-TLS/PEAP response. + set_state(eap_type_tls_peap_state_waiting_for_empty_response); + } + } + else if (m_current_eap_type == eap_type_ttls) + { + // Server waits the client send empty EAP-TLS/PEAP response. + m_tunneled_eap_type_active = true; + set_state(eap_type_tls_peap_state_waiting_for_response); + } + } + } + else if (state->get_current_state() == tls_peap_state_peap_tunnel_ready_wait_request) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_type_tls_peap_c::state_notification(): ") + EAPL("TLS tunnel ready: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_current_eap_type))); + + if (m_is_client == true) + { +#if defined(USE_FAST_EAP_TYPE) + if (m_current_eap_type == eap_type_fast) + { + m_tunneled_eap_type_active = true; + + // Client must sent an empty EAP-response. + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id( + m_am_tools, + get_send_network_id()->get_destination_id(), + get_send_network_id()->get_source_id(), + get_send_network_id()->get_type()); + + eap_status_e status = send_empty_eap_ack(); + if (status != eap_status_ok) + { + restore_saved_reassembly_state(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + set_state(eap_type_tls_peap_state_waiting_for_request); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + EAP_ASSERT_ANYWAY_TOOLS(m_am_tools); + } + } + else + { + EAP_ASSERT_ANYWAY_TOOLS(m_am_tools); + } + } + else if (state->get_current_state() == tls_peap_state_pending_tls_messages_processed) + { + if (get_state() == eap_type_tls_peap_state_process_tls_message + || get_state() == eap_type_tls_peap_state_process_tls_start) + { + if (m_is_client == true) + { + set_state(eap_type_tls_peap_state_waiting_for_request); + } + else + { + set_state(eap_type_tls_peap_state_waiting_for_response); + } + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::query_eap_identity( + const bool /* must_be_synchronous */, + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_tls_peap_c::query_eap_identity() ") + EAPL("in eap_type_tls_peap_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + if (m_tls_peap_test_version == true + && get_state() == eap_type_tls_peap_state_failure) + { + // This is for testing. + if (m_is_client == false) + { + set_state(eap_type_tls_peap_state_waiting_for_identity_response); + } + else if (m_is_client == true) + { + set_state(eap_type_tls_peap_state_waiting_for_tls_start); + } + } + + + bool use_manual_username(false); + eap_variable_data_c manual_username(m_am_tools); + bool use_manual_realm(false); + eap_variable_data_c manual_realm(m_am_tools); + + + if (m_state == eap_type_tls_peap_state_waiting_for_identity_request + || (m_tls_peap_test_version == true // This one is for testing purposes. + && m_state == eap_type_tls_peap_state_success)) + { + save_current_state(); + set_state(eap_type_tls_peap_state_pending_identity_query); + + eap_status_e status = eap_status_process_general_error; + + status = m_am_type_tls_peap->query_eap_identity( + identity, + receive_network_id, + eap_identifier, + &use_manual_username, + &manual_username, + &use_manual_realm, + &manual_realm); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_eap_identity_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_eap_identity_query() call. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok + && status != eap_status_success) + { + // This is an error case. + restore_saved_previous_state(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + status = handle_eap_identity_query( + identity, + receive_network_id, + eap_identifier, + use_manual_username, + &manual_username, + use_manual_realm, + &manual_realm); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_state == eap_type_tls_peap_state_waiting_for_tls_start) + { + // This is re-transmission request. We do not change our state. + // Just send EAP-Identity again. + if (get_NAI()->get_is_valid_data() == true) + { + eap_status_e status = identity->set_copy_of_buffer(get_NAI()); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_tls_peap_c::query_eap_identity() ") + EAPL("returns already obtained NAI in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::query_eap_identity(): ") + EAPL("EAP-Request/Identity cannot be completed, identity (NAI) ") + EAPL("is missing. in eap_type_tls_peap_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else if (m_state == eap_type_tls_peap_state_pending_identity_query) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_type_tls_peap_c::query_eap_identity(): ") + EAPL("Already pending EAP-Identity query in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: eap_type_tls_peap_c::query_eap_identity(): ") + EAPL("Illegal EAP-Identity query in eap_type_tls_peap_state_variable_e %d=%s.\n"), + get_state(), + get_state_string())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::set_initial_eap_identifier( + const eap_am_network_id_c * const /*receive_network_id*/, + const u8_t /*initial_identifier*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::eap_acknowledge( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + if (get_state() == eap_type_tls_peap_state_waiting_for_success) + { + if (m_wait_eap_success_packet == false) + { + /** + * @{ check right functionality. + * Here we return eap_status_ok, eap_status_success was + * returned after successfull + * EAP-Request/SIM/Challenge. This may change after EAP, + * 802.1X and 802.11i specifications are ready. } + */ + status = eap_status_ok; + } + else + { + if (m_current_eap_type == eap_type_tls) + { + status = finish_successful_authentication(false, false, true); + if (status != eap_status_success) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // We must forward this to the tunneled EAP-type. + + status = m_tls_record->plain_eap_success_failure_packet_received( + receive_network_id, + eap_code_success, + m_last_eap_identifier); + } + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ignored eap_acknowledge(): state %d=%s, is client %d, m_wait_eap_success_packet=%d, m_authentication_finished_successfully=%d\n"), + get_state(), + get_state_string(), + (m_is_client == true), + m_wait_eap_success_packet, + m_authentication_finished_successfully)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x, %s: eap_type_tls_peap_c::reset(): %d=%s.\n"), + this, + (m_is_client == true) ? "client": "server", + get_state(), + get_state_string())); + + m_current_identity.reset(); + + if (m_is_client == true) + { + // Client waits EAP-Request/Identity. + m_state = eap_type_tls_peap_state_waiting_for_identity_request; + m_saved_previous_state = eap_type_tls_peap_state_waiting_for_identity_request; + } + else if (m_is_client == false) + { + // Server waits EAP-Response/Identity. + m_state = eap_type_tls_peap_state_waiting_for_identity_response; + m_saved_previous_state = eap_type_tls_peap_state_waiting_for_identity_response; + } + + m_reassembly_state = eap_type_tls_peap_reassembly_state_wait_first_message; + + m_saved_previous_reassembly_state = eap_type_tls_peap_reassembly_state_wait_first_message; + + m_tls_message_send_offset = 0ul; + + m_includes_tls_handshake_message = false; + + m_tls_message_buffer.reset(); + + m_master_session_key.reset(); + + m_tunneled_eap_type_active = false; + m_tunneled_eap_type_authentication_state = eap_state_none; + + set_tls_session_type(tls_session_type_none); + + eap_status_e status = m_tls_record->reset(); + + m_failure_message_received = false; + m_authentication_finished_successfully = false; + m_last_eap_identifier = 0ul; + + m_current_peap_version = m_configured_peap_version; + + m_first_fragment_eap_identifier = 0ul; + + m_am_type_tls_peap->reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // This call is forwarded to EAPOL AM module because it handles all the + // tunneled EAP type handlings for PEAP. + const eap_status_e status = get_type_partner()->load_module( + type, + tunneling_type, + partner, + eap_type, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // This call is forwarded to EAPOL AM module because it handles all the + // tunneled EAP type handlings for PEAP. + const eap_status_e status = get_type_partner()->unload_module(type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool /*force_clean_restart*/, + const bool /*from_timer*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + const eap_status_e status = get_type_partner()->restart_authentication( + &send_network_id, + is_client_when_true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::packet_data_crypto_keys( + const eap_am_network_id_c * const /*send_network_id*/, + const eap_master_session_key_c * const /*master_session_key*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE we do NOT forwrd keys to lower layer. + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::check_is_valid_eap_type( + const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // This call is forwarded to TLS AM module because it handles all the + // tunneled EAP type handlings for PEAP. + const eap_status_e status = m_am_type_tls_peap->check_is_valid_eap_type(eap_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_am_type_tls_peap->get_eap_type_list(eap_type_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::set_session_timeout( + const u32_t session_timeout_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = get_type_partner()->set_session_timeout(session_timeout_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = get_type_partner()->add_rogue_ap(rogue_ap_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::peap_tunnel_ready() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x, %s: eap_type_tls_peap_c::peap_tunnel_ready() in ") + EAPL("eap_type_tls_peap_state_variable_e %d=%s.\n"), + this, + (m_is_client == true ? "client": "server"), + get_state(), + get_state_string())); + + m_tunneled_eap_type_active = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_type_tls_peap_c::set_tls_session_type(const tls_session_type_e tls_session_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x, %s: eap_type_tls_peap_c::set_tls_session_type() in ") + EAPL("m_tls_session_type=%d=%s.\n"), + this, + (m_is_client == true ? "client": "server"), + tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(tls_session_type))); + + m_tls_session_type = tls_session_type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_session_type_e eap_type_tls_peap_c::get_tls_session_type() +{ + return m_tls_session_type; +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/eap_type_tls_peap_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/eap_type_tls_peap_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,513 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 120 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_type_tls_peap_header.h" +#include "eap_header_string.h" + +/** @file */ + +EAP_FUNC_EXPORT eap_tls_peap_header_c::~eap_tls_peap_header_c() +{ +} + +// +EAP_FUNC_EXPORT eap_tls_peap_header_c::eap_tls_peap_header_c( + abs_eap_am_tools_c * const tools, + u8_t * const header_begin, + const u32_t header_buffer_length) + : eap_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) +{ +} + +EAP_FUNC_EXPORT eap_code_value_e eap_tls_peap_header_c::get_eap_code() const +{ + return eap_header_base_c::get_code(); +} + +EAP_FUNC_EXPORT u8_t eap_tls_peap_header_c::get_eap_identifier() const +{ + return eap_header_base_c::get_identifier(); +} + +EAP_FUNC_EXPORT u16_t eap_tls_peap_header_c::get_eap_length() const +{ + return eap_header_base_c::get_length(); +} + +EAP_FUNC_EXPORT eap_type_value_e eap_tls_peap_header_c::get_eap_type() const +{ + return eap_header_base_c::get_type(); +} + +EAP_FUNC_EXPORT u16_t eap_tls_peap_header_c::get_data_length() const +{ + if (get_flag_tls_length_included() == true + && get_eap_length() > static_cast(get_header_length())) + { + return static_cast(get_eap_length()-static_cast(get_header_length())); + } + else if (get_flag_tls_length_included() == false + && get_eap_length() > static_cast(get_header_length())) + { + return static_cast(get_eap_length()-static_cast(get_header_length())); + } + else + { + return 0; + } +} + +EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_tls_min_header_length() const +{ + return eap_header_base_c::get_header_length() + + eap_header_base_c::get_type_field_length() + + m_tls_length_delta_offset; +} + +EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_tls_max_header_length() +{ + return eap_header_base_c::get_header_length() + + eap_header_base_c::get_expanded_type_field_length() + + m_tls_length_delta_offset + + TLS_MESSAGE_LENGTH_FIELD_SIZE; +} + +EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_header_length() const +{ + u32_t length = get_tls_min_header_length(); + + if (get_flag_tls_length_included() == true) + { + return length+TLS_MESSAGE_LENGTH_FIELD_SIZE; + } + else + { + return length; + } +} + +EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_start_offset_of_data() const +{ + return get_header_length(); +} + +EAP_FUNC_EXPORT u8_t * eap_tls_peap_header_c::get_data_offset( + abs_eap_am_tools_c * const m_am_tools, + const u32_t offset, + const u32_t contignuous_bytes) const +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + u32_t data_length = get_data_length(); // Here is removed optional TLS message length. + + if (data_length >= offset+contignuous_bytes) + { + // get_header_length() handles optional TLS message length field. + u32_t offset_of_data = get_start_offset_of_data(); + u8_t * const data = get_header_offset(offset_of_data, offset+contignuous_bytes); + if (data != 0) + { + return data+offset; // Data begins after the header. + } + else + { + return 0; + } + } + else + { + EAP_ASSERT_ALWAYS(get_data_length() > 0u); + } + return 0; +} + + +EAP_FUNC_EXPORT u8_t * eap_tls_peap_header_c::get_data( + abs_eap_am_tools_c * const m_am_tools, + const u32_t contignuous_bytes) const +{ + return get_data_offset(m_am_tools, 0u, contignuous_bytes); +} + +EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_tls_flags_offset() const +{ + return eap_header_base_c::get_header_length() + eap_header_base_c::get_type_field_length(); +} + +EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_tls_length_offset() const +{ + return get_tls_flags_offset() + m_tls_length_delta_offset; +} + +EAP_FUNC_EXPORT u8_t * eap_tls_peap_header_c::get_tls_flags() const +{ + u32_t flag_offset(get_tls_flags_offset()+m_flag_delta_offset); + + return get_header_offset(flag_offset, sizeof(u8_t)); +} + +EAP_FUNC_EXPORT bool eap_tls_peap_header_c::get_tls_flag_bit(const u32_t mask) const +{ + const u8_t * const flag = get_tls_flags(); + + if (flag != 0 + && ((*flag) & mask)) + { + return true; + } + return false; +} + +EAP_FUNC_EXPORT u8_t eap_tls_peap_header_c::get_tls_flag_value(const u32_t mask, const u32_t shift) const +{ + const u8_t * const flag = get_tls_flags(); + + if (flag != 0) + { + return static_cast(((*flag) & mask) >> shift); + } + else + { + return 0; + } +} + +EAP_FUNC_EXPORT bool eap_tls_peap_header_c::get_flag_tls_length_included() const +{ + return get_tls_flag_bit(m_flag_mask_tls_length_included); +} + +EAP_FUNC_EXPORT bool eap_tls_peap_header_c::get_flag_more_fragments() const +{ + return get_tls_flag_bit(m_flag_mask_more_fragments); +} + +EAP_FUNC_EXPORT bool eap_tls_peap_header_c::get_flag_start() const +{ + return get_tls_flag_bit(m_flag_mask_start); +} + +EAP_FUNC_EXPORT u8_t eap_tls_peap_header_c::get_flag_reserved() const +{ + return get_tls_flag_value(m_flag_mask_reserved, m_flag_shift_reserved); +} + +EAP_FUNC_EXPORT u8_t eap_tls_peap_header_c::get_flag_version() const +{ + return get_tls_flag_value(m_flag_mask_version, m_flag_shift_version); +} + +EAP_FUNC_EXPORT eap_status_e eap_tls_peap_header_c::get_tls_message_length(u32_t * const tls_length) const +{ + if (get_flag_tls_length_included() == false) + { + // TLS data length is NOT included. + *tls_length = 0u; + return eap_status_ok; + } + + u8_t * const data = get_header_offset(get_tls_length_offset(), sizeof(u32_t)); + if (data != 0) + { + u32_t tls_message_length = + eap_read_u32_t_network_order(data, sizeof(u32_t)); + + *tls_length = tls_message_length; + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + + +EAP_FUNC_EXPORT eap_status_e eap_tls_peap_header_c::check_header( + abs_eap_am_tools_c * const tools, + const eap_type_value_e required_eap_type, + const bool is_client_when_true, + const peap_version_e peap_version, + const bool check_peap_version_when_true) const +{ + eap_status_e status = eap_status_ok; + + if (get_eap_type() != required_eap_type) + { + EAP_UNREFERENCED_PARAMETER(tools); + status = EAP_STATUS_RETURN(tools, eap_status_header_corrupted); + } + else if (get_flag_reserved() != static_cast(0ul)) + { + status = EAP_STATUS_RETURN(tools, eap_status_header_corrupted); + } + else if ((get_eap_type() == eap_type_tls + || get_eap_type() == eap_type_ttls) + && get_flag_version() != static_cast(0ul)) + { + status = EAP_STATUS_RETURN(tools, eap_status_header_corrupted); + } + else if (get_eap_type() == eap_type_peap + && check_peap_version_when_true == true + && peap_version == peap_version_0_xp + && get_flag_version() != static_cast(peap_version_0_xp)) + { + // In version negotiation this check will fail. + // Do not add error traces here. + status = eap_status_no_matching_protocol_version; + } + else if (get_eap_type() == eap_type_peap + && check_peap_version_when_true == true + && peap_version == peap_version_1 + && get_flag_version() != static_cast(peap_version_1)) + { + // In version negotiation this check will fail. + // Do not add error traces here. + status = eap_status_no_matching_protocol_version; + } + else if (get_eap_type() == eap_type_peap + && check_peap_version_when_true == true + && peap_version == peap_version_2 + && get_flag_version() != static_cast(peap_version_2)) + { + // In version negotiation this check will fail. + // Do not add error traces here. + status = eap_status_no_matching_protocol_version; + } + + if (status != eap_status_ok) + { + EAP_UNREFERENCED_PARAMETER(is_client_when_true); + + // In version negotiation this check will fail. + // Do not add error traces here. + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("WARNING: EAP_type_TLS_PEAP: check_header(): failed, %s, required_eap_type 0x%08x, ") + EAPL("peap_version %d, check_peap_version_when_true %d, get_eap_type() 0x%08x, get_flag_reserved() %d, get_flag_version() %d, status %s\n"), + (is_client_when_true == true) ? "client": "server", + convert_eap_type_to_u32_t(required_eap_type), + peap_version, + check_peap_version_when_true, + convert_eap_type_to_u32_t(get_eap_type()), + get_flag_reserved(), + get_flag_version(), + status_string.get_status_string(status))); + } + + if (status == eap_status_no_matching_protocol_version) + { + // In version negotiation this check will fail. + // Do not add error traces here. + return status; + } + else + { + return EAP_STATUS_RETURN(tools, status); + } +} + +EAP_FUNC_EXPORT eap_const_string eap_tls_peap_header_c::get_code_string() const +{ + return eap_header_string_c::get_eap_code_string(get_eap_code()); +} + +EAP_FUNC_EXPORT eap_const_string eap_tls_peap_header_c::get_eap_type_string() const +{ + if (get_eap_length() <= eap_header_base_c::get_header_length()) + { + return EAPL("No EAP-type"); + } + + return eap_header_string_c::get_eap_type_string(get_eap_type()); +} + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_eap_code(const eap_code_value_e p_code) +{ + eap_header_base_c::set_code(p_code); +} + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_eap_identifier(const u8_t p_identifier) +{ + eap_header_base_c::set_identifier(p_identifier); +} + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_eap_length( + const u16_t p_length, + const bool expanded_type_when_true) +{ + eap_header_base_c::set_length( + p_length, + expanded_type_when_true); +} + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_eap_type( + const eap_type_value_e p_type, + const bool expanded_type_when_true) +{ + eap_header_base_c::set_type(p_type, expanded_type_when_true); +} + + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_tls_flag_value(const u8_t value, const u32_t mask, const u32_t shift) const +{ + u8_t *flag = get_tls_flags(); + + if (flag != 0) + { + (*flag) = static_cast(((*flag) & ~mask) | ((value << shift) & mask)); + } +} + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_tls_flag_bit(const bool flag, u32_t mask) const +{ + u8_t *p_flag = get_tls_flags(); + + if (p_flag != 0) + { + if (flag == true) + { + (*p_flag) = static_cast((*p_flag) | mask); + } + else + { + (*p_flag) = static_cast((*p_flag) & ~mask); + } + } +} + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_flag_reserved(const u8_t reserved) +{ + set_tls_flag_value(reserved, m_flag_mask_reserved, m_flag_shift_reserved); +} + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_flag_version(const u8_t version) +{ + set_tls_flag_value(version, m_flag_mask_version, m_flag_shift_version); +} + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_flag_tls_length_included(const bool tls_length_included) +{ + set_tls_flag_bit(tls_length_included, m_flag_mask_tls_length_included); +} + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_flag_more_fragments(const bool more_fragments) +{ + set_tls_flag_bit(more_fragments, m_flag_mask_more_fragments); +} + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_flag_start(const bool start) +{ + set_tls_flag_bit(start, m_flag_mask_start); +} + + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_data_length( + const u32_t p_data_length, + const bool expanded_type_when_true) +{ + EAP_ASSERT_ALWAYS(p_data_length+get_header_length() <= 0xffff); + + set_eap_length( + static_cast(p_data_length+get_header_length()), + expanded_type_when_true); +} + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_tls_message_length(const u32_t tls_length) +{ + EAP_ASSERT_ALWAYS(get_flag_tls_length_included() == true); + + u8_t * const data = get_header_offset(get_tls_length_offset(), sizeof(u32_t)); + + EAP_ASSERT(data != 0); + + data[0] = static_cast((tls_length & 0xff000000) >> 24); + data[1] = static_cast((tls_length & 0x00ff0000) >> 16); + data[2] = static_cast((tls_length & 0x0000ff00) >> 8); + data[3] = static_cast((tls_length & 0x000000ff) >> 0); +} + + +EAP_FUNC_EXPORT void eap_tls_peap_header_c::reset_header( + abs_eap_am_tools_c * const m_am_tools, + const eap_type_value_e required_eap_type, + const u32_t buffer_length, + const peap_version_e peap_version, + const bool expanded_type_when_true) +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + eap_header_base_c::set_length( + static_cast(buffer_length), + expanded_type_when_true); + + set_eap_code(eap_code_none); + set_eap_identifier(0u); + set_eap_type( + required_eap_type, + expanded_type_when_true); + + set_flag_tls_length_included(false); + set_flag_more_fragments(false); + set_flag_start(false); + + set_flag_reserved(0u); + +#if defined(USE_FAST_EAP_TYPE) + if (required_eap_type == eap_type_fast) + { + set_flag_version(static_cast(peap_version)); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + if (required_eap_type == eap_type_peap) + { + if (peap_version >= peap_version_0_xp + && peap_version <= peap_version_2) + { + set_flag_version(static_cast(peap_version)); + } + else + { + EAP_ASSERT_ALWAYS((peap_version >= peap_version_0_xp) && (peap_version <= peap_version_2)); + } + } + else + { + // All other EAP-methods. + set_flag_version(0u); + } +} + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/eap_type_tls_peap_state_notification.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/eap_type_tls_peap_state_notification.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 121 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_type_tls_peap_state_notification.h" +#include "eap_type_tls_peap.h" +#include "eap_tools.h" + + +EAP_FUNC_EXPORT eap_type_tls_peap_state_notification_c::~eap_type_tls_peap_state_notification_c() +{ +} + +EAP_FUNC_EXPORT eap_type_tls_peap_state_notification_c::eap_type_tls_peap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_generic_e type, + eap_protocol_layer_e layer, + u32_t protocol, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + protocol, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + + +#if defined(USE_EAP_EXPANDED_TYPES) + +EAP_FUNC_EXPORT eap_type_tls_peap_state_notification_c::eap_type_tls_peap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e type, + eap_protocol_layer_e layer, + eap_type_value_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + eap_type, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + +EAP_FUNC_EXPORT eap_type_tls_peap_state_notification_c::eap_type_tls_peap_state_notification_c( + abs_eap_am_tools_c * const tools, + const eap_am_network_id_c * const send_network_id, + bool is_client, + eap_state_notification_eap_e type, + eap_protocol_layer_e layer, + eap_type_ietf_values_e eap_type, + u32_t previous_state, + u32_t current_state, + u8_t eap_identifier, + bool allow_send_eap_success) + : eap_state_notification_c( + tools, + send_network_id, + is_client, + type, + layer, + eap_type, + previous_state, + current_state, + eap_identifier, + allow_send_eap_success) +{ +} + + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,27 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_tls_peap + +SRC_FILES_CPP = $(WLAN_COMMON)/type/tls_peap/eap/src/eap_type_tls_peap.cpp \ + $(WLAN_COMMON)/type/tls_peap/eap/src/eap_type_tls_peap_state_notification.cpp \ + $(WLAN_COMMON)/type/tls_peap/eap/src/eap_type_tls_peap_header.cpp + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_tls_peap.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_tls_tools.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \ + -lstdc++ + +ifdef USE_MSCHAPV2_EAP_TYPE +# This is needed for EAP-TTLS/plain MsChapv2. +LIBS := ${LIBS} \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_mschapv2.$(LIB) +endif + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/abs_tls_apply_cipher_spec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/abs_tls_apply_cipher_spec.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_TLS_MESSAGE_RECORD_PROCESS_H_) +#define _ABS_TLS_MESSAGE_RECORD_PROCESS_H_ + +#include "eap_am_export.h" + +/// This class declares the functions message classes of TLS +/// requires from the TLS. +class EAP_EXPORT abs_tls_apply_cipher_spec_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing. + virtual ~abs_tls_apply_cipher_spec_c() + { + } + + /// Constructor does nothing. + + abs_tls_apply_cipher_spec_c() + { + } + + /** + * This function applies the send cipher suite to record message. + * @param tls_record_message_buffer includes the buffer of the whole TLS-record. + */ + virtual eap_status_e apply_send_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer) = 0; + + //-------------------------------------------------- +}; // class abs_tls_apply_cipher_spec_c + +#endif //#if !defined(_ABS_TLS_MESSAGE_RECORD_PROCESS_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/abs_tls_base_application.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/abs_tls_base_application.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_TLS_BASE_APPLICATION_H_) +#define _ABS_TLS_BASE_APPLICATION_H_ + +#if defined(USE_FAST_EAP_TYPE) + #include "eap_fast_tlv_header.h" +#endif //#if defined(USE_FAST_EAP_TYPE) + +#include "tls_record_header.h" +#include "tls_handshake_header.h" + +class eap_buf_chain_wr_c; +class eap_variable_data_c; +class abs_eap_state_notification_c; +class abs_eap_base_timer_c; +class abs_eap_base_type_c; +class eap_base_type_c; +class eap_network_id_selector_c; +class eap_fast_variable_data_c; + + +/// The class is the interface to partner class of the tls_base_application_c class. +/// This declares the pure virtual member functions tls_base_application_c class could call. +class EAP_EXPORT abs_tls_base_application_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_tls_base_application_c class does nothing special. + */ + virtual ~abs_tls_base_application_c() + { + } + + /** + * The constructor of the abs_tls_base_application_c class does nothing special. + */ + abs_tls_base_application_c() + { + } + + /** + * The derived class could send packets to partner class with this function. + * @param sent_packet includes the buffer for the whole packet and initialized + * TLS-packet in correct offset. + * @param header_offset is offset of the TLS-header within the sent_packet. + * @param data_length is length in bytes of the TLS-packet. + * @param buffer_length is length in bytes of the whole packet buffer. + */ + virtual eap_status_e packet_send( + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) = 0; + + /** + * The get_header_offset() function obtains the header offset of PEAP-packet. + * @param MTU_length is pointer to variable to store the maximum transfer unit (MTU). + * MTU is the maximum PEAP-packet length in bytes + * @param trailer_length is pointer to the variable to store length + * of trailer needed by lower levels. + * @return Function returns the offset of PEAP-header. + * + * The needed buffer length is ((offset) + (PEAP-packet length) + (trailer)) bytes. + * Each layer adds the length of the header to offset. + * Each layer removes the length of the header and trailer from MTU. + * + * Now some ascii graphics follows. + * @code + * |<-------------------------buffer length----------------------------------------->| + * | | + * | +-----+--------------------------+ | + * | | EAP | data | | + * | +-----+--------------------------+ | + * |<----offset---------------------->|<----MTU----------------------->|<--trailer-->| + * | | | | + * | +------+--------------------------------+ | + * | | PEAP | data | | + * | +------+--------------------------------+ | + * |<----offset--------------->|<----MTU------------------------------>|<--trailer-->| + * | | | | + * | +-----+---------------------------------------+ | + * | | EAP | data | | + * | +-----+---------------------------------------+ | + * |<----offset--------->|<----MTU------------------------------------>|<--trailer-->| + * | | | | + * | +-------+---------------------------------------------+ | + * | | EAPOL | data | | + * | +-------+---------------------------------------------+ | + * |<--offset--->|<----MTU-------------------------------------------->|<--trailer-->| + * | | | | + * +-------------+-----------------------------------------------------+-------------+ + * | ETHERNET | data | trailer | + * +-------------+-----------------------------------------------------+-------------+ + * |<----MTU------------------------------------------------------------------------>| + * @endcode + * + */ + virtual u32_t get_header_offset( + u32_t * const MTU_length, + u32_t * const trailer_length) = 0; + + /** + * This function restarts authentication to receive_network_id. + * @param receive_network_id is network identity of target. + * @param is_client_when_true indicates whether this object should act as a client (true) + * or server (false), in terms of EAP-protocol whether this network entity is EAP-supplicant (true) + * or EAP-authenticator (false). + */ + virtual eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + * + * EAP-type should store it's parameters to an own database. The own database should be accessed + * through adaptation module of EAP-type. See eap_am_type_tls_peap_simulator_c::type_configure_read. + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + * + * EAP-type should store it's parameters to an own database. The own database should be accessed + * through adaptation module of EAP-type. See eap_am_type_tls_peap_simulator_c::type_configure_write. + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. EAP-type MUST send these + * two notifications to lower layer. + * These two notifications are sent using EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + * See also eap_state_notification_c. + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + /** + * This is needed by PEAP type. + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + /** + * This is needed by PEAP type. + * The unload_module() function unloads the module of a EAP-type. + * @param type is the requested EAP-type. + */ + virtual eap_status_e unload_module(const eap_type_value_e type) = 0; + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @see abs_eap_base_type_c::packet_data_crypto_keys(). + */ + virtual eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) = 0; + + /** + * This is needed by PEAP type. + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + /** + * The get_tls_master_secret() function copies the EAP-TLS master session key. + */ + virtual eap_status_e get_eap_tls_master_session_key( + eap_variable_data_c * const eap_tls_master_session_key, + eap_variable_data_c * const mschapv2_challenges + ) = 0; + + /** + * This function gets the TTLS implicit challenge from TLS. + */ + virtual eap_status_e get_ttls_implicit_challenge( + eap_variable_data_c * const ttls_implicit_challenge, + const u32_t required_ttls_implicit_challenge_length) = 0; + + virtual eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list) = 0; + + /** + * The set_session_timeout() function changes the session timeout timer to be elapsed after session_timeout_ms milliseconds. + */ + virtual eap_status_e set_session_timeout( + const u32_t session_timeout_ms) = 0; + +#if defined(USE_FAST_EAP_TYPE) + + virtual eap_status_e complete_query_tunnel_PAC( + const eap_status_e in_completion_status, + const eap_fast_pac_type_e in_pac_type, + const eap_fast_variable_data_c * const in_tunnel_PAC_key_tlv, + const eap_fast_variable_data_c * const in_tunnel_PAC_opaque_tlv) = 0; + +#endif //#if defined(USE_FAST_EAP_TYPE) + + + virtual eap_status_e query_ttls_pap_username_and_password( + const eap_variable_data_c * const reply_message) = 0; + + virtual eap_status_e verify_ttls_pap_username_and_password( + const eap_variable_data_c * const user_name, + const eap_variable_data_c * const user_password) = 0; + + // This is used in EAP-FAST to see the next TLS-handshake message protocol. + virtual tls_record_protocol_e get_next_tls_record_message_protocol() = 0; + + // This is used in EAP-FAST to see the next TLS-handshake message type. + virtual tls_handshake_type_e get_next_tls_handshake_message_type() = 0; + + //-------------------------------------------------- +}; // class abs_tls_base_application_c + +#endif //#if !defined(_ABS_TLS_BASE_APPLICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/abs_tls_base_record.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/abs_tls_base_record.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,305 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_TLS_BASE_RECORD_H_) +#define _ABS_TLS_BASE_RECORD_H_ + +#include "eap_header.h" +#include "tls_peap_types.h" + +class eap_buf_chain_wr_c; +class eap_variable_data_c; +class abs_eap_state_notification_c; +class abs_eap_base_timer_c; +class abs_eap_base_type_c; +class eap_base_type_c; +class eap_network_id_selector_c; +class eap_am_network_id_c; +class eap_rogue_ap_entry_c; +class eap_master_session_key_c; + + +/// The class is the interface to partner class of the tls_base_record_c class. +/// This declares the pure virtual member functions tls_base_record_c class could call. +class EAP_EXPORT abs_tls_base_record_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the abs_tls_base_record_c class does nothing special. + */ + virtual ~abs_tls_base_record_c() + { + } + + /** + * The constructor of the abs_tls_base_record_c class does nothing special. + */ + abs_tls_base_record_c() + { + } + + /** + * The derived class could send packets to partner class with this function. + * @param network_id carries the addresses (network identity) and type of the packet. + * @param sent_packet includes the buffer for the whole packet and initialized + * TLS-packet in correct offset. + * @param header_offset is offset of the TLS-header within the sent_packet. + * @param data_length is length in bytes of the TLS-packet. + * @param buffer_length is length in bytes of the whole packet buffer. + */ + virtual eap_status_e tls_peap_packet_send( + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length, + const bool includes_tls_handshake_message) = 0; + + /** + * The get_header_offset() function obtains the header offset of TLS-packet. + * @param MTU_length is pointer to variable to store the maximum transfer unit (MTU). + * MTU is the maximum TLS-packet length in bytes + * @param trailer_length is pointer to the variable to store length + * of trailer needed by lower levels. + * @return Function returns the offset of TLS-header. + * + * The needed buffer length is ((offset) + (TLS-packet length) + (trailer)) bytes. + * Each layer adds the length of the header to offset. + * Each layer removes the length of the header and trailer from MTU. + * + * Now some ascii graphics follows. + * @code + * |<-------------------------buffer length----------------------------------------->| + * | | + * | +-----+---------------------------------+ | + * | | TLS | data | | + * | +-----+---------------------------------+ | + * |<----offset--------------->|<----MTU------------------------------>|<--trailer-->| + * | | | | + * | | | | + * | +-----+---------------------------------------+ | + * | | EAP | data | | + * | +-----+---------------------------------------+ | + * |<----offset--------->|<----MTU------------------------------------>|<--trailer-->| + * | | | | + * | +-------+---------------------------------------------+ | + * | | EAPOL | data | | + * | +-------+---------------------------------------------+ | + * |<--offset--->|<----MTU-------------------------------------------->|<--trailer-->| + * | | | | + * +-------------+-----------------------------------------------------+-------------+ + * | ETHERNET | data | trailer | + * +-------------+-----------------------------------------------------+-------------+ + * |<----MTU------------------------------------------------------------------------>| + * @endcode + * + */ + virtual u32_t get_header_offset( + u32_t * const MTU_length, + u32_t * const trailer_length) = 0; + + /** + * This function restarts authentication to send_network_id. + * @param receive_network_id is network identity of source. + * @param is_client_when_true indicates whether this object should act as a client (true) + * or server (false), in terms of EAP-protocol whether this network entity is EAP-supplicant (true) + * or EAP-authenticator (false). + * @param force_clean_restart causes authentication restart even the current authentication is on going. + * @param from_timer indicates whether this was called from timer (true). + */ + virtual eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer) = 0; + + /** + * The set_tls_master_secret() function gives the generated master secret and random to lower level. + * @param eap_tls_master_session_key is pointer to the buffer of EAP-TLS master session key. + */ + virtual eap_status_e set_tls_master_secret( + const eap_variable_data_c * const eap_tls_master_session_key) = 0; + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + * + * EAP-type should store it's parameters to an own database. The own database should be accessed + * through adaptation module of EAP-type. See eap_am_type_tls_peap_simulator_c::type_configure_read. + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + * + * EAP-type should store it's parameters to an own database. The own database should be accessed + * through adaptation module of EAP-type. See eap_am_type_tls_peap_simulator_c::type_configure_write. + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. EAP-type MUST send these + * two notifications to lower layer. + * These two notifications are sent using EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + * See also eap_state_notification_c. + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + /** + * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) = 0; + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) = 0; + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers() = 0; + + /** + * This is needed by PEAP type. + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + /** + * This is needed by PEAP type. + * The unload_module() function unloads the module of a EAP-type. + * @param type is the requested EAP-type. + */ + virtual eap_status_e unload_module(const eap_type_value_e type) = 0; + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @param master_session_key is pointer to the first byte of the master session key. + * @param master_session_length is count of bytes in the master session key. + */ + virtual eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) = 0; + + /** + * This is needed by PEAP type. + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type) = 0; + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list) = 0; + + /** + * The set_session_timeout() function changes the session timeout timer to be elapsed after session_timeout_ms milliseconds. + */ + virtual eap_status_e set_session_timeout( + const u32_t session_timeout_ms) = 0; + + virtual eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list) = 0; + + virtual eap_status_e peap_tunnel_ready() = 0; + + virtual eap_status_e set_tls_session_type(const tls_session_type_e tls_session_type) = 0; + + //-------------------------------------------------- +}; // class abs_tls_base_record_c + +#endif //#if !defined(_ABS_TLS_BASE_RECORD_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/abs_tls_change_cipher_spec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/abs_tls_change_cipher_spec.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_TLS_CHANGE_CIPHER_SPEC_H_) +#define _ABS_TLS_CHANGE_CIPHER_SPEC_H_ + +#include "eap_am_export.h" + +/// This class declares the functions change cipher spec message class of TLS +/// requires from the TLS. +class EAP_EXPORT abs_tls_change_cipher_spec_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing. + virtual ~abs_tls_change_cipher_spec_c() + { + } + + /// Constructor does nothing. + abs_tls_change_cipher_spec_c() + { + } + + /** + * This function indicates the cipher spec must be changed. + */ + virtual eap_status_e change_cipher_spec(const bool send_when_true) = 0; + + //-------------------------------------------------- +}; // class abs_tls_change_cipher_spec_c + +#endif //#if !defined(_ABS_TLS_CHANGE_CIPHER_SPEC_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/abs_tls_message_hash.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/abs_tls_message_hash.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,92 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_TLS_MESSAGE_HASH_H_) +#define _ABS_TLS_MESSAGE_HASH_H_ + +#include "eap_am_export.h" + +/// This class declares the functions message classes of TLS +/// requires from the TLS. +class EAP_EXPORT abs_tls_message_hash_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing. + virtual ~abs_tls_message_hash_c() + { + } + + /// Constructor does nothing. + abs_tls_message_hash_c() + { + } + + /** + * This function adds the send and received TLS-handshake message to MD5 and SHA hashes. + * @param eap includes the buffer of the whole reassembled TLS-packet. + * @param packet_length is length in bytes of the TLS-packet. + */ + virtual eap_status_e message_hash_update( + const bool true_when_parse_message, + const tls_handshake_type_e type, + u8_t * const tls_packet, + const u32_t tls_packet_length) = 0; + + /** + * This function saves MD5 and SHA hashes for certificate verify message to + * member attributes m_message_hash_md5_certificate_verify and m_message_hash_sha1_certificate_verify. + */ + virtual eap_status_e message_hash_save_certificate_verify() = 0; + + /** + * This function saves MD5 and SHA hashes for finished message to + * member attributes message_hash_md5_finished and message_hash_sha1_finished. + */ + virtual eap_status_e message_hash_save_finished( + const bool client_originated) = 0; + + /** + * This function creates finished message hash. + * @param signed_message_hash is pointer to buffer of the message hash. + */ + virtual eap_status_e message_hash_create_finished( + const bool client_originated_message, + eap_variable_data_c * const signed_message_hash) = 0; + + //-------------------------------------------------- +}; // class abs_tls_message_hash_c + +#endif //#if !defined(_ABS_TLS_MESSAGE_HASH_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_alert_message.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_alert_message.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,139 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_ALERT_MESSAGE_H_) +#define _TLS_ALERT_MESSAGE_H_ + +#include "eap_tools.h" +#include "eap_array.h" +#include "tls_peap_types.h" + + +/** @file */ + + +/// This class defines one TLS alert message. +/** + * This class defines TLS-Alert message. + */ +class EAP_EXPORT tls_alert_message_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This is buffer for geneated TLS-Alert message. + eap_variable_data_c m_tls_alert_message_buffer; + + /// This is the alert level. + tls_alert_level_e m_alert_level; + + /// This is the alert description. + tls_alert_description_e m_alert_description; + + /// This indicates whether this object is client (true) or server (false). This mostly for traces. + bool m_is_client; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + //-------------------------------------------------- + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing. + EAP_FUNC_IMPORT virtual ~tls_alert_message_c(); + + /// Constructor initializes the object. + EAP_FUNC_IMPORT tls_alert_message_c( + abs_eap_am_tools_c * const tools, + const bool is_client); + + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + + /** + * This function creates data of the Handshake message to internal buffer. + * Later this data is added to final TLS-record buffer. + */ + EAP_FUNC_IMPORT eap_status_e create_message_data(); + + + + /** + * This function sets alert level. + */ + EAP_FUNC_IMPORT eap_status_e set_alert_level(const tls_alert_level_e alert_level); + + /** + * This function gets alert level. + */ + EAP_FUNC_IMPORT tls_alert_level_e get_alert_level() const; + + + /** + * This function sets alert description. + */ + EAP_FUNC_IMPORT eap_status_e set_alert_description(const tls_alert_description_e alert_description); + + /** + * This function gets alert description. + */ + EAP_FUNC_IMPORT tls_alert_description_e get_alert_description() const; + + + /** + * This function adds data of the TLS-Alert message to tls_message_buffer. + */ + EAP_FUNC_IMPORT eap_status_e add_message_data( + eap_variable_data_c * const tls_message_buffer); + + // + //-------------------------------------------------- +}; // class tls_alert_message_c + + +//-------------------------------------------------- + +#endif //#if !defined(_TLS_ALERT_MESSAGE_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_application_data_message.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_application_data_message.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,132 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_APPLICATION_DATA_MESSAGE_H_) +#define _TLS_APPLICATION_DATA_MESSAGE_H_ + +#include "eap_tools.h" +#include "eap_array.h" + +class eap_buf_chain_wr_c; + + +/** @file */ + +//---------------------------------------------------------------------------- + +/// This class defines one TLS application data message. +/** + * This class includes one application data message. + */ +class EAP_EXPORT tls_application_data_message_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + /// This attribute includes the application data. + eap_variable_data_c m_application_data; + + /// This indicates whether this object is client (true) or server (false). This mostly for traces. + bool m_is_client; + + /// This flag tells this message is analysed. + bool m_is_analysed; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + //-------------------------------------------------- + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor does nothing. + */ + EAP_FUNC_IMPORT virtual ~tls_application_data_message_c(); + + /** + * Constructor initializes the object. + */ + EAP_FUNC_IMPORT tls_application_data_message_c( + abs_eap_am_tools_c * const tools, + const bool is_client); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function sets this message is analysed. + */ + EAP_FUNC_IMPORT void set_is_analysed(); + + /** + * This function returns whether message is analysed (true) or not (false). + */ + EAP_FUNC_IMPORT bool get_is_analysed(); + + + /** + * This function stores the application data to m_application_data. + */ + EAP_FUNC_IMPORT eap_status_e set_application_data( + const u8_t * const packet, + const u32_t packet_length); + + /** + * This function returns pointer to m_application_data. + */ + EAP_FUNC_IMPORT eap_variable_data_c * get_application_data(); + + /** + * This function adds data of the TLS-Application data message from m_application_data to tls_message_buffer. + */ + EAP_FUNC_IMPORT eap_status_e add_message_data( + eap_variable_data_c * const tls_message_buffer); + + // + //-------------------------------------------------- +}; // class tls_application_data_message_c + + +//-------------------------------------------------- + +#endif //#if !defined(_TLS_APPLICATION_DATA_MESSAGE_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_application_eap_core.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_application_eap_core.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,668 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_APPLICATION_EAP_CORE_H_) +#define _TLS_APPLICATION_EAP_CORE_H_ + +#include "abs_eap_core.h" +#include "tls_base_application.h" +#include "tls_peap_types.h" +#include "tls_peap_tlv_header.h" +#include "tls_peap_tlv_payloads.h" +#include "eap_master_session_key.h" +#include "eap_diameter_payloads.h" + +class abs_tls_base_application_c; +class abs_eap_am_tools_c; +class eap_am_network_id_c; +class tls_record_header_c; +class eap_core_c; +class peap_tlv_payloads_c; +class eap_diameter_payloads_c; + + +/// The tls_application_eap_core_c class is a implementation of tls_base_application_c. +class EAP_EXPORT tls_application_eap_core_c +: public tls_base_application_c +, public abs_eap_core_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to EAP-core. + eap_core_c * m_eap_core; + + /// This flag tells whether the m_eap_core must be freed in destructor (true) or not (false). + const bool m_free_eap_core; + + /// This is pointer to TLS-application. + abs_tls_base_application_c * m_application_partner; + + /// This is network identity of the received packet. + eap_am_network_id_c m_receive_network_id; + + /// This is the EAP-type which creates the tunnel (PEAP or TTLS). + eap_type_value_e m_eap_type; + + /// This separates different PEAP versions (PEAPv2, PEAPv1 or XP PEAPv0). + peap_version_e m_peap_version; + + /// This is the EAP-type which is tunneled inside PEAP. + eap_type_value_e m_peap_tunneled_eap_type; + + /// This variable saves the state of the tunneled EAP-type. + /// State is changed during packet_process() and state_notification() function calls. + eap_state_variable_e m_tunneled_eap_type_authentication_state; + + + peap_tlv_payloads_c m_peapv2_tlv_payloads; + + eap_variable_data_c m_peap_v2_client_nonce; + + eap_variable_data_c m_peap_v2_server_nonce; + + eap_variable_data_c m_peap_v2_IPMKn; + + eap_variable_data_c m_peap_v2_ISKn; + + eap_variable_data_c m_peap_v2_CMK_B1_server; + + eap_variable_data_c m_peap_v2_CMK_B2_client; + + eap_master_session_key_c m_peap_v2_CSK; + + + eap_array_c m_accepted_tunneled_eap_types; + + eap_variable_data_c m_pseudo_ethernet_header; + + eap_diameter_payloads_c m_ttls_received_payloads; + + eap_ttls_tunneled_message_type_e m_ttls_message_type; + + + eap_variable_data_c m_ttls_sent_eap_packet; + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + eap_variable_data_c m_ttls_user_name; + + eap_variable_data_c m_ttls_implicit_challenge; + + eap_ttls_tunneled_message_state_e m_ttls_tunneled_message_state; + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + + u32_t m_error_probability; + + u8_t m_received_eap_identifier; + + /// This flag activates error manipulation to send tunneled packets. + bool m_enable_random_errors; + + /// This flag activates error manipulation to send tunneled packets. + bool m_manipulate_only_tunneled_messages; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This indicates whether this object is client (true) or server (false). + /// In terms of EAP-protocol whether this network entity is EAP-supplicant (true) or EAP-authenticator (false). + bool m_is_client; + + /// This flag tells whether the shutdown() function was called (true) or not (false). + bool m_shutdown_was_called; + + tls_session_type_e m_tls_session_type; + + bool m_peap_allow_tunneled_session_resumption; + + /// This configurable option selects whether the special style of TLS/PEAP + /// is used, the length field is added to all message fragments + /// even the message fits to one fragment except EAP-TLS-start, EAP-TLS-Acknowledge and + /// PEAP-application data. The client acknowledges tunneled EAP-Success message + /// with empty PEAP message. + bool m_use_tppd_tls_peap; + + /// On fast session resume server does not send tunneled EAP-Success. + /// Instead it sends plain EAP-Success. + /// True value of this flag allows this plain EAP-Success. + bool m_use_tppd_peapv1_acknowledge_hack; + + +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + bool m_server_use_peapv1_extensions_request; + bool m_client_send_peapv1_extensions_response; +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + bool m_tunneled_eap_in_ttls; + + u8_t m_ttls_plain_ms_chap_v2_eap_identifier; + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + bool m_use_eap_expanded_type; + + bool m_wait_plain_eap_success; + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT eap_status_e create_eap_success_failure_in_forward_to_tunnel( + const eap_am_network_id_c * const receive_network_id, + const eap_code_value_e forwarded_eap_code, + const u8_t received_eap_identifier); + + EAP_FUNC_IMPORT eap_status_e check_ttls_eap_payloads( + eap_diameter_payloads_c * const payloads, + eap_ttls_tunneled_message_type_e * const message_type); + + + EAP_FUNC_IMPORT eap_status_e ttls_server_handles_pap_response( + eap_diameter_payloads_c * const payloads, + const u8_t received_eap_identifier); + + EAP_FUNC_IMPORT eap_status_e ttls_server_handles_pap_reply_message( + eap_diameter_payloads_c * const payloads, + const u8_t received_eap_identifier); + + EAP_FUNC_IMPORT eap_status_e check_ttls_plain_pap_payloads( + eap_diameter_payloads_c * const payloads, + eap_ttls_tunneled_message_type_e * const message_type); + + EAP_FUNC_IMPORT eap_status_e handle_ttls_plain_pap_payloads( + eap_diameter_payloads_c * const payloads, + const eap_ttls_tunneled_message_type_e message_type, + const u8_t received_eap_identifier); + + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + EAP_FUNC_IMPORT eap_status_e create_ttls_diameter_avp( + eap_variable_data_c * const avp, + const eap_variable_data_c * const data, + eap_diameter_avp_code_c code, + const bool include_vendor_id); + + + EAP_FUNC_IMPORT eap_status_e check_ttls_plain_mschapv2_payloads( + eap_diameter_payloads_c * const payloads, + eap_ttls_tunneled_message_type_e * const message_type); + + EAP_FUNC_IMPORT eap_status_e handle_ttls_plain_mschapv2_payloads( + eap_diameter_payloads_c * const payloads, + const eap_ttls_tunneled_message_type_e message_type, + const u8_t received_eap_identifier); + + + EAP_FUNC_IMPORT eap_status_e ttls_server_handles_ms_chapv2_response( + eap_diameter_payloads_c * const payloads, + const u8_t received_eap_identifier); + + EAP_FUNC_IMPORT eap_status_e ttls_server_handles_ms_chapv2_change_password( + eap_diameter_payloads_c * const payloads, + const u8_t received_eap_identifier); + + EAP_FUNC_IMPORT eap_status_e ttls_client_handles_ms_chapv2_success( + eap_diameter_payloads_c * const payloads, + const u8_t received_eap_identifier); + + EAP_FUNC_IMPORT eap_status_e ttls_client_handles_ms_chapv2_error( + eap_diameter_payloads_c * const payloads, + const u8_t received_eap_identifier); + + + EAP_FUNC_IMPORT eap_status_e send_ttls_ms_chapv2_packet( + eap_header_wr_c * const sent_eap_packet); + + + EAP_FUNC_IMPORT eap_status_e ttls_tunneled_message_state_process_identity_response( + eap_header_wr_c * const sent_eap_packet); + + EAP_FUNC_IMPORT eap_status_e ttls_tunneled_message_state_process_response( + eap_header_wr_c * const sent_eap_packet); + + EAP_FUNC_IMPORT eap_status_e ttls_tunneled_message_state_process_change_password_response( + eap_header_wr_c * const sent_eap_packet); + + EAP_FUNC_IMPORT eap_status_e ttls_tunneled_message_state_process_identity_request( + eap_header_wr_c * const sent_eap_packet); + + EAP_FUNC_IMPORT eap_status_e ttls_tunneled_message_state_process_challenge_request( + eap_header_wr_c * const sent_eap_packet); + + EAP_FUNC_IMPORT eap_status_e ttls_tunneled_message_state_process_success_request( + eap_header_wr_c * const sent_eap_packet); + + EAP_FUNC_IMPORT eap_status_e ttls_tunneled_message_state_complete_success_request( + eap_header_wr_c * const sent_eap_packet); + + EAP_FUNC_IMPORT eap_status_e ttls_tunneled_message_state_process_error_request( + eap_header_wr_c * const sent_eap_packet); + + EAP_FUNC_IMPORT eap_status_e ttls_tunneled_message_state_complete_error_request( + eap_header_wr_c * const sent_eap_packet); + + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + + /** + * This function processes the received packet of TTLS. + * @param packet includes the received packet. + * @param received_eap_identifier is the EAP-identifier field of the PEAP packet. + * @param forwarded_eap_packet includes created EAP-packet that is forwarded to eap_core_c object. + */ + EAP_FUNC_IMPORT eap_status_e packet_process_ttls( + eap_variable_data_c * const received_eap_message, + const u8_t received_eap_identifier, + u32_t * const eap_packet_length); + + /** + * This function processes the received packet of XP PEAPv0. + * @param packet includes the received packet. + * @param received_eap_identifier is the EAP-identifier field of the PEAP packet. + * @param forwarded_eap_packet includes created EAP-packet that is forwarded to eap_core_c object. + */ + EAP_FUNC_IMPORT eap_status_e packet_process_xp_peap_v0( + eap_variable_data_c * const packet, + const u8_t received_eap_identifier, + u32_t * const eap_packet_length); + + /** + * This function processes the received packet of PEAPv1. + */ + EAP_FUNC_IMPORT eap_status_e packet_process_peap_v1( + eap_variable_data_c * const received_eap_message, + const u8_t received_eap_identifier, + u32_t * const eap_packet_length); + + EAP_FUNC_IMPORT eap_status_e finish_successfull_authentication_peap_v2( + const u8_t received_eap_identifier); + + EAP_FUNC_IMPORT eap_status_e store_nonce_peap_v2( + const bool is_client_when_true, + peap_tlv_payloads_c * const peapv2_tlv_payloads); + + /** + * This function processes the received packet of PEAPv2. + * @param packet includes the received packet. + * @param received_eap_identifier is the EAP-identifier field of the PEAP packet. + * @param forwarded_eap_packet includes created EAP-packet that is forwarded to eap_core_c object. + */ + EAP_FUNC_IMPORT eap_status_e packet_process_peap_v2( + eap_variable_data_c * const packet, + const u8_t received_eap_identifier, + u32_t * const eap_packet_length); + + /** + * This function verifies the previously received and parsed packet of PEAPv2. + */ + EAP_FUNC_IMPORT eap_status_e verify_tunneled_acknowledge_peap_v2(); + + + /** + * This function sends XP-PEAPv0 protected EAP-Success or EAP-Failure messages. + */ + EAP_FUNC_IMPORT eap_status_e send_tunneled_acknowledge_xp_peap_v0( + const eap_code_value_e result_eap_code, + const u8_t eap_identifier); + + /** + * This function sends PEAPv2 protected EAP-Success or EAP-Failure messages. + */ + EAP_FUNC_IMPORT eap_status_e send_tunneled_acknowledge_peap_v2( + const eap_code_value_e result_eap_code, + const u8_t eap_identifier); + + + EAP_FUNC_IMPORT eap_status_e create_nonce( + eap_variable_data_c * const nonce); + + EAP_FUNC_IMPORT eap_status_e create_nonce_peap_v2( + const bool create_client_nonce_when_true); + + EAP_FUNC_IMPORT eap_status_e create_compound_mac_key_peap_v2( + const bool create_client_CMK_when_true); + + EAP_FUNC_IMPORT eap_status_e create_compound_session_key_peap_v2(); + + + EAP_FUNC_IMPORT eap_status_e create_crypto_binding_compound_mac( + const eap_variable_data_c * const peap_v2_CMK, + const tls_peap_tlv_header_c * const crypto_binding_tlv, + eap_variable_data_c * const mac_data); + + + EAP_FUNC_IMPORT eap_status_e create_result_tlv_message( + eap_buf_chain_wr_c * const packet, + const eap_code_value_e result_eap_code, + const u8_t eap_identifier, + const tls_peap_tlv_type_e tlv_type); + + EAP_FUNC_IMPORT eap_status_e create_intermediate_result_tlv_message( + eap_buf_chain_wr_c * const packet, + const eap_code_value_e result_eap_code, + const u8_t eap_identifier); + + EAP_FUNC_IMPORT eap_status_e create_eap_payload_tlv_message( + eap_buf_chain_wr_c * const packet, + const eap_header_wr_c * const sent_eap_packet, + const u8_t eap_identifier); + + EAP_FUNC_IMPORT eap_status_e create_crypto_binding_tlv_message( + eap_buf_chain_wr_c * const packet, + const eap_code_value_e result_eap_code, + const u8_t eap_identifier, + const eap_variable_data_c * const nonce, + const u8_t received_version); + + EAP_FUNC_IMPORT eap_status_e create_eap_diameter_avp_message( + eap_buf_chain_wr_c * const packet, + const eap_header_wr_c * const sent_eap_packet, + const u8_t eap_identifier); + + EAP_FUNC_IMPORT eap_status_e parse_generic_payload( + const tls_peap_tlv_type_e current_payload, + const tls_peap_tlv_header_c * const payload, + peap_tlv_payloads_c * const p_peap_tlv_payloads); + + EAP_FUNC_IMPORT eap_status_e parse_peap_tlv_payload( + u8_t * const buffer, + u32_t * const buffer_length, + peap_tlv_payloads_c * const peap_tlv_payloads); + + EAP_FUNC_IMPORT void trace_tunneled_packet( + eap_const_string prefix, + const eap_header_wr_c * const eap_packet); + + EAP_FUNC_IMPORT eap_status_e packet_forward_to_tunnel( + const eap_am_network_id_c * const receive_network_id, + eap_header_wr_c * const forwarded_eap_packet, + const u32_t eap_packet_length); + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + eap_ttls_tunneled_message_state_e get_ttls_tunneled_message_state(); + + void set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_e ttls_state); + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the tls_application_eap_core_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~tls_application_eap_core_c(); + + /** + * The constructor of the tls_application_eap_core_c class simply initializes the attributes. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + * @param partner is back pointer to object which created this object. + * @param eap_core is pointer to EAP-core object. + * The tls_application_eap_core_c object sends packets to the network using m_type_partner object. + */ + EAP_FUNC_IMPORT tls_application_eap_core_c( + abs_eap_am_tools_c * const tools, + eap_core_c * const eap_core, + const bool free_eap_core, + const bool is_client_when_true, + const eap_type_value_e eap_type, + const eap_am_network_id_c * const receive_network_id); + + /** + * This function sets the PEAP version. + */ + EAP_FUNC_IMPORT void set_peap_version( + const peap_version_e peap_version, + const bool use_tppd_tls_peap, + const bool use_tppd_peapv1_acknowledge_hack); + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + */ + EAP_FUNC_IMPORT eap_status_e configure(); + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + EAP_FUNC_IMPORT eap_status_e shutdown(); + + /** + * This function processes the received packet. + * @param packet includes the received packet. + * @param received_eap_identifier is the EAP-identifier field of the PEAP packet. + */ + EAP_FUNC_IMPORT eap_status_e packet_process( + eap_variable_data_c * const packet, + const u8_t received_eap_identifier); + + /** + * This function indicates the plain text EAP-Success or EAP-Failure packet is received. + * @param receive_network_id includes the addresses (network identity) and packet type. + * @param received_eap_identifier is the EAP-Identifier of the received EAP-Success packet. + */ + EAP_FUNC_IMPORT eap_status_e plain_eap_success_failure_packet_received( + const eap_am_network_id_c * const receive_network_id, + const eap_code_value_e received_eap_code, + const u8_t received_eap_identifier); + + /** + * This function indicates the empty Ack packet is received. + * This is used in TTLS. + * @param receive_network_id includes the addresses (network identity) and packet type. + * @param received_eap_identifier is the EAP-Identifier of the received EAP-Success packet. + */ + EAP_FUNC_IMPORT eap_status_e empty_ack_packet_received( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier); + + /** + * This function starts TTLS tunneled authentication. + */ + EAP_FUNC_IMPORT eap_status_e start_ttls_tunneled_authentication( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function must reset the state of object to same as + * state was after the configure() function call. + * If object reset succeeds this function must return eap_status_ok. + * If object reset fails this function must return corresponding error status. + * @return This function returns the status of reset operation. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + + /** + * This function starts the tunneled EAP-type within PEAP. + */ + EAP_FUNC_IMPORT eap_status_e start_peap_tunneled_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const u8_t received_eap_identifier, + const tls_session_type_e tls_session_type, + const bool tls_peap_server_authenticates_client_action); + + /// @see abs_eap_core_c::packet_send(). + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + /// @see abs_eap_core_c::get_header_offset(). + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + /// @see abs_eap_core_c::load_module(). + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + /// @see abs_eap_core_c::unload_module(). + EAP_FUNC_IMPORT eap_status_e unload_module(const eap_type_value_e type); + + /// @see abs_eap_core_c::restart_authentication(). + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer = false); + + /// @see abs_eap_core_c::packet_data_crypto_keys(). + EAP_FUNC_IMPORT eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ); + + /// @see abs_eap_core_c::read_configure(). + EAP_FUNC_IMPORT eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /// @see abs_eap_core_c::write_configure(). + EAP_FUNC_IMPORT eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /// @see abs_eap_core_c::state_notification(). + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state); + + /// @see abs_eap_core_c::asynchronous_init_remove_eap_session(). + EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id); + + /// @see abs_eap_core_c::set_timer(). + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms); + + /// @see abs_eap_core_c::cancel_timer(). + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id); + + /// @see abs_eap_core_c::cancel_all_timers(). + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + /// @see abs_eap_core_c::check_is_valid_eap_type(). + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + /// @see abs_eap_core_c::get_eap_type_list(). + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + /// @see tls_base_application_c::get_application_partner(). + EAP_FUNC_IMPORT abs_tls_base_application_c * get_application_partner(); + + /// @see tls_base_application_c::set_application_partner(). + EAP_FUNC_IMPORT eap_status_e set_application_partner(abs_tls_base_application_c * const partner); + + /// @see tls_base_application_c::peap_tunnel_ready(). + EAP_FUNC_IMPORT eap_status_e peap_tunnel_ready(); + + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + // This is documented in tls_base_application_c::set_session_timeout(). + EAP_FUNC_IMPORT eap_status_e set_session_timeout( + const u32_t session_timeout_ms); + + EAP_FUNC_IMPORT void set_tunneled_state( + const tls_session_type_e tls_session_type); + + // This is commented in tls_base_record_c::read_authority_identity(). + EAP_FUNC_IMPORT eap_status_e read_authority_identity(eap_variable_data_c * const authority_identity_payload); + + // This is commented in tls_base_record_c::save_user_authorization_pac_opaque(). + EAP_FUNC_IMPORT eap_status_e save_user_authorization_pac_opaque(const tls_extension_c * const extension); + + // This is commented in tls_base_record_c::query_tunnel_PAC(). + EAP_FUNC_IMPORT eap_status_e query_tunnel_PAC( + const eap_fast_variable_data_c * const in_A_ID_TLV); + + // This is commented in tls_base_record_c::cancel_query_tunnel_PAC(). + EAP_FUNC_IMPORT eap_status_e cancel_query_tunnel_PAC(); + + EAP_FUNC_IMPORT eap_status_e complete_query_ttls_pap_username_and_password( + const eap_variable_data_c * const ttls_pap_username, + const eap_variable_data_c * const ttls_pap_password, + const eap_status_e query_result); + + EAP_FUNC_IMPORT eap_status_e complete_verify_ttls_pap_username_and_password( + const eap_status_e authentication_result, + const eap_variable_data_c * const ttls_pap_reply_message); + + /** + * This function is called when TLS-Alert message is received. + * Adaptation module could record this event. + */ + EAP_FUNC_IMPORT eap_status_e alert_received( + const tls_alert_level_e alert_level, + const tls_alert_description_e alert_description); + + //-------------------------------------------------- +}; // class tls_application_eap_core_c + +#endif //#if !defined(_TLS_APPLICATION_EAP_CORE_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_base_application.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_base_application.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,217 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_BASE_APPLICATION_H_) +#define _TLS_BASE_APPLICATION_H_ + +#include "tls_peap_types.h" +#include "eap_header.h" +#include "eap_protocol_layer.h" + +class abs_tls_base_application_c; +class abs_eap_am_tools_c; +class eap_am_network_id_c; +class tls_record_header_c; +class abs_eap_state_notification_c; +class tls_extension_c; +class eap_fast_variable_data_c; + + +/// The tls_base_application_c class declares pure virtual functions +/// a user class of TLS-application class could call. +class EAP_EXPORT tls_base_application_c +{ +private: + //-------------------------------------------------- + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor does nothing special. + */ + virtual ~tls_base_application_c(); + + /** + * Application partner is object below the tls_base_application_c object. + * @return The get_application_partner() function returns the pointer to the partner class. + */ + virtual abs_tls_base_application_c * get_application_partner() = 0; + + /** + * This function sets pointer to the partner class. + * The partner that instantiates object of this type must call this function + * to tell pointer to partner of this object. + */ + virtual eap_status_e set_application_partner(abs_tls_base_application_c * const partner) = 0; + + /** + * This function sets the PEAP version. + */ + virtual void set_peap_version( + const peap_version_e peap_version, + const bool use_tppd_tls_peap, + const bool use_tppd_peapv1_acknowledge_hack) = 0; + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + */ + virtual eap_status_e configure() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + /** + * This function starts the tunneled EAP-type within PEAP. + */ + virtual eap_status_e start_peap_tunneled_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const u8_t received_eap_identifier, + const tls_session_type_e tls_session_type, + const bool tls_peap_server_authenticates_client_action) = 0; + + /** + * This function processes the received packet. + * @param receive_network_id carries the addresses and type of the received packet. + * @param packet includes the buffer of the whole reassembled EAP-packet. + */ + virtual eap_status_e packet_process( + eap_variable_data_c * const packet, + const u8_t received_eap_identifier) = 0; + + /** + * This function indicates the plain text EAP-Success or EAP-Failure packet is received. + * @param receive_network_id includes the addresses (network identity) and packet type. + * @param received_eap_identifier is the EAP-Identifier of the received EAP-Success packet. + */ + virtual eap_status_e plain_eap_success_failure_packet_received( + const eap_am_network_id_c * const receive_network_id, + const eap_code_value_e received_eap_code, + const u8_t received_eap_identifier) = 0; + + /** + * This function indicates the empty Ack packet is received. + * This is used in TTLS. + * @param receive_network_id includes the addresses (network identity) and packet type. + * @param received_eap_identifier is the EAP-Identifier of the received EAP-Success packet. + */ + virtual eap_status_e empty_ack_packet_received( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier) = 0; + + /** + * This function starts TTLS tunneled authentication. + */ + virtual eap_status_e start_ttls_tunneled_authentication( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier) = 0; + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + virtual bool get_is_valid() = 0; + + /** + * This function resets the reused tls_base_application_c object. + */ + virtual eap_status_e reset() = 0; + + virtual eap_status_e peap_tunnel_ready() = 0; + + /** + * This is notification of internal state transition. + * This is used for telling tunneled EAP-type the TLS/PEAP-session was resumed. + */ + virtual void set_tunneled_state( + const tls_session_type_e tls_session_type) = 0; + + /** + * This function reads the authority identity (A-ID) of server. + * This is used in EAP-FAST. + */ + virtual eap_status_e read_authority_identity( + eap_variable_data_c * const authority_identity_payload) = 0; + + /** + * This function saves the received User Authorization PAC-Opaque. + * This is used in EAP-FAST. + */ + virtual eap_status_e save_user_authorization_pac_opaque(const tls_extension_c * const extension) = 0; + + /** + * Function queries tunnel PAC TLV for A-ID. + * This function is completed by complete_query_tunnel_PAC() function call. + */ + virtual eap_status_e query_tunnel_PAC( + const eap_fast_variable_data_c * const in_A_ID_TLV) = 0; + + /** + * Function cancels query of tunnel PAC TLV for A-ID. + */ + virtual eap_status_e cancel_query_tunnel_PAC() = 0; + + virtual eap_status_e complete_query_ttls_pap_username_and_password( + const eap_variable_data_c * const ttls_pap_username, + const eap_variable_data_c * const ttls_pap_password, + const eap_status_e query_result) = 0; + + virtual eap_status_e complete_verify_ttls_pap_username_and_password( + const eap_status_e authentication_result, + const eap_variable_data_c * const ttls_pap_reply_message) = 0; + + /** + * This function is called when TLS-Alert message is received. + * TLS-application module could record this event. + */ + virtual eap_status_e alert_received( + const tls_alert_level_e alert_level, + const tls_alert_description_e alert_description) = 0; + + //-------------------------------------------------- +}; // class tls_base_application_c + +#endif //#if !defined(_TLS_BASE_APPLICATION_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_base_record.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_base_record.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,185 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_BASE_RECORD_H_) +#define _TLS_BASE_RECORD_H_ + + +#include "tls_peap_types.h" +#include "eap_array.h" +#include "eap_header.h" + +class abs_tls_base_record_c; +class abs_eap_am_tools_c; +class eap_am_network_id_c; +class tls_record_header_c; +class eap_rogue_ap_entry_c; + + +/// The tls_base_record_c class declares pure virtual functions +/// a user class of TLS-record class could call. +class EAP_EXPORT tls_base_record_c +{ +private: + //-------------------------------------------------- + + /// This is back pointer to object which created this object. + /// The tls_base_record_c object sends packets to the network using m_type_partner object. + /// @see abs_tls_base_record_c. + abs_tls_base_record_c *m_type_partner; + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + virtual void set_is_valid() = 0; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the tls_base_record_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~tls_base_record_c(); + + /** + * The constructor of the tls_base_record_c class simply initializes the attributes. + * @param tools is pointer to the tools class. @see abs_eap_am_tools_c. + * @param partner is back pointer to object which created this object. + * The tls_base_record_c object sends packets to the network using m_type_partner object. + */ + EAP_FUNC_IMPORT tls_base_record_c( + abs_eap_am_tools_c * const tools /*, + abs_tls_base_record_c * const partner */); + + /** + * Type partner is object below the tls_base_record_c object. + * @return The get_type_partner() function returns the pointer to the partner class. + */ + EAP_FUNC_IMPORT abs_tls_base_record_c * get_type_partner(); + + EAP_FUNC_IMPORT void set_type_partner(abs_tls_base_record_c * const partner); + + virtual void set_peap_version( + const peap_version_e peap_version, ///< This is the PEAP version (PEAPv2, PEAPv1, XP PEAPv0), yes very nice to have many different versions. + const bool use_tppd_tls_peap, ///< Of course some vendors have own TLS/PEAP quirks. + const bool use_tppd_peapv1_acknowledge_hack) = 0; + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + */ + virtual eap_status_e configure() = 0; + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + virtual eap_status_e shutdown() = 0; + + /** + * This function sets the NAI realm. + */ + virtual eap_status_e set_nai_realm(const eap_variable_data_c * const NAI_realm) = 0; + + /** + * This function sends starts EAP-TLS/PEAP after a start message is received. + */ + virtual eap_status_e start_tls_peap_authentication( + const eap_variable_data_c * const received_authority_identity_payload + ) = 0; + + /** + * This function starts the tunneled EAP-type within PEAP. + */ + virtual eap_status_e start_peap_tunneled_authentication( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier, + const tls_session_type_e tls_session_type) = 0; + + /** + * This function processes the received packet. + * @param tls_packet points to the buffer of the whole reassembled TLS-packet. + */ + virtual eap_status_e packet_process( + eap_variable_data_c * const tls_packet, + const u8_t received_eap_identifier) = 0; + + /** + * This function indicates the plain text EAP-Success or EAP-Failure packet is received. + * @param receive_network_id includes the addresses (network identity) and packet type. + * @param received_eap_identifier is the EAP-Identifier of the received EAP-Success packet. + */ + virtual eap_status_e plain_eap_success_failure_packet_received( + const eap_am_network_id_c * const receive_network_id, + const eap_code_value_e received_eap_code, + const u8_t received_eap_identifier) = 0; + + /** + * This function indicates the empty Ack packet is received. + * This is used in TTLS. + * @param receive_network_id includes the addresses (network identity) and packet type. + * @param received_eap_identifier is the EAP-Identifier of the received EAP-Success packet. + */ + virtual eap_status_e empty_ack_packet_received( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier) = 0; + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + virtual bool get_is_valid() = 0; + + /** + * This function resets the reused tls_base_record_c object. + */ + virtual eap_status_e reset() = 0; + + virtual eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list) = 0; + + /** + * This function reads the authority identity (A-ID) of server. + * This is used in EAP-FAST. + */ + virtual eap_status_e read_authority_identity(eap_variable_data_c * const authority_identity_payload) = 0; + + //-------------------------------------------------- +}; // class tls_base_record_c + +#endif //#if !defined(_TLS_BASE_RECORD_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_change_cipher_spec_message.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_change_cipher_spec_message.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,139 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_CHANGE_CIPHER_SPEC_MESSAGE_H_) +#define _TLS_CHANGE_CIPHER_SPEC_MESSAGE_H_ + +#include "eap_tools.h" +#include "eap_array.h" +#include "abs_tls_change_cipher_spec.h" + + +/** @file */ + +/** + * This is enumeration of change cipher spec messages. + */ +enum tls_change_cipher_spec_type_e +{ + tls_change_cipher_spec_type_change_cipher_spec = (1), ///< This is the only one that is defined. + tls_change_cipher_spec_type_none = (255), ///< This is initialization value that means no type is defined. + }; + +//---------------------------------------------------------------------------- + +/// This class defines one TLS change cipher spec message. +/** + * This class includes data of TLS-ChangeCipherSpec message. + */ +class EAP_EXPORT tls_change_cipher_spec_message_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to interface of TLS-record. + /// Interface includes function to inform change cipher spec related events. + abs_tls_change_cipher_spec_c * m_change_cipher_spec; + + /// This buffer includes data of TLS-ChangeCipherSpec message. + eap_variable_data_c m_tls_change_cipher_spec_message_buffer; + + tls_change_cipher_spec_type_e m_type; + + /// This indicates whether this object is client (true) or server (false). This mostly for traces. + bool m_is_client; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + //-------------------------------------------------- + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~tls_change_cipher_spec_message_c(); + + /** + * Constructor initializes class. + */ + EAP_FUNC_IMPORT tls_change_cipher_spec_message_c( + abs_eap_am_tools_c * const tools, + abs_tls_change_cipher_spec_c * const change_cipher_spec, + const bool is_client); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function creates data of the Handshake message to internal buffer. + * Later this data is added to final TLS-record buffer. + */ + EAP_FUNC_IMPORT eap_status_e create_message_data(); + + + /** + * This function sets the change cipher spec message type. + */ + EAP_FUNC_IMPORT eap_status_e set_change_cipher_spec_type(tls_change_cipher_spec_type_e type); + + /** + * This function gets the change cipher spec message type. + */ + EAP_FUNC_IMPORT tls_change_cipher_spec_type_e get_change_cipher_spec_type() const; + + /** + * This function adds data of the TLS-CahneCipherSpec data message from m_tls_change_cipher_spec_message_buffer to tls_message_buffer. + */ + EAP_FUNC_IMPORT eap_status_e add_message_data( + eap_variable_data_c * const tls_message_buffer); + + // + //-------------------------------------------------- +}; // class tls_change_cipher_spec_message_c + + +//-------------------------------------------------- + +#endif //#if !defined(_TLS_CHANGE_CIPHER_SPEC_MESSAGE_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_completion.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_completion.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,140 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_COMPLETION_H_) +#define _TLS_COMPLETION_H_ + +#include "eap_tools.h" +#include "eap_array.h" +#include "tls_record_message.h" +#include "abs_tls_message_hash.h" + +/** @file */ + +/** + * This is enumeration of TLS competion actions. + */ +enum tls_completion_action_e +{ + tls_completion_action_none, ///< Initialization value means no action. + tls_completion_action_create_handshake_type_hello_request, ///< create_handshake_type_hello_request + tls_completion_action_create_handshake_type_client_hello, ///< create_handshake_type_client_hello + tls_completion_action_create_handshake_type_server_hello, ///< create_handshake_type_server_hello + tls_completion_action_create_handshake_type_certificate, ///< create_handshake_type_certificate + tls_completion_action_create_handshake_type_server_key_exchange, ///< create_handshake_type_server_key_exchange + tls_completion_action_create_handshake_type_certificate_request, ///< create_handshake_type_certificate_request + tls_completion_action_create_handshake_type_server_hello_done, ///< create_handshake_type_server_hello_done + tls_completion_action_create_handshake_type_certificate_verify, ///< create_handshake_type_certificate_verify + tls_completion_action_create_handshake_type_client_key_exchange, ///< create_handshake_type_client_key_exchange + tls_completion_action_create_handshake_type_finished, ///< create_handshake_type_finished + tls_completion_action_finish_handshake, ///< finish_handshake +#if defined(USE_EAP_TLS_SESSION_TICKET) + tls_completion_action_create_handshake_type_new_session_ticket, ///< create_handshake_type_new_session_ticket +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + tls_completion_action_create_change_cipher_spec_type_change_cipher_spec, ///< create_change_cipher_spec_type_change_cipher_spec + tls_completion_action_query_dh_parameters, ///< query_dh_parameters + tls_completion_action_verify_certificate_chain, ///< verify_certificate_chain + tls_completion_action_process_tls_records, ///< process_tls_records + tls_completion_action_check_sent_tls_message, ///< check_sent_tls_message + tls_completion_action_complete_create_handshake_type_server_key_exchange, ///< complete_create_handshake_type_server_key_exchange + tls_completion_action_complete_create_handshake_type_certificate_verify, ///< complete_create_handshake_type_certificate_verify + tls_completion_action_complete_create_handshake_type_client_key_exchange, ///< complete_create_handshake_type_client_key_exchange + tls_completion_action_query_cipher_suites_and_previous_session, ///< query_cipher_suites_and_previous_session + tls_completion_action_check_tunnel_authentication_runs, ///< check_tunnel_authentication_runs +}; + +//---------------------------------------------------------------------------- + + +/// This class defines one TLS completion action. +class EAP_EXPORT tls_completion_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This variable stores the completion action. + tls_completion_action_e m_completion_action; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~tls_completion_c(); + + /** + * Constructor initializes object. + */ + EAP_FUNC_IMPORT tls_completion_c( + abs_eap_am_tools_c * const tools, + tls_completion_action_e completion_action); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function sets the completion action type. + */ + EAP_FUNC_IMPORT void set_completion_action(tls_completion_action_e completion_action); + + /** + * This function gets the completion action type. + */ + EAP_FUNC_IMPORT tls_completion_action_e get_completion_action() const; + + /** + * This function gets the debug string of the completion action type. + */ + EAP_FUNC_IMPORT eap_const_string get_completion_action_string() const; + + // + //-------------------------------------------------- +}; // class tls_completion_c + + +//-------------------------------------------------- + +#endif //#if !defined(_TLS_COMPLETION_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_extension.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_extension.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,179 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_EXTENSION_H_) +#define _TLS_EXTENSION_H_ + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +#include "eap_tools.h" +#include "eap_array.h" +#include "eap_variable_data.h" +#if defined(USE_FAST_EAP_TYPE) +#include "eap_fast_tlv_header.h" +#endif //#if defined(USE_FAST_EAP_TYPE) + +/** @file */ + +/** + * This is enumeration of TLS competion actions. + */ +enum tls_extension_type_e +{ + tls_extension_type_none = 65535, ///< Initialization value means no type. + tls_extension_type_server_name = 0, ///< Server Name Indication, see RFC 4366 + tls_extension_type_max_frame_length = 1, ///< Maximum Fragment Length Negotiation, see RFC 4366 + tls_extension_type_client_certificate_url = 2, ///< Client Certificate URLs, see RFC 4366 + tls_extension_type_trusted_ca_keys = 3, ///< Trusted CA Indication, see RFC 4366 + tls_extension_type_truncated_hmac = 4, ///< Truncated HMAC, see RFC 4366 + tls_extension_type_status_request = 5, ///< Certificate Status Request, see RFC 4366 + tls_extension_type_session_ticket = 35, ///< Session Ticket, see RFC 4507 +}; + +//---------------------------------------------------------------------------- + + +/// This class defines one TLS completion action. +class EAP_EXPORT tls_extension_c +: public eap_variable_data_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This variable stores the lifetime hint of extension. + u32_t m_lifetime_hint; + + /// This variable stores the type of extension. + tls_extension_type_e m_type; + +#if defined(USE_FAST_EAP_TYPE) + /// This variable stores the PAC-Type for fast access. + eap_fast_pac_type_e m_pac_type; +#endif //#if defined(USE_FAST_EAP_TYPE) + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~tls_extension_c(); + + /** + * Constructor initializes object. + */ + EAP_FUNC_IMPORT tls_extension_c( + abs_eap_am_tools_c * const tools); + + /** + * Function copies the object. + */ + tls_extension_c * copy() const; + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function sets the extension lifitime hint. + */ + EAP_FUNC_IMPORT void set_lifetime_hint(const u32_t lifetime_hint); + + /** + * This function gets the extension lifetime hint. + */ + EAP_FUNC_IMPORT u32_t get_lifetime_hint() const; + + /** + * This function sets the extension type. + */ + EAP_FUNC_IMPORT void set_type(const tls_extension_type_e type); + + /** + * This function gets the extension type. + */ + EAP_FUNC_IMPORT tls_extension_type_e get_type() const; + +#if defined(USE_FAST_EAP_TYPE) + + /// This function stores the PAC-Type for fast access. + EAP_FUNC_IMPORT void set_pac_type(const eap_fast_pac_type_e pac_type); + + /// This function returns the PAC-Type for fast access. + EAP_FUNC_IMPORT eap_fast_pac_type_e get_pac_type() const; + +#endif //#if defined(USE_FAST_EAP_TYPE) + + /** + * This function gets the debug string of the extension type. + */ + EAP_FUNC_IMPORT static eap_const_string get_type_string(tls_extension_type_e type); + + /** + * This function gets the extension from the array of extensions. + */ + EAP_FUNC_IMPORT static const tls_extension_c * get_tls_extension( + const tls_extension_type_e tls_extension_type, + EAP_TEMPLATE_CONST eap_array_c * const tls_extensions, + abs_eap_am_tools_c * const am_tools); + +#if defined(USE_FAST_EAP_TYPE) + /** + * This function gets the extension from the array of extensions. + */ + EAP_FUNC_IMPORT static const tls_extension_c * get_tls_extension( + const tls_extension_type_e tls_extension_type, + const eap_fast_pac_type_e pac_type, + EAP_TEMPLATE_CONST eap_array_c * const tls_extensions, + abs_eap_am_tools_c * const am_tools); +#endif //#if defined(USE_FAST_EAP_TYPE) + + // + //-------------------------------------------------- +}; // class tls_extension_c + + +//-------------------------------------------------- + +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + +#endif //#if !defined(_TLS_EXTENSION_H_) + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_handshake_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_handshake_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,207 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_HANDSHAKE_HEADER_H_) +#define _TLS_HANDSHAKE_HEADER_H_ + +#include "eap_tools.h" +#include "eap_header.h" +#include "eap_general_header_base.h" +#include "tls_peap_types.h" + + +/** @file */ + +/** + * This is enumeration of TLS-Handshake message types. + */ +enum tls_handshake_type_e +{ + tls_handshake_type_hello_request = (0), + tls_handshake_type_client_hello = (1), + tls_handshake_type_server_hello = (2), +#if defined(USE_EAP_TLS_SESSION_TICKET) + tls_handshake_type_new_session_ticket = (4), +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + tls_handshake_type_certificate = (11), + tls_handshake_type_server_key_exchange = (12), + tls_handshake_type_certificate_request = (13), + tls_handshake_type_server_hello_done = (14), + tls_handshake_type_certificate_verify = (15), + tls_handshake_type_client_key_exchange = (16), + tls_handshake_type_finished = (20), + tls_handshake_type_none = (255), +}; + +//---------------------------------------------------------------------------- + + +/// This class defines header of TLS handshake protocol. +/** + * Here is a figure of header of TLS handshake protocol. + * TLS-type data follows tls_handshake_header_c. + * @code + * TLS handshake-header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type: aa | Length: h | Length: m | Length: l | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Handshake message follows immediately the TLS handshake-header. + * @endcode + * + * @code + * The fields of this header are: + * 8-bits m_handshake_type; This is a protocol type field. Look at tls_handshake_type_e values. + * 24-bits m_length; This is a length field. Length is measured in bytes and it does not include + * m_handshake_type, m_length_high, m_length_middle and m_length_low + * fields, only the length of the following handshake message. + * @endcode + * + */ +class EAP_EXPORT tls_handshake_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + enum sizes + { + m_max_data_length = TLS_PEAP_MAX_HANDSHAKE_DATA_LENGTH, + }; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + enum offsets + { + m_type_offset = 0ul, ///< This is offset of the type 8-bit field. + m_length_offset = m_type_offset+sizeof(u8_t), ///< This is offset of the length 24-bit field. + m_data_offset = m_length_offset+(3ul*sizeof(u8_t)), ///< This is offset of the data. + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * Destructor does nothing. + */ + virtual ~tls_handshake_header_c(); + + /** + * Constructor initializes class. + */ + tls_handshake_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + /** + * This function returns TLS-handshake type. + */ + tls_handshake_type_e get_handshake_type() const; + + /** + * This function returns data length of TLS-handshake message. + * Length is measured in bytes and it does not include m_handshake_type, m_length_high, + * m_length_middle and m_length_low fields, only the length of the following handshake message. + */ + u32_t get_data_length() const; + + /** + * This function returns maximum data length of TLS-handshake message. + */ + static u32_t get_max_data_length(); + + /** + * This function returns header length of TLS-handshake message. + */ + static u32_t get_header_length(); + + /** + * This function returns pointer to the offset of data of TLS-handshake message. + */ + u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + + /** + * This function returns pointer to data of TLS-handshake message. + */ + u8_t * get_data(const u32_t contignuous_bytes) const; + + + /** + * This function returns debug string of TLS-handshake type. + */ + static eap_const_string get_tls_handshake_string( + const tls_handshake_type_e type); + + /** + * This function returns debug string of TLS-handshake type. + */ + eap_const_string get_tls_handshake_string() const; + + /** + * This function sets the TLS-handshake type. + */ + void set_handshake_type(tls_handshake_type_e handshake_type); + + /** + * This function sets the length of data of the TLS-handshake type. + */ + void set_data_length(const u32_t p_length); + + /** + * This function resets the header of the TLS-handshake type. + */ + void reset_header( + const u32_t data_length); + + /** + * This function checks header of TLS-handshake message. + */ + eap_status_e check_header() const; + + /** + * This function checks header of TLS-handshake message + * is required type. + */ + eap_status_e check_header( + const tls_handshake_type_e required_type, + const bool /*is_client_when_true*/) const; + + // + //-------------------------------------------------- +}; // class tls_handshake_header_c + + +//-------------------------------------------------- + +#endif //#if !defined(_TLS_HANDSHAKE_HEADER_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_handshake_message.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_handshake_message.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,413 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_HANDSHAKE_MESSAGE_H_) +#define _TLS_HANDSHAKE_MESSAGE_H_ + +#include "eap_tools.h" +#include "eap_array.h" +#include "eap_variable_data.h" +#include "tls_handshake_header.h" +#include "tls_peap_types.h" +#include "abs_tls_message_hash.h" + +#if defined(USE_EAP_TLS_SESSION_TICKET) +#include "tls_extension.h" +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + +/** @file */ + +//---------------------------------------------------------------------------- + +/// This class defines one TLS handshake message. +/** + * This is class of the TLS-handshake message. + * The parse_tls_protocol_handshake() function parses each TLS-handshake message + * and generates this object. Parse and analyse of TLS-handshake is asyncronous. + * m_is_analysed tells this message is analysed. + * Analysed messages are skipped during the asyncronous + * analyse of messages. Asyncronous analyse is needed + * because of the PKI functions are asyncronous in + * Symbian. + */ +class EAP_EXPORT tls_handshake_message_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to interface of message HASH creation. See abs_tls_message_hash_c. + abs_tls_message_hash_c * const m_message_hash; + + /// This buffer includes data of the handshake message. + eap_variable_data_c m_tls_handshake_message_buffer; + + /// This The current time and date in standard UNIX 32-bit format (seconds + /// since the midnight starting Jan 1, 1970, GMT) according to the sender's internal clock. + eap_variable_data_c m_unix_time; + + /// 28 bytes generated by a secure random number generator. + eap_variable_data_c m_random_value; + + /// This is variable length. If not empty, the value identifies a session between the + /// same client and server whose security parameters the client wishes to reuse. + eap_variable_data_c m_session_id; + + /// This is list of cipher suites. + eap_array_c m_cipher_suites; + + /// This is list of compression methods. + eap_array_c m_compression_methods; + +#if defined(USE_EAP_TLS_SESSION_TICKET) + /// This is list of TLS extensions. + eap_array_c m_tls_extensions; +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + /// This is certificate chain. + eap_array_c m_certificate_chain; + + /// This is list of certificaet authorities. + eap_array_c m_certificate_authorities; + + /// This is list of certificaet types. + eap_array_c m_certificate_types; + + /// This is encrypted premaster secret. + eap_variable_data_c m_encrypted_premaster_secret; + + /// This is ephemeral Diffie-Hellman public key. + eap_variable_data_c m_public_dhe_key; + + /// This is ephemeral Diffie-Hellman prime. + eap_variable_data_c m_dhe_prime; + + /// This is ephemeral Diffie-Hellman group generator. + eap_variable_data_c m_dhe_group_generator; + + /// This is signed message hash. + eap_variable_data_c m_signed_message_hash; + + /// This is finished data of TLS-Handshake/Finished message. + eap_variable_data_c m_finished_data; + + /// This is the selected cipher suite. + tls_cipher_suites_e m_selected_cipher_suite; + + /// This is the selected compression method. + tls_compression_method_e m_selected_compression_method; + + /// This is handshake type. See tls_handshake_type_e. + tls_handshake_type_e m_handshake_type; + + /// This flag tells this message is analysed. + bool m_is_analysed; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This indicates whether this object is client (true) or server (false). + bool m_is_client; + + //-------------------------------------------------- + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT static eap_status_e u16_t_to_network_order( + u16_t * const value, + abs_eap_am_tools_c * const m_am_tools); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the tls_handshake_message_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~tls_handshake_message_c(); + + /** + * The constructor of the tls_handshake_message_c class simply initializes the attributes. + */ + EAP_FUNC_IMPORT tls_handshake_message_c( + abs_eap_am_tools_c * const tools, + abs_tls_message_hash_c * const message_hash, + const bool is_client); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + + /** + * This function sets this message is analysed. + */ + EAP_FUNC_IMPORT void set_is_analysed(); + + /** + * This function returns whether message is analysed (true) or not (false). + */ + EAP_FUNC_IMPORT bool get_is_analysed(); + + + /** + * This function creates data of the Handshake message to internal buffer. + * Later this data is added to final TLS-record buffer. + */ + EAP_FUNC_IMPORT eap_status_e create_message_data(); + + + /** + * This function copies the appropriate fields of the TLS-handshake message. + */ + EAP_FUNC_IMPORT eap_status_e set_handshake_header_copy(const tls_handshake_header_c * const tls_handshake_header); + + + /** + * This function sets the type of TLS-handshake message. + */ + EAP_FUNC_IMPORT eap_status_e set_handshake_type(tls_handshake_type_e type); + + /** + * This function returns the type of TLS-handshake message. + */ + EAP_FUNC_IMPORT tls_handshake_type_e get_handshake_type() const; + + + /** + * This function copies the list of the cipher suites. + */ + EAP_FUNC_IMPORT eap_status_e set_cipher_suites( + EAP_TEMPLATE_CONST eap_array_c * const cipher_suites); + + /** + * This function returns the list of the cipher suites. + */ + EAP_FUNC_IMPORT EAP_TEMPLATE_CONST eap_array_c * get_cipher_suites() EAP_TEMPLATE_CONST; + + + /** + * This function copies the list of the compression methods. + */ + EAP_FUNC_IMPORT eap_status_e set_compression_methods( + EAP_TEMPLATE_CONST eap_array_c * const compression_methods); + + /** + * This function returns the list of the compression methods. + */ + EAP_FUNC_IMPORT EAP_TEMPLATE_CONST eap_array_c * get_compression_methods() EAP_TEMPLATE_CONST; + + +#if defined(USE_EAP_TLS_SESSION_TICKET) + /** + * This function copies the list of the TLS extensions. + */ + EAP_FUNC_IMPORT eap_status_e set_tls_extensions( + EAP_TEMPLATE_CONST eap_array_c * const compression_methods); +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +#if defined(USE_EAP_TLS_SESSION_TICKET) + /** + * This function returns the list of the TLS extensions. + */ + EAP_FUNC_IMPORT EAP_TEMPLATE_CONST eap_array_c * get_tls_extensions() EAP_TEMPLATE_CONST; +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + + /** + * This function copies the random value. + */ + EAP_FUNC_IMPORT eap_status_e set_random_value( + const eap_variable_data_c * const random_value); + + /** + * This function returns the random value. + */ + EAP_FUNC_IMPORT const eap_variable_data_c * get_random_value() const; + + + /** + * This function copies the session id. + */ + EAP_FUNC_IMPORT eap_status_e set_session_id( + const eap_variable_data_c * const session_id); + + /** + * This function returns the session id. + */ + EAP_FUNC_IMPORT const eap_variable_data_c * get_session_id() const; + + + /** + * This function copies the certificate chain. + */ + EAP_FUNC_IMPORT eap_status_e set_certificate_chain( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain); + + /** + * This function returns the certificate chain. + */ + EAP_FUNC_IMPORT EAP_TEMPLATE_CONST eap_array_c * get_certificate_chain() EAP_TEMPLATE_CONST; + + + /** + * This function copies the list of the certificate authorities. + */ + EAP_FUNC_IMPORT eap_status_e set_certificate_authorities( + EAP_TEMPLATE_CONST eap_array_c * const certificate_authorities); + + /** + * This function returns the list of the certificate authorities. + */ + EAP_FUNC_IMPORT EAP_TEMPLATE_CONST eap_array_c * get_certificate_authorities() EAP_TEMPLATE_CONST; + + + /** + * This function copies the list of the certificate types. + */ + EAP_FUNC_IMPORT eap_status_e set_certificate_types( + EAP_TEMPLATE_CONST eap_array_c * const certificate_types); + + /** + * This function returns the list of the certificate types. + */ + EAP_FUNC_IMPORT EAP_TEMPLATE_CONST eap_array_c * get_certificate_types() EAP_TEMPLATE_CONST; + + + /** + * This function sets the list of the selected cipher suite. + */ + EAP_FUNC_IMPORT eap_status_e set_selected_cipher_suite(const tls_cipher_suites_e selected_cipher_suite); + + /** + * This function returns the list of the selected cipher suite. + */ + EAP_FUNC_IMPORT tls_cipher_suites_e get_selected_cipher_suite() const; + + + /** + * This function sets the list of the selected compression method. + */ + EAP_FUNC_IMPORT eap_status_e set_selected_compression_method(const tls_compression_method_e selected_compression_method); + + /** + * This function returns the list of the selected compression method. + */ + EAP_FUNC_IMPORT tls_compression_method_e get_selected_compression_method() const; + + + /** + * This function copies the encrypted premaster secret. + */ + EAP_FUNC_IMPORT eap_status_e set_encrypted_premaster_secret(const eap_variable_data_c * const encrypted_premaster_secret); + + /** + * This function returns the encrypted premaster secret. + */ + EAP_FUNC_IMPORT const eap_variable_data_c * get_encrypted_premaster_secret() const; + + + /** + * This function copies the ephemeral Diffie-Hellman public key. + */ + EAP_FUNC_IMPORT eap_status_e set_public_dhe_key(const eap_variable_data_c * const public_dhe_key); + + /** + * This function returns the ephemeral Diffie-Hellman public key. + */ + EAP_FUNC_IMPORT const eap_variable_data_c * get_public_dhe_key() const; + + + /** + * This function copies the ephemeral Diffie-Hellman prime. + */ + EAP_FUNC_IMPORT eap_status_e set_dhe_prime(const eap_variable_data_c * const dhe_prime); + + /** + * This function returns the ephemeral Diffie-Hellman prime. + */ + EAP_FUNC_IMPORT const eap_variable_data_c * get_dhe_prime() const; + + + /** + * This function copies the ephemeral Diffie-Hellman group generator. + */ + EAP_FUNC_IMPORT eap_status_e set_dhe_group_generator(const eap_variable_data_c * const dhe_group_generator); + + /** + * This function returns the ephemeral Diffie-Hellman group generator. + */ + EAP_FUNC_IMPORT const eap_variable_data_c * get_dhe_group_generator() const; + + + /** + * This function copies the signed message HASH. + */ + EAP_FUNC_IMPORT eap_status_e set_signed_message_hash(const eap_variable_data_c * const signed_message_hash); + + /** + * This function returns the signed message HASH. + */ + EAP_FUNC_IMPORT const eap_variable_data_c * get_signed_message_hash() const; + + + /** + * This function copies the TLS-finished data. + */ + EAP_FUNC_IMPORT eap_status_e set_finished_data(const eap_variable_data_c * const finished_data); + + /** + * This function returns the TLS-finished data. + */ + EAP_FUNC_IMPORT const eap_variable_data_c * get_finished_data() const; + + + /** + * This function adds data of the TLS-handshake message to tls_message_buffer. + */ + EAP_FUNC_IMPORT eap_status_e add_message_data( + eap_variable_data_c * const tls_message_buffer); + + // + //-------------------------------------------------- +}; // class tls_handshake_message_c + + +//-------------------------------------------------- + +#endif //#if !defined(_TLS_HANDSHAKE_MESSAGE_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_message.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_message.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,198 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_MESSAGE_H_) +#define _TLS_MESSAGE_H_ + +#include "eap_tools.h" +#include "eap_array.h" +#include "tls_record_message.h" +#include "abs_tls_message_hash.h" +#include "abs_tls_apply_cipher_spec.h" + +/** @file */ + + +//---------------------------------------------------------------------------- + + +/// This class defines one TLS-message. One TLS message could include many TLS-records. +/** + * This class defined one TLS-message. + * Parse and analyse of TLS-message is asyncronous. + * m_analyse_index tells the index of message where asyncronous + * analyse of TLS-message must continue. + * Analysed messages are skipped during the asyncronous + * analyse of messages. Asyncronous analyse is needed + * because of the PKI functions are asyncronous in + * Symbian. + */ +class EAP_EXPORT tls_message_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to interface of message HASH creation. See abs_tls_message_hash_c. + abs_tls_message_hash_c * const m_message_hash; + + /// This is pointer to interface of apply cipher spec. See abs_tls_apply_cipher_spec_c. + abs_tls_apply_cipher_spec_c * const m_apply_cipher_spec; + + /// This is pointer to interface of change cipher spec. See abs_tls_change_cipher_spec_c. + abs_tls_change_cipher_spec_c * m_change_cipher_spec; + + /// This buffer includes copy of the whole received TLS-message data. + eap_variable_data_c m_tls_message_data; + + /// This is EAP-identifier of the EAP-packet that includes TLS-message. This is needed in XP-PEAP. + u8_t m_received_eap_identifier; + + /// This is the index of message where asyncronous analyse of TLS-message must continue. + u32_t m_analyse_index; + + /// This array includes one or more records. + eap_array_c m_record_messages; + + /// This indicates whether this object is client (true) or server (false). This is mostly for traces. + const bool m_is_client; + + /// This flag tells the send message includes TLS-Handshake message. + /// Note the received messages are not marked. + /// This information is needed in special PEAP version. + /// All messages including TLS-Handshake message must have PEAP L bit and four octet TLS message length field. + bool m_includes_tls_handshake_message; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the tls_message_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~tls_message_c(); + + /** + * The constructor of the tls_message_c class simply initializes the attributes. + */ + EAP_FUNC_IMPORT tls_message_c( + abs_eap_am_tools_c * const tools, + abs_tls_message_hash_c * const message_hash, + abs_tls_apply_cipher_spec_c * const apply_cipher_spec, + abs_tls_change_cipher_spec_c * const change_cipher_spec, + const bool is_client); + + /** + * This function resets this object. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + /** + * This function returns the index of message where analyse must continue. + */ + EAP_FUNC_IMPORT u32_t get_analyse_index() const; + + /** + * This function saves the index of message where analyse must continue. + */ + EAP_FUNC_IMPORT void save_analyse_index(const u32_t analyse_index); + + /** + * This function copies the received TLS-message data and EAP-identifier. + * EAP-identifier is needed in XP PEAPv0. That stupid version uses + * same EAP-identifier with PEAP header and tunneled EAP-header. + */ + EAP_FUNC_IMPORT eap_status_e set_tls_message_data( + eap_variable_data_c * const tls_message_data, + const u8_t received_eap_identifier); + + /** + * This function returns the TLS-message data. + */ + EAP_FUNC_IMPORT eap_variable_data_c * get_tls_message_data(); + + /** + * This function returns the EAP-identifier. + */ + EAP_FUNC_IMPORT u8_t get_received_eap_identifier(); + + /** + * This function adds TLS-record to m_record_messages. + * Parameter free_record tells whether record must be freed in destructor. + */ + EAP_FUNC_IMPORT eap_status_e add_record_message( + tls_record_message_c * const record, + const bool free_record, + const bool includes_tls_handshake_message); + + /** + * This function fragments TLS-protocol messages to one or more TLS-record messages. + */ + EAP_FUNC_IMPORT eap_status_e fragment_tls_records( + tls_record_message_c * const tls_record_message, + eap_array_c * const tls_fragments); + + /** + * This function adds data of every TLS-record to tls_message_buffer. + */ + EAP_FUNC_IMPORT eap_status_e add_message_data( + eap_variable_data_c * const tls_message_buffer, + bool * const includes_tls_handshake_message); + + /** + * This function returns count of the TLS-records. + */ + EAP_FUNC_IMPORT u32_t get_record_message_count() const; + + /** + * This function returns pointer to the TLS-record selected by index. + */ + EAP_FUNC_IMPORT tls_record_message_c * get_record_message( + const u32_t index) const; + + /** + * This function removes the TLS-record selected by index. + */ + EAP_FUNC_IMPORT eap_status_e remove_record_message( + const u32_t index); + + /** + * This function returns pointer to the last TLS-record. + */ + EAP_FUNC_IMPORT tls_record_message_c * get_last_record_message() const; + + // + //-------------------------------------------------- +}; // class tls_message_c + + +//-------------------------------------------------- + +#endif //#if !defined(_TLS_MESSAGE_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_peap_tlv_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_peap_tlv_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,259 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_PEAP_TLV_HEADER_H_) +#define _TLS_PEAP_TLV_HEADER_H_ + +#include "eap_tools.h" +#include "eap_general_header_base.h" + +/** @file */ + + +/** + * This is enumeration of PEAP Type-Length-Value (TLV) values. + * See draft-puthenkulam-eap-binding-03.txt + * and draft-josefsson-pppext-eap-tls-eap-07.txt. + */ +enum tls_peap_tlv_type_e +{ + tls_peap_tlv_type_reserved_zero = 0, + tls_peap_tlv_type_reserved_one = 1, + tls_peap_tlv_type_reserved_two = 2, + tls_peap_tlv_type_result = 3, ///< RESULT_TLV + tls_peap_tlv_type_nak = 4, ///< NAK_TLV + tls_peap_tlv_type_crypto_binding = 5, ///< CRYPTO_BINDING_TLV + tls_peap_tlv_eap_payload = 8, ///< EAP-Payload TLV + tls_peap_tlv_type_intermediate_result = 10, ///< Intermediate Result TLV + tls_peap_tlv_type_none = 255, +}; + + +enum tls_peap_tlv_type_crypto_binding_type_e +{ + tls_peap_tlv_type_crypto_binding_request = 0, + tls_peap_tlv_type_crypto_binding_response = 1, + tls_peap_tlv_type_crypto_binding_none = 0xff, +}; + +/** + * This is enumeration of status values of result TLV. + * See draft-puthenkulam-eap-binding-03.txt + * and draft-josefsson-pppext-eap-tls-eap-07.txt. + */ +enum tls_peap_tlv_status_e +{ + tls_peap_tlv_status_none = 0, + tls_peap_tlv_status_success = 1, + tls_peap_tlv_status_failure = 2, +}; + + +//---------------------------------------------------------------------------- + + +/// This class defines header of Attribute-Value Pairs. +/** + * Here is a figure of header of Attribute-Value Pairs. + * Value data follows tls_peap_tlv_header_c. + * @code + * TLV-header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |M|R| TLV Type | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Value... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * @endcode + * + * @code + * The fields of this header are: + * 1-bit flag mandatory tlv (M); Whether this TLV is mandatory (1) + * 1-bit flag reserved (R); This is a reserved field, this is zero. + * 14-bits TLV Type; This is a TLV type. + * 16-bits value length (Length); This is a length field, the length (in bytes) of the following value. + * @endcode + * + * See draft-puthenkulam-eap-binding-03.txt + * and draft-josefsson-pppext-eap-tls-eap-07.txt. + */ +class EAP_EXPORT tls_peap_tlv_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This is enumeration of bit masks. + enum bit_masks + { + m_flag_mask_mandatory_tlv = 0x80, + m_flag_mask_reserved = 0x40, + }; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + /// This is enumeration of offsets to data fields. + enum offsets + { + m_flags_and_tlv_type_offset = 0ul, ///< This is offset to fags and tlv type 16-bit field. + m_length_offset = m_flags_and_tlv_type_offset+sizeof(u16_t), ///< This is offset to length 16-bit field. + m_data_offset = m_length_offset+sizeof(u16_t), ///< This is offset to data field. + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the tls_peap_tlv_header_c class does nothing. + */ + virtual ~tls_peap_tlv_header_c(); + + /** + * The constructor of the tls_peap_tlv_header_c class simply initializes the attributes. + */ + tls_peap_tlv_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length); + + /** + * This function returns the TLV type flag. + */ + tls_peap_tlv_type_e get_flag_tlv_type() const; + + /** + * This function returns the TLV mandatory flag. + */ + bool get_flag_mandatory_tlv() const; + + /** + * This function returns the TLV reserved flag. + */ + bool get_flag_reserved() const; + + /** + * This function returns the data length of TLV. + */ + u16_t get_data_length() const; + + /** + * This function returns the header length of TLV. + */ + static u32_t get_header_length(); + + /** + * This function returns pointer to the offset of data of TLV. + * @param offset is the offset of queried data in bytes. + * @param contignuous_bytes is the length of queried data in bytes. + */ + u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + + /** + * This function returns pointer to the offset of data of TLV. + * @param contignuous_bytes is the length of queried data in bytes. + */ + u8_t * get_data(const u32_t contignuous_bytes) const; + + + /** + * This function return pointer to the next TLV header in the same buffer. + */ + u8_t * get_next_header() const; + + + /** + * This function checks the header is valid. + */ + eap_status_e check_header() const; + + /** + * This function returns debug strings of the TLV type. + */ + eap_const_string get_tlv_type_string() const; + + /** + * This function sets the TLV type flag. + */ + void set_flag_tlv_type(tls_peap_tlv_type_e type); + + /** + * This function sets the TLV reserved flag. + */ + void set_flag_reserved(bool reserved); + + /** + * This function sets the TLV manadtory flag. + */ + void set_flag_mandatory_tlv(const bool mandatory_when_true); + + /** + * This function sets the TLV data length. + */ + void set_data_length(const u16_t p_length); + + /** + * This function resets the TLV header. + */ + void reset_header(const u16_t buffer_length); + + // + //-------------------------------------------------- +}; // class tls_peap_tlv_header_c + +//-------------------------------------------------- + +/// Macro traces payload type and data. +#define TLS_PEAP_TLV_TRACE_PAYLOAD(prefix, payload) \ + { \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v \n"))); \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("%s (0x%08x): M=%d, R=%d, TLV type 0x%08x=%s, data length 0x%04x.\n"), \ + prefix, (payload)->get_header_buffer((payload)->get_data_length()), \ + (payload)->get_flag_mandatory_tlv(), \ + (payload)->get_flag_reserved(), \ + (payload)->get_flag_tlv_type(), \ + (payload)->get_tlv_type_string(), \ + (payload)->get_data_length())); \ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("data"), (payload)->get_data((payload)->get_data_length()), \ + (payload)->get_data_length())); \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ \n"))); \ + } + +//-------------------------------------------------- + +#endif //#if !defined(_TLS_PEAP_TLV_HEADER_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_peap_tlv_payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_peap_tlv_payloads.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,155 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_PEAP_TLV_PAYLOADS_H_) +#define _PEAP_TLV_PAYLOADS_H_ + +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "tls_peap_tlv_header.h" + + + +class EAP_EXPORT peap_tlv_variable_data_c +: public eap_variable_data_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + tls_peap_tlv_header_c m_original_header; + + eap_variable_data_c m_header_copy; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT virtual ~peap_tlv_variable_data_c(); + + EAP_FUNC_IMPORT peap_tlv_variable_data_c(abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT const tls_peap_tlv_header_c * get_original_header() const; + + EAP_FUNC_IMPORT eap_status_e set_buffer( + const tls_peap_tlv_header_c * const original_header, + u8_t *data_buffer, + const u32_t data_buffer_length, + const bool free_buffer, + const bool is_writable); + + EAP_FUNC_IMPORT eap_status_e set_copy_of_buffer( + const tls_peap_tlv_header_c * const original_header); + + //-------------------------------------------------- +}; // class peap_tlv_variable_data_c + + +//-------------------------------------------------- + + +// +class EAP_EXPORT peap_tlv_payloads_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + peap_tlv_variable_data_c m_result_tlv; + + peap_tlv_variable_data_c m_nak_tlv; + + peap_tlv_variable_data_c m_crypto_binding_tlv; + + peap_tlv_variable_data_c m_eap_payload_tlv; + + peap_tlv_variable_data_c m_intermediate_result_tlv; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + + enum peap_tlv_payload_status_e + { + peap_tlv_payload_status_optional, + peap_tlv_payload_status_must_be, + peap_tlv_payload_status_must_not_be + }; + + + EAP_FUNC_IMPORT virtual ~peap_tlv_payloads_c(); + + EAP_FUNC_IMPORT peap_tlv_payloads_c( + abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT bool check_one_payload( + const peap_tlv_payload_status_e status, + const peap_tlv_variable_data_c * const payload); + + /** This function checks the correct set of payloads are included in the message. + * NOTE do not change the order of parameters. + * Add new payload type to the last of the parameter list. + */ + EAP_FUNC_IMPORT bool check_payloads( + const peap_tlv_payload_status_e result_tlv, + const peap_tlv_payload_status_e nak_tlv, + const peap_tlv_payload_status_e crypto_binding_tlv, + const peap_tlv_payload_status_e eap_payload_tlv, + const peap_tlv_payload_status_e intermediate_result_tlv + ); + + peap_tlv_variable_data_c * get_result_tlv(); + + peap_tlv_variable_data_c * get_nak_tlv(); + + peap_tlv_variable_data_c * get_crypto_binding_tlv(); + + peap_tlv_variable_data_c * get_eap_payload_tlv(); + + peap_tlv_variable_data_c * get_intermediate_result_tlv(); + + void reset(); + + bool get_is_valid() const; + + //-------------------------------------------------- +}; // class peap_tlv_payloads_c + + +#endif //#if !defined(_PEAP_TLV_PAYLOADS_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_peap_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_peap_types.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,838 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_PEAP_TYPES_H_) +#define _TLS_PEAP_TYPES_H_ + +#include "eap_buffer.h" +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "eap_type_all_types.h" +#include "eap_configuration_field.h" + +#if defined(USE_FAST_EAP_TYPE) + #include "eap_fast_types.h" +#endif //#if defined(USE_FAST_EAP_TYPE) + + +/** @file tls_peap_types.h + * @brief This file defines the constants of the TLS and PEAP. + */ + +//-------------------------------------------------- + +/// Macro traces payload type and data. +#define EAP_TLS_PEAP_TRACE_PAYLOAD(prefix, payload, is_client) \ + { \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n"))); \ + EAP_TRACE_DEBUG( \ + m_am_tools, \ + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- %s (0x%08x): %s, current payload 0x%04x=%s, data length 0x%04x.\n"), \ + prefix, (payload), (is_client == true ? "client": "server"), (payload)->get_flag_tlv_type(), \ + (payload)->get_tlv_type_string(), (payload)->get_data_length())); \ + EAP_TRACE_DATA_DEBUG( \ + m_am_tools, \ + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- payload"), \ + (payload)->get_header_buffer( \ + (payload)->get_header_length()+(payload)->get_data_length()), \ + (payload)->get_header_length()+(payload)->get_data_length())); \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n"))); \ + } + +#define EAP_TLS_PEAP_TRACE_TTLS_PAYLOAD(prefix, payload, is_client) \ + { \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n"))); \ + EAP_TRACE_DEBUG( \ + m_am_tools, \ + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- %s (0x%08x): %s, current payload 0x%08x:0x%08x=%s, data length 0x%04x.\n"), \ + prefix, (payload), (is_client == true ? "client": "server"), (payload)->get_avp_code().get_vendor_id(), \ + (payload)->get_avp_code().get_vendor_code(), \ + (payload)->get_avp_code_string(), (payload)->get_data_length())); \ + EAP_TRACE_DATA_DEBUG( \ + m_am_tools, \ + TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- payload"), \ + (payload)->get_header_buffer( \ + (payload)->get_header_length()+(payload)->get_data_length()), \ + (payload)->get_header_length()+(payload)->get_data_length())); \ + EAP_TRACE_DEBUG( \ + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \ + (EAPL("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n"))); \ + } + +//-------------------------------------------------- + +/** + * This is the size of the local send buffer. + */ +const u32_t TLS_PEAP_LOCAL_PACKET_BUFFER_LENGTH = EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH; + +/** + * This is the default size of the TLS-record buffer. + */ +const u32_t TLS_PEAP_DEFAULT_RECORD_LENGTH = 4096ul; + +/** + * This is the maximum size of the TLS-record fragment. + */ +const u32_t TLS_PEAP_MAX_RECORD_FRAGMENT_LENGTH = (2ul << 13); // 2^14 bytes = 16384 bytes. + +/** + * This is the maximum size of the TLS-handshake message. + */ +const u32_t TLS_PEAP_MAX_HANDSHAKE_DATA_LENGTH = (2ul << 23) - 1ul; // (2^24 - 1) bytes = 16777215 bytes. + +/** + * This is the default trace mask for TLS and PEAP. + */ +const u32_t TRACE_FLAGS_TLS_PEAP_ERROR = eap_am_tools_c::eap_trace_mask_error; + + +/** + * This is the size of the TLS-hello random. + */ +const u32_t TLS_HANDSHAKE_RANDOM_VALUE_SIZE = 32ul; + +/** + * This is the size of the TLS-session ID. + */ +const u32_t TLS_SESSION_ID_SIZE = 32ul; + +/** + * This is the size of the TLS-premaster secret. + */ +const u32_t TLS_PREMASTER_SECRET_SIZE = 48ul; + +/** + * This is the size of the TLS-master secret. + */ +const u32_t TLS_MASTER_SECRET_SIZE = 48ul; + + +enum tls_peap_protocol_field_size_e +{ + TLS_ALERT_DESCRIPTION_FIELD_SIZE = sizeof(u8_t), + TLS_ALERT_LEVEL_FIELD_SIZE = sizeof(u8_t), + TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE = sizeof(u16_t), + TLS_CERTIFICATE_LENGTH_FIELD_SIZE = 3UL*sizeof(u8_t), + TLS_CERTIFICATE_TYPE_FIELD_SIZE = sizeof(u8_t), + TLS_CERTIFICATE_TYPE_LENGTH_FIELD_SIZE = sizeof(u8_t), + TLS_CHANGE_CIPHER_SPEC_FIELD_SIZE = sizeof(u8_t), + TLS_CIPHER_SUITE_FIELD_SIZE = sizeof(u16_t), + TLS_CIPHER_SUITE_LENGTH_FIELD_SIZE = sizeof(u16_t), + TLS_COMPRESSION_FIELD_SIZE = sizeof(u8_t), + TLS_COMPRESSION_LENGTH_FIELD_SIZE = sizeof(u8_t), + TLS_COMPRESSION_METHOD_FIELD_SIZE = sizeof(u8_t), + TLS_EXTENSIONS_LENGTH_FIELD_SIZE = sizeof(u16_t), + TLS_EXTENSION_TYPE_FIELD_SIZE = sizeof(u16_t), + TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE = sizeof(u16_t), + TLS_DHE_GROUP_GENERATOR_LENGTH_FIELD_SIZE = sizeof(u16_t), + TLS_DHE_PRIME_LENGTH_FIELD_SIZE = sizeof(u16_t), + TLS_ENCRYPTED_PREMASTER_SECRET_LENGTH_FIELD_SIZE = sizeof(u16_t), + TLS_PADDINF_LENGTH_FIELD_SIZE = sizeof(u8_t), + TLS_PUBLIC_DHE_KEY_LENGTH_FIELD_SIZE = sizeof(u16_t), + TLS_PUBLIC_DHE_KEY_LENGTH_LENGTH_FIELD_SIZE = sizeof(u16_t), + TLS_DSS_SHA1_SIGNATURE_LENGTH_FIELD_SIZE = sizeof(u16_t), + TLS_SESSION_ID_LENGTH_FIELD_SIZE = sizeof(u8_t), + TLS_SIGNATURE_LENGTH_FIELD_SIZE = sizeof(u16_t), + TLS_VERSION_FIELD_SIZE = sizeof(u16_t), + TLS_SESSION_TICKET_LIFETIME_HINT_FIELD_SIZE = sizeof(u32_t), +}; + + +/** + * This is the label of the TLS-premaster secret. + * See Chapter "8.1. Computing the master secret" in RFC 2246. + */ +const u8_t TLS_MASTER_SECRET_LABEL[] = "master secret"; + +/** + * This is the length of the label of the TLS-premaster secret. + */ +const u32_t TLS_MASTER_SECRET_LABEL_LENGTH = sizeof(TLS_MASTER_SECRET_LABEL)-1ul; + + +/** + * This is the label of the TLS-client finished message. + * See Chapter "7.4.9. Finished" in RFC 2246. + */ +const u8_t TLS_CLIENT_FINISHED_LABEL[] = "client finished"; + +/** + * This is the length of the label of the TLS-client finished message. + */ +const u32_t TLS_CLIENT_FINISHED_LABEL_LENGTH = sizeof(TLS_CLIENT_FINISHED_LABEL)-1ul; + +/** + * This is the label of the TLS-server finished message. + * See Chapter "7.4.9. Finished" in RFC 2246. + */ +const u8_t TLS_SERVER_FINISHED_LABEL[] = "server finished"; + +/** + * This is the length of the label of the TLS-server finished message. + */ +const u32_t TLS_SERVER_FINISHED_LABEL_LENGTH = sizeof(TLS_SERVER_FINISHED_LABEL)-1ul; + +/** + * This is the length of the data of the TLS-finished message. + */ +const u32_t TLS_FINISHED_DATA_SIZE = 12ul; + + +/** + * This is the label of the TLS-key expansion function. + * See Chapter "6.3. Key calculation" in RFC 2246. + */ +const u8_t TLS_PEAP_KEY_EXPANSION_LABEL[] = "key expansion"; + +/** + * This is the length of the label of the TLS-key expansion function. + */ +const u32_t TLS_PEAP_KEY_EXPANSION_LABEL_LENGTH = sizeof(TLS_PEAP_KEY_EXPANSION_LABEL)-1ul; + + +/** + * This is the label of the TTLS-key expansion function. + * See Chapter "7. Generating Keying Material" in EAP-TTLSv0. + */ +const u8_t EAP_TTLS_KEY_EXPANSION_LABEL[] = "ttls keying material"; + +/** + * This is the length of the label of the TTLS-key expansion function. + */ +const u32_t EAP_TTLS_KEY_EXPANSION_LABEL_LENGTH = sizeof(EAP_TTLS_KEY_EXPANSION_LABEL)-1ul; + + +/** + * This is the label of the TTLS implicit challenge function. + * See Chapter "10.1 Implicit challenge" in EAP-TTLSv0. + */ +const u8_t EAP_TTLS_IMPLICIT_CHALLENGE_LABEL[] = "ttls challenge"; + +/** + * This is the length of the label of the TTLS implicit challenge function. + */ +const u32_t EAP_TTLS_IMPLICIT_CHALLENGE_LABEL_LENGTH = sizeof(EAP_TTLS_IMPLICIT_CHALLENGE_LABEL)-1ul; + + + +const u8_t EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL_V1_DRAFT_5[] = "client PEAP encryption"; + +const u32_t EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL_V1_DRAFT_5_LENGTH = sizeof(EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL_V1_DRAFT_5)-1ul; + + +const u8_t EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL[] = "client EAP encryption"; + +const u32_t EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL_LENGTH = sizeof(EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL)-1ul; + +const u32_t EAP_TLS_PEAP_MSK_SIZE = 64ul; +const u32_t EAP_TLS_PEAP_EMSK_SIZE = 64ul; +const u32_t EAP_TLS_PEAP_MASTER_SESSION_KEY_SIZE = EAP_TLS_PEAP_MSK_SIZE + EAP_TLS_PEAP_EMSK_SIZE; + + +/** + * This is the label of the PEAPv2 Intermediate Combined Key. + * See Chapter "2.5. Key derivation" in PEAPv2 draft 07. + */ +const u8_t TLS_INTERMEDIATE_COMBINED_KEY_LABEL[] = "Intermediate PEAP MAC key"; + +/** + * This is the length of the label of the PEAPv2 Intermediate Combined Key. + */ +const u32_t TLS_INTERMEDIATE_COMBINED_KEY_LABEL_LENGTH = sizeof(TLS_INTERMEDIATE_COMBINED_KEY_LABEL)-1ul; + + +/** + * This is the label of the PEAPv2 Compound Server MAC Key. + * See Chapter "2.5. Key derivation" in PEAPv2 draft 07. + */ +const u8_t TLS_INTERMEDIATE_COMPOUND_SERVER_MAC_KEY_LABEL[] = "PEAP Server B1 MAC key"; + +/** + * This is the length of the label of the PEAPv2 Compound Server MAC Key. + */ +const u32_t TLS_INTERMEDIATE_COMPOUND_SERVER_MAC_KEY_LABEL_LENGTH = sizeof(TLS_INTERMEDIATE_COMPOUND_SERVER_MAC_KEY_LABEL)-1ul; + + +/** + * This is the label of the PEAPv2 Compound Client MAC Key. + * See Chapter "2.5. Key derivation" in PEAPv2 draft 07. + */ +const u8_t TLS_INTERMEDIATE_COMPOUND_CLIENT_MAC_KEY_LABEL[] = "PEAP Client B2 MAC key"; + +/** + * This is the length of the label of the PEAPv2 Compound Client MAC Key. + */ +const u32_t TLS_INTERMEDIATE_COMPOUND_CLIENT_MAC_KEY_LABEL_LENGTH = sizeof(TLS_INTERMEDIATE_COMPOUND_CLIENT_MAC_KEY_LABEL)-1ul; + + +/** + * This is the label of the PEAPv2 Compound Session Key. + * See Chapter "2.5. Key derivation" in PEAPv2 draft 07. + */ +const u8_t TLS_INTERMEDIATE_COMPOUND_SESSION_KEY_LABEL[] = "PEAP compound session key"; + +/** + * This is the length of the label of the PEAPv2 Compound Session Key. + */ +const u32_t TLS_INTERMEDIATE_COMPOUND_SESSION_KEY_LABEL_LENGTH = sizeof(TLS_INTERMEDIATE_COMPOUND_SESSION_KEY_LABEL)-1ul; + + +/** + * This is the length of the RC4 key used in TLS. + */ +const u32_t TLS_RC4_128_KEY_LENGTH = 16ul; + +/** + * This is the length of the RC4 initialization vector used in TLS. + */ +const u32_t TLS_RC4_128_IV_LENGTH = 0ul; + + +/** + * The supported TLS-cipher suites are defined here. + */ +enum tls_cipher_suites_e +{ + tls_cipher_suites_TLS_NULL_WITH_NULL_NULL = (0x0000), ///< No key exchange, no encryption and no authentication. + tls_cipher_suites_TLS_RSA_WITH_RC4_128_MD5 = (0x0004), ///< RSA key exchange, RC4_128 encryption and MD5 authentication. NOTE this is included only because PEAP requires this cipher suite as a mandatory. Think carefully whether this meets your security requirements. + tls_cipher_suites_TLS_RSA_WITH_RC4_128_SHA = (0x0005), ///< RSA key exchange, RC4_128 encryption and SHA1 authentication. NOTE this is included only because PEAP requires this cipher suite as a mandatory. Think carefully whether this meets your security requirements. + tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA = (0x000a), ///< RSA key exchange, 3DES-EDE-CBC encryption and SHA1 authentication. + // not supported: tls_cipher_suites_TLS_RSA_WITH_DES_CBC_SHA = (0x0009), + tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = (0x0016), ///< Diffie-Helmann RSA key exchange, 3DES-EDE-CBC encryption and SHA1 authentication. + // not supported: tls_cipher_suites_TLS_RSA_EXPORT1024_WITH_RC4_56_SHA = (0x0064), + // not supported: tls_cipher_suites_TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA = (0x0062), + // not supported: tls_cipher_suites_TLS_RSA_EXPORT_WITH_RC4_40_MD5 = (0x0003), + // not supported: tls_cipher_suites_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = (0x0006), + tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = (0x0013), ///< Diffie-Helmann DSS key exchange, 3DES-EDE-CBC encryption and SHA1 authentication. + // not supported: tls_cipher_suites_TLS_DHE_DSS_WITH_DES_CBC_SHA = (0x0012), + // not supported: tls_cipher_suites_TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA = (0x0063), + tls_cipher_suites_TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F, ///< RSA key exchange, AES-128 encryption and SHA1 authentication. + // not supported: tls_cipher_suites_TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030, + // not supported: tls_cipher_suites_TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031, + tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032, ///< Diffie-Helmann DSS key exchange, AES-128-CBC encryption and SHA1 authentication. + tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033, ///< Diffie-Helmann RSA key exchange, AES-128-CBC encryption and SHA1 authentication. +#if defined(USE_FAST_EAP_TYPE) + tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x0034, ///< Diffie-Helmann anonymous key exchange, AES-128-CBC encryption and SHA1 authentication. +#endif //#if defined(USE_FAST_EAP_TYPE) + // not supported: tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x0034, + + tls_cipher_suites_none = (0xffff), ///< Internally used initialization value. This means no cipher suite is selected. +}; + + +/** + * The supported certificate types are defined here. + */ +enum tls_certificate_type_e +{ + tls_certificate_type_rsa_sign = (1), ///< RSA + tls_certificate_type_dss_sign = (2), ///< DSS + // not supported: tls_certificate_type_rsa_fixed_dh = (3), + // not supported: tls_certificate_type_dss_fixed_dh = (4), + tls_certificate_type_none = (255), ///< Internally used value. +}; + + +/** + * The supported compression methods are defined here. + */ +enum tls_compression_method_e +{ + tls_compression_method_null = (0), ///< No compression. + tls_compression_method_none = (255), ///< Internally used value. +}; + + +/** + * These are the internal TLS-states. + */ +enum tls_peap_state_e +{ + tls_peap_state_none, ///< Initialization value. + tls_peap_state_wait_tls_start, ///< Waits start of TLS. + tls_peap_state_wait_handshake_type_client_hello, ///< Waits TLS-handshake ClientHello. + tls_peap_state_wait_handshake_type_server_hello, ///< Waits TLS-handshake ServerHello. + tls_peap_state_wait_handshake_type_certificate, ///< Waits TLS-handshake Certificate. + tls_peap_state_wait_handshake_type_server_key_exchange, ///< Waits TLS-handshake ServerKeyExchange. + tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done, ///< Waits TLS-handshake CertificateRequest. + tls_peap_state_wait_handshake_type_server_hello_done, ///< Waits TLS-handshake ServerHelloDone. + tls_peap_state_wait_handshake_type_client_key_exchange, ///< Waits TLS-handshake ClientKeyExchange. + tls_peap_state_wait_handshake_type_certificate_verify, ///< Waits TLS-handshake CertificateVerify. + tls_peap_state_wait_handshake_type_finished, ///< Waits TLS-handshake Finished. +#if defined(USE_EAP_TLS_SESSION_TICKET) + tls_peap_state_wait_handshake_type_new_session_ticket, ///< Waits TLS-handshake NewSessionTicket. +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + tls_peap_state_wait_change_cipher_spec, ///< Waits TLS-ChangeCipherSpec + tls_peap_state_peap_tunnel_ready, ///< PEAP tunnel ready. + tls_peap_state_full_authentication, ///< Full TLS/PEAP authentication is running. + tls_peap_state_original_session_resumption, ///< Saved TLS/PEAP original session is being resumed. +#if defined(USE_EAP_TLS_SESSION_TICKET) + tls_peap_state_stateless_session_resumption, ///< Saved stateless TLS/PEAP session is being resumed, see RFC 4507. +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet, ///< PEAPv1 waits EAP-Success or tunneled packet. +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + tls_peap_state_client_send_ttls_plain_ms_chap_v2_empty_ack, + tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack, +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + tls_peap_state_wait_tunneled_authentication_start, ///< Server waits the lower layer start tunneled authentication. + tls_peap_state_wait_application_data, ///< Waits TLS-ApplicationData, this will include the tunneled EAP-type. + tls_peap_state_process_pending_tls_completions, ///< This is state process the pending completions. + tls_peap_state_pending_tls_messages_processed, ///< This is indication to lower layer that pending TLS-messages are processed, new messages could be accepted. + tls_peap_state_tls_success, ///< TLS authentication success. + tls_peap_state_failure, ///< Authentication failure. + tls_peap_state_peap_tunnel_ready_wait_request, ///< Tunnel ready waits new request. +}; + +enum tls_identity_privacy_handshake_state_e +{ + tls_identity_privacy_handshake_state_none, + tls_identity_privacy_handshake_state_negotiates, + tls_identity_privacy_handshake_state_runs, +}; + +/** + * This enumeration tells which authentication mode is used. + */ +enum tls_session_type_e +{ + tls_session_type_none, ///< Initial value. + tls_session_type_full_authentication, ///< Full authentication is performed. + tls_session_type_original_session_resumption, ///< Session is being resumed. + tls_session_type_stateless_session_resumption, ///< Stateless session is being resumed, see RFC 4507. +#if defined(USE_FAST_EAP_TYPE) + tls_session_type_eap_fast_pac_session_resumption, ///< EAP-FAST stateless session using PAC is being resumed, see RFC 4851. + tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP, ///< EAP-FAST server unauthenticated provisioning mode (ADHP), see draft-cam-winget-eap-fast-provisioning-**. +#endif //#if defined(USE_FAST_EAP_TYPE) +}; + +/** + * This enumeration separates the different PEAP versions. + */ +enum peap_version_e +{ + peap_version_0_xp = 0x00, ///< This version is specified in draft-kamath-pppext-peapv0-00.txt. + peap_version_1 = 0x01, ///< This version is specified in draft-josefsson-pppext-eap-tls-eap-05.txt. + peap_version_2 = 0x02, ///< This version is specified in draft-josefsson-pppext-eap-tls-eap-07.txt. This is not implemented yet. + peap_version_none = 0xff, +}; + +enum eap_ttls_tunneled_message_type_e +{ + eap_ttls_tunneled_message_type_none, + eap_ttls_tunneled_message_type_eap, ///< Client and server handles these messages. + eap_ttls_tunneled_message_type_ms_chapv2_response, ///< Client sends and server handles these messages. + eap_ttls_tunneled_message_type_ms_chapv2_change_password, ///< Client sends and server handles these messages. + eap_ttls_tunneled_message_type_ms_chapv2_success, ///< Server sends and client handles these messages. + eap_ttls_tunneled_message_type_ms_chapv2_error, ///< Server sends and client handles these messages. + eap_ttls_tunneled_message_type_pap_response, ///< Client sends and server handles these messages. + eap_ttls_tunneled_message_type_pap_reply_message, ///< Server sends and client handles these messages. +}; + +enum eap_ttls_tunneled_message_state_e +{ + eap_ttls_tunneled_message_state_none, + eap_ttls_tunneled_message_state_process_identity_response, + eap_ttls_tunneled_message_state_process_response, + eap_ttls_tunneled_message_state_process_change_password_response, + eap_ttls_tunneled_message_state_process_identity_request, + eap_ttls_tunneled_message_state_process_identity_request_pending, + eap_ttls_tunneled_message_state_process_challenge_request, + eap_ttls_tunneled_message_state_process_success_request, + eap_ttls_tunneled_message_state_complete_success_request, + eap_ttls_tunneled_message_state_process_error_request, + eap_ttls_tunneled_message_state_complete_error_request, +}; + + +const u32_t EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_OFFSET = 0ul; +const u32_t EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH = 16ul; + +const u32_t EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET = EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH; +const u32_t EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_LENGTH = 1ul; + +const u32_t EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_FULL_LENGTH + = EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH + + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_LENGTH; + + +//-------------------------------------------------------------------- + +enum tls_alert_level_e +{ + tls_alert_level_warning = (1), ///< if an alert with a level of warning is received, + ///< the receiving party may decide at its discretion whether to treat this as + ///< a fatal error or not. + tls_alert_level_fatal = (2), ///< Alert messages with a level of fatal result + ///< in the immediate termination of the connection. In this case, other + ///< connections corresponding to the session may continue, but the + ///< session identifier must be invalidated, preventing the failed session + ///< from being used to establish new connections. + ///< All messages which are transmitted + ///< with a level of fatal must be treated as fatal messages. + tls_alert_level_none = (255) +}; + +enum tls_alert_description_e +{ + tls_alert_description_close_notify = (0), ///< This message notifies the recipient that the sender will not send + ///< any more messages on this connection. The session becomes + ///< unresumable if any connection is terminated without proper + ///< close_notify messages with level equal to warning. + + tls_alert_description_unexpected_message = (10), ///< This message is always fatal. An inappropriate message was received. + ///< and should never be observed in communication between proper + ///< implementations. + + tls_alert_description_bad_record_mac = (20), ///< This message is always fatal. + ///EAP_TLS_PEAP.doc + * and RFC 2246. + */ +class EAP_EXPORT tls_record_c +: public tls_base_record_c +, public abs_tls_am_services_c +, public abs_tls_message_hash_c +, public abs_tls_change_cipher_spec_c +, public abs_tls_apply_cipher_spec_c +, public abs_tls_base_application_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to adaptation module of TLS. + tls_am_services_c * m_am_tls_services; + + /// This flag tells whether the m_am_tls_services must be freed in destructor. + const bool m_free_am_tls_services; + + /// This is pointer to application object. Mostly this is used in PEAP and the application is tls_application_eap_core_c object. + tls_base_application_c * m_application; + + /// This flag tells whether the m_application must be freed in destructor. + const bool m_free_application; + + + + /// This object includes pending asyncronous actions or it may be empty. + /// The check_sent_tls_message() function call will check and complete pending actions. + eap_array_c m_completion_queue; + + + + /// This object includes received message in parsed tree. + tls_message_c m_received_tls_message; + + /// This object includes the new created message in parsed tree. + /// The send message will be generated from this. + tls_message_c m_new_tls_message; + + + + /// This object includes MD5 HASH of received handshake messages. + crypto_md5_c m_message_hash_md5; + + /// This object includes SHA1 HASH of received handshake messages. + crypto_sha1_c m_message_hash_sha1; + + /// This object includes MD5 HASH for certificate verify message. + eap_variable_data_c m_message_hash_md5_certificate_verify; + + /// This object includes SHA1 HASH for certificate verify message. + eap_variable_data_c m_message_hash_sha1_certificate_verify; + + /// This object includes MD5 HASH of Finished message of client. + eap_variable_data_c m_client_message_hash_md5_finished; + + /// This object includes SHA1 HASH of Finished message of client. + eap_variable_data_c m_client_message_hash_sha1_finished; + + /// This object includes MD5 HASH of Finished message of server. + eap_variable_data_c m_server_message_hash_md5_finished; + + /// This object includes SHA1 HASH of Finished message of server. + eap_variable_data_c m_server_message_hash_sha1_finished; + + + + /// This object includes client random value for client handshake message. + eap_variable_data_c m_client_handshake_random_value; + + /// This object includes server random value for server handshake message. + eap_variable_data_c m_server_handshake_random_value; + + /// This object includes session ID. + eap_variable_data_c m_session_id; + + /// This object includes master secret. + eap_variable_data_c m_master_secret; + + /// This object includes EAP-TLS master session key. + eap_master_session_key_c m_eap_master_session_key; + + + + /// This object includes shared secret key for MAC of send packets. + eap_variable_data_c m_new_send_mac_key; + + /// This object includes shared secret key for MAC of received packets. + eap_variable_data_c m_new_receive_mac_key; + + /// This object includes shared secret key for encryption of send packets. + eap_variable_data_c m_new_send_encryption_key; + + /// This object includes shared secret key for decryption of received packets. + eap_variable_data_c m_new_receive_encryption_key; + + /// This object includes initialization vector for block encryption of send packets. + eap_variable_data_c m_new_send_iv; + + /// This object includes initialization vector for decryption of received packets. + eap_variable_data_c m_new_receive_iv; + + + + /// This object includes shared secret key for MAC of send packets. + eap_variable_data_c m_send_mac_key; + + /// This object includes shared secret key for MAC of received packets. + eap_variable_data_c m_receive_mac_key; + + /// This object includes shared secret key for encryption of send packets. + eap_variable_data_c m_send_encryption_key; + + /// This object includes shared secret key for decryption of received packets. + eap_variable_data_c m_receive_encryption_key; + + /// This object includes initialization vector for block encryption of send packets. + eap_variable_data_c m_send_iv; + + /// This object includes initialization vector for decryption of received packets. + eap_variable_data_c m_receive_iv; + + + + /// This object includes session key seed for EAP-FAST. + eap_variable_data_c m_session_key_seed; + + /// This object includes MsChapv2 challenges for EAP-FAST. + eap_variable_data_c m_mschapv2_challenges; + + + /// This object includes Diffie-Hellman private key of this TLS end point. + eap_variable_data_c m_own_private_dhe_key; + + /// This object includes Diffie-Hellman public key of this TLS end point. + eap_variable_data_c m_own_public_dhe_key; + + /// This object includes Diffie-Hellman public key of other TLS end point. + eap_variable_data_c m_peer_public_dhe_key; + + /// This object includes Diffie-Hellman shared key of the TLS session. + eap_variable_data_c m_shared_dh_key; + + /// This object includes Diffie-Hellman prime of the TLS session. + eap_variable_data_c m_dhe_prime; + + /// This object includes Diffie-Hellman group generator of the TLS session. + eap_variable_data_c m_dhe_group_generator; + + + /// This object includes signed HASH. This is needed to store asyncronously completed signature creation. + eap_variable_data_c m_signed_message_hash; + + /// This object includes the premaster secret. + /// In RSA cipher suite client generates this and and encrypts with server public key. + /// Server decrypts this within the client key exchange message and decrypts this with private key. + /// In DHE cipher suite this is the shared Diffie-Hellman secret. + eap_variable_data_c m_premaster_secret; + + /// This object includes encrypted premaster secret of this TLS end point. + /// This is needed to store asyncronously completed result of encryption. + eap_variable_data_c m_own_encrypted_premaster_secret; + +#if defined(USE_FAST_EAP_TYPE) + /// This object includes PAC-Key of EAP-FAST. + /// PAC-Key is stored here before master secret can be generated. + eap_variable_data_c m_eap_fast_pac_key; +#endif //#if defined(USE_FAST_EAP_TYPE) + + /// This object includes the proposed cipher suites. + /// Objects are in host network order. + /// Client creates this list and server receives the list in client hello handshake message. + eap_array_c m_proposed_cipher_suites; + + /// This object includes the proposed compression methods. + /// Client creates this list and server receives the list in client hello handshake message. + eap_array_c m_proposed_compression_methods; + +#if defined(USE_EAP_TLS_SESSION_TICKET) + /// All supported TLS extensions. + eap_array_c m_supported_tls_extensions; + + /// All received TLS extensions. + eap_array_c m_received_tls_extensions; +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + + /// This is the realm part of the NAI of the client. + eap_variable_data_c m_NAI_realm; + + /// This is network identity of the sent packet from this authentication session. + eap_am_network_id_c m_send_network_id; + + /// This object includes certificate chain of this TLS end point. + /// This is needed to store asyncronously completed result of certificate chain qyery. + eap_array_c m_own_certificate_chain; + + /// This object includes certificate types required by this TLS end point. + /// This is needed to store asyncronously completed result of certificate type qyery. + eap_array_c m_own_certificate_types; + + /// This object includes certificate authorities required by this TLS end point. + /// This is needed to store asyncronously completed result of certificate authorities qyery. + eap_array_c m_own_certificate_authorities; + + /// This object includes certificate chain of the other TLS end point. + eap_array_c m_peer_certificate_chain; + + /// This variable includes validity result of certificate chain of the other TLS end point. + eap_status_e m_peer_certificate_chain_result; + + /// This variable includes validity result of signature verification of the received message that includes signature. + eap_status_e m_verify_signature; + + /// This object includes certificate types of the other TLS end point. + eap_array_c m_peer_certificate_types; + + /// This object includes certificate authorities of the other TLS end point. + eap_array_c m_peer_certificate_authorities; + + + + /// This is the resumed cipher suite from previous TLS session. + tls_cipher_suites_e m_resumed_cipher_suite; + + /// This is the selected cipher suite for this TLS session. + tls_cipher_suites_e m_selected_cipher_suite; + + /// This is the selected compression method for this TLS session. + /// NOTE this is always null compression. + tls_compression_method_e m_selected_compression_method; + + /// This is the active cipher suite of received packets for this TLS session. + tls_cipher_suites_e m_receive_cipher_suite; + + /// This is the active compression method of received packets for this TLS session. + /// NOTE this is always null compression. + tls_compression_method_e m_receive_compression_method; + + /// This is the active cipher suite of send packets for this TLS session. + tls_cipher_suites_e m_send_cipher_suite; + + /// This is the active compression method of send packets for this TLS session. + /// NOTE this is always null compression. + tls_compression_method_e m_send_compression_method; + + + + /// This is pointer to CBC block cipher algorithm of send packets when cipher suite uses block cipher. + abs_crypto_cbc_block_algorithm_c *m_send_block_cipher; + + /// This is pointer to CBC block cipher algorithm of received packets when cipher suite uses block cipher. + abs_crypto_cbc_block_algorithm_c *m_receive_block_cipher; + + /// This is pointer to stream cipher algorithm of send packets when cipher suite uses block cipher. + abs_crypto_stream_algorithm_c *m_send_stream_cipher; + + /// This is pointer to stream cipher algorithm of received packets when cipher suite uses block cipher. + abs_crypto_stream_algorithm_c *m_receive_stream_cipher; + + + + /// This is pointer to HMAC algorithm of send packets. + abs_crypto_hmac_algorithm_c *m_send_hmac_algorithm; + + /// This is pointer to HMAC algorithm of received packets. + abs_crypto_hmac_algorithm_c *m_receive_hmac_algorithm; + + + + /// This is the counter of send TLS-records. See chapters "6.2.3. Record payload protection" + /// and "6.1. Connection states" from RFC 2246. + /// Sequence number is initialized to zero and incrmented after each record is processed. + u64_t m_send_record_sequence_number; + + /// This is the counter of received TLS-records. See chapters "6.2.3. Record payload protection" + /// and "6.1. Connection states" from RFC 2246. + /// Sequence number is initialized to zero and incrmented after each record is processed. + u64_t m_receive_record_sequence_number; + + + + /// This variable stored the internal state of TLS-session. See tls_peap_state_e. + tls_peap_state_e m_tls_peap_state; + + /// This flag tells which TLS session type is selected, + /// full authentication, original session resumption or stateless session resumption (RFC 4507). + tls_session_type_e m_tls_session_type; + + + /// This is the EAP-type (TLS, PEAP or TTLS). + eap_type_value_e m_eap_type; + + /// This separates different PEAP versions (PEAPv2, PEAPv1 or XP PEAPv0). + peap_version_e m_peap_version; + + /// This variable stores the state of tunneled EAP-authentication. + eap_state_variable_e m_tunneled_eap_type_authentication_state; + + /// This variable saves the EAP-identifier of the last received EAP-message. + u8_t m_received_eap_identifier; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + /// This indicates whether this object is client (true) or server (false). + const bool m_is_client; + + /// This flag tells whether messages could be send in the check_sent_tls_message() function. + bool m_allow_message_send; + + /// This flag prevents recursive calls of the completion_action_check() function. + bool m_already_in_completion_action_check; + + /// This flag prevents recursive calls of the process_tls_records() function. + bool m_already_in_process_tls_records; + + + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_query_certificate_authorities_and_types; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_query_certificate_chain; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_query_cipher_suites_and_previous_session; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_query_dh_parameters; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_query_realm; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_select_cipher_suite_and_check_session_id; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_verify_certificate_chain; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_rsa_decrypt_with_private_key; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_rsa_encrypt_with_public_key; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_sign_with_private_key; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_verify_with_public_key; + + /// This flag tells whether this function call is pending (true value). + /// After this function call is completed with appropriate completion function flag is set to false value. + bool m_pending_query_tunnel_PAC; + + + /// This flag tells whether this instance is test version (true) or real version (false). + /// Test version allows many subsequent TLS-sessions. + bool m_tls_peap_test_version; + + /// The flag prevents multiple call of generate_key_material() function. + bool m_key_material_generated; + + /// This flag tells whether the server authenticates client (true) or not (false). + /// NOTE: Server and client read this value from it's configuration. + /// Server acts as this flag says. + /// Client does allow only client and server mutual authentication when this flag is true. + /// Client does allow server authentication too when this flag is false. + bool m_tls_peap_server_authenticates_client_policy_flag; + + /// Server reads this from configure. + /// Server initiates mutual authentication when value is true. + /// Server initiates server authentication when value is false. + bool m_tls_peap_server_authenticates_client_config_server; + + /// Client and server set this flag to indicate the current function. + /// Action is mutual authentication when value is true. + /// Action is server authentication when value is false. + bool m_tls_peap_server_authenticates_client_action; + + /// Client uses this flag to remember the the certificate request message. + bool m_tls_peap_server_requested_client_certificate; + + /// This flag tells whether we could send fatal TLS-alert message (true) or not (false). + /// This is set false after we receive one TLS-alert message. + bool m_could_send_fatal_alert_message; + + /// This flag tells whether we could send warning TLS-alert message (true) or not (false). + /// This is set false after we receive one TLS-alert message. + bool m_could_send_warning_alert_message; + + /// This flag tells whether the check_sent_tls_message() must send TLS-alert message (true) or not (false). + /// This flag is set after the TLS-alert message is generated. This flag forses send of the TLS-alert message. + bool m_force_tls_message_send; + + /// This flag tells whether the shutdown() function was called (true) or not (false). + bool m_shutdown_was_called; + + /// This flag tells whether TLS-messages should be set to separate TLS-records (true) or TLS-message should + /// be packed to same TLS-record if it is possible (false). + bool m_use_separate_tls_record; + + /// This flag tells whether extra padding of block cipher should be used. + bool m_use_extra_padding_length; + + /// NOTE this is against the RFC 2246 The TLS Protocol Version 1.0. + /// Look at chapter 7.4.4. Certificate request. + bool m_client_allows_empty_certificate_authorities_list; + + /// NOTE this is against the RFC 2246 The TLS Protocol Version 1.0. + /// Look at chapter 7.4.4. Certificate request. + bool m_server_sends_empty_certificate_authorities_list; + + /// This configurable option selects whether the special TLS/PEAP style + /// is used, the length field is added to all message fragments + /// even the message fits to one fragment except EAP-TLS-start, EAP-TLS-Acknowledge and + /// PEAP-application data. The client acknowledges tunneled EAP-Success message + /// with empty PEAP message. + bool m_use_tppd_tls_peap; + + /// On fast session resume server does not send tunneled EAP-Success. + /// Instead it sends plain EAP-Success. + /// True value of this flag allows this plain EAP-Success. + bool m_use_tppd_peapv1_acknowledge_hack; + + /// This configuration flag tells the server will offer new session ID to client. + bool m_server_offers_new_session_id; + + /// Client will receive a new session ticket in NewSessionTicket message. + bool m_will_receive_new_session_ticket; + + /// True value means EAP-FAST server sends piggypacked EAP-Identity/Request. + /// False value means EAP-FAST server does not send piggypacked EAP-Identity/Request, instead it waits empty Ack-message from client. + bool m_send_piggypacked_eap_identity_request; + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + /// Flag causes TLS client to use privacy. + bool m_tls_use_identity_privacy; + + /// Variable tells state of TLS identity privacy handshake. + tls_identity_privacy_handshake_state_e m_tls_identity_privacy_handshake_state; +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + +#if defined(USE_FAST_EAP_TYPE) + /// This flag allows use of dynamic provisioning of PAC in Server-Unauthenticated Mode. + /// This is called also Authenticated Diffie-Hellman Protocol (ADHP). + bool m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP; + + /// This flag allows use of dynamic provisioning of PAC in Server-Authenticated Mode. + bool m_fast_allow_server_authenticated_provisioning_mode; + + bool m_remove_tunnel_pac; +#endif //#if defined(USE_FAST_EAP_TYPE) + + //-------------------------------------------------- + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT eap_status_e allocate_handshake_message( + tls_handshake_message_c ** const tls_handshake_message, + eap_automatic_variable_c * const automatic_tls_handshake_message, + const tls_handshake_type_e handshake_type); + + EAP_FUNC_IMPORT eap_status_e allocate_handshake_message_copy( + tls_handshake_message_c ** const tls_handshake_message, + eap_automatic_variable_c * const automatic_tls_handshake_message, + tls_handshake_header_c * const tls_handshake_header); + + /** + * This function creates TLS Handshake/HelloRequest message. + */ + EAP_FUNC_IMPORT eap_status_e create_handshake_type_hello_request(); + + /** + * This function creates TLS Handshake/ClientHello message. + */ + EAP_FUNC_IMPORT eap_status_e create_handshake_type_client_hello(); + + /** + * This function creates TLS Handshake/ServerHello message. + */ + EAP_FUNC_IMPORT eap_status_e create_handshake_type_server_hello( + const u16_t selected_cipher_suite, + const u8_t selected_compression_method); + + /** + * This function creates TLS Handshake/Certificate message. + */ + EAP_FUNC_IMPORT eap_status_e create_handshake_type_certificate( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain); + + /** + * This function creates TLS Handshake/CertificateRequest message. + */ + EAP_FUNC_IMPORT eap_status_e create_handshake_type_certificate_request( + EAP_TEMPLATE_CONST eap_array_c * const certificate_types, + EAP_TEMPLATE_CONST eap_array_c * const certificate_authorities); + + /** + * This function creates TLS Handshake/ServerHelloDone message. + */ + EAP_FUNC_IMPORT eap_status_e create_handshake_type_server_hello_done(); + + /** + * This function completes creation of TLS Handshake/ServerKeyExchange message. + */ + EAP_FUNC_IMPORT eap_status_e complete_create_handshake_type_server_key_exchange(); + + /** + * This function creates TLS Handshake/ServerKeyExchange message. + * NOTE: this function is asyncronous. complete_create_handshake_type_server_key_exchange() + * completes this operation. + */ + EAP_FUNC_IMPORT eap_status_e create_handshake_type_server_key_exchange(); + + /** + * This function completes creation of TLS Handshake/ClientKeyExchange message. + */ + EAP_FUNC_IMPORT eap_status_e complete_create_handshake_type_client_key_exchange(); + + /** + * This function creates TLS Handshake/ClientKeyExchange message. + * NOTE: this function is asyncronous. complete_create_handshake_type_client_key_exchange() + * completes this operation. + */ + EAP_FUNC_IMPORT eap_status_e create_handshake_type_client_key_exchange(); + + /** + * This function completes creation of TLS Handshake/CertificateVerify message. + */ + EAP_FUNC_IMPORT eap_status_e complete_create_handshake_type_certificate_verify(); + + /** + * This function creates TLS Handshake/CertificateVerify message. + * NOTE: this function is asyncronous. + */ + EAP_FUNC_IMPORT eap_status_e create_handshake_type_certificate_verify(); + + /** + * This function creates TLS Handshake/Finished message. + */ + EAP_FUNC_IMPORT eap_status_e create_handshake_type_finished(); + + /** + * This function creates TLS Handshake/NewSessionTicket message. + */ + EAP_FUNC_IMPORT eap_status_e create_handshake_type_new_session_ticket(); + + /** + * This function creates TLS ChangeCipherSpec/ChangeCipherSpec message. + */ + EAP_FUNC_IMPORT eap_status_e create_change_cipher_spec_type_change_cipher_spec(); + + /** + * This function finish TLS handshake. + */ + EAP_FUNC_IMPORT eap_status_e finish_handshake(); + + /** + * This function creates TLS Alert/Alert message. + */ + EAP_FUNC_IMPORT eap_status_e create_tls_protocol_alert( + const tls_alert_description_e alert_description, + const tls_alert_level_e alert_level, + const eap_status_e result); + + /** + * This function creates TLS ApplicationData message. + */ + EAP_FUNC_IMPORT eap_status_e create_tls_application_data( + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset); + + /** + * This function starts tunneled authentication. + */ + EAP_FUNC_IMPORT eap_status_e start_peap_tunneled_authentication( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier, + const tls_session_type_e tls_session_type); + + /** + * This function parses TLS extension list, see RFC 4366. + */ + EAP_FUNC_IMPORT eap_status_e parse_tls_extension_list( + const u32_t handshake_data_length, + u32_t * const data_offset, + const tls_handshake_header_c * const tls_handshake_header, + tls_handshake_message_c * const tls_handshake_message); + + /** + * This function parses TLS Handshake/HelloRequest message. + */ + EAP_FUNC_IMPORT eap_status_e parse_handshake_type_hello_request( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length); + + + /** + * This function parses TLS Handshake/ClientHello message. + */ + EAP_FUNC_IMPORT eap_status_e parse_handshake_type_client_hello( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length); + + /** + * This function parses TLS Handshake/ServerHello message. + */ + EAP_FUNC_IMPORT eap_status_e parse_handshake_type_server_hello( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length); + + /** + * This function parses TLS Handshake/Certificate message. + */ + EAP_FUNC_IMPORT eap_status_e parse_handshake_type_certificate( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length); + + /** + * This function parses TLS Handshake/CertificateRequest message. + */ + EAP_FUNC_IMPORT eap_status_e parse_handshake_type_certificate_request( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length); + + /** + * This function parses TLS Handshake/ServerHelloDone message. + */ + EAP_FUNC_IMPORT eap_status_e parse_handshake_type_server_hello_done( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length); + + /** + * This function parses TLS Handshake/ServerKeyExchange message. + */ + EAP_FUNC_IMPORT eap_status_e parse_handshake_type_server_key_exchange( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length); + + /** + * This function parses TLS Handshake/ClientKeyExchange message. + */ + EAP_FUNC_IMPORT eap_status_e parse_handshake_type_client_key_exchange( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length); + + /** + * This function parses TLS Handshake/CertificateVerify message. + */ + EAP_FUNC_IMPORT eap_status_e parse_handshake_type_certificate_verify( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length); + + /** + * This function parses TLS Handshake/Finished message. + */ + EAP_FUNC_IMPORT eap_status_e parse_handshake_type_finished( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length); + + +#if defined(USE_EAP_TLS_SESSION_TICKET) + + /** + * This function parses TLS Handshake/NewSessionTicket message. + */ + EAP_FUNC_IMPORT eap_status_e parse_handshake_type_new_session_ticket( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length); + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + + /** + * This function parses TLS ChangeCipherSpec protocol. + */ + EAP_FUNC_IMPORT eap_status_e parse_tls_protocol_change_cipher_spec( + tls_record_message_c * const tls_record_message, + eap_variable_data_c * const tls_protocols_messages_buffer); + + /** + * This function parses TLS Alert protocol. + */ + EAP_FUNC_IMPORT eap_status_e parse_tls_protocol_alert( + tls_record_message_c * const tls_record_message, + eap_variable_data_c * const tls_protocols_messages_buffer); + + /** + * This function parses TLS Handshake protocol. + */ + EAP_FUNC_IMPORT eap_status_e parse_tls_protocol_handshake( + tls_record_message_c * const tls_record_message, + eap_variable_data_c * const tls_protocols_messages_buffer); + + /** + * This function parses TLS ApplicationData protocol. + */ + EAP_FUNC_IMPORT eap_status_e parse_tls_protocol_application_data( + tls_record_message_c * const tls_record_message, + eap_variable_data_c * const tls_protocols_messages_buffer); + + /** + * This function reassembles data of received consecutive TLS-records with same protocol to tls_record_message. + */ + EAP_FUNC_IMPORT eap_status_e reassemble_tls_records( + tls_record_message_c * const tls_record_message, + tls_record_header_c * const next_tls_record_header); + + /** + * This function processes received TLS records. + */ + EAP_FUNC_IMPORT eap_status_e process_tls_records(); + + /** + * This function processes received TLS message. + */ + EAP_FUNC_IMPORT eap_status_e process_tls_message(); + + EAP_FUNC_IMPORT tls_record_protocol_e get_next_tls_record_message_protocol(); + + EAP_FUNC_IMPORT tls_handshake_type_e get_next_tls_handshake_message_type(); + + /** + * This function analyses TLS Handshake/HelloRequest message. + */ + EAP_FUNC_IMPORT eap_status_e analyse_handshake_type_hello_request( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message); + + /** + * This function analyses TLS Handshake/ClientHello message. + */ + EAP_FUNC_IMPORT eap_status_e analyse_handshake_type_client_hello( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message); + + /** + * This function analyses TLS Handshake/ServerHello message. + */ + EAP_FUNC_IMPORT eap_status_e analyse_handshake_type_server_hello( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message); + + /** + * This function analyses TLS Handshake/Certificate message. + */ + EAP_FUNC_IMPORT eap_status_e analyse_handshake_type_certificate( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message); + + /** + * This function analyses TLS Handshake/CertificateRequest message. + */ + EAP_FUNC_IMPORT eap_status_e analyse_handshake_type_certificate_request( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message); + + /** + * This function analyses TLS Handshake/ServerHelloDone message. + */ + EAP_FUNC_IMPORT eap_status_e analyse_handshake_type_server_hello_done( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message); + + /** + * This function analyses TLS Handshake/ServerKeyExchange message. + */ + EAP_FUNC_IMPORT eap_status_e analyse_handshake_type_server_key_exchange( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message); + + /** + * This function analyses TLS Handshake/ClientKeyExchange message. + */ + EAP_FUNC_IMPORT eap_status_e analyse_handshake_type_client_key_exchange( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message); + + /** + * This function analyses TLS Handshake/CertificateVerify message. + */ + EAP_FUNC_IMPORT eap_status_e analyse_handshake_type_certificate_verify( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message); + + /** + * This function analyses TLS Handshake/Finished message. + */ + EAP_FUNC_IMPORT eap_status_e analyse_handshake_type_finished( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message, + const u8_t received_eap_identifier); + +#if defined(USE_EAP_TLS_SESSION_TICKET) + + /** + * This function analyses TLS Handshake/NewSessionTicket message. + */ + EAP_FUNC_IMPORT eap_status_e analyse_handshake_type_new_session_ticket( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message, + const u8_t received_eap_identifier); + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + /** + * This function analyses TLS ChangeCipherSpec protocol. + */ + EAP_FUNC_IMPORT eap_status_e analyse_tls_protocol_change_cipher_spec( + const tls_record_message_c * const record); + + /** + * This function analyses TLS Alert protocol. + */ + EAP_FUNC_IMPORT eap_status_e analyse_tls_protocol_alert( + const tls_record_message_c * const record); + + /** + * This function analyses TLS Handshake protocol. + */ + EAP_FUNC_IMPORT eap_status_e analyse_tls_protocol_handshake( + tls_record_message_c * const record, + const u8_t received_eap_identifier); + + /** + * This function analyses TLS ApplicationData protocol. + */ + EAP_FUNC_IMPORT eap_status_e analyse_tls_protocol_application_data( + const tls_record_message_c * const record, + const u8_t received_eap_identifier); + + /** + * This function checks whether all pending queries are completed. + */ + EAP_FUNC_IMPORT eap_status_e are_pending_queries_completed(); + + /** + * This function indicates state to lower layer. + */ + EAP_FUNC_IMPORT eap_status_e indicate_state_to_lower_layer( + const tls_peap_state_e indicated_state); + + /** + * This function indicates all message processed to lower layer. + */ + EAP_FUNC_IMPORT eap_status_e indicate_messages_processed(); + + /** + * This function combines TLS-protocols data to a buffer and sends TLS-message. + */ + EAP_FUNC_IMPORT eap_status_e send_tls_message(); + + /** + * This function checks all queries are completed. + * If all queries are completed this function send the pending LS-messages. + */ + EAP_FUNC_IMPORT eap_status_e check_sent_tls_message(); + + /** + * This function check the selected cipher suite is one of the proposed cipher suites. + */ + EAP_FUNC_IMPORT eap_status_e check_selected_cipher_suite( + const tls_cipher_suites_e selected_cipher_suite); + + /** + * This function check the selected compression method is one of the proposed compression method. + */ + EAP_FUNC_IMPORT eap_status_e check_selected_compression_method( + const tls_compression_method_e selected_compression_method); + + /** + * This function changes one 16-bit value pointed by parameter value from network order to host order. + */ + EAP_FUNC_IMPORT static eap_status_e u16_t_to_host_order( + u16_t * const value, + abs_eap_am_tools_c * const m_am_tools); + + /** + * This function changes one 16-bit value pointed by parameter value from host order to network order. + */ + EAP_FUNC_IMPORT static eap_status_e u16_t_to_network_order( + u16_t * const value, + abs_eap_am_tools_c * const m_am_tools); + + /** + * This function initializes MD5 and SHA hashes. + */ + EAP_FUNC_IMPORT eap_status_e message_hash_init(); + + /** + * This function adds the send and received TLS-handshake message to MD5 and SHA hashes. + * @param eap includes the buffer of the whole reassembled TLS-packet. + * @param packet_length is length in bytes of the TLS-packet. + */ + EAP_FUNC_IMPORT eap_status_e message_hash_update( + const bool true_when_parse_message, + const tls_handshake_type_e type, + u8_t * const tls_packet, + const u32_t tls_packet_length); + + /** + * This function obtains and concatenates the message digest of MD5 and SHA hashes. + * @param type tells the handshake type where the message digest is used. + * @param message_hash includes the buffer of the message digest. The message_hash_create() function initializes the buffer. + * @param client_originated is boolean flag. When client calls this function value is true, when server calls this function value is false. + */ + EAP_FUNC_IMPORT eap_status_e message_hash_create( + const bool true_when_parse_message, + const tls_handshake_type_e type, + eap_variable_data_c * const message_hash, + const bool client_originated); + + EAP_FUNC_IMPORT eap_status_e message_hash_final( + eap_variable_data_c * const md5_digest, + eap_variable_data_c * const sha1_digest); + + /** + * This function saves MD5 and SHA hashes for certificate verify message to + * member attributes m_message_hash_md5_certificate_verify and m_message_hash_sha1_certificate_verify. + */ + EAP_FUNC_IMPORT eap_status_e message_hash_save_certificate_verify(); + + /** + * This function saves MD5 and SHA hashes for finished message to + * member attributes message_hash_md5_finished and message_hash_sha1_finished. + */ + EAP_FUNC_IMPORT eap_status_e message_hash_save_finished( + const bool client_originated); + + /** + * This function creates certificate verfy message hash. + */ + EAP_FUNC_IMPORT eap_status_e message_hash_create_certificate_verify( + const bool client_originated); + + /** + * This function creates finished message hash. + * @param signed_message_hash is pointer to buffer of the message hash. + */ + EAP_FUNC_IMPORT eap_status_e message_hash_create_finished( + const bool client_originated_message, + eap_variable_data_c * const signed_message_hash); + + + /** + * This function creates SHA1 HASH of server key exchange message when DHE cipher suite is used. + */ + EAP_FUNC_IMPORT eap_status_e create_server_key_exchange_sha1_hash( + const eap_variable_data_c * const dhe_prime, + const eap_variable_data_c * const dhe_group_generator, + const eap_variable_data_c * const public_dhe_key, + eap_variable_data_c * const hash); + + /** + * This function creates MD5 HASH of server key exchange message when DHE cipher suite is used. + */ + EAP_FUNC_IMPORT eap_status_e create_server_key_exchange_md5_hash( + const eap_variable_data_c * const dhe_prime, + const eap_variable_data_c * const dhe_group_generator, + const eap_variable_data_c * const public_dhe_key, + eap_variable_data_c * const hash); + + /** + * This function verifies the HASH of server key exchange message is valid. + */ + EAP_FUNC_IMPORT eap_status_e verify_signature_of_server_key_exchange( + const eap_variable_data_c * const signed_server_key_exchange_hash); + + + + /** + * This function verifies the cipher suite is one of using 3DES_EDE_CBC_SHA. + */ + EAP_FUNC_IMPORT bool cipher_suite_is_3DES_EDE_CBC_SHA(tls_cipher_suites_e cipher_suite) const; + + /** + * This function verifies the cipher suite is one of using AES_128_CBC_SHA. + */ + EAP_FUNC_IMPORT bool cipher_suite_is_AES_128_CBC_SHA(tls_cipher_suites_e cipher_suite) const; + + /** + * This function verifies the cipher suite is one of using RC4_128_MD5. + */ + EAP_FUNC_IMPORT bool cipher_suite_is_RC4_128_MD5(tls_cipher_suites_e cipher_suite) const; + + /** + * This function verifies the cipher suite is one of using RC4_128_SHA. + */ + EAP_FUNC_IMPORT bool cipher_suite_is_RC4_128_SHA(tls_cipher_suites_e cipher_suite) const; + + + + /** + * This function verifies the current cipher suite is one of using TLS_RSA. + */ + EAP_FUNC_IMPORT bool cipher_suite_is_TLS_RSA() const; + + /** + * This function verifies the current cipher suite is one of using TLS_DHE_RSA. + */ + EAP_FUNC_IMPORT bool cipher_suite_is_TLS_DHE_RSA() const; + + /** + * This function verifies the current cipher suite is one of using TLS_DHE_DSS. + */ + EAP_FUNC_IMPORT bool cipher_suite_is_TLS_DHE_DSS() const; + +#if defined(USE_FAST_EAP_TYPE) + /** + * This function verifies the current cipher suite is one of using TLS_DH_anon. + */ + EAP_FUNC_IMPORT bool cipher_suite_is_TLS_DH_anon() const; +#endif //#if defined(USE_FAST_EAP_TYPE) + + +#if EAP_TLS_NOT_SUPPORTED_CIPHER_SUITE + This is not implemented yet + EAP_FUNC_IMPORT bool cipher_suite_is_TLS_DH_DSS() const; +#endif + + + + /** + * This function generates ephemeral Diffie-Hellman keys. + * Keys are stored to m_own_private_dhe_key and m_own_public_dhe_key. + */ + EAP_FUNC_IMPORT eap_status_e generate_dhe_keys(); + + /** + * This function generates master secret. + */ + EAP_FUNC_IMPORT eap_status_e generate_master_secret(); + + /** + * This function generates premaster secret. + */ + EAP_FUNC_IMPORT eap_status_e generate_premaster_secret(); + +#if defined(USE_FAST_EAP_TYPE) + /** + * This function generates master secret from EAP-FAST PAC-Key. + */ + EAP_FUNC_IMPORT eap_status_e generate_eap_fast_master_secret_from_pac_key( + const eap_variable_data_c * const pac_key); +#endif //#if defined(USE_FAST_EAP_TYPE) + + + EAP_FUNC_IMPORT void send_error_notification(const eap_status_e error); + + /** + * This function adds new completion action to the end of the m_completion_queue. + */ + EAP_FUNC_IMPORT eap_status_e completion_action_add( + tls_completion_action_e action); + + /** + * This function verifies all completion actions are completed. + */ + EAP_FUNC_IMPORT eap_status_e completion_action_clenup(); + + /** + * This function checks and completes completion actions. + * This function could return eap_status_pending_request if the + * first completion action cannot be completed yet. + */ + EAP_FUNC_IMPORT eap_status_e completion_action_check(); + + + + + /** + * This function generates random padding length. See chapter "6.2.3.2. CBC block cipher" in RFC 2246. + */ + EAP_FUNC_IMPORT u8_t get_extra_padding_length(const u8_t padding_length, const u32_t block_size); + + /** + * This function applies the current block cipher suite to send TLS-record. + */ + EAP_FUNC_IMPORT eap_status_e apply_send_block_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer, + abs_crypto_cbc_block_algorithm_c * const encrypt, + abs_crypto_hmac_algorithm_c * const mac); + + /** + * This function applies the current block cipher suite to received TLS-record. + */ + EAP_FUNC_IMPORT eap_status_e apply_receive_block_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer, + abs_crypto_cbc_block_algorithm_c * const decrypt, + abs_crypto_hmac_algorithm_c * const mac); + + /** + * This function applies the current stream cipher suite to send TLS-record. + */ + EAP_FUNC_IMPORT eap_status_e apply_send_stream_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer, + abs_crypto_stream_algorithm_c * const encrypt, + abs_crypto_hmac_algorithm_c * const mac); + + /** + * This function applies the current stream cipher suite to received TLS-record. + */ + EAP_FUNC_IMPORT eap_status_e apply_receive_stream_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer, + abs_crypto_stream_algorithm_c * const decrypt, + abs_crypto_hmac_algorithm_c * const mac); + + /** + * This function applies the current cipher suite to send TLS-record. + */ + EAP_FUNC_IMPORT eap_status_e apply_send_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer); + + /** + * This function applies the current cipher suite to received TLS-record. + */ + EAP_FUNC_IMPORT eap_status_e apply_receive_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer); + + /** This function hides create_tls_protocol_alert() call. + */ + EAP_FUNC_IMPORT eap_status_e eap_status_return_and_create_tls_protocol_alert( + const eap_status_e status); + + + /** + * This function sets the state of TLS. + */ + EAP_FUNC_IMPORT tls_peap_state_e get_state() const; + + /** + * This function gets the state of TLS. + */ + EAP_FUNC_IMPORT void set_state(const tls_peap_state_e state); + + /** + * This function verified the current state of TLS and parameter state are equal. + */ + EAP_FUNC_IMPORT bool verify_state(const tls_peap_state_e state); + + + + /** + * This function initializes encryption and decryption objects for block cipher suite. + */ + EAP_FUNC_IMPORT eap_status_e cipher_suite_initialization_cbc( + abs_crypto_cbc_block_algorithm_c ** const cbc_crypto_block_algorithm, + abs_crypto_block_algorithm_c * const crypto_block_algorithm, + const eap_variable_data_c * const iv, + const eap_variable_data_c * const key, + const bool true_when_encrypt); + + /** + * This function initializes HMAC algorithm objects. + */ + EAP_FUNC_IMPORT eap_status_e cipher_suite_initialization_hmac( + abs_crypto_hmac_algorithm_c * const hmac_algorithm, + const eap_variable_data_c * const key); + + /** + * This function initializes encryption and decryption objects for stream cipher suite. + */ + EAP_FUNC_IMPORT eap_status_e cipher_suite_initialization_stream( + abs_crypto_stream_algorithm_c * const crypto_stream_algorithm, + const eap_variable_data_c * const key, + const bool true_when_encrypt); + + /** + * This function initializes HMAC-SHA1 objects for current cipher suite. + */ + EAP_FUNC_IMPORT eap_status_e cipher_suite_initialization_hmac_sha1(const bool send_when_true); + + /** + * This function initializes HMAC-MD5 objects for current cipher suite. + */ + EAP_FUNC_IMPORT eap_status_e cipher_suite_initialization_hmac_md5(const bool send_when_true); + + /** + * This function initializes encryption and decryption objects for current cipher suite. + */ + EAP_FUNC_IMPORT eap_status_e cipher_suite_initialization( + const bool send_when_true); + + + + /** + * This function creates a new TLS-record message or returns tha last one if + * parameter protocol and ther last TLS-record message match. + */ + EAP_FUNC_IMPORT eap_status_e new_record_message( + tls_record_message_c ** const tls_record_message, + const tls_record_protocol_e protocol); + + /** + * This function creates a new TLS-record including handshake protocol message. + */ + EAP_FUNC_IMPORT eap_status_e add_record_message( + tls_handshake_message_c * const tls_handshake_message); + + /** + * This function creates a new TLS-record including change cipher spec protocol message. + */ + EAP_FUNC_IMPORT eap_status_e add_record_message( + tls_change_cipher_spec_message_c * const change_cipher_spec_message); + + /** + * This function creates a new TLS-record including alert protocol message. + */ + EAP_FUNC_IMPORT eap_status_e add_record_message( + tls_alert_message_c * const alert_message); + + /** + * This function creates a new TLS-record including application data protocol message. + */ + EAP_FUNC_IMPORT eap_status_e add_record_message( + tls_application_data_message_c * const application_data_message); + + EAP_FUNC_IMPORT void reset_block_ciphers(const bool send_when_true); + + EAP_FUNC_IMPORT void reset_stream_ciphers(const bool send_when_true); + + EAP_FUNC_IMPORT void reset_hmac_algorithms(const bool send_when_true); + + EAP_FUNC_IMPORT eap_status_e get_tls_prf_data( + const eap_variable_data_c * const master_secret, + const eap_variable_data_c * const client_random, + const eap_variable_data_c * const server_random, + const eap_variable_data_c * const label, + eap_variable_data_c * const prf_data, + const u32_t required_prf_data_length); + + EAP_FUNC_IMPORT eap_status_e set_tls_session_type(const tls_session_type_e tls_session_type); + + EAP_FUNC_IMPORT tls_session_type_e get_tls_session_type(); + + EAP_FUNC_IMPORT void set_tls_identity_privacy_handshake_state(const tls_identity_privacy_handshake_state_e state); + + EAP_FUNC_IMPORT void set_selected_cipher_suite(const tls_cipher_suites_e cipher_suite); + + EAP_FUNC_IMPORT eap_status_e set_receive_cipher_suite(const tls_cipher_suites_e cipher_suite); + + EAP_FUNC_IMPORT eap_status_e set_send_cipher_suite(const tls_cipher_suites_e cipher_suite); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the tls_record_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~tls_record_c(); + + /** + * The constructor of the tls_record_c class simply initializes the attributes. + * The tls_record_c object sends packets to the network using tls_base_record_c::get_type_partner() object. + */ + EAP_FUNC_IMPORT tls_record_c( + abs_eap_am_tools_c * const tools, ///< tools is pointer to the tools class. @see abs_eap_am_tools_c. + tls_am_services_c * const am_tls_services, ///< This is pointer to adaoptation module of TLS. + const bool free_am_tls_services, + tls_base_application_c * const application, ///< application is pointer to application object. + const bool free_application, + const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false). + const eap_type_value_e eap_type, + const eap_am_network_id_c * const receive_network_id); + + /** + * This function returns true when EAP-type is TTLS or PEAP. + */ + EAP_FUNC_IMPORT bool get_is_tunneled_tls(); + + /** + * This function sets the tunnel type. + */ + void set_peap_version( + const peap_version_e peap_version, ///< This is the PEAP version (PEAPv2, PEAPv1, XP PEAPv0), yes very nice to have many different versions. + const bool use_tppd_tls_peap, ///< Of course some vendors have own TLS/PEAP quirks. + const bool use_tppd_peapv1_acknowledge_hack); + + /** + * The configure() function is called after the constructor of the + * object is successfully executed. During the function call the object + * could query the configuration. Each derived class must define this function. + */ + EAP_FUNC_IMPORT eap_status_e configure(); + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT eap_status_e get_ttls_implicit_challenge( + eap_variable_data_c * const ttls_implicit_challenge, + const u32_t required_ttls_implicit_challenge_length); + + /** + * This function sets the NAI realm. + */ + EAP_FUNC_IMPORT eap_status_e set_nai_realm( + const eap_variable_data_c * const NAI_realm ///< This is the full NAI realm. + ); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT eap_status_e packet_send( + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU_length, + u32_t * const trailer_length); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT eap_status_e unload_module(const eap_type_value_e type); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key); + + // This is commented in abs_tls_base_application_c. + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + // This is commented in abs_tls_base_application_c::get_eap_type_list(). + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + /** + * This function sends starts EAP-TLS/PEAP after a start message is received. + */ + EAP_FUNC_IMPORT eap_status_e start_tls_peap_authentication( + const eap_variable_data_c * const received_authority_identity + ); + + /** + * This function processes the received packet. + * @param tls_packet includes the buffer of the whole reassembled TLS-packet. + */ + EAP_FUNC_IMPORT eap_status_e packet_process( + eap_variable_data_c * const tls_packet, + const u8_t received_eap_identifier); + + /** + * This function indicates the plain text EAP-Success or EAP-Failure packet is received. + * @param receive_network_id includes the addresses (network identity) and packet type. + * @param received_eap_identifier is the EAP-Identifier of the received EAP-Success packet. + */ + EAP_FUNC_IMPORT eap_status_e plain_eap_success_failure_packet_received( + const eap_am_network_id_c * const receive_network_id, + const eap_code_value_e received_eap_code, + const u8_t received_eap_identifier); + + /** + * This function indicates the empty Ack packet is received. + * This is used in TTLS. + * @param receive_network_id includes the addresses (network identity) and packet type. + * @param received_eap_identifier is the EAP-Identifier of the received EAP-Success packet. + */ + EAP_FUNC_IMPORT eap_status_e empty_ack_packet_received( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function must reset the state of object to same as + * state was after the configure() function call. + * If object reset succeeds this function must return eap_status_ok. + * If object reset fails this function must return corresponding error status. + * @return This function returns the status of reset operation. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + /** + * This function calculates the required key lengths. This function consults current cipher suite. + */ + EAP_FUNC_IMPORT u32_t get_key_expansion_size( + u32_t * const mac_key_length, + u32_t * const encryption_key_length, + u32_t * const iv_length, + u32_t * const session_key_seed_length, + u32_t * const mschapv2_challenges_length); + + /** + * This function generates the key material for the current cipher suite. + */ + EAP_FUNC_IMPORT eap_status_e generate_key_material(); + + EAP_FUNC_IMPORT eap_status_e set_tls_master_secret( + const eap_variable_data_c * const master_secret, + const eap_variable_data_c * const client_random, + const eap_variable_data_c * const server_random); + + /** + * This function changes the current cipher suite to negotiated cipher suite. + * Parameter send_when_true tells whether the send cipher suite (true) or receive cipher suite (false) + * is acquired to be changed. + */ + EAP_FUNC_IMPORT eap_status_e change_cipher_spec(const bool send_when_true); + + + // This is commented in tls_base_record_c::read_authority_identity(). + EAP_FUNC_IMPORT eap_status_e read_authority_identity(eap_variable_data_c * const authority_identity_payload); + + + // This is commented in abs_tls_am_services_c::complete_query_cipher_suites_and_previous_session(). + EAP_FUNC_IMPORT eap_status_e complete_query_cipher_suites_and_previous_session( + const tls_session_type_e session_type, + EAP_TEMPLATE_CONST eap_array_c * const cipher_suites, + EAP_TEMPLATE_CONST eap_array_c * const compression_methods, +#if defined(USE_EAP_TLS_SESSION_TICKET) + EAP_TEMPLATE_CONST eap_array_c * const tls_extensions, +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + const eap_variable_data_c * const resumed_session_id, + const eap_variable_data_c * const resumed_master_secret, + const tls_cipher_suites_e resumed_cipher_suite, + const eap_status_e completion_status); + + // This is commented in abs_tls_am_services_c::complete_select_cipher_suite_and_check_session_id(). + EAP_FUNC_IMPORT eap_status_e complete_select_cipher_suite_and_check_session_id( + const tls_session_type_e session_type, + const u16_t selected_cipher_suite, + const eap_variable_data_c * const session_id, + const eap_variable_data_c * const master_secret, +#if defined(USE_EAP_TLS_SESSION_TICKET) + const tls_extension_c * const new_session_ticket_or_null, +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + const eap_status_e completion_status); + +#if defined(USE_EAP_TLS_SESSION_TICKET) + // This is commented in abs_tls_am_services_c::complete_query_new_session_ticket(). + EAP_FUNC_IMPORT eap_status_e complete_query_new_session_ticket( + const tls_extension_c * const new_session_ticket_or_null); +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + + // This is commented in abs_tls_am_services_c::complete_verify_certificate_chain(). + EAP_FUNC_IMPORT eap_status_e complete_verify_certificate_chain( + const eap_status_e result); + + // This is commented in abs_tls_am_services_c::complete_query_certificate_chain(). + EAP_FUNC_IMPORT eap_status_e complete_query_certificate_chain( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain, + const eap_status_e completion_status); + + // This is commented in abs_tls_am_services_c::complete_query_certificate_authorities_and_types(). + EAP_FUNC_IMPORT eap_status_e complete_query_certificate_authorities_and_types( + EAP_TEMPLATE_CONST eap_array_c * const authorities, + EAP_TEMPLATE_CONST eap_array_c * const types, + const eap_status_e completion_status); + + // This is commented in abs_tls_am_services_c::complete_query_dh_parameters(). + EAP_FUNC_IMPORT eap_status_e complete_query_dh_parameters( + const eap_variable_data_c * const dhe_prime, + const eap_variable_data_c * const dhe_group_generator, + const eap_status_e completion_status); + + // This is commented in abs_tls_am_services_c::complete_query_realm(). + EAP_FUNC_IMPORT eap_status_e complete_query_realm( + const eap_variable_data_c * const realm, + const eap_status_e completion_status); + + // This is commented in abs_tls_am_services_c::complete_rsa_encrypt_with_public_key(). + EAP_FUNC_IMPORT eap_status_e complete_rsa_encrypt_with_public_key( + const eap_variable_data_c * const encrypted_premaster_secret, + const eap_status_e completion_status); + + // This is commented in abs_tls_am_services_c::complete_rsa_decrypt_with_private_key(). + EAP_FUNC_IMPORT eap_status_e complete_rsa_decrypt_with_private_key( + const eap_variable_data_c * const premaster_secret, + const eap_status_e completion_status); + + // This is commented in abs_tls_am_services_c::complete_sign_with_private_key(). + EAP_FUNC_IMPORT eap_status_e complete_sign_with_private_key( + const eap_variable_data_c * const message_hash, + const eap_status_e completion_status); + + // This is commented in abs_tls_am_services_c::complete_verify_with_public_key(). + EAP_FUNC_IMPORT eap_status_e complete_verify_with_public_key( + const eap_status_e verify_status); + + // See abs_tls_base_application_c::get_eap_tls_master_session_key(). + EAP_FUNC_IMPORT eap_status_e get_eap_tls_master_session_key( + eap_variable_data_c * const eap_tls_master_session_key, + eap_variable_data_c * const mschapv2_challenges + ); + + EAP_FUNC_IMPORT eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + // This is documented in abs_tls_base_application_c::set_session_timeout(). + EAP_FUNC_IMPORT eap_status_e set_session_timeout( + const u32_t session_timeout_ms); + +#if defined(USE_FAST_EAP_TYPE) + + EAP_FUNC_IMPORT eap_status_e complete_query_tunnel_PAC( + const eap_status_e in_completion_status, + const eap_fast_pac_type_e in_pac_type, + const eap_fast_variable_data_c * const in_tunnel_PAC_key_tlv, + const eap_fast_variable_data_c * const in_tunnel_PAC_opaque_tlv); + +#endif //#if defined(USE_FAST_EAP_TYPE) + + EAP_FUNC_IMPORT eap_status_e query_ttls_pap_username_and_password( + const eap_variable_data_c * const reply_message); + + EAP_FUNC_IMPORT eap_status_e complete_query_ttls_pap_username_and_password( + const eap_variable_data_c * const ttls_pap_username, + const eap_variable_data_c * const ttls_pap_password, + const eap_status_e query_result); + + EAP_FUNC_IMPORT eap_status_e verify_ttls_pap_username_and_password( + const eap_variable_data_c * const user_name, + const eap_variable_data_c * const user_password); + + EAP_FUNC_IMPORT eap_status_e complete_verify_ttls_pap_username_and_password( + const eap_status_e authentication_result, + const eap_variable_data_c * const ttls_pap_reply_message); + + //-------------------------------------------------- +}; // class tls_record_c + +#endif //#if !defined(_TLS_RECORD_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_record_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_record_header.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,174 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_RECORD_HEADER_H_) +#define _TLS_RECORD_HEADER_H_ + +#include "eap_tools.h" +#include "eap_header.h" +#include "eap_general_header_base.h" + +/** @file */ + + +/** + * This is enumeration of TLS-versions. + */ +enum tls_version_e +{ + tls_version_illegal = 0x0000, + tls_version_3_1 = 0x0301, + tls_version_last = 0x0301, ///< keep this same as the last acceptable version. +}; + + +/** + * This is enumeration of TLS-record protocols. + */ +enum tls_record_protocol_e +{ + tls_record_protocol_change_cipher_spec = (20), ///< This is change cipher spec. + tls_record_protocol_alert = (21), ///< This is alert. + tls_record_protocol_handshake = (22), ///< This is handshake. + tls_record_protocol_application_data = (23), ///< This is application data. + tls_record_protocol_none = (255), ///< This is initialization value. Meaning is no protocol selected. +}; + + +//---------------------------------------------------------------------------- + + +/// This class defines header of TLS record. +/** + * Here is a figure of header of TLS record. + * TLS-record data follows tls_record_header_c. + * @code + * TLS record-header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Protocol: aa | Version: 3 | Version: 1 | Length: m | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Length: n | + * +-+-+-+-+-+-+-+-+ + * @endcode + * + * @code + * The fields of this header are: + * 8-bits m_protocol; This is a TLS-protocol field. + * 16-bits m_version; This is a TLS-version. + * 16-bits m_length; This is a length field. The length (in bytes) of + * the following TLSPlaintext.fragment (TLS-record data). + * The length should not exceed 2^14. + * @endcode + * + */ +class EAP_EXPORT tls_record_header_c +: public eap_general_header_base_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + enum offsets + { + m_protocol_offset = 0ul, ///< This is offset of the protocol 8-bit field. + m_version_offset = m_protocol_offset+sizeof(u8_t), ///< This is offset of the version 16-bit field. + m_length_offset = m_version_offset+sizeof(u16_t), ///< This is offset of the length 16-bit field. + m_data_offset = m_length_offset+sizeof(u16_t), ///< This is offset of the data of TLS-record. + }; + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /// Destructor does nothing. + virtual ~tls_record_header_c(); + + /// Constructor initializes the class. + tls_record_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length); + + /// This function returns protocol of the TLS-record. + tls_record_protocol_e get_protocol() const; + + /// This function returns version of the TLS-record. + tls_version_e get_version() const; + + /// This function returns data length of the TLS-record. + /// The length (in bytes) of the following TLSPlaintext.fragment (TLS-record data). The length should not exceed 2^14. + u16_t get_data_length() const; + + /// This function returns header length of the TLS-record. This includes only protocol, version and length fiels. + static u32_t get_header_length(); + + /// This function returns pointer to offset of the TLS-record data. + /// @param offset is the offset of queried data in bytes. + /// @param contignuous_bytes is the length of queried data in bytes. + u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const; + + + /// This function returns pointer to begin of the TLS-record data. + /// @param contignuous_bytes is the length of queried data in bytes. + u8_t * get_data(const u32_t contignuous_bytes) const; + + + static eap_const_string get_tls_protocol_string(const tls_record_protocol_e protocol); + + /// This function returns debug strings of the TLS-protocol values. + eap_const_string get_tls_protocol_string() const; + + /// This function sets the protocol of TLS-record. + void set_protocol(tls_record_protocol_e protocol); + + /// This function sets the version of the TLS-record. + void set_version(tls_version_e version); + + /// This function sets the data length of the TLS-record. + void set_data_length(const u16_t p_length); + + /// This function resets the TLS-record header. + void reset_header( + const u16_t buffer_length, + const tls_version_e version); + + /// This function checks the header is valid. + eap_status_e check_header() const; + + // + //-------------------------------------------------- +}; // class tls_record_header_c + + +//-------------------------------------------------- + +#endif //#if !defined(_TLS_RECORD_HEADER_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_record_message.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/include/tls_record_message.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,324 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_TLS_RECORD_MESSAGE_H_) +#define _TLS_RECORD_MESSAGE_H_ + +#include "eap_tools.h" +#include "eap_array.h" +#include "tls_record_header.h" +#include "tls_handshake_message.h" +#include "tls_change_cipher_spec_message.h" +#include "tls_alert_message.h" +#include "tls_application_data_message.h" +#include "abs_tls_message_hash.h" + + +/** @file */ + +//---------------------------------------------------------------------------- + +/** + * This class defines one TLS record message. + * Note the protocols are exclusive. Only one protocol is allowed in one record message. + * The m_protocol attribute of m_tls_record_header attribute tells the used protocol. + * Parse and analyse of TLS-records is asyncronous. + * m_analyse_index tells the index of message where asyncronous + * analyse of TLS-record must continue. + * Analysed records are skipped during the asyncronous + * analyse of records. Asyncronous analyse is needed + * because of the PKI functions are asyncronous in + * Symbian. + */ +class EAP_EXPORT tls_record_message_c +{ +private: + //-------------------------------------------------- + + /// This is pointer to the tools class. @see abs_eap_am_tools_c. + abs_eap_am_tools_c * const m_am_tools; + + /// This is pointer to interface of message HASH creation. See abs_tls_message_hash_c. + abs_tls_message_hash_c * const m_message_hash; + + /// This is the protocol of the TLS-record. See tls_record_protocol_e. + tls_record_protocol_e m_protocol; + + /// This is the version of the TLS-record. + tls_version_e m_version; + + /// This is the length of the data of the TLS-record, not including the header. + /// The length (in bytes) of the following TLSPlaintext.fragment (TLS-record data). The length should not exceed 2^14. + u32_t m_length; + + /// This flag tells the TLS-record header is included to m_record_message_data. + bool m_tls_record_header_is_included; + + /// This buffer is used both sent and received TLS-records. + /// This buffer includes reference to the record included in the whole received TLS-message (header+data) in tls_message_c. + /// This buffer includes whole data of TLS-record of sent TLS-message. + eap_variable_data_c m_record_message_data; + + /// This is the index of message where asyncronous analyse of TLS-message must continue. + u32_t m_analyse_index; + + /// This flag tells this record is parsed. + bool m_parsed_record; + + /// This flag tells whether the cipher suite is applied to this record (true) or not (false). + bool m_cipher_suite_applied; + + /// This array includes Handshake messages. There could be many handshake messages. + eap_array_c m_handshake_messages; + /// This array includes ChangeCipherSpec messages. Normally there should be only one message. + eap_array_c m_change_cipher_spec_messages; + /// This array includes Alert messages. Normally there should be only one message. + eap_array_c m_alert_messages; + /// This array includes Application data messages. + eap_array_c m_application_data_messages; + + /// This indicates whether this object is client (true) or server (false). This is mostly for traces. + const bool m_is_client; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + //-------------------------------------------------- + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + EAP_FUNC_IMPORT void set_is_valid(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + /** + * The destructor of the tls_record_message_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~tls_record_message_c(); + + /** + * The constructor of the tls_record_c class simply initializes the attributes. + */ + EAP_FUNC_IMPORT tls_record_message_c( + abs_eap_am_tools_c * const tools, + abs_tls_message_hash_c * const message_hash, + const bool is_client); + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + + /** + * This function returns the index of message where analyse must continue. + */ + EAP_FUNC_IMPORT u32_t get_analyse_index() const; + + /** + * This function saves the index of message where analyse must continue. + */ + EAP_FUNC_IMPORT void save_analyse_index(const u32_t analyse_index); + + + /** + * This function returns the flag that tells whether this record is parsed (true) or not (flase). + */ + EAP_FUNC_IMPORT bool get_parsed_record() const; + + /** + * This function sets the flag that tells this record is parsed. + */ + EAP_FUNC_IMPORT void set_parsed_record(); + + + /** + * This function returns the flag that tells whether the TLS-record header is included to m_record_message_data (true) or not (flase). + */ + EAP_FUNC_IMPORT bool get_tls_record_header_is_included() const; + + /** + * This function sets the flag that tells whether the TLS-record header is included to m_record_message_data (true) or not (flase). + */ + EAP_FUNC_IMPORT void set_tls_record_header_is_included(const bool when_true_tls_record_header_is_included); + + + /** + * This function returns the flag that tells whether the cipher suite is applied to this record (true) or not (flase). + */ + EAP_FUNC_IMPORT bool get_cipher_suite_applied() const; + + /** + * This function sets the flag that tells the cipher suite is applied to this record. + */ + EAP_FUNC_IMPORT void set_cipher_suite_applied(); + + + /** + * This function sets the protocol of this record. + */ + EAP_FUNC_IMPORT eap_status_e set_protocol( + tls_record_protocol_e protocol); + + /** + * This function sets the version of TLS. + */ + EAP_FUNC_IMPORT eap_status_e set_version( + tls_version_e version); + + /** + * This function copies the appropriate fields of this record. + */ + EAP_FUNC_IMPORT eap_status_e set_record_header_copy( + const tls_record_header_c * const tls_record_header); + + /** + * This function sets the reference of TLS-record data. + * NOTE this does not copy the message. + */ + EAP_FUNC_IMPORT eap_status_e set_record_message_data( + void * const data, + const u32_t data_length); + + /** + * This function returns the reference of TLS-record data. + * NOTE this is not a copy of the message. + */ + EAP_FUNC_IMPORT eap_variable_data_c * get_record_message_data(); + + /** + * This function returns the protocol of TLS-record. + */ + EAP_FUNC_IMPORT tls_record_protocol_e get_protocol() const; + + /** + * This function returns the version of TLS-record. + */ + EAP_FUNC_IMPORT tls_version_e get_version() const; + + /** + * This function returns the data length of TLS-record. + */ + EAP_FUNC_IMPORT u32_t get_data_length() const; + + /** + * This function adds the data length of TLS-record. + */ + EAP_FUNC_IMPORT eap_status_e add_data_length(const u32_t data_length); + + /** + * This function adds TLS-handshake message to this TLS-record. + */ + EAP_FUNC_IMPORT eap_status_e add_handshake_message( + tls_handshake_message_c * const handshake_message, + const bool free_handshake_message); + + /** + * This function adds TLS-change cipher spec message to this TLS-record. + */ + EAP_FUNC_IMPORT eap_status_e add_change_cipher_spec_message( + tls_change_cipher_spec_message_c * const change_cipher_spec_message, + const bool free_change_cipher_spec_message); + + /** + * This function adds TLS-alert message to this TLS-record. + */ + EAP_FUNC_IMPORT eap_status_e add_alert_message( + tls_alert_message_c * const alert_message, + const bool free_alert_message); + + /** + * This function adds TLS-application data message to this TLS-record. + */ + EAP_FUNC_IMPORT eap_status_e add_application_data_message( + tls_application_data_message_c * const alert_message, + const bool free_alert_message); + + /** + * This function adds data of every TLS-protocol message to internal message buffer (m_record_message_data). + */ + EAP_FUNC_IMPORT eap_status_e add_message_data(); + + /** + * This function returns count of the TLS-handshake messages. + */ + EAP_FUNC_IMPORT u32_t get_handshake_count() const; + + /** + * This function returns count of the TLS-change cipher spec messages. + */ + EAP_FUNC_IMPORT u32_t get_change_cipher_spec_count() const; + + /** + * This function returns count of the TLS-alert messages. + */ + EAP_FUNC_IMPORT u32_t get_alert_count() const; + + /** + * This function returns count of the TLS-application data messages. + */ + EAP_FUNC_IMPORT u32_t get_application_data_count() const; + + /** + * This function returns the TLS-handshake message selected by index. + */ + EAP_FUNC_IMPORT tls_handshake_message_c * get_handshake( + const u32_t index) EAP_TEMPLATE_CONST; + + /** + * This function returns the TLS-change cipher spec message selected by index. + */ + EAP_FUNC_IMPORT const tls_change_cipher_spec_message_c * get_change_cipher_spec( + const u32_t index) const; + + /** + * This function returns the TLS-alert message selected by index. + */ + EAP_FUNC_IMPORT const tls_alert_message_c * get_alert( + const u32_t index) const; + + /** + * This function returns the TLS-application data message selected by index. + */ + EAP_FUNC_IMPORT tls_application_data_message_c * get_application_data( + const u32_t index) const; + + // + //-------------------------------------------------- +}; // class tls_record_message_c + + +//-------------------------------------------------- + +#endif //#if !defined(_TLS_RECORD_MESSAGE_H_) + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,46 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_tls_peap + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_application_eap_core.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_application_ttls_plain_mschapv2.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_message.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_completion.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_record.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_base_record.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_base_application.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_record_message.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_handshake_message.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_alert_message.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_application_data_message.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_change_cipher_spec_message.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_peap_tlv_payloads.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_handshake_header.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_peap_tlv_header.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_record_header.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_extension.cpp \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_peap_types.cpp \ + $(WLAN_COMMON)/type/diameter/src/eap_diameter_avp_header.cpp \ + $(WLAN_COMMON)/type/diameter/src/eap_diameter_payloads.cpp \ + $(WLAN_COMMON)/type/diameter/src/eap_diameter_avp_code.cpp + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_tls_tools.$(LIB) \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_type_tls_peap_simulator.$(LIB) \ + -lstdc++ + +ifdef USE_MSCHAPV2_EAP_TYPE +# This is needed for EAP-TTLS/plain MsChapv2. +LIBS := ${LIBS} \ + $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_type_mschapv2.$(LIB) +endif + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_alert_message.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_alert_message.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,243 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 122 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_tools.h" +#include "eap_array.h" +#include "eap_array_algorithms.h" +#include "tls_alert_message.h" +#include "tls_record_header.h" +#include "tls_peap_types.h" + + +/** @file */ + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_alert_message_c::~tls_alert_message_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_alert_message_c::tls_alert_message_c( + abs_eap_am_tools_c * const tools, + const bool is_client) +: m_am_tools(tools) +, m_tls_alert_message_buffer(tools) +, m_alert_level(tls_alert_level_none) +, m_alert_description(tls_alert_description_none) +, m_is_client(is_client) +, m_is_valid(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_alert_message_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_alert_message_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_alert_message_c::set_alert_level(const tls_alert_level_e alert_level) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_alert_level = alert_level; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_alert_level_e tls_alert_message_c::get_alert_level() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_alert_level; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_alert_message_c::set_alert_description(const tls_alert_description_e alert_description) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_alert_description = alert_description; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_alert_description_e tls_alert_message_c::get_alert_description() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_alert_description; +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_alert_message_c::create_message_data() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: data_function: tls_alert_description_e::create_message_data()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eap_status_not_supported; + + m_tls_alert_message_buffer.reset(); + status = m_tls_alert_message_buffer.set_buffer_length(TLS_PEAP_DEFAULT_RECORD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t alert_data_length_start = m_tls_alert_message_buffer.get_data_length(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + u8_t alert_level = static_cast(m_alert_level); + + status = m_tls_alert_message_buffer.add_data( + &alert_level, + sizeof(alert_level)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-alert alert_level"), + &alert_level, + sizeof(alert_level))); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + u8_t alert_description = static_cast(m_alert_description); + + status = m_tls_alert_message_buffer.add_data( + &alert_description, + sizeof(alert_description)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-alert alert_description"), + &alert_description, + sizeof(alert_description))); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (status == eap_status_ok) + { + u32_t alert_data_length = m_tls_alert_message_buffer.get_data_length() - alert_data_length_start; + EAP_UNREFERENCED_PARAMETER(alert_data_length); // in release + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("alert length %d bytes.\n"), + alert_data_length)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_alert_message_c::add_message_data( + eap_variable_data_c * const tls_message_buffer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: data_function: tls_alert_message_c::add_message_data()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eap_status_not_supported; + + if (m_tls_alert_message_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = tls_message_buffer->add_data( + m_tls_alert_message_buffer.get_data(m_tls_alert_message_buffer.get_data_length()), + m_tls_alert_message_buffer.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_application_data_message.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_application_data_message.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,213 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 123 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_tools.h" +#include "eap_array.h" +#include "eap_array_algorithms.h" +#include "tls_application_data_message.h" +#include "tls_record_header.h" +#include "eap_buffer.h" +#include "tls_peap_types.h" + + +/** @file */ + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_application_data_message_c::~tls_application_data_message_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_application_data_message_c::tls_application_data_message_c( + abs_eap_am_tools_c * const tools, + const bool is_client) +: m_am_tools(tools) +, m_application_data(tools) +, m_is_client(is_client) +, m_is_analysed(false) +, m_is_valid(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_application_data_message_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_application_data_message_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_application_data_message_c::set_is_analysed() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_analysed = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_application_data_message_c::get_is_analysed() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_analysed; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_data_message_c::set_application_data( + const u8_t * const packet, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: data_function: tls_application_data_message_c::set_application_data()\n"))); + + eap_status_e status = eap_status_not_supported; + + m_application_data.reset(); + + if (m_application_data.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_application_data.add_data( + packet, + packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * tls_application_data_message_c::get_application_data() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_application_data; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_data_message_c::add_message_data( + eap_variable_data_c * const tls_message_buffer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: data_function: tls_application_data_message_c::add_message_data()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eap_status_not_supported; + + u32_t data_length_start = tls_message_buffer->get_data_length(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + status = tls_message_buffer->add_data( + m_application_data.get_data(m_application_data.get_data_length()), + m_application_data.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (status == eap_status_ok) + { + u32_t application_data_length = tls_message_buffer->get_data_length() - data_length_start; + EAP_UNREFERENCED_PARAMETER(application_data_length); // in release + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("application data length %d bytes.\n"), + application_data_length)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS-application data"), + tls_message_buffer->get_data_offset(data_length_start, application_data_length), + application_data_length)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_application_eap_core.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_application_eap_core.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,7779 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 124 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "eap_core.h" +#include "eap_type_tls_peap_types.h" +#include "tls_record_header.h" +#include "abs_tls_base_application.h" +#include "tls_application_eap_core.h" +#include "tls_peap_types.h" +#include "tls_peap_tlv_header.h" +#include "eap_diameter_avp_header.h" +#include "eap_state_notification.h" +#include "eap_crypto_api.h" +#include "eap_header_string.h" +#include "abs_eap_am_mutex.h" +#include "eap_config.h" +#include "eapol_header.h" +#include "eap_network_id_selector.h" +#include "eap_tlv_message_data.h" +#include "eap_array_algorithms.h" +#include "eap_automatic_variable.h" +#include "eap_base_type.h" + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + #include "eap_type_mschapv2_types.h" + #include "eap_type_mschapv2_header.h" +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +const u32_t TLV_NONCE_LENGTH = 32ul; +const u32_t TLV_MAC_LENGTH = 16ul; + +const u32_t TLV_NONCE_OFFSET = 4ul; +const u32_t TLV_MAC_OFFSET = TLV_NONCE_OFFSET + TLV_NONCE_LENGTH; + +const u32_t TLS_PEAP_V2_TK_OFFSET = 32ul; +const u32_t TLS_PEAP_V2_TK_LENGTH = 32ul; + +const u32_t TLS_PEAP_V2_COMPOUND_MAC_KEY_LENGTH = 20ul; + +const u32_t TLS_PEAP_V2_COMPOUND_SESSION_KEY_LENGTH = 128ul; + +//----------------------------------------------------------------------------------------- + +/// This is pseudo Ethernet and EAPOL header. +/// This is used in trace of tunneled EAP-packet. +const u8_t EAP_PSEUDO_ETHERNET_HEADER[] = +{ + 0x50, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x88, 0x8e, 0x01, 0x00, + 0x00, 0x00 +}; + +const u32_t EAP_PSEUDO_EAPOL_HEADER_OFFSET = 14ul; + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_application_eap_core_c::~tls_application_eap_core_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: function: tls_application_eap_core_c::~tls_application_eap_core_c(): ") + EAPL("this = 0x%08x, m_eap_core") + EAPL(" = 0x%08x (validity %d).\n"), + (m_is_client == true ? "client": "server"), + this, + m_eap_core, + ((m_eap_core != 0) ? m_eap_core->get_is_valid(): true))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::~tls_application_eap_core_c()"); + + EAP_ASSERT(m_shutdown_was_called == true); + + if (m_free_eap_core == true) + { + delete m_eap_core; + } + m_eap_core = 0; + + m_application_partner = 0; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_application_eap_core_c::tls_application_eap_core_c( + abs_eap_am_tools_c * const tools, + eap_core_c * const eap_core, + const bool free_eap_core, + const bool is_client_when_true, + const eap_type_value_e eap_type, + const eap_am_network_id_c * const receive_network_id) + : m_am_tools(tools) + , m_eap_core(eap_core) + , m_free_eap_core(free_eap_core) + , m_application_partner(0) + , m_receive_network_id(tools) + , m_eap_type(eap_type) + , m_peap_version(peap_version_none) + , m_peap_tunneled_eap_type(eap_type_none) + , m_tunneled_eap_type_authentication_state(eap_state_none) + , m_peapv2_tlv_payloads(tools) + , m_peap_v2_client_nonce(tools) + , m_peap_v2_server_nonce(tools) + , m_peap_v2_IPMKn(tools) + , m_peap_v2_ISKn(tools) + , m_peap_v2_CMK_B1_server(tools) + , m_peap_v2_CMK_B2_client(tools) + , m_peap_v2_CSK(tools, eap_type) + , m_accepted_tunneled_eap_types(tools) + , m_pseudo_ethernet_header(tools) + , m_ttls_received_payloads(tools) + , m_ttls_message_type(eap_ttls_tunneled_message_type_none) + , m_ttls_sent_eap_packet(tools) +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + , m_ttls_user_name(tools) + , m_ttls_implicit_challenge(tools) + , m_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_none) +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + , m_error_probability(0UL) + , m_received_eap_identifier(0u) + , m_enable_random_errors(false) + , m_manipulate_only_tunneled_messages(false) + , m_is_valid(false) + , m_is_client(is_client_when_true) + , m_shutdown_was_called(false) + , m_tls_session_type(tls_session_type_none) + , m_peap_allow_tunneled_session_resumption(true) + , m_use_tppd_tls_peap(true) + , m_use_tppd_peapv1_acknowledge_hack(false) +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + , m_server_use_peapv1_extensions_request(false) + , m_client_send_peapv1_extensions_response(false) +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + , m_tunneled_eap_in_ttls(true) + , m_ttls_plain_ms_chap_v2_eap_identifier(0ul) +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + , m_use_eap_expanded_type(false) + , m_wait_plain_eap_success(true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: function: tls_application_eap_core_c::tls_application_eap_core_c(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::tls_application_eap_core_c()"); + + if (m_eap_core == 0 + || m_eap_core->get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: %s: function: tls_application_eap_core_c() failed, ") + EAPL("m_eap_core is invalid.\n"), + (m_is_client == true ? "client": "server"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + m_eap_core->set_partner(this); + + eap_status_e status = m_receive_network_id.set_copy_of_network_id(receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + + status = m_pseudo_ethernet_header.set_copy_of_buffer( + EAP_PSEUDO_ETHERNET_HEADER, + sizeof(EAP_PSEUDO_ETHERNET_HEADER)); + if (status != eap_status_ok) + { + // Do not care of this error. + // User will check the validity of m_pseudo_ethernet_header. + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_application_eap_core_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_application_eap_core_c::set_peap_version( + const peap_version_e peap_version, + const bool use_tppd_tls_peap, + const bool use_tppd_peapv1_acknowledge_hack) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::set_peap_version()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::set_peap_version()"); + + m_peap_version = peap_version; + + m_use_tppd_tls_peap = use_tppd_tls_peap; + + m_use_tppd_peapv1_acknowledge_hack = use_tppd_peapv1_acknowledge_hack; + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: function: tls_application_eap_core_c::configure(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::configure()"); + + eap_status_e status = eap_status_process_general_error; + + //---------------------------------------------------------- + + { + eap_variable_data_c tunneled_eap_type(m_am_tools); + + if (m_is_client == true) + { + status = get_application_partner()->read_configure( + cf_str_PEAP_tunneled_eap_type_hex_data.get_field(), + &tunneled_eap_type); + if (status == eap_status_illegal_configure_type) + { + status = get_application_partner()->read_configure( + cf_str_PEAP_tunneled_eap_type_u32_t.get_field(), + &tunneled_eap_type); + } + } +#if defined(USE_EAP_CORE_SERVER) + else + { + status = get_application_partner()->read_configure( + cf_str_PEAP_server_tunneled_eap_type_hex_data.get_field(), + &tunneled_eap_type); + if (status == eap_status_illegal_configure_type) + { + status = get_application_partner()->read_configure( + cf_str_PEAP_server_tunneled_eap_type_u32_t.get_field(), + &tunneled_eap_type); + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (tunneled_eap_type.get_data_length() == sizeof(u32_t) + && tunneled_eap_type.get_data(sizeof(u32_t)) != 0) + { + u32_t *p_eap_type = reinterpret_cast( + tunneled_eap_type.get_data(sizeof(u32_t))); + if (p_eap_type != 0) + { + m_peap_tunneled_eap_type = static_cast(*p_eap_type); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } +//#if defined(USE_EAP_EXPANDED_TYPES) + else if (tunneled_eap_type.get_data_length() + == eap_expanded_type_c::get_eap_expanded_type_size() + && tunneled_eap_type.get_data(tunneled_eap_type.get_data_length()) != 0) + { + eap_expanded_type_c eap_type(eap_type_none); + + status = eap_type.set_expanded_type_data( + m_am_tools, + &tunneled_eap_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_type.get_type_data( + m_am_tools, + &m_peap_tunneled_eap_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +//#endif //#if defined(USE_EAP_EXPANDED_TYPES) + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s: No tunneled EAP-type configured, %s.\n"), + (m_is_client == true ? "client": "server"), + cf_str_EAP_default_type_hex_data.get_field()->get_field())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + if ( +#if defined(USE_EAP_EXPANDED_TYPES) + m_peap_tunneled_eap_type == eap_expanded_type_ttls_plain_mschapv2.get_type() +#else + m_peap_tunneled_eap_type == eap_type_plain_mschapv2 +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + ) + { + // This is special case. + // We must tell to inner EAP-stack to use EAP-MsChapv2. + m_tunneled_eap_in_ttls = false; + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + } + + //---------------------------------------------------------- + + { + eap_variable_data_c allowed_eap_types(m_am_tools); + + const eap_configuration_field_c * field + = cf_str_PEAP_accepted_tunneled_client_types_hex_data.get_field(); + if (m_is_client == false) + { + field = cf_str_PEAP_accepted_tunneled_server_types_hex_data.get_field(); + } + + eap_status_e status = read_configure( + field, + &allowed_eap_types); + if (status == eap_status_ok + && allowed_eap_types.get_is_valid_data() == true) + { + // OK read. + u32_t type_count = allowed_eap_types.get_data_length() + /eap_expanded_type_c::get_eap_expanded_type_size(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: tls_application_eap_core_c::configure(): Tunneled EAP-type count %d, hex data.\n"), + (m_is_client == true ? "client": "server"), + type_count)); + + for (u32_t ind = 0ul; ind < type_count; ind++) + { + eap_type_value_e * const eap_type = new eap_type_value_e(eap_type_none); + if (eap_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = eap_expanded_type_c::read_type( + m_am_tools, + ind, + allowed_eap_types.get_data(allowed_eap_types.get_data_length()), + allowed_eap_types.get_data_length(), + eap_type); + if (status != eap_status_ok) + { + delete eap_type; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: tls_application_eap_core_c::configure(): allowed EAP-type %d.\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(*eap_type))); + + status = m_accepted_tunneled_eap_types.add_object(eap_type, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + } + else + { + // Try different configuration type. + + const eap_configuration_field_c * field + = cf_str_PEAP_accepted_tunneled_client_types_u32array.get_field(); + if (m_is_client == false) + { + field = cf_str_PEAP_accepted_tunneled_server_types_u32array.get_field(); + } + + status = read_configure( + field, + &allowed_eap_types); + if (status == eap_status_ok + && allowed_eap_types.get_is_valid_data() == true) + { + // OK read. + u32_t type_count = allowed_eap_types.get_data_length() + / sizeof(u32_t); + + u32_t * const array = reinterpret_cast( + allowed_eap_types.get_data(type_count*sizeof(u32_t))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: tls_application_eap_core_c::configure(): Tunneled EAP-type count %d, u32array.\n"), + (m_is_client == true ? "client": "server"), + type_count)); + + for (u32_t ind = 0ul; ind < type_count; ind++) + { + eap_type_value_e * const eap_type = new eap_type_value_e(eap_type_none); + if (eap_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *eap_type = static_cast(array[ind]); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: tls_application_eap_core_c::configure(): allowed EAP-type %d.\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(*eap_type))); + + status = m_accepted_tunneled_eap_types.add_object(eap_type, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + } + } + } + + //---------------------------------------------------------- + + { + // Client and server configuration. + eap_variable_data_c allow_tunneled_session_resumption(m_am_tools); + + status = read_configure( + cf_str_PEAP_allow_tunneled_session_resumption.get_field(), + &allow_tunneled_session_resumption); + if (status == eap_status_ok + && allow_tunneled_session_resumption.get_is_valid_data() == true + && allow_tunneled_session_resumption.get_data_length() == sizeof(u32_t) + && allow_tunneled_session_resumption.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + allow_tunneled_session_resumption.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_peap_allow_tunneled_session_resumption = false; + } + else + { + m_peap_allow_tunneled_session_resumption = true; + } + } + } + + status = eap_status_ok; + } + + + if (m_is_client == false) + { + { + // Server only configuration. + // This configuration allows different actions to server and client. + eap_variable_data_c allow_tunneled_session_resumption(m_am_tools); + + status = read_configure( + cf_str_PEAP_server_allow_tunneled_session_resumption.get_field(), + &allow_tunneled_session_resumption); + if (status == eap_status_ok + && allow_tunneled_session_resumption.get_is_valid_data() == true + && allow_tunneled_session_resumption.get_data_length() == sizeof(u32_t) + && allow_tunneled_session_resumption.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + allow_tunneled_session_resumption.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_peap_allow_tunneled_session_resumption = false; + } + else + { + m_peap_allow_tunneled_session_resumption = true; + } + } + } + + status = eap_status_ok; + } + +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + { + // Server only configuration. + eap_variable_data_c server_use_peapv1_extensions_request(m_am_tools); + + status = read_configure( + cf_str_PEAPv1_server_use_extensions_request.get_field(), + &server_use_peapv1_extensions_request); + if (status == eap_status_ok + && server_use_peapv1_extensions_request.get_is_valid_data() == true + && server_use_peapv1_extensions_request.get_data_length() == sizeof(u32_t) + && server_use_peapv1_extensions_request.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + server_use_peapv1_extensions_request.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_server_use_peapv1_extensions_request = false; + } + else + { + m_server_use_peapv1_extensions_request = true; + } + } + } + + status = eap_status_ok; + + } +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + + } + + + //---------------------------------------------------------- + +#if defined(USE_EAP_ERROR_TESTS) + + { + eap_variable_data_c EAP_ERROR_TEST_enable_random_errors(m_am_tools); + + status = read_configure( + cf_str_EAP_ERROR_TEST_enable_random_errors.get_field(), + &EAP_ERROR_TEST_enable_random_errors); + if (status == eap_status_ok + && EAP_ERROR_TEST_enable_random_errors.get_is_valid_data() == true) + { + u32_t *enable_random_errors = reinterpret_cast( + EAP_ERROR_TEST_enable_random_errors.get_data(sizeof(u32_t))); + if (enable_random_errors != 0 + && *enable_random_errors != 0) + { + m_enable_random_errors = true; + } + } + } + + if (m_enable_random_errors == true) + { + eap_variable_data_c manipulate_only_tunneled_messages(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_ERROR_TEST_manipulate_only_tunneled_messages.get_field(), + &manipulate_only_tunneled_messages); + if (status == eap_status_ok + && manipulate_only_tunneled_messages.get_is_valid_data() == true) + { + // NOTE this is optional. + u32_t * const flag = reinterpret_cast( + manipulate_only_tunneled_messages.get_data(sizeof(u32_t))); + if (flag != 0 + && *flag != 0) + { + m_manipulate_only_tunneled_messages = true; + } + } + } + + { + eap_variable_data_c EAP_ERROR_TEST_error_probability(m_am_tools); + + status = read_configure( + cf_str_EAP_ERROR_TEST_error_probability.get_field(), + &EAP_ERROR_TEST_error_probability); + if (status == eap_status_ok + && EAP_ERROR_TEST_error_probability.get_is_valid_data() == true) + { + u32_t *error_probability = reinterpret_cast( + EAP_ERROR_TEST_error_probability.get_data(sizeof(u32_t))); + if (error_probability != 0) + { + m_error_probability = *error_probability; + } + } + } + +#endif //#if defined(USE_EAP_ERROR_TESTS) + + //---------------------------------------------------------- + +#if defined(USE_EAP_EXPANDED_TYPES) && 0 + { + eap_variable_data_c use_eap_expanded_type(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TLS_PEAP_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + + if (status != eap_status_ok) + { + status = read_configure( + cf_str_EAP_CORE_use_eap_expanded_type.get_field(), + &use_eap_expanded_type); + } + + if (status == eap_status_ok + && use_eap_expanded_type.get_data_length() == sizeof(u32_t) + && use_eap_expanded_type.get_data() != 0) + { + u32_t *flag = reinterpret_cast(use_eap_expanded_type.get_data(use_eap_expanded_type.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_use_eap_expanded_type = true; + } + else + { + m_use_eap_expanded_type = false; + } + } + } + } +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + + //---------------------------------------------------------- + + status = m_eap_core->configure(); + + if (m_peap_tunneled_eap_type == eap_type_ttls_plain_pap) + { + if (m_free_eap_core == true) + { + m_eap_core->ignore_notifications(); + + (void) m_eap_core->shutdown(); + + delete m_eap_core; + } + m_eap_core = 0; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: tls_application_eap_core_c::shutdown(), m_shutdown_was_called=%d\n"), + (m_is_client == true) ? "client": "server", + m_shutdown_was_called)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::shutdown()"); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + eap_status_e status(eap_status_ok); + + if (m_eap_core != 0) + { + status = m_eap_core->shutdown(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_application_eap_core_c::trace_tunneled_packet( + eap_const_string prefix, + const eap_header_wr_c * const eap_packet) +{ + if (eap_packet == 0 + || eap_packet->get_is_valid() == false) + { + EAP_UNREFERENCED_PARAMETER(prefix); + // ERROR: Cannot trace invalid packet. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s: %s: Cannot trace invalid packet.\n"), + prefix, + (m_is_client == true) ? "client": "server")); + return; + } + + if ((m_am_tools->get_trace_mask() & TRACE_FLAGS_DEFAULT) + && m_pseudo_ethernet_header.get_is_valid_data() == true + && m_pseudo_ethernet_header.get_data_length() >= sizeof(EAP_PSEUDO_ETHERNET_HEADER)) + { + m_pseudo_ethernet_header.set_data_length(sizeof(EAP_PSEUDO_ETHERNET_HEADER)); + + u32_t eap_packet_length = eap_packet->get_length(); + if (eap_packet->get_header_buffer_length() < eap_packet_length) + { + eap_packet_length = eap_packet->get_header_buffer_length(); + } + + eap_status_e status = m_pseudo_ethernet_header.add_data_to_offset( + sizeof(EAP_PSEUDO_ETHERNET_HEADER), + eap_packet->get_header_buffer(eap_packet_length), + eap_packet_length); + + if (status == eap_status_ok) + { + m_pseudo_ethernet_header.set_data_length( + sizeof(EAP_PSEUDO_ETHERNET_HEADER) + eap_packet_length); + + // Sets the EAPOL packet data length. + eapol_header_wr_c eapol( + m_am_tools, + m_pseudo_ethernet_header.get_data_offset( + EAP_PSEUDO_EAPOL_HEADER_OFFSET, + m_pseudo_ethernet_header.get_data_length()-EAP_PSEUDO_EAPOL_HEADER_OFFSET), + m_pseudo_ethernet_header.get_data_length()-EAP_PSEUDO_EAPOL_HEADER_OFFSET); + + if (eapol.get_is_valid() == true) + { + eapol.set_data_length(static_cast(eap_packet_length)); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: %s: type=0x%08x, eap_length 0x%04x\n"), + prefix, + (m_is_client == true) ? "client": "server", + convert_eap_type_to_u32_t(eap_packet->get_type()), + eap_packet->get_length())); // NOTE, this will trace the values from the header of the EAP-packet. + + EAP_TRACE_DATA_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (prefix, + m_pseudo_ethernet_header.get_data(m_pseudo_ethernet_header.get_data_length()), + m_pseudo_ethernet_header.get_data_length())); + } + } + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::parse_generic_payload( + const tls_peap_tlv_type_e current_payload, + const tls_peap_tlv_header_c * const payload, + peap_tlv_payloads_c * const p_peap_tlv_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::parse_generic_payload()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::parse_generic_payload()"); + + EAP_TLS_PEAP_TRACE_PAYLOAD("Parsing payload", payload, m_is_client); + + if (payload->get_data_length() == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length is 0x%04x.\n"), + payload, current_payload, payload->get_tlv_type_string(), payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + if (current_payload == tls_peap_tlv_type_result) + { + /* Result TLV: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |M|R| TLV Type (AVP Type) | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Status | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + const u32_t PEAP_TLV_STATUS_LENGTH = sizeof(u16_t); + + if (payload->get_data_length() != PEAP_TLV_STATUS_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_tlv_type_string(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(PEAP_TLV_STATUS_LENGTH)); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, + current_payload, + payload->get_tlv_type_string(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + eap_status_e status = p_peap_tlv_payloads->get_result_tlv()->set_copy_of_buffer( + payload); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == tls_peap_tlv_type_nak) + { + /* NAK TLV: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |M|R| TLV Type | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Vendor-Id | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TLV Type number | TLVs | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + const u32_t PEAP_TLV_NAK_MINIMUM_LENGTH = 6ul*sizeof(u8_t); + + if (payload->get_data_length() < PEAP_TLV_NAK_MINIMUM_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_tlv_type_string(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(payload->get_data_length())); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, + current_payload, + payload->get_tlv_type_string(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + eap_status_e status = p_peap_tlv_payloads->get_nak_tlv()->set_copy_of_buffer( + payload); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == tls_peap_tlv_type_crypto_binding) + { + /* Crypto binding TLV: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |M|R| TLV Type | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Version |Received Ver. | SubType | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + NONCE + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + Compound MAC + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + const u32_t PEAP_TLV_CRYPTO_BINDING_LENGTH = sizeof(u16_t)+sizeof(u16_t)+32ul+16ul; + + if (payload->get_data_length() != PEAP_TLV_CRYPTO_BINDING_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_tlv_type_string(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(PEAP_TLV_CRYPTO_BINDING_LENGTH)); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, + current_payload, + payload->get_tlv_type_string(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + eap_status_e status = p_peap_tlv_payloads->get_crypto_binding_tlv()->set_copy_of_buffer( + payload); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == tls_peap_tlv_eap_payload) + { + /* EAP-Payload TLV: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |M|R| TLV Type | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | EAP packet... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TLVs... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + const u32_t PEAP_TLV_EAP_PAYLOAD_MINIMUM_LENGTH = 4ul*sizeof(u8_t); + + if (payload->get_data_length() < PEAP_TLV_EAP_PAYLOAD_MINIMUM_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_tlv_type_string(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(payload->get_data_length())); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, + current_payload, + payload->get_tlv_type_string(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + eap_status_e status = p_peap_tlv_payloads->get_eap_payload_tlv()->set_copy_of_buffer( + payload); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (current_payload == tls_peap_tlv_type_intermediate_result) + { + /* Intermediate Result TLV: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |M|R| TLV Type (AVP Type) | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Status | TLVs... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + const u32_t PEAP_TLV_INTERMEDIATE_RESULTMINIMUM_LENGTH = 2ul*sizeof(u8_t); + + if (payload->get_data_length() < PEAP_TLV_INTERMEDIATE_RESULTMINIMUM_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, data length incorrect 0x%04x.\n"), + payload, current_payload, payload->get_tlv_type_string(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * buffer + = static_cast(payload->get_data(payload->get_data_length())); + + if (buffer == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), + payload, + current_payload, + payload->get_tlv_type_string(), + payload->get_data_length())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Note here we get a reference to the data bytes of the received packet. + eap_status_e status = p_peap_tlv_payloads->get_intermediate_result_tlv() + ->set_copy_of_buffer(payload); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (payload->get_flag_mandatory_tlv() == false) + { + // Silently ignore this optional payload. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("IGNORED: tls_application_eap_core_c::parse_generic_payload(): ") + EAPL("Ignored PEAP_TLV-payload %d=0x%04x.\n"), + current_payload, + current_payload)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + /** + * @{ Add creation and sending of message with NAK TLV. } + */ + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(): ") + EAPL("Unknown PEAP_TLV-payload %d.\n"), + current_payload)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::parse_peap_tlv_payload( + u8_t * const buffer, + u32_t * const buffer_length, + peap_tlv_payloads_c * const p_peap_tlv_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::parse_peap_tlv_payload()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::parse_peap_tlv_payload()"); + + u32_t buffer_offset = 0ul; + + tls_peap_tlv_header_c payload( + m_am_tools, + buffer+buffer_offset, + *buffer_length); // Const correctness is gone. + + tls_peap_tlv_type_e current_payload = payload.get_flag_tlv_type(); + + eap_status_e status = eap_status_header_corrupted; + + if (payload.get_is_valid() == true + && current_payload != tls_peap_tlv_type_none) + { + status = payload.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: TLV header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (*buffer_length < payload.get_header_length()+payload.get_data_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_peap_tlv_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, data length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload, + payload.get_tlv_type_string(), + payload.get_data_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_peap_tlv_payload(): ") + EAPL("PEAP_TLV-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload, p_peap_tlv_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (*buffer_length < payload.get_header_length()+payload.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + buffer_offset += payload.get_header_length()+payload.get_data_length(); + *buffer_length -= payload.get_header_length()+payload.get_data_length(); + + while(*buffer_length >= payload.get_header_length() + && payload.get_is_valid() == true) + { + // Sets payload point to the next TLV header. + payload.set_header_buffer( + buffer+buffer_offset, + *buffer_length); + if (payload.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + current_payload = payload.get_flag_tlv_type(); + + if (*buffer_length < payload.get_header_length()+payload.get_data_length()) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_peap_tlv_payload(0x%08x): ") + EAPL("current payload 0x%04x=%s, data length 0x%04x, buffer length 0x%04x.\n"), + payload.get_header_buffer(0ul), + current_payload, + payload.get_tlv_type_string(), + payload.get_data_length(), + *buffer_length)); + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_peap_tlv_payload(): ") + EAPL("PEAP_TLV-payload header is corrupted.\n"))); + EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"), + payload.get_header_buffer(*buffer_length), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = parse_generic_payload(current_payload, &payload, p_peap_tlv_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (*buffer_length < payload.get_header_length()+payload.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + buffer_offset += payload.get_header_length()+payload.get_data_length(); + *buffer_length -= payload.get_header_length()+payload.get_data_length(); + } + } + + if (*buffer_length != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::parse_peap_tlv_payload(): ") + EAPL("PEAP_TLV-header is corrupted. Buffer length and payload ") + EAPL("length does not match. %lu illegal bytes.\n"), + *buffer_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::start_ttls_tunneled_authentication( + const eap_am_network_id_c * const /*receive_network_id*/, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::start_ttls_tunneled_authentication()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::start_ttls_tunneled_authentication()"); + + if (m_eap_type != eap_type_ttls) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type); + } + + eap_status_e status(eap_status_process_general_error); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if ( +#if defined(USE_EAP_EXPANDED_TYPES) + m_peap_tunneled_eap_type == eap_expanded_type_ttls_plain_pap.get_type() +#else + m_peap_tunneled_eap_type == eap_type_ttls_plain_pap +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + ) + { + // Query PAP username and password. + status = m_application_partner->query_ttls_pap_username_and_password(0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + eap_variable_data_c forwarded_packet_buffer(m_am_tools); + + status = forwarded_packet_buffer.set_buffer_length(EAP_CORE_PACKET_BUFFER_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + forwarded_packet_buffer.set_data_length( + forwarded_packet_buffer.get_buffer_length()); + + eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul); + + forwarded_eap_packet.set_header_buffer( + forwarded_packet_buffer.get_data(), + forwarded_packet_buffer.get_buffer_length()); + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t packet_length = eap_header_wr_c::get_header_length() + 1ul; + + forwarded_eap_packet.reset_header( + static_cast(packet_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_identifier(received_eap_identifier); + forwarded_eap_packet.set_code(eap_code_request); + forwarded_eap_packet.set_length( + static_cast(packet_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_type( + eap_type_identity, + m_use_eap_expanded_type); + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + if (m_tunneled_eap_in_ttls == false) + { + set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_identity_request); + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + forwarded_eap_packet.get_length()); + + { + eap_status_string_c status_string; + EAP_UNREFERENCED_PARAMETER(status_string); + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + bool tmp_tunneled_eap_in_ttls(m_tunneled_eap_in_ttls); +#else + bool tmp_tunneled_eap_in_ttls(false); +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + EAP_UNREFERENCED_PARAMETER(tmp_tunneled_eap_in_ttls); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::start_ttls_tunneled_authentication() returns status=%d=%s, m_tunneled_eap_in_ttls=%d\n"), + (m_is_client == true ? "client": "server"), + status, + status_string.get_status_string(status), + tmp_tunneled_eap_in_ttls)); + } + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + if (m_tunneled_eap_in_ttls == false + && status == eap_status_pending_request) + { + set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_identity_request_pending); + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // NOTE, here we process client send packets separately to + // reduce stack consumption. + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + if (m_eap_type == eap_type_ttls +#if defined(USE_EAP_EXPANDED_TYPES) + && m_peap_tunneled_eap_type == eap_expanded_type_ttls_plain_mschapv2.get_type() +#else + && m_peap_tunneled_eap_type == eap_type_plain_mschapv2 +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + ) + { + eap_header_wr_c sent_eap_packet( + m_am_tools, + m_ttls_sent_eap_packet.get_data(), + m_ttls_sent_eap_packet.get_data_length()); + + if (m_ttls_sent_eap_packet.get_data_length() > 0ul + && sent_eap_packet.get_data_length() > 0ul + && sent_eap_packet.get_type() == eap_type_identity + && get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_identity_request) + { + // Client sent EAP-Response/Identity. + // This message should include username. + + status = ttls_tunneled_message_state_process_identity_request(&sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + if (m_eap_type == eap_type_ttls +#if defined(USE_EAP_EXPANDED_TYPES) + && m_peap_tunneled_eap_type == eap_expanded_type_ttls_plain_mschapv2.get_type() +#else + && m_peap_tunneled_eap_type == eap_type_plain_mschapv2 +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + ) + { + eap_header_wr_c sent_eap_packet( + m_am_tools, + m_ttls_sent_eap_packet.get_data(), + m_ttls_sent_eap_packet.get_data_length()); + + if (m_ttls_sent_eap_packet.get_data_length() > 0ul + && sent_eap_packet.get_data_length() > 0ul + && sent_eap_packet.get_type() == eap_type_mschapv2 + && get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_challenge_request) + { + // This message shoud include MS-CHAP-V2 Response. + status = ttls_tunneled_message_state_process_challenge_request(&sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_eap_success_failure_in_forward_to_tunnel( + const eap_am_network_id_c * const /*receive_network_id*/, + const eap_code_value_e forwarded_eap_code, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_variable_data_c forwarded_packet_buffer(m_am_tools); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::create_eap_success_failure_in_forward_to_tunnel()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_eap_success_failure_in_forward_to_tunnel()"); + + eap_status_e status = forwarded_packet_buffer.set_buffer_length(EAP_CORE_PACKET_BUFFER_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + forwarded_packet_buffer.set_data_length( + forwarded_packet_buffer.get_buffer_length()); + + eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul); + + forwarded_eap_packet.set_header_buffer( + forwarded_packet_buffer.get_data(), + forwarded_packet_buffer.get_buffer_length()); + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + forwarded_eap_packet.reset_header( + static_cast(eap_header_wr_c::get_header_length()), + m_use_eap_expanded_type); + forwarded_eap_packet.set_identifier(received_eap_identifier); + forwarded_eap_packet.set_code(forwarded_eap_code); + forwarded_eap_packet.set_length( + static_cast(eap_header_wr_c::get_header_length()), + m_use_eap_expanded_type); + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + forwarded_eap_packet.get_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::check_ttls_eap_payloads( + eap_diameter_payloads_c * const payloads, + eap_ttls_tunneled_message_type_e * const message_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::check_ttls_eap_payloads()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::check_ttls_eap_payloads()"); + + *message_type = eap_ttls_tunneled_message_type_none; + + eap_array_c needed_payloads(m_am_tools); + + eap_diameter_avp_code_c code_eap_message(eap_diameter_avp_code_eap_message); + + eap_status_e status = needed_payloads.add_object(&code_eap_message, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Test the required attribute. + status = payloads->check_payloads_existense( + &needed_payloads); + if (status != eap_status_ok) + { + // No required payloads. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This packet includes EAP-Message AVP. + + status = payloads->check_mandatory_payloads( + &needed_payloads); + if (status != eap_status_ok) + { + // Some mandatory payload is not used here. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *message_type = eap_ttls_tunneled_message_type_eap; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_process_ttls( + eap_variable_data_c * const received_eap_message, + const u8_t received_eap_identifier, + u32_t * const eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::packet_process_ttls()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_process_ttls()"); + + eap_status_e status = eap_status_process_general_error; + + + u32_t payload_length = received_eap_message->get_data_length(); + + if (payload_length == 0u) + { + // No payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + m_ttls_received_payloads.reset(); + + { + eap_diameter_avp_header_c received_avp( + m_am_tools, + received_eap_message->get_data(received_eap_message->get_data_length()), + received_eap_message->get_data_length()); + if (received_avp.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_ttls_received_payloads.parse_diameter_payloads( + &received_avp, + &payload_length); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (payload_length != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DIAMETER_ERROR, + (EAPL("ERROR: eap_radius_payloads_c::parse_radius_packet(): ") + EAPL("RADIUS-header is corrupted. Buffer length and payload ") + EAPL("length does not match. Illegal byte count %lu\n"), + payload_length)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + m_ttls_message_type = eap_ttls_tunneled_message_type_none; +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + + if (check_ttls_eap_payloads(&m_ttls_received_payloads, &m_ttls_message_type) + == eap_status_ok) + { + // This packet includes EAP-Message AVP. + + eap_diameter_variable_data_c * const eap_message_payload + = m_ttls_received_payloads.get_payload(eap_diameter_avp_code_eap_message); + + if (eap_message_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const eap_message + = eap_message_payload->get_payload_buffer(); + + if (eap_message == 0 + || eap_message->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (eap_message->get_data_length() < eap_header_base_c::get_header_length()) + { + // Not enough payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + *eap_packet_length = eap_message->get_data_length(); + + u8_t * const eap_payload + = eap_message->get_data(*eap_packet_length); + if (eap_payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul); + + // We must forward this EAP-packet to tunneled EAP-type. + forwarded_eap_packet.set_header_buffer( + eap_payload, + *eap_packet_length); + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + *eap_packet_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else if (check_ttls_plain_mschapv2_payloads(&m_ttls_received_payloads, &m_ttls_message_type) + == eap_status_ok) + { + status = handle_ttls_plain_mschapv2_payloads( + &m_ttls_received_payloads, + m_ttls_message_type, + received_eap_identifier); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + else if (check_ttls_plain_pap_payloads(&m_ttls_received_payloads, &m_ttls_message_type) + == eap_status_ok) + { + status = handle_ttls_plain_pap_payloads( + &m_ttls_received_payloads, + m_ttls_message_type, + received_eap_identifier); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + else + { + // Not correct AVP-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::packet_process_ttls(): ") + EAPL("Not correct AVP-payloads are included in eap_state_variable_e %d.\n"), + m_tunneled_eap_type_authentication_state)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_process_xp_peap_v0( + eap_variable_data_c * const packet, + const u8_t received_eap_identifier, + u32_t * const eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::packet_process_xp_peap_v0()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_process_xp_peap_v0()"); + + // XP PEAPv0 does not include EAP-header (code, identifier and length). + // Here we must create those attributes. + // Exception to this rule is, EAP-success and EAP-failure are sent in "Extensions Request Packet" + // or "Extensions Response Packet". + // The whole EAP-header is included + // to "Extensions Request Packet" and "Extensions Response Packet". + // See draft-kamath-pppext-peapv0-00.txt. + // + // EAP-packet without code, identifier and length: + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | EAP-type | EAP-data ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // EAP-packet with "Extensions Request Packet" or "Extensions Response Packet": + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | EAP-code |EAP-identifier | EAP-length | EAP-type | EAP-data ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // EAP-code of "Extensions Request Packet" is 1 which is same as EAP-type of EAP-identity. + // EAP-code of "Extensions Response Packet" is 2 which is same as EAP-type of EAP-notification. + + eap_status_e status = eap_status_process_general_error; + + u32_t received_eap_packet_length = packet->get_data_length(); + if (received_eap_packet_length == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + eap_type_value_e received_eap_type_or_code(eap_type_none); + + const u8_t * const p_received_eap_type_or_code + = static_cast(packet->get_data(sizeof(u8_t))); + + if (p_received_eap_type_or_code == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + else if (*p_received_eap_type_or_code == eap_type_expanded_type) + { + status = eap_expanded_type_c::read_type( + m_am_tools, + 0ul, + p_received_eap_type_or_code, + received_eap_packet_length, + &received_eap_type_or_code); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + received_eap_type_or_code = static_cast(*p_received_eap_type_or_code); + } + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_process_xp_peap_v0(): XP-PEAPv0 %s, tunneled eap_type_or_code %d, ") + EAPL("eap_packet_length %d, m_tunneled_eap_type_authentication_state %d, ") + EAPL("m_tls_session_type %d.\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(received_eap_type_or_code), + received_eap_packet_length, + m_tunneled_eap_type_authentication_state, + m_tls_session_type)); + + bool probably_is_extensions_packet = false; + + const u32_t EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH = sizeof(u16_t); + const u32_t EAP_PEAP_V0_EXTENSIONS_PACKET_LENGTH + = eap_header_wr_c::get_header_length() + + eap_header_wr_c::get_ietf_type_field_length() + + tls_peap_tlv_header_c::get_header_length() + + EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH; + + if (received_eap_packet_length >= EAP_PEAP_V0_EXTENSIONS_PACKET_LENGTH) + { + eap_header_wr_c possible_extensions_eap_packet( + m_am_tools, + packet->get_data(packet->get_data_length()), + packet->get_data_length()); + + if (possible_extensions_eap_packet.get_is_valid() == true + && possible_extensions_eap_packet.check_header() == eap_status_ok) + { + if (m_is_client == true + && possible_extensions_eap_packet.get_code() == eap_code_request + && possible_extensions_eap_packet.get_type() == eap_type_tlv_extensions) + { + // This is "Extensions Request Packet". + probably_is_extensions_packet = true; + } + else if (m_is_client == false + && possible_extensions_eap_packet.get_code() == eap_code_response + && possible_extensions_eap_packet.get_type() == eap_type_tlv_extensions) + { + // This is "Extensions Response Packet". + probably_is_extensions_packet = true; + } + } + } + + + eap_code_value_e forwarded_eap_code = eap_code_none; + eap_variable_data_c forwarded_packet_buffer(m_am_tools); + + // In the first phase we will check first byte as a EAP-type field. + if (probably_is_extensions_packet == false + && ((m_tunneled_eap_type_authentication_state == eap_state_none + && received_eap_type_or_code == eap_type_identity) + || (m_tunneled_eap_type_authentication_state == eap_state_identity_request_received + && (received_eap_type_or_code != eap_type_none + && received_eap_type_or_code != eap_type_identity) + ))) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_process_xp_peap_v0(): XP-PEAPv0 tunneled eap_type %d, ") + EAPL("m_tunneled_eap_type_authentication_state %d.\n"), + convert_eap_type_to_u32_t(received_eap_type_or_code), + m_tunneled_eap_type_authentication_state)); + + if (m_tunneled_eap_type_authentication_state == eap_state_none + && received_eap_type_or_code == eap_type_identity) + { + m_tunneled_eap_type_authentication_state = eap_state_identity_request_received; + } + + *eap_packet_length = eap_header_base_c::get_header_length()+packet->get_data_length(); + + status = forwarded_packet_buffer.set_buffer_length(*eap_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + forwarded_packet_buffer.set_data_length(*eap_packet_length); + + status = forwarded_packet_buffer.add_data_to_offset( + eap_header_base_c::get_header_length(), + packet->get_data(packet->get_data_length()), + packet->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_is_client == true) + { + forwarded_eap_code = eap_code_request; + } + else + { + forwarded_eap_code = eap_code_response; + } + } + else if (probably_is_extensions_packet == true + // The first case will allow sessions resumption without tunneled EAP-authentication + && ((m_tunneled_eap_type_authentication_state + == eap_state_none && m_peap_allow_tunneled_session_resumption == true) + || m_tunneled_eap_type_authentication_state == eap_state_identity_request_received + || m_tunneled_eap_type_authentication_state + == eap_state_authentication_finished_successfully + || m_tunneled_eap_type_authentication_state + == eap_state_authentication_terminated_unsuccessfully)) + { + // In the second phase we will check first byte as a EAP-code field + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_process_xp_peap_v0(): XP-PEAPv0 tunneled eap_code %d, ") + EAPL("m_tunneled_eap_type_authentication_state %d.\n"), + convert_eap_type_to_u32_t(received_eap_type_or_code), + m_tunneled_eap_type_authentication_state)); + + eap_header_wr_c final_eap_packet( + m_am_tools, + packet->get_data(packet->get_data_length()), + packet->get_data_length()); + if (final_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = final_eap_packet.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: EAP-header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t parsed_eap_data_length = final_eap_packet.get_type_data_length(); + + if (parsed_eap_data_length == 0u) + { + // No payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + if (final_eap_packet.get_header_length()+parsed_eap_data_length > packet->get_data_length()) + { + // Corrupted length in EAP-header. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: EAP-header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + if (m_is_client == true) + { + trace_tunneled_packet(EAPL("-> TUNNELED packet client"), &final_eap_packet); + } + else + { + trace_tunneled_packet(EAPL("-> TUNNELED packet server"), &final_eap_packet); + } + + + peap_tlv_payloads_c * peap_tlv_payloads = new peap_tlv_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_peap_tlv_payloads(m_am_tools, peap_tlv_payloads); + + if (peap_tlv_payloads == 0 + || peap_tlv_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + tls_peap_tlv_header_c tlv( + m_am_tools, + final_eap_packet.get_type_data(final_eap_packet.get_type_data_length()), + parsed_eap_data_length); + if (tlv.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: No peap_tlv_payloads_c.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tlv.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: TLV header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = parse_peap_tlv_payload( + final_eap_packet.get_type_data(final_eap_packet.get_type_data_length()), + &parsed_eap_data_length, + peap_tlv_payloads); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (parsed_eap_data_length != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::packet_process_xp_peap_v0(): ") + EAPL("PEAP-header is corrupted. Buffer length and payload ") + EAPL("length does not match. Illegal byte count %lu\n"), + parsed_eap_data_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Checks the payloads existence. + if (peap_tlv_payloads->check_payloads( + peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // result_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // nak_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // crypto_binding_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // eap_payload_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be // intermediate_result_tlv + ) == true + ) + { + // OK. + + if (peap_tlv_payloads->get_result_tlv()->get_data_length() + < EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: TLV-result payload too short.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * const tlv_status_network_order + = reinterpret_cast( + peap_tlv_payloads->get_result_tlv()->get_data( + EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH)); + if (tlv_status_network_order == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT(EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH == sizeof(u16_t)); + + u16_t tlv_status_host_order + = eap_read_u16_t_network_order( + tlv_status_network_order, + EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH); + + if (tlv_status_host_order == tls_peap_tlv_status_success) + { + forwarded_eap_code = eap_code_success; + } + else + { + // All other EAP-codes are assumed EAP-Failure. + forwarded_eap_code = eap_code_failure; + } + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_process_xp_peap_v0(): XP-PEAPv0 tunneled %s received.\n"), + eap_string.get_eap_code_string(forwarded_eap_code))); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + + if (m_is_client == true) + { + if ((m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && m_tunneled_eap_type_authentication_state == eap_state_none + && forwarded_eap_code == eap_code_success) + { + // Send tunneled EAP-Success acknowledge. + eap_status_e status = send_tunneled_acknowledge_xp_peap_v0( + eap_code_success, + received_eap_identifier); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + } + else + { + // Send state notification to lower layer. + + eap_state_notification_c * const notification = new eap_state_notification_c( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_finished_successfully, + received_eap_identifier, + false); + + eap_automatic_variable_c automatic_notification(m_am_tools, notification); + + if (notification == 0) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + get_application_partner()->state_notification(notification); + + status = eap_status_success; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if ((m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && m_tunneled_eap_type_authentication_state == eap_state_none + && forwarded_eap_code == eap_code_failure) + { + // Send tunneled EAP-Failure acknowledge. + eap_status_e status = send_tunneled_acknowledge_xp_peap_v0( + eap_code_failure, + received_eap_identifier); + + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + + // Send state notification to lower layer. + eap_state_notification_c * const notification = new eap_state_notification_c( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + received_eap_identifier, + false); + + eap_automatic_variable_c automatic_notification(m_am_tools, notification); + + if (notification == 0) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + notification->set_authentication_error(eap_status_authentication_failure); + + get_application_partner()->state_notification(notification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Client must forward this EAP-packet to tunneled EAP-type. + *eap_packet_length = eap_header_base_c::get_header_length(); + + status = forwarded_packet_buffer.set_buffer_length(*eap_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + forwarded_packet_buffer.set_data_length(*eap_packet_length); + } + } + else + { + status = eap_status_authentication_failure; + + // This is server. + // Client sent a acknowledge. + if (forwarded_eap_code == eap_code_success + && (m_tunneled_eap_type_authentication_state + == eap_state_authentication_finished_successfully + || ((m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && m_tunneled_eap_type_authentication_state == eap_state_none))) + { + // XP-PEAP Authentication OK. + + eap_state_notification_c * const notification = new eap_state_notification_c( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_finished_successfully, + received_eap_identifier, + false); + + eap_automatic_variable_c automatic_notification(m_am_tools, notification); + + if (notification == 0) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + get_application_partner()->state_notification(notification); + + status = eap_status_success; + } + else + { + // Authentication failed. + eap_state_notification_c * const notification = new eap_state_notification_c( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + received_eap_identifier, + false); + + eap_automatic_variable_c automatic_notification(m_am_tools, notification); + + if (notification == 0) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + notification->set_authentication_error(eap_status_authentication_failure); + + get_application_partner()->state_notification(notification); + + status = eap_status_authentication_failure; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Not correct PEAP_TLV-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::packet_process_xp_peap_v0(): ") + EAPL("Not correct PEAP_TLV-payloads are included in eap_state_variable_e %d.\n"), + m_tunneled_eap_type_authentication_state)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + } + else + { + status = eap_status_unexpected_message; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul); + + forwarded_eap_packet.set_header_buffer( + forwarded_packet_buffer.get_data(*eap_packet_length), + *eap_packet_length); + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + forwarded_eap_packet.reset_header( + static_cast(*eap_packet_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_identifier(received_eap_identifier); + forwarded_eap_packet.set_code(forwarded_eap_code); + forwarded_eap_packet.set_length( + static_cast(*eap_packet_length), + m_use_eap_expanded_type); + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + *eap_packet_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_process_peap_v1( + eap_variable_data_c * const received_eap_message, + const u8_t received_eap_identifier, + u32_t * const eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::packet_process_peap_v1()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_process_peap_v1()"); + + eap_status_e status = eap_status_process_general_error; + + + eap_header_wr_c received_eap_header( + m_am_tools, + received_eap_message->get_data(received_eap_message->get_data_length()), + received_eap_message->get_data_length()); + if (received_eap_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = received_eap_header.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: EAP-header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t parsed_eap_data_length = received_eap_header.get_type_data_length(); + + if (received_eap_header.get_header_length()+parsed_eap_data_length + > received_eap_message->get_data_length()) + { + // Corrupted length in EAP-header. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: EAP-header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + // This is plain EAP-packet. + *eap_packet_length = received_eap_message->get_data_length(); + + eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul); + + forwarded_eap_packet.set_header_buffer( + received_eap_message->get_data(*eap_packet_length), + *eap_packet_length); + + eap_code_value_e received_eap_code = received_eap_header.get_code(); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + if ( +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + m_is_client == false +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + && m_server_use_peapv1_extensions_request == false +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + && +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + m_use_tppd_tls_peap == true + && (m_tunneled_eap_type_authentication_state + == eap_state_authentication_finished_successfully + || m_tunneled_eap_type_authentication_state + == eap_state_authentication_terminated_unsuccessfully)) + { + status = eap_status_authentication_failure; + + // This is server. + // Client sent a acknowledge. + if (m_tunneled_eap_type_authentication_state + == eap_state_authentication_finished_successfully + && forwarded_eap_packet.get_type() == eap_type_peap + && forwarded_eap_packet.get_type_data_length() == sizeof(u8_t) // There is only flags and version + && forwarded_eap_packet.get_type_data(sizeof(u8_t)) != 0 + && *(forwarded_eap_packet.get_type_data(sizeof(u8_t))) == peap_version_1) + { + // PEAPv1 Authentication OK. + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_finished_successfully, + received_eap_identifier, + false); + get_application_partner()->state_notification(¬ification); + + status = eap_status_success; + } + else + { + // PEAPv1 Authentication failed. + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + received_eap_identifier, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + get_application_partner()->state_notification(¬ification); + + status = eap_status_authentication_failure; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + else if (m_is_client == true + && m_use_tppd_tls_peap == true + && (m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && m_tunneled_eap_type_authentication_state == eap_state_none + && received_eap_code == eap_code_success) + { + // Received tunneled EAP-Success. + // This will tell client the tunneled + // EAP-session was also restored. + + if (m_is_client == true) + { + trace_tunneled_packet(EAPL("-> TUNNELED packet client"), &forwarded_eap_packet); + } + else + { + trace_tunneled_packet(EAPL("-> TUNNELED packet server"), &forwarded_eap_packet); + } + + m_tunneled_eap_type_authentication_state = eap_state_authentication_finished_successfully; + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_tppd_peapv1_authentication_finished_successfully_with_tunneled_eap_success, + received_eap_identifier, + false); + get_application_partner()->state_notification(¬ification); + + status = eap_status_success; + } +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + else + { + +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + if ((m_is_client == true + && forwarded_eap_packet.get_code() == eap_code_request + && forwarded_eap_packet.get_type() == eap_type_tlv_extensions) +#if defined(USE_EAP_CORE_SERVER) + || (m_is_client == false + && forwarded_eap_packet.get_code() == eap_code_response + && forwarded_eap_packet.get_type() == eap_type_tlv_extensions) +#endif //#if defined(USE_EAP_CORE_SERVER) + ) + { + if (m_is_client == true) + { + trace_tunneled_packet(EAPL("-> TUNNELED packet client"), &forwarded_eap_packet); + } + else + { + trace_tunneled_packet(EAPL("-> TUNNELED packet server"), &forwarded_eap_packet); + } + + + peap_tlv_payloads_c * peap_tlv_payloads = new peap_tlv_payloads_c(m_am_tools); + eap_automatic_variable_c automatic_peap_tlv_payloads(m_am_tools, peap_tlv_payloads); + + if (peap_tlv_payloads == 0 + || peap_tlv_payloads->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + tls_peap_tlv_header_c tlv( + m_am_tools, + forwarded_eap_packet.get_type_data(forwarded_eap_packet.get_type_data_length()), + parsed_eap_data_length); + if (tlv.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: No peap_tlv_payloads_c.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tlv.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: TLV header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = parse_peap_tlv_payload( + forwarded_eap_packet.get_type_data(forwarded_eap_packet.get_type_data_length()), + &parsed_eap_data_length, + peap_tlv_payloads); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (parsed_eap_data_length != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::packet_process_peap_v1(): ") + EAPL("PEAP-header is corrupted. Buffer length and payload ") + EAPL("length does not match. Illegal byte count %lu\n"), + parsed_eap_data_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + // Checks the payloads existence. + if (peap_tlv_payloads->check_payloads( + peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // result_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // nak_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // crypto_binding_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // eap_payload_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be // intermediate_result_tlv + ) == true + ) + { + // OK. + + const u32_t EAP_PEAP_V1_RESULT_AVP_STATUS_LENGTH = sizeof(u16_t); + + if (peap_tlv_payloads->get_result_tlv()->get_data_length() + < EAP_PEAP_V1_RESULT_AVP_STATUS_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: TLV-result payload too short.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * const tlv_status_network_order + = reinterpret_cast( + peap_tlv_payloads->get_result_tlv()->get_data( + EAP_PEAP_V1_RESULT_AVP_STATUS_LENGTH)); + if (tlv_status_network_order == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_ASSERT(EAP_PEAP_V1_RESULT_AVP_STATUS_LENGTH == sizeof(u16_t)); + + u16_t tlv_status_host_order + = eap_read_u16_t_network_order( + tlv_status_network_order, + EAP_PEAP_V1_RESULT_AVP_STATUS_LENGTH); + + eap_code_value_e forwarded_eap_code(eap_code_none); + + if (tlv_status_host_order == tls_peap_tlv_status_success) + { + forwarded_eap_code = eap_code_success; + } + else + { + // All other EAP-codes are assumed EAP-Failure. + forwarded_eap_code = eap_code_failure; + } + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_application_eap_core_c::packet_process_peap_v1(): PEAPv1 tunneled %s received.\n"), + eap_string.get_eap_code_string(forwarded_eap_code))); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + + if (m_is_client == true) + { + if ((m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && m_tunneled_eap_type_authentication_state == eap_state_none + && forwarded_eap_code == eap_code_success) + { + // Send tunneled EAP-Success acknowledge. + status = send_tunneled_acknowledge_xp_peap_v0( + eap_code_success, + received_eap_identifier); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + } + else + { + // Send state notification to lower layer. + + eap_state_notification_c * const notification = new eap_state_notification_c( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_finished_successfully, + received_eap_identifier, + false); + + eap_automatic_variable_c automatic_notification(m_am_tools, notification); + + if (notification == 0) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + get_application_partner()->state_notification(notification); + + status = eap_status_success; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if ((m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && m_tunneled_eap_type_authentication_state == eap_state_none + && forwarded_eap_code == eap_code_failure) + { + // Send tunneled EAP-Failure acknowledge. + eap_status_e status = send_tunneled_acknowledge_xp_peap_v0( + eap_code_failure, + received_eap_identifier); + + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + + // Send state notification to lower layer. + eap_state_notification_c * const notification = new eap_state_notification_c( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + received_eap_identifier, + false); + + eap_automatic_variable_c automatic_notification(m_am_tools, notification); + + if (notification == 0) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + notification->set_authentication_error(eap_status_authentication_failure); + + get_application_partner()->state_notification(notification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Client must forward this EAP-packet to tunneled EAP-type. + + m_client_send_peapv1_extensions_response = true; + + eap_variable_data_c forwarded_packet_buffer(m_am_tools); + if (forwarded_packet_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *eap_packet_length = eap_header_base_c::get_header_length(); + + status = forwarded_packet_buffer.set_buffer_length(*eap_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = forwarded_packet_buffer.set_data_length(*eap_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul); + + forwarded_eap_packet.set_header_buffer( + forwarded_packet_buffer.get_data(*eap_packet_length), + *eap_packet_length); + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + forwarded_eap_packet.reset_header( + static_cast(*eap_packet_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_identifier(received_eap_identifier); + forwarded_eap_packet.set_code(forwarded_eap_code); + forwarded_eap_packet.set_length( + static_cast(*eap_packet_length), + m_use_eap_expanded_type); + + // Forward packet to upper layer. + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + *eap_packet_length); + } + } + } + else + { + status = eap_status_authentication_failure; + + // This is server. + // Client sent a acknowledge. + if (forwarded_eap_code == eap_code_success + && (m_tunneled_eap_type_authentication_state + == eap_state_authentication_finished_successfully + || ((m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && m_tunneled_eap_type_authentication_state == eap_state_none))) + { + // PEAPv1 Authentication OK. + + eap_state_notification_c * const notification = new eap_state_notification_c( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_finished_successfully_peapv1_extension, + received_eap_identifier, + false); + + eap_automatic_variable_c automatic_notification(m_am_tools, notification); + + if (notification == 0) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + get_application_partner()->state_notification(notification); + + status = eap_status_success; + } + else + { + // Authentication failed. + eap_state_notification_c * const notification = new eap_state_notification_c( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully_peapv1_extension, + received_eap_identifier, + false); + + eap_automatic_variable_c automatic_notification(m_am_tools, notification); + + if (notification == 0) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + notification->set_authentication_error(eap_status_authentication_failure); + + get_application_partner()->state_notification(notification); + + status = eap_status_authentication_failure; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Not correct PEAP_TLV-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::packet_process_peap_v1(): ") + EAPL("Not correct PEAP_TLV-payloads are included in eap_state_variable_e %d.\n"), + m_tunneled_eap_type_authentication_state)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + } + else +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + { + // Forward packet to upper layer. + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + *eap_packet_length); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::finish_successfull_authentication_peap_v2( + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::finish_successfull_authentication_peap_v2()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::finish_successfull_authentication_peap_v2()"); + + eap_status_e status = eap_status_process_general_error; + + if (m_tunneled_eap_type_authentication_state == eap_state_authentication_finished_successfully) + { + // PEAPv2 Authentication OK. + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + status = create_compound_session_key_peap_v2(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_application_partner()->packet_data_crypto_keys( + &send_network_id, + &m_peap_v2_CSK + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_finished_successfully, + received_eap_identifier, + false); + get_application_partner()->state_notification(¬ification); + + status = eap_status_success; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::store_nonce_peap_v2( + const bool is_client_when_true, + peap_tlv_payloads_c * const peapv2_tlv_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::store_nonce_peap_v2()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::store_nonce_peap_v2()"); + + eap_status_e status = eap_status_process_general_error; + + u8_t * const nonce = reinterpret_cast( + peapv2_tlv_payloads->get_crypto_binding_tlv()->get_data_offset( + TLV_NONCE_OFFSET, + TLV_NONCE_LENGTH)); + if (nonce == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (is_client_when_true == true) + { + status = m_peap_v2_server_nonce.set_copy_of_buffer( + nonce, + TLV_NONCE_LENGTH); + } + else + { + status = m_peap_v2_client_nonce.set_copy_of_buffer( + nonce, + TLV_NONCE_LENGTH); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_process_peap_v2( + eap_variable_data_c * const received_eap_message, + const u8_t received_eap_identifier, + u32_t * const eap_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::packet_process_peap_v2()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_process_peap_v2()"); + + eap_status_e status = eap_status_process_general_error; + eap_code_value_e forwarded_eap_code = eap_code_none; + + + eap_header_wr_c received_eap_header( + m_am_tools, + received_eap_message->get_data(received_eap_message->get_data_length()), + received_eap_message->get_data_length()); + if (received_eap_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = received_eap_header.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: EAP-header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t parsed_eap_data_length = received_eap_header.get_type_data_length(); + + if (parsed_eap_data_length < sizeof(u8_t)) + { + // Not enough payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (received_eap_header.get_header_length()+parsed_eap_data_length + > received_eap_message->get_data_length()) + { + // Corrupted length in EAP-header. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: EAP-header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (received_eap_header.get_type() != eap_type_tlv_extensions) + { + // Not enough payload in this packet. + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + tls_peap_tlv_header_c tlv( + m_am_tools, + received_eap_header.get_type_data(received_eap_header.get_type_data_length()), + parsed_eap_data_length); + if (tlv.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: No peap_tlv_payloads_c.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tlv.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: TLV header corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_peapv2_tlv_payloads.reset(); + + status = parse_peap_tlv_payload( + received_eap_header.get_type_data(received_eap_header.get_type_data_length()), + &parsed_eap_data_length, + &m_peapv2_tlv_payloads); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (parsed_eap_data_length != 0u) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::packet_process_peap_v2(): ") + EAPL("PEAP-header is corrupted. Buffer length and payload ") + EAPL("length does not match. Illegal byte count %lu\n"), + parsed_eap_data_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + // EAP-Identifier is used later in verify_tunneled_acknowledge_peap_v2(). + m_received_eap_identifier = received_eap_identifier; + + // Checks the payloads existence. + if (m_peapv2_tlv_payloads.check_payloads( + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // result_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // nak_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // crypto_binding_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // eap_payload_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be // intermediate_result_tlv + ) == true + ) + { + // This packet includes EAP-Payload TLV. + + *eap_packet_length = m_peapv2_tlv_payloads.get_eap_payload_tlv()->get_data_length(); + + u8_t * const eap_payload + = reinterpret_cast( + m_peapv2_tlv_payloads.get_eap_payload_tlv()->get_data( + *eap_packet_length)); + if (eap_payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul); + + // We must forward this EAP-packet to tunneled EAP-type. + forwarded_eap_packet.set_header_buffer( + eap_payload, + *eap_packet_length); + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + *eap_packet_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (m_peapv2_tlv_payloads.check_payloads( + peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // result_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // nak_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // crypto_binding_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // eap_payload_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_be // intermediate_result_tlv + ) == true + ) + { + // This is Protected termination. + + { + u8_t * const tlv_status_network_order = reinterpret_cast( + m_peapv2_tlv_payloads.get_result_tlv()->get_data(sizeof(u16_t))); + if (tlv_status_network_order == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u16_t tlv_status_host_order + = eap_read_u16_t_network_order(tlv_status_network_order, sizeof(u16_t)); + + if (tlv_status_host_order == tls_peap_tlv_status_success) + { + forwarded_eap_code = eap_code_success; + } + else + { + // All other EAP-codes are assumed EAP-Failure. + forwarded_eap_code = eap_code_failure; + } + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_process_peap_v2(): PEAPv2 tunneled %s received.\n"), + eap_string.get_eap_code_string(forwarded_eap_code))); + } + + + if (m_is_client == true) + { + // Client must forward created EAP-Success or EAP-Failure to tunneled EAP-type. + // Result TLV, Crypto Binding TLV and Intermediate Result TLV + // are checked within the state_notification() function + // by the verify_tunneled_acknowledge_peap_v2() function + // when eap_state_authentication_finished_successfully or + // eap_state_authentication_terminated_unsuccessfully indication + // is received. + + // Client stores the received server nonce. This is used later in key generation. + status = store_nonce_peap_v2(m_is_client, &m_peapv2_tlv_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = create_eap_success_failure_in_forward_to_tunnel( + &m_receive_network_id, + forwarded_eap_code, + received_eap_identifier); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Server checks the received TLVs immediately. + + status = store_nonce_peap_v2(m_is_client, &m_peapv2_tlv_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c saved_mac(m_am_tools); + + { + u8_t * const mac = reinterpret_cast( + m_peapv2_tlv_payloads.get_crypto_binding_tlv()->get_data_offset( + TLV_MAC_OFFSET, + TLV_MAC_LENGTH)); + if (mac == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = saved_mac.set_copy_of_buffer( + mac, + TLV_MAC_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_am_tools->memset(mac, 0, TLV_MAC_LENGTH); + } + + // Intermediate Combined Key is stored to m_peap_v2_IPMKn. + // Compound MAC Key is stored to m_peap_v2_CMK_Bn. + status = create_compound_mac_key_peap_v2(true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Client uses server CMK B1 key + // to check the message server sent. + eap_variable_data_c * mac_key = &m_peap_v2_CMK_B1_server; + if (m_is_client == false) + { + // Server uses Client CMK B2 key + // to check the message client sent. + mac_key = &m_peap_v2_CMK_B2_client; + } + + eap_variable_data_c mac_data(m_am_tools); + + status = create_crypto_binding_compound_mac( + mac_key, + m_peapv2_tlv_payloads.get_crypto_binding_tlv()->get_original_header(), + &mac_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("verify TLV MAC"), + saved_mac.get_data(saved_mac.get_data_length()), + saved_mac.get_data_length())); + + // Here we check only saved_mac.get_data_length() bytes. + // HMAC-SHA1 generates more than 128 bits used MAC. + if (saved_mac.get_data_length() > mac_data.get_data_length() + || m_am_tools->memcmp( + saved_mac.get_data(saved_mac.get_data_length()), + mac_data.get_data(mac_data.get_data_length()), + saved_mac.get_data_length()) != 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAPv2: ERROR: %s: receive_function: ") + EAPL("packet_process_peap_v2(): MAC failed\n"), + (m_is_client == true ? "client": "server"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAPv2: %s: MAC OK\n"), + (m_is_client == true ? "client": "server"))); + } + + + /** + * @{ Check Intermediate Result TLV. } + */ + + status = eap_status_authentication_failure; + + // This is server. + // Client sent an acknowledge. + if (forwarded_eap_code == eap_code_success + && m_tunneled_eap_type_authentication_state + == eap_state_authentication_finished_successfully) + { + // PEAPv2 Authentication OK. + + status = finish_successfull_authentication_peap_v2( + received_eap_identifier); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Authentication failed. + status = eap_status_authentication_failure; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Not correct PEAP_TLV-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::packet_process_peap_v2(): ") + EAPL("Not correct PEAP_TLV-payloads are included in eap_state_variable_e %d.\n"), + m_tunneled_eap_type_authentication_state)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::verify_tunneled_acknowledge_peap_v2() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::verify_tunneled_acknowledge_peap_v2(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::verify_tunneled_acknowledge_peap_v2()"); + + eap_status_e status = eap_status_process_general_error; + eap_code_value_e forwarded_eap_code = eap_code_none; + + + // Checks the payloads existence. + if (m_peapv2_tlv_payloads.check_payloads( + peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // result_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // nak_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // crypto_binding_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // eap_payload_tlv + peap_tlv_payloads_c::peap_tlv_payload_status_must_be // intermediate_result_tlv + ) == true + ) + { + // This is Protected termination. + + { + u8_t * const tlv_status_network_order = reinterpret_cast( + m_peapv2_tlv_payloads.get_result_tlv()->get_data(sizeof(u16_t))); + if (tlv_status_network_order == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u16_t tlv_status_host_order + = eap_read_u16_t_network_order(tlv_status_network_order, sizeof(u16_t)); + + if (tlv_status_host_order == tls_peap_tlv_status_success) + { + forwarded_eap_code = eap_code_success; + } + else + { + // All other EAP-codes are assumed EAP-Failure. + forwarded_eap_code = eap_code_failure; + } + } + + + // Client and server checks the received TLVs. + + status = store_nonce_peap_v2(m_is_client, &m_peapv2_tlv_payloads); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c saved_mac(m_am_tools); + + { + u8_t * const mac = reinterpret_cast( + m_peapv2_tlv_payloads.get_crypto_binding_tlv()->get_data_offset( + TLV_MAC_OFFSET, + TLV_MAC_LENGTH)); + if (mac == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = saved_mac.set_copy_of_buffer( + mac, + TLV_MAC_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_am_tools->memset(mac, 0, TLV_MAC_LENGTH); + } + + // Client uses server CMK B1 key + // to check the message server sent. + eap_variable_data_c * mac_key = &m_peap_v2_CMK_B1_server; + if (m_is_client == false) + { + // Server uses Client CMK B2 key + // to check the message client sent. + mac_key = &m_peap_v2_CMK_B2_client; + } + + eap_variable_data_c mac_data(m_am_tools); + + status = create_crypto_binding_compound_mac( + mac_key, + m_peapv2_tlv_payloads.get_crypto_binding_tlv()->get_original_header(), + &mac_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("verify TLV MAC"), + saved_mac.get_data(saved_mac.get_data_length()), + saved_mac.get_data_length())); + + // Here we check only saved_mac.get_data_length() bytes. + // HMAC-SHA1 generates more than 128 bits used MAC. + if (saved_mac.get_data_length() > mac_data.get_data_length() + || m_am_tools->memcmp( + saved_mac.get_data(saved_mac.get_data_length()), + mac_data.get_data(mac_data.get_data_length()), + saved_mac.get_data_length()) != 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAPv2: ERROR: %s: receive_function: ") + EAPL("packet_process_peap_v2(): MAC failed\n"), + (m_is_client == true ? "client": "server"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAPv2: %s: MAC OK\n"), + (m_is_client == true ? "client": "server"))); + } + + + /** + * @{ Check Intermediate Result TLV. } + */ + + status = eap_status_authentication_failure; + + // This is server. + // Client sent a acknowledge. + if (forwarded_eap_code == eap_code_success + && m_tunneled_eap_type_authentication_state + == eap_state_authentication_finished_successfully) + { + // PEAPv2 Authentication OK. + + if (m_is_client == false) + { + status = finish_successfull_authentication_peap_v2( + m_received_eap_identifier); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Server does nothing here. + status = eap_status_success; + } + + } + else + { + // Authentication failed. + status = eap_status_authentication_failure; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Not correct PEAP_TLV-payloads are included. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: tls_application_eap_core_c::verify_tunneled_acknowledge_peap_v2(): ") + EAPL("Not correct PEAP_TLV-payloads are included in eap_state_variable_e %d.\n"), + m_tunneled_eap_type_authentication_state)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_forward_to_tunnel( + const eap_am_network_id_c * const /*receive_network_id*/, + eap_header_wr_c * const forwarded_eap_packet, + const u32_t eap_packet_length) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::packet_forward_to_tunnel(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_forward_to_tunnel()"); + + if (m_is_client == true) + { + trace_tunneled_packet(EAPL("-> TUNNELED packet client"), forwarded_eap_packet); + } + else + { + trace_tunneled_packet(EAPL("-> TUNNELED packet server"), forwarded_eap_packet); + } + + eap_status_e status(eap_status_drop_packet_quietly); + + if (m_eap_core != 0) + { + status = m_eap_core->packet_process( + &m_receive_network_id, + forwarded_eap_packet, + eap_packet_length); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_process( + eap_variable_data_c * const received_eap_message, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + u32_t eap_packet_length = 0ul; + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_application_eap_core_c::packet_process(): received tunneled data:"), + received_eap_message->get_data(received_eap_message->get_data_length()), + received_eap_message->get_data_length())); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_process()"); + + // At least EAP-type or EAP-code field is needed. + if (received_eap_message->get_data_length() < sizeof(u8_t)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if (received_eap_message->get_data_length() > received_eap_message->get_buffer_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); + } + + if (m_eap_type == eap_type_peap) + { + if (m_peap_version == peap_version_0_xp) + { + status = packet_process_xp_peap_v0( + received_eap_message, + received_eap_identifier, + &eap_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if ((m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && m_tunneled_eap_type_authentication_state + == eap_state_authentication_finished_successfully) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + else if (m_peap_version == peap_version_1) + { + status = packet_process_peap_v1( + received_eap_message, + received_eap_identifier, + &eap_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (m_peap_version == peap_version_2) + { + status = packet_process_peap_v2( + received_eap_message, + received_eap_identifier, + &eap_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + } + else if (m_eap_type == eap_type_ttls) + { + status = packet_process_ttls( + received_eap_message, + received_eap_identifier, + &eap_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::plain_eap_success_failure_packet_received( + const eap_am_network_id_c * const receive_network_id, + const eap_code_value_e received_eap_code, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_tls_trace_string_c state_trace; + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: plain_eap_success_failure_packet_received(): m_wait_plain_eap_success=%d, EAP-Code=%d, m_tls_session_type=%s, m_eap_core=0x%08x\n"), + (m_is_client == true ? "client": "server"), + m_wait_plain_eap_success, + received_eap_code, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_eap_core)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::plain_eap_success_failure_packet_received()"); + + eap_status_e status(eap_status_ok); + + if (m_eap_core != 0 + && m_tls_session_type != tls_session_type_original_session_resumption + && m_tls_session_type != tls_session_type_stateless_session_resumption) + { + status = create_eap_success_failure_in_forward_to_tunnel( + receive_network_id, + received_eap_code, + received_eap_identifier); + if (status != eap_status_ok + && status != eap_status_drop_packet_quietly) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // This object might wait EAP-Success, too. + if (m_wait_plain_eap_success == true + && received_eap_code == eap_code_success) + { + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_eap_type, + eap_state_none, + eap_state_authentication_finished_successfully, + m_received_eap_identifier, + true); + m_application_partner->state_notification(¬ification); + + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::empty_ack_packet_received( + const eap_am_network_id_c * const /* receive_network_id */, + const u8_t /* received_eap_identifier */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: empty_ack_packet_received()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::empty_ack_packet_received()"); + + eap_status_e status(eap_status_not_found); + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + if (m_is_client == false + && m_tunneled_eap_in_ttls == false + && m_eap_type == eap_type_ttls) + { + u32_t eap_length + = EAP_MSCHAPV2_OPCODE_SIZE // OpCode is the only payload + + eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type); + + eap_buf_chain_wr_c eap_packet_buffer( + eap_write_buffer, + m_am_tools, + eap_length); + if (eap_packet_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_wr_c forwarded_eap_packet( + m_am_tools, + eap_packet_buffer.get_data(eap_length), + eap_length); + + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + forwarded_eap_packet.reset_header( + static_cast(eap_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_identifier(m_ttls_plain_ms_chap_v2_eap_identifier); + forwarded_eap_packet.set_code(eap_code_response); + forwarded_eap_packet.set_length( + static_cast(eap_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + forwarded_eap_packet.get_type_data_offset( + 0, + forwarded_eap_packet.get_type_data_length()), + forwarded_eap_packet.get_type_data_length()); + + mschapv2_header.set_opcode(mschapv2_opcode_success); + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + eap_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_application_eap_core_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: function: tls_application_eap_core_c::reset(): this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::reset()"); + + m_tunneled_eap_type_authentication_state = eap_state_none; + m_tls_session_type = tls_session_type_none; + m_use_tppd_tls_peap = false; + m_use_tppd_peapv1_acknowledge_hack = false; + + eap_status_e status(eap_status_ok); + + if (m_eap_core != 0) + { + status = m_eap_core->reset(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_result_tlv_message( + eap_buf_chain_wr_c * const packet, + const eap_code_value_e result_eap_code, + const u8_t eap_identifier, + const tls_peap_tlv_type_e tlv_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: create_result_tlv_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_result_tlv_message()"); + + if (packet->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t final_packet_length + = eap_header_wr_c::get_header_length() + + sizeof(u8_t) // EAP-type field + +tls_peap_tlv_header_c::get_header_length() + +sizeof(u16_t); + + eap_status_e status = packet->set_buffer_length(final_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (packet->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = packet->set_data_length(final_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_header_wr_c final_eap_packet( + m_am_tools, + packet->get_data(packet->get_data_length()), + packet->get_data_length()); + if (final_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + final_eap_packet.reset_header( + static_cast(final_packet_length), + m_use_eap_expanded_type); + final_eap_packet.set_identifier(eap_identifier); + if (m_is_client == true) + { + final_eap_packet.set_code(eap_code_response); + } + else + { + final_eap_packet.set_code(eap_code_request); + } + final_eap_packet.set_length( + static_cast(final_packet_length), + m_use_eap_expanded_type); + final_eap_packet.set_type( + eap_type_tlv_extensions, + m_use_eap_expanded_type); + + tls_peap_tlv_header_c tlv( + m_am_tools, + final_eap_packet.get_type_data(final_eap_packet.get_type_data_length()), + final_eap_packet.get_type_data_length()); + if (tlv.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + /* Result TLV: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |M|R| TLV Type (AVP Type) | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Status | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + tlv.reset_header(static_cast(sizeof(u16_t))); + tlv.set_flag_tlv_type(tlv_type); + tlv.set_flag_mandatory_tlv(true); + + u16_t * const tlv_status = reinterpret_cast(tlv.get_data(sizeof(u16_t))); + if (tlv_status == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u16_t tlv_status_network_order = 0ul; + + if (result_eap_code == eap_code_success) + { + tlv_status_network_order = eap_htons(static_cast(tls_peap_tlv_status_success)); + } + else + { + tlv_status_network_order = eap_htons(static_cast(tls_peap_tlv_status_failure)); + } + + m_am_tools->memmove(tlv_status, &tlv_status_network_order, sizeof(tlv_status_network_order)); + + EAP_TLS_PEAP_TRACE_PAYLOAD("Add TLV payload", &tlv, m_is_client); + + + if (m_is_client == true) + { + trace_tunneled_packet(EAPL("<- TUNNELED packet client"), &final_eap_packet); + } + else + { + trace_tunneled_packet(EAPL("<- TUNNELED packet client"), &final_eap_packet); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_intermediate_result_tlv_message( + eap_buf_chain_wr_c * const packet, + const eap_code_value_e result_eap_code, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: create_intermediate_result_tlv_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_intermediate_result_tlv_message()"); + + /* Intermediate Result TLV: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |M|R| TLV Type (AVP Type) | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Status | TLVs... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Now we do not support any included TLVs. + * This means Intermediate Result TLV is the same as Result TLV. + */ + + eap_status_e status = create_result_tlv_message( + packet, + result_eap_code, + eap_identifier, + tls_peap_tlv_type_intermediate_result); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_eap_payload_tlv_message( + eap_buf_chain_wr_c * const packet, + const eap_header_wr_c * const sent_eap_packet, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::create_eap_payload_tlv_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_eap_payload_tlv_message()"); + + if (packet->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + const u32_t tlv_payload_length + = sent_eap_packet->get_length(); + + const u32_t final_packet_length + = eap_header_wr_c::get_header_length() + + sizeof(u8_t) // EAP-type field + + tls_peap_tlv_header_c::get_header_length() + + tlv_payload_length; + + eap_status_e status = packet->set_buffer_length(final_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (packet->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = packet->set_data_length(final_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_header_wr_c final_eap_packet( + m_am_tools, + packet->get_data(packet->get_data_length()), + packet->get_data_length()); + if (final_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + final_eap_packet.reset_header( + static_cast(final_packet_length), + m_use_eap_expanded_type); + final_eap_packet.set_identifier(eap_identifier); + if (m_is_client == true) + { + final_eap_packet.set_code(eap_code_response); + } + else + { + final_eap_packet.set_code(eap_code_request); + } + final_eap_packet.set_length( + static_cast(final_packet_length), + m_use_eap_expanded_type); + final_eap_packet.set_type( + eap_type_tlv_extensions, + m_use_eap_expanded_type); + + tls_peap_tlv_header_c tlv( + m_am_tools, + final_eap_packet.get_type_data(final_eap_packet.get_type_data_length()), + final_eap_packet.get_type_data_length()); + if (tlv.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // EAP-Payload TLV: + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |M|R| TLV Type | Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | EAP packet... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | TLVs... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // We do not support any included TLVs. + // + tlv.reset_header(static_cast(tlv_payload_length)); + tlv.set_flag_tlv_type(tls_peap_tlv_eap_payload); + tlv.set_flag_mandatory_tlv(true); + + + { + // Adds EAP-Packet as a payload to EAP-Payload TLV. + u16_t * const eap_packet_payload = reinterpret_cast( + tlv.get_data_offset(0ul, sent_eap_packet->get_length())); + if (eap_packet_payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + eap_packet_payload, + sent_eap_packet->get_header_buffer(sent_eap_packet->get_length()), + sent_eap_packet->get_length()); + } + + EAP_TLS_PEAP_TRACE_PAYLOAD("Add TLV payload", &tlv, m_is_client); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_crypto_binding_tlv_message( + eap_buf_chain_wr_c * const packet, + const eap_code_value_e result_eap_code, + const u8_t eap_identifier, + const eap_variable_data_c * const nonce, + const u8_t received_version) +{ + EAP_UNREFERENCED_PARAMETER(result_eap_code); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::create_crypto_binding_tlv_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_crypto_binding_tlv_message()"); + + if (packet->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + const u32_t result_tlv_payload_length + = sizeof(u16_t); + + const u32_t result_tlv_length + = tls_peap_tlv_header_c::get_header_length() + + result_tlv_payload_length; + + const u32_t crypto_binding_tlv_payload_length + = sizeof(u8_t) + + sizeof(u8_t) + + sizeof(u16_t) + + TLV_NONCE_LENGTH + + TLV_MAC_LENGTH; + + const u32_t crypto_binding_tlv_length + = tls_peap_tlv_header_c::get_header_length() + + crypto_binding_tlv_payload_length; + + const u32_t intermediate_result_tlv_payload_length + = sizeof(u16_t); + + const u32_t intermediate_result_tlv_length + = tls_peap_tlv_header_c::get_header_length() + + intermediate_result_tlv_payload_length; + + const u32_t final_packet_length + = eap_header_wr_c::get_header_length() + + sizeof(u8_t) // EAP-type field + + result_tlv_length + + crypto_binding_tlv_length + + intermediate_result_tlv_length; + + eap_status_e status = packet->set_buffer_length(final_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (packet->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = packet->set_data_length(final_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_header_wr_c final_eap_packet( + m_am_tools, + packet->get_data(packet->get_data_length()), + packet->get_data_length()); + if (final_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + final_eap_packet.reset_header( + static_cast(final_packet_length), + m_use_eap_expanded_type); + final_eap_packet.set_identifier(eap_identifier); + if (m_is_client == true) + { + final_eap_packet.set_code(eap_code_response); + } + else + { + final_eap_packet.set_code(eap_code_request); + } + final_eap_packet.set_length( + static_cast(final_packet_length), + m_use_eap_expanded_type); + final_eap_packet.set_type( + eap_type_tlv_extensions, + m_use_eap_expanded_type); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t tlv_offset = 0ul; + + { + // Data includes Result TLV: + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |M|R| TLV Type | Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Status | TLVs... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // We do not support included TLVs. + // + + tls_peap_tlv_header_c result_tlv( + m_am_tools, + final_eap_packet.get_type_data_offset(tlv_offset, result_tlv_length), + final_eap_packet.get_type_data_length()); + if (result_tlv.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + tlv_offset += result_tlv_length; + + result_tlv.reset_header(static_cast(result_tlv_payload_length)); + result_tlv.set_flag_tlv_type(tls_peap_tlv_type_result); + result_tlv.set_flag_mandatory_tlv(true); + + + { + u16_t * const tlv_status = reinterpret_cast( + result_tlv.get_data_offset(0ul, sizeof(u16_t))); + if (tlv_status == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u16_t tlv_status_value = 0ul; + if (result_eap_code == eap_code_success) + { + tlv_status_value = static_cast(tls_peap_tlv_status_success); + } + else + { + tlv_status_value = static_cast(tls_peap_tlv_status_failure); + } + + status = eap_write_u16_t_network_order( + tlv_status, + sizeof(*tlv_status), + tlv_status_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TLS_PEAP_TRACE_PAYLOAD("Add TLV payload", &result_tlv, m_is_client); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + // Data includes Crypto Binding TLV: + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |M|R| TLV Type | Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Version |Received Ver. | Sub-Type | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // ~ Nonce ~ + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // ~ Compound MAC ~ + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + + tls_peap_tlv_header_c crypto_binding_tlv( + m_am_tools, + final_eap_packet.get_type_data_offset(tlv_offset, crypto_binding_tlv_length), + final_eap_packet.get_type_data_length()); + if (crypto_binding_tlv.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + tlv_offset += crypto_binding_tlv_length; + + crypto_binding_tlv.reset_header(static_cast(crypto_binding_tlv_payload_length)); + crypto_binding_tlv.set_flag_tlv_type(tls_peap_tlv_type_crypto_binding); + crypto_binding_tlv.set_flag_mandatory_tlv(true); + + u32_t tlv_data_offset = 0ul; + + { + u8_t * const tlv_version = reinterpret_cast( + crypto_binding_tlv.get_data_offset(tlv_data_offset, sizeof(u8_t))); + if (tlv_version == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *tlv_version = static_cast(0ul); + + tlv_data_offset += sizeof(u8_t); + } + + + { + u8_t * const tlv_received_version = reinterpret_cast( + crypto_binding_tlv.get_data_offset(tlv_data_offset, sizeof(u8_t))); + if (tlv_received_version == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *tlv_received_version = static_cast(received_version); + + tlv_data_offset += sizeof(u8_t); + } + + + { + u16_t * const tlv_sub_type = reinterpret_cast( + crypto_binding_tlv.get_data_offset(tlv_data_offset, sizeof(u16_t))); + if (tlv_sub_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u16_t tlv_sub_type_network_order = 0ul; + if (m_is_client == true) + { + tlv_sub_type_network_order = eap_htons( + static_cast(tls_peap_tlv_type_crypto_binding_request)); + } + else + { + tlv_sub_type_network_order = eap_htons( + static_cast(tls_peap_tlv_type_crypto_binding_response)); + } + + m_am_tools->memmove( + tlv_sub_type, + &tlv_sub_type_network_order, + sizeof(tlv_sub_type_network_order)); + + tlv_data_offset += sizeof(u16_t); + } + + + if (nonce->get_data_length() == TLV_NONCE_LENGTH) + { + u16_t * const tlv_nonce = reinterpret_cast( + crypto_binding_tlv.get_data_offset(tlv_data_offset, TLV_NONCE_LENGTH)); + if (tlv_nonce == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove(tlv_nonce, nonce->get_data(TLV_NONCE_LENGTH), TLV_NONCE_LENGTH); + + tlv_data_offset += TLV_NONCE_LENGTH; + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + { + u8_t * const tlv_mac = reinterpret_cast( + crypto_binding_tlv.get_data_offset(tlv_data_offset, TLV_MAC_LENGTH)); + if (tlv_mac == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memset(tlv_mac, 0, TLV_MAC_LENGTH); + + eap_variable_data_c * mac_key = &m_peap_v2_CMK_B1_server; + if (m_is_client == true) + { + mac_key = &m_peap_v2_CMK_B2_client; + } + + eap_variable_data_c mac_data(m_am_tools); + + status = create_crypto_binding_compound_mac( + mac_key, + &crypto_binding_tlv, + &mac_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_am_tools->memmove( + tlv_mac, + mac_data.get_data(mac_data.get_data_length()), + TLV_MAC_LENGTH); + + tlv_data_offset += TLV_MAC_LENGTH; + } + + EAP_TLS_PEAP_TRACE_PAYLOAD("Add TLV payload", &crypto_binding_tlv, m_is_client); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + // Data includes Intermediate Result TLV: + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |M|R| TLV Type | Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Status | TLVs... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // We do not support included TLVs. + // + + tls_peap_tlv_header_c intermediate_result_tlv( + m_am_tools, + final_eap_packet.get_type_data_offset(tlv_offset, intermediate_result_tlv_length), + final_eap_packet.get_type_data_length()); + if (intermediate_result_tlv.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + tlv_offset += intermediate_result_tlv_length; + + intermediate_result_tlv.reset_header( + static_cast(intermediate_result_tlv_payload_length)); + intermediate_result_tlv.set_flag_tlv_type(tls_peap_tlv_type_intermediate_result); + intermediate_result_tlv.set_flag_mandatory_tlv(true); + + + { + u16_t * const tlv_intermediate_status + = reinterpret_cast( + intermediate_result_tlv.get_data_offset(0ul, sizeof(u16_t))); + if (tlv_intermediate_status == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u16_t tlv_intermediate_status_value = 0ul; + if (result_eap_code == eap_code_success) + { + tlv_intermediate_status_value = static_cast(tls_peap_tlv_status_success); + } + else + { + tlv_intermediate_status_value = static_cast(tls_peap_tlv_status_failure); + } + + status = eap_write_u16_t_network_order( + tlv_intermediate_status, + sizeof(*tlv_intermediate_status), + tlv_intermediate_status_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TLS_PEAP_TRACE_PAYLOAD("Add TLV payload", &intermediate_result_tlv, m_is_client); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_eap_diameter_avp_message( + eap_buf_chain_wr_c * const packet, + const eap_header_wr_c * const sent_eap_packet, + const u8_t /* eap_identifier */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::create_eap_diameter_avp_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_eap_diameter_avp_message()"); + + if (packet->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + const u32_t tlv_payload_length + = sent_eap_packet->get_length(); + + const u32_t final_packet_length + = eap_diameter_avp_header_c::get_header_length(false) + + tlv_payload_length; + + eap_status_e status = packet->set_buffer_length(final_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (packet->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = packet->set_data_length(final_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_diameter_avp_header_c avp( + m_am_tools, + packet->get_data(packet->get_data_length()), + packet->get_data_length()); + if (avp.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // These packets are encapsulated to AVP. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AVP Code | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |V|M|r r r r r r| AVP Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Vendor-ID (optional) | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Data includes EAP-packet ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + status = avp.reset_header(static_cast(final_packet_length)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = avp.set_avp_code(eap_diameter_avp_code_eap_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = avp.set_avp_flag_mandatory_avp(false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + { + // Adds EAP-Packet as a payload to AVP. + u16_t * const eap_packet_payload = reinterpret_cast( + avp.get_data_offset(0ul, sent_eap_packet->get_length())); + if (eap_packet_payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + eap_packet_payload, + sent_eap_packet->get_header_buffer(sent_eap_packet->get_length()), + sent_eap_packet->get_length()); + } + + EAP_TLS_PEAP_TRACE_TTLS_PAYLOAD("Send TTLS AVP payload", &avp, m_is_client); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_nonce( + eap_variable_data_c * const nonce) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::create_nonce(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_nonce()"); + + eap_status_e status = nonce->set_buffer_length(TLV_NONCE_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + nonce->set_data_length(nonce->get_buffer_length()); + + crypto_random_c rand(m_am_tools); + if (rand.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = rand.get_rand_bytes( + nonce->get_data(nonce->get_data_length()), + nonce->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_nonce_peap_v2( + const bool create_client_nonce_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::create_nonce_peap_v2(%s): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + (create_client_nonce_when_true == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_nonce_peap_v2()"); + + eap_status_e status = eap_status_process_general_error; + + eap_variable_data_c * nonce = 0; + + if (create_client_nonce_when_true == true) + { + nonce = &m_peap_v2_client_nonce; + } + else + { + nonce = &m_peap_v2_server_nonce; + } + + status = create_nonce(nonce); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_compound_mac_key_peap_v2( + const bool create_client_CMK_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::create_compound_mac_key_peap_v2(%s): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + (create_client_CMK_when_true == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_compound_mac_key_peap_v2()"); + + eap_status_e status = eap_status_process_general_error; + + if (m_peap_v2_IPMKn.get_is_valid_data() == false + || m_peap_v2_IPMKn.get_data_length() != TLS_PEAP_V2_TK_LENGTH) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_peap_v2_ISKn.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_peap_v2_IPMKn"), + m_peap_v2_IPMKn.get_data(m_peap_v2_IPMKn.get_data_length()), + m_peap_v2_IPMKn.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_peap_v2_ISKn"), + m_peap_v2_ISKn.get_data(m_peap_v2_ISKn.get_data_length()), + m_peap_v2_ISKn.get_data_length())); + + { + eap_variable_data_c label(m_am_tools); + + status = label.set_copy_of_buffer( + TLS_INTERMEDIATE_COMBINED_KEY_LABEL, + TLS_INTERMEDIATE_COMBINED_KEY_LABEL_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + crypto_tls_sha1_prf_c tls_sha1_prf(m_am_tools); + + status = tls_sha1_prf.tls_prf_init( + &m_peap_v2_IPMKn, + &label, + &m_peap_v2_ISKn); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (tls_sha1_prf.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tls_sha1_prf.tls_prf_output( + m_peap_v2_IPMKn.get_data(m_peap_v2_IPMKn.get_data_length()), + m_peap_v2_IPMKn.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_peap_v2_IPMKn"), + m_peap_v2_IPMKn.get_data(m_peap_v2_IPMKn.get_data_length()), + m_peap_v2_IPMKn.get_data_length())); + } + + { + eap_variable_data_c label(m_am_tools); + + if (create_client_CMK_when_true == true) + { + status = label.set_copy_of_buffer( + TLS_INTERMEDIATE_COMPOUND_CLIENT_MAC_KEY_LABEL, + TLS_INTERMEDIATE_COMPOUND_CLIENT_MAC_KEY_LABEL_LENGTH); + } + else + { + status = label.set_copy_of_buffer( + TLS_INTERMEDIATE_COMPOUND_SERVER_MAC_KEY_LABEL, + TLS_INTERMEDIATE_COMPOUND_SERVER_MAC_KEY_LABEL_LENGTH); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + crypto_tls_sha1_prf_c tls_sha1_prf(m_am_tools); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_peap_v2_server_nonce"), + m_peap_v2_server_nonce.get_data(m_peap_v2_server_nonce.get_data_length()), + m_peap_v2_server_nonce.get_data_length())); + + if (create_client_CMK_when_true == true) + { + eap_variable_data_c client_server_nonce(m_am_tools); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_peap_v2_client_nonce"), + m_peap_v2_client_nonce.get_data(m_peap_v2_client_nonce.get_data_length()), + m_peap_v2_client_nonce.get_data_length())); + + status = client_server_nonce.set_copy_of_buffer( + &m_peap_v2_client_nonce); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = client_server_nonce.add_data( + &m_peap_v2_server_nonce); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_sha1_prf.tls_prf_init( + &m_peap_v2_IPMKn, + &label, + &client_server_nonce); + } + else + { + status = tls_sha1_prf.tls_prf_init( + &m_peap_v2_IPMKn, + &label, + &m_peap_v2_server_nonce); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (tls_sha1_prf.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c * cmk = &m_peap_v2_CMK_B1_server; + + if (create_client_CMK_when_true == true) + { + cmk = &m_peap_v2_CMK_B2_client; + } + + status = cmk->set_buffer_length(TLS_PEAP_V2_COMPOUND_MAC_KEY_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + cmk->set_data_length(TLS_PEAP_V2_COMPOUND_MAC_KEY_LENGTH); + + status = tls_sha1_prf.tls_prf_output( + cmk->get_data(cmk->get_data_length()), + cmk->get_data_length()); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLV MAC key CMK"), + cmk->get_data(cmk->get_data_length()), + cmk->get_data_length())); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_compound_session_key_peap_v2() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::create_compound_session_key_peap_v2(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_compound_session_key_peap_v2()"); + + eap_status_e status = eap_status_process_general_error; + + if (m_peap_v2_IPMKn.get_is_valid_data() == false + || m_peap_v2_IPMKn.get_data_length() != TLS_PEAP_V2_TK_LENGTH) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + { + eap_variable_data_c label(m_am_tools); + + status = label.set_copy_of_buffer( + TLS_INTERMEDIATE_COMPOUND_SESSION_KEY_LABEL, + TLS_INTERMEDIATE_COMPOUND_SESSION_KEY_LABEL_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + crypto_tls_sha1_prf_c tls_sha1_prf(m_am_tools); + + eap_variable_data_c client_server_nonce_outputlength(m_am_tools); + + status = client_server_nonce_outputlength.set_copy_of_buffer( + &m_peap_v2_client_nonce); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = client_server_nonce_outputlength.add_data( + &m_peap_v2_server_nonce); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + /* @{ What is the sizeof the OutputLength? } */ + + u8_t OutputLength = TLS_PEAP_V2_COMPOUND_SESSION_KEY_LENGTH; + + status = client_server_nonce_outputlength.add_data( + &OutputLength, + sizeof(OutputLength)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_sha1_prf.tls_prf_init( + &m_peap_v2_IPMKn, + &label, + &client_server_nonce_outputlength); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (tls_sha1_prf.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_peap_v2_CSK.set_buffer_length(TLS_PEAP_V2_COMPOUND_SESSION_KEY_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_peap_v2_CSK.set_data_length(TLS_PEAP_V2_COMPOUND_SESSION_KEY_LENGTH); + + status = tls_sha1_prf.tls_prf_output( + m_peap_v2_CSK.get_data(m_peap_v2_CSK.get_data_length()), + m_peap_v2_CSK.get_data_length()); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_crypto_binding_compound_mac( + const eap_variable_data_c * const peap_v2_CMK, + const tls_peap_tlv_header_c * const crypto_binding_tlv, + eap_variable_data_c * const mac_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::create_crypto_binding_compound_mac(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_crypto_binding_compound_mac()"); + + EAP_TLS_PEAP_TRACE_PAYLOAD("Create TLV MAC", crypto_binding_tlv, m_is_client); + + crypto_sha1_c sha1(m_am_tools); + crypto_hmac_c hmac(m_am_tools, &sha1, false); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLV MAC key CMK"), + peap_v2_CMK->get_data(peap_v2_CMK->get_data_length()), + peap_v2_CMK->get_data_length())); + + status = hmac.hmac_set_key(peap_v2_CMK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (hmac.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLV MAC data"), + crypto_binding_tlv->get_header_buffer( + crypto_binding_tlv->get_header_length() + + crypto_binding_tlv->get_data_length()), + crypto_binding_tlv->get_header_length() + + crypto_binding_tlv->get_data_length())); + + status = hmac.hmac_update( + crypto_binding_tlv->get_header_buffer( + crypto_binding_tlv->get_header_length() + + crypto_binding_tlv->get_data_length()), + crypto_binding_tlv->get_header_length() + + crypto_binding_tlv->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = mac_data->set_buffer_length(hmac.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + mac_data->set_data_length(hmac.get_digest_length()); + + u32_t mac_length = hmac.get_digest_length(); + + status = hmac.hmac_final( + mac_data->get_data(mac_data->get_data_length()), + &mac_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (mac_length != hmac.get_digest_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAPv2 Compound MAC"), + mac_data->get_data(mac_data->get_data_length()), + mac_data->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_send( + const eap_am_network_id_c * const /*network_id*/, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::packet_send(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_send()"); + + eap_buf_chain_wr_c * forwarded_packet = sent_packet; + u32_t forwarded_data_length = data_length; + u32_t forwarded_buffer_length = buffer_length; + u32_t forwaded_header_offset = header_offset; + + eap_status_e status = eap_status_process_general_error; + + eap_buf_chain_wr_c tmp_packet( + eap_write_buffer, + m_am_tools); + if (tmp_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + const u32_t eap_packet_length = sent_packet->get_data_length(); + + eap_header_wr_c sent_eap_packet( + m_am_tools, + sent_packet->get_data(eap_packet_length), + eap_packet_length); + if (sent_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + if (m_is_client == true) + { + trace_tunneled_packet(EAPL("<- TUNNELED packet client"), &sent_eap_packet); + } + else + { + trace_tunneled_packet(EAPL("<- TUNNELED packet server"), &sent_eap_packet); + } + + + if (m_eap_type == eap_type_peap) + { + if (m_peap_version == peap_version_0_xp) + { + // XP PEAP does not include EAP-header (code, identifier and length). + // Here we must remove those attributes. + // See draft-kamath-pppext-peapv0-00.txt. + + if (sent_eap_packet.get_code() == eap_code_request + || sent_eap_packet.get_code() == eap_code_response) + { + forwaded_header_offset += eap_header_base_c::get_header_length(); + } + else if (sent_eap_packet.get_code() == eap_code_success + || sent_eap_packet.get_code() == eap_code_failure) + { + if (m_is_client == true) + { + // Client does not send these packets. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // XP PEAPv0 does not include EAP-header (code, identifier and length). + // Here we must create those attributes. + // Exception to this rule is, EAP-success and EAP-failure are sent in "Extensions Request Packet" + // or "Extensions Response Packet". + // The whole EAP-header is included + // to "Extensions Request Packet" and "Extensions Response Packet". + // See draft-kamath-pppext-peapv0-00.txt. + // + // EAP-packet without code, identifier and length: + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | EAP-type | EAP-data ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // EAP-packet with "Extensions Request Packet" or "Extensions Response Packet": + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | EAP-code |EAP-identifier | EAP-length | EAP-type | EAP-data ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // EAP-code of "Extensions Request Packet" is 1 which is same as EAP-type of EAP-identity. + // EAP-code of "Extensions Response Packet" is 2 which is same as EAP-type of EAP-notification. + + u8_t send_eap_identifier = sent_eap_packet.get_identifier(); + if (m_is_client == false) + { + ++send_eap_identifier; + } + + status = create_result_tlv_message( + &tmp_packet, + sent_eap_packet.get_code(), + send_eap_identifier, + tls_peap_tlv_type_result); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + forwarded_packet = &tmp_packet; + + forwarded_data_length = tmp_packet.get_data_length(); + forwarded_buffer_length = tmp_packet.get_buffer_length(); + forwaded_header_offset = 0; + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send(): XP-PEAPv0 tunneled %s send.\n"), + eap_string.get_eap_code_string(sent_eap_packet.get_code()))); + } + } + else if (m_peap_version == peap_version_1) + { + // This version does not change packet. + +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + if (m_is_client == false + && m_server_use_peapv1_extensions_request == true + && (sent_eap_packet.get_code() == eap_code_success + || sent_eap_packet.get_code() == eap_code_failure)) + { + u8_t send_eap_identifier = sent_eap_packet.get_identifier(); + if (m_is_client == false) + { + ++send_eap_identifier; + } + + status = create_result_tlv_message( + &tmp_packet, + sent_eap_packet.get_code(), + send_eap_identifier, + tls_peap_tlv_type_result); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + forwarded_packet = &tmp_packet; + + forwarded_data_length = tmp_packet.get_data_length(); + forwarded_buffer_length = tmp_packet.get_buffer_length(); + forwaded_header_offset = 0; + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send(): PEAPv1 tunneled %s send.\n"), + eap_string.get_eap_code_string(sent_eap_packet.get_code()))); + } +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + + } + else if (m_peap_version == peap_version_2) + { + if (sent_eap_packet.get_code() == eap_code_request + || sent_eap_packet.get_code() == eap_code_response) + { + // These packets are encapsulated to EAP-TLV packet. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Code | Identifier | Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Type | Data.... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Data includes EAP-Payload TLV: + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |M|R| TLV Type | Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | EAP packet... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | TLVs... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + status = create_eap_payload_tlv_message( + &tmp_packet, + &sent_eap_packet, + sent_eap_packet.get_identifier()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + forwarded_packet = &tmp_packet; + + forwarded_data_length = tmp_packet.get_data_length(); + forwarded_buffer_length = tmp_packet.get_buffer_length(); + forwaded_header_offset = 0; + } + else if (sent_eap_packet.get_code() == eap_code_success + || sent_eap_packet.get_code() == eap_code_failure) + { + if (m_is_client == true) + { + // Client does not send these packets. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Server blocks the EAP-Success packet. + // Result TLV, Crypto Binding TLV and Intermediate Result TLV + // are created and sent within the state_notification() function + // by the send_tunneled_acknowledge_peap_v2() function + // when eap_state_authentication_finished_successfully or + // eap_state_authentication_terminated_unsuccessfully indication + // is received. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::") + EAPL("packet_send(), server blocks tunneled EAP-Success and EAP-Failure\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + } + else if (m_eap_type == eap_type_ttls) + { + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + if (m_tunneled_eap_in_ttls == true) +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + { + // These packets are encapsulated to AVP. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AVP Code | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |V|M|r r r r r r| AVP Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Vendor-ID (optional) | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Data includes EAP-packet ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (sent_eap_packet.get_code() == eap_code_success + || sent_eap_packet.get_code() == eap_code_failure) + { + if (m_is_client == true) + { + // Client does not send these packets. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Server blocks the tunneled EAP-Success packet. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::") + EAPL("packet_send(), server blocks tunneled EAP-Success and EAP-Failure\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + + } + else + { + status = create_eap_diameter_avp_message( + &tmp_packet, + &sent_eap_packet, + sent_eap_packet.get_identifier()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + forwarded_packet = &tmp_packet; + + forwarded_data_length = tmp_packet.get_data_length(); + forwarded_buffer_length = tmp_packet.get_buffer_length(); + forwaded_header_offset = 0; + } + } +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else + { + // This is plain MsChapv2 tunneled in EAP-TTLS. + status = send_ttls_ms_chapv2_packet(&sent_eap_packet); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("sent tunneled data:"), + forwarded_packet->get_data_offset( + forwaded_header_offset, + forwarded_packet->get_data_length()-forwaded_header_offset), + forwarded_packet->get_data_length()-forwaded_header_offset)); + + +#if defined(USE_EAP_ERROR_TESTS) + if (m_enable_random_errors == true + && m_manipulate_only_tunneled_messages == true) + { + status = m_am_tools->generate_random_error( + forwarded_packet, + false, + m_am_tools->get_packet_index(), + 0UL, + m_error_probability, + 0UL); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_EAP_ERROR_TESTS) + + + status = get_application_partner()->packet_send( + forwarded_packet, + forwaded_header_offset, + forwarded_data_length, + forwarded_buffer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::send_tunneled_acknowledge_xp_peap_v0( + const eap_code_value_e result_eap_code, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::send_tunneled_acknowledge_xp_peap_v0(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::send_tunneled_acknowledge_xp_peap_v0()"); + + eap_buf_chain_wr_c eap_ack_packet( + eap_write_buffer, + m_am_tools); + + if (eap_ack_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_application_eap_core_c::send_tunneled_acknowledge_xp_peap_v0(): ") + EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = create_result_tlv_message( + &eap_ack_packet, + result_eap_code, + eap_identifier, + tls_peap_tlv_type_result); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_tunneled_acknowledge_xp_peap_v0(): XP-PEAPv0 tunneled %s acknowledge send.\n"), + eap_string.get_eap_code_string(result_eap_code))); + + EAP_TRACE_DATA_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: XP-PEAPv0 EAP acknowledge packet"), + eap_ack_packet.get_data(eap_ack_packet.get_data_length()), + eap_ack_packet.get_data_length())); + + +#if defined(USE_EAP_ERROR_TESTS) + if (m_enable_random_errors == true + && m_manipulate_only_tunneled_messages == true) + { + status = m_am_tools->generate_random_error( + &eap_ack_packet, + false, + m_am_tools->get_packet_index(), + 0UL, + m_error_probability, + 0UL); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_EAP_ERROR_TESTS) + + status = get_application_partner()->packet_send( + &eap_ack_packet, + 0ul, + eap_ack_packet.get_data_length(), + EAP_CORE_PACKET_BUFFER_LENGTH + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::send_tunneled_acknowledge_peap_v2( + const eap_code_value_e result_eap_code, + const u8_t eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::send_tunneled_acknowledge_peap_v2()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::send_tunneled_acknowledge_peap_v2()"); + + eap_variable_data_c *peap_v2_nonce = &m_peap_v2_client_nonce; + if (m_is_client == false) + { + peap_v2_nonce = &m_peap_v2_server_nonce; + } + + if (peap_v2_nonce->get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_application_eap_core_c::send_tunneled_acknowledge_peap_v2(): ") + EAPL("peap_v2_nonce invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_buf_chain_wr_c eap_ack_packet( + eap_write_buffer, + m_am_tools); + + if (eap_ack_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_application_eap_core_c::send_tunneled_acknowledge_peap_v2(): ") + EAPL("packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = create_crypto_binding_tlv_message( + &eap_ack_packet, + result_eap_code, + eap_identifier, + peap_v2_nonce, + static_cast(m_peap_version)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_tunneled_acknowledge_peap_v2(): PEAPv2 tunneled %s acknowledge send.\n"), + eap_string.get_eap_code_string(result_eap_code))); + + EAP_TRACE_DATA_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" send: PEAPv2 EAP acknowledge packet"), + eap_ack_packet.get_data(eap_ack_packet.get_data_length()), + eap_ack_packet.get_data_length())); + +#if defined(USE_EAP_ERROR_TESTS) + if (m_enable_random_errors == true + && m_manipulate_only_tunneled_messages == true) + { + status = m_am_tools->generate_random_error( + &eap_ack_packet, + false, + m_am_tools->get_packet_index(), + 0UL, + m_error_probability, + 0UL); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_EAP_ERROR_TESTS) + + status = get_application_partner()->packet_send( + &eap_ack_packet, + 0ul, + eap_ack_packet.get_data_length(), + EAP_CORE_PACKET_BUFFER_LENGTH + ); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t tls_application_eap_core_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + u32_t offset = get_application_partner()->get_header_offset( + MTU, + trailer_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return offset; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (tunneling_type != eap_type_none) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::load_module(), ") + EAPL("tunneling_type is not eap_type_none, it is 0x%08x=%s\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(tunneling_type), + eap_header_string_c::get_eap_type_string(tunneling_type))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_status_e status = get_application_partner()->load_module( + type, + m_eap_type, // This is the tunneling EAP-type. + partner, + eap_type, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::unload_module( + const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_application_partner()->unload_module( + type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::peap_tunnel_ready() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::peap_tunnel_ready()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::peap_tunnel_ready()"); + + eap_status_e status = eap_status_ok; + + if (m_peap_version == peap_version_2) + { + eap_variable_data_c eap_tls_master_session_key(m_am_tools); + + status = get_application_partner()->get_eap_tls_master_session_key( + &eap_tls_master_session_key, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (eap_tls_master_session_key.get_data_length() + < TLS_PEAP_V2_TK_OFFSET + TLS_PEAP_V2_TK_LENGTH) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_encryption_parameter_size); + } + + status = m_peap_v2_IPMKn.set_copy_of_buffer( + eap_tls_master_session_key.get_data_offset( + TLS_PEAP_V2_TK_OFFSET, TLS_PEAP_V2_TK_LENGTH), + TLS_PEAP_V2_TK_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::start_peap_tunneled_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const u8_t received_eap_identifier, + const tls_session_type_e tls_session_type, + const bool /* tls_peap_server_authenticates_client_action */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::start_peap_tunneled_authentication(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::start_peap_tunneled_authentication()"); + + eap_status_e status = eap_status_process_general_error; + + +#if defined(USE_EAP_CORE_SERVER) + + if (m_is_client == false) + { + // Server + + if (m_eap_type == eap_type_peap + && (tls_session_type == tls_session_type_original_session_resumption + || tls_session_type == tls_session_type_stateless_session_resumption) + && m_peap_allow_tunneled_session_resumption == true +#if !defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + && m_peap_version == peap_version_0_xp +#endif //#if !defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + ) + { + if (m_peap_version == peap_version_0_xp) + { + if (is_client_when_true == false) + { + // Server sends tunneled EAP-Success. + + eap_buf_chain_wr_c forwarded_packet( + eap_write_buffer, + m_am_tools); + if (forwarded_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = create_result_tlv_message( + &forwarded_packet, + eap_code_success, + static_cast(received_eap_identifier+1ul), + tls_peap_tlv_type_result); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t forwarded_data_length = forwarded_packet.get_data_length(); + u32_t forwarded_buffer_length = forwarded_packet.get_buffer_length(); + u32_t forwaded_header_offset = 0; + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send(): XP-PEAPv0 tunneled %s send.\n"), + eap_string.get_eap_code_string(eap_code_success))); + +#if defined(USE_EAP_ERROR_TESTS) + if (m_enable_random_errors == true + && m_manipulate_only_tunneled_messages == true) + { + status = m_am_tools->generate_random_error( + &forwarded_packet, + false, + m_am_tools->get_packet_index(), + 0UL, + m_error_probability, + 0UL); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_EAP_ERROR_TESTS) + + + status = get_application_partner()->packet_send( + &forwarded_packet, + forwaded_header_offset, + forwarded_data_length, + forwarded_buffer_length); +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + } + } + else if (m_peap_version == peap_version_1) + { + +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + + // Send tunneled EAP-Success. + // This will tell client the tunneled + // EAP-session was also restored. + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + if (m_use_tppd_tls_peap == true + && m_use_tppd_peapv1_acknowledge_hack == true) + { + // This case does not send tunneled EAP-Success + // instead it sends plain EAP-Success. + + m_tunneled_eap_type_authentication_state + = eap_state_authentication_wait_tppd_peapv1_empty_acknowledge; + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_eap_type, + eap_state_none, + m_tunneled_eap_type_authentication_state, + received_eap_identifier, + true); + get_application_partner()->state_notification(¬ification); + + status = eap_status_ok; + } + else + { + if (m_eap_core == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + status = m_eap_core->send_eap_success( + &send_network_id, + received_eap_identifier); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_tunneled_eap_type_authentication_state + = eap_state_authentication_finished_successfully; + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + m_tunneled_eap_type_authentication_state, + received_eap_identifier, + false); + get_application_partner()->state_notification(¬ification); + + status = eap_status_success; + } + +#else + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + + } + else if (m_peap_version == peap_version_2) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + } + else + { + if (m_eap_core == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + status = m_eap_core->send_eap_identity_request( + receive_network_id); + } + } + else +#endif //#if defined(USE_EAP_CORE_SERVER) + { + // Client + + status = eap_status_ok; + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::restart_authentication( + const eap_am_network_id_c * const /*receive_network_id*/, + const bool /*is_client_when_true*/, + const bool /*force_clean_restart*/, + const bool /*from_timer*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE, we do not allow tunneled EAP-type restart authentication. + eap_status_e status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_data_crypto_keys( + const eap_am_network_id_c * const /*send_network_id*/, + const eap_master_session_key_c * const master_session_key + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::packet_data_crypto_keys()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_data_crypto_keys()"); + + eap_status_e status = eap_status_process_general_error; + + if (m_peap_version == peap_version_2) + { + status = m_peap_v2_ISKn.set_copy_of_buffer( + master_session_key); + } + else + { + // Note older PEAP version does not use keys generated by tunneled EAP-type. + // This is sad but true. + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + if (field == 0 + || data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (cf_str_EAP_default_type_hex_data.get_field()->compare( + m_am_tools, + field) == true + || cf_str_EAP_server_default_type_hex_data.get_field()->compare( + m_am_tools, + field) == true) + { + eap_type_value_e tunneled_type = m_peap_tunneled_eap_type; + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + if (m_tunneled_eap_in_ttls == false + && ( +#if defined(USE_EAP_EXPANDED_TYPES) + m_peap_tunneled_eap_type == eap_expanded_type_ttls_plain_mschapv2.get_type() +#else + m_peap_tunneled_eap_type == eap_type_plain_mschapv2 +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + )) + { + tunneled_type = eap_type_mschapv2; + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + if (field->get_type() == eap_configure_type_u32_t) + { + u32_t tunneled_eap_type = convert_eap_type_to_u32_t(tunneled_type); + status = data->set_copy_of_buffer(&tunneled_eap_type, sizeof(tunneled_eap_type)); + } + else if (field->get_type() == eap_configure_type_hex_data) + { + eap_expanded_type_c default_type(tunneled_type); + status = default_type.get_expanded_type_data(m_am_tools, data); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_type); + } + + } + else if (cf_str_EAP_CORE_retransmission_counter.get_field()->compare( + m_am_tools, + field) == true) + { + // We do not allow inner EAP Core to re-transmit packets. + u32_t retransmission_counter = 0ul; + status = data->set_copy_of_buffer(&retransmission_counter, sizeof(retransmission_counter)); + } + else if (cf_str_EAP_CORE_process_EAP_Nak_immediately.get_field()->compare( + m_am_tools, + field) == true) + { + // We do not allow inner EAP Core to delay EAP-Nak processing. + u32_t EAP_CORE_process_EAP_Nak_immediately = 1ul; // This is true value. + status = data->set_copy_of_buffer( + &EAP_CORE_process_EAP_Nak_immediately, + sizeof(EAP_CORE_process_EAP_Nak_immediately)); + } +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else if (m_tunneled_eap_in_ttls == false + && cf_str_EAP_MSCHAPV2_use_implicit_challenge.get_field()->compare( + m_am_tools, + field) == true) + { + u32_t use_implicit_challenge = 1ul; + status = data->set_copy_of_buffer(&use_implicit_challenge, sizeof(use_implicit_challenge)); + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else if (m_is_client == false + && m_eap_type == eap_type_peap + && m_peap_version == peap_version_0_xp + && cf_str_EAP_TLS_PEAP_check_identifier_of_eap_identity_response.get_field()->compare( + m_am_tools, + field) == true) + { + // Tunneled type on PEAPv0 server cannot check EAP-Identity exactly. + u32_t check_identifier_of_eap_identity_response = 0ul; + status = data->set_copy_of_buffer(&check_identifier_of_eap_identity_response, sizeof(check_identifier_of_eap_identity_response)); + } + else + { + status = get_application_partner()->read_configure( + field, + data); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_application_partner()->write_configure( + field, + data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_application_eap_core_c::set_tunneled_state( + const tls_session_type_e tls_session_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::set_tunneled_state(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::set_tunneled_state()"); + + m_tls_session_type = tls_session_type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_application_eap_core_c::state_notification( + const abs_eap_state_notification_c * const state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::state_notification(): notification state=%s") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + eap_state_notification_c::get_state_string(state->get_protocol_layer(), state->get_current_state()), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::state_notification()"); + + + const abs_eap_state_notification_c * notification = state; + eap_automatic_variable_c automatic_notification(m_am_tools, 0); + + if (state->get_protocol_layer() == eap_protocol_layer_eap) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::state_notification(): eap_protocol_layer_eap: state = %s") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + eap_state_notification_c::get_state_string(state->get_protocol_layer(), state->get_current_state()), + this)); + + if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully) + { + // Tunneled EAP-type terminated unsuccessfully. + m_tunneled_eap_type_authentication_state = static_cast( + state->get_current_state()); + if (m_is_client == true + && m_eap_type == eap_type_peap) + { + if (m_peap_version == peap_version_0_xp) + { + // Send tunneled EAP-Success acknowledge. + eap_status_e status = send_tunneled_acknowledge_xp_peap_v0( + eap_code_failure, + state->get_eap_identifier()); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + } + // XP-PEAPv0 Authentication FAILED. + } +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + else if (m_peap_version == peap_version_1 + && m_client_send_peapv1_extensions_response == true) + { + // Send tunneled EAP-Success acknowledge. + eap_status_e status = send_tunneled_acknowledge_xp_peap_v0( + eap_code_failure, + state->get_eap_identifier()); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + } + // PEAPv1 Authentication FAILED. + + notification = new eap_state_notification_c( + m_am_tools, + state->get_send_network_id(), + state->get_is_client(), + eap_state_notification_eap, + state->get_protocol_layer(), + state->get_eap_type(), + state->get_previous_state(), + eap_state_authentication_terminated_unsuccessfully_peapv1_extension, + state->get_eap_identifier(), + state->get_allow_send_eap_success()); + + automatic_notification.set_variable(notification); + + if (notification == 0) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + } +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + else if (m_peap_version == peap_version_2) + { + // Send tunneled EAP-Success acknowledge. + eap_status_e status = send_tunneled_acknowledge_peap_v2( + eap_code_failure, + state->get_eap_identifier()); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + } + // PEAPv2 Authentication FAILED. + } + } + else if (m_eap_type == eap_type_peap) + { + // Server + if (m_peap_version == peap_version_0_xp) + { + // Does nothing special. + // Server waits the EAP Response of Type=Extensions + // acknowled packet from client. + return; + } + else if (m_peap_version == peap_version_2) + { + // Does nothing special. + // Server waits the EAP Response of Type=Extensions + // acknowled packet from client. + return; + } + } + } + else if (state->get_current_state() == eap_state_authentication_finished_successfully) + { + // Tunneled EAP-type finished successfully. + m_tunneled_eap_type_authentication_state = static_cast( + state->get_current_state()); + + if (m_is_client == true + && m_eap_type == eap_type_peap) + { + if (m_peap_version == peap_version_0_xp) + { + // Send tunneled EAP-Success acknowledge. + eap_status_e status = send_tunneled_acknowledge_xp_peap_v0( + eap_code_success, + state->get_eap_identifier()); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + } + + // XP-PEAPv0 Authentication OK. + } +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + else if (m_peap_version == peap_version_1 + && m_client_send_peapv1_extensions_response == true) + { + // Send tunneled EAP-Success acknowledge. + eap_status_e status = send_tunneled_acknowledge_xp_peap_v0( + eap_code_success, + state->get_eap_identifier()); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + } + // PEAPv1 Authentication OK. + + notification = new eap_state_notification_c( + m_am_tools, + state->get_send_network_id(), + state->get_is_client(), + eap_state_notification_eap, + state->get_protocol_layer(), + state->get_eap_type(), + state->get_previous_state(), + eap_state_authentication_finished_successfully_peapv1_extension, + state->get_eap_identifier(), + state->get_allow_send_eap_success()); + + automatic_notification.set_variable(notification); + + if (notification == 0) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + } +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + else if (m_peap_version == peap_version_2) + { + // Send tunneled EAP-Success acknowledge. + + eap_status_e status = create_nonce_peap_v2(m_is_client); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + // Intermediate Combined Key is stored to m_peap_v2_IPMKn. + // Compound MAC Key is stored to m_peap_v2_CMK_Bn. + status = create_compound_mac_key_peap_v2(false); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + status = create_compound_mac_key_peap_v2(true); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + // First we must verify the received TLVs and B1 MAC. + status = verify_tunneled_acknowledge_peap_v2(); + if (status != eap_status_success) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + status = send_tunneled_acknowledge_peap_v2( + eap_code_success, + state->get_eap_identifier()); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + status = finish_successfull_authentication_peap_v2( + m_received_eap_identifier); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_terminated_unsuccessfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + + // PEAPv2 Authentication OK. + } + } + else if (m_eap_type == eap_type_peap) + { + // Server + if (m_peap_version == peap_version_0_xp) + { + // Does nothing special. + // Server waits the EAP Response of Type=Extensions acknowled packet from client. + return; + } + else if (m_peap_version == peap_version_2) + { + eap_status_e status = create_nonce_peap_v2(m_is_client); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_finished_successfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + // Intermediate Combined Key is stored to m_peap_v2_IPMKn. + // Compound MAC Key is stored to m_peap_v2_CMK_Bn. + status = create_compound_mac_key_peap_v2(m_is_client); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_finished_successfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + status = send_tunneled_acknowledge_peap_v2( + eap_code_success, + state->get_eap_identifier()); + if (status != eap_status_ok) + { + m_tunneled_eap_type_authentication_state + = eap_state_authentication_finished_successfully; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + else if (m_eap_type == eap_type_ttls) + { +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + if (m_tunneled_eap_in_ttls == true) + { + // TTLS with tunneled EAP. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::state_notification(): notification state=%s") + EAPL("this = 0x%08x, TTLS with tunneled EAP.\n"), + (m_is_client == true ? "client": "server"), + eap_state_notification_c::get_state_string(state->get_protocol_layer(), state->get_current_state()), + this)); + } + else if (m_tunneled_eap_in_ttls == false) + { + // TTLS with plain MsChapv2. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::state_notification(): notification state=%s") + EAPL("this = 0x%08x, TTLS with plain MsChapv2.\n"), + (m_is_client == true ? "client": "server"), + eap_state_notification_c::get_state_string(state->get_protocol_layer(), state->get_current_state()), + this)); + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + } + } + } + + get_application_partner()->state_notification(notification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const /* send_network_id */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Here we do not want to remove the session yet. It is removed after PEAP session finishes. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_application_partner()->set_timer( + initializer, + id, + data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + abs_tls_base_application_c * partner = get_application_partner(); + if (partner != 0) + { + status = partner->cancel_timer( + initializer, + id); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + abs_tls_base_application_c * partner = get_application_partner(); + if (partner != 0) + { + status = partner->cancel_all_timers(); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::check_is_valid_eap_type( + const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_application_eap_core_c::check_is_valid_eap_type(): EAP-type=0x%08x=%s\n"), + convert_eap_type_to_u32_t(eap_type), + eap_string.get_eap_type_string(eap_type))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::check_is_valid_eap_type()"); + + if (m_accepted_tunneled_eap_types.get_object_count() > 0ul) + { + bool allow_this_eap_type = false; + + eap_type_value_e * type = 0; + + for (u32_t ind = 0ul; ind < m_accepted_tunneled_eap_types.get_object_count(); ind++) + { + type = m_accepted_tunneled_eap_types.get_object(ind); + + if (type != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: tls_application_eap_core_c::check_is_valid_eap_type(): allowed EAP-type %d.\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(*type))); + } + + if (type != 0 + && eap_type == *type) + { + allow_this_eap_type = true; + break; + } + } // for() + + if (allow_this_eap_type == false) + { + // Not allowed EAP-type inside PEAP. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: tls_application_eap_core_c::check_is_valid_eap_type(): No allowed EAP-type=0x%08x=%s\n"), + convert_eap_type_to_u32_t(eap_type), + eap_string.get_eap_type_string(eap_type))); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::get_eap_type_list(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::get_eap_type_list()"); + + for (u32_t ind = 0ul; ind < m_accepted_tunneled_eap_types.get_object_count(); ind++) + { + const eap_type_value_e * const type = m_accepted_tunneled_eap_types.get_object(ind); + + if (type != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: tls_application_eap_core_c::get_eap_type_list(): allowed EAP-type %d.\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(*type))); + } + } + + eap_status_e status = copy_simple( + &m_accepted_tunneled_eap_types, + eap_type_list, + m_am_tools, + false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT abs_tls_base_application_c * tls_application_eap_core_c::get_application_partner() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_application_partner; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::set_application_partner( + abs_tls_base_application_c * const partner) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::set_application_partner(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::set_application_partner()"); + + m_application_partner = partner; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_application_partner()->add_rogue_ap(rogue_ap_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::set_session_timeout( + const u32_t session_timeout_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::set_session_timeout(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::set_session_timeout()"); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = get_application_partner()->set_session_timeout(session_timeout_ms); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::read_authority_identity(eap_variable_data_c * const /* authority_identity_payload*/) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::save_user_authorization_pac_opaque(const tls_extension_c * const /* extension */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// This is commented in tls_base_record_c::query_tunnel_PAC(). +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::query_tunnel_PAC( + const eap_fast_variable_data_c * const /* in_A_ID_TLV */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// This is commented in tls_base_record_c::cancel_query_tunnel_PAC(). +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::cancel_query_tunnel_PAC() +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::complete_query_ttls_pap_username_and_password( + const eap_variable_data_c * const ttls_pap_username, + const eap_variable_data_c * const ttls_pap_password, + const eap_status_e query_result) +{ + eap_status_e status(eap_status_process_general_error); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::complete_query_ttls_pap_username_and_password()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::complete_query_ttls_pap_username_and_password()"); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + if (query_result != eap_status_ok) + { + { + eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error); + + if (query_result == eap_status_user_cancel_authentication) + { + general_state_variable = eap_general_state_authentication_cancelled; + } + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + true, + eap_state_notification_eap, + eap_protocol_layer_general, + m_peap_tunneled_eap_type, + eap_state_none, + general_state_variable, + m_received_eap_identifier, + false); + + notification.set_authentication_error(query_result); + + m_application_partner->state_notification(¬ification); + } + + { + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + m_received_eap_identifier, + true); + m_application_partner->state_notification(¬ification); + } + } + else + { + if (ttls_pap_username == 0 + || ttls_pap_username->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (ttls_pap_password == 0 + || ttls_pap_password->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_variable_data_c tunneled_data(m_am_tools); + eap_variable_data_c avp(m_am_tools); + + { + status = create_ttls_diameter_avp( + &avp, + ttls_pap_username, + eap_diameter_avp_code_user_name, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tunneled_data.add_data(&avp); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + { + eap_variable_data_c padded_password(m_am_tools); + + status = padded_password.set_copy_of_buffer(ttls_pap_password); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t PADDING_LENGTH_MULTIPLIER(16ul); + + const u32_t padding_length((PADDING_LENGTH_MULTIPLIER - (padded_password.get_data_length() % PADDING_LENGTH_MULTIPLIER)) % PADDING_LENGTH_MULTIPLIER); + + if (padding_length > 0ul) + { + const u8_t PADDING[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; + + status = padded_password.add_data_to_offset(padded_password.get_data_length(), PADDING, padding_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = create_ttls_diameter_avp( + &avp, + &padded_password, + eap_diameter_avp_code_user_password, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tunneled_data.add_data(&avp); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_buf_chain_wr_c forwarded_packet( + eap_write_buffer, + m_am_tools, + tunneled_data.get_data(), + tunneled_data.get_data_length(), + false, + false, + 0ul); + if (forwarded_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = get_application_partner()->packet_send( + &forwarded_packet, + 0ul, + forwarded_packet.get_data_length(), + forwarded_packet.get_buffer_length()); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::check_ttls_plain_pap_payloads( + eap_diameter_payloads_c * const payloads, + eap_ttls_tunneled_message_type_e * const message_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::check_ttls_plain_pap_payloads()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::check_ttls_plain_pap_payloads()"); + + *message_type = eap_ttls_tunneled_message_type_none; + + eap_status_e status(eap_status_not_found); + + eap_array_c needed_payloads(m_am_tools); + + needed_payloads.reset(); + + if (m_is_client == false) + { + // First check are there User-Name and User-Password AVPs. + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_avp_code_c code_user_name( + eap_diameter_avp_code_user_name); + + status = needed_payloads.add_object(&code_user_name, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_avp_code_c code_user_password( + eap_diameter_avp_code_user_password); + + status = needed_payloads.add_object(&code_user_password, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Test the required attribute. + status = payloads->check_payloads_existense( + &needed_payloads); + if (status == eap_status_ok) + { + // This packet includes required AVPs. + + status = payloads->check_mandatory_payloads( + &needed_payloads); + if (status == eap_status_ok) + { + // All mandatory AVPs are included. + + *message_type = eap_ttls_tunneled_message_type_pap_response; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Match User-Name and User-Password AVPs.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else //if (m_is_client == true) + { + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // First check is there Reply-Message AVP. + + eap_diameter_avp_code_c code_reply_message( + eap_diameter_avp_code_reply_message); + + status = needed_payloads.add_object(&code_reply_message, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Test the required attribute. + status = payloads->check_payloads_existense( + &needed_payloads); + if (status == eap_status_ok) + { + // This packet includes required AVPs. + + status = payloads->check_mandatory_payloads( + &needed_payloads); + if (status == eap_status_ok) + { + // All mandatory AVPs are included. + + *message_type = eap_ttls_tunneled_message_type_pap_reply_message; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Match Reply-Message AVP.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_server_handles_pap_response( + eap_diameter_payloads_c * const /* payloads */, + const u8_t /* received_eap_identifier */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::ttls_server_handles_pap_response()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_server_handles_pap_response()"); + + eap_status_e status(eap_status_not_found); + + eap_diameter_variable_data_c * const user_name_payload + = m_ttls_received_payloads.get_payload(eap_diameter_avp_code_user_name); + + if (user_name_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_diameter_variable_data_c * const user_password_payload + = m_ttls_received_payloads.get_payload(eap_diameter_avp_code_user_password); + + if (user_password_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const password = user_password_payload->get_payload_buffer(); + + // Remove possible padding of user_password_payload. + while(true) + { + if (password->get_data_length() < 1ul) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t * last_char = password->get_data_offset(password->get_data_length()-1ul, 1ul) ; + + if (last_char != 0 + && *last_char == 0x00) + { + status = password->set_data_length(password->get_data_length()-1ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + break; + } + } + + status = m_application_partner->verify_ttls_pap_username_and_password( + user_name_payload->get_payload_buffer(), + password); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_server_handles_pap_reply_message( + eap_diameter_payloads_c * const /* payloads */, + const u8_t /* received_eap_identifier */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::ttls_server_handles_pap_reply_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_server_handles_pap_reply_message()"); + + eap_status_e status(eap_status_not_found); + + eap_diameter_variable_data_c * const reply_message_payload + = m_ttls_received_payloads.get_payload(eap_diameter_avp_code_reply_message); + + if (reply_message_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + status = m_application_partner->query_ttls_pap_username_and_password( + reply_message_payload->get_payload_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::handle_ttls_plain_pap_payloads( + eap_diameter_payloads_c * const payloads, + const eap_ttls_tunneled_message_type_e message_type, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::handle_ttls_plain_pap_payloads()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::handle_ttls_plain_pap_payloads()"); + + eap_status_e status(eap_status_not_found); + + switch(message_type) + { + case eap_ttls_tunneled_message_type_pap_response: + // Here are included User-Name, User-Password AVPs. + status = ttls_server_handles_pap_response(payloads, received_eap_identifier); + break; + case eap_ttls_tunneled_message_type_pap_reply_message: + // Here are included Reply-Message AVP. + status = ttls_server_handles_pap_reply_message(payloads, received_eap_identifier); + break; + default: + status = eap_status_unexpected_message; + break; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::complete_verify_ttls_pap_username_and_password( + const eap_status_e authentication_result, + const eap_variable_data_c * const ttls_pap_reply_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::complete_verify_ttls_pap_username_and_password()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::complete_verify_ttls_pap_username_and_password()"); + + eap_status_e status(eap_status_not_found); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + status = authentication_result; + + if (authentication_result == eap_status_ok) + { + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_finished_successfully, + m_received_eap_identifier, + true); + m_application_partner->state_notification(¬ification); + } + else + { + if (ttls_pap_reply_message != 0 + && ttls_pap_reply_message->get_is_valid_data() == true) + { + eap_variable_data_c tunneled_data(m_am_tools); + eap_variable_data_c avp(m_am_tools); + + { + status = create_ttls_diameter_avp( + &avp, + ttls_pap_reply_message, + eap_diameter_avp_code_reply_message, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tunneled_data.add_data(&avp); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_buf_chain_wr_c forwarded_packet( + eap_write_buffer, + m_am_tools, + tunneled_data.get_data(), + tunneled_data.get_data_length(), + false, + false, + 0ul); + if (forwarded_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = get_application_partner()->packet_send( + &forwarded_packet, + 0ul, + forwarded_packet.get_data_length(), + forwarded_packet.get_buffer_length()); + } + else + { + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_peap_tunneled_eap_type, + eap_state_none, + eap_state_authentication_terminated_unsuccessfully, + m_received_eap_identifier, + true); + m_application_partner->state_notification(¬ification); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::alert_received( + const tls_alert_level_e alert_level, + const tls_alert_description_e alert_description) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(alert_level); + EAP_UNREFERENCED_PARAMETER(alert_description); + + eap_tls_trace_string_c tls_trace; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s: tls_application_eap_core_c::alert_received(), level %d=%s, description %d=%s\n"), + (m_is_client == true ? "client": "server"), + alert_level, + tls_trace.get_alert_level_string(alert_level), + alert_description, + tls_trace.get_alert_description_string(alert_description))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_application_ttls_plain_mschapv2.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_application_ttls_plain_mschapv2.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2728 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 124 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "eap_core.h" +#include "eap_type_tls_peap_types.h" +#include "tls_record_header.h" +#include "abs_tls_base_application.h" +#include "tls_application_eap_core.h" +#include "tls_peap_types.h" +#include "tls_peap_tlv_header.h" +#include "eap_diameter_avp_header.h" +#include "eap_state_notification.h" +#include "eap_crypto_api.h" +#include "eap_header_string.h" +#include "abs_eap_am_mutex.h" +#include "eap_config.h" +#include "eapol_header.h" +#include "eap_network_id_selector.h" +#include "eap_tlv_message_data.h" +#include "eap_array_algorithms.h" +#include "eap_automatic_variable.h" +#include "eap_base_type.h" + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + #include "eap_type_mschapv2_types.h" + #include "eap_type_mschapv2_header.h" +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::check_ttls_plain_mschapv2_payloads( + eap_diameter_payloads_c * const payloads, + eap_ttls_tunneled_message_type_e * const message_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::check_ttls_plain_mschapv2_payloads()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::check_ttls_plain_mschapv2_payloads()"); + + *message_type = eap_ttls_tunneled_message_type_none; + + eap_status_e status(eap_status_not_found); + + eap_array_c needed_payloads(m_am_tools); + + if (m_is_client == false) + { + { + // First check are there User-Name, MS-CHAP-Challenge and MS-CHAP2-Response AVPs. + + needed_payloads.reset(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_avp_code_c code_user_name( + eap_diameter_avp_code_user_name); + + status = needed_payloads.add_object(&code_user_name, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_avp_code_c code_ms_chap_challenge( + eap_diameter_vendor_code_of_microsoft_ms_chap_challenge.get_code()); + + status = needed_payloads.add_object(&code_ms_chap_challenge, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_avp_code_c code_ms_chap2_response( + eap_diameter_vendor_code_of_microsoft_ms_chap2_response.get_code()); + + status = needed_payloads.add_object(&code_ms_chap2_response, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Test the required attribute. + status = payloads->check_payloads_existense( + &needed_payloads); + if (status == eap_status_ok) + { + // This packet includes required AVPs. + + status = payloads->check_mandatory_payloads( + &needed_payloads); + if (status == eap_status_ok) + { + // All mandatory AVPs are included. + + *message_type = eap_ttls_tunneled_message_type_ms_chapv2_response; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Match User-Name, MS-CHAP-Challenge and MS-CHAP2-Response AVPs.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + { + // Second check are there MS-CHAP-NT-Enc-PW, MS-CHAP2-CPW, and MS-CHAP-Challenge AVPs. + + needed_payloads.reset(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_avp_code_c code_ms_chap_nt_enc_pw( + eap_diameter_vendor_code_of_microsoft_ms_chap_nt_enc_pw.get_code()); + + status = needed_payloads.add_object(&code_ms_chap_nt_enc_pw, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_avp_code_c code_ms_chap2_cpw( + eap_diameter_vendor_code_of_microsoft_ms_chap2_cpw.get_code()); + + status = needed_payloads.add_object(&code_ms_chap2_cpw, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_avp_code_c code_ms_chap_challenge( + eap_diameter_vendor_code_of_microsoft_ms_chap_challenge.get_code()); + + status = needed_payloads.add_object(&code_ms_chap_challenge, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Test the required attribute. + status = payloads->check_payloads_existense( + &needed_payloads); + if (status == eap_status_ok) + { + // This packet includes required AVPs. + + status = payloads->check_mandatory_payloads( + &needed_payloads); + if (status == eap_status_ok) + { + // All mandatory AVPs are included. + + *message_type = eap_ttls_tunneled_message_type_ms_chapv2_change_password; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Match MS-CHAP-NT-Enc-PW, MS-CHAP2-CPW, and MS-CHAP-Challenge AVPs.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + else //if (m_is_client == true) + { + { + // First check are there MS-CHAP2-Success AVP. + + needed_payloads.reset(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_avp_code_c code_ms_chap2_success( + eap_diameter_vendor_code_of_microsoft_ms_chap2_success.get_code()); + + status = needed_payloads.add_object(&code_ms_chap2_success, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Test the required attribute. + status = payloads->check_payloads_existense( + &needed_payloads); + if (status == eap_status_ok) + { + // This packet includes required AVPs. + + status = payloads->check_mandatory_payloads( + &needed_payloads); + if (status == eap_status_ok) + { + // All mandatory AVPs are included. + + *message_type = eap_ttls_tunneled_message_type_ms_chapv2_success; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Match MS-CHAP2-Success AVP.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + { + // Second check are there MS-CHAP2-Error AVP. + + needed_payloads.reset(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_avp_code_c code_ms_chap_error( + eap_diameter_vendor_code_of_microsoft_ms_chap_error.get_code()); + + status = needed_payloads.add_object(&code_ms_chap_error, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Test the required attribute. + status = payloads->check_payloads_existense( + &needed_payloads); + if (status == eap_status_ok) + { + // This packet includes required AVPs. + + status = payloads->check_mandatory_payloads( + &needed_payloads); + if (status == eap_status_ok) + { + // All mandatory AVPs are included. + + *message_type = eap_ttls_tunneled_message_type_ms_chapv2_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Match MS-CHAP2-Error AVP.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_server_handles_ms_chapv2_response( + eap_diameter_payloads_c * const /* payloads */, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("PEAP: %s: function: tls_application_eap_core_c::ttls_server_handles_ms_chapv2_response(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_server_handles_ms_chapv2_response()"); + + eap_status_e status(eap_status_not_found); + + eap_diameter_variable_data_c * const user_name_payload + = m_ttls_received_payloads.get_payload(eap_diameter_avp_code_user_name); + + if (user_name_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const user_name + = user_name_payload->get_payload_buffer(); + + if (user_name->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + + status = get_application_partner()->get_ttls_implicit_challenge( + &m_ttls_implicit_challenge, + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_FULL_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u8_t * const mschapv2_challenge = m_ttls_implicit_challenge.get_data_offset( + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_OFFSET, + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH); + if (mschapv2_challenge == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ttls_server_handles_ms_chapv2_response(): mschapv2_challenge"), + mschapv2_challenge, + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH)); + + { + eap_variable_data_c memory_store_key(m_am_tools); + + eap_status_e status = memory_store_key.set_copy_of_buffer( + EAP_MSCHAPV2_IMPLICIT_CHALLENGE_HANDLE_KEY, + sizeof(EAP_MSCHAPV2_IMPLICIT_CHALLENGE_HANDLE_KEY)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = memory_store_key.add_data( + &m_is_client, + sizeof(m_is_client)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_network_id_selector_c state_selector( + m_am_tools, + &m_receive_network_id); + + status = memory_store_key.add_data( + &state_selector); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_tlv_message_data_c tlv_data(m_am_tools); + + status = tlv_data.add_message_data( + eap_type_mschapv2_implicit_challenge, + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH, + mschapv2_challenge); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_am_tools->memory_store_remove_data(&memory_store_key); + if (status != eap_status_ok + && status != eap_status_not_found) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_am_tools->memory_store_add_data( + &memory_store_key, + &tlv_data, + eap_type_default_credential_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ttls_server_handles_ms_chapv2_response(): cannot store credentials\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // We must create EAP-Response/Identity message and forward that message + // to tunneled EAP-MsChapv2. + + u32_t eap_length = eap_header_wr_c::get_header_length() + 1ul + user_name->get_data_length(); + + eap_buf_chain_wr_c eap_packet_buffer( + eap_write_buffer, + m_am_tools, + eap_length); + + if (eap_packet_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_wr_c forwarded_eap_packet( + m_am_tools, + eap_packet_buffer.get_data(eap_length), + eap_length); + + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + forwarded_eap_packet.reset_header( + static_cast(eap_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_identifier(received_eap_identifier); + forwarded_eap_packet.set_code(eap_code_response); + forwarded_eap_packet.set_length( + static_cast(eap_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_type( + eap_type_identity, + m_use_eap_expanded_type); + + u8_t * const eap_type_data = forwarded_eap_packet.get_type_data(user_name->get_data_length()); + if (eap_type_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove(eap_type_data, user_name->get_data(), user_name->get_data_length()); + + set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_identity_response); + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + eap_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_server_handles_ms_chapv2_change_password( + eap_diameter_payloads_c * const /* payloads */, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::ttls_server_handles_ms_chapv2_change_password()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_server_handles_ms_chapv2_change_password()"); + + eap_status_e status(eap_status_not_found); + + const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length + + mschapv2_change_password_c::get_header_minimum_size(); + + const u32_t eap_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + type_data_length; + + eap_buf_chain_wr_c eap_packet_buffer( + eap_write_buffer, + m_am_tools, + eap_length); + if (eap_packet_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_wr_c forwarded_eap_packet( + m_am_tools, + eap_packet_buffer.get_data(eap_length), + eap_length); + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + forwarded_eap_packet.set_code(eap_code_response); + forwarded_eap_packet.set_identifier(received_eap_identifier); + forwarded_eap_packet.set_length( + static_cast(eap_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + forwarded_eap_packet.get_type_data_offset(0, forwarded_eap_packet.get_type_data_length()), + forwarded_eap_packet.get_type_data_length()); + mschapv2_header.set_opcode(mschapv2_opcode_change_password); + + const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset( + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET, + sizeof(u8_t)); + if (mschapv2ident == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ttls_server_handles_ms_chapv2_change_password(): mschapv2ident"), + mschapv2ident, + sizeof(*mschapv2ident))); + + mschapv2_header.set_mschapv2_id(*mschapv2ident); + mschapv2_header.set_ms_length(static_cast(type_data_length)); + + mschapv2_change_password_c response( + m_am_tools, + mschapv2_header.get_data(), + mschapv2_header.get_data_length()); + if (response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = response.set_constants(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + eap_diameter_variable_data_c * const nt_enc_pw_payload + = m_ttls_received_payloads.get_payload( + eap_diameter_vendor_code_of_microsoft_ms_chap_nt_enc_pw.get_code()); + + if (nt_enc_pw_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const nt_enc_pw + = nt_enc_pw_payload->get_payload_buffer(); + + if (nt_enc_pw == 0 + || nt_enc_pw->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (nt_enc_pw->get_data_length() != EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_PASSWORD_SIZE) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + response.set_encrypted_pw_block(nt_enc_pw->get_data()); + } + + { + eap_diameter_variable_data_c * const cpw_payload + = m_ttls_received_payloads.get_payload( + eap_diameter_vendor_code_of_microsoft_ms_chap2_cpw.get_code()); + + if (cpw_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const cpw + = cpw_payload->get_payload_buffer(); + + if (cpw == 0 + || cpw->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (cpw->get_data_length() + != (EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_HASH_SIZE + + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE + + EAP_MSCHAPV2_NT_RESPONSE_SIZE)) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u32_t offset = 0ul; + + response.set_encrypted_hash( + cpw->get_data_offset(offset, EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_HASH_SIZE)); + + offset += EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_HASH_SIZE; + + response.set_peer_challenge( + cpw->get_data_offset(offset, EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + + offset += EAP_MSCHAPV2_PEER_CHALLENGE_SIZE; + + response.set_nt_response( + cpw->get_data_offset(offset, EAP_MSCHAPV2_NT_RESPONSE_SIZE)); + } + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + eap_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_change_password_response); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_client_handles_ms_chapv2_success( + eap_diameter_payloads_c * const /* payloads */, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::ttls_client_handles_ms_chapv2_success()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_client_handles_ms_chapv2_success()"); + + eap_status_e status(eap_status_not_found); + + eap_diameter_variable_data_c * const success_data_payload + = m_ttls_received_payloads.get_payload( + eap_diameter_vendor_code_of_microsoft_ms_chap2_success.get_code()); + + if (success_data_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const success_data + = success_data_payload->get_payload_buffer(); + + if (success_data == 0 + || success_data->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + const u32_t type_data_length + = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length + + (success_data->get_data_length() - 1ul); + + const u32_t eap_length + = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + type_data_length; + + eap_buf_chain_wr_c eap_packet_buffer( + eap_write_buffer, + m_am_tools, + eap_length); + if (eap_packet_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_wr_c forwarded_eap_packet( + m_am_tools, + eap_packet_buffer.get_data(eap_length), + eap_length); + + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + forwarded_eap_packet.reset_header( + static_cast(eap_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_identifier(static_cast(received_eap_identifier+1ul)); + forwarded_eap_packet.set_code(eap_code_request); + forwarded_eap_packet.set_length( + static_cast(eap_length), + m_use_eap_expanded_type); + + u8_t * const eap_data = forwarded_eap_packet.get_data(success_data->get_data_length()); + if (eap_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + forwarded_eap_packet.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + forwarded_eap_packet.get_type_data_offset( + 0, + forwarded_eap_packet.get_type_data_length()), + forwarded_eap_packet.get_type_data_length()); + + mschapv2_header.set_opcode(mschapv2_opcode_success); + + const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset( + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET, + sizeof(u8_t)); + if (mschapv2ident == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ttls_client_handles_ms_chapv2_success(): mschapv2ident"), + mschapv2ident, + sizeof(*mschapv2ident))); + + mschapv2_header.set_mschapv2_id(*mschapv2ident); + mschapv2_header.set_ms_length(static_cast(type_data_length)); + + mschapv2_response_c response( + m_am_tools, + mschapv2_header.get_data(), + mschapv2_header.get_data_length()); + if (response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = response.set_constants(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + u8_t * ms_success_data = mschapv2_header.get_data(); + if (ms_success_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (success_data->get_data_length() < 1ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Copy auth string after headers + m_am_tools->memmove( + ms_success_data, + success_data->get_data_offset(1ul, success_data->get_data_length() - 1ul), + success_data->get_data_length() - 1ul); + + set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_success_request); + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + eap_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_complete_success_request) + { + eap_header_wr_c sent_eap_packet( + m_am_tools, + m_ttls_sent_eap_packet.get_data(), + m_ttls_sent_eap_packet.get_data_length()); + + status = ttls_tunneled_message_state_complete_success_request(&sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_client_handles_ms_chapv2_error( + eap_diameter_payloads_c * const /* payloads */, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::ttls_client_handles_ms_chapv2_error()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_client_handles_ms_chapv2_error()"); + + eap_status_e status(eap_status_not_found); + + eap_diameter_variable_data_c * const error_data_payload + = m_ttls_received_payloads.get_payload( + eap_diameter_vendor_code_of_microsoft_ms_chap_error.get_code()); + + if (error_data_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const error_data + = error_data_payload->get_payload_buffer(); + + if (error_data == 0 + || error_data->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length + + mschapv2_challenge_c::get_header_minimum_size() + + error_data->get_data_length(); + + const u32_t eap_length + = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + type_data_length; + + eap_buf_chain_wr_c eap_packet_buffer( + eap_write_buffer, + m_am_tools, + eap_length); + if (eap_packet_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_wr_c forwarded_eap_packet( + m_am_tools, + eap_packet_buffer.get_data(eap_length), + eap_length); + + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + forwarded_eap_packet.reset_header( + static_cast(eap_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_identifier(static_cast(received_eap_identifier+1ul)); + forwarded_eap_packet.set_code(eap_code_request); + forwarded_eap_packet.set_length( + static_cast(eap_length), + m_use_eap_expanded_type); + + u8_t * const eap_data = forwarded_eap_packet.get_data(error_data->get_data_length()); + if (eap_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + forwarded_eap_packet.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + forwarded_eap_packet.get_type_data_offset( + 0, + forwarded_eap_packet.get_type_data_length()), + forwarded_eap_packet.get_type_data_length()); + + mschapv2_header.set_opcode(mschapv2_opcode_failure); + + const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset( + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET, + sizeof(u8_t)); + if (mschapv2ident == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ttls_client_handles_ms_chapv2_error(): mschapv2ident"), + mschapv2ident, + sizeof(*mschapv2ident))); + + mschapv2_header.set_mschapv2_id(*mschapv2ident); + mschapv2_header.set_ms_length(static_cast(type_data_length)); + + mschapv2_response_c response( + m_am_tools, + mschapv2_header.get_data(), + mschapv2_header.get_data_length()); + if (response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = response.set_constants(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + u8_t * ms_error_data = mschapv2_header.get_data(); + if (ms_error_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Copy auth string after headers + m_am_tools->memmove( + ms_error_data, + error_data->get_data(), + error_data->get_data_length()); + + set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_error_request); + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + eap_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_complete_error_request) + { + eap_header_wr_c sent_eap_packet( + m_am_tools, + m_ttls_sent_eap_packet.get_data(), + m_ttls_sent_eap_packet.get_data_length()); + + status = ttls_tunneled_message_state_complete_error_request(&sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::handle_ttls_plain_mschapv2_payloads( + eap_diameter_payloads_c * const payloads, + const eap_ttls_tunneled_message_type_e message_type, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: tls_application_eap_core_c::handle_ttls_plain_mschapv2_payloads()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::handle_ttls_plain_mschapv2_payloads()"); + + eap_status_e status(eap_status_not_found); + + switch(message_type) + { + case eap_ttls_tunneled_message_type_ms_chapv2_response: + // Here are included User-Name, MS-CHAP-Challenge and MS-CHAP2-Response AVPs. + status = ttls_server_handles_ms_chapv2_response(payloads, received_eap_identifier); + break; + case eap_ttls_tunneled_message_type_ms_chapv2_change_password: + // Here are included MS-CHAP-NT-Enc-PW, MS-CHAP2-CPW, and MS-CHAP-Challenge AVPs. + status = ttls_server_handles_ms_chapv2_change_password(payloads, received_eap_identifier); + break; + case eap_ttls_tunneled_message_type_ms_chapv2_success: + // Here is included MS-CHAP2-Success AVP. + status = ttls_client_handles_ms_chapv2_success(payloads, received_eap_identifier); + break; + case eap_ttls_tunneled_message_type_ms_chapv2_error: + // Here is included MS-CHAP2-Error AVP. + status = ttls_client_handles_ms_chapv2_error(payloads, received_eap_identifier); + break; + default: + status = eap_status_unexpected_message; + break; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_ttls_diameter_avp( + eap_variable_data_c * const avp, + const eap_variable_data_c * const data, + eap_diameter_avp_code_c code, + const bool include_vendor_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: tls_application_eap_core_c::create_ttls_diameter_avp()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_ttls_diameter_avp()"); + + if (avp == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (data == 0 + || data->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (code.get_vendor_code() == eap_diameter_avp_code_none) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = avp->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + bool needs_vendor_id = include_vendor_id; + if (code.get_vendor_id() != eap_diameter_vendor_id_of_ietf) + { + needs_vendor_id = true; + } + + const u32_t padding_byte_data = 3ul; + const u32_t avp_payload_length + = eap_diameter_avp_header_c::get_header_length(needs_vendor_id) + data->get_data_length(); + + status = avp->set_buffer_length(avp_payload_length + padding_byte_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (avp->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = avp->set_data_length(avp_payload_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_diameter_avp_header_c avp_header( + m_am_tools, + avp->get_data(), + avp->get_data_length()); + if (avp_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // These packets are encapsulated to AVP. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | AVP Code | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |V|M|r r r r r r| AVP Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Vendor-ID (optional) | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Data ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + status = avp_header.reset_header(static_cast(avp_payload_length)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = avp_header.set_avp_code(code); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = avp_header.set_avp_flag_mandatory_avp(false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + { + // Adds data as a payload to AVP. + u16_t * const avp_payload = reinterpret_cast( + avp_header.get_data_offset(0ul, data->get_data_length())); + if (avp_payload == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_am_tools->memmove( + avp_payload, + data->get_data(), + data->get_data_length()); + } + + u32_t padding_length = avp_header.get_padding_length(); + if (padding_length != 0ul) + { + // Add padding. + u8_t padding_byte = 0ul; + + for (u32_t ind = 0ul; ind < padding_length; ind++) + { + status = avp->add_data( + &padding_byte, + sizeof(padding_byte)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + } + + EAP_TLS_PEAP_TRACE_TTLS_PAYLOAD("Created TTLS AVP payload", &avp_header, m_is_client); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_response( + eap_header_wr_c * const sent_eap_packet) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_response(): ") + EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"), + (m_is_client == true ? "client": "server"), + this, + get_ttls_tunneled_message_state(), + eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()), + convert_eap_type_to_u32_t(sent_eap_packet->get_type()))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_response()"); + + eap_status_e status(eap_status_process_general_error); + + // This message shoud include MS-CHAP-V2 Challenge. + // We ignore this Challenge and instead we send Implicit Challenge from client. + /** + * @{ This will require changes in EAP-MsChapv2 server. + * Implicit Challenge need to be used in authentication check. } + */ + + const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset( + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET, + sizeof(u8_t)); + if (mschapv2ident == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ttls_tunneled_message_state_process_identity_response(): mschapv2ident"), + mschapv2ident, + sizeof(*mschapv2ident))); + + eap_diameter_variable_data_c * const user_name_payload + = m_ttls_received_payloads.get_payload(eap_diameter_avp_code_user_name); + + if (user_name_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const user_name + = user_name_payload->get_payload_buffer(); + + if (user_name != 0 + && user_name->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length + + mschapv2_response_c::get_header_minimum_size() + + user_name->get_data_length(); + + const u32_t eap_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + type_data_length; + + eap_buf_chain_wr_c eap_packet_buffer( + eap_write_buffer, + m_am_tools, + eap_length); + if (eap_packet_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_wr_c forwarded_eap_packet( + m_am_tools, + eap_packet_buffer.get_data(eap_length), + eap_length); + + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + forwarded_eap_packet.reset_header( + static_cast(eap_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_identifier(sent_eap_packet->get_identifier()); + forwarded_eap_packet.set_code(eap_code_response); + forwarded_eap_packet.set_length( + static_cast(eap_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + forwarded_eap_packet.get_type_data_offset( + 0, + forwarded_eap_packet.get_type_data_length()), + forwarded_eap_packet.get_type_data_length()); + + mschapv2_header.set_opcode(mschapv2_opcode_response); + mschapv2_header.set_mschapv2_id(*mschapv2ident); + mschapv2_header.set_ms_length(static_cast(type_data_length)); + + mschapv2_response_c response( + m_am_tools, + mschapv2_header.get_data(), + mschapv2_header.get_data_length()); + if (response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = response.set_constants(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_variable_data_c * const peer_challenge_payload + = m_ttls_received_payloads.get_payload( + eap_diameter_vendor_code_of_microsoft_ms_chap_challenge.get_code()); + + if (peer_challenge_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const peer_challenge + = peer_challenge_payload->get_payload_buffer(); + + if (peer_challenge != 0 + && peer_challenge->get_is_valid_data() == false + && peer_challenge->get_data_length() == EAP_MSCHAPV2_PEER_CHALLENGE_SIZE) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + const u8_t * const mschapv2_challenge = m_ttls_implicit_challenge.get_data_offset( + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_OFFSET, + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH); + if (mschapv2_challenge == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_am_tools->memcmp( + peer_challenge->get_data(), + mschapv2_challenge, + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_diameter_variable_data_c * const response_data_payload + = m_ttls_received_payloads.get_payload( + eap_diameter_vendor_code_of_microsoft_ms_chap2_response.get_code()); + + if (response_data_payload == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_variable_data_c * const response_data + = response_data_payload->get_payload_buffer(); + + if (response_data != 0 + && response_data->get_is_valid_data() == false + && response_data->get_data_length() != EAP_MSCHAPV2_RESPONSE_MESSAGE_SIZE) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + response.set_peer_challenge( + response_data->get_data_offset( + EAP_MSCHAPV2_PEER_CHALLENGE_OFFSET, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); + + response.set_nt_response( + response_data->get_data_offset( + EAP_MSCHAPV2_NT_RESPONSE_OFFSET, + EAP_MSCHAPV2_NT_RESPONSE_SIZE)); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Copy username to end of response packet + response.set_name(user_name->get_data()); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_response); + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + eap_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_response( + eap_header_wr_c * const sent_eap_packet) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_response(): ") + EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"), + (m_is_client == true ? "client": "server"), + this, + get_ttls_tunneled_message_state(), + eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()), + convert_eap_type_to_u32_t(sent_eap_packet->get_type()))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_response()"); + + eap_status_e status(eap_status_process_general_error); + + // This message should include MS-CHAP-V2 Success or MS-CHAP-V2 Error. + + mschapv2_header_c mschapv2_header( + m_am_tools, + sent_eap_packet->get_type_data_offset(0, sent_eap_packet->get_type_data_length()), + sent_eap_packet->get_type_data_length()); + + status = mschapv2_header.check_header(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (mschapv2_header.get_opcode() == mschapv2_opcode_success) + { + eap_variable_data_c avp_success(m_am_tools); + + { + eap_variable_data_c success_data(m_am_tools); + + success_data.reset(); + + u8_t ident = mschapv2_header.get_mschapv2_id(); + + status = success_data.add_data( + &ident, + EAP_MSCHAPV2_IDENT_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (mschapv2_header.get_ms_length() < EAP_MSCHAPV2_HEADER_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ttls_tunneled_message_state_process_response(): mschapv2 data"), + mschapv2_header.get_data(), + mschapv2_header.get_ms_length()- EAP_MSCHAPV2_HEADER_SIZE)); + + status = success_data.add_data( + mschapv2_header.get_data(), + mschapv2_header.get_ms_length() - EAP_MSCHAPV2_HEADER_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = create_ttls_diameter_avp( + &avp_success, + &success_data, + eap_diameter_vendor_code_of_microsoft_ms_chap2_success.get_code(), + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_buf_chain_wr_c forwarded_packet( + eap_write_buffer, + m_am_tools, + avp_success.get_data(), + avp_success.get_data_length(), + false, + false, + 0ul); + if (forwarded_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = get_application_partner()->packet_send( + &forwarded_packet, + 0ul, + forwarded_packet.get_data_length(), + forwarded_packet.get_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_internal_type, + eap_type_ttls, + eap_state_none, + tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack, + sent_eap_packet->get_identifier(), + false); + get_application_partner()->state_notification(¬ification); + + m_ttls_plain_ms_chap_v2_eap_identifier = sent_eap_packet->get_identifier(); + } + else if (mschapv2_header.get_opcode() == mschapv2_opcode_failure) + { + eap_variable_data_c avp_error(m_am_tools); + + { + eap_variable_data_c error_data(m_am_tools); + status = error_data.set_buffer( + mschapv2_header.get_data(), + mschapv2_header.get_ms_length() - EAP_MSCHAPV2_HEADER_SIZE, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = create_ttls_diameter_avp( + &avp_error, + &error_data, + eap_diameter_vendor_code_of_microsoft_ms_chap_error.get_code(), + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_buf_chain_wr_c forwarded_packet( + eap_write_buffer, + m_am_tools, + avp_error.get_data(), + avp_error.get_data_length(), + false, + false, + 0ul); + if (forwarded_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = get_application_partner()->packet_send( + &forwarded_packet, + 0ul, + forwarded_packet.get_data_length(), + forwarded_packet.get_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_ttls_plain_ms_chap_v2_eap_identifier = sent_eap_packet->get_identifier(); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_change_password_response( + eap_header_wr_c * const sent_eap_packet) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_change_password_response(): ") + EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"), + (m_is_client == true ? "client": "server"), + this, + get_ttls_tunneled_message_state(), + eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()), + convert_eap_type_to_u32_t(sent_eap_packet->get_type()))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_change_password_response()"); + + eap_status_e status(eap_status_process_general_error); + + // This message should include MS-CHAP-V2 Success. + + status = ttls_tunneled_message_state_process_response(sent_eap_packet); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_request( + eap_header_wr_c * const sent_eap_packet) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_request(): ") + EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"), + (m_is_client == true ? "client": "server"), + this, + get_ttls_tunneled_message_state(), + eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()), + convert_eap_type_to_u32_t(sent_eap_packet->get_type()))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_request()"); + + eap_status_e status(eap_status_process_general_error); + + // This message includes username. + + u32_t user_name_length = sent_eap_packet->get_type_data_length(); + + status = m_ttls_user_name.set_copy_of_buffer( + sent_eap_packet->get_type_data(user_name_length), + user_name_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_application_partner()->get_ttls_implicit_challenge( + &m_ttls_implicit_challenge, + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_FULL_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length + + mschapv2_challenge_c::get_header_minimum_size() + + m_ttls_user_name.get_data_length(); + + const u32_t eap_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type) + + type_data_length; + + eap_buf_chain_wr_c eap_packet_buffer( + eap_write_buffer, + m_am_tools, + eap_length); + if (eap_packet_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_header_wr_c forwarded_eap_packet( + m_am_tools, + eap_packet_buffer.get_data(eap_length), + eap_length); + if (forwarded_eap_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + forwarded_eap_packet.set_code(eap_code_request); + forwarded_eap_packet.set_identifier(static_cast(sent_eap_packet->get_identifier()+1ul)); + forwarded_eap_packet.set_length( + static_cast(eap_length), + m_use_eap_expanded_type); + forwarded_eap_packet.set_type( + eap_type_mschapv2, + m_use_eap_expanded_type); + + mschapv2_header_c mschapv2_header( + m_am_tools, + forwarded_eap_packet.get_type_data_offset(0, forwarded_eap_packet.get_type_data_length()), + forwarded_eap_packet.get_type_data_length()); + mschapv2_header.set_opcode(mschapv2_opcode_challenge); + + const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset( + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET, + sizeof(u8_t)); + if (mschapv2ident == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ttls_tunneled_message_state_process_identity_request(): mschapv2ident"), + mschapv2ident, + sizeof(*mschapv2ident))); + + mschapv2_header.set_mschapv2_id(*mschapv2ident); + mschapv2_header.set_ms_length(static_cast(type_data_length)); + + mschapv2_challenge_c challenge_packet( + m_am_tools, + mschapv2_header.get_data(), + mschapv2_header.get_data_length()); + if (challenge_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + const u8_t * const mschapv2_challenge = m_ttls_implicit_challenge.get_data_offset( + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_OFFSET, + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH); + if (mschapv2_challenge == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ttls_tunneled_message_state_process_identity_request(): mschapv2_challenge"), + mschapv2_challenge, + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH)); + + + challenge_packet.set_challenge(mschapv2_challenge); + challenge_packet.set_value_size(); + challenge_packet.set_name(m_ttls_user_name.get_data(m_ttls_user_name.get_data_length())); + + set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_challenge_request); + + status = packet_forward_to_tunnel( + &m_receive_network_id, + &forwarded_eap_packet, + eap_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_challenge_request( + eap_header_wr_c * const sent_eap_packet) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_challenge_request(): ") + EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"), + (m_is_client == true ? "client": "server"), + this, + get_ttls_tunneled_message_state(), + eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()), + convert_eap_type_to_u32_t(sent_eap_packet->get_type()))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_challenge_request()"); + + eap_status_e status(eap_status_process_general_error); + + // This message shoud include MS-CHAP-V2 Response. + + mschapv2_header_c mschapv2_header( + m_am_tools, + sent_eap_packet->get_type_data_offset(0, sent_eap_packet->get_type_data_length()), + sent_eap_packet->get_type_data_length()); + + mschapv2_response_c response( + m_am_tools, + mschapv2_header.get_data(), + mschapv2_header.get_data_length()); + if (response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + eap_variable_data_c tunneled_data(m_am_tools); + eap_variable_data_c avp(m_am_tools); + + { + status = create_ttls_diameter_avp( + &avp, + &m_ttls_user_name, + eap_diameter_avp_code_user_name, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tunneled_data.add_data(&avp); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + { + const u8_t * const mschapv2_challenge = m_ttls_implicit_challenge.get_data_offset( + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_OFFSET, + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH); + if (mschapv2_challenge == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ttls_tunneled_message_state_process_challenge_request(): mschapv2_challenge"), + mschapv2_challenge, + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH)); + + eap_variable_data_c peer_challenge(m_am_tools); + status = peer_challenge.set_buffer( + mschapv2_challenge, + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = create_ttls_diameter_avp( + &avp, + &peer_challenge, + eap_diameter_vendor_code_of_microsoft_ms_chap_challenge.get_code(), + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tunneled_data.add_data(&avp); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + { + eap_variable_data_c response_data(m_am_tools); + + response_data.reset(); + + const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset( + EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET, + EAP_MSCHAPV2_IDENT_SIZE); + if (mschapv2ident == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = response_data.add_data( + mschapv2ident, + EAP_MSCHAPV2_IDENT_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t flags = 0ul; + + status = response_data.add_data( + &flags, + EAP_MSCHAPV2_FLAGS_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = response_data.add_data( + response.get_peer_challenge(), + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t reserved_data[EAP_MSCHAPV2_RESERVED_RESPONSE_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; + + status = response_data.add_data( + reserved_data, + EAP_MSCHAPV2_RESERVED_RESPONSE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = response_data.add_data( + response.get_nt_response(), + EAP_MSCHAPV2_NT_RESPONSE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = create_ttls_diameter_avp( + &avp, + &response_data, + eap_diameter_vendor_code_of_microsoft_ms_chap2_response.get_code(), + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tunneled_data.add_data(&avp); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_buf_chain_wr_c forwarded_packet( + eap_write_buffer, + m_am_tools, + tunneled_data.get_data(), + tunneled_data.get_data_length(), + false, + false, + 0ul); + if (forwarded_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = get_application_partner()->packet_send( + &forwarded_packet, + 0ul, + forwarded_packet.get_data_length(), + forwarded_packet.get_buffer_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_success_request( + eap_header_wr_c * const sent_eap_packet) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_success_request(): ") + EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"), + (m_is_client == true ? "client": "server"), + this, + get_ttls_tunneled_message_state(), + eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()), + convert_eap_type_to_u32_t(sent_eap_packet->get_type()))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_success_request()"); + + // Here should be no data. + + mschapv2_header_c mschapv2_header( + m_am_tools, + sent_eap_packet->get_type_data(sent_eap_packet->get_type_data_length()), + sent_eap_packet->get_type_data_length()); + + if (mschapv2_header.get_opcode() != mschapv2_opcode_success) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + eap_status_e status = m_ttls_sent_eap_packet.set_copy_of_buffer( + sent_eap_packet->get_header_buffer(sent_eap_packet->get_header_buffer_length()), + sent_eap_packet->get_header_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This will be completed after EAP-MSChapv2 returns. This is to reduce stack usage. + set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_complete_success_request); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_complete_success_request( + eap_header_wr_c * const sent_eap_packet) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_complete_success_request(): ") + EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s\n"), + (m_is_client == true ? "client": "server"), + this, + get_ttls_tunneled_message_state(), + eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()) + )); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_complete_success_request()"); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_internal_type, + eap_type_ttls, + eap_state_none, + tls_peap_state_client_send_ttls_plain_ms_chap_v2_empty_ack, + sent_eap_packet->get_identifier(), + false); + get_application_partner()->state_notification(¬ification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_error_request( + eap_header_wr_c * const sent_eap_packet) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_error_request(): ") + EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"), + (m_is_client == true ? "client": "server"), + this, + get_ttls_tunneled_message_state(), + eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()), + convert_eap_type_to_u32_t(sent_eap_packet->get_type()))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_error_request()"); + + eap_status_e status(eap_status_process_general_error); + + // This message shoud include MS-CHAP-V2 Change-Password. + + mschapv2_header_c mschapv2_header( + m_am_tools, + sent_eap_packet->get_type_data(sent_eap_packet->get_type_data_length()), + sent_eap_packet->get_type_data_length()); + + if (mschapv2_header.get_opcode() != mschapv2_opcode_change_password) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + status = m_ttls_sent_eap_packet.set_copy_of_buffer( + sent_eap_packet->get_header_buffer(sent_eap_packet->get_header_buffer_length()), + sent_eap_packet->get_header_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This will be completed after EAP-MSChapv2 returns. This is to reduce stack usage. + set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_complete_error_request); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_complete_error_request( + eap_header_wr_c * const sent_eap_packet) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_error_request(): ") + EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"), + (m_is_client == true ? "client": "server"), + this, + get_ttls_tunneled_message_state(), + eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()), + convert_eap_type_to_u32_t(sent_eap_packet->get_type()))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_complete_error_request()"); + + eap_status_e status(eap_status_process_general_error); + + // This message shoud include MS-CHAP-V2 Change-Password. + + mschapv2_header_c mschapv2_header( + m_am_tools, + sent_eap_packet->get_type_data(sent_eap_packet->get_type_data_length()), + sent_eap_packet->get_type_data_length()); + + if (mschapv2_header.get_opcode() != mschapv2_opcode_change_password) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + mschapv2_change_password_c response( + m_am_tools, + mschapv2_header.get_data(), + mschapv2_header.get_data_length()); + if (response.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // We need to create MS-CHAP-NT-Enc-PW, MS-CHAP2-CPW, and MS-CHAP-Challenge AVPs. + + eap_variable_data_c tunneled_data(m_am_tools); + eap_variable_data_c avp(m_am_tools); + + { + eap_variable_data_c nt_enc_pw(m_am_tools); + status = nt_enc_pw.set_buffer( + response.get_encrypted_pw_block(), + EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_PASSWORD_SIZE, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = create_ttls_diameter_avp( + &avp, + &nt_enc_pw, + eap_diameter_vendor_code_of_microsoft_ms_chap_nt_enc_pw.get_code(), + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tunneled_data.add_data(&avp); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + { + eap_variable_data_c cpw(m_am_tools); + + status = cpw.set_copy_of_buffer( + response.get_encrypted_hash(), + EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_HASH_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = cpw.add_data( + response.get_peer_challenge(), + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = cpw.add_data( + response.get_nt_response(), + EAP_MSCHAPV2_NT_RESPONSE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = create_ttls_diameter_avp( + &avp, + &cpw, + eap_diameter_vendor_code_of_microsoft_ms_chap2_cpw.get_code(), + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tunneled_data.add_data(&avp); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + { + eap_variable_data_c challenge_data(m_am_tools); + status = challenge_data.set_buffer( + response.get_peer_challenge(), + EAP_MSCHAPV2_PEER_CHALLENGE_SIZE, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = create_ttls_diameter_avp( + &avp, + &challenge_data, + eap_diameter_vendor_code_of_microsoft_ms_chap_challenge.get_code(), + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tunneled_data.add_data(&avp); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_buf_chain_wr_c forwarded_packet( + eap_write_buffer, + m_am_tools, + tunneled_data.get_data(), + tunneled_data.get_data_length(), + false, + false, + 0ul); + if (forwarded_packet.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = get_application_partner()->packet_send( + &forwarded_packet, + 0ul, + forwarded_packet.get_data_length(), + forwarded_packet.get_buffer_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::send_ttls_ms_chapv2_packet( + eap_header_wr_c * const sent_eap_packet) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: function: tls_application_eap_core_c::send_ttls_ms_chapv2_packet(): ") + EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"), + (m_is_client == true ? "client": "server"), + this, + get_ttls_tunneled_message_state(), + eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()), + convert_eap_type_to_u32_t(sent_eap_packet->get_type()))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::send_ttls_ms_chapv2_packet()"); + + eap_status_e status(eap_status_process_general_error); + + + if (m_is_client == false) + { + // Server + if (sent_eap_packet->get_code() == eap_code_request + && sent_eap_packet->get_type() == eap_type_mschapv2) + { + if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_identity_response) + { + status = ttls_tunneled_message_state_process_identity_response(sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_response) + { + status = ttls_tunneled_message_state_process_response(sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_change_password_response) + { + status = ttls_tunneled_message_state_process_change_password_response(sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + } + else if (sent_eap_packet->get_code() == eap_code_success) + { + // EAP-Success is not needed in TTLS/MsChapv2. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + } + else + { + // Client + if (sent_eap_packet->get_type() == eap_type_identity) + { + // Client sends EAP-Response/Identity. + if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_identity_request + || get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_identity_request_pending) + { + status = m_ttls_sent_eap_packet.set_copy_of_buffer( + sent_eap_packet->get_header_buffer(sent_eap_packet->get_header_buffer_length()), + sent_eap_packet->get_header_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_identity_request_pending) + { + // NOTE, here we process client send packets separately to + // reduce stack consumption. + + { + eap_header_wr_c tmp_sent_eap_packet( + m_am_tools, + m_ttls_sent_eap_packet.get_data(), + m_ttls_sent_eap_packet.get_data_length()); + + if (tmp_sent_eap_packet.get_type() == eap_type_identity) + { + // Client sent EAP-Response/Identity. + // This message should include username. + + status = ttls_tunneled_message_state_process_identity_request(&tmp_sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + eap_header_wr_c tmp_sent_eap_packet( + m_am_tools, + m_ttls_sent_eap_packet.get_data(), + m_ttls_sent_eap_packet.get_data_length()); + + if (tmp_sent_eap_packet.get_type() == eap_type_mschapv2 + && get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_challenge_request) + { + // This message should include MS-CHAP-V2 Response. + status = ttls_tunneled_message_state_process_challenge_request(&tmp_sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + } + else if (sent_eap_packet->get_type() == eap_type_mschapv2) + { + if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_challenge_request) + { + status = m_ttls_sent_eap_packet.set_copy_of_buffer( + sent_eap_packet->get_header_buffer(sent_eap_packet->get_header_buffer_length()), + sent_eap_packet->get_header_buffer_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_success_request) + { + // NOTE, here we process client send packets separately to + // reduce stack consumption. + status = ttls_tunneled_message_state_process_success_request(sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_error_request) + { + mschapv2_header_c mschapv2_header( + m_am_tools, + sent_eap_packet->get_type_data(sent_eap_packet->get_type_data_length()), + sent_eap_packet->get_type_data_length()); + + if (mschapv2_header.get_opcode() == mschapv2_opcode_change_password) + { + // This message shoud include MS-CHAP-V2 Change-Password. + status = ttls_tunneled_message_state_process_error_request(sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (mschapv2_header.get_opcode() == mschapv2_opcode_response) + { + // This message shoud include MS-CHAP-V2 Response. + + status = ttls_tunneled_message_state_process_challenge_request(sent_eap_packet); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +eap_ttls_tunneled_message_state_e tls_application_eap_core_c::get_ttls_tunneled_message_state() +{ + return m_ttls_tunneled_message_state; +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +void tls_application_eap_core_c::set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_e ttls_state) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TTLS: %s: function: tls_application_eap_core_c::set_ttls_tunneled_message_state(): ") + EAPL("old m_ttls_tunneled_message_state=%d=%s, new m_ttls_tunneled_message_state=%d=%s\n"), + (m_is_client == true ? "client": "server"), + m_ttls_tunneled_message_state, + eap_tls_trace_string_c::get_ttls_state_string(m_ttls_tunneled_message_state), + ttls_state, + eap_tls_trace_string_c::get_ttls_state_string(ttls_state))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::set_ttls_tunneled_message_state()"); + + m_ttls_tunneled_message_state = ttls_state; +} + +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_base_application.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_base_application.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 125 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "tls_base_application.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_base_application_c::~tls_base_application_c() +{ + // Does nothing +} + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_base_record.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_base_record.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 126 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "tls_base_record.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_base_record_c::~tls_base_record_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + // Does nothing. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_base_record_c::tls_base_record_c( + abs_eap_am_tools_c * const tools /*, + abs_tls_base_record_c * const partner */) + : m_type_partner(0) + , m_am_tools(tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + // Does nothing. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_base_record_c::set_type_partner(abs_tls_base_record_c * const partner) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_type_partner = partner; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT abs_tls_base_record_c * tls_base_record_c::get_type_partner() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_type_partner; +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_change_cipher_spec_message.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_change_cipher_spec_message.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,212 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 127 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_tools.h" +#include "eap_array.h" +#include "eap_array_algorithms.h" +#include "tls_change_cipher_spec_message.h" +#include "tls_record_header.h" +#include "tls_peap_types.h" + + +/** @file */ + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_change_cipher_spec_message_c::~tls_change_cipher_spec_message_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_change_cipher_spec_message_c::tls_change_cipher_spec_message_c( + abs_eap_am_tools_c * const tools, + abs_tls_change_cipher_spec_c * const change_cipher_spec, + const bool is_client) +: m_am_tools(tools) +, m_change_cipher_spec(change_cipher_spec) +, m_tls_change_cipher_spec_message_buffer(tools) +, m_type(tls_change_cipher_spec_type_none) +, m_is_client(is_client) +, m_is_valid(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_change_cipher_spec_message_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_change_cipher_spec_message_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_change_cipher_spec_message_c::set_change_cipher_spec_type( + const tls_change_cipher_spec_type_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_type = type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_change_cipher_spec_type_e tls_change_cipher_spec_message_c::get_change_cipher_spec_type() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_change_cipher_spec_message_c::create_message_data() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: data_function: tls_change_cipher_spec_message_c::create_message_data(): tls_change_cipher_spec_type_change_cipher_spec\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eap_status_not_supported; + + m_tls_change_cipher_spec_message_buffer.reset(); + status = m_tls_change_cipher_spec_message_buffer.set_buffer_length(TLS_PEAP_DEFAULT_RECORD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t change_cipher_spec_data_length_start = m_tls_change_cipher_spec_message_buffer.get_data_length(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + u8_t type = static_cast(m_type); + + status = m_tls_change_cipher_spec_message_buffer.add_data( + &type, + sizeof(type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-change_cipher_spec type"), + &type, + sizeof(type))); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (status == eap_status_ok) + { + u32_t change_cipher_spec_data_length + = m_tls_change_cipher_spec_message_buffer.get_data_length() + - change_cipher_spec_data_length_start; + + EAP_UNREFERENCED_PARAMETER(change_cipher_spec_data_length); // in release + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("change_cipher_spec length %d bytes.\n"), + change_cipher_spec_data_length)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_change_cipher_spec_message_c::add_message_data( + eap_variable_data_c * const tls_message_buffer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: data_function: tls_change_cipher_spec_message_c::add_message_data(): tls_change_cipher_spec_type_change_cipher_spec\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eap_status_not_supported; + + if (m_tls_change_cipher_spec_message_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = tls_message_buffer->add_data( + m_tls_change_cipher_spec_message_buffer.get_data(m_tls_change_cipher_spec_message_buffer.get_data_length()), + m_tls_change_cipher_spec_message_buffer.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_completion.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_completion.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,144 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 128 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_tools.h" +#include "eap_array.h" +#include "tls_completion.h" +#include "tls_peap_types.h" + +/** @file */ + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_completion_c::~tls_completion_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_completion_c::tls_completion_c( + abs_eap_am_tools_c * const tools, + tls_completion_action_e completion_action) +: m_am_tools(tools) +, m_completion_action(completion_action) +, m_is_valid(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_completion_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_completion_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_completion_c::set_completion_action(tls_completion_action_e completion_action) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_completion_action = completion_action; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_completion_action_e tls_completion_c::get_completion_action() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_completion_action; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string tls_completion_c::get_completion_action_string() const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_none) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_handshake_type_hello_request) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_handshake_type_client_hello) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_handshake_type_server_hello) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_handshake_type_certificate) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_handshake_type_server_key_exchange) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_handshake_type_certificate_request) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_handshake_type_server_hello_done) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_handshake_type_certificate_verify) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_handshake_type_client_key_exchange) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_handshake_type_finished) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_finish_handshake) +#if defined(USE_EAP_TLS_SESSION_TICKET) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_handshake_type_new_session_ticket) +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_create_change_cipher_spec_type_change_cipher_spec) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_query_dh_parameters) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_verify_certificate_chain) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_process_tls_records) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_check_sent_tls_message) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_complete_create_handshake_type_server_key_exchange) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_complete_create_handshake_type_certificate_verify) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_complete_create_handshake_type_client_key_exchange) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_query_cipher_suites_and_previous_session) + else EAP_IF_RETURN_STRING(m_completion_action, tls_completion_action_check_tunnel_authentication_runs) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown completion_action"); + } +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_extension.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_extension.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,249 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +#include "tls_extension.h" + +/** @file */ + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void tls_extension_c::set_is_valid() +{ + m_is_valid = true; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT tls_extension_c::~tls_extension_c() +{ +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT tls_extension_c::tls_extension_c( + abs_eap_am_tools_c * const tools) + : eap_variable_data_c(tools) + , m_am_tools(tools) + , m_lifetime_hint(0ul) + , m_type(tls_extension_type_none) +#if defined(USE_FAST_EAP_TYPE) + , m_pac_type(eap_fast_pac_type_none) +#endif //#if defined(USE_FAST_EAP_TYPE) + , m_is_valid(false) +{ + if (eap_variable_data_c::get_is_valid() == false) + { + return; + } + + set_is_valid(); +} + +//---------------------------------------------------------------------------- + +tls_extension_c * tls_extension_c::copy() const +{ + tls_extension_c * const copy_object = new tls_extension_c(m_am_tools); + + if (copy_object == 0 + || copy_object->get_is_valid() == false) + { + delete copy_object; + return 0; + } + + copy_object->set_type(get_type()); + +#if defined(USE_FAST_EAP_TYPE) + copy_object->set_pac_type(get_pac_type()); +#endif //#if defined(USE_FAST_EAP_TYPE) + + eap_status_e status = copy_object->set_copy_of_buffer(this); + + if (status != eap_status_ok) + { + delete copy_object; + return 0; + } + + return copy_object; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_extension_c::get_is_valid() +{ + return m_is_valid; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void tls_extension_c::set_lifetime_hint(const u32_t lifetime_hint) +{ + m_lifetime_hint = lifetime_hint; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT u32_t tls_extension_c::get_lifetime_hint() const +{ + return m_lifetime_hint; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT void tls_extension_c::set_type(const tls_extension_type_e type) +{ + m_type = type; +} + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT tls_extension_type_e tls_extension_c::get_type() const +{ + return m_type; +} + +//---------------------------------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + +EAP_FUNC_EXPORT void tls_extension_c::set_pac_type(const eap_fast_pac_type_e pac_type) +{ + m_pac_type = pac_type; +} + +#endif //#if defined(USE_FAST_EAP_TYPE) + +//---------------------------------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + +EAP_FUNC_EXPORT eap_fast_pac_type_e tls_extension_c::get_pac_type() const +{ + return m_pac_type; +} + +#endif //#if defined(USE_FAST_EAP_TYPE) + +//---------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_const_string tls_extension_c::get_type_string(tls_extension_type_e type) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(type, tls_extension_type_none) + else EAP_IF_RETURN_STRING(type, tls_extension_type_server_name) + else EAP_IF_RETURN_STRING(type, tls_extension_type_max_frame_length) + else EAP_IF_RETURN_STRING(type, tls_extension_type_client_certificate_url) + else EAP_IF_RETURN_STRING(type, tls_extension_type_trusted_ca_keys) + else EAP_IF_RETURN_STRING(type, tls_extension_type_truncated_hmac) + else EAP_IF_RETURN_STRING(type, tls_extension_type_status_request) + else EAP_IF_RETURN_STRING(type, tls_extension_type_session_ticket) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + EAP_UNREFERENCED_PARAMETER(type); + return EAPL("Unknown TLS extension type"); + } +} + +//---------------------------------------------------------------------------- + +const tls_extension_c * tls_extension_c::get_tls_extension( + const tls_extension_type_e tls_extension_type, + EAP_TEMPLATE_CONST eap_array_c * const tls_extensions, + abs_eap_am_tools_c * const am_tools) +{ + if (tls_extensions == 0) + { + EAP_UNREFERENCED_PARAMETER(am_tools); + (void) EAP_STATUS_RETURN(am_tools, eap_status_not_found); + return 0; + } + + for (u32_t ind = 0ul; ind < tls_extensions->get_object_count(); ++ind) + { + const tls_extension_c * extension = tls_extensions->get_object(ind); + + if (extension == 0) + { + (void) EAP_STATUS_RETURN(am_tools, eap_status_not_found); + return 0; + } + + if (extension->get_type() == tls_extension_type) + { + return extension; + } + } // for() + + (void) EAP_STATUS_RETURN(am_tools, eap_status_not_found); + return 0; +} + +//---------------------------------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + +const tls_extension_c * tls_extension_c::get_tls_extension( + const tls_extension_type_e tls_extension_type, + const eap_fast_pac_type_e pac_type, + EAP_TEMPLATE_CONST eap_array_c * const tls_extensions, + abs_eap_am_tools_c * const am_tools) +{ + if (tls_extensions == 0) + { + EAP_UNREFERENCED_PARAMETER(am_tools); + (void) EAP_STATUS_RETURN(am_tools, eap_status_not_found); + return 0; + } + + for (u32_t ind = 0ul; ind < tls_extensions->get_object_count(); ++ind) + { + const tls_extension_c * extension = tls_extensions->get_object(ind); + + if (extension == 0) + { + (void) EAP_STATUS_RETURN(am_tools, eap_status_not_found); + return 0; + } + + if (extension->get_type() == tls_extension_type) + { + if (pac_type == eap_fast_pac_type_none + || pac_type == extension->get_pac_type()) + { + return extension; + } + } + } // for() + + (void) EAP_STATUS_RETURN(am_tools, eap_status_not_found); + return 0; +} + +#endif //#if defined(USE_FAST_EAP_TYPE) + +//---------------------------------------------------------------------------- + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_handshake_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_handshake_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,283 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 129 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "tls_handshake_header.h" + + +/** @file */ + + +/** + * Destructor does nothing. + */ +tls_handshake_header_c::~tls_handshake_header_c() +{ +} + +/** + * Constructor initializes class. + */ +tls_handshake_header_c::tls_handshake_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +/** + * This function returns TLS-handshake type. + */ +tls_handshake_type_e tls_handshake_header_c::get_handshake_type() const +{ + const u8_t * const type_data = get_header_offset(m_type_offset, sizeof(u8_t)); + if (type_data != 0) + { + return static_cast(*type_data); + } + else + { + return tls_handshake_type_none; + } +} + +/** + * This function returns data length of TLS-handshake message. + * Length is measured in bytes and it does not include m_handshake_type, m_length_high, + * m_length_middle and m_length_low fields, only the length of the following handshake message. + */ +u32_t tls_handshake_header_c::get_data_length() const +{ + // Note the lenght is 24-bit value. + const u8_t * const length_data = get_header_offset(m_length_offset, 3ul*sizeof(u8_t)); + if (length_data != 0) + { + return eap_read_u24_t_network_order(length_data, 3ul*sizeof(u8_t)); + } + else + { + return 0ul; + } +} + +/** + * This function returns maximum data length of TLS-handshake message. + */ +u32_t tls_handshake_header_c::get_max_data_length() +{ + return m_max_data_length; +} + +/** + * This function returns header length of TLS-handshake message. + */ +u32_t tls_handshake_header_c::get_header_length() +{ + return m_data_offset; +} + +/** + * This function returns pointer to the offset of data of TLS-handshake message. + */ +u8_t * tls_handshake_header_c::get_data_offset( + const u32_t offset, + const u32_t contignuous_bytes) const +{ + u32_t data_length = get_data_length(); // Here is included TLS handshake message length. + + if (data_length >= offset+contignuous_bytes + && contignuous_bytes > 0u) + { + u8_t * const data = get_header_offset(m_data_offset, offset); + if (data != 0) + { + return &data[offset]; + } + else + { + return 0; + } + } + else + { + return 0; + } +} + +/** + * This function returns pointer to data of TLS-handshake message. + */ +u8_t * tls_handshake_header_c::get_data(const u32_t contignuous_bytes) const +{ + return get_data_offset(0u, contignuous_bytes); +} + + +/** + * This function returns debug string of TLS-handshake type. + */ +eap_const_string tls_handshake_header_c::get_tls_handshake_string( + const tls_handshake_type_e type) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(type, tls_handshake_type_hello_request) + else EAP_IF_RETURN_STRING(type, tls_handshake_type_client_hello) + else EAP_IF_RETURN_STRING(type, tls_handshake_type_server_hello) + else EAP_IF_RETURN_STRING(type, tls_handshake_type_certificate) + else EAP_IF_RETURN_STRING(type, tls_handshake_type_server_key_exchange) + else EAP_IF_RETURN_STRING(type, tls_handshake_type_certificate_request) + else EAP_IF_RETURN_STRING(type, tls_handshake_type_server_hello_done) + else EAP_IF_RETURN_STRING(type, tls_handshake_type_certificate_verify) + else EAP_IF_RETURN_STRING(type, tls_handshake_type_client_key_exchange) + else EAP_IF_RETURN_STRING(type, tls_handshake_type_finished) +#if defined(USE_EAP_TLS_SESSION_TICKET) + else EAP_IF_RETURN_STRING(type, tls_handshake_type_new_session_ticket) +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + else EAP_IF_RETURN_STRING(type, tls_handshake_type_none) + else +#else +EAP_UNREFERENCED_PARAMETER(type); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown TLS handshake type"); + } +} + +/** + * This function returns debug string of TLS-handshake type. + */ +eap_const_string tls_handshake_header_c::get_tls_handshake_string() const +{ + const tls_handshake_type_e type = get_handshake_type(); + + return get_tls_handshake_string(type); +} + +/** + * This function sets the TLS-handshake type. + */ +void tls_handshake_header_c::set_handshake_type(tls_handshake_type_e handshake_type) +{ + u8_t * const type_data = get_header_offset(m_type_offset, sizeof(u8_t)); + + EAP_ASSERT(type_data != 0); + + *type_data = static_cast(handshake_type); +} + +/** + * This function sets the length of data of the TLS-handshake type. + */ +void tls_handshake_header_c::set_data_length(const u32_t p_length) +{ + u8_t * const length_data = get_header_offset(m_length_offset, 3ul*sizeof(u8_t)); + + EAP_ASSERT(length_data != 0); + + length_data[0] = static_cast((p_length & 0x00ff0000) >> 16); + length_data[1] = static_cast((p_length & 0x0000ff00) >> 8); + length_data[2] = static_cast((p_length & 0x000000ff) >> 0); +} + +/** + * This function resets the header of the TLS-handshake type. + */ +void tls_handshake_header_c::reset_header( + const u32_t data_length) +{ + set_handshake_type(tls_handshake_type_none); + set_data_length(data_length); +} + +/** + * This function checks header of TLS-handshake message. + */ +eap_status_e tls_handshake_header_c::check_header() const +{ + if (get_handshake_type() != tls_handshake_type_hello_request + && get_handshake_type() != tls_handshake_type_client_hello + && get_handshake_type() != tls_handshake_type_server_hello + && get_handshake_type() != tls_handshake_type_certificate + && get_handshake_type() != tls_handshake_type_server_key_exchange + && get_handshake_type() != tls_handshake_type_certificate_request + && get_handshake_type() != tls_handshake_type_server_hello_done + && get_handshake_type() != tls_handshake_type_certificate_verify + && get_handshake_type() != tls_handshake_type_client_key_exchange + && get_handshake_type() != tls_handshake_type_finished +#if defined(USE_EAP_TLS_SESSION_TICKET) + && get_handshake_type() != tls_handshake_type_new_session_ticket +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + ) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +/** + * This function checks header of TLS-handshake message + * is required type. + */ +eap_status_e tls_handshake_header_c::check_header( + const tls_handshake_type_e required_type, + const bool /*is_client_when_true*/) const +{ + switch(get_handshake_type()) + { + case tls_handshake_type_hello_request: + case tls_handshake_type_client_hello: + case tls_handshake_type_server_hello: + case tls_handshake_type_certificate: + case tls_handshake_type_server_key_exchange: + case tls_handshake_type_certificate_request: + case tls_handshake_type_server_hello_done: + case tls_handshake_type_certificate_verify: + case tls_handshake_type_client_key_exchange: + case tls_handshake_type_finished: +#if defined(USE_EAP_TLS_SESSION_TICKET) + case tls_handshake_type_new_session_ticket: +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + if (get_handshake_type() == required_type) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + default: + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } +} + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_handshake_message.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_handshake_message.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1611 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 130 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_tools.h" +#include "eap_array.h" +#include "eap_array_algorithms.h" +#include "tls_handshake_message.h" +#include "tls_record_header.h" +#include "eap_crypto_api.h" +#include "eap_automatic_variable.h" + +/** @file */ + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_handshake_message_c::~tls_handshake_message_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_handshake_message_c::tls_handshake_message_c( + abs_eap_am_tools_c * const tools, + abs_tls_message_hash_c * const message_hash, + const bool is_client) +: m_am_tools(tools) +, m_message_hash(message_hash) +, m_tls_handshake_message_buffer(tools) +, m_unix_time(tools) +, m_random_value(tools) +, m_session_id(tools) +, m_cipher_suites(tools) +, m_compression_methods(tools) +#if defined(USE_EAP_TLS_SESSION_TICKET) +, m_tls_extensions(tools) +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) +, m_certificate_chain(tools) +, m_certificate_authorities(tools) +, m_certificate_types(tools) +, m_encrypted_premaster_secret(tools) +, m_public_dhe_key(tools) +, m_dhe_prime(tools) +, m_dhe_group_generator(tools) +, m_signed_message_hash(tools) +, m_finished_data(tools) +, m_selected_cipher_suite(tls_cipher_suites_none) +, m_selected_compression_method(tls_compression_method_none) +, m_handshake_type(tls_handshake_type_none) +, m_is_analysed(false) +, m_is_valid(false) +, m_is_client(is_client) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_handshake_message_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_handshake_message_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_handshake_message_c::set_is_analysed() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_analysed = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_handshake_message_c::get_is_analysed() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_analysed; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_handshake_type(tls_handshake_type_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_handshake_type = type; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_handshake_header_copy( + const tls_handshake_header_c * const tls_handshake_header) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_handshake_type = tls_handshake_header->get_handshake_type(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_handshake_type_e tls_handshake_message_c::get_handshake_type() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_handshake_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_cipher_suites( + EAP_TEMPLATE_CONST eap_array_c * const cipher_suites) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_cipher_suites.reset(); + + eap_status_e status = copy_simple( + cipher_suites, + &m_cipher_suites, + m_am_tools, + false); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c * tls_handshake_message_c::get_cipher_suites() EAP_TEMPLATE_CONST +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_cipher_suites; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_compression_methods( + EAP_TEMPLATE_CONST eap_array_c * const compression_methods) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = copy_simple( + compression_methods, + &m_compression_methods, + m_am_tools, + false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c * tls_handshake_message_c::get_compression_methods() EAP_TEMPLATE_CONST +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_compression_methods; +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_tls_extensions( + EAP_TEMPLATE_CONST eap_array_c * const tls_extensionss) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = copy( + tls_extensionss, + &m_tls_extensions, + m_am_tools, + false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +//-------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c * tls_handshake_message_c::get_tls_extensions() EAP_TEMPLATE_CONST +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_tls_extensions; +} + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_random_value( + const eap_variable_data_c * const random_value) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_random_value.set_copy_of_buffer(random_value); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_random_value() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_random_value; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_session_id( + const eap_variable_data_c * const session_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_session_id.set_copy_of_buffer(session_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_session_id() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_session_id; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_certificate_chain( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = copy( + certificate_chain, + &m_certificate_chain, + m_am_tools, + false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c * tls_handshake_message_c::get_certificate_chain() EAP_TEMPLATE_CONST +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_certificate_chain; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_certificate_authorities( + EAP_TEMPLATE_CONST eap_array_c * const certificate_authorities) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = copy( + certificate_authorities, + &m_certificate_authorities, + m_am_tools, + false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c * tls_handshake_message_c::get_certificate_authorities() EAP_TEMPLATE_CONST +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_certificate_authorities; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_certificate_types( + EAP_TEMPLATE_CONST eap_array_c * const certificate_types) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = copy_simple( + certificate_types, + &m_certificate_types, + m_am_tools, + false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c * tls_handshake_message_c::get_certificate_types() EAP_TEMPLATE_CONST +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_certificate_types; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_selected_cipher_suite(const tls_cipher_suites_e selected_cipher_suite) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_selected_cipher_suite = selected_cipher_suite; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +EAP_FUNC_EXPORT tls_cipher_suites_e tls_handshake_message_c::get_selected_cipher_suite() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_selected_cipher_suite; +} + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_selected_compression_method(const tls_compression_method_e selected_compression_method) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_selected_compression_method = selected_compression_method; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +EAP_FUNC_EXPORT tls_compression_method_e tls_handshake_message_c::get_selected_compression_method() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_selected_compression_method; +} + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_public_dhe_key(const eap_variable_data_c * const public_dhe_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_public_dhe_key.set_copy_of_buffer(public_dhe_key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_public_dhe_key() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_public_dhe_key; +} + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_encrypted_premaster_secret(const eap_variable_data_c * const encrypted_premaster_secret) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_encrypted_premaster_secret.set_copy_of_buffer(encrypted_premaster_secret); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_encrypted_premaster_secret() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_encrypted_premaster_secret; +} + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_dhe_prime(const eap_variable_data_c * const dhe_prime) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_dhe_prime.set_copy_of_buffer(dhe_prime); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_dhe_prime() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_dhe_prime; +} + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_dhe_group_generator(const eap_variable_data_c * const dhe_group_generator) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_dhe_group_generator.set_copy_of_buffer(dhe_group_generator); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_dhe_group_generator() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_dhe_group_generator; +} + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_signed_message_hash(const eap_variable_data_c * const signed_message_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_signed_message_hash.set_copy_of_buffer(signed_message_hash); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_signed_message_hash() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_signed_message_hash; +} + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_finished_data(const eap_variable_data_c * const finished_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_finished_data.set_copy_of_buffer(finished_data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_finished_data() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_finished_data; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::u16_t_to_network_order( + u16_t * const value, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + *value = eap_htons(*value); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::create_message_data() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; + + m_tls_handshake_message_buffer.reset(); + status = m_tls_handshake_message_buffer.set_buffer_length(TLS_PEAP_DEFAULT_RECORD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const u32_t offset_of_tmp_tls_handshake_header = m_tls_handshake_message_buffer.get_data_length(); + + m_tls_handshake_message_buffer.set_data_length( + m_tls_handshake_message_buffer.get_data_length() + tls_handshake_header_c::get_header_length()); + + tls_handshake_header_c tmp_tls_handshake_header_on_tls_message_buffer( + m_am_tools, + m_tls_handshake_message_buffer.get_data_offset( + offset_of_tmp_tls_handshake_header, tls_handshake_header_c::get_header_length()), + tls_handshake_header_c::get_header_length()); + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + tmp_tls_handshake_header_on_tls_message_buffer.reset_header(0ul); + tmp_tls_handshake_header_on_tls_message_buffer.set_handshake_type(get_handshake_type()); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: data_function: tls_handshake_message_c::create_message_data(): %s\n"), + (m_is_client == true ? "client": "server"), + tmp_tls_handshake_header_on_tls_message_buffer.get_tls_handshake_string())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS-handshake tls_handshake_header"), + tmp_tls_handshake_header_on_tls_message_buffer.get_header_buffer( + tls_handshake_header_c::get_header_length()), + tls_handshake_header_c::get_header_length())); + + const u32_t handshake_data_length_start = m_tls_handshake_message_buffer.get_data_length(); + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello + || tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello) + { + u16_t version = eap_htons(tls_version_3_1); + + status = m_tls_handshake_message_buffer.add_data( + &version, + sizeof(version)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake version"), + &version, + sizeof(version))); + } + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello + || tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello) + { + if (m_random_value.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else + { + status = m_tls_handshake_message_buffer.add_data( + m_random_value.get_data(m_random_value.get_data_length()), + m_random_value.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake random"), + m_random_value.get_data(m_random_value.get_data_length()), + m_random_value.get_data_length())); + } + } + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello + || tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello) + { + u8_t session_id_length = 0ul; + + if (m_session_id.get_is_valid_data() == true + && m_session_id.get_data_length() > 0ul) + { + session_id_length = static_cast(m_session_id.get_data_length()); + } + + status = m_tls_handshake_message_buffer.add_data( + &session_id_length, + sizeof(session_id_length)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake session_id_length"), + &session_id_length, + sizeof(session_id_length))); + + if (m_session_id.get_is_valid_data() == true + && m_session_id.get_data_length() > 0ul) + { + status = m_tls_handshake_message_buffer.add_data( + m_session_id.get_data(m_session_id.get_data_length()), + m_session_id.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake session_id"), + m_session_id.get_data(m_session_id.get_data_length()), + m_session_id.get_data_length())); + } + } + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello) + { + u16_t data_size = static_cast(m_cipher_suites.get_object_count() * sizeof(u16_t)); + u16_t data_size_network_order = eap_htons(data_size); + + status = m_tls_handshake_message_buffer.add_data( + &data_size_network_order, + sizeof(data_size_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake cipher_suite_length"), + &data_size_network_order, + sizeof(data_size_network_order))); + + if (m_cipher_suites.get_object_count() > 0ul) + { + // Copy cipher suites and change them to network order. + eap_array_c * const tmp_cipher_suites = new eap_array_c(m_am_tools); + + eap_automatic_variable_c > automatic_tmp_cipher_suites(m_am_tools, tmp_cipher_suites); + + if (tmp_cipher_suites == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = copy_simple( + &m_cipher_suites, + tmp_cipher_suites, + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = for_each(tmp_cipher_suites, u16_t_to_network_order, m_am_tools, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = add_simple_data(tmp_cipher_suites, &m_tls_handshake_message_buffer, m_am_tools); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello) + { + u16_t selected_cipher_suite_network_order = eap_htons(static_cast(m_selected_cipher_suite)); + + status = m_tls_handshake_message_buffer.add_data( + &selected_cipher_suite_network_order, + sizeof(selected_cipher_suite_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake selected_cipher_suite"), + &selected_cipher_suite_network_order, + sizeof(selected_cipher_suite_network_order))); + + u8_t selected_compression_method_network_order = static_cast(m_selected_compression_method); + + status = m_tls_handshake_message_buffer.add_data( + &selected_compression_method_network_order, + sizeof(selected_compression_method_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake selected_compression_method"), + &selected_compression_method_network_order, + sizeof(selected_compression_method_network_order))); + } + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello) + { + u8_t data_size = static_cast(m_compression_methods.get_object_count() * sizeof(u8_t)); + + status = m_tls_handshake_message_buffer.add_data( + &data_size, + sizeof(data_size)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS-handshake compression_methods length"), + &data_size, + sizeof(data_size))); + + if (m_compression_methods.get_object_count() > 0ul) + { + status = add_simple_data(&m_compression_methods, &m_tls_handshake_message_buffer, m_am_tools); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + +#if defined(USE_EAP_TLS_SESSION_TICKET) + + if (m_tls_extensions.get_object_count() > 0 + && (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello + || tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello)) + { + u32_t data_size(0ul); + u32_t ind(0ul); + + for (ind = 0ul; ind < m_tls_extensions.get_object_count(); ++ind) + { + const tls_extension_c * const extension = m_tls_extensions.get_object(ind); + if (extension == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // Session ticket is always empty in ServerHello message. + const bool add_extension_data = + ((extension->get_type() == tls_extension_type_session_ticket + && tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello)) + == false; + + // Extension list is formatted as: + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | extension list length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | extension 1 type | extension 1 data length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | extension 1 data ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | extension 2 type | extension 2 data length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | extension 2 data ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + data_size += 2 * sizeof(u16_t); + + if (add_extension_data == true) + { + data_size += extension->get_data_length(); + } + + } // for() + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS-handshake extensions list length = %d\n"), + data_size)); + + if (data_size > 0x0000ffff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u8_t data_size_array[2]; + data_size_array[0] = static_cast((data_size & 0x0000ff00) >> 8); + data_size_array[1] = static_cast(data_size & 0x000000ff); + + status = m_tls_handshake_message_buffer.add_data( + &data_size_array, + sizeof(data_size_array)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (ind = 0ul; ind < m_tls_extensions.get_object_count(); ++ind) + { + const tls_extension_c * const extension = m_tls_extensions.get_object(ind); + if (extension == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // Session ticket is always empty in ServerHello message. + const bool add_extension_data = + ((extension->get_type() == tls_extension_type_session_ticket + && tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello)) + == false; + + tls_extension_type_e type = extension->get_type(); + u16_t network_order_type(eap_htons(type)); + + status = m_tls_handshake_message_buffer.add_data( + &network_order_type, + sizeof(network_order_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (add_extension_data == true) + { + data_size = extension->get_data_length(); + } + else + { + data_size = 0ul; + } + + data_size_array[0] = static_cast((data_size & 0x0000ff00) >> 8); + data_size_array[1] = static_cast(data_size & 0x000000ff); + + status = m_tls_handshake_message_buffer.add_data( + &data_size_array, + sizeof(data_size_array)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS-handshake extension type = %s, length = %d\n"), + extension->get_type_string(extension->get_type()), + data_size)); + + if (add_extension_data == true) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS-handshake extension data"), + extension->get_data(), + extension->get_data_length())); + + status = m_tls_handshake_message_buffer.add_data( + extension); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } // for() + } + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_certificate) + { + u32_t data_size = 0ul; + u32_t ind = 0ul; + + for (ind = 0ul; ind < m_certificate_chain.get_object_count(); ind++) + { + const eap_variable_data_c * const certificate = m_certificate_chain.get_object(ind); + if (certificate == 0 + || certificate->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // Data size includes certificate length field and certificate data. + data_size += (3ul + certificate->get_data_length()); + } + + if (data_size > 0x00ffffff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u8_t data_size_array[3]; + data_size_array[0] = static_cast((data_size & 0x00ff0000) >> 16); + data_size_array[1] = static_cast((data_size & 0x0000ff00) >> 8); + data_size_array[2] = static_cast(data_size & 0x000000ff); + + status = m_tls_handshake_message_buffer.add_data( + data_size_array, + sizeof(data_size_array)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate_chain length"), + data_size_array, + sizeof(data_size_array))); + + + for (ind = 0ul; ind < m_certificate_chain.get_object_count(); ind++) + { + const eap_variable_data_c * const certificate = m_certificate_chain.get_object(ind); + if (certificate == 0 + || certificate->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + data_size = certificate->get_data_length(); + u8_t data_size_array[3]; + data_size_array[0] = static_cast((data_size & 0x00ff0000) >> 16); + data_size_array[1] = static_cast((data_size & 0x0000ff00) >> 8); + data_size_array[2] = static_cast(data_size & 0x000000ff); + + status = m_tls_handshake_message_buffer.add_data( + data_size_array, + sizeof(data_size_array)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate length"), + data_size_array, + sizeof(data_size_array))); + + status = m_tls_handshake_message_buffer.add_data( + certificate->get_data(certificate->get_data_length()), + certificate->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate"), + certificate->get_data(certificate->get_data_length()), + certificate->get_data_length())); + } + } + + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_key_exchange) + { + if (m_dhe_prime.get_is_valid_data() == true) + { + u16_t dhe_prime_length_network_order = eap_htons(static_cast(m_dhe_prime.get_data_length())); + + status = m_tls_handshake_message_buffer.add_data( + &dhe_prime_length_network_order, + sizeof(dhe_prime_length_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake dhe_prime_length"), + &dhe_prime_length_network_order, + sizeof(dhe_prime_length_network_order))); + + status = m_tls_handshake_message_buffer.add_data( + m_dhe_prime.get_data(m_dhe_prime.get_data_length()), + m_dhe_prime.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake dhe_prime"), + m_dhe_prime.get_data(m_dhe_prime.get_data_length()), + m_dhe_prime.get_data_length())); + } + else if (m_dhe_group_generator.get_is_valid_data() == true + || m_public_dhe_key.get_is_valid_data() == true + || m_signed_message_hash.get_is_valid_data() == true) + { + // all parameters m_dhe_prime, m_dhe_group_generator and m_public_dhe_key are needed. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_dhe_group_generator.get_is_valid_data() == true) + { + u16_t dhe_group_generator_length_network_order = eap_htons(static_cast(m_dhe_group_generator.get_data_length())); + + status = m_tls_handshake_message_buffer.add_data( + &dhe_group_generator_length_network_order, + sizeof(dhe_group_generator_length_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake dhe_group_generator_length"), + &dhe_group_generator_length_network_order, + sizeof(dhe_group_generator_length_network_order))); + + status = m_tls_handshake_message_buffer.add_data( + m_dhe_group_generator.get_data(m_dhe_group_generator.get_data_length()), + m_dhe_group_generator.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake dhe_group_generator"), + m_dhe_group_generator.get_data(m_dhe_group_generator.get_data_length()), + m_dhe_group_generator.get_data_length())); + } + else if (m_dhe_prime.get_is_valid_data() == true + || m_public_dhe_key.get_is_valid_data() == true + || m_signed_message_hash.get_is_valid_data() == true) + { + // all parameters m_dhe_prime, m_dhe_group_generator and m_public_dhe_key are needed. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_public_dhe_key.get_is_valid_data() == true) + { + u16_t public_dhe_key_length_network_order = eap_htons(static_cast(m_public_dhe_key.get_data_length())); + + status = m_tls_handshake_message_buffer.add_data( + &public_dhe_key_length_network_order, + sizeof(public_dhe_key_length_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake public_dhe_key_length"), + &public_dhe_key_length_network_order, + sizeof(public_dhe_key_length_network_order))); + + status = m_tls_handshake_message_buffer.add_data( + m_public_dhe_key.get_data(m_public_dhe_key.get_data_length()), + m_public_dhe_key.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake public_dhe_key"), + m_public_dhe_key.get_data(m_public_dhe_key.get_data_length()), + m_public_dhe_key.get_data_length())); + } + else if (m_dhe_prime.get_is_valid_data() == true + || m_dhe_group_generator.get_is_valid_data() == true + || m_signed_message_hash.get_is_valid_data() == true) + { + // all parameters m_dhe_prime, m_dhe_group_generator and m_public_dhe_key are needed. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_signed_message_hash.get_is_valid_data() == true) + { + if (m_signed_message_hash.get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = m_tls_handshake_message_buffer.add_data( + m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()), + m_signed_message_hash.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake signed_message_hash"), + m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()), + m_signed_message_hash.get_data_length())); + } + } + + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_key_exchange) + { + if (m_encrypted_premaster_secret.get_is_valid_data() == true) + { + u16_t length_of_encrypted_premaster_secret_network_order + = eap_htons(static_cast(m_encrypted_premaster_secret.get_data_length())); + + status = m_tls_handshake_message_buffer.add_data( + &length_of_encrypted_premaster_secret_network_order, + sizeof(length_of_encrypted_premaster_secret_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake encrypted premaster_secret"), + &length_of_encrypted_premaster_secret_network_order, + sizeof(length_of_encrypted_premaster_secret_network_order))); + + status = m_tls_handshake_message_buffer.add_data( + m_encrypted_premaster_secret.get_data(m_encrypted_premaster_secret.get_data_length()), + m_encrypted_premaster_secret.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake encrypted premaster_secret"), + m_encrypted_premaster_secret.get_data(m_encrypted_premaster_secret.get_data_length()), + m_encrypted_premaster_secret.get_data_length())); + } + else if (m_encrypted_premaster_secret.get_is_valid_data() == false + && m_public_dhe_key.get_is_valid_data() == false) + { + // Either parameters m_encrypted_premaster_secret or m_public_dhe_key is needed. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (m_public_dhe_key.get_is_valid_data() == true) + { + u16_t length_of_public_dhe_key_length_network_order = eap_htons(static_cast(m_public_dhe_key.get_data_length())); + + status = m_tls_handshake_message_buffer.add_data( + &length_of_public_dhe_key_length_network_order, + sizeof(length_of_public_dhe_key_length_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake public_dhe_key_length"), + &length_of_public_dhe_key_length_network_order, + sizeof(length_of_public_dhe_key_length_network_order))); + + status = m_tls_handshake_message_buffer.add_data( + m_public_dhe_key.get_data(m_public_dhe_key.get_data_length()), + m_public_dhe_key.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake public_dhe_key"), + m_public_dhe_key.get_data(m_public_dhe_key.get_data_length()), + m_public_dhe_key.get_data_length())); + } + else if (m_encrypted_premaster_secret.get_is_valid_data() == false + && m_public_dhe_key.get_is_valid_data() == false) + { + // Either parameters m_encrypted_premaster_secret or m_public_dhe_key is needed. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_certificate_request) + { + u32_t data_size = m_certificate_types.get_object_count() * sizeof(u8_t); + + if (data_size > 0x000000ff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u8_t data_size_u8_t = static_cast(data_size & 0x000000ff); + + status = m_tls_handshake_message_buffer.add_data( + &data_size_u8_t, + sizeof(data_size_u8_t)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate_types length"), + &data_size_u8_t, + sizeof(data_size_u8_t))); + + if (data_size_u8_t > 0ul) + { + status = add_simple_data(&m_certificate_types, &m_tls_handshake_message_buffer, m_am_tools); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_certificate_request) + { + u32_t data_size = 0ul; + u32_t ind = 0ul; + + for (ind = 0ul; ind < m_certificate_authorities.get_object_count(); ind++) + { + const eap_variable_data_c * const certificate_authority = m_certificate_authorities.get_object(ind); + if (certificate_authority == 0 + || certificate_authority->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + data_size += certificate_authority->get_data_length(); + } + + if (data_size > 0x0000ffff) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + u8_t data_size_array[2]; + data_size_array[0] = static_cast((data_size & 0x0000ff00) >> 8); + data_size_array[1] = static_cast(data_size & 0x000000ff); + + status = m_tls_handshake_message_buffer.add_data( + data_size_array, + sizeof(data_size_array)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate_authorities length"), + data_size_array, + sizeof(data_size_array))); + + + for (ind = 0ul; ind < m_certificate_authorities.get_object_count(); ind++) + { + const eap_variable_data_c * const certificate_authority = m_certificate_authorities.get_object(ind); + if (certificate_authority == 0 + || certificate_authority->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + data_size = certificate_authority->get_data_length(); + u8_t data_size_array[2]; + data_size_array[0] = static_cast((data_size & 0x0000ff00) >> 8); + data_size_array[1] = static_cast(data_size & 0x000000ff); + + status = m_tls_handshake_message_buffer.add_data( + data_size_array, + sizeof(data_size_array)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate_authority length"), + data_size_array, + sizeof(data_size_array))); + + status = m_tls_handshake_message_buffer.add_data( + certificate_authority->get_data(certificate_authority->get_data_length()), + certificate_authority->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate_authority"), + certificate_authority->get_data(certificate_authority->get_data_length()), + certificate_authority->get_data_length())); + } + } + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_certificate_verify) + { + u16_t length_of_certificate_verify_network_order = eap_htons(static_cast(m_signed_message_hash.get_data_length())); + + status = m_tls_handshake_message_buffer.add_data( + &length_of_certificate_verify_network_order, + sizeof(length_of_certificate_verify_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS-handshake certificate_verify"), + &length_of_certificate_verify_network_order, + sizeof(length_of_certificate_verify_network_order))); + + status = m_tls_handshake_message_buffer.add_data( + m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()), + m_signed_message_hash.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake signed_message_hash"), + m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()), + m_signed_message_hash.get_data_length())); + + } + + if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_finished) + { + eap_variable_data_c signed_message_hash(m_am_tools); + + status = m_message_hash->message_hash_save_finished(m_is_client); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_message_hash->message_hash_create_finished(m_is_client, &signed_message_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_tls_handshake_message_buffer.add_data( + signed_message_hash.get_data(signed_message_hash.get_data_length()), + signed_message_hash.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake signed_message_hash"), + signed_message_hash.get_data(signed_message_hash.get_data_length()), + signed_message_hash.get_data_length())); + + } + + +#if defined(USE_EAP_TLS_SESSION_TICKET) + + if (m_tls_extensions.get_object_count() > 0 + && tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_new_session_ticket) + { + const tls_extension_c * const p_new_session_ticket = tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + &m_tls_extensions, + m_am_tools); + + if (p_new_session_ticket != 0) + { + u32_t ticket_lifetime_hint_network_order = eap_htonl(p_new_session_ticket->get_lifetime_hint()); + + status = m_tls_handshake_message_buffer.add_data( + &ticket_lifetime_hint_network_order, + sizeof(ticket_lifetime_hint_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t length_of_opaque_ticket = p_new_session_ticket->get_data_length(); + u16_t length_of_opaque_ticket_network_order = eap_htons(static_cast(length_of_opaque_ticket)); + + status = m_tls_handshake_message_buffer.add_data( + &length_of_opaque_ticket_network_order, + sizeof(length_of_opaque_ticket_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (length_of_opaque_ticket > 0ul) + { + status = m_tls_handshake_message_buffer.add_data( + p_new_session_ticket); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (status == eap_status_ok) + { + u32_t handshake_data_length = m_tls_handshake_message_buffer.get_data_length() - handshake_data_length_start; + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("handshake length %d bytes.\n"), + handshake_data_length)); + + if (handshake_data_length <= 0x00ffffff) + { + // NOTE the address of tmp_tls_handshake_header_on_tls_message_buffer must be queried again. + // The whole buffer might be allocated from other address. + tmp_tls_handshake_header_on_tls_message_buffer.set_header_buffer( + m_tls_handshake_message_buffer.get_data_offset( + offset_of_tmp_tls_handshake_header, + tls_handshake_header_c::get_header_length()+handshake_data_length), + tls_handshake_header_c::get_header_length()+handshake_data_length); + if (tmp_tls_handshake_header_on_tls_message_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + tmp_tls_handshake_header_on_tls_message_buffer.set_data_length(handshake_data_length); + + + switch (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type()) + { + case tls_handshake_type_hello_request: + // This message is NOT included to TLS-message hash. + break; + case tls_handshake_type_client_hello: + case tls_handshake_type_server_hello: + case tls_handshake_type_certificate: + case tls_handshake_type_server_key_exchange: + case tls_handshake_type_certificate_request: + case tls_handshake_type_server_hello_done: + case tls_handshake_type_certificate_verify: + case tls_handshake_type_client_key_exchange: + case tls_handshake_type_finished: +#if defined(USE_EAP_TLS_SESSION_TICKET) + case tls_handshake_type_new_session_ticket: +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + { + status = m_message_hash->message_hash_update( + false, + tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type(), + tmp_tls_handshake_header_on_tls_message_buffer.get_header_buffer( + tmp_tls_handshake_header_on_tls_message_buffer.get_header_length() + + tmp_tls_handshake_header_on_tls_message_buffer.get_data_length()), + tmp_tls_handshake_header_on_tls_message_buffer.get_header_length() + + tmp_tls_handshake_header_on_tls_message_buffer.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + break; + } + default: + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } // switch() + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::add_message_data( + eap_variable_data_c * const tls_message_buffer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: data_function: tls_handshake_message_c::add_message_data(): %s\n"), + (m_is_client == true ? "client": "server"), + tls_handshake_header_c::get_tls_handshake_string(get_handshake_type()))); + + eap_status_e status = eap_status_ok; + + if (m_tls_handshake_message_buffer.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = tls_message_buffer->add_data( + m_tls_handshake_message_buffer.get_data(m_tls_handshake_message_buffer.get_data_length()), + m_tls_handshake_message_buffer.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_message.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_message.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,443 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 131 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_array.h" +#include "tls_message.h" +#include "tls_peap_types.h" +#include "eap_automatic_variable.h" + +/** @file */ + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_message_c::~tls_message_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_record_messages.reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_message_c::tls_message_c( + abs_eap_am_tools_c * const tools, + abs_tls_message_hash_c * const message_hash, + abs_tls_apply_cipher_spec_c * const apply_cipher_spec, + abs_tls_change_cipher_spec_c * change_cipher_spec, + const bool is_client) +: m_am_tools(tools) +, m_message_hash(message_hash) +, m_apply_cipher_spec(apply_cipher_spec) +, m_change_cipher_spec(change_cipher_spec) +, m_tls_message_data(tools) +, m_received_eap_identifier(0ul) +, m_analyse_index(0ul) +, m_record_messages(tools) +, m_is_client(is_client) +, m_includes_tls_handshake_message(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_message_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_analyse_index = 0ul; + m_received_eap_identifier = 0ul; + m_includes_tls_handshake_message = false; + + eap_status_e status = m_record_messages.reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t tls_message_c::get_analyse_index() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_analyse_index; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_message_c::save_analyse_index(const u32_t analyse_index) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_analyse_index = analyse_index; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_message_c::set_tls_message_data( + eap_variable_data_c * const tls_message_data, + u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_tls_message_data.set_copy_of_buffer(tls_message_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_received_eap_identifier = received_eap_identifier; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * tls_message_c::get_tls_message_data() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_tls_message_data; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u8_t tls_message_c::get_received_eap_identifier() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_received_eap_identifier; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_message_c::add_record_message( + tls_record_message_c * const record, + const bool free_record, + const bool includes_tls_handshake_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_includes_tls_handshake_message == false) + { + m_includes_tls_handshake_message = includes_tls_handshake_message; + } + + eap_status_e status = m_record_messages.add_object(record, free_record); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_message_c::fragment_tls_records( + tls_record_message_c * const tls_record_message, + eap_array_c * const tls_fragments) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; + + // Here we assume data included in tls_record_message does not include TLS-record header. + // Only data TLS-protocol messages are included. All TLS-protocol messages are same protocol. + // This function fragments TLS-protocol messages to one or more TLS-record messages. + + u32_t size_of_data = tls_record_message->get_data_length(); + u32_t offset_of_data = 0ul; + + while(size_of_data > 0ul) + { + tls_record_message_c * const fragment = new tls_record_message_c( + m_am_tools, m_message_hash, m_is_client); + + eap_automatic_variable_c + automatic_fragment(m_am_tools, fragment); + + if (fragment == 0 + || fragment->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t fragment_length = size_of_data; + if (fragment_length > TLS_PEAP_MAX_RECORD_FRAGMENT_LENGTH) + { + fragment_length = TLS_PEAP_MAX_RECORD_FRAGMENT_LENGTH; + } + + + // Adds TLS-record header. + status = fragment->get_record_message_data()->set_buffer_length(tls_record_header_c::get_header_length()+fragment_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + tls_record_header_c tmp_tls_record_header_on_tls_message_buffer( + m_am_tools, + fragment->get_record_message_data()->get_buffer(tls_record_header_c::get_header_length()+fragment_length), + tls_record_header_c::get_header_length()+fragment_length); + + if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + // Note this is the length of the TLS-record header. + fragment->get_record_message_data()->set_data_length(tls_record_header_c::get_header_length()); + fragment->set_protocol(tls_record_message->get_protocol()); + fragment->set_version(tls_record_message->get_version()); + // Note this is the length of the TLS-record header and TLS-record data. + // The length of the TLS-record data is the length of the fragment. + fragment->add_data_length(tls_record_header_c::get_header_length()+fragment_length); + fragment->set_tls_record_header_is_included(true); + + tmp_tls_record_header_on_tls_message_buffer.reset_header(0ul, tls_record_message->get_version()); + tmp_tls_record_header_on_tls_message_buffer.set_protocol(tls_record_message->get_protocol()); + tmp_tls_record_header_on_tls_message_buffer.set_data_length(static_cast(fragment_length)); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: tls_message_c::fragment_tls_records(): %s fragment %d bytes from %d bytes.\n"), + (m_is_client == true ? "client": "server"), + tmp_tls_record_header_on_tls_message_buffer.get_tls_protocol_string(), + fragment_length, + tls_record_message->get_data_length())); + + // Adds TLS-record data, this includes TLS-protocol messages. + status = fragment->get_record_message_data()->add_data( + tls_record_message->get_record_message_data()->get_data_offset( + offset_of_data, fragment_length), + fragment_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + size_of_data -= fragment_length; + offset_of_data += fragment_length; + + automatic_fragment.do_not_free_variable(); + + status = tls_fragments->add_object(fragment, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } // while() + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_message_c::add_message_data( + eap_variable_data_c * const tls_message_buffer, + bool * const includes_tls_handshake_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; + + tls_message_buffer->reset(); + status = tls_message_buffer->set_buffer_length(TLS_PEAP_DEFAULT_RECORD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (u32_t ind = 0ul; ind < m_record_messages.get_object_count(); ind++) + { + tls_record_message_c * const tls_record_message = m_record_messages.get_object(ind); + if (tls_record_message == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (tls_record_message->get_record_message_data()->get_is_valid() == false + || tls_record_message->get_record_message_data()->get_buffer_length() < TLS_PEAP_DEFAULT_RECORD_LENGTH) + { + status = tls_record_message->get_record_message_data()->set_buffer_length(TLS_PEAP_DEFAULT_RECORD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + tls_record_message->get_record_message_data()->set_data_length(0ul); + + // This function creates data of TLS-protocol message to internal buffer (tls_record_message->get_record_message_data()). + status = tls_record_message->add_message_data(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_ASSERT(tls_record_message->get_tls_record_header_is_included() == false); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("TLS-record data"), + tls_record_message->get_record_message_data()->get_data( + tls_record_message->get_record_message_data()->get_data_length()), + tls_record_message->get_record_message_data()->get_data_length())); + + // Fragmentation checks the TLS-record is not too long, data more than 2^14 bytes. + // It fragments TLS-record to two or more TLS-records. + // TLS-records could be stored to object of type of eap_array_c. + // In a case the TLS-record cannot be fragmented the whole TLS-message must be dropped. + eap_array_c tls_fragments(m_am_tools); + status = fragment_tls_records( + tls_record_message, + &tls_fragments); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // After the fragmentation cipher suite can be applied to every fragment. + for (u32_t ind_frag = 0ul; ind_frag < tls_fragments.get_object_count(); ind_frag++) + { + tls_record_message_c * const fragment = tls_fragments.get_object(ind_frag); + if (fragment == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_ASSERT(fragment->get_data_length() == fragment->get_record_message_data()->get_data_length()); + + status = m_apply_cipher_spec->apply_send_cipher_suite(fragment->get_record_message_data()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (ind_frag == 0ul) + { + if (fragment->get_protocol() == tls_record_protocol_change_cipher_spec) + { + // This is the right place to change the send cipher spec. + status = m_change_cipher_spec->change_cipher_spec(true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + status = tls_message_buffer->add_data(fragment->get_record_message_data()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + + } // for() + + *includes_tls_handshake_message = m_includes_tls_handshake_message; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t tls_message_c::get_record_message_count() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_record_messages.get_object_count(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_record_message_c * tls_message_c::get_record_message( + const u32_t index) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_record_messages.get_object(index); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_message_c::remove_record_message( + const u32_t index) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_record_messages.remove_object(index); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_record_message_c * tls_message_c::get_last_record_message() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_record_messages.get_last_object(); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_peap_tlv_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_peap_tlv_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,307 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 132 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "tls_peap_tlv_header.h" + +/** @file */ + + +/** + * The destructor of the tls_peap_tlv_header_c class does nothing. + */ +tls_peap_tlv_header_c::~tls_peap_tlv_header_c() +{ +} + +/** + * The constructor of the tls_peap_tlv_header_c class simply initializes the attributes. + */ +tls_peap_tlv_header_c::tls_peap_tlv_header_c( + abs_eap_am_tools_c * const tools, + void * const header_begin, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_begin, header_buffer_length) + , m_am_tools(tools) +{ +} + +/** + * This function returns the TLV type flag. + */ +tls_peap_tlv_type_e tls_peap_tlv_header_c::get_flag_tlv_type() const +{ + const u8_t * const flag_tlv_type_data = get_header_offset(m_flags_and_tlv_type_offset, sizeof(u16_t)); + if (flag_tlv_type_data != 0) + { + return static_cast( + (static_cast( + flag_tlv_type_data[0] & ~(m_flag_mask_mandatory_tlv|m_flag_mask_reserved)) << 8) + | (static_cast(flag_tlv_type_data[1]))); + } + else + { + return tls_peap_tlv_type_none; + } +} + +/** + * This function returns the TLV mandatory flag. + */ +bool tls_peap_tlv_header_c::get_flag_mandatory_tlv() const +{ + const u8_t * const flag_tlv_type_data = get_header_offset(m_flags_and_tlv_type_offset, sizeof(u8_t)); + if (flag_tlv_type_data != 0) + { + u8_t flag = static_cast(flag_tlv_type_data[0] & m_flag_mask_mandatory_tlv); + if (flag != 0) + { + return true; + } + } + return false; +} + +/** + * This function returns the TLV reserved flag. + */ +bool tls_peap_tlv_header_c::get_flag_reserved() const +{ + const u8_t * const flag_tlv_type_data = get_header_offset(m_flags_and_tlv_type_offset, sizeof(u8_t)); + if (flag_tlv_type_data != 0) + { + u8_t flag = static_cast(flag_tlv_type_data[0] & m_flag_mask_reserved); + if (flag != 0) + { + return true; + } + } + return false; +} + +/** + * This function returns the data length of TLV. + */ +u16_t tls_peap_tlv_header_c::get_data_length() const +{ + const u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u16_t)); + if (length_data != 0) + { + return eap_read_u16_t_network_order(length_data, sizeof(u16_t)); + } + else + { + return 0ul; + } +} + +/** + * This function returns the header length of TLV. + */ +u32_t tls_peap_tlv_header_c::get_header_length() +{ + return m_data_offset; +} + +/** + * This function returns pointer to the offset of data of TLV. + * @param offset is the offset of queried data in bytes. + * @param contignuous_bytes is the length of queried data in bytes. + */ +u8_t * tls_peap_tlv_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + u32_t data_length = get_data_length(); // Here is removed optional TLS message length. + + if (data_length >= offset+contignuous_bytes) + { + u8_t * const data = get_header_offset(m_data_offset, offset+contignuous_bytes); + if (data != 0) + { + return &data[offset]; + } + else + { + return 0; + } + } + else + { + EAP_ASSERT_ALWAYS(data_length >= offset+contignuous_bytes); + } + return 0; +} + + +/** + * This function returns pointer to the offset of data of TLV. + * @param contignuous_bytes is the length of queried data in bytes. + */ +u8_t * tls_peap_tlv_header_c::get_data(const u32_t contignuous_bytes) const +{ + return get_data_offset(0u, contignuous_bytes); +} + + +/** + * This function return pointer to the next TLV header in the same buffer. + */ +u8_t * tls_peap_tlv_header_c::get_next_header() const +{ + if (get_header_buffer_length() >= 2ul*get_header_length()+get_data_length()) + { + return get_data_offset(get_data_length(), get_header_length()); + } + else + { + return 0; + } +} + + +/** + * This function checks the header is valid. + */ +eap_status_e tls_peap_tlv_header_c::check_header() const +{ + if (get_flag_tlv_type() != tls_peap_tlv_type_result + && get_flag_tlv_type() != tls_peap_tlv_type_nak + && get_flag_tlv_type() != tls_peap_tlv_type_crypto_binding + && get_flag_tlv_type() != tls_peap_tlv_eap_payload + && get_flag_tlv_type() != tls_peap_tlv_type_intermediate_result) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (get_flag_reserved() != 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +/** + * This function returns debug strings of the TLV type. + */ +eap_const_string tls_peap_tlv_header_c::get_tlv_type_string() const +{ + +#if defined(USE_EAP_TRACE_STRINGS) + const tls_peap_tlv_type_e protocol = get_flag_tlv_type(); + + EAP_IF_RETURN_STRING(protocol, tls_peap_tlv_type_none) + else EAP_IF_RETURN_STRING(protocol, tls_peap_tlv_type_result) + else EAP_IF_RETURN_STRING(protocol, tls_peap_tlv_type_nak) + else EAP_IF_RETURN_STRING(protocol, tls_peap_tlv_type_crypto_binding) + else EAP_IF_RETURN_STRING(protocol, tls_peap_tlv_eap_payload) + else EAP_IF_RETURN_STRING(protocol, tls_peap_tlv_type_intermediate_result) + else +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown TLV type"); + } +} + +/** + * This function sets the TLV type flag. + */ +void tls_peap_tlv_header_c::set_flag_tlv_type(tls_peap_tlv_type_e type) +{ + u8_t * const flag_tlv_type_data = get_header_offset(m_flags_and_tlv_type_offset, sizeof(u16_t)); + + EAP_ASSERT(flag_tlv_type_data != 0); + + flag_tlv_type_data[0] = static_cast( + flag_tlv_type_data[0] & (m_flag_mask_mandatory_tlv|m_flag_mask_reserved) + | ((type & 0xff00) >> 8) & ~(m_flag_mask_mandatory_tlv|m_flag_mask_reserved)); + flag_tlv_type_data[1] = static_cast(type & 0x00ff); +} + +/** + * This function sets the TLV reserved flag. + */ +void tls_peap_tlv_header_c::set_flag_reserved(bool reserved) +{ + u8_t * const flag_tlv_type_data = get_header_offset(m_flags_and_tlv_type_offset, sizeof(u16_t)); + EAP_ASSERT(flag_tlv_type_data != 0); + + if (reserved == true) + { + flag_tlv_type_data[0] |= m_flag_mask_reserved; + } + else + { + flag_tlv_type_data[0] &= ~m_flag_mask_reserved; + } +} + +/** + * This function sets the TLV manadtory flag. + */ +void tls_peap_tlv_header_c::set_flag_mandatory_tlv(const bool mandatory_when_true) +{ + u8_t * const flag_tlv_type_data = get_header_offset(m_flags_and_tlv_type_offset, sizeof(u16_t)); + EAP_ASSERT(flag_tlv_type_data != 0); + + if (mandatory_when_true == true) + { + flag_tlv_type_data[0] |= m_flag_mask_mandatory_tlv; + } + else + { + flag_tlv_type_data[0] &= ~m_flag_mask_mandatory_tlv; + } +} + +/** + * This function sets the TLV data length. + */ +void tls_peap_tlv_header_c::set_data_length(const u16_t p_length) +{ + u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u16_t)); + + EAP_ASSERT(length_data != 0); + + length_data[0] = static_cast((p_length & 0xff00) >> 8); + length_data[1] = static_cast((p_length & 0x00ff)); +} + +/** + * This function resets the TLV header. + */ +void tls_peap_tlv_header_c::reset_header(const u16_t buffer_length) +{ + set_flag_tlv_type(tls_peap_tlv_type_none); + set_flag_reserved(0); + set_flag_mandatory_tlv(true); + set_data_length(buffer_length); +} + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_peap_tlv_payloads.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_peap_tlv_payloads.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,224 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 133 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "tls_peap_tlv_payloads.h" +#include "abs_eap_am_tools.h" +#include "eap_tools.h" + + + +EAP_FUNC_EXPORT peap_tlv_variable_data_c::~peap_tlv_variable_data_c() +{ +} + +EAP_FUNC_EXPORT peap_tlv_variable_data_c::peap_tlv_variable_data_c(abs_eap_am_tools_c * const tools) + : eap_variable_data_c(tools) + , m_am_tools(tools) + , m_original_header(tools, 0, 0) + , m_header_copy(tools) +{ +} + +EAP_FUNC_EXPORT const tls_peap_tlv_header_c * peap_tlv_variable_data_c::get_original_header() const +{ + return &m_original_header; +} + +EAP_FUNC_EXPORT eap_status_e peap_tlv_variable_data_c::set_buffer( + const tls_peap_tlv_header_c * const original_header, + u8_t *data_buffer, + const u32_t data_buffer_length, + const bool free_buffer, + const bool is_writable) +{ + m_original_header.set_header_buffer( + original_header->get_header_buffer(original_header->get_header_buffer_length()), + original_header->get_header_buffer_length()); + + eap_status_e status = eap_variable_data_c::set_buffer(data_buffer, data_buffer_length, free_buffer, is_writable); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e peap_tlv_variable_data_c::set_copy_of_buffer( + const tls_peap_tlv_header_c * const original_header) +{ + u32_t data_length = original_header->get_header_length()+original_header->get_data_length(); + + if (original_header->get_header_buffer_length() < data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + eap_status_e status = m_header_copy.set_copy_of_buffer( + original_header->get_header_buffer(data_length), + data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_original_header.set_header_buffer( + m_header_copy.get_data(m_header_copy.get_data_length()), + m_header_copy.get_data_length()); + + tls_peap_tlv_header_c payload_copy( + m_am_tools, + m_header_copy.get_data(m_header_copy.get_data_length()), + m_header_copy.get_data_length()); + + status = eap_variable_data_c::set_buffer( + payload_copy.get_data(payload_copy.get_data_length()), + payload_copy.get_data_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + + +EAP_FUNC_EXPORT peap_tlv_payloads_c::~peap_tlv_payloads_c() +{ +} + +EAP_FUNC_EXPORT peap_tlv_payloads_c::peap_tlv_payloads_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_result_tlv(tools) + , m_nak_tlv(tools) + , m_crypto_binding_tlv(tools) + , m_eap_payload_tlv(tools) + , m_intermediate_result_tlv(tools) + , m_is_valid(false) +{ + m_is_valid = true; +} + +EAP_FUNC_EXPORT bool peap_tlv_payloads_c::check_one_payload( + const peap_tlv_payload_status_e status, + const peap_tlv_variable_data_c * const payload) +{ + if (status == peap_tlv_payload_status_optional) + { + return true; + } + else if (status == peap_tlv_payload_status_must_not_be + && payload->eap_variable_data_c::get_is_valid_data() == false) + { + return true; + } + else if (status == peap_tlv_payload_status_must_be + && payload->eap_variable_data_c::get_is_valid_data() == true) + { + return true; + } + else + { + return false; + } +} + +EAP_FUNC_EXPORT bool peap_tlv_payloads_c::check_payloads( + const peap_tlv_payload_status_e result_tlv, + const peap_tlv_payload_status_e nak_tlv, + const peap_tlv_payload_status_e crypto_binding_tlv, + const peap_tlv_payload_status_e eap_payload_tlv, + const peap_tlv_payload_status_e intermediate_result_tlv + ) +{ + if (check_one_payload(result_tlv, get_result_tlv()) == true + && check_one_payload(nak_tlv, get_nak_tlv()) == true + && check_one_payload(crypto_binding_tlv, get_crypto_binding_tlv()) == true + && check_one_payload(eap_payload_tlv, get_eap_payload_tlv()) == true + && check_one_payload(intermediate_result_tlv, get_intermediate_result_tlv()) == true + ) + { + return true; + } + else + { + return false; + } +} + +EAP_FUNC_EXPORT peap_tlv_variable_data_c * peap_tlv_payloads_c::get_result_tlv() +{ + return static_cast(&m_result_tlv); +} + +EAP_FUNC_EXPORT peap_tlv_variable_data_c * peap_tlv_payloads_c::get_nak_tlv() +{ + return static_cast(&m_nak_tlv); +} + +EAP_FUNC_EXPORT peap_tlv_variable_data_c * peap_tlv_payloads_c::get_crypto_binding_tlv() +{ + return static_cast(&m_crypto_binding_tlv); +} + +EAP_FUNC_EXPORT peap_tlv_variable_data_c * peap_tlv_payloads_c::get_eap_payload_tlv() +{ + return static_cast(&m_eap_payload_tlv); +} + +EAP_FUNC_EXPORT peap_tlv_variable_data_c * peap_tlv_payloads_c::get_intermediate_result_tlv() +{ + return static_cast(&m_intermediate_result_tlv); +} + +EAP_FUNC_EXPORT bool peap_tlv_payloads_c::get_is_valid() const +{ + return m_is_valid; +} + +EAP_FUNC_EXPORT void peap_tlv_payloads_c::reset() +{ + m_result_tlv.reset(); + m_nak_tlv.reset(); + m_crypto_binding_tlv.reset(); + m_eap_payload_tlv.reset(); + m_intermediate_result_tlv.reset(); + m_is_valid = false; +} + + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_peap_types.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_peap_types.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,307 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 134 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "tls_peap_types.h" + +/** @file tls_peap_types.cpp + */ + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_tls_trace_string_c::~eap_tls_trace_string_c() +{ +} + +EAP_FUNC_EXPORT eap_tls_trace_string_c::eap_tls_trace_string_c() +{ +} + + +#if defined(USE_FAST_EAP_TYPE) + +EAP_FUNC_EXPORT eap_const_string eap_tls_trace_string_c::get_eap_fast_state_string(const eap_fast_state_e state) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(state, eap_fast_state_none) + else EAP_IF_RETURN_STRING(state, eap_fast_state_wait_TLVs) + else EAP_IF_RETURN_STRING(state, eap_fast_state_wait_crypto_binding_TLV) + else EAP_IF_RETURN_STRING(state, eap_fast_state_wait_result_TLV) + else EAP_IF_RETURN_STRING(state, eap_fast_state_wait_PAC_TLV) + else EAP_IF_RETURN_STRING(state, eap_fast_state_wait_PAC_acknowledge_TLV) + else EAP_IF_RETURN_STRING(state, eap_fast_state_wait_PAC_TLV_or_plain_eap_success) + else EAP_IF_RETURN_STRING(state, eap_fast_state_success) +#else + EAP_UNREFERENCED_PARAMETER(state); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown EAP-FAST state"); + } +} + +#endif //#if defined(USE_FAST_EAP_TYPE) + + +EAP_FUNC_EXPORT eap_const_string eap_tls_trace_string_c::get_cipher_suite_string(const tls_cipher_suites_e suite) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(suite, tls_cipher_suites_TLS_NULL_WITH_NULL_NULL) + else EAP_IF_RETURN_STRING(suite, tls_cipher_suites_TLS_RSA_WITH_RC4_128_MD5) + else EAP_IF_RETURN_STRING(suite, tls_cipher_suites_TLS_RSA_WITH_RC4_128_SHA) + else EAP_IF_RETURN_STRING(suite, tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA) + else EAP_IF_RETURN_STRING(suite, tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) + else EAP_IF_RETURN_STRING(suite, tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA) + else EAP_IF_RETURN_STRING(suite, tls_cipher_suites_TLS_RSA_WITH_AES_128_CBC_SHA) + else EAP_IF_RETURN_STRING(suite, tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA) + else EAP_IF_RETURN_STRING(suite, tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA) +#if defined(USE_FAST_EAP_TYPE) + else EAP_IF_RETURN_STRING(suite, tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA) +#endif //#if defined(USE_FAST_EAP_TYPE) + else +#else + EAP_UNREFERENCED_PARAMETER(suite); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown cipher suite"); + } +} + +EAP_FUNC_EXPORT eap_const_string eap_tls_trace_string_c::get_certificate_type_string(const tls_certificate_type_e certificate_type) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(certificate_type, tls_certificate_type_rsa_sign) + else EAP_IF_RETURN_STRING(certificate_type, tls_certificate_type_dss_sign) + else EAP_IF_RETURN_STRING(certificate_type, tls_certificate_type_none) + else +#else + EAP_UNREFERENCED_PARAMETER(certificate_type); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown certificate type"); + } +} + +EAP_FUNC_EXPORT eap_const_string eap_tls_trace_string_c::get_compression_method_string(const tls_compression_method_e compression_method) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(compression_method, tls_compression_method_null) + else EAP_IF_RETURN_STRING(compression_method, tls_compression_method_none) + else +#else + EAP_UNREFERENCED_PARAMETER(compression_method); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown compression method"); + } +} + +EAP_FUNC_EXPORT eap_const_string eap_tls_trace_string_c::get_state_string(const tls_peap_state_e state) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(state, tls_peap_state_none) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_tls_start) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_handshake_type_client_hello) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_handshake_type_server_hello) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_handshake_type_certificate) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_handshake_type_server_key_exchange) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_handshake_type_server_hello_done) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_handshake_type_client_key_exchange) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_handshake_type_certificate_verify) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_handshake_type_finished) +#if defined(USE_EAP_TLS_SESSION_TICKET) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_handshake_type_new_session_ticket) +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_change_cipher_spec) + else EAP_IF_RETURN_STRING(state, tls_peap_state_peap_tunnel_ready) + else EAP_IF_RETURN_STRING(state, tls_peap_state_full_authentication) + else EAP_IF_RETURN_STRING(state, tls_peap_state_original_session_resumption) +#if defined(USE_EAP_TLS_SESSION_TICKET) + else EAP_IF_RETURN_STRING(state, tls_peap_state_stateless_session_resumption) +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + else EAP_IF_RETURN_STRING(state, tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet) +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else EAP_IF_RETURN_STRING(state, tls_peap_state_client_send_ttls_plain_ms_chap_v2_empty_ack) + else EAP_IF_RETURN_STRING(state, tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack) +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_tunneled_authentication_start) + else EAP_IF_RETURN_STRING(state, tls_peap_state_wait_application_data) + else EAP_IF_RETURN_STRING(state, tls_peap_state_process_pending_tls_completions) + else EAP_IF_RETURN_STRING(state, tls_peap_state_pending_tls_messages_processed) + else EAP_IF_RETURN_STRING(state, tls_peap_state_tls_success) + else EAP_IF_RETURN_STRING(state, tls_peap_state_failure) + else +#else + EAP_UNREFERENCED_PARAMETER(state); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown TLS-state"); + } +} + +EAP_FUNC_EXPORT eap_const_string eap_tls_trace_string_c::get_peap_version_string(const peap_version_e peap_version) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(peap_version, peap_version_none) + else EAP_IF_RETURN_STRING(peap_version, peap_version_0_xp) + else EAP_IF_RETURN_STRING(peap_version, peap_version_1) + else EAP_IF_RETURN_STRING(peap_version, peap_version_2) + else +#else + EAP_UNREFERENCED_PARAMETER(peap_version); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown TLS-tunnel (PEAP) type"); + } +} + +EAP_FUNC_EXPORT eap_const_string eap_tls_trace_string_c::get_alert_level_string(const tls_alert_level_e alert_level) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(alert_level, tls_alert_level_warning) + else EAP_IF_RETURN_STRING(alert_level, tls_alert_level_fatal) + else EAP_IF_RETURN_STRING(alert_level, tls_alert_level_none) + else +#else + EAP_UNREFERENCED_PARAMETER(alert_level); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown TLS-alert level"); + } +} + +EAP_FUNC_EXPORT eap_const_string eap_tls_trace_string_c::get_alert_description_string(const tls_alert_description_e alert_description) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(alert_description, tls_alert_description_close_notify) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_unexpected_message) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_bad_record_mac) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_decryption_failed) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_record_overflow) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_decompression_failure) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_handshake_failure) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_bad_certificate) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_unsupported_certificate) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_certificate_revoked) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_certificate_expired) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_certificate_unknown) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_illegal_parameter) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_unknown_ca) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_access_denied) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_decode_error) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_decrypt_error) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_export_restriction) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_protocol_version) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_insufficient_security) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_internal_error) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_user_canceled) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_no_renegotiation) + else EAP_IF_RETURN_STRING(alert_description, tls_alert_description_none) + else +#else + EAP_UNREFERENCED_PARAMETER(alert_description); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown TLS-alert description"); + } +} + + +EAP_FUNC_EXPORT eap_const_string eap_tls_trace_string_c::get_tls_session_type_string(const tls_session_type_e tls_session_type) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(tls_session_type, tls_session_type_none) + else EAP_IF_RETURN_STRING(tls_session_type, tls_session_type_full_authentication) + else EAP_IF_RETURN_STRING(tls_session_type, tls_session_type_original_session_resumption) + else EAP_IF_RETURN_STRING(tls_session_type, tls_session_type_stateless_session_resumption) +#if defined(USE_FAST_EAP_TYPE) + else EAP_IF_RETURN_STRING(tls_session_type, tls_session_type_eap_fast_pac_session_resumption) + else EAP_IF_RETURN_STRING(tls_session_type, tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP) +#endif //#if defined(USE_FAST_EAP_TYPE) + else +#else + EAP_UNREFERENCED_PARAMETER(tls_session_type); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown TLS-session type"); + } +} + + +EAP_FUNC_EXPORT eap_const_string eap_tls_trace_string_c::get_ttls_state_string(const eap_ttls_tunneled_message_state_e ttls_state) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_none) + else EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_process_identity_response) + else EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_process_identity_response) + else EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_process_response) + else EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_process_change_password_response) + else EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_process_identity_request) + else EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_process_identity_request_pending) + else EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_process_challenge_request) + else EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_process_success_request) + else EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_complete_success_request) + else EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_process_error_request) + else EAP_IF_RETURN_STRING(ttls_state, eap_ttls_tunneled_message_state_complete_error_request) + else +#else + EAP_UNREFERENCED_PARAMETER(ttls_state); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown TTLS-state"); + } +} + + +EAP_FUNC_EXPORT eap_const_string eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(const tls_identity_privacy_handshake_state_e privacy_state) +{ + +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(privacy_state, tls_identity_privacy_handshake_state_none) + else EAP_IF_RETURN_STRING(privacy_state, tls_identity_privacy_handshake_state_negotiates) + else EAP_IF_RETURN_STRING(privacy_state, tls_identity_privacy_handshake_state_runs) + else +#else + EAP_UNREFERENCED_PARAMETER(privacy_state); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown privacy-state"); + } +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_record.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_record.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,20190 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 135 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_am_export.h" +#include "eap_am_tools.h" +#include "eap_tools.h" +#include "eap_crypto_api.h" +#include "abs_tls_base_record.h" +#include "tls_base_record.h" +#include "tls_record.h" +#include "tls_am_services.h" +#include "tls_handshake_header.h" +#include "tls_peap_types.h" +#include "tls_message.h" +#include "eap_automatic_variable.h" +#include "eap_state_notification.h" +#include "eap_type_tls_peap_types.h" +#include "eap_header_string.h" + +#if defined(USE_FAST_EAP_TYPE) + #include "eap_fast_tlv_payloads.h" +#endif //#if defined(USE_FAST_EAP_TYPE) + +#if defined(USE_EAP_TLS_SESSION_TICKET) +#include "tls_extension.h" +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +//-------------------------------------------------- + +#define EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(tools, status) \ + EAP_STATUS_RETURN(tools, eap_status_return_and_create_tls_protocol_alert((status))) + + +eap_status_e tls_record_c::eap_status_return_and_create_tls_protocol_alert( + const eap_status_e status) +{ + if (status != eap_status_ok + && status != eap_status_success + && status != eap_status_pending_request + && status != eap_status_drop_packet_quietly) + { + (void) create_tls_protocol_alert(tls_alert_description_none, tls_alert_level_none, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_record_c::~tls_record_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x, %s: function: starts: tls_record_c::~tls_record_c(): m_am_tls_services") + EAPL(" = 0x%08x (validity %d).\n"), + this, + (m_is_client == true ? "client": "server"), + m_am_tls_services, + m_am_tls_services->get_is_valid())); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::~tls_record_c()"); + + EAP_ASSERT(m_shutdown_was_called == true); + + completion_action_clenup(); + + if (m_free_am_tls_services == true) + { + delete m_am_tls_services; + } + m_am_tls_services = 0; + + if (m_free_application == true) + { + delete m_application; + } + m_application = 0; + + reset_block_ciphers(true); + reset_block_ciphers(false); + + reset_stream_ciphers(true); + reset_stream_ciphers(false); + + reset_hmac_algorithms(true); + reset_hmac_algorithms(false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +EAP_FUNC_EXPORT tls_record_c::tls_record_c( + abs_eap_am_tools_c * const tools, ///< tools is pointer to the tools class. @see abs_eap_am_tools_c. + tls_am_services_c * const am_tls_services, ///< This is pointer to adaptation module of TLS. + const bool free_am_tls_services, + tls_base_application_c * const application, ///< application is pointer to application object. + const bool free_application, + const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false). + const eap_type_value_e eap_type, + const eap_am_network_id_c * const receive_network_id) + : tls_base_record_c(tools /*, partner */) + , m_am_tools(tools) + , m_am_tls_services(am_tls_services) + , m_free_am_tls_services(free_am_tls_services) + , m_application(application) + , m_free_application(free_application) + , m_completion_queue(tools) + , m_received_tls_message(tools, this, this, this, is_client_when_true) + , m_new_tls_message(tools, this, this, this, is_client_when_true) + , m_message_hash_md5(tools) + , m_message_hash_sha1(tools) + , m_message_hash_md5_certificate_verify(tools) + , m_message_hash_sha1_certificate_verify(tools) + , m_client_message_hash_md5_finished(tools) + , m_client_message_hash_sha1_finished(tools) + , m_server_message_hash_md5_finished(tools) + , m_server_message_hash_sha1_finished(tools) + , m_client_handshake_random_value(tools) + , m_server_handshake_random_value(tools) + , m_session_id(tools) + , m_master_secret(tools) + , m_eap_master_session_key(tools, eap_type) + , m_new_send_mac_key(tools) + , m_new_receive_mac_key(tools) + , m_new_send_encryption_key(tools) + , m_new_receive_encryption_key(tools) + , m_new_send_iv(tools) + , m_new_receive_iv(tools) + , m_send_mac_key(tools) + , m_receive_mac_key(tools) + , m_send_encryption_key(tools) + , m_receive_encryption_key(tools) + , m_send_iv(tools) + , m_receive_iv(tools) + , m_session_key_seed(tools) + , m_mschapv2_challenges(tools) + , m_own_private_dhe_key(tools) + , m_own_public_dhe_key(tools) + , m_peer_public_dhe_key(tools) + , m_shared_dh_key(tools) + , m_dhe_prime(tools) + , m_dhe_group_generator(tools) + , m_signed_message_hash(tools) + , m_premaster_secret(tools) + , m_own_encrypted_premaster_secret(tools) +#if defined(USE_FAST_EAP_TYPE) + , m_eap_fast_pac_key(tools) +#endif //#if defined(USE_FAST_EAP_TYPE) + , m_proposed_cipher_suites(tools) + , m_proposed_compression_methods(tools) +#if defined(USE_EAP_TLS_SESSION_TICKET) + , m_supported_tls_extensions(tools) + , m_received_tls_extensions(tools) +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + , m_NAI_realm(tools) + , m_send_network_id(tools) + , m_own_certificate_chain(tools) + , m_own_certificate_types(tools) + , m_own_certificate_authorities(tools) + , m_peer_certificate_chain(tools) + , m_peer_certificate_chain_result(eap_status_illegal_certificate) + , m_verify_signature(eap_status_authentication_failure) + , m_peer_certificate_types(tools) + , m_peer_certificate_authorities(tools) + , m_resumed_cipher_suite(tls_cipher_suites_none) + , m_selected_cipher_suite(tls_cipher_suites_none) + , m_selected_compression_method(tls_compression_method_none) + , m_receive_cipher_suite(tls_cipher_suites_TLS_NULL_WITH_NULL_NULL) + , m_receive_compression_method(tls_compression_method_null) + , m_send_cipher_suite(tls_cipher_suites_TLS_NULL_WITH_NULL_NULL) + , m_send_compression_method(tls_compression_method_null) + , m_send_block_cipher(0) + , m_receive_block_cipher(0) + , m_send_stream_cipher(0) + , m_receive_stream_cipher(0) + , m_send_hmac_algorithm(0) + , m_receive_hmac_algorithm(0) + , m_send_record_sequence_number(0ul) + , m_receive_record_sequence_number(0ul) + , m_tls_peap_state(tls_peap_state_wait_tls_start) + , m_tls_session_type(tls_session_type_none) + , m_eap_type(eap_type) + , m_peap_version(peap_version_none) + , m_tunneled_eap_type_authentication_state(eap_state_none) + , m_is_valid(false) + , m_is_client(is_client_when_true) + , m_allow_message_send(true) + , m_already_in_completion_action_check(false) + , m_already_in_process_tls_records(false) + , m_pending_query_certificate_authorities_and_types(false) + , m_pending_query_certificate_chain(false) + , m_pending_query_cipher_suites_and_previous_session(false) + , m_pending_query_dh_parameters(false) + , m_pending_query_realm(false) + , m_pending_select_cipher_suite_and_check_session_id(false) + , m_pending_verify_certificate_chain(false) + , m_pending_rsa_decrypt_with_private_key(false) + , m_pending_rsa_encrypt_with_public_key(false) + , m_pending_sign_with_private_key(false) + , m_pending_verify_with_public_key(false) + , m_pending_query_tunnel_PAC(false) + , m_tls_peap_test_version(false) + , m_key_material_generated(false) + , m_tls_peap_server_authenticates_client_policy_flag(true) + , m_tls_peap_server_authenticates_client_config_server(true) + , m_tls_peap_server_authenticates_client_action(true) + , m_tls_peap_server_requested_client_certificate(false) + , m_could_send_fatal_alert_message(true) + , m_could_send_warning_alert_message(true) + , m_force_tls_message_send(false) + , m_shutdown_was_called(false) + , m_use_separate_tls_record(true) // Some vendors seems to use only separate TLS-records. Windows RAS and FreeRadius works too with this. + , m_use_extra_padding_length(false) // It seems that EAP-TLS of Microsoft Windows does not work with extra padding. + , m_client_allows_empty_certificate_authorities_list(false) + , m_server_sends_empty_certificate_authorities_list(false) + , m_use_tppd_tls_peap(true) + , m_use_tppd_peapv1_acknowledge_hack(false) + , m_server_offers_new_session_id(true) + , m_will_receive_new_session_ticket(false) + , m_send_piggypacked_eap_identity_request(true) +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + , m_tls_use_identity_privacy(false) + , m_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_none) +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) +#if defined(USE_FAST_EAP_TYPE) + , m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP(false) + , m_remove_tunnel_pac(false) +#endif //#if defined(USE_FAST_EAP_TYPE) + { + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: function: starts: tls_record_c::tls_record_c(): "), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::tls_record_c()"); + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + // No need to delete anything here because it is done in destructor. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (m_am_tls_services == 0 + || m_am_tls_services->get_is_valid() == false) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_TLS_PEAP_ERROR, + (EAPL("ERROR: %s: function: tls_record_c::tls_record_c() failed,") + EAPL(" m_am_tls_services = 0x%08x (validity %d) is invalid.\n"), + (m_is_client == true ? "client": "server"), + m_am_tls_services, (m_am_tls_services != 0) ? m_am_tls_services->get_is_valid() : false)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + m_am_tls_services->set_tls_am_partner(this); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id( + m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + eap_status_e status = m_send_network_id.set_copy_of_network_id(&send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (get_is_tunneled_tls() == true + && m_application == 0) + { + // Application is required in tunneled mode. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (m_application != 0) + { + m_application->set_application_partner(this); + } + + if (m_is_client == false) + { + set_state(tls_peap_state_wait_handshake_type_client_hello); + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_c::reset_block_ciphers(const bool send_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (send_when_true == true) + { + delete m_send_block_cipher; + m_send_block_cipher = 0; + } + else + { + delete m_receive_block_cipher; + m_receive_block_cipher = 0; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_c::reset_stream_ciphers(const bool send_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (send_when_true == true) + { + delete m_send_stream_cipher; + m_send_stream_cipher = 0; + } + else + { + delete m_receive_stream_cipher; + m_receive_stream_cipher = 0; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_c::reset_hmac_algorithms(const bool send_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (send_when_true == true) + { + delete m_send_hmac_algorithm; + m_send_hmac_algorithm = 0; + } + else + { + delete m_receive_hmac_algorithm; + m_receive_hmac_algorithm = 0; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_c::set_state(const tls_peap_state_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: state_function: starts: tls_record_c::set_state() from %s to %s\n"), + this, + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string(state))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::set_state()"); + + if (m_tls_peap_state != tls_peap_state_failure) + { + m_tls_peap_state = state; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_peap_state_e tls_record_c::get_state() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_tls_peap_state; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_c::verify_state(const tls_peap_state_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + bool are_equal = false; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: state_function: starts: tls_record_c::verify_state(): (current state %s) %s (new state %s)\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + ((m_tls_peap_state == state) ? "==" : "!="), + eap_tls_trace_string_c::get_state_string(state))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::verify_state()"); + + if (m_tls_peap_state == state) + { + are_equal = true; + } + else + { + are_equal = false; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return are_equal; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_c::get_is_tunneled_tls() +{ + return ( + m_eap_type == eap_type_peap + || m_eap_type == eap_type_ttls +#if defined(USE_FAST_EAP_TYPE) + || m_eap_type == eap_type_fast +#endif //#if defined(USE_FAST_EAP_TYPE) + ); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_c::set_peap_version( + const peap_version_e peap_version, + const bool use_tppd_tls_peap, + const bool use_tppd_peapv1_acknowledge_hack) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_peap_version = peap_version; + + m_use_tppd_tls_peap = use_tppd_tls_peap; + + m_use_tppd_peapv1_acknowledge_hack = use_tppd_peapv1_acknowledge_hack; + + m_am_tls_services->set_peap_version( + peap_version, + use_tppd_tls_peap, + use_tppd_peapv1_acknowledge_hack); + + if (m_application != 0) + { + m_application->set_peap_version( + peap_version, + use_tppd_tls_peap, + use_tppd_peapv1_acknowledge_hack); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: function: starts: tls_record_c::configure():\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::configure()"); + + eap_status_e status = m_am_tls_services->configure(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + //---------------------------------------------------------- + + { + eap_variable_data_c test_version(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_EAP_TLS_test_version.get_field(), + &test_version); + if (status == eap_status_ok + && test_version.get_is_valid_data() == true + && test_version.get_data_length() == sizeof(u32_t) + && test_version.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast(test_version.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_tls_peap_test_version = false; + } + else + { + m_tls_peap_test_version = true; + } + } + } + + status = eap_status_ok; + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_separate_tls_record(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_TLS_use_separate_tls_record.get_field(), + &use_separate_tls_record); + if (status == eap_status_ok + && use_separate_tls_record.get_is_valid_data() == true + && use_separate_tls_record.get_data_length() == sizeof(u32_t) + && use_separate_tls_record.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + use_separate_tls_record.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_use_separate_tls_record = false; + } + else + { + m_use_separate_tls_record = true; + } + } + } + + status = eap_status_ok; + } + + //---------------------------------------------------------- + + if (m_is_client == false) + { + eap_variable_data_c server_offers_new_session_id(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_TLS_server_offers_new_session_id.get_field(), + &server_offers_new_session_id); + if (status == eap_status_ok + && server_offers_new_session_id.get_is_valid_data() == true + && server_offers_new_session_id.get_data_length() == sizeof(u32_t) + && server_offers_new_session_id.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + server_offers_new_session_id.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_server_offers_new_session_id = false; + } + else + { + m_server_offers_new_session_id = true; + } + } + } + + status = eap_status_ok; + } + + //---------------------------------------------------------- + + if (get_is_tunneled_tls() == true) + { + // Default function in PEAP and TTLS is only client authenticates server. + m_tls_peap_server_authenticates_client_config_server = false; + } + + if (m_is_client == false) + { + eap_variable_data_c server_authenticates_client(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_TLS_server_authenticates_client.get_field(), + &server_authenticates_client); + if (status == eap_status_ok + && server_authenticates_client.get_is_valid_data() == true + && server_authenticates_client.get_data_length() == sizeof(u32_t) + && server_authenticates_client.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + server_authenticates_client.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_tls_peap_server_authenticates_client_config_server = false; + } + else + { + m_tls_peap_server_authenticates_client_config_server = true; + } + } + } + + if (m_tls_peap_server_authenticates_client_config_server == false) + { + m_tls_peap_server_authenticates_client_action = false; + } + + status = eap_status_ok; + } + + //---------------------------------------------------------- + + if (get_is_tunneled_tls() == true) + { + // Default function in PEAP and TTLS is only client authenticates server. + m_tls_peap_server_authenticates_client_policy_flag = false; + } + + if (m_is_client == true) + { + eap_variable_data_c server_authenticates_client(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_TLS_server_authenticates_client_policy_in_client.get_field(), + &server_authenticates_client); + if (status == eap_status_ok + && server_authenticates_client.get_is_valid_data() == true + && server_authenticates_client.get_data_length() == sizeof(u32_t) + && server_authenticates_client.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + server_authenticates_client.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_tls_peap_server_authenticates_client_policy_flag = false; + } + else + { + m_tls_peap_server_authenticates_client_policy_flag = true; + } + } + } + + status = eap_status_ok; + } + else + { + eap_variable_data_c server_authenticates_client(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_TLS_server_authenticates_client_policy_in_server.get_field(), + &server_authenticates_client); + if (status == eap_status_ok + && server_authenticates_client.get_is_valid_data() == true + && server_authenticates_client.get_data_length() == sizeof(u32_t) + && server_authenticates_client.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + server_authenticates_client.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_tls_peap_server_authenticates_client_policy_flag = false; + } + else + { + m_tls_peap_server_authenticates_client_policy_flag = true; + } + } + } + + status = eap_status_ok; + } + + //---------------------------------------------------------- + + if (m_is_client == true) + { + eap_variable_data_c client_allows_empty_certificate_authorities_list(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_TLS_client_allows_empty_certificate_authorities_list.get_field(), + &client_allows_empty_certificate_authorities_list); + if (status == eap_status_ok + && client_allows_empty_certificate_authorities_list.get_is_valid_data() == true + && client_allows_empty_certificate_authorities_list.get_data_length() == sizeof(u32_t) + && client_allows_empty_certificate_authorities_list.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + client_allows_empty_certificate_authorities_list.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_client_allows_empty_certificate_authorities_list = false; + } + else + { + m_client_allows_empty_certificate_authorities_list = true; + } + } + } + + status = eap_status_ok; + } + else + { + eap_variable_data_c server_sends_empty_certificate_authorities_list(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_TLS_server_sends_empty_certificate_authorities_list.get_field(), + &server_sends_empty_certificate_authorities_list); + if (status == eap_status_ok + && server_sends_empty_certificate_authorities_list.get_is_valid_data() == true + && server_sends_empty_certificate_authorities_list.get_data_length() == sizeof(u32_t) + && server_sends_empty_certificate_authorities_list.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + server_sends_empty_certificate_authorities_list.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_server_sends_empty_certificate_authorities_list = false; + } + else + { + m_server_sends_empty_certificate_authorities_list = true; + } + } + } + + status = eap_status_ok; + } + + //---------------------------------------------------------- + + if (m_is_client == false) + { + eap_variable_data_c send_piggypacked_eap_identity_request(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_EAP_FAST_send_piggypacked_eap_identity_request.get_field(), + &send_piggypacked_eap_identity_request); + if (status == eap_status_ok + && send_piggypacked_eap_identity_request.get_is_valid_data() == true + && send_piggypacked_eap_identity_request.get_data_length() == sizeof(u32_t) + && send_piggypacked_eap_identity_request.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + send_piggypacked_eap_identity_request.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_send_piggypacked_eap_identity_request = false; + } + else + { + m_send_piggypacked_eap_identity_request = true; + } + } + } + + status = eap_status_ok; + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + { + eap_variable_data_c tls_use_privacy(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_EAP_TLS_PEAP_use_identity_privacy.get_field(), + &tls_use_privacy); + if (status == eap_status_ok + && tls_use_privacy.get_is_valid_data() == true + && tls_use_privacy.get_data_length() == sizeof(u32_t) + && tls_use_privacy.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + tls_use_privacy.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_tls_use_identity_privacy = false; + } + else + { + m_tls_use_identity_privacy = true; + } + } + } + + status = eap_status_ok; + } + + if (m_is_client == false) + { + eap_variable_data_c tls_server_use_privacy(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_EAP_TLS_PEAP_use_identity_privacy_server.get_field(), + &tls_server_use_privacy); + if (status == eap_status_ok + && tls_server_use_privacy.get_is_valid_data() == true + && tls_server_use_privacy.get_data_length() == sizeof(u32_t) + && tls_server_use_privacy.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + tls_server_use_privacy.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_tls_use_identity_privacy = false; + } + else + { + m_tls_use_identity_privacy = true; + } + } + } + + status = eap_status_ok; + } + +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + //---------------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast) + { + // Client and server configuration. + { + eap_variable_data_c provisioning(m_am_tools); + + status = get_type_partner()->read_configure( + cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP.get_field(), + &provisioning); + if (status == eap_status_ok + && provisioning.get_is_valid_data() == true + && provisioning.get_data_length() == sizeof(u32_t) + && provisioning.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + provisioning.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP = false; + } + else + { + m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP = true; + } + } + } + + status = eap_status_ok; + } + + { + eap_variable_data_c allow_server_authenticated_provisioning_mode(m_am_tools); + + status = read_configure( + cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode.get_field(), + &allow_server_authenticated_provisioning_mode); + if (status == eap_status_ok + && allow_server_authenticated_provisioning_mode.get_is_valid_data() == true + && allow_server_authenticated_provisioning_mode.get_data_length() == sizeof(u32_t) + && allow_server_authenticated_provisioning_mode.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + allow_server_authenticated_provisioning_mode.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_fast_allow_server_authenticated_provisioning_mode = false; + } + else + { + m_fast_allow_server_authenticated_provisioning_mode = true; + } + } + } + + status = eap_status_ok; + } + + } +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + //---------------------------------------------------------- + + status = message_hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + //---------------------------------------------------------- + + if (m_application != 0) + { + status = m_application->configure(); + } + else + { + status = eap_status_ok; + } + + //---------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: function: starts: tls_record_c::shutdown():\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::shutdown()"); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + if (m_tls_peap_state != tls_peap_state_tls_success) + { + set_state(tls_peap_state_failure); + } + + eap_status_e status = eap_status_ok; + + if (m_application != 0) + { + status = m_application->shutdown(); + } + + + if (m_pending_query_certificate_authorities_and_types == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_certificate_authorities_and_types()\n"))); + + m_am_tls_services->cancel_query_certificate_authorities_and_types(); + m_pending_query_certificate_authorities_and_types = false; + } + + if (m_pending_query_certificate_chain == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_certificate_chain()\n"))); + + m_am_tls_services->cancel_query_certificate_chain(); + m_pending_query_certificate_chain = false; + } + + if (m_pending_query_cipher_suites_and_previous_session == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_cipher_suites_and_previous_session()\n"))); + + m_am_tls_services->cancel_query_cipher_suites_and_previous_session(); + m_pending_query_cipher_suites_and_previous_session = false; + } + + if (m_pending_query_dh_parameters == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_dh_parameters()\n"))); + + m_am_tls_services->cancel_query_dh_parameters(); + m_pending_query_dh_parameters = false; + } + + if (m_pending_query_realm == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_realm()\n"))); + + m_am_tls_services->cancel_query_realm(); + m_pending_query_realm = false; + } + + if (m_pending_select_cipher_suite_and_check_session_id == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_select_cipher_suite_and_check_session_id()\n"))); + + m_am_tls_services->cancel_select_cipher_suite_and_check_session_id(); + m_pending_select_cipher_suite_and_check_session_id = false; + } + + if (m_pending_verify_certificate_chain == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_verify_certificate_chain()\n"))); + + m_am_tls_services->cancel_verify_certificate_chain(); + m_pending_verify_certificate_chain = false; + } + + if (m_pending_rsa_decrypt_with_private_key == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_rsa_decrypt_with_private_key()\n"))); + + m_am_tls_services->cancel_rsa_decrypt_with_private_key(); + m_pending_rsa_decrypt_with_private_key = false; + } + + if (m_pending_rsa_encrypt_with_public_key == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_rsa_encrypt_with_public_key()\n"))); + + m_am_tls_services->cancel_rsa_encrypt_with_public_key(); + m_pending_rsa_encrypt_with_public_key = false; + } + + if (m_pending_sign_with_private_key == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_sign_with_private_key()\n"))); + + m_am_tls_services->cancel_sign_with_private_key(); + m_pending_sign_with_private_key = false; + } + + if (m_pending_verify_with_public_key == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_verify_with_public_key()\n"))); + + m_am_tls_services->cancel_verify_with_public_key(); + m_pending_verify_with_public_key = false; + } + + if (m_pending_query_tunnel_PAC == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_tunnel_PAC()\n"))); + + if (m_application != 0) + { + m_application->cancel_query_tunnel_PAC(); + } + m_pending_query_tunnel_PAC = false; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::set_nai_realm( + const eap_variable_data_c * const NAI_realm) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_NAI_realm.set_copy_of_buffer(NAI_realm); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void tls_record_c::send_error_notification(const eap_status_e error) +{ + // Notifies the lower level of an authentication error. + + eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error); + + if (error == eap_status_user_cancel_authentication) + { + general_state_variable = eap_general_state_authentication_cancelled; + } + + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + true, + eap_state_notification_eap, + eap_protocol_layer_general, + m_eap_type, + eap_state_none, + general_state_variable, + 0, + false); + + notification.set_authentication_error(error); + + get_type_partner()->state_notification(¬ification); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::completion_action_add( + tls_completion_action_e action) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: completion_action_add()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::completion_action_add()"); + + tls_completion_c *completion_action = new tls_completion_c( + m_am_tools, + action); + + if (completion_action == 0 + || completion_action->get_is_valid() == false) + { + delete completion_action; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // add_object() will delete completion_action if operation fails. + eap_status_e status = m_completion_queue.add_object(completion_action, true); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: completion_action_add(): action %s\n"), + (m_is_client == true ? "client": "server"), + completion_action->get_completion_action_string())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::completion_action_clenup() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: starts: tls_record_c::completion_action_clenup()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::completion_action_clenup()"); + + eap_status_e final_status = eap_status_ok; + u32_t counter = 0ul; + + while(m_completion_queue.get_object_count() > 0ul) + { + tls_completion_c * const completion_action = m_completion_queue.get_object(0ul); + EAP_UNREFERENCED_PARAMETER(completion_action); // Not referenced without trace. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: send_function: completion_action_clenup(): ") + EAPL("action[%u] %s not completed.\n"), + (m_is_client == true ? "client": "server"), + counter, + completion_action->get_completion_action_string())); + + final_status = m_completion_queue.remove_object(0ul); + if (final_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, final_status); + } + + ++counter; + + } // while() + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, final_status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::completion_action_check() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: starts: tls_record_c::completion_action_check()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::completion_action_check()"); + + if (m_already_in_completion_action_check == true) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + // This is recursive call of completion_action_check(). + // This MUST return eap_status_ok. Other return values will skip + // further prosessing of completion action list. + EAP_TRACE_DEBUG( + m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: completion_action_check(): skip recursion\n"), + (m_is_client == true ? "client": "server"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_already_in_completion_action_check = true; + + eap_automatic_simple_value_c restore_already_in_completion_action_check( + m_am_tools, + &m_already_in_completion_action_check, + false); + + eap_status_e status = eap_status_ok; + bool continue_with_next_action = true; + u32_t counter = 0ul; + + while(continue_with_next_action == true + && m_completion_queue.get_object_count() > 0ul) + { + status = eap_status_ok; + + tls_completion_c * const completion_action = m_completion_queue.get_object(0ul); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: completion_action_check(): action[%d] %s\n"), + (m_is_client == true ? "client": "server"), + counter, + completion_action->get_completion_action_string())); + + switch(completion_action->get_completion_action()) + { +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + case tls_completion_action_create_handshake_type_hello_request: + { + // We must send Handshake/HelloRequest message. + eap_status_e status = create_handshake_type_hello_request(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + break; + } +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + case tls_completion_action_query_cipher_suites_and_previous_session: + { + m_allow_message_send = false; + + status = m_am_tls_services->query_cipher_suites_and_previous_session(); + + m_allow_message_send = true; + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_query_cipher_suites_and_previous_session() call. + m_pending_query_cipher_suites_and_previous_session = true; + + // Cannot complete yet. + continue_with_next_action = false; + } + + break; + } + case tls_completion_action_create_handshake_type_client_hello: + { + if (m_pending_query_cipher_suites_and_previous_session == false + && m_proposed_cipher_suites.get_object_count() > 0ul + && m_proposed_compression_methods.get_object_count() > 0ul) + { + // We must send Handshake/ClientHello message. + eap_status_e status = create_handshake_type_client_hello(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_create_handshake_type_server_hello: + { + if (m_pending_select_cipher_suite_and_check_session_id == false + && m_selected_cipher_suite != tls_cipher_suites_none + && m_selected_compression_method != tls_compression_method_none) + { + // We must send Handshake/ServerHello message. + eap_status_e status = create_handshake_type_server_hello( + static_cast(m_selected_cipher_suite), + static_cast(m_selected_compression_method)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_create_handshake_type_certificate: + { + if (m_pending_query_certificate_chain == false + && m_pending_verify_certificate_chain == false) + { + // We must send Handshake/Certificate message. + // NOTE m_own_certificate_chain could be empty. + status = create_handshake_type_certificate(&m_own_certificate_chain); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_create_handshake_type_server_key_exchange: + { + if (m_pending_query_dh_parameters == false) + { + if ((cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + && m_dhe_prime.get_is_valid_data() == true + && m_dhe_group_generator.get_is_valid_data() == true) + { + status = generate_dhe_keys(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + // We must send Handshake/ServerKeyExchange. + status = create_handshake_type_server_key_exchange(); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_create_handshake_type_server_key_exchange() call. + } + else if (status == eap_status_completed_request) + { + // This is already completed by + // complete_create_handshake_type_server_key_exchange() call. + status = eap_status_ok; + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call + // is always completed on success. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_process_general_error); + } + else // All other status values means error, because this + // call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_create_handshake_type_certificate_request: + { + if (m_pending_query_certificate_authorities_and_types == false + && m_own_certificate_types.get_object_count() != 0ul + && (m_own_certificate_authorities.get_object_count() != 0ul + || m_server_sends_empty_certificate_authorities_list == false)) + { + // We must send Handshake/CertificateRequest message. + status = create_handshake_type_certificate_request( + &m_own_certificate_types, + &m_own_certificate_authorities); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_create_handshake_type_server_hello_done: + { + status = create_handshake_type_server_hello_done(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + break; + } + case tls_completion_action_create_handshake_type_certificate_verify: + { + if (m_pending_query_certificate_chain == false + && m_pending_verify_certificate_chain == false + && m_own_certificate_chain.get_object_count() > 0ul) + { + // We must send Handshake/CertificateVerify. + status = create_handshake_type_certificate_verify(); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_create_handshake_type_certificate_verify() call. + } + else if (status == eap_status_completed_request) + { + // This is already completed by + // complete_create_handshake_type_certificate_verify() call. + status = eap_status_ok; + } + else if (status == eap_status_ok) + { + // This is also an error case, because this + // call is always completed on success. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_process_general_error); + } + else // All other status values means error, because this + // call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else if (m_pending_query_certificate_chain == false + && m_pending_verify_certificate_chain == false + && m_own_certificate_chain.get_object_count() == 0ul) + { + // No user certificate. + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_create_handshake_type_client_key_exchange: + { + if (m_pending_query_certificate_chain == false + && m_pending_verify_certificate_chain == false) + { + if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + // DHE parameters should have been received in ServerKeyExchange message. + + if (m_dhe_prime.get_is_valid_data() == true + && m_dhe_group_generator.get_is_valid_data() == true) + { + status = generate_dhe_keys(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_authentication_failure); + } + } + else if (cipher_suite_is_TLS_RSA() == true) + { + // Do nothing special. + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_not_supported); + } + + // We must generate premaster secret. + status = generate_premaster_secret(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + // We must generate master secret. + status = generate_master_secret(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + // We must generate the key material. + status = generate_key_material(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + // We must send Handshake/ClientKeyExchange. + status = create_handshake_type_client_key_exchange(); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_create_handshake_type_client_key_exchange() call. + // Cannot complete yet. + continue_with_next_action = false; + } + else if (status == eap_status_completed_request) + { + // This is already completed by + // complete_create_handshake_type_client_key_exchange() call. + status = eap_status_ok; + } + else if (status == eap_status_ok) + { + // NOTE: This is not always an error case. + if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + // Cipher suites cipher_suite_is_TLS_DHE_DSS() + // and cipher_suite_is_TLS_DHE_RSA() are syncronous. + // Do nothing special. + } + else if (cipher_suite_is_TLS_RSA() == true) + { + // Cipher suites cipher_suite_is_TLS_RSA() are asyncronous + // and they must NOT return eap_status_ok. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_process_general_error); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_not_supported); + } + } + else // All other status values means error, because this + // call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_create_handshake_type_finished: + { + // We must send Handshake/Finished. + status = create_handshake_type_finished(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + break; + } + case tls_completion_action_finish_handshake: + { + // We must finish the handshake. + status = finish_handshake(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + break; + } + case tls_completion_action_create_change_cipher_spec_type_change_cipher_spec: + { + // We must send ChangeCipherSpec/ChangeCipherSpec. + status = create_change_cipher_spec_type_change_cipher_spec(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + break; + } +#if defined(USE_EAP_TLS_SESSION_TICKET) + case tls_completion_action_create_handshake_type_new_session_ticket: + { + // We must send Hanshake/NewSessionTicket. + status = create_handshake_type_new_session_ticket(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + break; + } +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + case tls_completion_action_query_dh_parameters: + { + if (m_selected_cipher_suite != tls_cipher_suites_none) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: query_dh_parameters()\n"), + (m_is_client == true ? "client": "server"))); + // Note, server does not query DH parametrs from certificate chain, + // instead server should consult it's configuration settings. + status = m_am_tls_services->query_dh_parameters(0, m_selected_cipher_suite); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed + // by complete_query_dh_parameters() call. + m_pending_query_dh_parameters = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_query_dh_parameters() call. + status = eap_status_ok; + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call + // is always completed on success. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_process_general_error); + } + else // All other status values means error, because this + // call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_process_tls_records: + { + if (are_pending_queries_completed() == eap_status_ok) + { + status = process_tls_records(); + if (status == eap_status_ok) + { + // All pending messages processed. + // Do nothing special. + } + else if (status == eap_status_end_recursion) + { + // Break recursion. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, eap_status_ok); + } + else if (status == eap_status_pending_request) + { + // Cannot complete yet. + continue_with_next_action = false; + } + else + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + if ((get_is_tunneled_tls() == false + && m_tls_peap_state == tls_peap_state_tls_success) + || (get_is_tunneled_tls() == true + && m_tls_peap_state == tls_peap_state_peap_tunnel_ready)) + { + // TLS authentication OK. + // Note PEAP may continue. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: process_tls_records() returned, ") + EAPL("TLS authentication successfull.\n"), + (m_is_client == true ? "client": "server"))); + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_complete_create_handshake_type_server_key_exchange: + { + if (m_signed_message_hash.get_is_valid_data() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + status = complete_create_handshake_type_server_key_exchange(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_complete_create_handshake_type_certificate_verify: + { + if (m_signed_message_hash.get_is_valid_data() == true + && m_own_certificate_chain.get_object_count() > 0ul) + { + status = complete_create_handshake_type_certificate_verify(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else if (m_own_certificate_chain.get_object_count() == 0ul) + { + // No user certificate. + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_complete_create_handshake_type_client_key_exchange: + { + if (cipher_suite_is_TLS_RSA() == true + && m_own_encrypted_premaster_secret.get_is_valid_data() == true + || ((cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + && m_own_encrypted_premaster_secret.get_is_valid_data() == false)) + { + status = complete_create_handshake_type_client_key_exchange(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_verify_certificate_chain: + { + if (m_peer_certificate_chain.get_object_count() != 0ul + && m_selected_cipher_suite != tls_cipher_suites_none + && m_pending_query_certificate_chain == false + && m_pending_verify_certificate_chain == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: verify_certificate_chain()\n"), + (m_is_client == true ? "client": "server"))); + + status = m_am_tls_services->verify_certificate_chain( + &m_peer_certificate_chain, + m_selected_cipher_suite); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed + // by complete_verify_certificate_chain() call. + m_pending_verify_certificate_chain = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_verify_certificate_chain() call. + status = eap_status_ok; + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is + // always completed on success. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_process_general_error); + } + else // All other status values means error, because this + // call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + // Cannot complete yet. + continue_with_next_action = false; + } + break; + } + case tls_completion_action_check_sent_tls_message: + { + // Note this call will return eap_status_pending_request if any asyncronous call is pending. + status = check_sent_tls_message(); + break; + } + case tls_completion_action_check_tunnel_authentication_runs: + { + // Check we get some tunneled authentication message and tunneled authentication runs or it did finished. + if (m_tunneled_eap_type_authentication_state == eap_state_none) + { + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + m_send_network_id.get_destination_id(), + m_send_network_id.get_source_id(), + m_send_network_id.get_type()); + + status = start_peap_tunneled_authentication( + &receive_network_id, + m_received_eap_identifier, + m_tls_session_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + break; + } + default: + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR TLS: %s: send_function: completion_action_check(): ") + EAPL("unhandled action[%u] %s.\n"), + (m_is_client == true ? "client": "server"), + counter, + completion_action->get_completion_action_string())); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_not_supported); + } + } // switch() + + if (continue_with_next_action == true + || status == eap_status_pending_request) + { + const tls_completion_c * const removed_completion_action = m_completion_queue.get_object(0ul); + EAP_UNREFERENCED_PARAMETER(removed_completion_action); // Not referenced without trace. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: encrypt_function: starts: tls_record_c::completion_action_check(): removes action[%d] %s\n"), + (m_is_client == true ? "client": "server"), + 0ul, + removed_completion_action->get_completion_action_string())); + + eap_status_e remove_status = m_completion_queue.remove_object(0ul); + if (remove_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + + ++counter; + + } // while() + + if (continue_with_next_action == false) + { + status = eap_status_pending_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u8_t tls_record_c::get_extra_padding_length( + const u8_t padding_length, + const u32_t block_size) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: encrypt_function: starts: tls_record_c::get_extra_padding_length()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_extra_padding_length()"); + + crypto_random_c rand(m_am_tools); + + u8_t count = 0ul; + + if (m_use_extra_padding_length == true) + { + eap_status_e status = rand.get_rand_bytes(&count, sizeof(count)); + if (status != eap_status_ok) + { + count = 3ul; + } + } + + u32_t final_padding_length = ((count * block_size) % 0xff) + padding_length; + + count = static_cast((final_padding_length-padding_length) / block_size); + + while (count > 0ul + && (count * block_size)+padding_length > 0xff) + { + --count; + } + + const u8_t final_length = static_cast((count * block_size)+padding_length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: encrypt_function: get_extra_padding_length(): length = %d = 0x%02x\n"), + (m_is_client == true ? "client": "server"), + final_length, + final_length)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return final_length; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_send_block_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer, + abs_crypto_cbc_block_algorithm_c * const encrypt, + abs_crypto_hmac_algorithm_c * const mac) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: starts: tls_record_c::apply_send_block_cipher_suite(): %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_cipher_suite_string(m_send_cipher_suite))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_send_block_cipher_suite()"); + + eap_status_e status = eap_status_process_general_error; + + tls_record_header_c tmp_tls_record_header_on_tls_message_buffer( + m_am_tools, + tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()), + tls_record_message_buffer->get_data_length()); + + if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false + || tls_record_message_buffer->get_data_length() + < tmp_tls_record_header_on_tls_message_buffer.get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_send_mac_key"), + m_send_mac_key.get_data(m_send_mac_key.get_data_length()), + m_send_mac_key.get_data_length())); + + status = mac->hmac_set_key(&m_send_mac_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + if (mac->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + u64_t send_record_sequence_number_network_order = eap_htonll(m_send_record_sequence_number); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_record_sequence_number_network_order"), + &send_record_sequence_number_network_order, + sizeof(send_record_sequence_number_network_order))); + + status = mac->hmac_update( + &send_record_sequence_number_network_order, + sizeof(send_record_sequence_number_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("verified record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + + status = mac->hmac_update( + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c mac_data(m_am_tools); + + status = mac_data.set_buffer_length(mac->get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + mac_data.set_data_length(mac->get_digest_length()); + + u32_t mac_length = mac->get_digest_length(); + + status = mac->hmac_final( + mac_data.get_data(mac_data.get_data_length()), + &mac_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (mac_length != mac->get_digest_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send MAC"), + mac_data.get_data(mac_data.get_data_length()), + mac_data.get_data_length())); + + status = tls_record_message_buffer->add_data(&mac_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // We must get the address of the record header again. A new buffer may be allocated. + tmp_tls_record_header_on_tls_message_buffer.set_header_buffer( + tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()), + tls_record_message_buffer->get_data_length()); + + if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false + || tls_record_message_buffer->get_data_length() + < tmp_tls_record_header_on_tls_message_buffer.get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + tmp_tls_record_header_on_tls_message_buffer.set_data_length( + static_cast( + tmp_tls_record_header_on_tls_message_buffer.get_data_length() + + mac->get_digest_length())); + + + u32_t padded_data_length = encrypt->aligned_data_length( + tmp_tls_record_header_on_tls_message_buffer.get_data_length()); + u8_t padding_length = static_cast( + padded_data_length-tmp_tls_record_header_on_tls_message_buffer.get_data_length()); + + padding_length = get_extra_padding_length(padding_length, encrypt->get_block_size()); + + eap_variable_data_c padding(m_am_tools); + status = padding.set_buffer_length(padding_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + padding.set_data_length(padding_length); + + status = encrypt->add_padding_bytes( + padding.get_data(padding.get_data_length()), + padding.get_data_length(), + static_cast(padding_length-1ul)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_record_message_buffer->add_data(&padding); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // We must get the address of the record header again. A new buffer may be allocated. + tmp_tls_record_header_on_tls_message_buffer.set_header_buffer( + tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()), + tls_record_message_buffer->get_data_length()); + + if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false + || tls_record_message_buffer->get_data_length() + < tmp_tls_record_header_on_tls_message_buffer.get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + tmp_tls_record_header_on_tls_message_buffer.set_data_length( + static_cast( + tmp_tls_record_header_on_tls_message_buffer.get_data_length() + + padding_length)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("plain text record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + + status = encrypt->encrypt_data( + tmp_tls_record_header_on_tls_message_buffer.get_data( + tmp_tls_record_header_on_tls_message_buffer.get_data_length()), + tmp_tls_record_header_on_tls_message_buffer.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("encrypted record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_receive_block_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer, + abs_crypto_cbc_block_algorithm_c * const encrypt, + abs_crypto_hmac_algorithm_c * const mac) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::apply_receive_block_cipher_suite(): %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_receive_block_cipher_suite()"); + + eap_status_e status = eap_status_process_general_error; + + tls_record_header_c tmp_tls_record_header_on_tls_message_buffer( + m_am_tools, + tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()), + tls_record_message_buffer->get_data_length()); + + if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false + || tls_record_message_buffer->get_data_length() + < tmp_tls_record_header_on_tls_message_buffer.get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("encrypted record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + + status = encrypt->decrypt_data( + tmp_tls_record_header_on_tls_message_buffer.get_data( + tmp_tls_record_header_on_tls_message_buffer.get_data_length()), + tmp_tls_record_header_on_tls_message_buffer.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("plain text record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + + // We must get the address of the record header again. A new buffer may be allocated. + tmp_tls_record_header_on_tls_message_buffer.set_header_buffer( + tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()), + tls_record_message_buffer->get_data_length()); + + if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false + || tls_record_message_buffer->get_data_length() + < tmp_tls_record_header_on_tls_message_buffer.get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u32_t padding_length_offset + = tmp_tls_record_header_on_tls_message_buffer.get_data_length() - 1ul; + const u8_t * const p_padding_length + = tmp_tls_record_header_on_tls_message_buffer.get_data_offset(padding_length_offset, + TLS_PADDINF_LENGTH_FIELD_SIZE); + + if (p_padding_length == 0 + || (*p_padding_length)+1ul > tmp_tls_record_header_on_tls_message_buffer.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + u32_t padding_length = (*p_padding_length) + 1ul; + + const u8_t * const p_padding + = tmp_tls_record_header_on_tls_message_buffer.get_data_offset( + tmp_tls_record_header_on_tls_message_buffer.get_data_length() - padding_length, + padding_length); + if (p_padding == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding); + } + + eap_status_e padding_status = encrypt->check_padding_bytes( + p_padding, + *p_padding_length, + *p_padding_length); + if (padding_status != eap_status_ok) + { + // NOTE, padding_status is checked in the end of this function. + // HMAC is checked always. + // We set the padding length to zero, so the end of the message is used as a MAC. + // This will fail anyway. + // This will make some timing attacks more difficult. + padding_length = 0ul; + } + + + + tmp_tls_record_header_on_tls_message_buffer.set_data_length( + static_cast( + tmp_tls_record_header_on_tls_message_buffer.get_data_length() - padding_length)); + + tls_record_message_buffer->set_data_length( + tls_record_message_buffer->get_data_length() + - padding_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // HMAC-XXX authentication. + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_receive_mac_key"), + m_receive_mac_key.get_data(m_receive_mac_key.get_data_length()), + m_receive_mac_key.get_data_length())); + + status = mac->hmac_set_key(&m_receive_mac_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + if (mac->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + if (tls_record_message_buffer->get_data_length() + < (tmp_tls_record_header_on_tls_message_buffer.get_data_length() + + tmp_tls_record_header_on_tls_message_buffer.get_header_length())) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if (tmp_tls_record_header_on_tls_message_buffer.get_data_length() < mac->get_digest_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u32_t start_offset_of_mac + = tmp_tls_record_header_on_tls_message_buffer.get_data_length() + - mac->get_digest_length(); + + const u8_t * const received_mac + = tmp_tls_record_header_on_tls_message_buffer.get_data_offset( + start_offset_of_mac, + mac->get_digest_length()); + if (received_mac == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("received MAC"), + received_mac, + mac->get_digest_length())); + + tmp_tls_record_header_on_tls_message_buffer.set_data_length( + static_cast(tmp_tls_record_header_on_tls_message_buffer.get_data_length() + - mac->get_digest_length())); + + u64_t receive_record_sequence_number_network_order + = eap_htonll(m_receive_record_sequence_number); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("receive_record_sequence_number_network_order"), + &receive_record_sequence_number_network_order, + sizeof(receive_record_sequence_number_network_order))); + + status = mac->hmac_update( + &receive_record_sequence_number_network_order, + sizeof(receive_record_sequence_number_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("verified record"), + tmp_tls_record_header_on_tls_message_buffer.get_header_buffer( + tmp_tls_record_header_on_tls_message_buffer.get_header_length() + + tmp_tls_record_header_on_tls_message_buffer.get_data_length()), + tmp_tls_record_header_on_tls_message_buffer.get_header_length() + + tmp_tls_record_header_on_tls_message_buffer.get_data_length())); + + status = mac->hmac_update( + tmp_tls_record_header_on_tls_message_buffer.get_header_buffer( + tmp_tls_record_header_on_tls_message_buffer.get_header_length() + + tmp_tls_record_header_on_tls_message_buffer.get_data_length()), + tmp_tls_record_header_on_tls_message_buffer.get_header_length() + + tmp_tls_record_header_on_tls_message_buffer.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c mac_data(m_am_tools); + + status = mac_data.set_buffer_length(mac->get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + mac_data.set_data_length(mac->get_digest_length()); + + u32_t mac_length = mac->get_digest_length(); + + status = mac->hmac_final( + mac_data.get_data(mac_data.get_data_length()), + &mac_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (mac_length != mac->get_digest_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("verify MAC"), + mac_data.get_data(mac_data.get_data_length()), + mac_data.get_data_length())); + + if (padding_status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: ERROR: %s: receive_function: apply_receive_cipher_suite(): ") + EAPL("padding failed\n"), + (m_is_client == true ? "client": "server"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, padding_status); + } + else if (m_am_tools->memcmp( + mac_data.get_data(mac_data.get_data_length()), + received_mac, + mac_data.get_data_length()) != 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: ERROR: %s: receive_function: apply_receive_cipher_suite(): MAC failed\n"), + (m_is_client == true ? "client": "server"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + else + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: apply_receive_cipher_suite(): MAC OK\n"), + (m_is_client == true ? "client": "server"))); + } + + tls_record_message_buffer->set_data_length( + tls_record_message_buffer->get_data_length() + - mac->get_digest_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_send_stream_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer, + abs_crypto_stream_algorithm_c * const encrypt, + abs_crypto_hmac_algorithm_c * const mac) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: starts: tls_record_c::apply_send_stream_cipher_suite(): %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_cipher_suite_string(m_send_cipher_suite))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_send_stream_cipher_suite()"); + + eap_status_e status = eap_status_process_general_error; + + tls_record_header_c tmp_tls_record_header_on_tls_message_buffer( + m_am_tools, + tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()), + tls_record_message_buffer->get_data_length()); + + if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false + || tls_record_message_buffer->get_data_length() + < tmp_tls_record_header_on_tls_message_buffer.get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_send_mac_key"), + m_send_mac_key.get_data(m_send_mac_key.get_data_length()), + m_send_mac_key.get_data_length())); + + status = mac->hmac_set_key(&m_send_mac_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + if (mac->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + u64_t send_record_sequence_number_network_order = eap_htonll(m_send_record_sequence_number); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_record_sequence_number_network_order"), + &send_record_sequence_number_network_order, + sizeof(send_record_sequence_number_network_order))); + + status = mac->hmac_update( + &send_record_sequence_number_network_order, + sizeof(send_record_sequence_number_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("verified record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + + status = mac->hmac_update( + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c mac_data(m_am_tools); + + status = mac_data.set_buffer_length(mac->get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + mac_data.set_data_length(mac->get_digest_length()); + + u32_t mac_length = mac->get_digest_length(); + + status = mac->hmac_final( + mac_data.get_data(mac_data.get_data_length()), + &mac_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (mac_length != mac->get_digest_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send MAC"), + mac_data.get_data(mac_data.get_data_length()), + mac_data.get_data_length())); + + status = tls_record_message_buffer->add_data(&mac_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // We must get the address of the record header again. A new buffer may be allocated. + tmp_tls_record_header_on_tls_message_buffer.set_header_buffer( + tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()), + tls_record_message_buffer->get_data_length()); + + if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false + || tls_record_message_buffer->get_data_length() + < tmp_tls_record_header_on_tls_message_buffer.get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + tmp_tls_record_header_on_tls_message_buffer.set_data_length( + static_cast( + tmp_tls_record_header_on_tls_message_buffer.get_data_length() + + mac->get_digest_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("plain text record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + + status = encrypt->encrypt_data( + tmp_tls_record_header_on_tls_message_buffer.get_data( + tmp_tls_record_header_on_tls_message_buffer.get_data_length()), + tmp_tls_record_header_on_tls_message_buffer.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("encrypted record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_receive_stream_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer, + abs_crypto_stream_algorithm_c * const encrypt, + abs_crypto_hmac_algorithm_c * const mac) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::apply_receive_block_cipher_suite(): %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_receive_stream_cipher_suite()"); + + eap_status_e status = eap_status_process_general_error; + + tls_record_header_c tmp_tls_record_header_on_tls_message_buffer( + m_am_tools, + tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()), + tls_record_message_buffer->get_data_length()); + + if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false + || tls_record_message_buffer->get_data_length() + < tmp_tls_record_header_on_tls_message_buffer.get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("encrypted record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + + status = encrypt->decrypt_data( + tmp_tls_record_header_on_tls_message_buffer.get_data( + tmp_tls_record_header_on_tls_message_buffer.get_data_length()), + tmp_tls_record_header_on_tls_message_buffer.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("plain text record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + + tls_record_message_buffer->set_data_length( + tls_record_message_buffer->get_data_length()); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // HMAC-SHA1 authentication. + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_receive_mac_key"), + m_receive_mac_key.get_data(m_receive_mac_key.get_data_length()), + m_receive_mac_key.get_data_length())); + + status = mac->hmac_set_key(&m_receive_mac_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + if (mac->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + if (tls_record_message_buffer->get_data_length() + < (tmp_tls_record_header_on_tls_message_buffer.get_data_length() + + tmp_tls_record_header_on_tls_message_buffer.get_header_length())) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if (tmp_tls_record_header_on_tls_message_buffer.get_data_length() < mac->get_digest_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u32_t start_offset_of_mac + = tmp_tls_record_header_on_tls_message_buffer.get_data_length() + - mac->get_digest_length(); + + const u8_t * const received_mac + = tmp_tls_record_header_on_tls_message_buffer.get_data_offset( + start_offset_of_mac, + mac->get_digest_length()); + if (received_mac == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("received MAC"), + received_mac, + mac->get_digest_length())); + + tmp_tls_record_header_on_tls_message_buffer.set_data_length( + static_cast(tmp_tls_record_header_on_tls_message_buffer.get_data_length() + - mac->get_digest_length())); + + u64_t receive_record_sequence_number_network_order + = eap_htonll(m_receive_record_sequence_number); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("receive_record_sequence_number_network_order"), + &receive_record_sequence_number_network_order, + sizeof(receive_record_sequence_number_network_order))); + + status = mac->hmac_update( + &receive_record_sequence_number_network_order, + sizeof(receive_record_sequence_number_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("verified record"), + tmp_tls_record_header_on_tls_message_buffer.get_header_buffer( + tmp_tls_record_header_on_tls_message_buffer.get_header_length() + + tmp_tls_record_header_on_tls_message_buffer.get_data_length()), + tmp_tls_record_header_on_tls_message_buffer.get_header_length() + + tmp_tls_record_header_on_tls_message_buffer.get_data_length())); + + status = mac->hmac_update( + tmp_tls_record_header_on_tls_message_buffer.get_header_buffer( + tmp_tls_record_header_on_tls_message_buffer.get_header_length() + + tmp_tls_record_header_on_tls_message_buffer.get_data_length()), + tmp_tls_record_header_on_tls_message_buffer.get_header_length() + + tmp_tls_record_header_on_tls_message_buffer.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c mac_data(m_am_tools); + + status = mac_data.set_buffer_length(mac->get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + mac_data.set_data_length(mac->get_digest_length()); + + u32_t mac_length = mac->get_digest_length(); + + status = mac->hmac_final( + mac_data.get_data(mac_data.get_data_length()), + &mac_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (mac_length != mac->get_digest_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("verify MAC"), + mac_data.get_data(mac_data.get_data_length()), + mac_data.get_data_length())); + + if (m_am_tools->memcmp( + mac_data.get_data(mac_data.get_data_length()), + received_mac, mac_data.get_data_length()) != 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: apply_receive_cipher_suite(): MAC failed\n"), + (m_is_client == true ? "client": "server"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + else + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: apply_receive_cipher_suite(): MAC OK\n"), + (m_is_client == true ? "client": "server"))); + } + + tls_record_message_buffer->set_data_length( + tls_record_message_buffer->get_data_length() + - mac->get_digest_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_send_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: starts: tls_record_c::apply_send_cipher_suite(): %d=%s\n"), + (m_is_client == true ? "client": "server"), + m_send_cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(m_send_cipher_suite))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_send_cipher_suite()"); + + eap_status_e status = eap_status_process_general_error; + + tls_record_header_c tmp_tls_record_header_on_tls_message_buffer( + m_am_tools, + tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()), + tls_record_message_buffer->get_data_length()); + + if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false + || tls_record_message_buffer->get_data_length() + < tmp_tls_record_header_on_tls_message_buffer.get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if (m_send_cipher_suite != tls_cipher_suites_TLS_NULL_WITH_NULL_NULL) + { + EAP_TRACE_DATA_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("plaintext TLS-record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * @{ Add compression of data. Well this will be optional very long time. } + */ + if (m_send_compression_method == tls_compression_method_null) + { + // No compression. + status = eap_status_ok; + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_send_cipher_suite == tls_cipher_suites_TLS_NULL_WITH_NULL_NULL) + { + // No authentication. + // No encryption. + + u64_t send_record_sequence_number_network_order = eap_htonll(m_send_record_sequence_number); + EAP_UNREFERENCED_PARAMETER(send_record_sequence_number_network_order); // in release + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_record_sequence_number_network_order"), + &send_record_sequence_number_network_order, + sizeof(send_record_sequence_number_network_order))); + + status = eap_status_ok; + } + else if (cipher_suite_is_3DES_EDE_CBC_SHA(m_send_cipher_suite) == true + || cipher_suite_is_AES_128_CBC_SHA(m_send_cipher_suite) == true) + { + EAP_ASSERT_TOOLS(m_am_tools, m_send_block_cipher != 0); + EAP_ASSERT_TOOLS(m_am_tools, m_send_hmac_algorithm != 0); + + status = apply_send_block_cipher_suite( + tls_record_message_buffer, + m_send_block_cipher, + m_send_hmac_algorithm); + } + else if (cipher_suite_is_RC4_128_MD5(m_send_cipher_suite) == true + || cipher_suite_is_RC4_128_SHA(m_send_cipher_suite) == true) + { + EAP_ASSERT_TOOLS(m_am_tools, m_send_stream_cipher != 0); + EAP_ASSERT_TOOLS(m_am_tools, m_send_hmac_algorithm != 0); + + status = apply_send_stream_cipher_suite( + tls_record_message_buffer, + m_send_stream_cipher, + m_send_hmac_algorithm); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_send_cipher_suite != tls_cipher_suites_TLS_NULL_WITH_NULL_NULL) + { + m_send_record_sequence_number = m_send_record_sequence_number + 1ul; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_receive_cipher_suite( + eap_variable_data_c * const tls_record_message_buffer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::apply_receive_cipher_suite(): %d=%s\n"), + (m_is_client == true ? "client": "server"), + m_receive_cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_receive_cipher_suite()"); + + eap_status_e status = eap_status_process_general_error; + + tls_record_header_c tmp_tls_record_header_on_tls_message_buffer( + m_am_tools, + tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()), + tls_record_message_buffer->get_data_length()); + + if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false + || tls_record_message_buffer->get_data_length() + < tmp_tls_record_header_on_tls_message_buffer.get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_receive_cipher_suite == tls_cipher_suites_TLS_NULL_WITH_NULL_NULL) + { + // No decryption. + // No authentication. + + u64_t receive_record_sequence_number_network_order + = eap_htonll(m_receive_record_sequence_number); + EAP_UNREFERENCED_PARAMETER(receive_record_sequence_number_network_order); // in release + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("receive_record_sequence_number_network_order"), + &receive_record_sequence_number_network_order, + sizeof(receive_record_sequence_number_network_order))); + + status = eap_status_ok; + } + else if (cipher_suite_is_3DES_EDE_CBC_SHA(m_receive_cipher_suite) == true + || cipher_suite_is_AES_128_CBC_SHA(m_receive_cipher_suite) == true) + { + status = apply_receive_block_cipher_suite( + tls_record_message_buffer, + m_receive_block_cipher, + m_receive_hmac_algorithm); + } + else if (cipher_suite_is_RC4_128_MD5(m_receive_cipher_suite) == true + || cipher_suite_is_RC4_128_SHA(m_receive_cipher_suite) == true) + { + status = apply_receive_stream_cipher_suite( + tls_record_message_buffer, + m_receive_stream_cipher, + m_receive_hmac_algorithm); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + + if (m_receive_cipher_suite != tls_cipher_suites_TLS_NULL_WITH_NULL_NULL) + { + EAP_TRACE_DATA_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("decrypted TLS-record"), + tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()), + tls_record_message_buffer->get_data_length())); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * @{ Add de-compression of data. Well this will be optional very long time. } + */ + if (m_send_compression_method == tls_compression_method_null) + { + // No de-compression. + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_receive_cipher_suite != tls_cipher_suites_TLS_NULL_WITH_NULL_NULL) + { + m_receive_record_sequence_number = m_receive_record_sequence_number + 1ul; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::packet_send( + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t /*data_length*/, + const u32_t /*buffer_length*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::packet_send(): %d=%s\n"), + (m_is_client == true ? "client": "server"), + m_receive_cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::packet_send()"); + + eap_status_e status = create_tls_application_data( + sent_packet, + header_offset); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT u32_t tls_record_c::get_header_offset( + u32_t * const MTU_length, + u32_t * const trailer_length) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::get_header_offset()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_header_offset()"); + + if (m_eap_type == eap_type_peap + && m_peap_version == peap_version_0_xp) + { + // PEAPv0 cannot use long tunneled EAP-packets, + // bacause of the inner EAP-packets does not + // have own EAP-header. Long inner EAP-packets will be + // fragmented in outer PEAPv0 application data and that will cause + // wrong EAP-identifier values after reassembly. + u32_t offset = get_type_partner()->get_header_offset( + MTU_length, + trailer_length); + + // Here we try set MTU such the inner EAP-packets does not need fragmentation. + *MTU_length -= (offset + + 4ul*(tls_record_header_c::get_header_length() + + tls_handshake_header_c::get_header_length())); + *trailer_length = 0ul; + + return 0ul; + } + else + { + *MTU_length = EAP_TLS_PEAP_MAX_MESSAGE_LENGTH; + *trailer_length = 0ul; + + return 0ul; + } +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return get_type_partner()->read_configure( + field, + data); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return get_type_partner()->write_configure( + field, + data); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT void tls_record_c::state_notification( + const abs_eap_state_notification_c * const state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("this = 0x%08x, %s: starts: tls_record_c::state_notification(): EAP-type 0x%08x: m_tls_session_type=%d=%s, tls_state=%d=%s, notification state=%s\n"), + this, + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_eap_type), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_state_notification_c::get_state_string(state->get_protocol_layer(), state->get_current_state()))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::state_notification()"); + + if (state->get_protocol_layer() == eap_protocol_layer_general) + { + if (state->get_current_state() == eap_general_state_authentication_cancelled) + { + // Tunneled EAP-type terminated unsuccessfully. + m_tunneled_eap_type_authentication_state + = static_cast(state->get_current_state()); + set_state(tls_peap_state_failure); + } + } + else if (state->get_protocol_layer() == eap_protocol_layer_eap) + { + if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + || state->get_current_state() == eap_state_authentication_terminated_unsuccessfully_peapv1_extension +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + ) + { + // Tunneled EAP-type terminated unsuccessfully. + m_tunneled_eap_type_authentication_state + = static_cast(state->get_current_state()); + set_state(tls_peap_state_failure); + + // Because we process aplication data, we do not send alert messages anymore. + m_could_send_fatal_alert_message = false; + m_could_send_warning_alert_message = false; + } + else if (state->get_current_state() + == eap_state_authentication_finished_successfully + || state->get_current_state() + == eap_state_tppd_peapv1_authentication_finished_successfully_with_tunneled_eap_success +#if defined(USE_EAP_PEAPV1_EXTENSIONS) + || state->get_current_state() + == eap_state_authentication_finished_successfully_peapv1_extension +#endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS) + ) + { + // Tunneled EAP-type finished successfully. + + if ((m_eap_type == eap_type_peap + && m_peap_version >= peap_version_0_xp + && m_peap_version <= peap_version_2) + || m_eap_type == eap_type_ttls +#if defined(USE_FAST_EAP_TYPE) + || m_eap_type == eap_type_fast +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + eap_status_e status = get_type_partner()->set_tls_master_secret( + &m_eap_master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (m_eap_type == eap_type_ttls + || m_eap_type == eap_type_peap +#if defined(USE_FAST_EAP_TYPE) + || m_eap_type == eap_type_fast +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + + tls_identity_privacy_handshake_state_e tmp_identity_privacy_handshake_state = +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + m_tls_identity_privacy_handshake_state; +#else + tls_identity_privacy_handshake_state_none; +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + EAP_UNREFERENCED_PARAMETER(tmp_identity_privacy_handshake_state); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: state_notification(): TLS/PEAP authentication ") + EAPL("SUCCESS: %s, %s, tunnel %d, tunneling type %s, tunneling version %s, cipher_suite %s, %s\n"), + (m_is_client == true ? "client": "server"), + (m_tls_peap_server_authenticates_client_action == true + ? "mutual": "anonymous client"), + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + get_is_tunneled_tls(), + eap_header_string_c::get_eap_type_string(m_eap_type), + eap_tls_trace_string_c::get_peap_version_string(m_peap_version), + eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite), + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state))); + + eap_status_e save_status = m_am_tls_services->save_tls_session( + &m_session_id, + &m_master_secret, + m_selected_cipher_suite +#if defined(USE_EAP_TLS_SESSION_TICKET) + , tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + &m_received_tls_extensions, + m_am_tools) +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + ); + if (save_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, save_status); + } + } + + } + + m_tunneled_eap_type_authentication_state + = static_cast(state->get_current_state()); + set_state(tls_peap_state_tls_success); + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_eap_type == eap_type_fast + && state->get_current_state() == eap_state_inner_eap_method_skipped) + { + m_tunneled_eap_type_authentication_state + = static_cast(state->get_current_state()); + } + else if (m_is_client == false + && m_eap_type == eap_type_fast + && state->get_current_state() == eap_state_authentication_wait_eap_fast_empty_acknowledge) + { + set_state(tls_peap_state_wait_tunneled_authentication_start); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + } + else if (state->get_protocol_layer() == eap_protocol_layer_internal_type) + { + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + if (state->get_current_state() == tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: tls_record_c::state_notification(): ") + EAPL("waits TTLS/plain MsChapv2 empty Ack: EAP-type 0x%08x\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(m_eap_type))); + } +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + + } + + get_type_partner()->state_notification( + state); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (get_type_partner() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return get_type_partner()->set_timer( + initializer, + id, + data, + p_time_ms); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (get_type_partner() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return get_type_partner()->cancel_timer( + initializer, + id); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (get_type_partner() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return get_type_partner()->cancel_all_timers(); +} + +//-------------------------------------------------- + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->load_module( + type, + tunneling_type, + partner, + eap_type, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->unload_module(type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->restart_authentication( + receive_network_id, + is_client_when_true, + force_clean_restart, + from_timer); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::packet_data_crypto_keys( + const eap_am_network_id_c * const /* send_network_id */, + const eap_master_session_key_c * const master_session_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::packet_data_crypto_keys()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::packet_data_crypto_keys()"); + + if ((m_eap_type == eap_type_peap + && (m_peap_version == peap_version_0_xp + || m_peap_version == peap_version_1)) + || m_eap_type == eap_type_ttls) + { + // We do not forward keys to lower layer. + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_eap_type == eap_type_fast) + { + eap_status_e status = m_eap_master_session_key.set_copy_of_buffer( + master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // NOTE: state_notification() will deliver master_session_key to lower layers. + } +#endif //#if defined(USE_FAST_EAP_TYPE) + else if (m_eap_type == eap_type_peap + && m_peap_version == peap_version_2) + { + eap_status_e status = m_eap_master_session_key.set_copy_of_buffer( + master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_type_partner()->set_tls_master_secret(&m_eap_master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::check_is_valid_eap_type( + const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->check_is_valid_eap_type(eap_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +// This is commented in abs_tls_base_application_c. +EAP_FUNC_EXPORT eap_status_e tls_record_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->get_eap_type_list(eap_type_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::start_tls_peap_authentication( + const eap_variable_data_c * const received_authority_identity_payload + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::start_tls_peap_authentication()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::start_tls_peap_authentication()"); + + eap_status_e status = completion_action_add(tls_completion_action_query_cipher_suites_and_previous_session); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(tls_peap_state_wait_handshake_type_server_hello); + + status = completion_action_add(tls_completion_action_create_handshake_type_client_hello); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast) + { + if (m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true) + { + set_tls_session_type(tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP); + } + else if (received_authority_identity_payload != 0 + && received_authority_identity_payload->get_is_valid_data() == true) + { + eap_fast_variable_data_c in_A_ID_TLV(m_am_tools); + + status = in_A_ID_TLV.set_copy_of_buffer( + received_authority_identity_payload->get_data(), + received_authority_identity_payload->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_application->query_tunnel_PAC( + &in_A_ID_TLV); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_query_tunnel_PAC() call. + m_pending_query_tunnel_PAC = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_query_PACs() call. + + status = check_sent_tls_message(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + } +#else + EAP_UNREFERENCED_PARAMETER(received_authority_identity_payload); +#endif //#if defined(USE_FAST_EAP_TYPE) + + + status = check_sent_tls_message(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::start_peap_tunneled_authentication( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier, + const tls_session_type_e tls_session_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::start_peap_tunneled_authentication()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::start_peap_tunneled_authentication()"); + + if (m_is_client == true + && verify_state(tls_peap_state_peap_tunnel_ready) == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string(tls_peap_state_peap_tunnel_ready))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + else if (m_is_client == false + && verify_state(tls_peap_state_wait_tunneled_authentication_start) == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string(tls_peap_state_wait_tunneled_authentication_start))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + + set_state(tls_peap_state_wait_application_data); + + eap_status_e status = eap_status_process_general_error; + + { + // This must be inside a block. Automatic variable must be restored after + // the start_peap_tunneled_authentication() function call. + eap_automatic_simple_value_c restore_allow_message_send( + m_am_tools, + &m_allow_message_send, + m_allow_message_send); + + // Packet send is delayed until after the + // m_application->start_peap_tunneled_authentication() function returns. + m_allow_message_send = false; + + status = m_application->start_peap_tunneled_authentication( + receive_network_id, + m_is_client, + received_eap_identifier, + tls_session_type, + m_tls_peap_server_authenticates_client_action); + } + + + { + // Note this call will return eap_status_pending_request + // if any asyncronous call is pending. + eap_status_e send_status = check_sent_tls_message(); + if (send_status != eap_status_ok) + { + status = send_status; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::allocate_handshake_message_copy( + tls_handshake_message_c ** const tls_handshake_message, + eap_automatic_variable_c * const automatic_tls_handshake_message, + tls_handshake_header_c * const tls_handshake_header) +{ + *tls_handshake_message + = new tls_handshake_message_c(m_am_tools, this, m_is_client); + + automatic_tls_handshake_message->set_variable(*tls_handshake_message); + + if (*tls_handshake_message == 0 + || (*tls_handshake_message)->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = (*tls_handshake_message)->set_handshake_header_copy( + tls_handshake_header); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_tls_extension_list( + const u32_t handshake_data_length, + u32_t * const data_offset, + const tls_handshake_header_c * const tls_handshake_header, + tls_handshake_message_c * const tls_handshake_message +) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::parse_tls_extension_list()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_tls_extension_list()"); + + eap_status_e status(eap_status_ok); + + // This is optional field. + if ((*data_offset)+TLS_EXTENSIONS_LENGTH_FIELD_SIZE <= handshake_data_length) + { + // Extension list is formatted as: + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | extension list length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | extension 1 type | extension 1 data length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | extension 1 data ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | extension 2 type | extension 2 data length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | extension 2 data ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + u8_t *p_extension_list = tls_handshake_header->get_data_offset( + (*data_offset), + TLS_EXTENSIONS_LENGTH_FIELD_SIZE); + if (p_extension_list == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + (*data_offset) += TLS_EXTENSIONS_LENGTH_FIELD_SIZE; + + u32_t extension_list_length( + eap_read_u16_t_network_order( + p_extension_list, + TLS_EXTENSIONS_LENGTH_FIELD_SIZE)); + + if ((*data_offset)+extension_list_length > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + const u32_t offset_end((*data_offset)+extension_list_length); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS-handshake extension payload"), + p_extension_list, + TLS_EXTENSIONS_LENGTH_FIELD_SIZE+extension_list_length)); + + if (extension_list_length > 0ul) + { + eap_array_c extensions_array(m_am_tools); + + while((*data_offset) < offset_end) + { + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if ((*data_offset)+TLS_EXTENSION_TYPE_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_extension_type = tls_handshake_header->get_data_offset( + (*data_offset), + TLS_EXTENSION_TYPE_FIELD_SIZE); + if (p_extension_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + (*data_offset) += TLS_EXTENSION_TYPE_FIELD_SIZE; + + u16_t extension_type_host( + eap_read_u16_t_network_order( + p_extension_type, + TLS_EXTENSIONS_LENGTH_FIELD_SIZE)); + + tls_extension_type_e extension_type(static_cast(extension_type_host)); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if ((*data_offset)+TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_extension_data_length = tls_handshake_header->get_data_offset( + (*data_offset), + TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE); + if (p_extension_data_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + (*data_offset) += TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE; + + u16_t extension_data_length_host( + eap_read_u16_t_network_order( + p_extension_data_length, + TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE)); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + tls_extension_c * const tls_extension = new tls_extension_c(m_am_tools); + + eap_automatic_variable_c + automatic_tls_extension(m_am_tools, tls_extension); + + if (tls_extension == 0 + || tls_extension->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + tls_extension->set_type(extension_type); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (extension_data_length_host > 0ul) + { + if ((*data_offset)+extension_data_length_host > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + const u8_t * const p_extension_data = tls_handshake_header->get_data_offset( + (*data_offset), + extension_data_length_host); + if (p_extension_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = tls_extension->set_copy_of_buffer(p_extension_data, extension_data_length_host); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + (*data_offset) += extension_data_length_host; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + automatic_tls_extension.do_not_free_variable(); + + // add_object() will delete extension if operation fails. + status = extensions_array.add_object(tls_extension, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } // while() + + status = tls_handshake_message->set_tls_extensions(&extensions_array); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_hello_request( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_hello_request()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_hello_request()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message_copy( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (handshake_data_length != 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + if (status == eap_status_ok) + { + // Note the add_handshake_message() frees message in any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = received_tls_record_message->add_handshake_message(tls_handshake_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_client_hello( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_client_hello()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_client_hello()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message_copy( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t data_offset = 0ul; + u8_t * const handshake_data = tls_handshake_header->get_data_offset( + data_offset, + tls_handshake_header->get_data_length()); + if (handshake_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_VERSION_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_version = handshake_data; + u16_t version = eap_read_u16_t_network_order(p_version, TLS_VERSION_FIELD_SIZE); + + if (version != tls_version_3_1) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + data_offset += TLS_VERSION_FIELD_SIZE; + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_HANDSHAKE_RANDOM_VALUE_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_random_value = tls_handshake_header->get_data_offset( + data_offset, + TLS_HANDSHAKE_RANDOM_VALUE_SIZE); + if (p_random_value == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + eap_variable_data_c client_random_value(m_am_tools); + status = client_random_value.set_buffer( + p_random_value, + TLS_HANDSHAKE_RANDOM_VALUE_SIZE, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_random_value(&client_random_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += TLS_HANDSHAKE_RANDOM_VALUE_SIZE; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: parse_handshake_type_client_hello(): m_client_random_value"), + client_random_value.get_data(client_random_value.get_data_length()), + client_random_value.get_data_length())); + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_SESSION_ID_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_session_id_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_SESSION_ID_LENGTH_FIELD_SIZE); + if (p_session_id_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + data_offset += TLS_SESSION_ID_LENGTH_FIELD_SIZE; + + if (data_offset+*p_session_id_length > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if (*p_session_id_length > 0ul) + { + u8_t *p_session_id = tls_handshake_header->get_data_offset( + data_offset, + *p_session_id_length); + if (p_session_id == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_variable_data_c session_id(m_am_tools); + status = session_id.set_buffer(p_session_id, *p_session_id_length, false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_session_id(&session_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + data_offset += *p_session_id_length; + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_CIPHER_SUITE_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_cipher_suite_length_network_order = tls_handshake_header->get_data_offset( + data_offset, + TLS_CIPHER_SUITE_LENGTH_FIELD_SIZE); + if (p_cipher_suite_length_network_order == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + u16_t cipher_suite_length = eap_read_u16_t_network_order( + p_cipher_suite_length_network_order, + TLS_CIPHER_SUITE_LENGTH_FIELD_SIZE); + data_offset += TLS_CIPHER_SUITE_LENGTH_FIELD_SIZE; + + if (data_offset+cipher_suite_length > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if ((cipher_suite_length % 2) != 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (cipher_suite_length > 0ul) + { + u8_t *p_cipher_suite = tls_handshake_header->get_data_offset( + data_offset, + cipher_suite_length); + if (p_cipher_suite == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_array_c cipher_suites_array(m_am_tools); + + for (u32_t ind = 0ul; ind < cipher_suite_length; ind += 2ul) + { + u16_t * const cipher_suite = new u16_t; + if (cipher_suite == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u16_t cipher_suite_host_order = eap_read_u16_t_network_order( + p_cipher_suite, + TLS_CIPHER_SUITE_FIELD_SIZE); + *cipher_suite = cipher_suite_host_order; + + // add_object() will delete cipher_suite if operation fails. + status = cipher_suites_array.add_object(cipher_suite, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + p_cipher_suite += TLS_CIPHER_SUITE_FIELD_SIZE; + } // for() + + status = tls_handshake_message->set_cipher_suites(&cipher_suites_array); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + data_offset += cipher_suite_length; + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_COMPRESSION_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_compression_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_COMPRESSION_LENGTH_FIELD_SIZE); + if (p_compression_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + data_offset += TLS_COMPRESSION_LENGTH_FIELD_SIZE; + + if (data_offset+*p_compression_length > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if (*p_compression_length > 0ul) + { + u8_t *p_compression = tls_handshake_header->get_data_offset( + data_offset, + *p_compression_length); + if (p_compression == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_array_c compression_array(m_am_tools); + + for (u32_t ind = 0ul; ind < *p_compression_length; ind++) + { + u8_t * const compression_value = new u8_t; + if (compression_value == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *compression_value = *p_compression; + + // add_object() will delete compression_value if operation fails. + status = compression_array.add_object(compression_value, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + p_compression += TLS_COMPRESSION_FIELD_SIZE; + } // for() + + status = tls_handshake_message->set_compression_methods(&compression_array); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + data_offset += *p_compression_length; + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + + status = parse_tls_extension_list( + handshake_data_length, + &data_offset, + tls_handshake_header, + tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + //---------------------------------------------------------- + + if (status == eap_status_ok) + { + // Note the add_handshake_message() frees message in any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = received_tls_record_message->add_handshake_message(tls_handshake_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message_hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_certificate( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_certificate()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_certificate()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message_copy( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t data_offset = 0ul; + + //---------------------------------------------------------- + + { + if (data_offset+(TLS_CERTIFICATE_LENGTH_FIELD_SIZE) > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_certificate_chain_length = tls_handshake_header->get_data_offset( + data_offset, + (TLS_CERTIFICATE_LENGTH_FIELD_SIZE)); + if (p_certificate_chain_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u32_t certificate_chain_length = + eap_read_u24_t_network_order( + p_certificate_chain_length, + TLS_CERTIFICATE_LENGTH_FIELD_SIZE); + + data_offset += (TLS_CERTIFICATE_LENGTH_FIELD_SIZE); + + if (certificate_chain_length > 0ul) + { + eap_array_c certificate_chain(m_am_tools); + u32_t max_data_offset = data_offset + certificate_chain_length; + + for (;data_offset < max_data_offset;) + { + u8_t *p_certificate_length = tls_handshake_header->get_data_offset( + data_offset, + (TLS_CERTIFICATE_LENGTH_FIELD_SIZE)); + if (p_certificate_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u32_t certificate_length = + eap_read_u24_t_network_order( + p_certificate_length, + TLS_CERTIFICATE_LENGTH_FIELD_SIZE); + + data_offset += (TLS_CERTIFICATE_LENGTH_FIELD_SIZE); + + + eap_variable_data_c * const certificate = new eap_variable_data_c(m_am_tools); + + eap_automatic_variable_c + automatic_certificate(m_am_tools, certificate); + + if (certificate == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + u8_t *p_certificate = tls_handshake_header->get_data_offset( + data_offset, + certificate_length); + if (p_certificate == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = certificate->set_copy_of_buffer(p_certificate, certificate_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + automatic_certificate.do_not_free_variable(); + + // add_object() will delete certificate if operation fails. + status = certificate_chain.add_object(certificate, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += certificate_length; + } // for() + + status = tls_handshake_message->set_certificate_chain(&certificate_chain); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + data_offset += certificate_chain_length; + } + + //---------------------------------------------------------- + + if (status == eap_status_ok) + { + // Note the add_handshake_message() frees message in any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = received_tls_record_message->add_handshake_message(tls_handshake_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_certificate_request( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_certificate_request()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_certificate_request()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message_copy( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t data_offset = 0ul; + + //---------------------------------------------------------- + + { + if (data_offset+TLS_CERTIFICATE_TYPE_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_certificate_type_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_CERTIFICATE_TYPE_LENGTH_FIELD_SIZE); + if (p_certificate_type_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + data_offset += TLS_CERTIFICATE_TYPE_LENGTH_FIELD_SIZE; + + if (data_offset+*p_certificate_type_length > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if (*p_certificate_type_length > 0ul) + { + u8_t *p_certificate_type = tls_handshake_header->get_data_offset( + data_offset, + *p_certificate_type_length); + if (p_certificate_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_array_c certificate_type_array(m_am_tools); + + for (u32_t ind = 0ul; ind < *p_certificate_type_length; ind++) + { + u8_t * const certificate_type_value = new u8_t; + if (certificate_type_value == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *certificate_type_value = *p_certificate_type; + + // add_object() will delete certificate_type_value if operation fails. + status = certificate_type_array.add_object(certificate_type_value, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + p_certificate_type += TLS_CERTIFICATE_TYPE_FIELD_SIZE; + } // for() + + status = tls_handshake_message->set_certificate_types(&certificate_type_array); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + data_offset += *p_certificate_type_length; + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_certificate_authorities_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE); + if (p_certificate_authorities_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u32_t certificate_authorities_length = + eap_read_u16_t_network_order( + p_certificate_authorities_length, + TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE); + + data_offset += TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE; + + if (certificate_authorities_length > 0ul) + { + eap_array_c certificate_authorities(m_am_tools); + u32_t max_data_offset = data_offset + certificate_authorities_length; + + for (;data_offset < max_data_offset;) + { + u8_t *p_certificate_authority_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE); + if (p_certificate_authority_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u32_t certificate_authority_length = + eap_read_u16_t_network_order( + p_certificate_authority_length, + TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE); + + data_offset += TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE; + + { + eap_variable_data_c * const certificate_authority + = new eap_variable_data_c(m_am_tools); + + eap_automatic_variable_c + automatic_certificate_authority(m_am_tools, certificate_authority); + + if (certificate_authority == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + u8_t *p_certificate_authority = tls_handshake_header->get_data_offset( + data_offset, + certificate_authority_length); + if (p_certificate_authority == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = certificate_authority->set_copy_of_buffer( + p_certificate_authority, + certificate_authority_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + automatic_certificate_authority.do_not_free_variable(); + + // add_object() will delete certificate_authority if operation fails. + status = certificate_authorities.add_object(certificate_authority, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + data_offset += certificate_authority_length; + } // for() + + status = tls_handshake_message->set_certificate_authorities(&certificate_authorities); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + data_offset += certificate_authorities_length; + } + + //---------------------------------------------------------- + + if (status == eap_status_ok) + { + // Note the add_handshake_message() frees message in any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = received_tls_record_message->add_handshake_message(tls_handshake_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_server_hello_done( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t /* handshake_data_length */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_server_hello_done()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_server_hello_done()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message_copy( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (tls_handshake_header->get_data_length() > 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + //---------------------------------------------------------- + + if (status == eap_status_ok) + { + // Note the add_handshake_message() frees message in any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = received_tls_record_message->add_handshake_message(tls_handshake_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_server_hello( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_server_hello()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_server_hello()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message_copy( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t data_offset = 0ul; + + u8_t * handshake_data = tls_handshake_header->get_data_offset( + data_offset, + tls_handshake_header->get_data_length()); + if (handshake_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_VERSION_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_version = handshake_data; + u16_t version = eap_read_u16_t_network_order(p_version, TLS_VERSION_FIELD_SIZE); + + if (version != tls_version_3_1) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + data_offset += TLS_VERSION_FIELD_SIZE; + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_HANDSHAKE_RANDOM_VALUE_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_random_value = tls_handshake_header->get_data_offset( + data_offset, + TLS_HANDSHAKE_RANDOM_VALUE_SIZE); + if (p_random_value == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + eap_variable_data_c server_random_value(m_am_tools); + status = server_random_value.set_buffer( + p_random_value, + TLS_HANDSHAKE_RANDOM_VALUE_SIZE, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_random_value(&server_random_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += TLS_HANDSHAKE_RANDOM_VALUE_SIZE; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: parse_handshake_type_server_hello(): m_server_random_value"), + server_random_value.get_data(server_random_value.get_data_length()), + server_random_value.get_data_length())); + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_SESSION_ID_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_session_id_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_SESSION_ID_LENGTH_FIELD_SIZE); + if (p_session_id_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + data_offset += TLS_SESSION_ID_LENGTH_FIELD_SIZE; + + if (data_offset+*p_session_id_length > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + if (*p_session_id_length > 0ul) + { + u8_t *p_session_id = tls_handshake_header->get_data_offset( + data_offset, + *p_session_id_length); + if (p_session_id == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_variable_data_c session_id(m_am_tools); + status = session_id.set_buffer(p_session_id, *p_session_id_length, false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_session_id(&session_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: parse_handshake_type_server_hello(): session_id"), + session_id.get_data(session_id.get_data_length()), + session_id.get_data_length())); + } + + data_offset += *p_session_id_length; + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_CIPHER_SUITE_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_cipher_suite_network_order = tls_handshake_header->get_data_offset( + data_offset, + TLS_CIPHER_SUITE_FIELD_SIZE); + if (p_cipher_suite_network_order == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + u16_t cipher_suite + = eap_read_u16_t_network_order( + p_cipher_suite_network_order, + TLS_CIPHER_SUITE_FIELD_SIZE); + + status = tls_handshake_message->set_selected_cipher_suite( + static_cast(cipher_suite)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: parse_handshake_type_server_hello(): cipher_suite"), + &cipher_suite, + sizeof(cipher_suite))); + + data_offset += TLS_CIPHER_SUITE_FIELD_SIZE; + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_COMPRESSION_METHOD_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_compression = tls_handshake_header->get_data_offset( + data_offset, + TLS_COMPRESSION_METHOD_FIELD_SIZE); + if (p_compression == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = tls_handshake_message->set_selected_compression_method( + static_cast(*p_compression)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: parse_handshake_type_server_hello(): p_compression"), + p_compression, + sizeof(*p_compression))); + + data_offset += TLS_COMPRESSION_METHOD_FIELD_SIZE; + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + + status = parse_tls_extension_list( + handshake_data_length, + &data_offset, + tls_handshake_header, + tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + //---------------------------------------------------------- + + if (status == eap_status_ok) + { + // Note the add_handshake_message() frees message in any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = received_tls_record_message->add_handshake_message(tls_handshake_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_server_key_exchange( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_server_key_exchange()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_server_key_exchange()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message_copy( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t handshake_length = tls_handshake_header->get_data_length(); + u32_t data_offset = 0ul; + + //---------------------------------------------------------- + + { + if (data_offset+TLS_DHE_PRIME_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_dhe_prime_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_DHE_PRIME_LENGTH_FIELD_SIZE); + if (p_dhe_prime_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + data_offset += TLS_DHE_PRIME_LENGTH_FIELD_SIZE; + + u16_t dhe_prime_length + = eap_read_u16_t_network_order(p_dhe_prime_length, TLS_DHE_PRIME_LENGTH_FIELD_SIZE); + + u8_t *p_dhe_prime_value = tls_handshake_header->get_data_offset( + data_offset, + dhe_prime_length); + if (p_dhe_prime_value == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_variable_data_c dhe_prime(m_am_tools); + status = dhe_prime.set_buffer(p_dhe_prime_value, dhe_prime_length, false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_dhe_prime(&dhe_prime); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += dhe_prime_length; + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_DHE_GROUP_GENERATOR_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_dhe_group_generator_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_DHE_GROUP_GENERATOR_LENGTH_FIELD_SIZE); + if (p_dhe_group_generator_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + data_offset += TLS_DHE_GROUP_GENERATOR_LENGTH_FIELD_SIZE; + + u16_t dhe_group_generator_length = + eap_read_u16_t_network_order( + p_dhe_group_generator_length, + TLS_DHE_GROUP_GENERATOR_LENGTH_FIELD_SIZE); + + u8_t *p_dhe_group_generator_value = tls_handshake_header->get_data_offset( + data_offset, + dhe_group_generator_length); + if (p_dhe_group_generator_value == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_variable_data_c dhe_group_generator(m_am_tools); + status = dhe_group_generator.set_buffer( + p_dhe_group_generator_value, + dhe_group_generator_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_dhe_group_generator(&dhe_group_generator); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += dhe_group_generator_length; + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_PUBLIC_DHE_KEY_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_public_dhe_key_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_PUBLIC_DHE_KEY_LENGTH_FIELD_SIZE); + if (p_public_dhe_key_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + data_offset += TLS_PUBLIC_DHE_KEY_LENGTH_FIELD_SIZE; + + u16_t public_dhe_key_length = + eap_read_u16_t_network_order( + p_public_dhe_key_length, + TLS_PUBLIC_DHE_KEY_LENGTH_FIELD_SIZE); + + u8_t *p_public_dhe_key_value = tls_handshake_header->get_data_offset( + data_offset, + public_dhe_key_length); + if (p_public_dhe_key_value == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_variable_data_c public_dhe_key(m_am_tools); + status = public_dhe_key.set_buffer( + p_public_dhe_key_value, + public_dhe_key_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_public_dhe_key(&public_dhe_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += public_dhe_key_length; + } + + //---------------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && data_offset == handshake_data_length) + { + // Here are no signed hash. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_server_key_exchange(): EAP-FAST server unauthenticated provisioning mode, no signed hash\n"), + (m_is_client == true ? "client": "server"))); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + if (data_offset >= handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u16_t expected_dss_sha1_signature_length + = static_cast(handshake_length - data_offset); + + u8_t *p_dss_sha1_signature_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_DSS_SHA1_SIGNATURE_LENGTH_FIELD_SIZE); + if (p_dss_sha1_signature_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u16_t dss_sha1_signature_length = + eap_read_u16_t_network_order( + p_dss_sha1_signature_length, + TLS_DSS_SHA1_SIGNATURE_LENGTH_FIELD_SIZE); + + if (expected_dss_sha1_signature_length == dss_sha1_signature_length+2ul) + { + // WARNING: Here we have additional length field. OpenSSL does this. + /* + // TLS 1.0 RFC 2246 says the length of sha_hash is explicitly 20 bytes + // (Chapter 7.4.3. Server key exchange message). + // The length of the vector is not included in the encoded stream + // (Chapter 4.3. Vectors). + select (SignatureAlgorithm) + { case anonymous: struct { }; + case rsa: + digitally-signed struct { + opaque md5_hash[16]; + opaque sha_hash[20]; + }; + case dsa: + digitally-signed struct { + opaque sha_hash[20]; + }; + } Signature; + */ + data_offset += TLS_DSS_SHA1_SIGNATURE_LENGTH_FIELD_SIZE; + } + else + { + dss_sha1_signature_length = expected_dss_sha1_signature_length; + } + + u8_t *p_dss_sha1_signature = tls_handshake_header->get_data_offset( + data_offset, + dss_sha1_signature_length); + if (p_dss_sha1_signature == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_variable_data_c dss_sha1_signature(m_am_tools); + status = dss_sha1_signature.set_buffer( + p_dss_sha1_signature, + dss_sha1_signature_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_signed_message_hash(&dss_sha1_signature); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += dss_sha1_signature_length; + } + + //---------------------------------------------------------- + + if (status == eap_status_ok) + { + // Note the add_handshake_message() frees message in any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = received_tls_record_message->add_handshake_message(tls_handshake_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_client_key_exchange( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_client_key_exchange()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_client_key_exchange()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message_copy( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t data_offset = 0ul; + + //---------------------------------------------------------- + + if (cipher_suite_is_TLS_RSA() == true) + { + u32_t encrypted_premaster_secret_length = tls_handshake_header->get_data_length(); + + if (data_offset+encrypted_premaster_secret_length > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_encrypted_premaster_secret_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_ENCRYPTED_PREMASTER_SECRET_LENGTH_FIELD_SIZE); + if (p_encrypted_premaster_secret_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + data_offset += TLS_ENCRYPTED_PREMASTER_SECRET_LENGTH_FIELD_SIZE; + + u16_t data_encrypted_premaster_secret_length + = eap_read_u16_t_network_order( + p_encrypted_premaster_secret_length, + TLS_ENCRYPTED_PREMASTER_SECRET_LENGTH_FIELD_SIZE); + + if ((data_encrypted_premaster_secret_length + 2ul) != encrypted_premaster_secret_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t *p_encrypted_premaster_secret_value = tls_handshake_header->get_data_offset( + data_offset, + encrypted_premaster_secret_length-2ul); + if (p_encrypted_premaster_secret_value == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_variable_data_c encrypted_premaster_secret(m_am_tools); + status = encrypted_premaster_secret.set_buffer( + p_encrypted_premaster_secret_value, + encrypted_premaster_secret_length-2ul, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: parse_handshake_type_client_key_exchange(): encrypted premaster_secret"), + encrypted_premaster_secret.get_data(), + encrypted_premaster_secret.get_data_length())); + + status = tls_handshake_message->set_encrypted_premaster_secret(&encrypted_premaster_secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += encrypted_premaster_secret_length; + } + else if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + if (data_offset+TLS_PUBLIC_DHE_KEY_LENGTH_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_public_dhe_key_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_PUBLIC_DHE_KEY_LENGTH_LENGTH_FIELD_SIZE); + if (p_public_dhe_key_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + data_offset += TLS_PUBLIC_DHE_KEY_LENGTH_LENGTH_FIELD_SIZE; + + u16_t public_dhe_key_length + = eap_read_u16_t_network_order( + p_public_dhe_key_length, + TLS_PUBLIC_DHE_KEY_LENGTH_LENGTH_FIELD_SIZE); + + u8_t *p_public_dhe_key_value = tls_handshake_header->get_data_offset( + data_offset, + public_dhe_key_length); + if (p_public_dhe_key_value == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + eap_variable_data_c public_dhe_key(m_am_tools); + status = public_dhe_key.set_buffer( + p_public_dhe_key_value, + public_dhe_key_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_public_dhe_key(&public_dhe_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += public_dhe_key_length; + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + + //---------------------------------------------------------- + + if (status == eap_status_ok) + { + // Note the add_handshake_message() frees message in any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = received_tls_record_message->add_handshake_message(tls_handshake_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_certificate_verify( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_certificate_verify()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_certificate_verify()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message_copy( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t data_offset = 0ul; + + //---------------------------------------------------------- + + + // Save the message hash. + message_hash_save_certificate_verify(); + + if (cipher_suite_is_TLS_RSA() == true + || cipher_suite_is_TLS_DHE_RSA() == true) + { + eap_variable_data_c signed_hash(m_am_tools); + + if (data_offset >= handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u32_t handshake_length = tls_handshake_header->get_data_length(); + u32_t rsa_md5_sha1_signature_length = handshake_length - data_offset; + + u8_t *p_signature_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_SIGNATURE_LENGTH_FIELD_SIZE); + if (p_signature_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + data_offset += TLS_SIGNATURE_LENGTH_FIELD_SIZE; + + u16_t data_signature_length + = eap_read_u16_t_network_order(p_signature_length, TLS_SIGNATURE_LENGTH_FIELD_SIZE); + + if ((data_signature_length + 2ul) != rsa_md5_sha1_signature_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t *p_rsa_md5_sha1_signature = tls_handshake_header->get_data_offset( + data_offset, + rsa_md5_sha1_signature_length-2ul); + if (p_rsa_md5_sha1_signature == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = signed_hash.set_copy_of_buffer( + p_rsa_md5_sha1_signature, + rsa_md5_sha1_signature_length-2ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tls_handshake_message->set_signed_message_hash( + &signed_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += rsa_md5_sha1_signature_length; + } + else if (cipher_suite_is_TLS_DHE_DSS() == true) + { + eap_variable_data_c signed_hash(m_am_tools); + + if (data_offset >= handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u32_t handshake_length = tls_handshake_header->get_data_length(); + u32_t dss_sha1_signature_length = handshake_length - data_offset; + + u8_t *p_signature_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_SIGNATURE_LENGTH_FIELD_SIZE); + if (p_signature_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + data_offset += TLS_SIGNATURE_LENGTH_FIELD_SIZE; + + u16_t data_signature_length + = eap_read_u16_t_network_order(p_signature_length, TLS_SIGNATURE_LENGTH_FIELD_SIZE); + + if ((data_signature_length + 2ul) != dss_sha1_signature_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + u8_t *p_dss_sha1_signature = tls_handshake_header->get_data_offset( + data_offset, + dss_sha1_signature_length-2ul); + if (p_dss_sha1_signature == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = signed_hash.set_copy_of_buffer( + p_dss_sha1_signature, + dss_sha1_signature_length-2ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tls_handshake_message->set_signed_message_hash( + &signed_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += dss_sha1_signature_length; + } + + //---------------------------------------------------------- + + if (status == eap_status_ok) + { + // Note the add_handshake_message() frees message in any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = received_tls_record_message->add_handshake_message(tls_handshake_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_finished( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t /* handshake_data_length */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_finished()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_finished()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message_copy( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t data_offset = 0ul; + + //---------------------------------------------------------- + + bool client_originated = true; + if (m_is_client == true) + { + client_originated = false; + } + // Save the message hash. + message_hash_save_finished(client_originated); + + { + eap_variable_data_c finished_data(m_am_tools); + + u8_t *p_finished_data = tls_handshake_header->get_data_offset( + data_offset, + TLS_FINISHED_DATA_SIZE); + if (p_finished_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = finished_data.set_copy_of_buffer(p_finished_data, TLS_FINISHED_DATA_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tls_handshake_message->set_finished_data( + &finished_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += TLS_FINISHED_DATA_SIZE; + } + + //---------------------------------------------------------- + + if (status == eap_status_ok) + { + // Note the add_handshake_message() frees message in any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = received_tls_record_message->add_handshake_message(tls_handshake_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_new_session_ticket( + tls_record_message_c * const received_tls_record_message, + tls_handshake_header_c * const tls_handshake_header, + const u32_t handshake_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_new_session_ticket()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_new_session_ticket()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message_copy( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t data_offset = 0ul; + + u8_t * handshake_data = tls_handshake_header->get_data_offset( + data_offset, + tls_handshake_header->get_data_length()); + if (handshake_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + //---------------------------------------------------------- + + u32_t session_ticket_lifetime_hint(0ul); + + { + if (data_offset+TLS_SESSION_TICKET_LIFETIME_HINT_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_session_ticket_lifetime_hint = handshake_data; + + session_ticket_lifetime_hint = eap_read_u32_t_network_order( + p_session_ticket_lifetime_hint, + TLS_SESSION_TICKET_LIFETIME_HINT_FIELD_SIZE); + + data_offset += TLS_SESSION_TICKET_LIFETIME_HINT_FIELD_SIZE; + } + + //---------------------------------------------------------- + + { + if (data_offset+TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_opaque_session_ticket_length = tls_handshake_header->get_data_offset( + data_offset, + TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE); + if (p_opaque_session_ticket_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u16_t opaque_session_ticket_length = eap_read_u16_t_network_order( + p_opaque_session_ticket_length, + TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE); + + data_offset += TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE; + + if (data_offset+opaque_session_ticket_length > handshake_data_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + tls_extension_c opaque_session_ticket(m_am_tools); + + if (opaque_session_ticket.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u8_t *p_opaque_session_ticket = tls_handshake_header->get_data_offset( + data_offset, + opaque_session_ticket_length); + if (p_opaque_session_ticket_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = opaque_session_ticket.set_buffer( + p_opaque_session_ticket, + opaque_session_ticket_length, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + opaque_session_ticket.set_type(tls_extension_type_session_ticket); + + opaque_session_ticket.set_lifetime_hint(session_ticket_lifetime_hint); + + eap_array_c tls_extensions(m_am_tools); + + status = tls_extensions.add_object(&opaque_session_ticket, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Save the new session ticket to be included in next NewSessionTicket message. + status = tls_handshake_message->set_tls_extensions( + &tls_extensions); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: parse_handshake_type_new_session_ticket(): opaque_session_ticket"), + opaque_session_ticket.get_data(opaque_session_ticket.get_data_length()), + opaque_session_ticket.get_data_length())); + + data_offset += opaque_session_ticket_length; + } + + //---------------------------------------------------------- + + if (status == eap_status_ok) + { + // Note the add_handshake_message() frees message in any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = received_tls_record_message->add_handshake_message(tls_handshake_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_tls_protocol_change_cipher_spec( + tls_record_message_c * const tls_record_message, + eap_variable_data_c * const tls_protocol_messages_buffer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_tls_protocol_change_cipher_spec()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_tls_protocol_change_cipher_spec()"); + + tls_record_message->set_parsed_record(); + + if (verify_state(tls_peap_state_wait_change_cipher_spec) == false +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + && (m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none + && verify_state(tls_peap_state_wait_handshake_type_certificate_verify) == false) +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + ) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string(tls_peap_state_wait_change_cipher_spec))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + eap_status_e status = eap_status_not_supported; + + const u32_t tls_protocols_length = tls_protocol_messages_buffer->get_data_length(); + + tls_change_cipher_spec_message_c * const tls_change_cipher_spec_message + = new tls_change_cipher_spec_message_c(m_am_tools, this, m_is_client); + + eap_automatic_variable_c + automatic_tls_change_cipher_spec_message(m_am_tools, tls_change_cipher_spec_message); + + if (tls_change_cipher_spec_message == 0 + || tls_change_cipher_spec_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t data_offset = 0ul; + + //---------------------------------------------------------- + + { + if (data_offset+TLS_CHANGE_CIPHER_SPEC_FIELD_SIZE > tls_protocols_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_change_cipher_spec_type = tls_protocol_messages_buffer->get_data_offset( + data_offset, + TLS_CHANGE_CIPHER_SPEC_FIELD_SIZE); + if (p_change_cipher_spec_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = tls_change_cipher_spec_message->set_change_cipher_spec_type( + static_cast(*p_change_cipher_spec_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += TLS_CHANGE_CIPHER_SPEC_FIELD_SIZE; + } + + //---------------------------------------------------------- + + if (tls_protocols_length != data_offset) + { + // Parsed record length does not match with received record length. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (status == eap_status_ok) + { + // Note add_change_cipher_spec_message() frees message on any case. + automatic_tls_change_cipher_spec_message.do_not_free_variable(); + + status = tls_record_message->add_change_cipher_spec_message( + tls_change_cipher_spec_message, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_tls_protocol_alert( + tls_record_message_c * const tls_record_message, + eap_variable_data_c * const tls_protocol_messages_buffer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_tls_protocol_alert()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_tls_protocol_alert()"); + + tls_record_message->set_parsed_record(); + + eap_status_e status = eap_status_not_supported; + + // Because we received alert message, we do not send alert messages anymore. + m_could_send_fatal_alert_message = false; + m_could_send_warning_alert_message = false; + + const u32_t tls_protocol_messages_length = tls_protocol_messages_buffer->get_data_length(); + u32_t data_start_offset = 0ul; + + while (data_start_offset < tls_protocol_messages_length) + { + tls_alert_message_c * const tls_alert_message + = new tls_alert_message_c(m_am_tools, m_is_client); + + eap_automatic_variable_c + automatic_tls_alert_message(m_am_tools, tls_alert_message); + + if (tls_alert_message == 0 + || tls_alert_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t data_offset = 0ul; + + //---------------------------------------------------------- + + { + if (data_start_offset+data_offset+TLS_ALERT_LEVEL_FIELD_SIZE + > tls_protocol_messages_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_alert_level = tls_protocol_messages_buffer->get_data_offset( + data_start_offset+data_offset, + TLS_ALERT_LEVEL_FIELD_SIZE); + if (p_alert_level == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = tls_alert_message->set_alert_level( + static_cast(*p_alert_level)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += TLS_ALERT_LEVEL_FIELD_SIZE; + } + + //---------------------------------------------------------- + + { + if (data_start_offset+data_offset+TLS_ALERT_DESCRIPTION_FIELD_SIZE + > tls_protocol_messages_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u8_t *p_alert_description = tls_protocol_messages_buffer->get_data_offset( + data_start_offset+data_offset, + TLS_ALERT_DESCRIPTION_FIELD_SIZE); + if (p_alert_description == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = tls_alert_message->set_alert_description( + static_cast(*p_alert_description)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += TLS_ALERT_DESCRIPTION_FIELD_SIZE; + } + + if (status == eap_status_ok) + { + // Note add_alert_message() frees message on any case. + automatic_tls_alert_message.do_not_free_variable(); + + status = tls_record_message->add_alert_message(tls_alert_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + data_start_offset += data_offset; + } // while() + + //---------------------------------------------------------- + + if (tls_protocol_messages_length != data_start_offset) + { + // Parsed record length does not match with received record length. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_tls_protocol_handshake( + tls_record_message_c * const tls_record_message, + eap_variable_data_c * const tls_protocol_messages_buffer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_tls_protocol_handshake()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_tls_protocol_handshake()"); + + tls_record_message->set_parsed_record(); + + const u32_t tls_protocol_messages_length = tls_protocol_messages_buffer->get_data_length(); + + u32_t data_start_offset = 0ul; + + tls_handshake_header_c tls_handshake_header( + m_am_tools, + tls_protocol_messages_buffer->get_data_offset( + data_start_offset, + tls_protocol_messages_buffer->get_data_length()-data_start_offset), + tls_protocol_messages_buffer->get_data_length()-data_start_offset); + if (tls_handshake_header.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length() > tls_handshake_header.get_header_buffer_length() + || tls_handshake_header.get_header_buffer( + tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length()) == 0) + { + // Not enough data. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("TLS-handshake tls_handshake_header"), + tls_handshake_header.get_header_buffer( + tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length()), + (tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length()))); + + eap_status_e status = eap_status_ok; + + u32_t counter = 0ul; + + + while (tls_handshake_header.get_is_valid() == true + && data_start_offset < tls_protocol_messages_length) + { + const u32_t handshake_data_length = tls_handshake_header.get_data_length(); + if (handshake_data_length+data_start_offset > tls_protocol_messages_length) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: parse_tls_protocol_handshake(): ") + EAPL("counter[%u] type = 0x%08x=%s.\n"), + (m_is_client == true ? "client": "server"), + counter, + tls_handshake_header.get_handshake_type(), + tls_handshake_header.get_tls_handshake_string())); + + status = tls_handshake_header.check_header( + tls_handshake_header.get_handshake_type(), + m_is_client); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length() + > tls_handshake_header.get_header_buffer_length() + || tls_handshake_header.get_header_buffer( + tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length()) == 0) + { + // Not enough data. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + bool add_to_message_hash = false; + + switch (tls_handshake_header.get_handshake_type()) + { + case tls_handshake_type_hello_request: + status = parse_handshake_type_hello_request( + tls_record_message, + &tls_handshake_header, + handshake_data_length); + add_to_message_hash = false; + break; + case tls_handshake_type_client_hello: + status = parse_handshake_type_client_hello( + tls_record_message, + &tls_handshake_header, + handshake_data_length); + add_to_message_hash = true; + break; + case tls_handshake_type_server_hello: + status = parse_handshake_type_server_hello( + tls_record_message, + &tls_handshake_header, + handshake_data_length); + add_to_message_hash = true; + break; + case tls_handshake_type_certificate: + status = parse_handshake_type_certificate( + tls_record_message, + &tls_handshake_header, + handshake_data_length); + add_to_message_hash = true; + break; + case tls_handshake_type_server_key_exchange: + status = parse_handshake_type_server_key_exchange( + tls_record_message, + &tls_handshake_header, + handshake_data_length); + add_to_message_hash = true; + break; + case tls_handshake_type_certificate_request: + status = parse_handshake_type_certificate_request( + tls_record_message, + &tls_handshake_header, + handshake_data_length); + add_to_message_hash = true; + break; + case tls_handshake_type_server_hello_done: + status = parse_handshake_type_server_hello_done( + tls_record_message, + &tls_handshake_header, + handshake_data_length); + add_to_message_hash = true; + break; + case tls_handshake_type_certificate_verify: + status = parse_handshake_type_certificate_verify( + tls_record_message, + &tls_handshake_header, + handshake_data_length); + add_to_message_hash = true; + break; + case tls_handshake_type_client_key_exchange: + status = parse_handshake_type_client_key_exchange( + tls_record_message, + &tls_handshake_header, + handshake_data_length); + add_to_message_hash = true; + break; + case tls_handshake_type_finished: + status = parse_handshake_type_finished( + tls_record_message, + &tls_handshake_header, + handshake_data_length); + add_to_message_hash = true; + break; +#if defined(USE_EAP_TLS_SESSION_TICKET) + case tls_handshake_type_new_session_ticket: + status = parse_handshake_type_new_session_ticket( + tls_record_message, + &tls_handshake_header, + handshake_data_length); + add_to_message_hash = true; + break; +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + default: + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } // switch() + + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + if (add_to_message_hash == true) + { + status = message_hash_update( + true, + tls_handshake_header.get_handshake_type(), + tls_handshake_header.get_header_buffer( + tls_handshake_header.get_header_length() + +tls_handshake_header.get_data_length()), + tls_handshake_header.get_header_length() + +tls_handshake_header.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + data_start_offset += (tls_handshake_header.get_header_length() + +tls_handshake_header.get_data_length()); + + if (data_start_offset > tls_protocol_messages_buffer->get_data_length()) + { + // Parsed record length does not match with received record length. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + tls_handshake_header.set_header_buffer( + tls_protocol_messages_buffer->get_data_offset( + data_start_offset, + tls_protocol_messages_buffer->get_data_length()-data_start_offset), + tls_protocol_messages_buffer->get_data_length()-data_start_offset); + // NOTE tls_handshake_header is checked in the begin of the loop. + + ++counter; + + } // while() + + if (tls_protocol_messages_length != data_start_offset) + { + // Parsed record length does not match with received record length. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_tls_protocol_application_data( + tls_record_message_c * const tls_record_message, + eap_variable_data_c * const tls_protocol_messages_buffer) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_tls_protocol_application_data()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_tls_protocol_application_data()"); + + tls_record_message->set_parsed_record(); + + eap_status_e status = eap_status_not_supported; + + const u32_t tls_protocol_messages_length = tls_protocol_messages_buffer->get_data_length(); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("TLS-application data"), + tls_protocol_messages_buffer->get_data(tls_protocol_messages_length), + tls_protocol_messages_length)); + + tls_application_data_message_c * const tls_application_data_message + = new tls_application_data_message_c(m_am_tools, m_is_client); + + eap_automatic_variable_c + automatic_tls_application_data_message(m_am_tools, tls_application_data_message); + + if (tls_application_data_message == 0 + || tls_application_data_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t data_offset = 0ul; + + //---------------------------------------------------------- + + { + u8_t *p_application_data = tls_protocol_messages_buffer->get_data( + tls_protocol_messages_length); + if (p_application_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = tls_application_data_message->set_application_data( + p_application_data, + tls_protocol_messages_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + data_offset += tls_protocol_messages_length; + } + + //---------------------------------------------------------- + + if (tls_protocol_messages_length != data_offset) + { + // Parsed record length does not match with received record length. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + if (status == eap_status_ok) + { + // Note add_application_data_message() frees message on any case. + automatic_tls_application_data_message.do_not_free_variable(); + + status = tls_record_message->add_application_data_message( + tls_application_data_message, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::reassemble_tls_records( + tls_record_message_c * const tls_record_message, + tls_record_header_c * const next_tls_record_header) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: starts: tls_record_c::reassemble_tls_records()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::reassemble_tls_records()"); + + eap_status_e status = tls_record_message->get_record_message_data()->add_data( + next_tls_record_header->get_data(next_tls_record_header->get_data_length()), + next_tls_record_header->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_record_message->add_data_length(next_tls_record_header->get_data_length()); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: tls_record_c::reassemble_tls_records(): fragment %d bytes, ") + EAPL("message %d bytes.\n"), + this, + (m_is_client == true ? "client": "server"), + next_tls_record_header->get_data_length(), + tls_record_message->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::process_tls_records() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::process_tls_records(): index = %d, record count = %d\n"), + (m_is_client == true ? "client": "server"), + m_received_tls_message.get_analyse_index(), + m_received_tls_message.get_record_message_count())); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::process_tls_records()"); + + if (m_already_in_process_tls_records == true) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + // This is recursive call of process_tls_records(). + // This MUST return eap_status_ok. Other return values will skip + // further prosessing of TLS message. + EAP_TRACE_DEBUG( + m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: process_tls_records(): skip recursion\n"), + (m_is_client == true ? "client": "server"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_end_recursion); + } + m_already_in_process_tls_records = true; + + eap_automatic_simple_value_c restore_already_in_process_tls_records( + m_am_tools, + &m_already_in_process_tls_records, + false); + + // One TLS-message could include many records. Each of records could + // include many protocol messages. + // +=================================================+ + // +=================================================+ + // | 1. tls_record_header_c | + // | protocol tls_record_protocol_handshake | + // +-------------------------------------------------+ + // | 1a. tls_handshake_header_c | + // +- - - - - - - - - - - - - - - - - - - - - - - - -+ + // | 1a. data of handshake | + // +-------------------------------------------------+ + // | 1b. tls_handshake_header_c | + // +- - - - - - - - - - - - - - - - - - - - - - - - -+ + // | 1b. data of handshake | + // +=================================================+ + // +=================================================+ + // | 2. tls_record_header_c | + // | protocol tls_record_protocol_change_cipher_spec | + // +-------------------------------------------------+ + // | 2a. data of change_cipher_spec | + // +=================================================+ + // +=================================================+ + // | 3. tls_record_header_c | + // | protocol tls_record_protocol_handshake | + // +-------------------------------------------------+ + // | 3a. tls_handshake_header_c | + // +- - - - - - - - - - - - - - - - - - - - - - - - -+ + // | 3a. data of handshake | + // +=================================================+ + // +=================================================+ + + // One protocol message could be fragmented to many records. + // +=================================================+ + // +=================================================+ + // | 1. tls_record_header_c | + // | protocol tls_record_protocol_handshake | + // +-------------------------------------------------+ + // | 1a. tls_handshake_header_c | + // +- - - - - - - - - - - - - - - - - - - - - - - - -+ + // | 1a. data of handshake (1/2) | + // +=================================================+ + // +=================================================+ + // | 2. tls_record_header_c | + // | protocol tls_record_protocol_change_cipher_spec | + // +-------------------------------------------------+ + // | 2a. data of handshake (2/2) | + // +=================================================+ + // +=================================================+ + + eap_status_e status = eap_status_ok; + u32_t index = 0ul; + bool analyse_messages = true; + + for (index = m_received_tls_message.get_analyse_index() + ; analyse_messages == true + && index < m_received_tls_message.get_record_message_count() + ; index++) + { + // This is used in EAP-FAST to see the next TLS message type. + m_received_tls_message.save_analyse_index(index); + + tls_record_message_c * const tls_record_message + = m_received_tls_message.get_record_message(index); + if (tls_record_message == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_too_short_message); + } + + u32_t tls_record_length = tls_record_message->get_record_message_data()->get_data_length(); + + tls_record_header_c tls_record_header( + m_am_tools, + tls_record_message->get_record_message_data()->get_data( + tls_record_header_c::get_header_length()), + tls_record_length); + + if (tls_record_header.get_is_valid() == false + || tls_record_length < tls_record_header.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_too_short_message); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("process TLS-record message"), + tls_record_header.get_header_buffer(tls_record_header.get_header_length() + + tls_record_header.get_data_length()), + tls_record_header.get_header_length() + + tls_record_header.get_data_length())); + + if ((tls_record_length) + < (tls_record_header.get_header_length() + tls_record_header.get_data_length())) + { + // Record header indicates more data than the received buffer includes. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_process_illegal_packet_error); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: process_tls_records(): ") + EAPL("index[%u] protocol = 0x%08x=%s.\n"), + (m_is_client == true ? "client": "server"), + index, + tls_record_header.get_protocol(), + tls_record_header.get_tls_protocol_string())); + + + if (tls_record_message->get_cipher_suite_applied() == false) + { + status = apply_receive_cipher_suite(tls_record_message->get_record_message_data()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + tls_record_message->set_cipher_suite_applied(); + + tls_record_length = tls_record_message->get_record_message_data()->get_data_length(); + + // We must query tls_record_header again, + // memory buffer may be changed during apply_receive_cipher_suite() call. + tls_record_header.set_header_buffer( + tls_record_message->get_record_message_data()->get_data( + tls_record_header_c::get_header_length()), + tls_record_length); + + if (tls_record_header.get_is_valid() == false + || tls_record_length < tls_record_header.get_data_length() + || tls_record_length + < tls_record_header.get_header_length() + + tls_record_header.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_too_short_message); + } + } + + + while (index+1ul < m_received_tls_message.get_record_message_count()) + { + tls_record_message_c * const next_tls_record_message + = m_received_tls_message.get_record_message(index+1ul); + if (next_tls_record_message != 0) + { + u32_t next_tls_record_length + = next_tls_record_message->get_record_message_data()->get_data_length(); + + tls_record_header_c next_tls_record_header( + m_am_tools, + next_tls_record_message->get_record_message_data()->get_data( + tls_record_header_c::get_header_length()), + next_tls_record_length); + + if (next_tls_record_header.get_is_valid() == false + || next_tls_record_length < next_tls_record_header.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_too_short_message); + } + + if (tls_record_header.get_protocol() == next_tls_record_header.get_protocol()) + { + // Reassembly checks this and the next TLS-records whether they are fragments + // and it reassembles fragments to one TLS-record. + // The easiest check does need only the TLS-protocol fields. + // If TLS-protocol fields are the same those records could be reassembled. + + if (next_tls_record_message->get_cipher_suite_applied() == false) + { + status = apply_receive_cipher_suite( + next_tls_record_message->get_record_message_data()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + status); + } + + next_tls_record_message->set_cipher_suite_applied(); + } + + next_tls_record_length + = next_tls_record_message->get_record_message_data()->get_data_length(); + + next_tls_record_header.set_header_buffer( + next_tls_record_message->get_record_message_data()->get_data( + tls_record_header_c::get_header_length()), + next_tls_record_length); + + if (next_tls_record_header.get_is_valid() == false + || next_tls_record_length < next_tls_record_header.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_too_short_message); + } + + status = reassemble_tls_records(tls_record_message, &next_tls_record_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + // If TLS-record is complete then it could be parsed and analysed. + // TLS-record is complete when the next TLS-record is other type of protocol. + // If TLS-record is NOT complete the next TLS-record must processed. + // In a case the TLS-record cannot be reassemled the whole + // TLS-message must be dropped. + + // Remove the next_tls_record_message. + status = m_received_tls_message.remove_record_message(index+1ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + break; + } + } + else + { + break; + } + } // while() + + // NOTE at this point the length may be longer than 2^14 bytes. + tls_record_length = tls_record_message->get_record_message_data()->get_data_length(); + + // We must query tls_record_header again, + // memory buffer may be changed during reassembly. + tls_record_header.set_header_buffer( + tls_record_message->get_record_message_data()->get_data( + tls_record_length), + tls_record_length); + + if (tls_record_header.get_is_valid() == false + || tls_record_length < tls_record_header.get_data_length() + || tls_record_length + < tls_record_header.get_header_length() + + tls_record_header.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_too_short_message); + } + + + + // Here we extract the protocol messages from the buffer. + // Note the tls_record_header includes only the first protocol message, + // that causes the use of tls_record_message->get_record_message_data(). + u32_t protocol_messages_length = tls_record_length - tls_record_header.get_header_length(); + eap_variable_data_c protocol_messages(m_am_tools); + + status = protocol_messages.set_buffer( + tls_record_message->get_record_message_data()->get_data_offset( + tls_record_header.get_header_length(), + protocol_messages_length), + protocol_messages_length, + false, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("reassembled TLS-protocol messages"), + protocol_messages.get_data( + protocol_messages.get_data_length()), + protocol_messages.get_data_length())); + + switch(tls_record_header.get_protocol()) + { + case tls_record_protocol_change_cipher_spec: + { + if (tls_record_message->get_parsed_record() == false) + { + status = parse_tls_protocol_change_cipher_spec( + tls_record_message, + &protocol_messages); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + + status = analyse_tls_protocol_change_cipher_spec( + tls_record_message); + break; + } + case tls_record_protocol_alert: + { + if (tls_record_message->get_parsed_record() == false) + { + status = parse_tls_protocol_alert( + tls_record_message, + &protocol_messages); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + + status = analyse_tls_protocol_alert( + tls_record_message); + break; + } + case tls_record_protocol_handshake: + { + if (tls_record_message->get_parsed_record() == false) + { + status = parse_tls_protocol_handshake( + tls_record_message, + &protocol_messages); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + + status = analyse_tls_protocol_handshake( + tls_record_message, + m_received_tls_message.get_received_eap_identifier()); + break; + } + case tls_record_protocol_application_data: + { + if (tls_record_message->get_parsed_record() == false) + { + status = parse_tls_protocol_application_data( + tls_record_message, + &protocol_messages); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + + status = analyse_tls_protocol_application_data( + tls_record_message, + m_received_tls_message.get_received_eap_identifier()); + break; + } + default: + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_wrong_protocol); + } // switch() + + + // Save the analysed state. We will continue from the following record + // after the pending request is completed. + m_received_tls_message.save_analyse_index(index+1ul); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: process_tls_records(): saves index+1 = %u.\n"), + (m_is_client == true ? "client": "server"), + index+1ul)); + + + if (status == eap_status_pending_request) + { + // Save analyse state. We will continue from the current record + // after the pending request is completed. + m_received_tls_message.save_analyse_index(index); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: process_tls_records(): pending request, saves index = %u.\n"), + (m_is_client == true ? "client": "server"), + index)); + + analyse_messages = false; + + eap_status_e compl_status = completion_action_add( + tls_completion_action_process_tls_records); + if (compl_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (status != eap_status_ok) + { + analyse_messages = false; + } + + if ((get_is_tunneled_tls() == false + && m_tls_peap_state == tls_peap_state_tls_success) + || (get_is_tunneled_tls() == true + && m_tls_peap_state == tls_peap_state_peap_tunnel_ready)) + { + // Authentication OK. + + if (m_eap_type == eap_type_peap + && m_peap_version == peap_version_2 + && m_tls_peap_state == tls_peap_state_peap_tunnel_ready) + { + // PEAPv2 sends EAP-Request/Identity message + // within the application data within the same message + // with TLS hello finished. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: PEAPv2 tunnel ready, application data may follow.\n"))); + } + else + { + analyse_messages = false; + if ((index+1ul) != m_received_tls_message.get_record_message_count()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: parse_function: starts: tls_record_c::process_tls_records(): (index+1 = %d) != (record count = %d)\n"), + (m_is_client == true ? "client": "server"), + index+1, + m_received_tls_message.get_record_message_count())); + // Authentication was successfull, but there are unused TLS-records to process. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: tls_record_c::process_tls_records(): m_received_tls_message.reset().\n"))); + m_received_tls_message.reset(); + } + } + } // for() + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::process_tls_message() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: starts: tls_record_c::process_tls_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::process_tls_message()"); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("TLS-message"), + m_received_tls_message.get_tls_message_data()->get_data( + m_received_tls_message.get_tls_message_data()->get_data_length()), + m_received_tls_message.get_tls_message_data()->get_data_length())); + + u32_t next_start_offset = 0ul; + u32_t tls_packet_length = m_received_tls_message.get_tls_message_data()->get_data_length(); + + if (tls_packet_length < tls_record_header_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_too_short_message); + } + + tls_record_header_c tls_record_header( + m_am_tools, + m_received_tls_message.get_tls_message_data()->get_data_offset( + next_start_offset, + tls_record_header_c::get_header_length()), + tls_packet_length); + + if (tls_record_header.get_is_valid() == false + || tls_packet_length < tls_record_header.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_too_short_message); + } + + eap_status_e status = eap_status_ok; + u32_t counter = 0ul; + + // One TLS-message could include many records. Each of records + // could include many protocol messages. + // +=================================================+ + // +=================================================+ + // | 1. tls_record_header_c | + // | protocol tls_record_protocol_handshake | + // +-------------------------------------------------+ + // | 1a. tls_handshake_header_c | + // +- - - - - - - - - - - - - - - - - - - - - - - - -+ + // | 1a. data of handshake | + // +-------------------------------------------------+ + // | 1b. tls_handshake_header_c | + // +- - - - - - - - - - - - - - - - - - - - - - - - -+ + // | 1b. data of handshake | + // +=================================================+ + // +=================================================+ + // | 2. tls_record_header_c | + // | protocol tls_record_protocol_change_cipher_spec | + // +-------------------------------------------------+ + // | 2a. data of change_cipher_spec | + // +=================================================+ + // +=================================================+ + // | 3. tls_record_header_c | + // | protocol tls_record_protocol_handshake | + // +-------------------------------------------------+ + // | 3a. tls_handshake_header_c | + // +- - - - - - - - - - - - - - - - - - - - - - - - -+ + // | 3a. data of handshake | + // +=================================================+ + // +=================================================+ + + // One protocol message could be fragmented to many records. + // +=================================================+ + // +=================================================+ + // | 1. tls_record_header_c | + // | protocol tls_record_protocol_handshake | + // +-------------------------------------------------+ + // | 1a. tls_handshake_header_c | + // +- - - - - - - - - - - - - - - - - - - - - - - - -+ + // | 1a. data of handshake (1/2) | + // +=================================================+ + // +=================================================+ + // | 2. tls_record_header_c | + // | protocol tls_record_protocol_change_cipher_spec | + // +-------------------------------------------------+ + // | 2a. data of handshake (2/2) | + // +=================================================+ + // +=================================================+ + + while(status == eap_status_ok + && next_start_offset < tls_packet_length + && tls_record_header.get_is_valid() == true) + { + if ((tls_packet_length-next_start_offset) + < (tls_record_header.get_header_length() + tls_record_header.get_data_length())) + { + // Record header indicates more data than the received buffer includes. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Record header indicates more data %u ") + EAPL("than the received buffer includes %u.\n"), + (tls_record_header.get_header_length() + tls_record_header.get_data_length()), + (tls_packet_length-next_start_offset))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_process_illegal_packet_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("process TLS-record"), + tls_record_header.get_header_buffer( + tls_record_header.get_header_length() + + tls_record_header.get_data_length()), + tls_record_header.get_header_length() + + tls_record_header.get_data_length())); + + u32_t tls_record_length = tls_record_header.get_header_length() + + tls_record_header.get_data_length(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: parse_function: process_tls_message(): ") + EAPL("counter[%u] protocol = 0x%08x=%s.\n"), + (m_is_client == true ? "client": "server"), + counter, + tls_record_header.get_protocol(), + tls_record_header.get_tls_protocol_string())); + + tls_record_message_c * const tls_record_message + = new tls_record_message_c(m_am_tools, this, m_is_client); + + eap_automatic_variable_c + automatic_tls_record_message(m_am_tools, tls_record_message); + + if (tls_record_message == 0 + || tls_record_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_allocation_error); + } + + tls_record_message->set_tls_record_header_is_included(true); + + status = tls_record_message->set_record_header_copy(&tls_record_header); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + tls_record_message->set_record_message_data( + tls_record_header.get_header_buffer(tls_record_header.get_header_length() + + tls_record_header.get_data_length()), + tls_record_header.get_header_length() + + tls_record_header.get_data_length()); + + // Note m_received_tls_message frees message on any case. + automatic_tls_record_message.do_not_free_variable(); + + status = m_received_tls_message.add_record_message( + tls_record_message, + true, + false // Here the TLS-Hello messages are not marked. + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + + next_start_offset += tls_record_length; + + if (next_start_offset < tls_packet_length) + { + u32_t remain_data_length = tls_packet_length - next_start_offset; + if (remain_data_length < tls_record_header_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_too_short_message); + } + + tls_record_header.set_header_buffer( + m_received_tls_message.get_tls_message_data()->get_data_offset( + next_start_offset, + tls_record_header_c::get_header_length()), + remain_data_length); + + if (tls_record_header.get_is_valid() == false + || remain_data_length < tls_record_header.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_too_short_message); + } + } + + ++counter; + + } // while() + + if (next_start_offset != tls_packet_length) + { + // Parsed packet length does not match with received packet length. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT( + m_am_tools, + eap_status_process_illegal_packet_error); + } + + status = process_tls_records(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::check_selected_cipher_suite( + const tls_cipher_suites_e selected_cipher_suite) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: suite_function: starts: tls_record_c::check_selected_cipher_suite(): selected_cipher_suite=%d=%s\n"), + (m_is_client == true ? "client": "server"), + selected_cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(selected_cipher_suite))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::check_selected_cipher_suite()"); + + u16_t tmp_selected_cipher_suite = static_cast(selected_cipher_suite); + + i32_t index = find_simple( + &m_proposed_cipher_suites, + &tmp_selected_cipher_suite, + m_am_tools); + if (index == -1) + { + for (u32_t ind = 0ul; ind < m_proposed_cipher_suites.get_object_count(); ++ind) + { + u16_t * proposed_cipher_suite = m_proposed_cipher_suites.get_object(ind); + if (proposed_cipher_suite != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: suite_function: check_selected_cipher_suite(): proposed cipher suite=%d=%s\n"), + (m_is_client == true ? "client": "server"), + *proposed_cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(static_cast(*proposed_cipher_suite)))); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::check_selected_compression_method( + const tls_compression_method_e selected_compression_method) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: suite_function: starts: tls_record_c::check_selected_compression_method(): %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_compression_method_string(selected_compression_method))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::check_selected_compression_method()"); + + if (selected_compression_method == tls_compression_method_null) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + u8_t tmp_selected_compression_method = static_cast(selected_compression_method); + + i32_t index = find_simple( + &m_proposed_compression_methods, + &tmp_selected_compression_method, m_am_tools); + if (index == -1) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::u16_t_to_host_order( + u16_t * const value, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + *value = eap_ntohs(*value); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::u16_t_to_network_order( + u16_t * const value, + abs_eap_am_tools_c * const m_am_tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(m_am_tools); + + *value = eap_htons(*value); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_hello_request( + EAP_TEMPLATE_CONST tls_handshake_message_c * const /* handshake_message */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_hello_request()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_hello_request()"); + + EAP_ASSERT(m_is_client == true); + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_runs); +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + set_state(tls_peap_state_wait_handshake_type_server_hello); + + eap_status_e status = completion_action_add(tls_completion_action_create_handshake_type_client_hello); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_client_hello( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_client_hello(): privacy_handshake_state=%d=%s, session_type=%s\n"), + (m_is_client == true ? "client": "server"), + m_tls_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(m_tls_identity_privacy_handshake_state), + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type) + )); +#else + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_client_hello(): privacy_handshake_state=%d=%s\n"), + (m_is_client == true ? "client": "server"), + 0, + "" + )); +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_client_hello()"); + + EAP_ASSERT(m_is_client == false); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Version: 3 | Version: 1 | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | | + // + + + // | ClientRandomValue | + // + (32 bytes) +-+-+-+-+-+-+-+-+ + // | | ID length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | Session ID | + // + (maximum 32 bytes) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CipherSuite length | CipherSuite 1 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CipherSuite 2 | CipherSuite 3 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CipherSuite 4 | Cmp length | Cmp 1 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Cmp 2 | Cmp 3 | extensions ... | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + eap_status_e status = eap_status_not_supported; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (handshake_message->get_random_value() == 0 + || handshake_message->get_random_value()->get_data_length() + != TLS_HANDSHAKE_RANDOM_VALUE_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + + status = m_client_handshake_random_value.set_copy_of_buffer( + handshake_message->get_random_value()); + if (status != eap_status_ok + || m_client_handshake_random_value.get_data_length() != TLS_HANDSHAKE_RANDOM_VALUE_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (handshake_message->get_session_id() == 0 + || (handshake_message->get_session_id()->get_is_valid_data() == true + && handshake_message->get_session_id()->get_data_length() > TLS_SESSION_ID_SIZE)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + if (handshake_message->get_session_id()->get_is_valid_data() == true + && handshake_message->get_session_id()->get_data_length() > 0ul) + { + status = m_session_id.set_copy_of_buffer(handshake_message->get_session_id()); + if (status != eap_status_ok + || m_session_id.get_data_length() > TLS_SESSION_ID_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + EAP_TEMPLATE_CONST eap_array_c * const cipher_suites + = handshake_message->get_cipher_suites(); + + if (cipher_suites->get_object_count() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + m_proposed_cipher_suites.reset(); + + status = copy_simple( + cipher_suites, + &m_proposed_cipher_suites, + m_am_tools, + false); + if (status != eap_status_ok + || m_proposed_cipher_suites.get_object_count() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + EAP_TEMPLATE_CONST eap_array_c * const compression_methods + = handshake_message->get_compression_methods(); + + status = copy_simple( + compression_methods, + &m_proposed_compression_methods, + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_TLS_SESSION_TICKET) + + { + EAP_TEMPLATE_CONST eap_array_c * const tls_extensions + = handshake_message->get_tls_extensions(); + + status = copy( + tls_extensions, + &m_received_tls_extensions, + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (m_tls_session_type == tls_session_type_full_authentication + && m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_negotiates) + { + set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_runs); + } +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + status = completion_action_add(tls_completion_action_create_handshake_type_server_hello); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none) +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + { + status = m_am_tls_services->select_cipher_suite_and_check_session_id( + &m_proposed_cipher_suites, + &m_session_id + #if defined(USE_EAP_TLS_SESSION_TICKET) + , tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + &m_received_tls_extensions, + m_am_tools) + #endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + ); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_select_cipher_suite_and_check_session_id() call. + m_pending_select_cipher_suite_and_check_session_id = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_select_cipher_suite_and_check_session_id() call. + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + else if (m_tls_session_type == tls_session_type_full_authentication + && m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs) + { + if (m_tls_peap_server_authenticates_client_config_server == true) + { + set_state(tls_peap_state_wait_handshake_type_certificate); + } + else + { + set_state(tls_peap_state_wait_handshake_type_client_key_exchange); + } + + status = completion_action_add(tls_completion_action_create_handshake_type_certificate); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true) + { + // Ephemeral DH key exchange causes creation of server_key_exchange message. + // Server sends DH public key and related parameters to client. + + status = completion_action_add(tls_completion_action_query_dh_parameters); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = completion_action_add( + tls_completion_action_create_handshake_type_server_key_exchange); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This will complete creation of handshake_type_server_key_exchange message. + status = completion_action_add( + tls_completion_action_complete_create_handshake_type_server_key_exchange); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Also the other pending messages will be processed after this action is completed. + eap_status_e compl_status = completion_action_add( + tls_completion_action_process_tls_records); + if (compl_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (m_tls_peap_server_authenticates_client_config_server == true) + { + // Server initiates client authentication. + status = completion_action_add( + tls_completion_action_create_handshake_type_certificate_request); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = completion_action_add( + tls_completion_action_create_handshake_type_server_hello_done); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (/* status == eap_status_pending_request + || */ status == eap_status_completed_request) + { + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_server_hello( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_server_hello()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_server_hello()"); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Version: 3 | Version: 1 | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | | + // + + + // | ServerRandomValue | + // + (32 bytes) +-+-+-+-+-+-+-+-+ + // | | ID length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | Session ID | + // + (maximum 32 bytes) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CipherSuite | Cmp | extensions ...| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + eap_status_e status = eap_status_not_supported; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (handshake_message->get_random_value() == 0 + || handshake_message->get_random_value()->get_data_length() + != TLS_HANDSHAKE_RANDOM_VALUE_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = m_server_handshake_random_value.set_copy_of_buffer( + handshake_message->get_random_value()); + if (status != eap_status_ok + || m_server_handshake_random_value.get_data_length() != TLS_HANDSHAKE_RANDOM_VALUE_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_selected_cipher_suite(handshake_message->get_selected_cipher_suite()); + + status = check_selected_cipher_suite(m_selected_cipher_suite); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: TLS/PEAP selected cipher_suite %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite))); + } + + + m_selected_compression_method = handshake_message->get_selected_compression_method(); + + status = check_selected_compression_method(m_selected_compression_method); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (handshake_message->get_session_id() == 0 + || (handshake_message->get_session_id()->get_is_valid_data() == true + && handshake_message->get_session_id()->get_data_length() > TLS_SESSION_ID_SIZE)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + +#if defined(USE_EAP_TLS_SESSION_TICKET) + m_will_receive_new_session_ticket = false; +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast + && m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ") + EAPL("EAP-FAST server unauthenticated provisioning mode\n"), + (m_is_client == true ? "client": "server"))); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + if (handshake_message->get_session_id()->get_is_valid_data() == true + && handshake_message->get_session_id()->get_data_length() > 0ul +#if defined(USE_FAST_EAP_TYPE) + // EAP-FAST specification says to watch the next message to see whether the session is resumed or not. + // Original TLS is specified to correctly so the client know what happens when it receives ServerHello message. + && (m_eap_type != eap_type_fast + || (m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_full_authentication)) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + +#if defined(USE_EAP_TLS_SESSION_TICKET) + + if (m_tls_session_type == tls_session_type_stateless_session_resumption) + { + m_received_tls_extensions.reset(); + + const tls_extension_c * const supported_session_ticket_extension = tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + &m_supported_tls_extensions, + m_am_tools); + + if (supported_session_ticket_extension != 0) + { + EAP_TEMPLATE_CONST eap_array_c * const tls_extensions + = handshake_message->get_tls_extensions(); + + const tls_extension_c * const received_session_ticket_extension = tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + tls_extensions, + m_am_tools); + + if (received_session_ticket_extension != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ") + EAPL("SST: receives stateless session ticket: length = %d\n"), + (m_is_client == true ? "client": "server"), + received_session_ticket_extension->get_data_length())); + + eap_array_c tmp_extensions(m_am_tools); + + tls_extension_c * const received_session_ticket_extension_copy = received_session_ticket_extension->copy(); + + if (received_session_ticket_extension_copy != 0) + { + status = tmp_extensions.add_object(received_session_ticket_extension_copy, true); + + status = copy( + &tmp_extensions, + &m_received_tls_extensions, + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + m_will_receive_new_session_ticket = true; + } + } + } + } + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + +#if defined(USE_EAP_TLS_SESSION_TICKET) + if (m_tls_session_type == tls_session_type_stateless_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ") + EAPL("restores stateless session\n"), + (m_is_client == true ? "client": "server"))); + + status = m_session_id.set_copy_of_buffer(handshake_message->get_session_id()); + if (status != eap_status_ok + || m_session_id.get_data_length() > TLS_SESSION_ID_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = indicate_state_to_lower_layer( + tls_peap_state_stateless_session_resumption); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + /** @{ PEAPv2 does not support session resumption yet. } */ + if (((m_eap_type == eap_type_peap + && m_peap_version != peap_version_2) + || m_eap_type == eap_type_tls + || m_eap_type == eap_type_ttls +#if defined(USE_FAST_EAP_TYPE) + || m_eap_type == eap_type_fast +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + && m_tls_session_type == tls_session_type_original_session_resumption + && m_resumed_cipher_suite == m_selected_cipher_suite + && handshake_message->get_session_id()->compare(&m_session_id) == 0) + { + // OK, previous session will be restored. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ") + EAPL("restores session\n"), + (m_is_client == true ? "client": "server"))); + + + eap_status_e notification_status = indicate_state_to_lower_layer( + tls_peap_state_original_session_resumption); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } + else + { + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (m_is_client == true + && m_tls_use_identity_privacy == true + && m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none) + { + set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_negotiates); + } +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + set_tls_session_type(tls_session_type_full_authentication); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ") + EAPL("creates new session\n"), + (m_is_client == true ? "client": "server"))); + + status = m_session_id.set_copy_of_buffer(handshake_message->get_session_id()); + if (status != eap_status_ok + || m_session_id.get_data_length() > TLS_SESSION_ID_SIZE) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = indicate_state_to_lower_layer( + tls_peap_state_full_authentication); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + // No session identifier. +#if defined(USE_FAST_EAP_TYPE) + if (m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption + && get_next_tls_handshake_message_type() == tls_handshake_type_none + && get_next_tls_record_message_protocol() == tls_record_protocol_change_cipher_spec) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ") + EAPL("EAP-FAST PAC session resumtion.\n"), + (m_is_client == true ? "client": "server"))); + + // Generates master secret from PAC-Key. + status = generate_eap_fast_master_secret_from_pac_key( + &m_eap_fast_pac_key); + + m_eap_fast_pac_key.reset(); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ") + EAPL("creates new session, no session identifier\n"), + (m_is_client == true ? "client": "server"))); + +#if defined(USE_FAST_EAP_TYPE) + if (m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption) + { + // Server does not accept the Tunnel PAC. + // We will remove the Tunnel PAC if server authenticates OK. + m_remove_tunnel_pac = true; + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + set_tls_session_type(tls_session_type_full_authentication); + } + + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_tls_session_type == tls_session_type_original_session_resumption +#if defined(USE_EAP_TLS_SESSION_TICKET) + || m_tls_session_type == tls_session_type_stateless_session_resumption +#if defined(USE_FAST_EAP_TYPE) + || m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption +#endif //#if defined(USE_FAST_EAP_TYPE) +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + ) + { + if (m_tls_session_type == tls_session_type_original_session_resumption +#if defined(USE_FAST_EAP_TYPE) + || m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + // We must generate the key material. + status = generate_key_material(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + set_state(tls_peap_state_wait_change_cipher_spec); + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_eap_type == eap_type_fast + && m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true) + { + set_state(tls_peap_state_wait_handshake_type_server_key_exchange); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + else + { + set_state(tls_peap_state_wait_handshake_type_certificate); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_certificate( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_certificate()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_certificate()"); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Certificate Chain Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Certificate 1 Length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | Certificate 1 | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // . ... . + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Certificate n Length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | Certificate n | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + eap_status_e status = eap_status_not_supported; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain + = handshake_message->get_certificate_chain(); + + if (m_is_client == false + && certificate_chain->get_object_count() == 0ul + && m_tls_peap_server_authenticates_client_policy_flag == false) + { + // Server allows server only authentication, client is anonymous. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: analyse_handshake_type_certificate(): ") + EAPL("Server allows anonymous client.\n"), + (m_is_client == true ? "client": "server"))); + + m_tls_peap_server_authenticates_client_action = false; + } +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + else if (m_is_client == false + && m_tls_use_identity_privacy == true + && m_tls_session_type == tls_session_type_full_authentication + && m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none + && certificate_chain->get_object_count() == 0ul) + { + // Server allows TLS identity privacy, at this point client is anonymous. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: analyse_handshake_type_certificate(): ") + EAPL("Server allows TLS identity privacy.\n"), + (m_is_client == true ? "client": "server"))); + + set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_negotiates); + } +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + else if (certificate_chain->get_object_count() == 0ul) + { +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) +#if defined(USE_FAST_EAP_TYPE) + if (m_is_client == false + && m_tls_use_identity_privacy == false + && m_eap_type == eap_type_fast + && m_tls_session_type == tls_session_type_full_authentication) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: analyse_handshake_type_certificate(): ") + EAPL("EAP-FAST %s allows anonymous client.\n"), + (m_is_client == true ? "client": "server"), + (m_is_client == true ? "client": "server"))); + + m_tls_peap_server_authenticates_client_action = false; + m_tls_identity_privacy_handshake_state = tls_identity_privacy_handshake_state_none; + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: analyse_handshake_type_certificate(): ") + EAPL("TLS %s does NOT allow anonymous %s.\n"), + (m_is_client == true ? "client": "server"), + (m_is_client == true ? "client": "server"), + (m_is_client == false ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_insufficient_security); + } + } + else + { + status = copy( + certificate_chain, + &m_peer_certificate_chain, + m_am_tools, + false); + if (status != eap_status_ok + || m_peer_certificate_chain.get_object_count() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_is_client == true) + { + status = completion_action_add(tls_completion_action_verify_certificate_chain); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: query_certificate_chain()\n"), + (m_is_client == true ? "client": "server"))); + + status = m_am_tls_services->query_certificate_chain( + &m_peer_certificate_authorities, + &m_peer_certificate_types, + m_selected_cipher_suite); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_query_certificate_chain() call. + m_pending_query_certificate_chain = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_query_certificate_chain() call. + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this + // call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else if (m_is_client == false + && m_tls_peap_server_authenticates_client_action == true) + { + // This is server. + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (m_tls_session_type == tls_session_type_full_authentication + && m_tls_use_identity_privacy == true + && certificate_chain->get_object_count() == 0ul) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: TLS identity privacy does not verify client certificate yet.\n"), + (m_is_client == true ? "client": "server"))); + status = eap_status_ok; + } + else +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: verify_certificate_chain()\n"), + (m_is_client == true ? "client": "server"))); + + status = m_am_tls_services->verify_certificate_chain( + &m_peer_certificate_chain, + m_selected_cipher_suite); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_verify_certificate_chain() call. + m_pending_verify_certificate_chain = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_verify_certificate_chain() call. + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this + // call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + } + else if (m_is_client == false + && m_tls_peap_server_authenticates_client_action == false) + { + // This is server. Server allows anonymous client. + status = eap_status_ok; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (status == eap_status_completed_request) + { + status = eap_status_ok; + } + + if (m_is_client == true) + { + if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true) + { + set_state(tls_peap_state_wait_handshake_type_server_key_exchange); + } + else if (cipher_suite_is_TLS_RSA() == true) + { + set_state(tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + } + else + { + // Server. + set_state(tls_peap_state_wait_handshake_type_client_key_exchange); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_certificate_request( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_certificate_request()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_certificate_request()"); + + EAP_ASSERT_ALWAYS(m_is_client == true); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CT length | CT 1 | CT 2 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CT 3 | CT 4 | CAs length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CA 1 length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | Distinguished name of Certificate Authority 1 | + // + + + // | | + // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | CA 2 length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | Distinguished name of Certificate Authority 2 | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + eap_status_e status = eap_status_not_supported; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + EAP_TEMPLATE_CONST eap_array_c * const certificate_types + = handshake_message->get_certificate_types(); + + if (certificate_types->get_object_count() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = copy_simple( + certificate_types, + &m_peer_certificate_types, + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + EAP_TEMPLATE_CONST eap_array_c * const certificate_authorities + = handshake_message->get_certificate_authorities(); + + if (certificate_authorities->get_object_count() == 0ul + && m_client_allows_empty_certificate_authorities_list == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = copy( + certificate_authorities, + &m_peer_certificate_authorities, + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + + m_tls_peap_server_requested_client_certificate = true; + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(tls_peap_state_wait_handshake_type_server_hello_done); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_server_hello_done( + EAP_TEMPLATE_CONST tls_handshake_message_c * const /*handshake_message*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_server_hello_done()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_server_hello_done()"); + + EAP_ASSERT(m_is_client == true); + + eap_status_e status = eap_status_process_general_error; + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // + // ServerHelloDone message does not include payload. + + if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_RSA() == true + || cipher_suite_is_TLS_DHE_RSA() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + if (m_tls_peap_server_requested_client_certificate == true) + { + status = completion_action_add(tls_completion_action_create_handshake_type_certificate); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = completion_action_add( + tls_completion_action_create_handshake_type_client_key_exchange); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = completion_action_add( + tls_completion_action_complete_create_handshake_type_client_key_exchange); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_tls_peap_server_authenticates_client_action == true +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + && ( + m_tls_use_identity_privacy == false + || (m_tls_session_type == tls_session_type_full_authentication + && m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs)) +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + ) + { + status = completion_action_add( + tls_completion_action_create_handshake_type_certificate_verify); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This will complete creation of handshake_type_certificate_verify message. + status = completion_action_add( + tls_completion_action_complete_create_handshake_type_certificate_verify); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Also the other pending messages will be processed after this action is completed. + eap_status_e compl_status = completion_action_add( + tls_completion_action_process_tls_records); + if (compl_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = completion_action_add( + tls_completion_action_create_change_cipher_spec_type_change_cipher_spec); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = completion_action_add(tls_completion_action_create_handshake_type_finished); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(tls_peap_state_wait_change_cipher_spec); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_server_key_exchange( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_server_key_exchange()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_server_key_exchange()"); + + eap_status_e status = eap_status_not_supported; + +#if EAP_TLS_UNSUPPORTED_CIPHER_SUITE + #error This one needs more code. RSA key exchange with different parameters is NOT supported. + if (cipher_suite_is_TLS_RSA() == true) + { + // RSA modulus and exponent are included when selected cipher suite + // is using RSA key exchange + // and parameters are different than included in the certificate. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | rsa_modulus length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | rsa_modulus | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | rsa_exponent length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + rsa_exponent + + // | | + // + + + // | | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed MD5 hash 16 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed SHA-1 hash 20 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + else +#endif + if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true) + { + // Diffie-Hellman prime modulus, generator and server's + // Diffie-Hellman public value (g^X mod p) + // are included when selected cipher suite is ephemeral Diffie-Hellman key exchange. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH p length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH p value (prime modulus) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH g length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH g value (generator) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Ys length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Ys value | + // + (server's Diffie-Hellman public value) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed SHA-1 hash 47 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (handshake_message->get_dhe_prime() == 0 + || handshake_message->get_dhe_prime()->get_is_valid_data() == false + || handshake_message->get_dhe_prime()->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + if (handshake_message->get_dhe_group_generator() == 0 + || handshake_message->get_dhe_group_generator()->get_is_valid_data() == false + || handshake_message->get_dhe_group_generator()->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + if (handshake_message->get_public_dhe_key() == 0 + || handshake_message->get_public_dhe_key()->get_is_valid_data() == false + || handshake_message->get_public_dhe_key()->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + if (handshake_message->get_signed_message_hash() == 0 + || handshake_message->get_signed_message_hash()->get_is_valid_data() == false + || handshake_message->get_signed_message_hash()->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_dhe_prime.set_copy_of_buffer(handshake_message->get_dhe_prime()); + if (status != eap_status_ok + || m_dhe_prime.get_is_valid_data() == false + || m_dhe_prime.get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = m_dhe_group_generator.set_copy_of_buffer( + handshake_message->get_dhe_group_generator()); + if (status != eap_status_ok + || m_dhe_group_generator.get_is_valid_data() == false + || m_dhe_group_generator.get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = m_peer_public_dhe_key.set_copy_of_buffer(handshake_message->get_public_dhe_key()); + if (status != eap_status_ok + || m_peer_public_dhe_key.get_is_valid_data() == false + || m_peer_public_dhe_key.get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true) + { + // We must verify the signature of ServerKeyExchange. + status = verify_signature_of_server_key_exchange( + handshake_message->get_signed_message_hash()); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_query_certificate_chain() call. + m_pending_verify_with_public_key = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_query_certificate_chain() call. + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this call + // is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) + { + // Diffie-Hellman prime modulus, generator and server's + // Diffie-Hellman public value (g^X mod p) + // are included when selected cipher suite is ephemeral Diffie-Hellman key exchange. + // NOTE: Here are no signed hash. This is not authenticated at all and vulnerable to + // man-in-the-middle attacks. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH p length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH p value (prime modulus) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH g length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH g value (generator) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Ys length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Ys value | + // + (server's Diffie-Hellman public value) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: analyse_handshake_type_server_key_exchange() no m_signed_message_hash\n"))); + + if (handshake_message->get_dhe_prime() == 0 + || handshake_message->get_dhe_prime()->get_is_valid_data() == false + || handshake_message->get_dhe_prime()->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + if (handshake_message->get_dhe_group_generator() == 0 + || handshake_message->get_dhe_group_generator()->get_is_valid_data() == false + || handshake_message->get_dhe_group_generator()->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + if (handshake_message->get_public_dhe_key() == 0 + || handshake_message->get_public_dhe_key()->get_is_valid_data() == false + || handshake_message->get_public_dhe_key()->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = m_dhe_prime.set_copy_of_buffer(handshake_message->get_dhe_prime()); + if (status != eap_status_ok + || m_dhe_prime.get_is_valid_data() == false + || m_dhe_prime.get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = m_dhe_group_generator.set_copy_of_buffer( + handshake_message->get_dhe_group_generator()); + if (status != eap_status_ok + || m_dhe_group_generator.get_is_valid_data() == false + || m_dhe_group_generator.get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = m_peer_public_dhe_key.set_copy_of_buffer(handshake_message->get_public_dhe_key()); + if (status != eap_status_ok + || m_peer_public_dhe_key.get_is_valid_data() == false + || m_peer_public_dhe_key.get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (/* status == eap_status_pending_request + ||*/ status == eap_status_completed_request) + { + status = eap_status_ok; + } + + // Next we wait certificate_request or server_hello_done + // If next message is certificate_request, server requires client authentication. + // If next message is server_hello_done, server does NOT require client authentication. + set_state(tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_client_key_exchange( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_client_key_exchange()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_client_key_exchange()"); + + eap_status_e status = eap_status_not_supported; + + + if (cipher_suite_is_TLS_RSA() == true) + { + // Encrypted premaster secret is included when selected cipher suite + // is using RSA key exchange. + // First two bytes are version of TLS. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // +-+-+-+-+-+-+-+-+ + + // | | + // + + + // | Encrypted Premaster Secret (48 bytes) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (handshake_message->get_encrypted_premaster_secret() == 0 + || handshake_message->get_encrypted_premaster_secret()->get_is_valid_data() == false + || handshake_message->get_encrypted_premaster_secret()->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: rsa_decrypt_with_private_key()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: analyse_handshake_type_client_key_exchange(): encrypted premaster_secret"), + handshake_message->get_encrypted_premaster_secret()->get_data(), + handshake_message->get_encrypted_premaster_secret()->get_data_length())); + + status = m_am_tls_services->rsa_decrypt_with_private_key( + handshake_message->get_encrypted_premaster_secret()); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_rsa_decrypt_with_private_key() call. + m_pending_rsa_decrypt_with_private_key = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_rsa_decrypt_with_private_key() call. + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this call + // is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + // Diffie-Hellman prime modulus, generator and server's + // Diffie-Hellman public value (g^X mod p) + // are included when selected cipher suite is ephemeral Diffie-Hellman key exchange. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH p length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH p value (prime modulus) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH g length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH g value (generator) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Ys length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Ys value | + // + (server's Diffie-Hellman public value) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (handshake_message->get_public_dhe_key() == 0 + || handshake_message->get_public_dhe_key()->get_is_valid_data() == false + || handshake_message->get_public_dhe_key()->get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + status = m_peer_public_dhe_key.set_copy_of_buffer(handshake_message->get_public_dhe_key()); + if (status != eap_status_ok + || m_peer_public_dhe_key.get_is_valid_data() == false + || m_peer_public_dhe_key.get_data_length() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + + // We must generate premaster secret. + status = generate_premaster_secret(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // We must generate master secret. + status = generate_master_secret(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // We must generate the key material. + status = generate_key_material(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (/*status == eap_status_pending_request + ||*/ status == eap_status_completed_request) + { + status = eap_status_ok; + } + + if (m_tls_peap_server_authenticates_client_action == true) + { + set_state(tls_peap_state_wait_handshake_type_certificate_verify); + } + else + { + set_state(tls_peap_state_wait_change_cipher_spec); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_certificate_verify( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_certificate_verify()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_certificate_verify()"); + + eap_status_e status = eap_status_not_supported; + + if (cipher_suite_is_TLS_RSA() == true + || cipher_suite_is_TLS_DHE_RSA() == true + || cipher_suite_is_TLS_DHE_DSS() == true) + { + // Signatures when RSA is used: + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // +-+-+-+-+-+-+-+-+ + + // | | + // + Signed MD5 hash + + // | (16 bytes) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + Signed SHA hash + + // | (20 bytes) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // Signature when DSA is used: + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // +-+-+-+-+-+-+-+-+ + + // | | + // + Signed SHA hash + + // | (48 bytes) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + eap_variable_data_c signed_certificate_verify_hash(m_am_tools); + + status = signed_certificate_verify_hash.set_copy_of_buffer( + handshake_message->get_signed_message_hash()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (signed_certificate_verify_hash.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_variable_data_c message_hash(m_am_tools); + + status = message_hash_create( + true, + tls_handshake_type_certificate_verify, + &message_hash, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: analyse_handshake_type_certificate_verify()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: analyse_handshake_type_certificate_verify(): message_hash"), + message_hash.get_data(message_hash.get_data_length()), + message_hash.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: analyse_handshake_type_certificate_verify(): signed_certificate_verify_hash"), + signed_certificate_verify_hash.get_data( + signed_certificate_verify_hash.get_data_length()), + signed_certificate_verify_hash.get_data_length())); + + status = m_am_tls_services->verify_with_public_key( + &message_hash, + &signed_certificate_verify_hash); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_query_certificate_chain() call. + m_pending_verify_with_public_key = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_query_certificate_chain() call. + status = eap_status_ok; + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this call + // is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + set_state(tls_peap_state_wait_change_cipher_spec); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_finished( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_finished()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_finished()"); + + eap_status_e status = eap_status_not_supported; + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (handshake_message->get_finished_data() == 0 + || handshake_message->get_finished_data()->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + eap_variable_data_c message_hash(m_am_tools); + + bool client_originated_message = true; + if (m_is_client == true) + { + client_originated_message = false; + } + + status = message_hash_create_finished(client_originated_message, &message_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (message_hash.compare(handshake_message->get_finished_data()) != 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: analyse_handshake_type_finished(): ") + EAPL("verify check finished data failed, m_tls_session_type=%d=%s.\n"), + (m_is_client == true ? "client": "server"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type) + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); + } + else + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_handshake_type_finished(): ") + EAPL("verify check finished data OK, m_tls_session_type=%d=%s.\n"), + (m_is_client == true ? "client": "server"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type))); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if ((m_is_client == false + && m_tls_session_type == tls_session_type_full_authentication) + || (m_is_client == true + && (m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption +#if defined(USE_FAST_EAP_TYPE) + || m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + ) + ) + { + // We need to send ChangeCipherSpec and Handshake/Finished. + +#if defined(USE_EAP_TLS_SESSION_TICKET) + if ( + m_is_client == false +#if defined(USE_FAST_EAP_TYPE) + && m_eap_type != eap_type_fast +#endif //#if defined(USE_FAST_EAP_TYPE) +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + && (m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none + || m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs) +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + && m_tls_session_type == tls_session_type_full_authentication + && tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + &m_supported_tls_extensions, + m_am_tools) != 0) + { + { + const tls_extension_c * const supported_session_ticket_extension = tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + &m_supported_tls_extensions, + m_am_tools); + EAP_UNREFERENCED_PARAMETER(supported_session_ticket_extension); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_handshake_type_finished(): ") + EAPL("SST: Server will send a new session ticket to client, length = %d.\n"), + (m_is_client == true ? "client": "server"), + supported_session_ticket_extension->get_data_length())); + } + + // Server will send a new session ticket to client. + status = completion_action_add( + tls_completion_action_create_handshake_type_new_session_ticket); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + status = completion_action_add( + tls_completion_action_create_change_cipher_spec_type_change_cipher_spec); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = completion_action_add(tls_completion_action_create_handshake_type_finished); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (m_is_client == false + && m_tls_session_type == tls_session_type_full_authentication + && m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_negotiates) + { + status = completion_action_add(tls_completion_action_create_handshake_type_hello_request); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + status = completion_action_add(tls_completion_action_check_sent_tls_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_is_client == false + && m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) + { + status = completion_action_add( + tls_completion_action_create_change_cipher_spec_type_change_cipher_spec); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = completion_action_add(tls_completion_action_create_handshake_type_finished); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = completion_action_add(tls_completion_action_check_sent_tls_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none + || m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs + || m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_negotiates + ) +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + { + // Authentication OK. + status = completion_action_add(tls_completion_action_finish_handshake); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = completion_action_add(tls_completion_action_process_tls_records); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_is_client == false + && m_eap_type == eap_type_fast + && m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption) + { + status = completion_action_add(tls_completion_action_check_tunnel_authentication_runs); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + } + + m_received_eap_identifier = received_eap_identifier; + + + set_state(tls_peap_state_process_pending_tls_completions); + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_new_session_ticket( + EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message, + const u8_t /* received_eap_identifier */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_new_session_ticket()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_new_session_ticket()"); + + eap_status_e status = eap_status_not_supported; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TEMPLATE_CONST eap_array_c * const tls_extensions + = handshake_message->get_tls_extensions(); + + if (tls_extensions == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + const tls_extension_c * const session_ticket = tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + tls_extensions, + m_am_tools); + + if (session_ticket == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + m_received_tls_extensions.reset(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_handshake_type_new_session_ticket(): ") + EAPL("SST: session ticket received, length = %d.\n"), + (m_is_client == true ? "client": "server"), + session_ticket->get_data_length())); + + tls_extension_c * const copy_of_session_ticket = session_ticket->copy(); + + if (copy_of_session_ticket == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_received_tls_extensions.add_object(copy_of_session_ticket, true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_tls_protocol_change_cipher_spec( + const tls_record_message_c * const record) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_change_cipher_spec()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_tls_protocol_change_cipher_spec()"); + + eap_status_e status = eap_status_not_supported; + + u32_t ind_change_cipher_spec = 0ul; + + for (ind_change_cipher_spec = 0ul + ; ind_change_cipher_spec < record->get_change_cipher_spec_count() + ; ind_change_cipher_spec++) + { + const tls_change_cipher_spec_message_c * const change_cipher_spec_message + = record->get_change_cipher_spec(ind_change_cipher_spec); + + switch (change_cipher_spec_message->get_change_cipher_spec_type()) + { + case tls_change_cipher_spec_type_change_cipher_spec: + + if (m_tls_session_type == tls_session_type_stateless_session_resumption +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + || (m_tls_session_type == tls_session_type_full_authentication + && m_tls_use_identity_privacy == true + && m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs) +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + ) + { + // We must generate the key material. + status = generate_key_material(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // We change the receive cipher suite. + status = change_cipher_spec(false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + set_state(tls_peap_state_wait_handshake_type_finished); + } + + break; + + default: + + set_state(tls_peap_state_failure); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } // switch() + + } // for() + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_tls_protocol_alert( + const tls_record_message_c * const record) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_alert()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_tls_protocol_alert()"); + + eap_status_e status = eap_status_authentication_failure; + + u32_t ind_alert = 0ul; + + m_new_tls_message.reset(); + + + for (ind_alert = 0ul + ; ind_alert < record->get_alert_count() + ; ind_alert++) + { + const tls_alert_message_c * const alert_message + = record->get_alert(ind_alert); + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s: EAP_type_TLS_PEAP: Alert message %s:%s\n"), + (m_is_client == true) ? "client": "server", + eap_tls_trace_string_c::get_alert_level_string(alert_message->get_alert_level()), + eap_tls_trace_string_c::get_alert_description_string(alert_message->get_alert_description()))); + + if (m_application != 0) + { + // Indication to TLS-application. + (void) m_application->alert_received( + alert_message->get_alert_level(), + alert_message->get_alert_description()); + } + + // indication to TLS AM. + m_am_tls_services->alert_received( + alert_message->get_alert_level(), + alert_message->get_alert_description()); + + switch (alert_message->get_alert_description()) + { + case tls_alert_description_close_notify: + break; + case tls_alert_description_unexpected_message: + // This message is always fatal. + break; + case tls_alert_description_bad_record_mac: + // This message is always fatal. + break; + case tls_alert_description_decryption_failed: + // This message is always fatal. + break; + case tls_alert_description_record_overflow: + // This message is always fatal. + break; + case tls_alert_description_decompression_failure: + // This message is always fatal. + break; + case tls_alert_description_handshake_failure: + // This message is always fatal. + break; + case tls_alert_description_bad_certificate: + break; + case tls_alert_description_unsupported_certificate: + break; + case tls_alert_description_certificate_revoked: + break; + case tls_alert_description_certificate_expired: + break; + case tls_alert_description_certificate_unknown: + break; + case tls_alert_description_illegal_parameter: + // This message is always fatal. + break; + case tls_alert_description_unknown_ca: + // This message is always fatal. + break; + case tls_alert_description_access_denied: + // This message is always fatal. + break; + case tls_alert_description_decode_error: + // This message is always fatal. + break; + case tls_alert_description_decrypt_error: + break; + case tls_alert_description_export_restriction: + // This message is always fatal. + break; + case tls_alert_description_protocol_version: + // This message is always fatal. + break; + case tls_alert_description_insufficient_security: + // This message is always fatal. + break; + case tls_alert_description_internal_error: + // This message is always fatal. + break; + case tls_alert_description_user_canceled: + break; + case tls_alert_description_no_renegotiation: + // This message is always a warning. + break; + case tls_alert_description_none: + break; + default: + break; + } // switch() + + } // for() + + + set_state(tls_peap_state_failure); + + // This will cause the session terminate immediately. + status = get_type_partner()->set_session_timeout(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + { + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_internal_type, + 0, + tls_peap_state_none, + eap_state_authentication_terminated_unsuccessfully, + 0, + false); + + notification.set_authentication_error(eap_status_authentication_failure); + + get_type_partner()->state_notification(¬ification); + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_record_protocol_e tls_record_c::get_next_tls_record_message_protocol() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::get_next_tls_record_message_protocol()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_next_tls_record_message_protocol()"); + + tls_record_protocol_e record_protocol(tls_record_protocol_none); + + if (m_received_tls_message.get_record_message_count() <= m_received_tls_message.get_analyse_index()+1ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return record_protocol; + } + + tls_record_message_c * const tls_record_message + = m_received_tls_message.get_record_message(m_received_tls_message.get_analyse_index()+1ul); + if (tls_record_message == 0 + || tls_record_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return record_protocol; + } + + const u32_t tls_record_length = tls_record_message->get_record_message_data()->get_data_length(); + + if (tls_record_message->get_record_message_data()->get_data_length() < tls_record_header_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return record_protocol; + } + + tls_record_header_c tls_record_header( + m_am_tools, + tls_record_message->get_record_message_data()->get_data( + tls_record_header_c::get_header_length()), + tls_record_length); + + if (tls_record_header.get_is_valid() == false + || tls_record_length < tls_record_header.get_data_length() + || tls_record_length + < tls_record_header.get_header_length() + + tls_record_header.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return record_protocol; + } + + record_protocol = tls_record_header.get_protocol(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: ends: tls_record_c::get_next_tls_record_message_protocol(): %d=%s\n"), + (m_is_client == true ? "client": "server"), + record_protocol, + tls_record_header_c::get_tls_protocol_string(record_protocol))); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return record_protocol; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_handshake_type_e tls_record_c::get_next_tls_handshake_message_type() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::get_next_tls_handshake_message_type()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_next_tls_handshake_message_type()"); + + tls_handshake_type_e handshake_type(tls_handshake_type_none); + + if (m_received_tls_message.get_record_message_count() <= m_received_tls_message.get_analyse_index()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return handshake_type; + } + + tls_record_message_c * const tls_record_message + = m_received_tls_message.get_record_message(m_received_tls_message.get_analyse_index()); + if (tls_record_message == 0 + || tls_record_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return handshake_type; + } + + const u32_t tls_record_length = tls_record_message->get_record_message_data()->get_data_length(); + + if (tls_record_message->get_record_message_data()->get_data_length() < tls_record_header_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return handshake_type; + } + + tls_record_header_c tls_record_header( + m_am_tools, + tls_record_message->get_record_message_data()->get_data( + tls_record_header_c::get_header_length()), + tls_record_length); + + if (tls_record_header.get_is_valid() == false + || tls_record_length < tls_record_header.get_data_length() + || tls_record_length + < tls_record_header.get_header_length() + + tls_record_header.get_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return handshake_type; + } + + tls_record_protocol_e tls_protocol(tls_record_header.get_protocol()); + + if (tls_protocol == tls_record_protocol_handshake) + { + if (tls_record_message->get_handshake_count() <= tls_record_message->get_analyse_index()+1ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return handshake_type; + } + + tls_handshake_message_c * const handshake_message = tls_record_message->get_handshake(tls_record_message->get_analyse_index()+1ul); + + if (handshake_message == 0 + || handshake_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return handshake_type; + } + + handshake_type = handshake_message->get_handshake_type(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: ends: tls_record_c::get_next_tls_handshake_message_type(): %d=%s\n"), + (m_is_client == true ? "client": "server"), + handshake_type, + tls_handshake_header_c::get_tls_handshake_string(handshake_type))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return handshake_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_tls_protocol_handshake( + tls_record_message_c * const record, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_handshake()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_tls_protocol_handshake()"); + + eap_status_e status = eap_status_ok; + + u32_t ind_handshake = 0ul; + + for (ind_handshake = record->get_analyse_index() + ; ind_handshake < record->get_handshake_count() + ; ind_handshake++) + { + // This is used in EAP-FAST to see the next TLS-handshake message type. + record->save_analyse_index(ind_handshake); + + tls_handshake_message_c * const handshake_message = record->get_handshake(ind_handshake); + + if (handshake_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_tls_protocol_handshake(): ") + EAPL("handshake type %d, analysed %d\n"), + (m_is_client == true ? "client": "server"), + handshake_message->get_handshake_type(), + handshake_message->get_is_analysed())); + + if (handshake_message->get_is_analysed() == false) + { + handshake_message->set_is_analysed(); + + switch (handshake_message->get_handshake_type()) + { + case tls_handshake_type_hello_request: + status = analyse_handshake_type_hello_request( + handshake_message); + break; + case tls_handshake_type_client_hello: + if (m_tls_peap_test_version == true + && verify_state(tls_peap_state_tls_success) == true) + { + // OK, this is test version. + } + else if (verify_state(tls_peap_state_wait_handshake_type_client_hello) == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string( + tls_peap_state_wait_handshake_type_client_hello))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + status = analyse_handshake_type_client_hello( + handshake_message); + break; + case tls_handshake_type_server_hello: + if (verify_state(tls_peap_state_wait_handshake_type_server_hello) == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string( + tls_peap_state_wait_handshake_type_server_hello))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + status = analyse_handshake_type_server_hello( + handshake_message); + break; + case tls_handshake_type_certificate: + if (m_tls_session_type == tls_session_type_stateless_session_resumption + && verify_state(tls_peap_state_wait_change_cipher_spec) == true) + { + // Server wish to initiate a full handshake. + m_tls_session_type = tls_session_type_full_authentication; + set_state(tls_peap_state_wait_handshake_type_certificate); + } + else if (verify_state(tls_peap_state_wait_handshake_type_certificate) == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string( + tls_peap_state_wait_handshake_type_certificate))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + status = analyse_handshake_type_certificate( + handshake_message); + break; + case tls_handshake_type_server_key_exchange: + if (verify_state(tls_peap_state_wait_handshake_type_server_key_exchange) == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string( + tls_peap_state_wait_handshake_type_server_key_exchange))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + status = analyse_handshake_type_server_key_exchange( + handshake_message); + break; + case tls_handshake_type_certificate_request: + if (verify_state( + tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done) + == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string( + tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + status = analyse_handshake_type_certificate_request( + handshake_message); + break; + case tls_handshake_type_server_hello_done: + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: analyse_tls_protocol_handshake(): m_tls_peap_server_authenticates_client_policy_flag=%d\n"), + (m_is_client == true ? "client": "server"), + m_tls_peap_server_authenticates_client_policy_flag)); + + if (verify_state( + tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done) + == true) + { + if (m_tls_peap_server_authenticates_client_policy_flag == false) + { + // Client accepts server only authentication. + m_tls_peap_server_authenticates_client_action = false; + } + else + { + // ERROR: Client does NOT accept server only authentication. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: current state %s: ") + EAPL("Client does NOT accept server only authentication.\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_insufficient_security); + } + } + else if (verify_state(tls_peap_state_wait_handshake_type_server_hello_done) + == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string( + tls_peap_state_wait_handshake_type_server_hello_done))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + status = analyse_handshake_type_server_hello_done( + handshake_message); + break; + case tls_handshake_type_certificate_verify: + if (verify_state(tls_peap_state_wait_handshake_type_certificate_verify) == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string( + tls_peap_state_wait_handshake_type_certificate_verify))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + status = analyse_handshake_type_certificate_verify( + handshake_message); + break; + case tls_handshake_type_client_key_exchange: + if (verify_state(tls_peap_state_wait_handshake_type_client_key_exchange) == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string( + tls_peap_state_wait_handshake_type_client_key_exchange))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + status = analyse_handshake_type_client_key_exchange( + handshake_message); + break; + case tls_handshake_type_finished: + if (verify_state(tls_peap_state_wait_handshake_type_finished) == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string( + tls_peap_state_wait_handshake_type_finished))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + status = analyse_handshake_type_finished( + handshake_message, + received_eap_identifier); + break; +#if defined(USE_EAP_TLS_SESSION_TICKET) + case tls_handshake_type_new_session_ticket: + { + // Note This is optional Handshake message. + + const tls_extension_c * const supported_session_ticket_extension = tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + &m_supported_tls_extensions, + m_am_tools); + + if (supported_session_ticket_extension != 0 + && (verify_state(tls_peap_state_wait_change_cipher_spec) == true + || verify_state(tls_peap_state_wait_handshake_type_new_session_ticket) == true)) + { + // OK new Session ticket handshake allowed. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: function: verify_state(): SST: current state %s == %s: Session Ticket Handshake allowed, length = %d.\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string( + tls_peap_state_wait_handshake_type_new_session_ticket), + supported_session_ticket_extension->get_data_length())); + } + else if (verify_state(tls_peap_state_wait_handshake_type_new_session_ticket) == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: function: verify_state(): SST: current state %s != %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_state_string( + tls_peap_state_wait_handshake_type_new_session_ticket))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); + } + + status = analyse_handshake_type_new_session_ticket( + handshake_message, + received_eap_identifier); + break; + } +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + default: + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } // switch() + } + + if (status == eap_status_pending_request) + { + // Save pending state. + record->save_analyse_index(ind_handshake); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if ((get_is_tunneled_tls() == false + && m_tls_peap_state == tls_peap_state_tls_success) + || (get_is_tunneled_tls() == true + && m_tls_peap_state == tls_peap_state_peap_tunnel_ready)) + { + // Stop processing TLS-records. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // for() + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_tls_protocol_application_data( + const tls_record_message_c * const record, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_application_data()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_tls_protocol_application_data()"); + + eap_status_e status = eap_status_ok; + + u32_t ind; + for (ind = 0ul + ; ind < record->get_application_data_count() + ; ind++) + { + tls_application_data_message_c * const application_data_message + = record->get_application_data(ind); + if (application_data_message == 0 + || application_data_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (application_data_message->get_is_analysed() == false) + { + application_data_message->set_is_analysed(); + + if (m_application == 0) + { + // ERROR: No application. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_application_data(): no application.\n"), + (m_is_client == true ? "client": "server"))); + status = eap_status_illegal_data_payload; + } + else + { + status = m_application->packet_process( + application_data_message->get_application_data(), + received_eap_identifier); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_application_data(): already analysed.\n"), + (m_is_client == true ? "client": "server"))); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::are_pending_queries_completed() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_pending_request; + + eap_status_string_c status_string; + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pending_function: starts: tls_record_c::are_pending_queries_completed(): %s\n"), + (m_is_client == true ? "client": "server"), + status_string.get_status_string(status))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::are_pending_queries_completed()"); + + if (m_pending_query_certificate_authorities_and_types == false + && m_pending_query_certificate_chain == false + && m_pending_query_cipher_suites_and_previous_session == false + && m_pending_query_dh_parameters == false + && m_pending_query_realm == false + && m_pending_select_cipher_suite_and_check_session_id == false + && m_pending_verify_certificate_chain == false + && m_pending_rsa_decrypt_with_private_key == false + && m_pending_rsa_encrypt_with_public_key == false + && m_pending_sign_with_private_key == false + && m_pending_verify_with_public_key == false + && m_pending_query_tunnel_PAC == false) + { + status = eap_status_ok; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pending_function: are_pending_queries_completed(): %s\n"), + (m_is_client == true ? "client": "server"), + status_string.get_status_string(status))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::indicate_state_to_lower_layer( + const tls_peap_state_e indicated_state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Notify lower layer the state of TLS. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: state_function: starts: tls_record_c::indicate_state_to_lower_layer(): m_tls_session_type=%d=%s, state=%d=%s\n"), + (m_is_client == true ? "client": "server"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + indicated_state, + eap_tls_trace_string_c::get_state_string(indicated_state))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::indicate_state_to_lower_layer()"); + + +#if defined(USE_EAP_TRACE_ALWAYS) + + if (m_tls_peap_state == tls_peap_state_tls_success) + { + + tls_identity_privacy_handshake_state_e tmp_identity_privacy_handshake_state = +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + m_tls_identity_privacy_handshake_state; +#else + tls_identity_privacy_handshake_state_none; +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: indicate_state_to_lower_layer(): TLS/PEAP authentication ") + EAPL("SUCCESS: %s, %s, tunnel %d, tunneling type %s, tunneling version %s, cipher_suite %s, %s\n"), + (m_is_client == true ? "client": "server"), + (m_tls_peap_server_authenticates_client_action == true + ? "mutual": "anonymous client"), + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + get_is_tunneled_tls(), + eap_header_string_c::get_eap_type_string(m_eap_type), + eap_tls_trace_string_c::get_peap_version_string(m_peap_version), + eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite), + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state))); + } + else if (m_tls_peap_state == tls_peap_state_peap_tunnel_ready + || m_tls_peap_state == tls_peap_state_wait_application_data) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: indicate_state_to_lower_layer(): TLS/PEAP authentication ") + EAPL("tunnel ready: %s, %s, tunnel %d, tunneling type %s, tunneling version %s, cipher_suite %s\n"), + (m_is_client == true ? "client": "server"), + (m_tls_peap_server_authenticates_client_action == true + ? "mutual": "anonymous client"), + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + get_is_tunneled_tls(), + eap_header_string_c::get_eap_type_string(m_eap_type), + eap_tls_trace_string_c::get_peap_version_string(m_peap_version), + eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite))); + + } + else if (m_tls_peap_state == tls_peap_state_failure) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: indicate_state_to_lower_layer(): TLS/PEAP authentication ") + EAPL("FAILED: %s, %s, tunnel %d, tunneling type %s, tunneling version %s, cipher_suite %s\n"), + (m_is_client == true ? "client": "server"), + (m_tls_peap_server_authenticates_client_action == true ? "mutual": "anonymous client"), + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + get_is_tunneled_tls(), + eap_header_string_c::get_eap_type_string(m_eap_type), + eap_tls_trace_string_c::get_peap_version_string(m_peap_version), + eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite))); + } + +#endif //#if !defined(USE_EAP_TRACE_ALWAYS) + + + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_internal_type, + 0, + tls_peap_state_none, + indicated_state, + 0, + false); + get_type_partner()->state_notification(¬ification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::indicate_messages_processed() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Notify lower layer that TLS-messages are processed. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: state_function: starts: tls_record_c::indicate_messages_processed(): %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::indicate_messages_processed()"); + + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_generic, + eap_protocol_layer_internal_type, + 0, + tls_peap_state_none, + tls_peap_state_pending_tls_messages_processed, + 0, + false); + get_type_partner()->state_notification(¬ification); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::send_tls_message() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: starts: tls_record_c::send_tls_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::send_tls_message()"); + + eap_variable_data_c tls_message_buffer(m_am_tools); + + bool includes_tls_handshake_message = false; + + eap_status_e status = m_new_tls_message.add_message_data( + &tls_message_buffer, + &includes_tls_handshake_message); + if (status != eap_status_ok) + { + m_new_tls_message.reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + eap_buf_chain_wr_c sent_packet( + eap_write_buffer, + m_am_tools, + tls_message_buffer.get_data(tls_message_buffer.get_data_length()), + tls_message_buffer.get_data_length(), + false, + false, + 0ul); + if (sent_packet.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("send TLS-message"), + sent_packet.get_data(sent_packet.get_data_length()), + sent_packet.get_data_length())); + + status = get_type_partner()->tls_peap_packet_send( + &sent_packet, + 0ul, + sent_packet.get_data_length(), + sent_packet.get_data_length(), + includes_tls_handshake_message + ); + + m_new_tls_message.reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::check_sent_tls_message() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: starts: tls_record_c::check_sent_tls_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::check_sent_tls_message()"); + + eap_status_e msg_status = eap_status_authentication_failure; + + if (m_already_in_completion_action_check == true) + { + // This is recursive call. Do not process yet. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + if (m_force_tls_message_send == true) + { + // There may be an alert message pending. + msg_status = send_tls_message(); + } + else + { + msg_status = are_pending_queries_completed(); + if (msg_status == eap_status_ok) + { + eap_status_e compl_status = completion_action_check(); + + if (compl_status == eap_status_pending_request) + { + // Some asyncronous query is still pending. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, compl_status); + } + else if (compl_status != eap_status_ok) + { + // There may be Alert message to be sent. + msg_status = compl_status; + } + + + if (m_allow_message_send == true) + { + if (msg_status == eap_status_ok + && m_new_tls_message.get_record_message_count() > 0ul) + { + // We could send the pending TLS-messages. + msg_status = send_tls_message(); + } + else if (m_force_tls_message_send == true // There may be Alert message to be sent. + && m_new_tls_message.get_record_message_count() > 0ul) + { + // We could send the pending TLS-messages. + send_tls_message(); + } + else + { + // No message to sent. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: send_function: check_sent_tls_message(), ") + EAPL("No message to sent.\n"), + (m_is_client == true ? "client": "server"))); + } + } + + if (msg_status == eap_status_ok + && m_allow_message_send == true) + { + eap_status_e indication_status = indicate_messages_processed(); + if (indication_status != eap_status_ok) + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, indication_status); + } + } + } + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, msg_status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_init() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: hash_function: starts: tls_record_c::message_hash_init()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_init()"); + + eap_status_e status = eap_status_not_supported; + + status = m_message_hash_md5.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_message_hash_sha1.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_update( + const bool true_when_parse_message, + const tls_handshake_type_e type, + u8_t * const tls_packet, + const u32_t tls_packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#if !defined(USE_EAP_DEBUG_TRACE) +EAP_UNREFERENCED_PARAMETER(true_when_parse_message); +EAP_UNREFERENCED_PARAMETER(type); +#endif + + eap_status_e status = eap_status_not_supported; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: hash_function: starts: tls_record_c::message_hash_update(): handshake type %s, %s\n"), + (m_is_client == true ? "client": "server"), + tls_handshake_header_c::get_tls_handshake_string(type), + (true_when_parse_message == true ? "parse": "create"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_update()"); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + EAP_TRACE_FLAGS_MESSAGE_DATA, + (EAPL("TLS: message_hash_update()"), + tls_packet, + tls_packet_length)); + + if (tls_packet == 0 + || tls_packet_length == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + status = m_message_hash_md5.hash_update(tls_packet, tls_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_message_hash_sha1.hash_update(tls_packet, tls_packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_create( + const bool true_when_parse_message, + const tls_handshake_type_e type, + eap_variable_data_c * const message_hash, + const bool client_originated) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#if !defined(USE_EAP_DEBUG_TRACE) +EAP_UNREFERENCED_PARAMETER(true_when_parse_message); +#endif + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: hash_function: starts: tls_record_c::message_hash_create(): handshake type %s, %s\n"), + (m_is_client == true ? "client": "server"), + tls_handshake_header_c::get_tls_handshake_string(type), + (true_when_parse_message == true ? "parse": "create"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_create()"); + + eap_status_e status = eap_status_not_supported; + + eap_variable_data_c * message_hash_md5 = 0; + eap_variable_data_c * message_hash_sha1 = 0; + + if (type == tls_handshake_type_certificate_verify) + { + message_hash_md5 = &m_message_hash_md5_certificate_verify; + message_hash_sha1 = &m_message_hash_sha1_certificate_verify; + } + else if (type == tls_handshake_type_finished) + { + if (client_originated == true) + { + message_hash_md5 = &m_client_message_hash_md5_finished; + message_hash_sha1 = &m_client_message_hash_sha1_finished; + } + else + { + message_hash_md5 = &m_server_message_hash_md5_finished; + message_hash_sha1 = &m_server_message_hash_sha1_finished; + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_type); + } + + u32_t md5_digest_length = message_hash_md5->get_data_length(); + + u32_t sha1_digest_length = message_hash_sha1->get_data_length(); + + if (cipher_suite_is_TLS_DHE_DSS() == true) + { + md5_digest_length = 0ul; + } + + status = message_hash->set_buffer_length(md5_digest_length+sha1_digest_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + message_hash->set_data_length(0ul); + + + + if (type == tls_handshake_type_certificate_verify) + { + if (cipher_suite_is_TLS_RSA() == true + || cipher_suite_is_TLS_DHE_RSA() == true) + { + status = message_hash->add_data(message_hash_md5); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (cipher_suite_is_TLS_RSA() == true + || cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true) + { + status = message_hash->add_data(message_hash_sha1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else if (type == tls_handshake_type_finished) + { + status = message_hash->add_data(message_hash_md5); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message_hash->add_data(message_hash_sha1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: message_hash_create(): message_hash"), + message_hash->get_data(message_hash->get_data_length()), + message_hash->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_final( + eap_variable_data_c * const md5_digest, + eap_variable_data_c * const sha1_digest) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: hash_function: starts: tls_record_c::message_hash_final()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_final()"); + + eap_status_e status = eap_status_process_general_error; + + if (md5_digest == 0 + || sha1_digest == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + { + // The copy of hash context saves original hash context for later use. + // This way we do need store only one SHA1 and MD5 context for all handshake message hashes. + abs_crypto_hash_algorithm_c * const copy_message_hash_md5 = m_message_hash_md5.copy(); + + eap_automatic_variable_c + deletes_copy_message_hash_md5(m_am_tools, copy_message_hash_md5); + + if (copy_message_hash_md5 == 0 + || copy_message_hash_md5->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = md5_digest->set_buffer_length(copy_message_hash_md5->get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + md5_digest->set_data_length(copy_message_hash_md5->get_digest_length()); + + u32_t digest_length = md5_digest->get_data_length(); + + status = copy_message_hash_md5->hash_final( + md5_digest->get_data(md5_digest->get_data_length()), + &digest_length); + if (digest_length != copy_message_hash_md5->get_digest_length()) + { + status = eap_status_process_general_error; + } + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + { + // The copy of hash context saves original hash context for later use. + // This way we do need store only one SHA1 and MD5 context for all handshake message hashes. + abs_crypto_hash_algorithm_c * const copy_message_hash_sha1 = m_message_hash_sha1.copy(); + + eap_automatic_variable_c + deletes_copy_message_hash_sha1(m_am_tools, copy_message_hash_sha1); + + if (copy_message_hash_sha1 == 0 + || copy_message_hash_sha1->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = sha1_digest->set_buffer_length(copy_message_hash_sha1->get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + sha1_digest->set_data_length(copy_message_hash_sha1->get_digest_length()); + + u32_t digest_length = sha1_digest->get_data_length(); + + status = copy_message_hash_sha1->hash_final( + sha1_digest->get_data(sha1_digest->get_data_length()), + &digest_length); + if (digest_length != copy_message_hash_sha1->get_digest_length()) + { + status = eap_status_process_general_error; + } + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_save_certificate_verify() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: hash_function: starts: tls_record_c::message_hash_save_certificate_verify()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_save_certificate_verify()"); + + eap_status_e status = eap_status_process_general_error; + + status = message_hash_final( + &m_message_hash_md5_certificate_verify, + &m_message_hash_sha1_certificate_verify); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_save_finished( + const bool client_originated) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: hash_function: starts: tls_record_c::message_hash_save_finished()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_save_finished()"); + + eap_variable_data_c *message_hash_md5_finished = &m_client_message_hash_md5_finished; + eap_variable_data_c *message_hash_sha1_finished = &m_client_message_hash_sha1_finished; + + eap_status_e status = eap_status_process_general_error; + + + if (client_originated == false) + { + message_hash_md5_finished = &m_server_message_hash_md5_finished; + message_hash_sha1_finished = &m_server_message_hash_sha1_finished; + } + + status = message_hash_final( + message_hash_md5_finished, + message_hash_sha1_finished); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_create_finished( + const bool client_originated_message, + eap_variable_data_c * const message_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: hash_function: starts: tls_record_c::message_hash_create_finished()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_create_finished()"); + + eap_status_e status = eap_status_not_supported; + + eap_variable_data_c label_finished(m_am_tools); + if (label_finished.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (client_originated_message == true) + { + status = label_finished.add_data( + TLS_CLIENT_FINISHED_LABEL, + TLS_CLIENT_FINISHED_LABEL_LENGTH); + } + else + { + status = label_finished.add_data( + TLS_SERVER_FINISHED_LABEL, + TLS_SERVER_FINISHED_LABEL_LENGTH); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c hash(m_am_tools); + if (hash.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = message_hash_create( + false, + tls_handshake_type_finished, + &hash, + client_originated_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: message_hash_create_finished(): m_master_secret"), + m_master_secret.get_data(), + m_master_secret.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: message_hash_create_finished(): label_finished"), + label_finished.get_data(), + label_finished.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: message_hash_create_finished(): hash"), + hash.get_data(), + hash.get_data_length())); + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: prf_function: tls_prf.tls_prf_output()\n"), + (m_is_client == true ? "client": "server"))); + + crypto_tls_prf_c tls_prf(m_am_tools); + + status = tls_prf.tls_prf_init( + &m_master_secret, + &label_finished, + &hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = message_hash->set_buffer_length(TLS_FINISHED_DATA_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + message_hash->set_data_length(TLS_FINISHED_DATA_SIZE); + + status = tls_prf.tls_prf_output( + message_hash->get_data(message_hash->get_data_length()), + message_hash->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: message_hash_create_finished(): message hash"), + message_hash->get_data(), + message_hash->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::packet_process( + eap_variable_data_c * const tls_packet, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + + tls_identity_privacy_handshake_state_e tmp_identity_privacy_handshake_state = +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + m_tls_identity_privacy_handshake_state; +#else + tls_identity_privacy_handshake_state_none; +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + EAP_UNREFERENCED_PARAMETER(tmp_identity_privacy_handshake_state); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::packet_process(): state %s, privacy_handshake_state=%d=%s, session_type=%s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + tmp_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state), + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::packet_process()"); + + m_received_tls_message.reset(); + + eap_status_e status = m_received_tls_message.set_tls_message_data( + tls_packet, + received_eap_identifier); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_automatic_simple_value_c restore_allow_message_send( + m_am_tools, + &m_allow_message_send, + true); + + // Packet send is delayed until after the process_tls_message() function returns. + m_allow_message_send = false; + + status = process_tls_message(); + + m_allow_message_send = true; + + + if (status != eap_status_pending_request) + { + // Note this call will return eap_status_pending_request if any asyncronous call is pending. + eap_status_e send_status = check_sent_tls_message(); + if (send_status != eap_status_ok) + { + status = send_status; + } + } + + if (status == eap_status_success + && m_tls_peap_state != tls_peap_state_tls_success) + { + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::plain_eap_success_failure_packet_received( + const eap_am_network_id_c * const receive_network_id, + const eap_code_value_e received_eap_code, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::plain_eap_success_failure_packet_received(): state %s, m_tls_session_type=%s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::plain_eap_success_failure_packet_received()"); + + eap_status_e status(eap_status_ok); + + if (received_eap_code == eap_code_success + && m_eap_type == eap_type_peap + && m_peap_version == peap_version_1 + && m_use_tppd_tls_peap == true) + { + status = m_am_tls_services->save_tls_session( + &m_session_id, + &m_master_secret, + m_selected_cipher_suite +#if defined(USE_EAP_TLS_SESSION_TICKET) + , tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + &m_received_tls_extensions, + m_am_tools) +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_eap_type == eap_type_fast) + { + if (received_eap_code == eap_code_success + && m_tls_peap_state == tls_peap_state_tls_success + && (m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption)) + { + eap_state_variable_e current_state(eap_state_authentication_finished_successfully); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_eap_type, + eap_state_none, + current_state, + m_received_eap_identifier, + false); + + state_notification(¬ification); + } + else + { + status = m_application->plain_eap_success_failure_packet_received( + receive_network_id, + received_eap_code, + received_eap_identifier); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + else if (m_eap_type == eap_type_peap + || m_eap_type == eap_type_ttls + ) + { + status = m_application->plain_eap_success_failure_packet_received( + receive_network_id, + received_eap_code, + received_eap_identifier); + } + + if (status != eap_status_pending_request) + { + // Note this call will return eap_status_pending_request if any asyncronous call is pending. + eap_status_e send_status = check_sent_tls_message(); + if (send_status != eap_status_ok) + { + status = send_status; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::empty_ack_packet_received( + const eap_am_network_id_c * const receive_network_id, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: starts: tls_record_c::empty_ack_packet_received(): state %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_state_string(m_tls_peap_state))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::empty_ack_packet_received()"); + + eap_status_e status(eap_status_not_supported); + + if (m_eap_type == eap_type_ttls) + { + status = m_application->empty_ack_packet_received( + receive_network_id, + received_eap_identifier); + + if (status != eap_status_pending_request) + { + // Note this call will return eap_status_pending_request if any asyncronous call is pending. + eap_status_e send_status = check_sent_tls_message(); + if (send_status != eap_status_ok) + { + status = send_status; + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: function: starts: tls_record_c::reset()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::reset()"); + + completion_action_clenup(); + + { + m_received_tls_message.reset(); + m_new_tls_message.reset(); + m_message_hash_md5.hash_cleanup(); + m_message_hash_sha1.hash_cleanup(); + m_message_hash_md5_certificate_verify.reset(); + m_message_hash_sha1_certificate_verify.reset(); + m_client_message_hash_md5_finished.reset(); + m_client_message_hash_sha1_finished.reset(); + m_server_message_hash_md5_finished.reset(); + m_server_message_hash_sha1_finished.reset(); + m_client_handshake_random_value.reset(); + m_server_handshake_random_value.reset(); + m_session_id.reset(); + m_master_secret.reset(); + m_eap_master_session_key.reset(); + m_send_mac_key.reset(); + m_receive_mac_key.reset(); + m_send_encryption_key.reset(); + m_receive_encryption_key.reset(); + m_send_iv.reset(); + m_receive_iv.reset(); + m_own_private_dhe_key.reset(); + m_own_public_dhe_key.reset(); + m_peer_public_dhe_key.reset(); + m_shared_dh_key.reset(); + m_dhe_prime.reset(); + m_dhe_group_generator.reset(); + m_signed_message_hash.reset(); + m_premaster_secret.reset(); +#if defined(USE_FAST_EAP_TYPE) + m_eap_fast_pac_key.reset(); +#endif //#if defined(USE_FAST_EAP_TYPE) + m_own_encrypted_premaster_secret.reset(); + m_proposed_cipher_suites.reset(); + m_proposed_compression_methods.reset(); + m_NAI_realm.reset(); + m_own_certificate_chain.reset(); + m_own_certificate_types.reset(); + m_own_certificate_authorities.reset(); + m_peer_certificate_chain.reset(); + m_peer_certificate_chain_result = eap_status_illegal_certificate; + m_verify_signature = eap_status_authentication_failure; + m_peer_certificate_types.reset(); + m_peer_certificate_authorities.reset(); + } + + eap_status_e status = message_hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_selected_cipher_suite(tls_cipher_suites_none); + m_selected_compression_method = tls_compression_method_none; + + status = set_receive_cipher_suite(tls_cipher_suites_TLS_NULL_WITH_NULL_NULL); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_receive_compression_method = tls_compression_method_null; + + status = set_send_cipher_suite(tls_cipher_suites_TLS_NULL_WITH_NULL_NULL); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_send_compression_method = tls_compression_method_null; + + m_completion_queue.reset(); + + m_send_record_sequence_number = 0ul; + m_receive_record_sequence_number = 0ul; + + m_key_material_generated = false; + + m_force_tls_message_send = false; + + if (m_is_client == false) + { + // Server + // NOTE: set_state() function cannot reset state. + m_tls_peap_state = tls_peap_state_wait_handshake_type_client_hello; + } + else + { + // Client + // NOTE: set_state() function cannot reset state. + m_tls_peap_state = tls_peap_state_wait_tls_start; + } + + m_tunneled_eap_type_authentication_state = eap_state_none; + + m_tls_peap_server_authenticates_client_action = true; + if (m_is_client == false + && m_tls_peap_server_authenticates_client_config_server == false) + { + m_tls_peap_server_authenticates_client_action = false; + } + + m_tls_peap_server_requested_client_certificate = false; + + m_could_send_fatal_alert_message = true; + m_could_send_warning_alert_message = true; + + if (m_application != 0) + { + m_application->reset(); + } + + reset_block_ciphers(true); + reset_block_ciphers(false); + + reset_stream_ciphers(true); + reset_stream_ciphers(false); + + reset_hmac_algorithms(true); + reset_hmac_algorithms(false); + + m_use_tppd_tls_peap = false; + m_use_tppd_peapv1_acknowledge_hack = false; + + m_will_receive_new_session_ticket = false; + +#if defined(USE_FAST_EAP_TYPE) + m_remove_tunnel_pac = false; +#endif //#if defined(USE_FAST_EAP_TYPE) + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_none); +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t tls_record_c::get_key_expansion_size( + u32_t * const mac_key_length, + u32_t * const encryption_key_length, + u32_t * const iv_length, + u32_t * const session_key_seed_length, + u32_t * const mschapv2_challenges_length + ) +{ + u32_t length = 0ul; + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: key_function: starts: tls_record_c::get_key_expansion_size()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_key_expansion_size()"); + + *mac_key_length = 0ul; + *encryption_key_length = 0ul; + *iv_length = 0ul; + *session_key_seed_length = 0ul; + *mschapv2_challenges_length = 0ul; + + if (cipher_suite_is_3DES_EDE_CBC_SHA(m_selected_cipher_suite) == true) + { + crypto_3des_ede_c ede_3des(m_am_tools); + + crypto_sha1_c sha1(m_am_tools); + crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false); + + if (hmac_sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + eap_variable_data_c tmp_key(m_am_tools); + if (tmp_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = tmp_key.add_data("", 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + status = hmac_sha1.hmac_set_key(&tmp_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + length = 2ul * hmac_sha1.get_digest_length() + + 2ul * ede_3des.get_key_length() + + 2ul * ede_3des.get_block_size(); + + *mac_key_length = hmac_sha1.get_digest_length(); + *encryption_key_length = ede_3des.get_key_length(); + *iv_length = ede_3des.get_block_size(); + } + else if (cipher_suite_is_AES_128_CBC_SHA(m_selected_cipher_suite) == true) + { + crypto_aes_c aes(m_am_tools); + + crypto_sha1_c sha1(m_am_tools); + crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false); + + if (hmac_sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c tmp_key(m_am_tools); + if (tmp_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = tmp_key.add_data("", 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + status = hmac_sha1.hmac_set_key(&tmp_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + length = 2ul * hmac_sha1.get_digest_length() + + 2ul * aes.get_key_length() + + 2ul * aes.get_block_size(); + + *mac_key_length = hmac_sha1.get_digest_length(); + *encryption_key_length = aes.get_key_length(); + *iv_length = aes.get_block_size(); + } + else if (cipher_suite_is_RC4_128_MD5(m_selected_cipher_suite) == true) + { + crypto_md5_c md5(m_am_tools); + crypto_hmac_c hmac_md5(m_am_tools, &md5, false); + + if (hmac_md5.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c tmp_key(m_am_tools); + if (tmp_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = tmp_key.add_data("", 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + status = hmac_md5.hmac_set_key(&tmp_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + length = 2ul * hmac_md5.get_digest_length() + + 2ul * TLS_RC4_128_KEY_LENGTH + + 2ul * TLS_RC4_128_IV_LENGTH; + + *mac_key_length = hmac_md5.get_digest_length(); + *encryption_key_length = TLS_RC4_128_KEY_LENGTH; + *iv_length = TLS_RC4_128_IV_LENGTH; + } + else if (cipher_suite_is_RC4_128_SHA(m_selected_cipher_suite) == true) + { + crypto_sha1_c sha1(m_am_tools); + crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false); + + if (hmac_sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c tmp_key(m_am_tools); + if (tmp_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = tmp_key.add_data("", 0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + status = hmac_sha1.hmac_set_key(&tmp_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; + } + + length = 2ul * hmac_sha1.get_digest_length() + + 2ul * TLS_RC4_128_KEY_LENGTH + + 2ul * TLS_RC4_128_IV_LENGTH; + + *mac_key_length = hmac_sha1.get_digest_length(); + *encryption_key_length = TLS_RC4_128_KEY_LENGTH; + *iv_length = TLS_RC4_128_IV_LENGTH; + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast) + { + *session_key_seed_length = EAP_FAST_SESSION_KEY_SEED_LENGTH; + length += EAP_FAST_SESSION_KEY_SEED_LENGTH; + + if (m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP + && m_selected_cipher_suite == tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA) + { + *mschapv2_challenges_length = 2ul * EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH; + length += 2ul * EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH; + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + return length; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization_cbc( + abs_crypto_cbc_block_algorithm_c ** const member_cbc_crypto_block_algorithm, + abs_crypto_block_algorithm_c * const crypto_block_algorithm, + const eap_variable_data_c * const member_iv, + const eap_variable_data_c * const member_key, + const bool true_when_encrypt) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: key_function: starts: tls_record_c::cipher_suite_initialization_cbc()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization_cbc()"); + + eap_automatic_variable_c + block_algorithm_remove(m_am_tools, crypto_block_algorithm); + + if (crypto_block_algorithm == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (crypto_block_algorithm->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (member_cbc_crypto_block_algorithm == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *member_cbc_crypto_block_algorithm = new crypto_cbc_c( + m_am_tools, + crypto_block_algorithm, + true); + + if (*member_cbc_crypto_block_algorithm == 0 + || (*member_cbc_crypto_block_algorithm)->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // After this point *member_cbc_crypto_block_algorithm will delete crypto_block_algorithm. + block_algorithm_remove.do_not_free_variable(); + + if ((*member_cbc_crypto_block_algorithm)->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_status_process_general_error; + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CBC member_iv"), + member_iv->get_data(member_iv->get_data_length()), + member_iv->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CBC member_key"), + member_key->get_data(member_key->get_data_length()), + member_key->get_data_length())); + + + if (true_when_encrypt == true) + { + status = (*member_cbc_crypto_block_algorithm)->set_encryption_key( + member_iv->get_data(member_iv->get_data_length()), + member_iv->get_data_length(), + member_key->get_data(member_key->get_data_length()), + member_key->get_data_length()); + } + else + { + status = (*member_cbc_crypto_block_algorithm)->set_decryption_key( + member_iv->get_data(member_iv->get_data_length()), + member_iv->get_data_length(), + member_key->get_data(member_key->get_data_length()), + member_key->get_data_length()); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization_hmac( + abs_crypto_hmac_algorithm_c * const member_hmac_algorithm, + const eap_variable_data_c * const member_key) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: key_function: starts: tls_record_c::cipher_suite_initialization_hmac()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization_hmac()"); + + if (member_hmac_algorithm == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (member_hmac_algorithm->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("HMAC member_key"), + member_key->get_data(member_key->get_data_length()), + member_key->get_data_length())); + + status = member_hmac_algorithm->hmac_set_key( + member_key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization_stream( + abs_crypto_stream_algorithm_c * const member_crypto_stream_algorithm, + const eap_variable_data_c * const member_key, + const bool /* true_when_encrypt */) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: key_function: starts: tls_record_c::cipher_suite_initialization_stream()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization_stream()"); + + if (member_crypto_stream_algorithm == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (member_crypto_stream_algorithm->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("STREAM member_key"), + member_key->get_data(member_key->get_data_length()), + member_key->get_data_length())); + + eap_status_e status = member_crypto_stream_algorithm->set_key(member_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization_hmac_sha1(const bool send_when_true) +{ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: key_function: starts: tls_record_c::cipher_suite_initialization_hmac_sha1()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization_hmac_sha1()"); + + reset_hmac_algorithms(send_when_true); + + eap_status_e status = eap_status_ok; + + if (send_when_true == true) + { + crypto_sha1_c * const sha1 = new crypto_sha1_c(m_am_tools); + if (sha1 == 0) + { + delete sha1; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_send_hmac_algorithm = new crypto_hmac_c(m_am_tools, sha1, true); + + status = cipher_suite_initialization_hmac( + m_send_hmac_algorithm, + &m_send_mac_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + else + { + crypto_sha1_c * const sha1 = new crypto_sha1_c(m_am_tools); + if (sha1 == 0) + { + delete sha1; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_receive_hmac_algorithm = new crypto_hmac_c(m_am_tools, sha1, true); + + status = cipher_suite_initialization_hmac( + m_receive_hmac_algorithm, + &m_receive_mac_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization_hmac_md5(const bool send_when_true) +{ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: key_function: starts: cipher_suite_initialization_hmac_md5()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization_hmac_md5()"); + + reset_hmac_algorithms(send_when_true); + + eap_status_e status = eap_status_ok; + + if (send_when_true == true) + { + crypto_md5_c * const md5 = new crypto_md5_c(m_am_tools); + if (md5 == 0) + { + delete md5; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_send_hmac_algorithm = new crypto_hmac_c(m_am_tools, md5, true); + + status = cipher_suite_initialization_hmac( + m_send_hmac_algorithm, + &m_send_mac_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + else + { + crypto_md5_c * const md5 = new crypto_md5_c(m_am_tools); + if (md5 == 0) + { + delete md5; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_receive_hmac_algorithm = new crypto_hmac_c(m_am_tools, md5, true); + + status = cipher_suite_initialization_hmac( + m_receive_hmac_algorithm, + &m_receive_mac_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization( + const bool send_when_true) +{ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: key_function: starts: tls_record_c::cipher_suite_initialization(), cipher suite %s: %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite), + (send_when_true == true ? "send": "receive"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization()"); + + reset_block_ciphers(send_when_true); + + reset_stream_ciphers(send_when_true); + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_send_encryption_key"), + m_send_encryption_key.get_data(), + m_send_encryption_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_receive_encryption_key"), + m_receive_encryption_key.get_data(), + m_receive_encryption_key.get_data_length())); + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_send_mac_key"), + m_send_mac_key.get_data(), + m_send_mac_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_receive_mac_key"), + m_receive_mac_key.get_data(), + m_receive_mac_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_send_iv"), + m_send_iv.get_data(), + m_send_iv.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_receive_iv"), + m_receive_iv.get_data(), + m_receive_iv.get_data_length())); + + + eap_status_e status = eap_status_ok; + + if (cipher_suite_is_3DES_EDE_CBC_SHA(m_selected_cipher_suite) == true) + { + if (send_when_true == true) + { + crypto_3des_ede_c * des3 = new crypto_3des_ede_c(m_am_tools); + + status = cipher_suite_initialization_cbc( + &m_send_block_cipher, + des3, + &m_send_iv, + &m_send_encryption_key, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + else + { + crypto_3des_ede_c * des3 = new crypto_3des_ede_c(m_am_tools); + + status = cipher_suite_initialization_cbc( + &m_receive_block_cipher, + des3, + &m_receive_iv, + &m_receive_encryption_key, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + status = cipher_suite_initialization_hmac_sha1(send_when_true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (cipher_suite_is_AES_128_CBC_SHA(m_selected_cipher_suite) == true) + { + if (send_when_true == true) + { + crypto_aes_c * aes = new crypto_aes_c(m_am_tools); + + status = cipher_suite_initialization_cbc( + &m_send_block_cipher, + aes, + &m_send_iv, + &m_send_encryption_key, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + else + { + crypto_aes_c * aes = new crypto_aes_c(m_am_tools); + + status = cipher_suite_initialization_cbc( + &m_receive_block_cipher, + aes, + &m_receive_iv, + &m_receive_encryption_key, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + status = cipher_suite_initialization_hmac_sha1(send_when_true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (cipher_suite_is_RC4_128_MD5(m_selected_cipher_suite) == true) + { + if (send_when_true == true) + { + m_send_stream_cipher = new crypto_rc4_c(m_am_tools); + + status = cipher_suite_initialization_stream( + m_send_stream_cipher, + &m_send_encryption_key, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + else + { + m_receive_stream_cipher = new crypto_rc4_c(m_am_tools); + + status = cipher_suite_initialization_stream( + m_receive_stream_cipher, + &m_receive_encryption_key, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + status = cipher_suite_initialization_hmac_md5(send_when_true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (cipher_suite_is_RC4_128_SHA(m_selected_cipher_suite) == true) + { + if (send_when_true == true) + { + m_send_stream_cipher = new crypto_rc4_c(m_am_tools); + + status = cipher_suite_initialization_stream( + m_send_stream_cipher, + &m_send_encryption_key, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + else + { + m_receive_stream_cipher = new crypto_rc4_c(m_am_tools); + + status = cipher_suite_initialization_stream( + m_receive_stream_cipher, + &m_receive_encryption_key, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + status = cipher_suite_initialization_hmac_sha1(send_when_true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = eap_status_illegal_cipher_suite; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::generate_key_material() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: tls_record_c::generate_key_material()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::generate_key_material()"); + + eap_status_e status = eap_status_illegal_cipher_suite; + + if (m_key_material_generated == true) + { + // Already generated. + status = eap_status_ok; + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: key_function: starts: tls_record_c::generate_key_material()\n"), + (m_is_client == true) ? "client": "server")); + + if (m_master_secret.get_is_valid_data() == false + || m_client_handshake_random_value.get_is_valid_data() == false + || m_server_handshake_random_value.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u32_t mac_key_length = 0ul; + u32_t encryption_key_length = 0ul; + u32_t iv_length = 0ul; + u32_t session_key_seed_length = 0ul; + u32_t mschapv2_challenges_length = 0ul; + + u32_t key_expansion_size = get_key_expansion_size( + &mac_key_length, + &encryption_key_length, + &iv_length, + &session_key_seed_length, + &mschapv2_challenges_length); + + if (key_expansion_size == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + eap_variable_data_c label(m_am_tools); + if (label.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = label.add_data( + TLS_PEAP_KEY_EXPANSION_LABEL, + TLS_PEAP_KEY_EXPANSION_LABEL_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c seed(m_am_tools); + if (seed.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + status = seed.set_copy_of_buffer(&m_server_handshake_random_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = seed.add_data(&m_client_handshake_random_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: prf_function: tls_prf.tls_prf_output()\n"), + (m_is_client == true ? "client": "server"))); + + crypto_tls_prf_c tls_prf(m_am_tools); + + status = tls_prf.tls_prf_init( + &m_master_secret, + &label, + &seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c key_expansion(m_am_tools); + + status = key_expansion.set_buffer_length(key_expansion_size); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_expansion.set_data_length(key_expansion_size); + + status = tls_prf.tls_prf_output( + key_expansion.get_data(key_expansion.get_data_length()), + key_expansion.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + u32_t key_offset = 0ul; + + eap_variable_data_c *send_mac_key = &m_new_send_mac_key; + eap_variable_data_c *receive_mac_key = &m_new_receive_mac_key; + eap_variable_data_c *send_encryption_key = &m_new_send_encryption_key; + eap_variable_data_c *receive_encryption_key = &m_new_receive_encryption_key; + eap_variable_data_c *send_iv = &m_new_send_iv; + eap_variable_data_c *receive_iv = &m_new_receive_iv; + + if (m_is_client == false) + { + send_mac_key = &m_new_receive_mac_key; + receive_mac_key = &m_new_send_mac_key; + send_encryption_key = &m_new_receive_encryption_key; + receive_encryption_key = &m_new_send_encryption_key; + send_iv = &m_new_receive_iv; + receive_iv = &m_new_send_iv; + } + + status = send_mac_key->set_copy_of_buffer( + key_expansion.get_data_offset(key_offset, mac_key_length), + mac_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_offset += mac_key_length; + + status = receive_mac_key->set_copy_of_buffer( + key_expansion.get_data_offset(key_offset, mac_key_length), + mac_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_offset += mac_key_length; + + status = send_encryption_key->set_copy_of_buffer( + key_expansion.get_data_offset(key_offset, encryption_key_length), + encryption_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_offset += encryption_key_length; + + status = receive_encryption_key->set_copy_of_buffer( + key_expansion.get_data_offset(key_offset, encryption_key_length), + encryption_key_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_offset += encryption_key_length; + + if (iv_length > 0ul) + { + status = send_iv->set_copy_of_buffer( + key_expansion.get_data_offset(key_offset, iv_length), + iv_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_offset += iv_length; + } + else + { + status = send_iv->init(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + send_iv->set_is_valid(); + } + + if (iv_length > 0ul) + { + status = receive_iv->set_copy_of_buffer( + key_expansion.get_data_offset(key_offset, iv_length), + iv_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_offset += iv_length; + } + else + { + status = receive_iv->init(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + receive_iv->set_is_valid(); + } + +#if defined(USE_FAST_EAP_TYPE) + if (session_key_seed_length > 0ul) + { + status = m_session_key_seed.set_copy_of_buffer( + key_expansion.get_data_offset(key_offset, session_key_seed_length), + session_key_seed_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_offset += session_key_seed_length; + } + + if (mschapv2_challenges_length > 0ul) + { + status = m_mschapv2_challenges.set_copy_of_buffer( + key_expansion.get_data_offset(key_offset, mschapv2_challenges_length), + mschapv2_challenges_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + key_offset += mschapv2_challenges_length; + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): m_master_secret"), + m_master_secret.get_data(), + m_master_secret.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): m_client_handshake_random_value"), + m_client_handshake_random_value.get_data(), + m_client_handshake_random_value.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): m_server_handshake_random_value"), + m_server_handshake_random_value.get_data(), + m_server_handshake_random_value.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): key_expansion"), + key_expansion.get_data(), + key_expansion.get_data_length())); + + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): m_new_send_mac_key"), + m_new_send_mac_key.get_data(), + m_new_send_mac_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): m_new_receive_mac_key"), + m_new_receive_mac_key.get_data(), + m_new_receive_mac_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): m_new_send_encryption_key"), + m_new_send_encryption_key.get_data(), + m_new_send_encryption_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): m_new_receive_encryption_key"), + m_new_receive_encryption_key.get_data(), + m_new_receive_encryption_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): m_new_send_iv"), + m_new_send_iv.get_data(), + m_new_send_iv.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): m_new_receive_iv"), + m_new_receive_iv.get_data(), + m_new_receive_iv.get_data_length())); + + if (m_session_key_seed.get_is_valid_data() == true) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): m_session_key_seed"), + m_session_key_seed.get_data(), + m_session_key_seed.get_data_length())); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_mschapv2_challenges.get_is_valid_data() == true) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): server_mschapv2_challenge"), + m_mschapv2_challenges.get_data(), + EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: generate_key_material(): client_mschapv2_challenge"), + m_mschapv2_challenges.get_data_offset(EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH, EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH), + EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH)); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + m_key_material_generated = true; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::set_tls_master_secret( + const eap_variable_data_c * const master_secret, + const eap_variable_data_c * const client_random, + const eap_variable_data_c * const server_random) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: key_function: starts: tls_record_c::set_tls_master_secret()\n"), + this, + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::set_tls_master_secret()"); + + eap_variable_data_c label(m_am_tools); + if (label.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_status_process_general_error; + + if (m_eap_type == eap_type_ttls) + { + status = label.add_data( + EAP_TTLS_KEY_EXPANSION_LABEL, + EAP_TTLS_KEY_EXPANSION_LABEL_LENGTH); + } + else if (m_eap_type == eap_type_peap + && m_peap_version == peap_version_1 + && m_use_tppd_tls_peap == false) + { + status = label.add_data( + EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL_V1_DRAFT_5, + EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL_V1_DRAFT_5_LENGTH); + } + else + { + status = label.add_data( + EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL, + EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL_LENGTH); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = get_tls_prf_data( + master_secret, + client_random, + server_random, + &label, + &m_eap_master_session_key, + EAP_TLS_PEAP_MASTER_SESSION_KEY_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_record_c::set_tls_master_secret(): TLS_MSK"), + m_eap_master_session_key.get_data(EAP_TLS_PEAP_MSK_SIZE), + EAP_TLS_PEAP_MSK_SIZE)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_record_c::set_tls_master_secret(): TLS_EMSK"), + m_eap_master_session_key.get_data_offset(EAP_TLS_PEAP_MSK_SIZE, EAP_TLS_PEAP_EMSK_SIZE), + EAP_TLS_PEAP_EMSK_SIZE)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::get_ttls_implicit_challenge( + eap_variable_data_c * const ttls_implicit_challenge, + const u32_t required_ttls_implicit_challenge_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: key_function: starts: tls_record_c::get_ttls_implicit_challenge()\n"), + this, + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_ttls_implicit_challenge()"); + + eap_variable_data_c label(m_am_tools); + if (label.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + + eap_status_e status = eap_status_process_general_error; + + status = label.add_data( + EAP_TTLS_IMPLICIT_CHALLENGE_LABEL, + EAP_TTLS_IMPLICIT_CHALLENGE_LABEL_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_tls_prf_data( + &m_master_secret, + &m_client_handshake_random_value, + &m_server_handshake_random_value, + &label, + ttls_implicit_challenge, + required_ttls_implicit_challenge_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_record_c::get_ttls_implicit_challenge(): ttls_implicit_challenge"), + ttls_implicit_challenge->get_data(), + ttls_implicit_challenge->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::get_tls_prf_data( + const eap_variable_data_c * const master_secret, + const eap_variable_data_c * const client_random, + const eap_variable_data_c * const server_random, + const eap_variable_data_c * const label, + eap_variable_data_c * const prf_data, + const u32_t required_prf_data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: key_function: starts: tls_record_c::get_tls_prf_data()\n"), + this, + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_tls_prf_data()"); + + eap_status_e status = eap_status_process_general_error; + + eap_variable_data_c seed(m_am_tools); + if (seed.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = seed.set_copy_of_buffer(client_random); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = seed.add_data(server_random); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + crypto_tls_prf_c tls_prf(m_am_tools); + + status = tls_prf.tls_prf_init( + master_secret, + label, + &seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = prf_data->set_buffer_length( + required_prf_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + prf_data->set_data_length(required_prf_data_length); + + status = tls_prf.tls_prf_output( + prf_data->get_data(), + prf_data->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("tls_record_c::get_tls_prf_data(): prf_data"), + prf_data->get_data(), + prf_data->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::change_cipher_spec( + const bool send_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: suite_function: starts: tls_record_c::change_cipher_spec(%s)\n"), + this, + (m_is_client == true) ? "client": "server", + (send_when_true == true) ? "send": "receive")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::change_cipher_spec()"); + + eap_status_e status = eap_status_illegal_cipher_suite; + + if (m_selected_cipher_suite != tls_cipher_suites_none) + { + status = eap_status_ok; + + if (send_when_true == true) + { + status = set_send_cipher_suite(m_selected_cipher_suite); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: change_cipher_spec(): send to %s\n"), + eap_tls_trace_string_c::get_cipher_suite_string(m_send_cipher_suite))); + + } + else + { + status = set_receive_cipher_suite(m_selected_cipher_suite); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: change_cipher_spec(): receive to %s\n"), + eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite))); + } + + // This will initialize encryption, decryption and MAC algorithms. + status = cipher_suite_initialization(send_when_true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (status == eap_status_ok) + { + if (send_when_true == true) + { + m_send_compression_method = m_selected_compression_method; + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: change_cipher_spec() send to %s\n"), + eap_tls_trace_string_c::get_compression_method_string( + m_send_compression_method))); + } + else + { + m_receive_compression_method = m_selected_compression_method; + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: change_cipher_spec() receive to %s\n"), + eap_tls_trace_string_c::get_compression_method_string( + m_receive_compression_method))); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::new_record_message( + tls_record_message_c ** const tls_record_message, + const tls_record_protocol_e protocol) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::new_record_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::new_record_message()"); + + bool add_new_record = false; + + eap_automatic_variable_c automatic_tls_record_message( + m_am_tools, + 0); + + eap_status_e status = eap_status_process_general_error; + + + *tls_record_message = m_new_tls_message.get_last_record_message(); + if (*tls_record_message != 0 + && (*tls_record_message)->get_protocol() != protocol) + { + // We need a new different protocol. + *tls_record_message = 0; + } + + if (m_use_separate_tls_record == true) + { + // Every message is in separate TLS-record. + *tls_record_message = 0; + } + + if (*tls_record_message == 0) + { + *tls_record_message = new tls_record_message_c(m_am_tools, this, m_is_client); + + automatic_tls_record_message.set_variable(*tls_record_message); + + if (*tls_record_message == 0 + || (*tls_record_message)->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = (*tls_record_message)->set_protocol(protocol); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = (*tls_record_message)->set_version(tls_version_3_1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + add_new_record = true; + } + + if (add_new_record == true) + { + // Note m_new_tls_message free message on any case. + automatic_tls_record_message.do_not_free_variable(); + + bool includes_tls_handshake_message = false; + + if (protocol == tls_record_protocol_handshake) + { + includes_tls_handshake_message = true; + } + + status = m_new_tls_message.add_record_message( + (*tls_record_message), + true, + includes_tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::add_record_message( + tls_handshake_message_c * const tls_handshake_message) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::add_record_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::add_record_message()"); + + tls_record_message_c *tls_record_message = 0; + + eap_status_e status = new_record_message( + &tls_record_message, + tls_record_protocol_handshake); + if (status != eap_status_ok + || tls_record_message == 0) + { + delete tls_handshake_message; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_record_message->add_handshake_message( + tls_handshake_message, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->create_message_data(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::add_record_message( + tls_change_cipher_spec_message_c * const change_cipher_spec_message) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::add_record_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::add_record_message()"); + + tls_record_message_c *tls_record_message = 0; + + eap_status_e status = new_record_message( + &tls_record_message, + tls_record_protocol_change_cipher_spec); + if (status != eap_status_ok + || tls_record_message == 0) + { + delete change_cipher_spec_message; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_record_message->add_change_cipher_spec_message( + change_cipher_spec_message, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = change_cipher_spec_message->create_message_data(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::add_record_message( + tls_alert_message_c * const alert_message) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::add_record_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::add_record_message()"); + + tls_record_message_c *tls_record_message = 0; + + eap_status_e status = new_record_message( + &tls_record_message, + tls_record_protocol_alert); + if (status != eap_status_ok + || tls_record_message == 0) + { + delete alert_message; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_record_message->add_alert_message( + alert_message, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = alert_message->create_message_data(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::add_record_message( + tls_application_data_message_c * const application_data_message) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::add_record_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::add_record_message()"); + + tls_record_message_c *tls_record_message = 0; + + eap_status_e status = new_record_message( + &tls_record_message, + tls_record_protocol_application_data); + if (status != eap_status_ok + || tls_record_message == 0) + { + delete application_data_message; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_record_message->add_application_data_message( + application_data_message, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::allocate_handshake_message( + tls_handshake_message_c ** const tls_handshake_message, + eap_automatic_variable_c * const automatic_tls_handshake_message, + const tls_handshake_type_e handshake_type) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: receive_function: starts: tls_record_c::allocate_handshake_message()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::allocate_handshake_message()"); + + *tls_handshake_message + = new tls_handshake_message_c(m_am_tools, this, m_is_client); + + automatic_tls_handshake_message->set_variable(*tls_handshake_message); + + if (*tls_handshake_message == 0 + || (*tls_handshake_message)->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = (*tls_handshake_message)->set_handshake_type( + handshake_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_hello_request() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_hello_request()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_hello_request()"); + + // This is an empty message. + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_type_hello_request); + + // Note add_record_message() frees message on any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = add_record_message(tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(tls_peap_state_wait_handshake_type_client_hello); + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_client_hello() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_client_hello(): privacy_handshake_state=%d=%s, session_type=%s\n"), + this, + (m_is_client == true ? "client": "server"), + m_tls_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(m_tls_identity_privacy_handshake_state), + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type))); +#else + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_client_hello(): privacy_handshake_state=%d=%s\n"), + this, + (m_is_client == true ? "client": "server"), + 0, + "")); +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_client_hello()"); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Version: 3 | Version: 1 | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | | + // + + + // | ClientRandomValue | + // + (32 bytes) +-+-+-+-+-+-+-+-+ + // | | ID length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | Session ID | + // + (maximum 32 bytes) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CipherSuite length | CipherSuite 1 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CipherSuite 2 | CipherSuite 3 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CipherSuite 4 | Cmp length | Cmp 1 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Cmp 2 | Cmp 3 | extensions ... | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + eap_status_e status(eap_status_ok); + + status = message_hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + status = allocate_handshake_message( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_type_client_hello); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u32_t tmp_gmt_unix_time_network_order = eap_htonl(m_am_tools->get_gmt_unix_time()); + eap_variable_data_c tmp_client_random(m_am_tools); + + status = tmp_client_random.set_buffer_length(TLS_HANDSHAKE_RANDOM_VALUE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + tmp_client_random.set_data_length(TLS_HANDSHAKE_RANDOM_VALUE_SIZE); + + crypto_random_c rand(m_am_tools); + + status = rand.get_rand_bytes( + tmp_client_random.get_data(tmp_client_random.get_data_length()), + tmp_client_random.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Sets the first bytes to GMT unix time. + u8_t *p_gmt_unix_time = reinterpret_cast(tmp_client_random.get_data(sizeof(u32_t))); + if (p_gmt_unix_time == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_am_tools->memmove(p_gmt_unix_time, &tmp_gmt_unix_time_network_order, sizeof(tmp_gmt_unix_time_network_order)); + + + status = m_client_handshake_random_value.set_copy_of_buffer( + &tmp_client_random); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = tls_handshake_message->set_random_value( + &tmp_client_random); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_tls_session_type == tls_session_type_original_session_resumption + && m_session_id.get_is_valid_data() == true) + { + status = tls_handshake_message->set_session_id( + &m_session_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // -------------------------------------------------------------------- + + // This copies proposed cipher suites to tls_handshake_message. + status = tls_handshake_message->set_cipher_suites(&m_proposed_cipher_suites); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + status = tls_handshake_message->set_compression_methods(&m_proposed_compression_methods); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + + { + status = tls_handshake_message->set_tls_extensions(&m_supported_tls_extensions); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = add_record_message(tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_server_hello( + const u16_t /*selected_cipher_suite*/, + const u8_t /*selected_compression_method*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_server_hello()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_server_hello()"); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Version: 3 | Version: 1 | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | | + // + + + // | ServerRandomValue | + // + (32 bytes) +-+-+-+-+-+-+-+-+ + // | | ID length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | Session ID | + // + (maximum 32 bytes) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CipherSuite | Cmp | extensions ... + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_type_server_hello); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + u32_t tmp_gmt_unix_time_network_order = eap_htonl(m_am_tools->get_gmt_unix_time()); + eap_variable_data_c tmp_server_random(m_am_tools); + + status = tmp_server_random.set_buffer_length(TLS_HANDSHAKE_RANDOM_VALUE_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + tmp_server_random.set_data_length(TLS_HANDSHAKE_RANDOM_VALUE_SIZE); + + crypto_random_c rand(m_am_tools); + + status = rand.get_rand_bytes( + tmp_server_random.get_data(tmp_server_random.get_data_length()), + tmp_server_random.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Sets the first bytes to GMT unix time. + u8_t *p_gmt_unix_time = reinterpret_cast(tmp_server_random.get_data(sizeof(u32_t))); + if (p_gmt_unix_time == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_am_tools->memmove(p_gmt_unix_time, &tmp_gmt_unix_time_network_order, sizeof(tmp_gmt_unix_time_network_order)); + + status = m_server_handshake_random_value.set_copy_of_buffer( + &tmp_server_random); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + status = tls_handshake_message->set_random_value( + &tmp_server_random); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + if ((m_tls_session_type == tls_session_type_full_authentication +#if defined(USE_FAST_EAP_TYPE) + || m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + && m_server_offers_new_session_id == true) + { + // We create a new session. + status = m_session_id.set_buffer_length(TLS_SESSION_ID_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_session_id.set_data_length(TLS_SESSION_ID_SIZE); + + status = rand.get_rand_bytes( + m_session_id.get_data(m_session_id.get_data_length()), + m_session_id.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // -------------------------------------------------------------------- + + status = tls_handshake_message->set_session_id( + &m_session_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: TLS/PEAP selected cipher_suite %s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite))); + } + + status = tls_handshake_message->set_selected_cipher_suite( + m_selected_cipher_suite); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + status = tls_handshake_message->set_selected_compression_method( + m_selected_compression_method); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type != eap_type_fast) // EAP-FAST does not use session ticket in ServerHello message. +#endif //#if defined(USE_FAST_EAP_TYPE) + { + status = tls_handshake_message->set_tls_extensions(&m_supported_tls_extensions); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + // -------------------------------------------------------------------- + + if (m_tls_session_type == tls_session_type_original_session_resumption +#if defined(USE_EAP_TLS_SESSION_TICKET) + || m_tls_session_type == tls_session_type_stateless_session_resumption +#if defined(USE_FAST_EAP_TYPE) + || m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption +#endif //#if defined(USE_FAST_EAP_TYPE) +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + ) + { + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast + && m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption) + { + // Generates master secret from PAC-Key. + // Parameter resumed_master_secret includes PAC-Key. + status = generate_eap_fast_master_secret_from_pac_key( + &m_eap_fast_pac_key); + + m_eap_fast_pac_key.reset(); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + // We must generate the key material. + status = generate_key_material(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = add_record_message(tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_certificate( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + + tls_identity_privacy_handshake_state_e tmp_identity_privacy_handshake_state = +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + m_tls_identity_privacy_handshake_state; +#else + tls_identity_privacy_handshake_state_none; +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + EAP_UNREFERENCED_PARAMETER(tmp_identity_privacy_handshake_state); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_certificate(): state=%d=%s, privacy_handshake_state=%d=%s, session_type=%s\n"), + this, + (m_is_client == true ? "client": "server"), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + tmp_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state), + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_certificate()"); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Certificate Chain Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Certificate 1 Length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | Certificate 1 | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // . ... . + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Certificate n Length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | Certificate n | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_type_certificate); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + // Certificate chain is included when TLS identity privacy is not used, + // or send cipher is not NULL + // or sender is server + if (m_tls_session_type == tls_session_type_full_authentication + && (m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none + || m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs + || m_is_client == false)) +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + { + status = tls_handshake_message->set_certificate_chain( + certificate_chain); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = add_record_message(tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_certificate_request( + EAP_TEMPLATE_CONST eap_array_c * const certificate_types, + EAP_TEMPLATE_CONST eap_array_c * const certificate_authorities) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_certificate_request()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_certificate_request()"); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CT length | CT 1 | CT 2 | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CT 3 | CT 4 | CAs length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | CA 1 length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | Distinguished name of Certificate Authority 1 | + // + + + // | | + // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | CA 2 length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | Distinguished name of Certificate Authority 2 | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_type_certificate_request); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_certificate_types( + certificate_types); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_server_sends_empty_certificate_authorities_list == false) + { + status = tls_handshake_message->set_certificate_authorities( + certificate_authorities); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = add_record_message(tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_server_hello_done() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_server_hello_done()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_server_hello_done()"); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // + // ServerHelloDone message does not include payload. + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_type_server_hello_done); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = add_record_message(tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_server_key_exchange_sha1_hash( + const eap_variable_data_c * const dhe_prime, + const eap_variable_data_c * const dhe_group_generator, + const eap_variable_data_c * const public_dhe_key, + eap_variable_data_c * const hash) +{ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: hash_function: starts: tls_record_c::create_server_key_exchange_sha1_hash()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_server_key_exchange_sha1_hash()"); + + if (m_client_handshake_random_value.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_server_handshake_random_value.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u16_t dhe_prime_length_network_order + = eap_htons(static_cast(dhe_prime->get_data_length())); + + u16_t dhe_group_generator_length_network_order + = eap_htons(static_cast(dhe_group_generator->get_data_length())); + + u16_t public_dhe_key_length_network_order + = eap_htons(static_cast(public_dhe_key->get_data_length())); + + crypto_sha1_c sha1(m_am_tools); + + eap_status_e status = sha1.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_sha1_hash(): client random"), + m_client_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()), + m_client_handshake_random_value.get_data_length())); + + status = sha1.hash_update( + m_client_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()), + m_client_handshake_random_value.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_sha1_hash(): server random"), + m_server_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()), + m_server_handshake_random_value.get_data_length())); + + status = sha1.hash_update( + m_server_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()), + m_server_handshake_random_value.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_sha1_hash(): dhe_prime_length_network_order"), + &dhe_prime_length_network_order, + sizeof(dhe_prime_length_network_order))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_sha1_hash(): dhe_prime"), + dhe_prime->get_data(dhe_prime->get_data_length()), + dhe_prime->get_data_length())); + + status = sha1.hash_update( + &dhe_prime_length_network_order, + sizeof(dhe_prime_length_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + dhe_prime->get_data( + dhe_prime->get_data_length()), + dhe_prime->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_sha1_hash(): ") + EAPL("dhe_group_generator_length_network_order"), + &dhe_group_generator_length_network_order, + sizeof(dhe_group_generator_length_network_order))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_sha1_hash(): dhe_group_generator"), + dhe_group_generator->get_data(dhe_group_generator->get_data_length()), + dhe_group_generator->get_data_length())); + + status = sha1.hash_update( + &dhe_group_generator_length_network_order, + sizeof(dhe_group_generator_length_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + dhe_group_generator->get_data( + dhe_group_generator->get_data_length()), + dhe_group_generator->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_sha1_hash(): public_dhe_key_length_network_order"), + &public_dhe_key_length_network_order, + sizeof(public_dhe_key_length_network_order))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_sha1_hash(): public_dhe_key"), + public_dhe_key->get_data(public_dhe_key->get_data_length()), + public_dhe_key->get_data_length())); + + status = sha1.hash_update( + &public_dhe_key_length_network_order, + sizeof(public_dhe_key_length_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = sha1.hash_update( + public_dhe_key->get_data( + public_dhe_key->get_data_length()), + public_dhe_key->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = hash->set_buffer_length(sha1.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + hash->set_data_length(sha1.get_digest_length()); + + u32_t digest_length = hash->get_data_length(); + status = sha1.hash_final( + hash->get_data(hash->get_data_length()), + &digest_length); + if (digest_length != sha1.get_digest_length()) + { + status = eap_status_process_general_error; + } + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_sha1_hash(): hash"), + hash->get_data(hash->get_data_length()), + hash->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_server_key_exchange_md5_hash( + const eap_variable_data_c * const dhe_prime, + const eap_variable_data_c * const dhe_group_generator, + const eap_variable_data_c * const public_dhe_key, + eap_variable_data_c * const hash) +{ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: hash_function: starts: tls_record_c::create_server_key_exchange_md5_hash()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_server_key_exchange_md5_hash()"); + + if (m_client_handshake_random_value.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (m_server_handshake_random_value.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u16_t dhe_prime_length_network_order + = eap_htons(static_cast(dhe_prime->get_data_length())); + + u16_t dhe_group_generator_length_network_order + = eap_htons(static_cast(dhe_group_generator->get_data_length())); + + u16_t public_dhe_key_length_network_order + = eap_htons(static_cast(public_dhe_key->get_data_length())); + + crypto_md5_c md5(m_am_tools); + + eap_status_e status = md5.hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_md5_hash(): client random"), + m_client_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()), + m_client_handshake_random_value.get_data_length())); + + status = md5.hash_update( + m_client_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()), + m_client_handshake_random_value.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_md5_hash(): server random"), + m_server_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()), + m_server_handshake_random_value.get_data_length())); + + status = md5.hash_update( + m_server_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()), + m_server_handshake_random_value.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_md5_hash(): dhe_prime_length_network_order"), + &dhe_prime_length_network_order, + sizeof(dhe_prime_length_network_order))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_md5_hash(): dhe_prime"), + dhe_prime->get_data(dhe_prime->get_data_length()), + dhe_prime->get_data_length())); + + status = md5.hash_update( + &dhe_prime_length_network_order, + sizeof(dhe_prime_length_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5.hash_update( + dhe_prime->get_data( + dhe_prime->get_data_length()), + dhe_prime->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_md5_hash(): ") + EAPL("dhe_group_generator_length_network_order"), + &dhe_group_generator_length_network_order, + sizeof(dhe_group_generator_length_network_order))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_md5_hash(): dhe_group_generator"), + dhe_group_generator->get_data(dhe_group_generator->get_data_length()), + dhe_group_generator->get_data_length())); + + status = md5.hash_update( + &dhe_group_generator_length_network_order, + sizeof(dhe_group_generator_length_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5.hash_update( + dhe_group_generator->get_data( + dhe_group_generator->get_data_length()), + dhe_group_generator->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_md5_hash(): public_dhe_key_length_network_order"), + &public_dhe_key_length_network_order, + sizeof(public_dhe_key_length_network_order))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_md5_hash(): public_dhe_key"), + public_dhe_key->get_data(public_dhe_key->get_data_length()), + public_dhe_key->get_data_length())); + + status = md5.hash_update( + &public_dhe_key_length_network_order, + sizeof(public_dhe_key_length_network_order)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = md5.hash_update( + public_dhe_key->get_data( + public_dhe_key->get_data_length()), + public_dhe_key->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = hash->set_buffer_length(md5.get_digest_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + hash->set_data_length(md5.get_digest_length()); + + u32_t digest_length = hash->get_data_length(); + status = md5.hash_final( + hash->get_data(hash->get_data_length()), + &digest_length); + if (digest_length != md5.get_digest_length()) + { + status = eap_status_process_general_error; + } + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_server_key_exchange_md5_hash(): hash"), + hash->get_data(hash->get_data_length()), + hash->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::verify_signature_of_server_key_exchange( + const eap_variable_data_c * const signed_server_key_exchange_hash) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: hash_function: starts: tls_record_c::verify_signature_of_server_key_exchange()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::verify_signature_of_server_key_exchange()"); + + eap_status_e status = eap_status_not_supported; + + eap_variable_data_c hash(m_am_tools); + + + if (cipher_suite_is_TLS_DHE_DSS() == true) + { + status = create_server_key_exchange_sha1_hash( + &m_dhe_prime, + &m_dhe_group_generator, + &m_peer_public_dhe_key, + &hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (cipher_suite_is_TLS_DHE_RSA() == true) + { + eap_variable_data_c md5_hash(m_am_tools); + + status = create_server_key_exchange_md5_hash( + &m_dhe_prime, + &m_dhe_group_generator, + &m_peer_public_dhe_key, + &md5_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c sha1_hash(m_am_tools); + + status = create_server_key_exchange_sha1_hash( + &m_dhe_prime, + &m_dhe_group_generator, + &m_peer_public_dhe_key, + &sha1_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hash.add_data(&md5_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hash.add_data(&sha1_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: verify_signature_of_server_key_exchange(): hash"), + hash.get_data(hash.get_data_length()), + hash.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: verify_signature_of_server_key_exchange(): signed_server_key_exchange_hash"), + signed_server_key_exchange_hash->get_data( + signed_server_key_exchange_hash->get_data_length()), + signed_server_key_exchange_hash->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: verify_with_public_key()\n"), + (m_is_client == true ? "client": "server"))); + + status = m_am_tls_services->verify_with_public_key( + &hash, + signed_server_key_exchange_hash); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_query_certificate_chain() call. + m_pending_verify_with_public_key = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_query_certificate_chain() call. + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_create_handshake_type_server_key_exchange() +{ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: parse_function: starts: tls_record_c::complete_create_handshake_type_server_key_exchange()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_create_handshake_type_server_key_exchange()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_type_server_key_exchange); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if EAP_TLS_UNSUPPORTED_CIPHER_SUITE + #error This one needs more code. RSA key exchange with different parameters is NOT supported. + if (cipher_suite_is_TLS_RSA() == true) + { + // RSA modulus and exponent are included when selected cipher suite is + // using RSA key exchange + // and parameters are different than included in the certificate. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | rsa_modulus length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | rsa_modulus | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | rsa_exponent length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + rsa_exponent + + // | | + // + + + // | | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed MD5 hash 16 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed SHA-1 hash 20 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + else +#endif + if (cipher_suite_is_TLS_DHE_DSS() == true) + { + // Diffie-Hellman prime modulus, generator and server's + // Diffie-Hellman public value (g^X mod p) + // are included when selected cipher suite is ephemeral Diffie-Hellman key exchange. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH p length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH p value (prime modulus) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH g length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH g value (generator) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Ys length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Ys value | + // + (server's Diffie-Hellman public value) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed SHA-1 hash 47 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_create_handshake_type_server_key_exchange(): m_signed_message_hash"), + m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()), + m_signed_message_hash.get_data_length())); + + status = tls_handshake_message->set_signed_message_hash( + &m_signed_message_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (cipher_suite_is_TLS_DHE_RSA() == true) + { + // Diffie-Hellman prime modulus, generator and server's + // Diffie-Hellman public value (g^X mod p) + // are included when selected cipher suite is ephemeral Diffie-Hellman key exchange. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH p length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH p value (prime modulus) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH g length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH g value (generator) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Ys length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Ys value | + // + (server's Diffie-Hellman public value) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed MD5 hash 16 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed SHA-1 hash 47 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_create_handshake_type_server_key_exchange(): m_signed_message_hash"), + m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()), + m_signed_message_hash.get_data_length())); + + status = tls_handshake_message->set_signed_message_hash( + &m_signed_message_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) + { + // Diffie-Hellman prime modulus, generator and server's + // Diffie-Hellman public value (g^X mod p) + // are included when selected cipher suite is ephemeral Diffie-Hellman key exchange. + // NOTE: Here are no signed hash. This is not authenticated at all and vulnerable to + // man-in-the-middle attacks. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH p length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH p value (prime modulus) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH g length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH g value (generator) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Ys length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Ys value | + // + (server's Diffie-Hellman public value) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_create_handshake_type_server_key_exchange() no m_signed_message_hash\n"))); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + + // -------------------------------------------------------------------- + + + status = tls_handshake_message->set_dhe_prime( + &m_dhe_prime); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_dhe_group_generator( + &m_dhe_group_generator); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_public_dhe_key( + &m_own_public_dhe_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = add_record_message(tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_server_key_exchange() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_server_key_exchange()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_server_key_exchange()"); + + eap_status_e status = eap_status_process_general_error; + eap_variable_data_c hash(m_am_tools); + + +#if EAP_TLS_UNSUPPORTED_CIPHER_SUITE + #error This one needs more code. RSA key exchange with different parameters is NOT supported. + if (cipher_suite_is_TLS_RSA() == true) + { + // RSA modulus and exponent are included when selected + // cipher suite is using RSA key exchange + // and parameters are different than included in the certificate. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | rsa_modulus length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | rsa_modulus | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | rsa_exponent length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + rsa_exponent + + // | | + // + + + // | | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed MD5 hash 16 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed SHA-1 hash 20 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + else +#endif + if (cipher_suite_is_TLS_DHE_DSS() == true) + { + // Diffie-Hellman prime modulus, generator and server's + // Diffie-Hellman public value (g^X mod p) + // are included when selected cipher suite is ephemeral Diffie-Hellman key exchange. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH p length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH p value (prime modulus) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH g length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH g value (generator) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Ys length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Ys value | + // + (server's Diffie-Hellman public value) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed SHA-1 hash 47 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + status = create_server_key_exchange_sha1_hash( + &m_dhe_prime, + &m_dhe_group_generator, + &m_own_public_dhe_key, + &hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_handshake_type_server_key_exchange(): hash"), + hash.get_data(hash.get_data_length()), + hash.get_data_length())); + } + else if (cipher_suite_is_TLS_DHE_RSA() == true) + { + // Diffie-Hellman prime modulus, generator and server's + // Diffie-Hellman public value (g^X mod p) + // are included when selected cipher suite is ephemeral Diffie-Hellman key exchange. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH p length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH p value (prime modulus) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH g length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH g value (generator) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Ys length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Ys value | + // + (server's Diffie-Hellman public value) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed MD5 hash 16 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + + + // | digitally-signed SHA-1 hash 47 bytes | + // + (ClientHello.random + ServerHello.random + ServerParams) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + eap_variable_data_c md5_hash(m_am_tools); + + status = create_server_key_exchange_md5_hash( + &m_dhe_prime, + &m_dhe_group_generator, + &m_own_public_dhe_key, + &md5_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_handshake_type_server_key_exchange() md5_hash"), + md5_hash.get_data(md5_hash.get_data_length()), + md5_hash.get_data_length())); + + eap_variable_data_c sha1_hash(m_am_tools); + + status = create_server_key_exchange_sha1_hash( + &m_dhe_prime, + &m_dhe_group_generator, + &m_own_public_dhe_key, + &sha1_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_handshake_type_server_key_exchange() sha1_hash"), + sha1_hash.get_data(sha1_hash.get_data_length()), + sha1_hash.get_data_length())); + + status = hash.add_data(&md5_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = hash.add_data(&sha1_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_handshake_type_server_key_exchange(): hash"), + hash.get_data(hash.get_data_length()), + hash.get_data_length())); + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) + { + // Diffie-Hellman prime modulus, generator and server's + // Diffie-Hellman public value (g^X mod p) + // are included when selected cipher suite is ephemeral Diffie-Hellman key exchange. + // NOTE: Here are no signed hash. This is not authenticated at all and vulnerable to + // man-in-the-middle attacks. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH p length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH p value (prime modulus) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH g length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH g value (generator) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Ys length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Ys value | + // + (server's Diffie-Hellman public value) + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + // NOTE: Here the return value is eap_status_pending_request to avoid error after return. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: create_handshake_type_server_key_exchange()\n"), + (m_is_client == true ? "client": "server"))); + + m_signed_message_hash.reset(); + + // NOTE this function is asyncronous. This causes complex control flow. + // This function call will be completed always. + status = m_am_tls_services->sign_with_private_key( + &hash); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_sign_with_private_key() call. + m_pending_sign_with_private_key = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_sign_with_private_key() call. + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_create_handshake_type_client_key_exchange() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_create_handshake_type_client_key_exchange(): cipher suite=%d=%s\n"), + this, + (m_is_client == true ? "client": "server"), + m_selected_cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_create_handshake_type_client_key_exchange()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_type_client_key_exchange); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + if (cipher_suite_is_TLS_RSA() == true) + { + // Encrypted premaster secret is included when selected + // cipher suite is using RSA key exchange. + // First two bytes are version of TLS. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // +-+-+-+-+-+-+-+-+ + + // | | + // + + + // | Encrypted Premaster Secret (48 bytes) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (m_own_encrypted_premaster_secret.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_create_handshake_type_client_key_exchange(): encrypted premaster_secret"), + m_own_encrypted_premaster_secret.get_data(), + m_own_encrypted_premaster_secret.get_data_length())); + + status = tls_handshake_message->set_encrypted_premaster_secret( + &m_own_encrypted_premaster_secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + // Diffie-Hellman Yc is included when selected cipher suite is + // ephemeral Diffie-Hellman key exchange. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Yc length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Yc value | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (m_own_public_dhe_key.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + status = tls_handshake_message->set_public_dhe_key( + &m_own_public_dhe_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = add_record_message(tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_client_key_exchange() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_client_key_exchange()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_client_key_exchange()"); + + eap_status_e status = eap_status_process_general_error; + + if (cipher_suite_is_TLS_RSA() == true) + { + // Encrypted premaster secret is included when selected + // cipher suite is using RSA key exchange. + // First two bytes are version of TLS. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // +-+-+-+-+-+-+-+-+ + + // | | + // + + + // | Encrypted Premaster Secret (48 bytes) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (m_premaster_secret.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: rsa_encrypt_with_public_key()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_handshake_type_client_key_exchange(): premaster_secret"), + m_premaster_secret.get_data(), + m_premaster_secret.get_data_length())); + + status = m_am_tls_services->rsa_encrypt_with_public_key( + &m_premaster_secret); + + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_rsa_encrypt_with_public_key() call. + m_pending_rsa_encrypt_with_public_key = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_rsa_encrypt_with_public_key() call. + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this + // call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + else if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + // Diffie-Hellman Yc is included when selected cipher suite is + // ephemeral Diffie-Hellman key exchange. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Yc length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Yc value | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // These cipher suites does not need asyncronous operations. + // Still these cipher suites are completed in + // complete_create_handshake_type_client_key_exchange(). + status = eap_status_ok; + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_create_handshake_type_certificate_verify() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_create_handshake_type_certificate_verify()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_create_handshake_type_certificate_verify()"); + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_type_certificate_verify); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_create_handshake_type_certificate_verify(): m_signed_message_hash"), + m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()), + m_signed_message_hash.get_data_length())); + + status = tls_handshake_message->set_signed_message_hash( + &m_signed_message_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = add_record_message(tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_certificate_verify() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_certificate_verify()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_certificate_verify()"); + + // -------------------------------------------------------------------- + + if (cipher_suite_is_TLS_RSA() == true) + { + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // +-+-+-+-+-+-+-+-+ + + // | | + // + Signed MD5 hash + + // | (16 bytes) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // + Signed SHA hash + + // | (20 bytes) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // this will be created in tls_handshake_message_c::add_message_data(). + } + else if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true) + { + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // +-+-+-+-+-+-+-+-+ + + // | | + // + Signed SHA hash + + // | (48 bytes) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // this will be created in tls_handshake_message_c::add_message_data(). + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + + eap_status_e status = message_hash_save_certificate_verify(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c message_hash(m_am_tools); + + status = message_hash_create( + false, + tls_handshake_type_certificate_verify, + &message_hash, + m_is_client); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: sign_with_private_key()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: create_handshake_type_certificate_verify() message_hash"), + message_hash.get_data(message_hash.get_data_length()), + message_hash.get_data_length())); + + // NOTE this function is asyncronous. This causes complex control flow. + status = m_am_tls_services->sign_with_private_key( + &message_hash); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by complete_query_certificate_chain() call. + m_pending_sign_with_private_key = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_query_certificate_chain() call. + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_finished() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_finished()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_finished()"); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // +-+-+-+-+-+-+-+-+ + + // | | + // + + + // | PRF(master_secret, finished_label, | + // + MD5(handshake_messages) + + + // | SHA-1(handshake_messages)) [0..11] | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_type_finished); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = add_record_message(tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_new_session_ticket() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_new_session_ticket()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_new_session_ticket()"); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | ticket lifetime hint (4 bytes) ... | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | ... | opaque ticket ... n bytes + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + tls_handshake_message_c *tls_handshake_message = 0; + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools); + + eap_status_e status = allocate_handshake_message( + &tls_handshake_message, + &automatic_tls_handshake_message, + tls_handshake_type_new_session_ticket); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + + const tls_extension_c * const p_new_session_ticket = tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + &m_supported_tls_extensions, + m_am_tools); + + if (p_new_session_ticket != 0) + { + eap_array_c session_ticket_extension_array(m_am_tools); + + tls_extension_c * const p_new_session_ticket_copy = p_new_session_ticket->copy(); + if (p_new_session_ticket_copy == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = session_ticket_extension_array.add_object(p_new_session_ticket_copy, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_handshake_message->set_tls_extensions(&session_ticket_extension_array); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_handshake_message.do_not_free_variable(); + + status = add_record_message(tls_handshake_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_change_cipher_spec_type_change_cipher_spec() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_change_cipher_spec_type_change_cipher_spec()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_change_cipher_spec_type_change_cipher_spec()"); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+ + // | CCS: 1 | + // +-+-+-+-+-+-+-+-+ + + tls_change_cipher_spec_message_c * const tls_change_cipher_spec_message + = new tls_change_cipher_spec_message_c(m_am_tools, this, m_is_client); + + eap_automatic_variable_c + automatic_tls_change_cipher_spec_message( + m_am_tools, tls_change_cipher_spec_message); + + if (tls_change_cipher_spec_message == 0 + || tls_change_cipher_spec_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = tls_change_cipher_spec_message->set_change_cipher_spec_type( + tls_change_cipher_spec_type_change_cipher_spec); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_change_cipher_spec_message.do_not_free_variable(); + + status = add_record_message(tls_change_cipher_spec_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::finish_handshake() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::finish_handshake(): m_tls_session_type=%d=%s, state=%d=%s\n"), + this, + (m_is_client == true ? "client": "server"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::finish_handshake()"); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: finish_handshake(): m_master_secret"), + m_master_secret.get_data(), + m_master_secret.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: finish_handshake(): m_client_handshake_random_value"), + m_client_handshake_random_value.get_data(), + m_client_handshake_random_value.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: finish_handshake(): m_server_handshake_random_value"), + m_server_handshake_random_value.get_data(), + m_server_handshake_random_value.get_data_length())); + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + eap_status_e status(eap_status_ok); + + tls_identity_privacy_handshake_state_e tmp_identity_privacy_handshake_state = +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + m_tls_identity_privacy_handshake_state; +#else + tls_identity_privacy_handshake_state_none; +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (m_tls_use_identity_privacy == false + || tmp_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs + || m_tls_session_type != tls_session_type_full_authentication) +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + { + status = set_tls_master_secret( + &m_master_secret, + &m_client_handshake_random_value, + &m_server_handshake_random_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_DEBUG_TRACE) + // These are for debug break points. + + if (m_is_client == true) + { + if (m_tls_session_type == tls_session_type_full_authentication) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: client, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + tmp_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state))); + + } + else if (m_tls_session_type == tls_session_type_original_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: client, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + tmp_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state))); + + } + else if (m_tls_session_type == tls_session_type_stateless_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: client, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + tmp_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state))); + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: client, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + tmp_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state))); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + } + else // if (m_is_client == false) + { + if (m_tls_session_type == tls_session_type_full_authentication) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: server, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + tmp_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state))); + + } + else if (m_tls_session_type == tls_session_type_original_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: server, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + tmp_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state))); + + } + else if (m_tls_session_type == tls_session_type_stateless_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: server, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + tmp_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state))); + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: server, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state), + tmp_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state))); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + } +#endif //#if defined(USE_EAP_DEBUG_TRACE) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_application != 0) + { + m_application->set_tunneled_state( + m_tls_session_type); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_FAST_EAP_TYPE) + if (m_is_client == false + && m_eap_type == eap_type_fast + && m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption) + { + // This is server. + // EAP-FAST is using Tunnel PAC. + // Here we cannot start tunneled authentication immediately + // because client migth have sent a User Authorization PAC. + // We must process the optional TLS Application message(s) + // to see did client send the User Authorization PAC. + set_state(tls_peap_state_wait_tunneled_authentication_start); + + eap_status_e tunnel_ready_status = m_application->peap_tunnel_ready(); + if (tunnel_ready_status != eap_status_ok) + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, tunnel_ready_status); + } + + tunnel_ready_status = get_type_partner()->peap_tunnel_ready(); + if (tunnel_ready_status != eap_status_ok) + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, tunnel_ready_status); + } + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + if (get_is_tunneled_tls() == false + || ((m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && ( +#if defined(USE_FAST_EAP_TYPE) + m_eap_type == eap_type_fast + || +#endif //#if defined(USE_FAST_EAP_TYPE) + m_eap_type == eap_type_ttls + || (m_eap_type == eap_type_peap +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + && m_peap_version > peap_version_1 +#else + && m_peap_version > peap_version_0_xp +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + && m_peap_version < peap_version_2)))) + { + if (m_tls_session_type == tls_session_type_full_authentication + && tmp_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_negotiates) + { + // TLS-privacy negotiation running. + } + else + { + set_state(tls_peap_state_tls_success); + } + + // PEAPv2 does not use m_eap_master_session_key directly. + // PEAPv2 does derive an other master session key. + // EAP-TLS, PEAPv0 and PEAPv1 does use m_eap_master_session_key. + if (m_eap_type == eap_type_tls // Plain EAP-TLS. + || m_eap_type == eap_type_ttls +#if defined(USE_FAST_EAP_TYPE) + || m_eap_type == eap_type_fast +#endif //#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_peap + && (m_peap_version == peap_version_0_xp + || m_peap_version == peap_version_1))) + { + status = get_type_partner()->set_tls_master_secret(&m_eap_master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (( +#if defined(USE_FAST_EAP_TYPE) + m_eap_type == eap_type_fast + || +#endif //#if defined(USE_FAST_EAP_TYPE) + m_eap_type == eap_type_ttls) + && (m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption)) + { + eap_status_e notification_status = indicate_state_to_lower_layer(m_tls_peap_state); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } + } + else if (tmp_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none + || tmp_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs) + { + if ((m_eap_type == eap_type_peap + && m_peap_version >= peap_version_0_xp + && m_peap_version <= peap_version_2) + || m_eap_type == eap_type_ttls +#if defined(USE_FAST_EAP_TYPE) + || m_eap_type == eap_type_fast +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + if (m_application == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + set_state(tls_peap_state_peap_tunnel_ready); + + eap_status_e tunnel_ready_status = m_application->peap_tunnel_ready(); + if (tunnel_ready_status != eap_status_ok) + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, tunnel_ready_status); + } + + tunnel_ready_status = get_type_partner()->peap_tunnel_ready(); + if (tunnel_ready_status != eap_status_ok) + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, tunnel_ready_status); + } + +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + if ((m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && m_use_tppd_tls_peap == true + && m_peap_version == peap_version_1 + && m_use_tppd_peapv1_acknowledge_hack == true) + { + status = get_type_partner()->set_tls_master_secret(&m_eap_master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + + + if (m_is_client == true + && m_eap_type == eap_type_ttls) + { + // EAP-TTLS client starts the tunneled authentication. + + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + m_send_network_id.get_destination_id(), + m_send_network_id.get_source_id(), + m_send_network_id.get_type()); + + status = m_application->start_ttls_tunneled_authentication( + &receive_network_id, + m_received_eap_identifier); + if (status != eap_status_ok + && status != eap_status_pending_request) + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, tunnel_ready_status); + } + } + + +#if defined(USE_EAP_CORE_SERVER) + if (m_is_client == false) + { + // Server + + if ( +#if defined(USE_FAST_EAP_TYPE) + m_eap_type == eap_type_fast + || +#endif //#if defined(USE_FAST_EAP_TYPE) + (m_eap_type == eap_type_peap + && (m_peap_version >= peap_version_2 + || ((m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && ( + m_peap_version == peap_version_0_xp +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + || m_peap_version == peap_version_1 +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + ) + ) + ) + ) + ) + { +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast + && m_send_piggypacked_eap_identity_request == false + && (m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP + || m_tls_session_type == tls_session_type_full_authentication)) + { + // Server does not start tunneled authentication yet. + // Instead server waits empty EAP-FAST acnowledge message from client. + + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_eap, + m_eap_type, + eap_state_none, + eap_state_authentication_wait_eap_fast_empty_acknowledge, + m_received_eap_identifier, + false); + get_type_partner()->state_notification(¬ification); + status = eap_status_ok; + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + m_send_network_id.get_destination_id(), + m_send_network_id.get_source_id(), + m_send_network_id.get_type()); + + set_state(tls_peap_state_wait_tunneled_authentication_start); + + // Here we must start the tunneled EAP-type. + status = start_peap_tunneled_authentication( + &receive_network_id, + m_received_eap_identifier, + m_tls_session_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + else +#endif //#if defined(USE_EAP_CORE_SERVER) + { + // Client + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast) + { + // Here we swap the addresses. + eap_am_network_id_c receive_network_id(m_am_tools, + m_send_network_id.get_destination_id(), + m_send_network_id.get_source_id(), + m_send_network_id.get_type()); + + // Here we must start the tunneled EAP-type. + status = start_peap_tunneled_authentication( + &receive_network_id, + m_received_eap_identifier, + m_tls_session_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + } + + +#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + if ((m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + && m_use_tppd_tls_peap == true + && m_peap_version == peap_version_1 + && m_use_tppd_peapv1_acknowledge_hack == true) + { + if (m_is_client == true) + { + eap_state_notification_c notification( + m_am_tools, + &m_send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_internal_type, + m_eap_type, + eap_state_none, + tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet, + m_received_eap_identifier, + false); + get_type_partner()->state_notification(¬ification); + } + } +#endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES) + + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_tls_peap_state == tls_peap_state_tls_success) + { + // Notify lower layer that TLS/PEAP ended successfully + + if (get_is_tunneled_tls() == false + || (get_is_tunneled_tls() == true + && m_tunneled_eap_type_authentication_state + == eap_state_authentication_finished_successfully) + || (get_is_tunneled_tls() == true + && m_tls_session_type == tls_session_type_original_session_resumption)) + { + eap_status_e save_status = m_am_tls_services->save_tls_session( + &m_session_id, + &m_master_secret, + m_selected_cipher_suite +#if defined(USE_EAP_TLS_SESSION_TICKET) + , tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + &m_received_tls_extensions, + m_am_tools) +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + ); + if (save_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, save_status); + } + + eap_status_e notification_status = indicate_state_to_lower_layer(m_tls_peap_state); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } + } + else if (m_tls_peap_state == tls_peap_state_peap_tunnel_ready) + { + // Notify lower layer that TLS tunnel is ready. + + eap_status_e notification_status = indicate_state_to_lower_layer(m_tls_peap_state); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + + // Change state that only one indication is sent to lower layer. + if (m_is_client == true) + { + set_state(tls_peap_state_wait_application_data); + } + else + { + set_state(tls_peap_state_wait_tunneled_authentication_start); + } + } + else if (m_tls_peap_state == tls_peap_state_failure) + { + eap_status_e notification_status = indicate_state_to_lower_layer(m_tls_peap_state); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: tls_record_c::finish_handshake(): No notification, m_tls_session_type=%d=%s, state=%d=%s\n"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type), + m_tls_peap_state, + eap_tls_trace_string_c::get_state_string(m_tls_peap_state))); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_tls_protocol_alert( + const tls_alert_description_e par_alert_description, + const tls_alert_level_e par_alert_level, + const eap_status_e par_result) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_tls_protocol_alert()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_tls_protocol_alert()"); + + eap_status_e status = eap_status_authentication_failure; + + //-------------------------------------------------------------------- + + tls_alert_level_e alert_level = par_alert_level; + tls_alert_description_e alert_description = par_alert_description; + + if (alert_level == tls_alert_level_none) + { + alert_level = tls_alert_level_fatal; + } + + if (alert_description == tls_alert_description_none) + { + // Examine par_result. + switch(par_result) + { +#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION + #error Alert descriptions need more code. + case : + alert_description = tls_alert_description_close_notify; + break; +#endif //#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION + case eap_status_unexpected_message: + alert_description = tls_alert_description_unexpected_message; + break; + case eap_status_authentication_failure: + alert_description = tls_alert_description_bad_record_mac; + break; + case eap_status_decryption_failure: + case eap_status_illegal_padding: + alert_description = tls_alert_description_decryption_failed; + break; +#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION + case : + alert_description = tls_alert_description_record_overflow; + break; + case : + alert_description = tls_alert_description_decompression_failure; + break; +#endif //#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION + case eap_status_illegal_cipher_suite: + alert_description = tls_alert_description_handshake_failure; + break; + case eap_status_illegal_certificate: + case eap_status_bad_certificate: + alert_description = tls_alert_description_bad_certificate; +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast + && par_result == eap_status_bad_certificate) + { + alert_level = tls_alert_level_fatal; + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + alert_level = tls_alert_level_warning; + } + break; + case eap_status_unsupported_certificate: + alert_description = tls_alert_description_unsupported_certificate; + alert_level = tls_alert_level_warning; + break; + case eap_status_certificate_revoked: + alert_description = tls_alert_description_certificate_revoked; + alert_level = tls_alert_level_warning; + break; + case eap_status_certificate_expired: + alert_description = tls_alert_description_certificate_expired; + alert_level = tls_alert_level_warning; + break; + case eap_status_user_certificate_unknown: + case eap_status_ca_certificate_unknown: + alert_description = tls_alert_description_certificate_unknown; + alert_level = tls_alert_level_warning; + break; + case eap_status_illegal_encryption_parameter_size: + case eap_status_illegal_parameter: + alert_description = tls_alert_description_illegal_parameter; + break; + case eap_status_unknown_ca: + alert_description = tls_alert_description_unknown_ca; + break; + case eap_status_access_denied: + alert_description = tls_alert_description_access_denied; + break; + case eap_status_process_illegal_packet_error: + case eap_status_illegal_eap_code: + case eap_status_illegal_eap_type: + case eap_status_illegal_eap_identity: + case eap_status_too_short_message: + case eap_status_too_long_message: + case eap_status_wrong_protocol: + case eap_status_wrong_type: + case eap_status_data_length_not_aligned_to_block_size: + case eap_status_illegal_data_payload: + case eap_status_illegal_payload: + case eap_status_header_corrupted: + case eap_status_illegal_nai: + case eap_status_illegal_nai_payload: + alert_description = tls_alert_description_decode_error; + break; +#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION + case : + alert_description = tls_alert_description_decrypt_error; + break; + case : + alert_description = tls_alert_description_export_restriction; + break; +#endif //#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION + case eap_status_no_matching_protocol_version: + alert_description = tls_alert_description_protocol_version; + break; + case eap_status_insufficient_security: + alert_description = tls_alert_description_insufficient_security; + break; + case eap_status_allocation_error: + case eap_status_not_supported: + case eap_status_process_general_error: + case eap_status_type_does_not_exists_error: + case eap_status_timed_out: + case eap_status_hardware_not_ready: + alert_description = tls_alert_description_internal_error; + break; +#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION + case : + alert_description = tls_alert_description_user_canceled; + break; + case : + alert_description = tls_alert_description_no_renegotiation; + break; +#endif //#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION + default: + alert_description = tls_alert_description_internal_error; + break; + } + } + else + { + alert_description = par_alert_description; + } + + if (alert_level == tls_alert_level_fatal + && m_could_send_fatal_alert_message == false) + { + // If alert message is received or we have sent a fatal alert, we do not send alert anymore. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: create_tls_protocol_alert(), ") + EAPL("do not send fatal alert message\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, par_result); + } + + if (alert_level == tls_alert_level_warning + && m_could_send_warning_alert_message == false) + { + // If alert message is received or we have sent a warning alert, + // we do not send alert anymore. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: create_tls_protocol_alert(), ") + EAPL("do not send warning alert message\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, par_result); + } + + //-------------------------------------------------------------------- + + + set_state(tls_peap_state_failure); + + // This will cause the session terminate immediately. + status = get_type_partner()->set_session_timeout(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | alert level | alert descrip.| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + tls_alert_message_c * const tls_alert_message + = new tls_alert_message_c(m_am_tools, m_is_client); + + eap_automatic_variable_c + automatic_tls_alert_message(m_am_tools, tls_alert_message); + + if (tls_alert_message == 0 + || tls_alert_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // -------------------------------------------------------------------- + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: create_tls_protocol_alert(): Alert message %s:%s\n"), + (m_is_client == true ? "client": "server"), + eap_tls_trace_string_c::get_alert_level_string(alert_level), + eap_tls_trace_string_c::get_alert_description_string(alert_description))); + + + status = tls_alert_message->set_alert_level(alert_level); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_alert_message->set_alert_description(alert_description); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_alert_message.do_not_free_variable(); + + status = add_record_message(tls_alert_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + m_force_tls_message_send = true; + + if (alert_level == tls_alert_level_fatal) + { + m_could_send_fatal_alert_message = false; + } + + if (alert_level == tls_alert_level_warning) + { + m_could_send_warning_alert_message = false; + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::create_tls_application_data( + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_tls_application_data()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_tls_application_data()"); + + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Application data n bytes | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + tls_application_data_message_c * const tls_application_data_message + = new tls_application_data_message_c(m_am_tools, m_is_client); + + eap_automatic_variable_c + automatic_tls_application_data_message( + m_am_tools, tls_application_data_message); + + if (tls_application_data_message == 0 + || tls_application_data_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (sent_packet->get_data_length() < header_offset) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); + } + + u32_t packet_length = sent_packet->get_data_length()-header_offset; + + eap_status_e status = tls_application_data_message->set_application_data( + sent_packet->get_data_offset(header_offset, packet_length), + packet_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + // Note add_record_message() frees message on any case. + automatic_tls_application_data_message.do_not_free_variable(); + + status = add_record_message(tls_application_data_message); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // -------------------------------------------------------------------- + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // -------------------------------------------------------------------- + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_3DES_EDE_CBC_SHA( + tls_cipher_suites_e cipher_suite) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (cipher_suite == tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA + || cipher_suite == tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA + || cipher_suite == tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) + { + return true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_AES_128_CBC_SHA( + tls_cipher_suites_e cipher_suite) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (cipher_suite == tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA + || cipher_suite == tls_cipher_suites_TLS_RSA_WITH_AES_128_CBC_SHA + || cipher_suite == tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA +#if defined(USE_FAST_EAP_TYPE) + || cipher_suite == tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + return true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_RC4_128_MD5( + tls_cipher_suites_e cipher_suite) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (cipher_suite == tls_cipher_suites_TLS_RSA_WITH_RC4_128_MD5) + { + return true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_RC4_128_SHA( + tls_cipher_suites_e cipher_suite) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (cipher_suite == tls_cipher_suites_TLS_RSA_WITH_RC4_128_SHA) + { + return true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_TLS_RSA() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_selected_cipher_suite == tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA + || m_selected_cipher_suite == tls_cipher_suites_TLS_RSA_WITH_AES_128_CBC_SHA + || m_selected_cipher_suite == tls_cipher_suites_TLS_RSA_WITH_RC4_128_MD5 + || m_selected_cipher_suite == tls_cipher_suites_TLS_RSA_WITH_RC4_128_SHA) + { + return true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_TLS_DHE_RSA() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_selected_cipher_suite == tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + || m_selected_cipher_suite == tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA) + { + return true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_TLS_DHE_DSS() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_selected_cipher_suite == tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA + || m_selected_cipher_suite == tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA) + { + return true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; +} + +//-------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + +EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_TLS_DH_anon() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_selected_cipher_suite == tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA) + { + return true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; +} + +#endif //#if defined(USE_FAST_EAP_TYPE) + +//-------------------------------------------------- + +#if EAP_TLS_UNSUPPORTED_CIPHER_SUITE +#error This one needs more code. Diffie-Hellman sertificate key exchange with different parameters is NOT supported. +EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_TLS_DH_DSS() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_selected_cipher_suite == tls_cipher_suites_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA) + { + return true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return false; +} +#endif + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::generate_dhe_keys() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: key_function: starts: tls_record_c::generate_dhe_keys()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::generate_dhe_keys()"); + + eap_status_e status = eap_status_not_supported; + + if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + if (m_dhe_prime.get_is_valid_data() == false + || m_dhe_group_generator.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + crypto_ephemeral_diffie_hellman_c dhe(m_am_tools); + + if (dhe.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: key_function: dhe.generate_diffie_hellman_keys()\n"), + (m_is_client == true ? "client": "server"))); + + status = dhe.generate_diffie_hellman_keys( + &m_own_private_dhe_key, + &m_own_public_dhe_key, + m_dhe_prime.get_data(m_dhe_prime.get_data_length()), + m_dhe_prime.get_data_length(), + m_dhe_group_generator.get_data(m_dhe_group_generator.get_data_length()), + m_dhe_group_generator.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::generate_premaster_secret() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: key_function: starts: tls_record_c::generate_premaster_secret()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::generate_premaster_secret()"); + + eap_status_e status = eap_status_not_supported; + + m_key_material_generated = false; + + if (cipher_suite_is_TLS_RSA() == true) + { + // Encrypted premaster secret is included when selected + // cipher suite is using RSA key exchange. + // First two bytes are version of TLS. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // +-+-+-+-+-+-+-+-+ + + // | | + // + + + // | Encrypted Premaster Secret (48 bytes) | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + crypto_random_c rand(m_am_tools); + + status = m_premaster_secret.set_buffer_length(TLS_PREMASTER_SECRET_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_premaster_secret.set_data_length(TLS_PREMASTER_SECRET_SIZE); + + u16_t version = eap_htons(tls_version_3_1); + status = m_premaster_secret.add_data_to_offset(0ul, &version, sizeof(version)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_premaster_secret.get_data_length() < sizeof(version)) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = rand.get_rand_bytes( + m_premaster_secret.get_data_offset( + sizeof(version), + m_premaster_secret.get_data_length()-sizeof(version)), + m_premaster_secret.get_data_length()-sizeof(version)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: m_premaster_secret"), + m_premaster_secret.get_data(m_premaster_secret.get_data_length()), + m_premaster_secret.get_data_length())); + } + else if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true +#if defined(USE_FAST_EAP_TYPE) + || (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && cipher_suite_is_TLS_DH_anon() == true) +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + { + // Diffie-Hellman Yc is included when selected cipher suite is + // ephemeral Diffie-Hellman key exchange. + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | DH Yc length | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // | | + // + + + // | DH Yc value | + // + + + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + if (m_dhe_prime.get_is_valid_data() == false + || m_dhe_group_generator.get_is_valid_data() == false + || m_peer_public_dhe_key.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + crypto_ephemeral_diffie_hellman_c dhe(m_am_tools); + + if (dhe.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: key_function: dhe.generate_g_power_to_xy()\n"), + (m_is_client == true ? "client": "server"))); + + status = dhe.generate_g_power_to_xy( + &m_own_private_dhe_key, + &m_peer_public_dhe_key, + &m_premaster_secret, + m_dhe_prime.get_data(m_dhe_prime.get_data_length()), + m_dhe_prime.get_data_length(), + m_dhe_group_generator.get_data(m_dhe_group_generator.get_data_length()), + m_dhe_group_generator.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: m_premaster_secret"), + m_premaster_secret.get_data(m_premaster_secret.get_data_length()), + m_premaster_secret.get_data_length())); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::generate_master_secret() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: key_function: starts: tls_record_c::generate_master_secret()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::generate_master_secret()"); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_master_secret(): m_premaster_secret"), + m_premaster_secret.get_data(), + m_premaster_secret.get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_master_secret(): m_client_handshake_random_value"), + m_client_handshake_random_value.get_data(), + m_client_handshake_random_value.get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_master_secret(): m_server_handshake_random_value"), + m_server_handshake_random_value.get_data(), + m_server_handshake_random_value.get_data_length())); + + if (m_premaster_secret.get_is_valid_data() == false + || m_client_handshake_random_value.get_is_valid_data() == false + || m_server_handshake_random_value.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = eap_status_not_supported; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: prf_function: tls_prf.tls_prf_output()\n"), + (m_is_client == true ? "client": "server"))); + + crypto_tls_prf_c tls_prf(m_am_tools); + + eap_variable_data_c label(m_am_tools); + if (label.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = label.add_data( + TLS_MASTER_SECRET_LABEL, + TLS_MASTER_SECRET_LABEL_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c seed(m_am_tools); + if (seed.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + status = seed.set_copy_of_buffer(&m_client_handshake_random_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = seed.add_data(&m_server_handshake_random_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_prf.tls_prf_init( + &m_premaster_secret, + &label, + &seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_master_secret.set_buffer_length(TLS_MASTER_SECRET_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_master_secret.set_data_length(TLS_MASTER_SECRET_SIZE); + + status = tls_prf.tls_prf_output( + m_master_secret.get_data(m_master_secret.get_data_length()), + m_master_secret.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: tls_record_c::generate_master_secret(): m_master_secret"), + m_master_secret.get_data(), + m_master_secret.get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + +EAP_FUNC_EXPORT eap_status_e tls_record_c::generate_eap_fast_master_secret_from_pac_key( + const eap_variable_data_c * const pac_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: key_function: starts: tls_record_c::generate_eap_fast_master_secret_from_pac_key()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::generate_eap_fast_master_secret_from_pac_key()"); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_eap_fast_master_secret_from_pac_key(): PAC_Key"), + pac_key->get_data(), + pac_key->get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_eap_fast_master_secret_from_pac_key(): m_server_handshake_random_value"), + m_server_handshake_random_value.get_data(), + m_server_handshake_random_value.get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_eap_fast_master_secret_from_pac_key(): m_client_handshake_random_value"), + m_client_handshake_random_value.get_data(), + m_client_handshake_random_value.get_data_length())); + + if (pac_key == 0 + || pac_key->get_is_valid_data() == false + || m_client_handshake_random_value.get_is_valid_data() == false + || m_server_handshake_random_value.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_not_supported); + + + crypto_eap_fast_hmac_sha1_prf_c tls_prf(m_am_tools); + + eap_variable_data_c label(m_am_tools); + if (label.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = label.add_data( + EAP_FAST_PAC_TO_MASTER_SECRET_LABEL, + EAP_FAST_PAC_TO_MASTER_SECRET_LABEL_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c seed(m_am_tools); + if (seed.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = seed.set_copy_of_buffer(&m_server_handshake_random_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = seed.add_data(&m_client_handshake_random_value); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = tls_prf.t_prf_init( + pac_key, + &label, + &seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_master_secret.set_buffer_length(TLS_MASTER_SECRET_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + m_master_secret.set_data_length(TLS_MASTER_SECRET_SIZE); + + status = tls_prf.t_prf_output( + m_master_secret.get_data(), + static_cast(m_master_secret.get_data_length())); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAP-FAST: m_master_secret"), + m_master_secret.get_data(), + m_master_secret.get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_FAST_EAP_TYPE) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_cipher_suites_and_previous_session( + const tls_session_type_e /* tls_session_type */, + EAP_TEMPLATE_CONST eap_array_c * const cipher_suites, + EAP_TEMPLATE_CONST eap_array_c * const compression_methods, +#if defined(USE_EAP_TLS_SESSION_TICKET) + EAP_TEMPLATE_CONST eap_array_c * const tls_extensions, +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + const eap_variable_data_c * const resumed_session_id, + const eap_variable_data_c * const resumed_master_secret, + const tls_cipher_suites_e resumed_cipher_suite, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_query_cipher_suites_and_previous_session()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_cipher_suites_and_previous_session()"); + + m_pending_query_cipher_suites_and_previous_session = false; + + m_proposed_cipher_suites.reset(); + m_proposed_compression_methods.reset(); + + eap_status_e status = eap_status_process_general_error; + + + if (completion_status != eap_status_ok) + { + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + completion_status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = copy_simple( + cipher_suites, + &m_proposed_cipher_suites, + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = for_each(&m_proposed_cipher_suites, u16_t_to_host_order, m_am_tools, false); + if (status != eap_status_ok + || m_proposed_cipher_suites.get_object_count() == 0ul) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == false) + { + // TLS_DH_anon_WITH_AES_128_CBC_SHA is allowed only with EAP-FAST unauthenticated provisioning mode. + u16_t illegal_cipher_suite(static_cast(tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA)); + + i32_t index = find_simple( + &m_proposed_cipher_suites, + &illegal_cipher_suite, + m_am_tools); + if (index >= 0) + { + status = m_proposed_cipher_suites.remove_object(index); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + status = copy_simple( + compression_methods, + &m_proposed_compression_methods, + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast + && m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption) + { + // Let's try tunnel PAC authentication. + + // We will use the first cipher suite as an default one. + u16_t * cipher_suite = m_proposed_cipher_suites.get_object(0ul); + if (cipher_suite != 0) + { + m_resumed_cipher_suite = static_cast(*cipher_suite); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + if (resumed_session_id != 0 + && resumed_session_id->get_is_valid_data() == true + && resumed_session_id->get_data_length() > 0ul + && resumed_master_secret != 0 + && resumed_master_secret->get_is_valid_data() == true + && resumed_master_secret->get_data_length() == TLS_MASTER_SECRET_SIZE + && resumed_cipher_suite != tls_cipher_suites_none) + { + // Resume previous session. + + status = m_session_id.set_copy_of_buffer(resumed_session_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_master_secret.set_copy_of_buffer(resumed_master_secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: complete_query_cipher_suites_and_previous_session(): ") + EAPL("Resume previous session.\n"), + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_query_cipher_suites_and_previous_session(): resumed m_master_secret"), + m_master_secret.get_data(m_master_secret.get_data_length()), + m_master_secret.get_data_length())); + + m_resumed_cipher_suite = resumed_cipher_suite; + + set_tls_session_type(tls_session_type_original_session_resumption); + } + else + { + +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + if (m_is_client == true + && m_tls_use_identity_privacy == true + && m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none) + { + set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_negotiates); + } +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + + set_tls_session_type(tls_session_type_full_authentication); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: complete_query_cipher_suites_and_previous_session(): ") + EAPL("full authentication.\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e notification_status = indicate_state_to_lower_layer( + tls_peap_state_full_authentication); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } + +#if defined(USE_EAP_TLS_SESSION_TICKET) + if (tls_extensions != 0) + { + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast) + { + // Nothing to do. + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + status = copy( + tls_extensions, + &m_supported_tls_extensions, + m_am_tools, + false); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_FAST_EAP_TYPE) + eap_fast_pac_type_e required_pac_type(eap_fast_pac_type_none); + + if (m_eap_type == eap_type_fast) + { + // In EAP-FAST we are interested only Tunnel PAC. + required_pac_type = eap_fast_pac_type_tunnel_pac; + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + const tls_extension_c * const supported_session_ticket_extension = tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, +#if defined(USE_FAST_EAP_TYPE) + required_pac_type, +#endif //#if defined(USE_FAST_EAP_TYPE) + &m_supported_tls_extensions, + m_am_tools); + + if (supported_session_ticket_extension != 0 + && supported_session_ticket_extension->get_is_valid_data() == true + && supported_session_ticket_extension->get_data_length() > 0ul) + { +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: complete_query_cipher_suites_and_previous_session(): ") + EAPL("SST: EAP-FAST PAC stateless session resumption, length = %d.\n"), + (m_is_client == true ? "client": "server"), + supported_session_ticket_extension->get_data_length())); + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + //if (m_tls_session_type == tls_session_type_original_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: complete_query_cipher_suites_and_previous_session(): ") + EAPL("SST: stateless session resumption, length = %d.\n"), + (m_is_client == true ? "client": "server"), + supported_session_ticket_extension->get_data_length())); + + set_tls_session_type(tls_session_type_stateless_session_resumption); + } + } + } +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast + //&& m_tls_session_type == tls_session_type_full_authentication + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true) + { + // Try dynamic provisioning of PAC. + + set_tls_session_type(tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: complete_query_cipher_suites_and_previous_session(): ") + EAPL("server unauthenticated provisioning mode ADHP.\n"), + (m_is_client == true ? "client": "server"))); + + m_proposed_cipher_suites.reset(); + + u16_t * const anonymous_cipher_suite = new u16_t; + + if (anonymous_cipher_suite == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *anonymous_cipher_suite = static_cast(tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA); + + status = m_proposed_cipher_suites.add_object( + anonymous_cipher_suite, + true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: complete_query_cipher_suites_and_previous_session(): ") + EAPL("m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP = %d.\n"), + (m_is_client == true ? "client": "server"), + m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP)); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + + } + + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_select_cipher_suite_and_check_session_id( + const tls_session_type_e tls_session_type, + const u16_t selected_cipher_suite, + const eap_variable_data_c * const resumed_session_id, + const eap_variable_data_c * const resumed_master_secret, +#if defined(USE_EAP_TLS_SESSION_TICKET) + const tls_extension_c * const new_session_ticket_or_null, +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_select_cipher_suite_and_check_session_id()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_select_cipher_suite_and_check_session_id()"); + + EAP_ASSERT_ALWAYS(m_is_client == false); + + eap_status_e status = eap_status_ok; + + m_pending_select_cipher_suite_and_check_session_id = false; + + + if (completion_status != eap_status_ok) + { + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + completion_status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + set_tls_session_type(tls_session_type); + + set_selected_cipher_suite(static_cast(selected_cipher_suite)); + m_selected_compression_method = tls_compression_method_null; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast + && m_tls_session_type == tls_session_type_full_authentication + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true + && m_selected_cipher_suite == tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA) + { + // Try dynamic provisioning of PAC. + + set_tls_session_type(tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_TLS_SESSION_TICKET) + if (new_session_ticket_or_null != 0) + { + // We are using the session ticket payload. + + tls_extension_c * copy_of_new_session_ticket = new_session_ticket_or_null->copy(); + if (copy_of_new_session_ticket == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Save the new session ticket to be included in next NewSessionTicket message. + status = m_supported_tls_extensions.add_object(copy_of_new_session_ticket, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (m_tls_session_type == tls_session_type_stateless_session_resumption) + { + if (resumed_session_id != 0 + && resumed_session_id->get_is_valid_data() == true) + { + // The session ID is needed if client did include it to the ClientHello. + status = m_session_id.set_copy_of_buffer(resumed_session_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (resumed_master_secret != 0 + && resumed_master_secret->get_is_valid_data() == true + && resumed_master_secret->get_data_length() == TLS_MASTER_SECRET_SIZE) + { + status = m_master_secret.set_copy_of_buffer(resumed_master_secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): session ticket resumed m_master_secret"), + m_master_secret.get_data(m_master_secret.get_data_length()), + m_master_secret.get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: ") + EAPL("complete_select_cipher_suite_and_check_session_id(): restores session using session ticket\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e notification_status = indicate_state_to_lower_layer( + tls_peap_state_original_session_resumption); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } + } + else +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + if (m_tls_session_type == tls_session_type_original_session_resumption + && ((m_eap_type == eap_type_peap + /** @{ PEAPv2 does not support session resumption yet. } */ + && m_peap_version != peap_version_2) + || m_eap_type == eap_type_tls + || m_eap_type == eap_type_ttls +#if defined(USE_FAST_EAP_TYPE) + || m_eap_type == eap_type_fast +#endif //#if defined(USE_FAST_EAP_TYPE) + ) + && resumed_session_id != 0 + && resumed_session_id->get_is_valid_data() == true + && resumed_session_id->get_data_length() > 0ul + && resumed_master_secret != 0 + && resumed_master_secret->get_is_valid_data() == true + && resumed_master_secret->get_data_length() == TLS_MASTER_SECRET_SIZE + ) + { + // Restore previous session. + + status = m_session_id.set_copy_of_buffer(resumed_session_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_master_secret.set_copy_of_buffer(resumed_master_secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): resumed m_master_secret"), + m_master_secret.get_data(m_master_secret.get_data_length()), + m_master_secret.get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: ") + EAPL("complete_select_cipher_suite_and_check_session_id(): restores session\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e notification_status = indicate_state_to_lower_layer( + tls_peap_state_original_session_resumption); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): EAP-FAST server: %s\n"), + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type))); + + // Parameter resumed_master_secret includes PAC-Key. + status = m_eap_fast_pac_key.set_copy_of_buffer(resumed_master_secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): resumed m_master_secret"), + m_master_secret.get_data(m_master_secret.get_data_length()), + m_master_secret.get_data_length())); + + eap_status_e notification_status = indicate_state_to_lower_layer( + tls_peap_state_original_session_resumption); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } + else if (m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): EAP-FAST server unauthenticated provisioning mode\n"))); + + eap_status_e notification_status = indicate_state_to_lower_layer( + tls_peap_state_full_authentication); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + else + { + set_tls_session_type(tls_session_type_full_authentication); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): full authentication\n"))); + + eap_status_e notification_status = indicate_state_to_lower_layer( + tls_peap_state_full_authentication); + if (notification_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, notification_status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type != eap_type_fast) +#endif //#if defined(USE_FAST_EAP_TYPE) + { + if (m_tls_session_type == tls_session_type_original_session_resumption + || m_tls_session_type == tls_session_type_stateless_session_resumption) + { + const tls_extension_c * const supported_session_ticket_extension = tls_extension_c::get_tls_extension( + tls_extension_type_session_ticket, + &m_supported_tls_extensions, + m_am_tools); + if (supported_session_ticket_extension != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: complete_select_cipher_suite_and_check_session_id(): ") + EAPL("SST: Server will send a new session ticket to client, length = %d.\n"), + (m_is_client == true ? "client": "server"), + supported_session_ticket_extension->get_data_length())); + + // Server will send a new session ticket to client. + status = completion_action_add( + tls_completion_action_create_handshake_type_new_session_ticket); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + } + +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + + + // The following sequence depends on whether the previous + // session is restored and on the selected cipher suite. + + if (m_tls_session_type == tls_session_type_original_session_resumption +#if defined(USE_EAP_TLS_SESSION_TICKET) + || m_tls_session_type == tls_session_type_stateless_session_resumption +#if defined(USE_FAST_EAP_TYPE) + || m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption +#endif //#if defined(USE_FAST_EAP_TYPE) +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + ) + { +#if defined(USE_EAP_TLS_SESSION_TICKET) + if (m_will_receive_new_session_ticket == true) + { + set_state(tls_peap_state_wait_handshake_type_new_session_ticket); + } + else +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + { + set_state(tls_peap_state_wait_change_cipher_spec); + } + + status = completion_action_add( + tls_completion_action_create_change_cipher_spec_type_change_cipher_spec); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = completion_action_add(tls_completion_action_create_handshake_type_finished); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#if defined(USE_FAST_EAP_TYPE) + else if (m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP) + { + // Ephemeral DH key exchange causes creation of server_key_exchange message. + // Server sends DH public key and related parameters to client. + + status = completion_action_add(tls_completion_action_query_dh_parameters); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = completion_action_add( + tls_completion_action_create_handshake_type_server_key_exchange); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This will complete creation of handshake_type_server_key_exchange message. + status = completion_action_add( + tls_completion_action_complete_create_handshake_type_server_key_exchange); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Also the other pending messages will be processed after this action is completed. + eap_status_e compl_status = completion_action_add( + tls_completion_action_process_tls_records); + if (compl_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = completion_action_add( + tls_completion_action_create_handshake_type_server_hello_done); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + set_state(tls_peap_state_wait_handshake_type_client_key_exchange); + } +#endif //#if defined(USE_FAST_EAP_TYPE) + else + { + if (m_tls_peap_server_authenticates_client_config_server == true) + { + set_state(tls_peap_state_wait_handshake_type_certificate); + } + else + { + set_state(tls_peap_state_wait_handshake_type_client_key_exchange); + } + + status = completion_action_add(tls_completion_action_create_handshake_type_certificate); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (cipher_suite_is_TLS_DHE_DSS() == true + || cipher_suite_is_TLS_DHE_RSA() == true) + { + // Ephemeral DH key exchange causes creation of server_key_exchange message. + // Server sends DH public key and related parameters to client. + + status = completion_action_add(tls_completion_action_query_dh_parameters); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = completion_action_add( + tls_completion_action_create_handshake_type_server_key_exchange); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This will complete creation of handshake_type_server_key_exchange message. + status = completion_action_add( + tls_completion_action_complete_create_handshake_type_server_key_exchange); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Also the other pending messages will be processed after this action is completed. + eap_status_e compl_status = completion_action_add( + tls_completion_action_process_tls_records); + if (compl_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (m_tls_peap_server_authenticates_client_config_server == true) + { + // Server initiates client authentication. + status = completion_action_add( + tls_completion_action_create_handshake_type_certificate_request); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = completion_action_add( + tls_completion_action_create_handshake_type_server_hello_done); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: pki_function: query_certificate_chain()\n"), + (m_is_client == true ? "client": "server"))); + + status = m_am_tls_services->query_certificate_chain( + &m_own_certificate_authorities, + &m_own_certificate_types, + m_selected_cipher_suite); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_query_certificate_chain() call. + m_pending_query_certificate_chain = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by complete_query_certificate_chain() call. + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this + // call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (m_tls_peap_server_authenticates_client_config_server == true) + { + // Server initiates client authentication. + status = m_am_tls_services->query_certificate_authorities_and_types(); + if (status == eap_status_pending_request) + { + // This is pending query, that will be completed by + // complete_query_certificate_authorities_and_types() call. + m_pending_query_certificate_authorities_and_types = true; + } + else if (status == eap_status_completed_request) + { + // This is already completed by + // complete_query_certificate_authorities_and_types() call. + } + else if (status == eap_status_ok) + { + // This is also an error case, because this call is + // always completed on success. + status = eap_status_process_general_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else // All other status values means error, because this + // call is always completed on success. + { + // This is an error case. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status); + } + } + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_new_session_ticket( + const tls_extension_c * const new_session_ticket_or_null) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_query_new_session_ticket()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_new_session_ticket()"); + + eap_status_e status(eap_status_ok); + + if (new_session_ticket_or_null != 0) + { + tls_extension_c * const copy_of_session_ticket = new_session_ticket_or_null->copy(); + + if (copy_of_session_ticket == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_supported_tls_extensions.add_object(copy_of_session_ticket, true); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_verify_certificate_chain( + const eap_status_e result) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_verify_certificate_chain()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_verify_certificate_chain()"); + + eap_status_e status = result; + + m_pending_verify_certificate_chain = false; + + m_peer_certificate_chain_result = result; + + if (m_peer_certificate_chain_result == eap_status_ok) + { + // Ok certificate. + } + else + { + // Illegal certificate. + + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + m_peer_certificate_chain_result); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_certificate_chain( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_query_certificate_chain()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_certificate_chain()"); + + eap_status_e status = eap_status_not_supported; + + m_pending_query_certificate_chain = false; + + { + if (completion_status != eap_status_ok + || certificate_chain == 0 + || certificate_chain->get_object_count() == 0) + { + if (completion_status != eap_status_ok) + { + (void)EAP_STATUS_RETURN(m_am_tools, completion_status); + } + + if (m_is_client == false) + { + // Server fails immediately. + + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + completion_status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: pki_function: complete_query_certificate_chain(): ") + EAPL("Server have illegal sertificate for this cipher suite.\n"), + (m_is_client == true ? "client": "server"))); + } + else + { + if (m_tls_peap_server_authenticates_client_policy_flag == true + || (m_tls_peap_server_authenticates_client_policy_flag == false + && completion_status != eap_status_illegal_certificate + && completion_status != eap_status_ca_certificate_unknown)) + { + // Client does fail immediately. + // This session could NOT use server only authentication. + if (completion_status == eap_status_illegal_certificate) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: pki_function: complete_query_certificate_chain(): ") + EAPL("Client have illegal sertificate for this cipher suite.\n"), + (m_is_client == true ? "client": "server"))); + + status = eap_status_illegal_certificate; + (void)EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: TLS: %s: pki_function: complete_query_certificate_chain(): ") + EAPL("Client does NOT allow anonymous client.\n"), + (m_is_client == true ? "client": "server"))); + + status = eap_status_insufficient_security; + (void)EAP_STATUS_RETURN(m_am_tools, status); + } + + // This will cause the session terminate immediately. + status = get_type_partner()->set_session_timeout(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast) + { + send_error_notification(eap_status_no_pac_nor_certs_to_authenticate_with_provision_disabled); + + status = create_tls_protocol_alert( + tls_alert_description_internal_error, + tls_alert_level_fatal, + status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + completion_status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + else + { + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast + && m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == false + && m_fast_allow_server_authenticated_provisioning_mode == false) + { + // No PAC, no sertificate, no provision allowed. + // This will cause the session terminate immediately. + status = get_type_partner()->set_session_timeout(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + send_error_notification(eap_status_no_pac_nor_certs_to_authenticate_with_provision_disabled); + + status = create_tls_protocol_alert( + tls_alert_description_internal_error, + tls_alert_level_fatal, + status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else +#endif //#if defined(USE_FAST_EAP_TYPE) + { + // Client does not fail immediately. + // This session could use server only authentication. + // NOTE, in this case client must send empty certificate message to server. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("INFO: TLS: %s: pki_function: complete_query_certificate_chain(): ") + EAPL("Client allows anonymous client.\n"), + (m_is_client == true ? "client": "server"))); + + m_tls_peap_server_authenticates_client_action = false; + status = eap_status_ok; + } + } + } + } + else + { + status = copy( + certificate_chain, + &m_own_certificate_chain, + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_certificate_authorities_and_types( + EAP_TEMPLATE_CONST eap_array_c * const certificate_authorities, + EAP_TEMPLATE_CONST eap_array_c * const certificate_types, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_query_certificate_authorities_and_types()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_certificate_authorities_and_types()"); + + m_pending_query_certificate_authorities_and_types = false; + + eap_status_e status = eap_status_not_supported; + + if (completion_status != eap_status_ok) + { + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + completion_status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = copy( + certificate_authorities, + &m_own_certificate_authorities, + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = copy_simple( + certificate_types, + &m_own_certificate_types, + m_am_tools, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_dh_parameters( + const eap_variable_data_c * const dhe_prime, + const eap_variable_data_c * const dhe_group_generator, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_query_dh_parameters()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_dh_parameters()"); + + m_pending_query_dh_parameters = false; + + eap_status_e status = eap_status_not_supported; + + if (completion_status != eap_status_ok) + { + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + completion_status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = m_dhe_prime.set_copy_of_buffer(dhe_prime); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_dhe_group_generator.set_copy_of_buffer(dhe_group_generator); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_realm( + const eap_variable_data_c * const realm, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_query_realm()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_realm()"); + + m_pending_query_realm = false; + + eap_status_e status = eap_status_not_supported; + + if (completion_status != eap_status_ok) + { + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + completion_status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = m_NAI_realm.set_copy_of_buffer(realm); + } + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_rsa_decrypt_with_private_key( + const eap_variable_data_c * const premaster_secret, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_rsa_decrypt_with_private_key()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_rsa_decrypt_with_private_key()"); + + m_pending_rsa_decrypt_with_private_key = false; + + eap_status_e status = eap_status_not_supported; + + if (completion_status != eap_status_ok) + { + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + completion_status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_rsa_decrypt_with_private_key(): premaster_secret"), + premaster_secret->get_data(), + premaster_secret->get_data_length())); + + status = m_premaster_secret.set_copy_of_buffer(premaster_secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: m_premaster_secret"), + m_premaster_secret.get_data(m_premaster_secret.get_data_length()), + m_premaster_secret.get_data_length())); + + m_key_material_generated = false; + + // We must generate master secret. + status = generate_master_secret(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // We must generate the key material. + status = generate_key_material(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_rsa_encrypt_with_public_key( + const eap_variable_data_c * const encrypted_premaster_secret, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_rsa_encrypt_with_public_key()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_rsa_encrypt_with_public_key()"); + + m_pending_rsa_encrypt_with_public_key = false; + + eap_status_e status = eap_status_not_supported; + + if (completion_status != eap_status_ok) + { + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + completion_status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_rsa_encrypt_with_public_key(): encrypted premaster_secret"), + encrypted_premaster_secret->get_data(), + encrypted_premaster_secret->get_data_length())); + + status = m_own_encrypted_premaster_secret.set_copy_of_buffer(encrypted_premaster_secret); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_sign_with_private_key( + const eap_variable_data_c * const signed_message_hash, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_sign_with_private_key()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_sign_with_private_key()"); + + m_pending_sign_with_private_key = false; + + eap_status_e status = eap_status_not_supported; + + if (completion_status != eap_status_ok) + { + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + completion_status); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + if (signed_message_hash->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + status = m_signed_message_hash.set_copy_of_buffer(signed_message_hash); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: complete_sign_with_private_key(): m_signed_message_hash"), + m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()), + m_signed_message_hash.get_data_length())); + } + + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_verify_with_public_key( + const eap_status_e verify_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_verify_with_public_key()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_verify_with_public_key()"); + + m_pending_verify_with_public_key = false; + + eap_status_e status = eap_status_ok; + + m_verify_signature = verify_status; + + if (m_verify_signature != eap_status_ok) + { + // Verification failed. + + status = create_tls_protocol_alert( + tls_alert_description_none, + tls_alert_level_none, + m_verify_signature); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (status == eap_status_ok) + { + status = check_sent_tls_message(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::get_eap_tls_master_session_key( + eap_variable_data_c * const eap_tls_master_session_key, + eap_variable_data_c * const mschapv2_challenges + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::get_eap_tls_master_session_key()\n"), + this, + (m_is_client == true ? "client": "server"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_eap_tls_master_session_key()"); + + eap_status_e status(eap_status_process_general_error); + +#if defined(USE_FAST_EAP_TYPE) + if (m_eap_type == eap_type_fast) + { + status = eap_tls_master_session_key->set_copy_of_buffer(&m_session_key_seed); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (mschapv2_challenges != 0 + && mschapv2_challenges->get_is_valid() == true + && m_mschapv2_challenges.get_is_valid_data() == true) + { + status = mschapv2_challenges->set_copy_of_buffer(&m_mschapv2_challenges); + } + } + else +#else + EAP_UNREFERENCED_PARAMETER(mschapv2_challenges); +#endif //#if defined(USE_FAST_EAP_TYPE) + { + status = eap_tls_master_session_key->set_copy_of_buffer(&m_eap_master_session_key); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + return EAP_STATUS_RETURN(m_am_tools, get_type_partner()->add_rogue_ap(rogue_ap_list)); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e tls_record_c::set_session_timeout( + const u32_t session_timeout_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = get_type_partner()->set_session_timeout(session_timeout_ms); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::set_tls_session_type(const tls_session_type_e tls_session_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::set_tls_session_type(): m_tls_session_type=%d=%s\n"), + this, + (m_is_client == true ? "client": "server"), + tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(tls_session_type))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::set_tls_session_type()"); + + m_tls_session_type = tls_session_type; + + eap_status_e status = get_type_partner()->set_tls_session_type(tls_session_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_session_type_e tls_record_c::get_tls_session_type() +{ + return m_tls_session_type; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_c::set_tls_identity_privacy_handshake_state(const tls_identity_privacy_handshake_state_e state) +{ +#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::set_tls_identity_privacy_handshake_state(): Changes from %d=%s to %d=%s\n"), + this, + (m_is_client == true ? "client": "server"), + m_tls_identity_privacy_handshake_state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(m_tls_identity_privacy_handshake_state), + state, + eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(state))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::set_tls_identity_privacy_handshake_state()"); + + m_tls_identity_privacy_handshake_state = state; +#else + EAP_UNREFERENCED_PARAMETER(state); +#endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY) +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_c::set_selected_cipher_suite(const tls_cipher_suites_e cipher_suite) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: suite_function: starts: tls_record_c::set_selected_cipher_suite(): Changes from %d=%s to %d=%s\n"), + this, + (m_is_client == true ? "client": "server"), + m_selected_cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite), + cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(cipher_suite))); + + m_selected_cipher_suite = cipher_suite; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::set_receive_cipher_suite(const tls_cipher_suites_e cipher_suite) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: suite_function: starts: tls_record_c::set_receive_cipher_suite(): Changes from %d=%s to %d=%s\n"), + this, + (m_is_client == true ? "client": "server"), + m_receive_cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite), + cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(cipher_suite))); + + m_receive_cipher_suite = cipher_suite; + + m_receive_record_sequence_number = 0ul; + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_receive_cipher_suite(): m_receive_encryption_key"), + m_receive_encryption_key.get_data(), + m_receive_encryption_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_receive_cipher_suite(): m_new_receive_encryption_key"), + m_new_receive_encryption_key.get_data(), + m_new_receive_encryption_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_receive_cipher_suite(): m_receive_mac_key"), + m_receive_mac_key.get_data(), + m_receive_mac_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_receive_cipher_suite(): m_new_receive_mac_key"), + m_new_receive_mac_key.get_data(), + m_new_receive_mac_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_receive_cipher_suite(): m_receive_iv"), + m_receive_iv.get_data(), + m_receive_iv.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_receive_cipher_suite(): m_new_receive_iv"), + m_new_receive_iv.get_data(), + m_new_receive_iv.get_data_length())); + + + eap_status_e status = m_receive_mac_key.set_copy_of_buffer(&m_new_receive_mac_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_receive_encryption_key.set_copy_of_buffer(&m_new_receive_encryption_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_receive_iv.set_copy_of_buffer(&m_new_receive_iv); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::set_send_cipher_suite(const tls_cipher_suites_e cipher_suite) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: suite_function: starts: tls_record_c::set_send_cipher_suite(): Changes from %d=%s to %d=%s\n"), + this, + (m_is_client == true ? "client": "server"), + m_send_cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(m_send_cipher_suite), + cipher_suite, + eap_tls_trace_string_c::get_cipher_suite_string(cipher_suite))); + + m_send_cipher_suite = cipher_suite; + + m_send_record_sequence_number = 0ul; + + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_send_cipher_suite(): m_send_encryption_key"), + m_send_encryption_key.get_data(), + m_send_encryption_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_send_cipher_suite(): m_new_send_encryption_key"), + m_new_send_encryption_key.get_data(), + m_new_send_encryption_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_send_cipher_suite(): m_send_mac_key"), + m_send_mac_key.get_data(), + m_send_mac_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_send_cipher_suite(): m_new_send_mac_key"), + m_new_send_mac_key.get_data(), + m_new_send_mac_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_send_cipher_suite(): m_send_iv"), + m_send_iv.get_data(), + m_send_iv.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_send_cipher_suite(): m_new_send_iv"), + m_new_send_iv.get_data(), + m_new_send_iv.get_data_length())); + + + eap_status_e status = m_send_mac_key.set_copy_of_buffer(&m_new_send_mac_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_send_encryption_key.set_copy_of_buffer(&m_new_send_encryption_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_send_iv.set_copy_of_buffer(&m_new_send_iv); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_c::read_authority_identity(eap_variable_data_c * const authority_identity_payload) +{ + return m_application->read_authority_identity(authority_identity_payload); +} + +//-------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_tunnel_PAC( + const eap_status_e in_completion_status, + const eap_fast_pac_type_e in_pac_type, + const eap_fast_variable_data_c * const in_tunnel_PAC_key_tlv, + const eap_fast_variable_data_c * const in_tunnel_PAC_opaque_tlv) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_query_tunnel_PAC(): m_tls_session_type=%d=%s\n"), + this, + (m_is_client == true ? "client": "server"), + m_tls_session_type, + eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_tunnel_PAC()"); + + eap_status_e status(eap_status_process_general_error); + + m_pending_query_tunnel_PAC = false; + + if (in_completion_status == eap_status_ok) + { + tls_extension_c extension(m_am_tools); + if (extension.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (in_tunnel_PAC_opaque_tlv != 0 + && in_tunnel_PAC_opaque_tlv->get_is_valid_data() == true) + { + status = extension.set_copy_of_buffer(in_tunnel_PAC_opaque_tlv->get_full_tlv_buffer()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + extension.set_type(tls_extension_type_session_ticket); + extension.set_pac_type(in_pac_type); + + status = m_supported_tls_extensions.add_object(extension.copy(), true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (in_tunnel_PAC_key_tlv != 0 + && in_tunnel_PAC_key_tlv->get_is_valid_data() == true) + { + status = m_eap_fast_pac_key.set_copy_of_buffer( + in_tunnel_PAC_key_tlv->get_data(in_tunnel_PAC_key_tlv->get_data_length()), + in_tunnel_PAC_key_tlv->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + set_tls_session_type(tls_session_type_eap_fast_pac_session_resumption); + + if (m_application != 0) + { + m_application->set_tunneled_state(get_tls_session_type()); + } + } + + status = check_sent_tls_message(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_completed_request); +} + +#endif //#if defined(USE_FAST_EAP_TYPE) + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e tls_record_c::query_ttls_pap_username_and_password( + const eap_variable_data_c * const reply_message) +{ + eap_status_e status(eap_status_process_general_error); + + status = m_am_tls_services->query_ttls_pap_username_and_password(reply_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_ttls_pap_username_and_password( + const eap_variable_data_c * const ttls_pap_username, + const eap_variable_data_c * const ttls_pap_password, + const eap_status_e query_result) +{ + eap_status_e status(eap_status_process_general_error); + + status = m_application->complete_query_ttls_pap_username_and_password( + ttls_pap_username, + ttls_pap_password, + query_result); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e tls_record_c::verify_ttls_pap_username_and_password( + const eap_variable_data_c * const user_name, + const eap_variable_data_c * const user_password) +{ + eap_status_e status(eap_status_process_general_error); + + status = m_am_tls_services->verify_ttls_pap_username_and_password( + user_name, + user_password); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_verify_ttls_pap_username_and_password( + const eap_status_e authentication_result, + const eap_variable_data_c * const ttls_pap_reply_message) +{ + eap_status_e status(eap_status_process_general_error); + + status = m_application->complete_verify_ttls_pap_username_and_password( + authentication_result, + ttls_pap_reply_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_record_header.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_record_header.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,209 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 136 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "tls_record_header.h" + +/** @file */ + + +/// Destructor does nothing. +tls_record_header_c::~tls_record_header_c() +{ +} + +/// Constructor initializes the class. +tls_record_header_c::tls_record_header_c( + abs_eap_am_tools_c * const tools, + void * const header_buffer, + const u32_t header_buffer_length) + : eap_general_header_base_c(tools, header_buffer, header_buffer_length) + , m_am_tools(tools) +{ +} + +/// This function returns protocol of the TLS-record. +tls_record_protocol_e tls_record_header_c::get_protocol() const +{ + const u8_t * const protocol_data = get_header_offset(m_protocol_offset, sizeof(u8_t)); + if (protocol_data != 0) + { + return static_cast(*protocol_data); + } + else + { + return tls_record_protocol_none; + } +} + +/// This function returns version of the TLS-record. +tls_version_e tls_record_header_c::get_version() const +{ + const u8_t * const version_data = get_header_offset(m_version_offset, sizeof(u16_t)); + if (version_data != 0) + { + return static_cast(eap_read_u16_t_network_order(version_data, sizeof(u16_t))); + } + else + { + return tls_version_illegal; + } +} + +/// This function returns data length of the TLS-record. +/// The length (in bytes) of the following TLSPlaintext.fragment (TLS-record data). The length should not exceed 2^14. +u16_t tls_record_header_c::get_data_length() const +{ + const u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u16_t)); + if (length_data != 0) + { + return eap_read_u16_t_network_order(length_data, sizeof(u16_t)); + } + else + { + return 0ul; + } +} + +/// This function returns header length of the TLS-record. This includes only protocol, version and length fiels. +u32_t tls_record_header_c::get_header_length() +{ + return m_data_offset; +} + +/// This function returns pointer to offset of the TLS-record data. +/// @param offset is the offset of queried data in bytes. +/// @param contignuous_bytes is the length of queried data in bytes. +u8_t * tls_record_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const +{ + u32_t data_length = get_data_length(); // Here is removed optional TLS message length. + + if (data_length >= offset+contignuous_bytes) + { + u8_t * const data_begin = get_header_offset(m_data_offset, sizeof(u8_t)); + if (data_begin == 0) + { + return 0; + } + return &(data_begin[offset]); + } + else + { + return 0; + } +} + + +/// This function returns pointer to begin of the TLS-record data. +/// @param contignuous_bytes is the length of queried data in bytes. +u8_t * tls_record_header_c::get_data(const u32_t contignuous_bytes) const +{ + return get_data_offset(0u, contignuous_bytes); +} + + +/// This function returns debug strings of the TLS-protocol values. +eap_const_string tls_record_header_c::get_tls_protocol_string(const tls_record_protocol_e protocol) +{ +#if defined(USE_EAP_TRACE_STRINGS) + EAP_IF_RETURN_STRING(protocol, tls_record_protocol_none) + else EAP_IF_RETURN_STRING(protocol, tls_record_protocol_change_cipher_spec) + else EAP_IF_RETURN_STRING(protocol, tls_record_protocol_alert) + else EAP_IF_RETURN_STRING(protocol, tls_record_protocol_handshake) + else EAP_IF_RETURN_STRING(protocol, tls_record_protocol_application_data) + else +#else + EAP_UNREFERENCED_PARAMETER(protocol); +#endif // #if defined(USE_EAP_TRACE_STRINGS) + { + return EAPL("Unknown TLS record protocol"); + } +} + +/// This function returns debug strings of the TLS-protocol values. +eap_const_string tls_record_header_c::get_tls_protocol_string() const +{ + const tls_record_protocol_e protocol = get_protocol(); + return get_tls_protocol_string(protocol); +} + + +/// This function sets the protocol of TLS-record. +void tls_record_header_c::set_protocol(tls_record_protocol_e protocol) +{ + u8_t * const protocol_data = get_header_offset(m_protocol_offset, sizeof(u8_t)); + EAP_ASSERT(protocol_data != 0); + *protocol_data = static_cast(protocol); +} + +/// This function sets the version of the TLS-record. +void tls_record_header_c::set_version(tls_version_e version) +{ + u8_t * const version_data = get_header_offset(m_version_offset, sizeof(u16_t)); + EAP_ASSERT(version_data != 0); + version_data[0] = static_cast((version & 0xff00) >> 8); + version_data[1] = static_cast(version & 0x00ff); +} + +/// This function sets the data length of the TLS-record. +void tls_record_header_c::set_data_length(const u16_t p_length) +{ + u8_t * const length_data = get_header_offset(m_length_offset, sizeof(u16_t)); + EAP_ASSERT(length_data != 0); + length_data[0] = static_cast((p_length & 0xff00) >> 8); + length_data[1] = static_cast(p_length & 0x00ff); +} + +/// This function resets the TLS-record header. +void tls_record_header_c::reset_header( + const u16_t buffer_length, + const tls_version_e version) +{ + set_protocol(tls_record_protocol_none); + set_version(version); + set_data_length(buffer_length); +} + +/// This function checks the header is valid. +eap_status_e tls_record_header_c::check_header() const +{ + if (get_protocol() > tls_record_protocol_application_data + || get_protocol() < tls_record_protocol_change_cipher_spec) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (get_version() != tls_version_3_1) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_record_message.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_record_message.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,650 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 137 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_tools.h" +#include "eap_array.h" +#include "tls_record_message.h" +#include "eap_automatic_variable.h" + + +/** @file */ + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_record_message_c::~tls_record_message_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_record_message_c::tls_record_message_c( + abs_eap_am_tools_c * const tools, + abs_tls_message_hash_c * const message_hash, + const bool is_client) +: m_am_tools(tools) +, m_message_hash(message_hash) +, m_protocol(tls_record_protocol_none) +, m_version(tls_version_illegal) +, m_length(0ul) +, m_tls_record_header_is_included(false) +, m_record_message_data(tools) +, m_analyse_index(0ul) +, m_parsed_record(false) +, m_cipher_suite_applied(false) +, m_handshake_messages(tools) +, m_change_cipher_spec_messages(tools) +, m_alert_messages(tools) +, m_application_data_messages(tools) +, m_is_client(is_client) +, m_is_valid(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_message_c::set_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_message_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t tls_record_message_c::get_analyse_index() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_analyse_index; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_message_c::save_analyse_index(const u32_t analyse_index) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_analyse_index = analyse_index; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_message_c::get_parsed_record() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_parsed_record; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_message_c::set_parsed_record() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_parsed_record = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_message_c::get_tls_record_header_is_included() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_tls_record_header_is_included; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_message_c::set_tls_record_header_is_included(const bool when_true_tls_record_header_is_included) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_tls_record_header_is_included = when_true_tls_record_header_is_included; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool tls_record_message_c::get_cipher_suite_applied() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_cipher_suite_applied; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void tls_record_message_c::set_cipher_suite_applied() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_cipher_suite_applied = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_message_c::set_protocol(tls_record_protocol_e protocol) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_protocol = protocol; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_message_c::set_version( + tls_version_e version) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_version = version; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_message_c::set_record_header_copy( + const tls_record_header_c * const tls_record_header) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_protocol = tls_record_header->get_protocol(); + m_version = tls_record_header->get_version(); + m_length = tls_record_header->get_data_length(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_message_c::set_record_message_data( + void * const data, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_record_message_data.set_buffer(data, data_length, false, true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_variable_data_c * tls_record_message_c::get_record_message_data() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return &m_record_message_data; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_record_protocol_e tls_record_message_c::get_protocol() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_protocol; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_version_e tls_record_message_c::get_version() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_version; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t tls_record_message_c::get_data_length() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_length; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_message_c::add_data_length(const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if ((m_length + data_length) > tls_handshake_header_c::get_max_data_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); + } + + m_length += data_length; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_message_c::add_handshake_message( + tls_handshake_message_c * const handshake_message, + const bool free_handshake_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools, handshake_message); + if (free_handshake_message == false) + { + automatic_tls_handshake_message.do_not_free_variable(); + } + + if (handshake_message == 0 + || handshake_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (get_protocol() != tls_record_protocol_handshake) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_protocol); + } + + // Note the m_handshake_messages will free handshake_message, in all cases if free_handshake_message == true. + automatic_tls_handshake_message.do_not_free_variable(); + + eap_status_e status = m_handshake_messages.add_object( + handshake_message, + free_handshake_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_message_c::add_change_cipher_spec_message( + tls_change_cipher_spec_message_c * const change_cipher_spec_message, + const bool free_change_cipher_spec_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools, change_cipher_spec_message); + if (free_change_cipher_spec_message == false) + { + automatic_tls_handshake_message.do_not_free_variable(); + } + + if (change_cipher_spec_message == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (get_protocol() != tls_record_protocol_change_cipher_spec) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_protocol); + } + + // Note the m_change_cipher_spec_messages will free handshake_message, in all cases if free_change_cipher_spec_message == true. + automatic_tls_handshake_message.do_not_free_variable(); + + eap_status_e status = m_change_cipher_spec_messages.add_object( + change_cipher_spec_message, + free_change_cipher_spec_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_message_c::add_alert_message( + tls_alert_message_c * const alert_message, + const bool free_alert_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools, alert_message); + if (free_alert_message == false) + { + automatic_tls_handshake_message.do_not_free_variable(); + } + + if (alert_message == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (get_protocol() != tls_record_protocol_alert) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_protocol); + } + + // Note the m_alert_messages will free handshake_message, in all cases if free_alert_message == true. + automatic_tls_handshake_message.do_not_free_variable(); + + eap_status_e status = m_alert_messages.add_object( + alert_message, + free_alert_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_message_c::add_application_data_message( + tls_application_data_message_c * const application_data_message, + const bool free_application_data_message) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_automatic_variable_c + automatic_tls_handshake_message(m_am_tools, application_data_message); + if (free_application_data_message == false) + { + automatic_tls_handshake_message.do_not_free_variable(); + } + + if (application_data_message == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (get_protocol() != tls_record_protocol_application_data) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_protocol); + } + + // Note the m_application_data_messages will free handshake_message, in all cases if free_application_data_message == true. + automatic_tls_handshake_message.do_not_free_variable(); + + eap_status_e status = m_application_data_messages.add_object( + application_data_message, + free_application_data_message); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e tls_record_message_c::add_message_data() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_not_supported; + + u32_t offset_of_tmp_tls_record_header = m_record_message_data.get_data_length(); + + EAP_UNREFERENCED_PARAMETER(offset_of_tmp_tls_record_header); // Not referenced without assert. + EAP_ASSERT(offset_of_tmp_tls_record_header == 0ul); + + + u32_t record_data_length_start = m_record_message_data.get_data_length(); + + + switch (get_protocol()) + { + case tls_record_protocol_change_cipher_spec: + { + u32_t ind; + for (ind = 0ul; ind < m_change_cipher_spec_messages.get_object_count(); ind++) + { + tls_change_cipher_spec_message_c * const tls_change_cipher_spec_message + = m_change_cipher_spec_messages.get_object(ind); + if (tls_change_cipher_spec_message == 0 + || tls_change_cipher_spec_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tls_change_cipher_spec_message->add_message_data(&m_record_message_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + break; + case tls_record_protocol_alert: + { + u32_t ind; + for (ind = 0ul; ind < m_alert_messages.get_object_count(); ind++) + { + tls_alert_message_c * const tls_alert_message + = m_alert_messages.get_object(ind); + if (tls_alert_message == 0 + || tls_alert_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tls_alert_message->add_message_data(&m_record_message_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + break; + case tls_record_protocol_handshake: + { + u32_t ind; + for (ind = 0ul; ind < m_handshake_messages.get_object_count(); ind++) + { + tls_handshake_message_c * const tls_handshake_message = m_handshake_messages.get_object(ind); + if (tls_handshake_message == 0 + || tls_handshake_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tls_handshake_message->add_message_data(&m_record_message_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + break; + case tls_record_protocol_application_data: + { + u32_t ind; + for (ind = 0ul; ind < m_application_data_messages.get_object_count(); ind++) + { + tls_application_data_message_c * const tls_application_data_message = m_application_data_messages.get_object(ind); + if (tls_application_data_message == 0 + || tls_application_data_message->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = tls_application_data_message->add_message_data(&m_record_message_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + break; + default: + break; + } // switch() + + + if (status == eap_status_ok) + { + u32_t record_data_length = m_record_message_data.get_data_length() - record_data_length_start; + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("record data length %d bytes.\n"), + record_data_length)); + + status = add_data_length(record_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t tls_record_message_c::get_handshake_count() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_handshake_messages.get_object_count(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t tls_record_message_c::get_change_cipher_spec_count() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_change_cipher_spec_messages.get_object_count(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t tls_record_message_c::get_alert_count() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_alert_messages.get_object_count(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t tls_record_message_c::get_application_data_count() const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_application_data_messages.get_object_count(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_handshake_message_c * tls_record_message_c::get_handshake( + const u32_t index) EAP_TEMPLATE_CONST +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_handshake_messages.get_object(index); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const tls_change_cipher_spec_message_c * tls_record_message_c::get_change_cipher_spec( + const u32_t index) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_change_cipher_spec_messages.get_object(index); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const tls_alert_message_c * tls_record_message_c::get_alert( + const u32_t index) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_alert_messages.get_object(index); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT tls_application_data_message_c * tls_record_message_c::get_application_data( + const u32_t index) const +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_application_data_messages.get_object(index); +} + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_tools/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_tools/makefile Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,17 @@ +#.EXPORT_ALL_VARIABLES: + +DLL_TARGET = do_dll + +LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_tls_tools + +SRC_FILES_CPP = \ + $(WLAN_COMMON)/type/tls_peap/tls/src/tls_peap_types.cpp \ + +SRC_FILES_C = + +LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \ + -lstdc++ + +include $(WLAN_LINUX)/base.mak + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/wpxstub/eapol_core_wpxm_stub.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/wpxstub/eapol_core_wpxm_stub.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 581 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eapol_core.h" +#include "eap_crypto_api.h" +#include "eapol_key_header.h" +#include "eapol_rc4_key_header.h" +#include "eap_state_notification.h" +#include "eap_automatic_variable.h" +#include "eap_network_id_selector.h" +#include "eap_config.h" +#include "eap_buffer.h" +#include "eapol_session_key.h" +#include "eap_master_session_key.h" + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::start_WPXM_reassociation( + const eap_am_network_id_c * const /* receive_network_id */, + const eapol_key_authentication_type_e /* authentication_type */, + eap_variable_data_c * const /* send_reassociation_request_ie */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::complete_WPXM_reassociation( + const eapol_wlan_authentication_state_e /* reassociation_result */, + const eap_am_network_id_c * const /* receive_network_id */, + const eapol_key_authentication_type_e /* authentication_type */, + const eap_variable_data_c * const /* received_reassociation_ie */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/wpxstub/eapol_key_state_common_wpxm_stub.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/wpxstub/eapol_key_state_common_wpxm_stub.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,113 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 583 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eapol_key_state.h" +#include "eapol_key_header.h" +#include "eap_crypto_api.h" +#include "abs_eap_am_mutex.h" +#include "eap_state_notification.h" +#include "eap_automatic_variable.h" +#include "eapol_rsna_key_data_gtk_header.h" +#include "abs_eapol_core.h" +#include "abs_eapol_key_state.h" +#include "eap_core_retransmission.h" +#include "eapol_rsna_key_data_payloads.h" +#include "eap_buffer.h" +#include "eapol_session_key.h" + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::set_WPXM_parameters( + const eap_am_network_id_c * const /* receive_network_id */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::start_WPXM_reassociation( + const eap_am_network_id_c * const /*receive_network_id*/, + const eapol_key_authentication_type_e /*authentication_type*/, + eap_variable_data_c * const /* send_reassociation_request_ie */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::complete_WPXM_reassociation( + const eapol_wlan_authentication_state_e /*reassociation_result*/, + const eap_am_network_id_c * const /*receive_network_id*/, + const eapol_key_authentication_type_e /*authentication_type*/, + const eap_variable_data_c * const /* received_reassociation_ie */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_WPXM() +{ + return false; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::derive_WPXM_WPXK1_WPXK2() +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_key_state_c::save_keys_for_test_use( + const eap_variable_data_c * const /* confirmation_KCK */, + const eap_variable_data_c * const /* encryption_KEK */, + const eap_variable_data_c * const /* temporal_TK */, + const u32_t /* WPXM_WPXC */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::derive_WPXM_PTK(const u32_t /* WPXM_WPXC */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/wpxstub/ethernet_core_wpxm_stub.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/wpxstub/ethernet_core_wpxm_stub.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 587 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_variable_data.h" +#include "eap_tools.h" +#include "ethernet_core.h" +#include "eapol_ethernet_header.h" +#include "eap_buffer.h" +#include "eapol_session_key.h" + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::start_WPXM_reassociation( + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + eap_variable_data_c * const send_reassociation_request_ie) +{ + eap_status_e status = m_eapol_core->start_WPXM_reassociation( + receive_network_id, + authentication_type, + send_reassociation_request_ie); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e ethernet_core_c::complete_WPXM_reassociation( + const eapol_wlan_authentication_state_e reassociation_result, + const eap_am_network_id_c * const receive_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const received_reassociation_ie) +{ + eap_status_e status = m_eapol_core->complete_WPXM_reassociation( + reassociation_result, + receive_network_id, + authentication_type, + received_reassociation_ie); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/common/DSS_random/dss_random_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/common/DSS_random/dss_random_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,242 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 142 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include + +#include "dss_random.h" + +#include "eap_am_assert.h" +#include "abs_eap_am_crypto.h" + +#include "eap_am_crypto_sha1.h" + +/** @file */ + +/** This is the block size in bytes. */ +const u32_t BLOCK_SIZE = 160/8; + +#if defined(EAP_DEBUG_TRACE_ACTIVE) + const u32_t DEBUG_BUFFER_SIZE = 64; +#endif //#if defined(EAP_DEBUG_TRACE_ACTIVE) + + +LOCAL_C void dss_pseudo_randomL(abs_eap_am_tools_c * const m_am_tools, u8_t *out, u32_t out_length, u8_t *xkey, u32_t xkey_length); + + +/** + * dss_random_G() implements the G() function using modified SHA-1. + * @code + * Copied from "Multiple Examples of DSA" http://csrc.nist.gov/encryption/dss/Examples-1024bit.pdf. + * Using the revised algorithm found in the Change Notice for the generation of x values: + * XKEY= bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6 + * XSEED= 00000000 00000000 00000000 00000000 00000000 + * The first loop through step 3.2 provides: + * XVAL= bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6 + * Using the routine in Appendix 3.3 Constructing The Function G From SHA-1 + * provides: + * w[0]= 2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614 + * The following value is the updated XKEY value from step 3.2.c: + * XKEY= dd734ee0 bd0bcd3b adbaeb27 dd1eaa59 76803ecb + * The second loop through step 3.2 provides: + * XVAL= dd734ee0 bd0bcd3b adbaeb27 dd1eaa59 76803ecb + * Using the routine in Appendix 3.3 Constructing The Function G From SHA-1 + * provides: + * w[1]= 3c6c18ba cb0f6c55 babb1378 8e20d737 a3275116 + * The following value is the updated XKEY value from step 3.2.c: + * XKEY= 19df679b 881b3991 6875fea0 6b3f8191 19a78fe2 + * Step 3.3 provides the following values: + * w[0] || w[1]= 2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614 + * 3c6c18ba cb0f6c55 babb1378 8e20d737 a3275116 + * X= 47c27eb6 16dba413 91e5165b e9c5e397 7e39a15d + * @endcode +*/ +void dss_random_G(abs_eap_am_tools_c * const m_am_tools, u8_t *out, u32_t out_length, const u8_t *c, u32_t c_length) +{ + u32_t *out_array = reinterpret_cast(out); + + eap_am_crypto_sha1_c sha1(m_am_tools); + u32_t output_length = out_length; + + eap_status_e status = sha1.eap_sha1_dss_G_function( + c, + c_length, + out_array, + &output_length + ); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("eap_sha1_dss_G_function(): status = %d"), + status)); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("dss_random_G(): out_array"), + out_array, sizeof(out_array)*5)); + +} + +/** + * dss_pseudo_random() implements pseudo random function for key generation of EAP/SIM. + * @code + * Random generator becomes as follows: + * Step 1. Choose a new, secret value for the seed-key, XKEY. + * Step 2. In hexadecimal notation let + * t = 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0. + * This is the initial value for H0 || H1 || H2 || H3 || H4 in the SHS. + * Step 3. For j = 0 to m - 1 do + * c. xj = G(t,XKEY). + * d. XKEY = (1 + XKEY + xj) mod 2^b. + * @endcode +*/ +eap_status_e dss_pseudo_random(abs_eap_am_tools_c * const m_am_tools, u8_t *out, u32_t out_length, u8_t *xkey, u32_t xkey_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_ok; + __UHEAP_MARK; + + TRAPD(err, dss_pseudo_randomL(m_am_tools, out, out_length, xkey, xkey_length)); + if (err != KErrNone) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + __UHEAP_MARKEND; + return status; +} + +LOCAL_C void dss_pseudo_randomL(abs_eap_am_tools_c * const m_am_tools, u8_t *out, u32_t out_length, u8_t *xkey, u32_t xkey_length) +{ + EAP_UNREFERENCED_PARAMETER(xkey_length); + + u32_t block_count = out_length/BLOCK_SIZE; + if ((out_length % BLOCK_SIZE) != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: dss_pseudo_random(): out buffer length 0x%08x not aligned to 0x%08x.\n"), + out_length, BLOCK_SIZE)); + + User::Leave(KErrArgument); + } + + TBuf8 tmp_out; + TBuf8 tmp_xkey; + + tmp_xkey.Append(xkey, BLOCK_SIZE); + +#if defined(EAP_DEBUG_TRACE_ACTIVE) + u8_t debug_buffer[DEBUG_BUFFER_SIZE]; +#endif //#if defined(EAP_DEBUG_TRACE_ACTIVE) + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("dss_pseudo_random(): xkey"), + xkey, xkey_length)); + + RInteger bn_xkey = RInteger::NewL(tmp_xkey); + CleanupStack::PushL(bn_xkey); + + RInteger bn_two = RInteger::NewL(2); + CleanupStack::PushL(bn_two); + + RInteger bn_160 = RInteger::NewL(160); + CleanupStack::PushL(bn_160); + + // Calculate 2^160 + RInteger bn_mod = bn_two.ExponentiateL(bn_160); + + CleanupStack::PopAndDestroy(&bn_160); + CleanupStack::PopAndDestroy(&bn_two); + + CleanupStack::PushL(bn_mod); + + for (u32_t ind = 0; ind < block_count; ind++) + { + dss_random_G(m_am_tools, &(out[ind*BLOCK_SIZE]), BLOCK_SIZE, tmp_xkey.Ptr(), BLOCK_SIZE); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("dss_pseudo_random(): xj = G(xkey)"), + &(out[ind*BLOCK_SIZE]), BLOCK_SIZE)); + + if (ind+1u >= block_count) + { + break; + } + + // Get the calculated block to be used + tmp_out.Copy(&(out[ind*BLOCK_SIZE]), BLOCK_SIZE); + + // This must be constructed inside the loop because the only way + // to assign descriptor values to CInteger seems to be by using NewLC. + RInteger bn_xj = RInteger::NewL(tmp_out); + CleanupStack::PushL(bn_xj); + + // Calculate bn_xkey = (XKEY + 1 + xj) mod 2^b + bn_xkey += 1; + bn_xkey += bn_xj; + bn_xkey %= bn_mod; + + // New tmp_xkey + tmp_xkey.Copy(bn_xkey.BufferLC()->Des()); + + CleanupStack::PopAndDestroy(); // bn_xkey buffer + CleanupStack::PopAndDestroy(&bn_xj); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + (EAPL("dss_pseudo_random(): xkey[%d] = (1 + xkey[%d] + x[%d]) % mod\n"), + ind+1u, + ind, + ind)); + + EAP_TRACE_FORMAT( + m_am_tools, + (debug_buffer, + sizeof(debug_buffer), + EAPL("xkey[%d]"), + ind+1u)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_EAP_AM_CRYPTO, + ((eap_format_string)debug_buffer, + tmp_xkey.Ptr(), + tmp_xkey.Length())); + + } // for() + + CleanupStack::PopAndDestroy(&bn_mod); + CleanupStack::PopAndDestroy(&bn_xkey); +} + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/common/file_io/symbian/eap_am_file_input_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/common/file_io/symbian/eap_am_file_input_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,677 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 143 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include + +#include "eap_am_file_input_symbian.h" + +//---------------------------------------------------------------------------------------------------- + +/** + * The destructor of the eap_am_file_input_symbian_c class does nothing special. + */ +EAP_FUNC_EXPORT eap_am_file_input_symbian_c::~eap_am_file_input_symbian_c() +{ + file_close(); + + delete m_input_buffer; + m_input_buffer = 0; +} + +//---------------------------------------------------------------------------------------------------- + +/** + * The constructor of the eap_am_file_input_symbian_c does nothing special. + */ +EAP_FUNC_EXPORT eap_am_file_input_symbian_c::eap_am_file_input_symbian_c( + abs_eap_am_tools_c * const tools) +: m_am_tools(tools) +, m_is_valid(false) +, m_input_buffer(0) +, m_input_buffer_offset(0ul) +{ + m_input_buffer = new TBuf8; + if (m_input_buffer == 0) + { + return; + } + + set_is_valid(); +} + +//---------------------------------------------------------------------------------------------------- + +/** + * This function checks the file of name file_name exists. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_file_input_symbian_c::file_exists(const eap_variable_data_c * const file_name) +{ + eap_am_file_input_symbian_c file(m_am_tools); + + eap_status_e status = file.file_open( + file_name, + eap_file_io_direction_read); + + if (status == eap_status_ok) + { + (void)file.file_close(); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//---------------------------------------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_file_input_symbian_c::file_delete( + const eap_variable_data_c * const /* file_name */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//---------------------------------------------------------------------------------------------------- + +/** + * This function copies the file source_file_name to file target_file_name. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_file_input_symbian_c::file_copy( + const eap_variable_data_c * const target_file_name, + const eap_variable_data_c * const source_file_name) +{ + eap_am_file_input_symbian_c read_file(m_am_tools); + + eap_status_e status = read_file.file_open( + source_file_name, + eap_file_io_direction_read); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: file_copy(): Cannot open source file %s\n"), + source_file_name->get_data(source_file_name->get_data_length()))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_am_file_input_symbian_c write_file(m_am_tools); + + status = write_file.file_open( + target_file_name, + eap_file_io_direction_write); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: file_copy(): Cannot open target file %s\n"), + target_file_name->get_data(target_file_name->get_data_length()))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_variable_data_c buffer(m_am_tools); + status = buffer.init(EAP_AM_FILE_INPUT_BUFFER_SIZE); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + bool end_of_file(false); + + while(end_of_file == false) + { + status = read_file.file_read(&buffer); + if (status == eap_status_end_of_file) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("file_copy(): End of file.\n"))); + end_of_file = true; + } + else if (status != eap_status_ok) + { + eap_status_string_c status_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: file_copy(): file_read(): status = %s\n"), + status_string.get_status_string(status))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("read data"), + buffer.get_data(), + buffer.get_data_length())); + + status = write_file.file_write(&buffer); + if (status != eap_status_ok) + { + eap_status_string_c status_string; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: file_copy(): file_write(): status = %s\n"), + status_string.get_status_string(status))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } // while() + + write_file.file_close(); + read_file.file_close(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("file_copy(): OK\n"))); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//---------------------------------------------------------------------------------------------------- + +/** + * This function returns size of a file. + */ +EAP_FUNC_EXPORT u32_t eap_am_file_input_symbian_c::file_size() +{ + TInt aSize(0ul); + + TInt size_status = m_File.Size(aSize); + + if (size_status != KErrNone) + { + return 0ul; + } + + return static_cast(aSize); +} + +//---------------------------------------------------------------------------------------------------- + +/** + * This function reads data from file. + * Maximum size read is the buffer size. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_file_input_symbian_c::file_read(eap_variable_data_c * const buffer) +{ + TPtr8 tmp(buffer->get_buffer(buffer->get_buffer_length()), buffer->get_buffer_length()); + + TInt ReadStatus = m_File.Read(tmp); + + if (ReadStatus != KErrNone + || tmp.Length() == 0UL + || tmp.Ptr() == 0) + { + buffer->set_data_length(0ul); + return EAP_STATUS_RETURN(m_am_tools, eap_status_end_of_file); + } + else + { + buffer->set_data_length(tmp.Length()); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } +} + +//---------------------------------------------------------------------------------------------------- + +/** + * This function write data to a file. + * Maximum size write is the buffer size. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_file_input_symbian_c::file_write(const eap_variable_data_c * const buffer) +{ + TPtr8 tmp(buffer->get_data(), buffer->get_data_length()); + + TInt WriteStatus = m_File.Write(tmp); + + if (WriteStatus != KErrNone) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_file_write_failed); + } + + WriteStatus = m_File.Flush(); + + if (WriteStatus != KErrNone) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_file_write_failed); + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//---------------------------------------------------------------------------------------------------- + +const u32_t EAP_MAX_FILENAME_LENGTH = 128; + +/** + * This function opens file of name file_name. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_file_input_symbian_c::file_open( + const eap_variable_data_c * const file_name, + const eap_file_io_direction_e dir) +{ + TBuf8 tmpFilename((TUint8 *)file_name->get_data(file_name->get_data_length())); + tmpFilename.SetLength(file_name->get_data_length()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Configure file"), + tmpFilename.PtrZ(), + tmpFilename.Length())); + + TBuf filename; + filename.Copy(tmpFilename); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Configure file"), + filename.PtrZ(), + filename.Size())); + + TInt result = m_file_session.Connect(); + if (result != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: configuration file %s not found, error %d\n"), + reinterpret_cast(file_name->get_data(file_name->get_data_length())), + result)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_file_does_not_exist); + } + + TUint aFileMode = EFileRead | EFileShareAny; + if (dir == eap_file_io_direction_write) + { + aFileMode = EFileWrite; + } + + TInt err = m_File.Open(m_file_session, filename, aFileMode); + if (err != KErrNone) + { + if (aFileMode == EFileWrite) + { + // Try create a new file. + err = m_File.Create(m_file_session, filename, aFileMode); + } + + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: configuration file %s not found, mode %d, error %d\n"), + reinterpret_cast(file_name->get_data(file_name->get_data_length())), + aFileMode, + err)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_file_does_not_exist); + } + } + + m_input_buffer_offset = 0ul; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//---------------------------------------------------------------------------------------------------- + +/** + * The function closes the file. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_file_input_symbian_c::file_close() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_File.Close(); + m_file_session.Close(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//---------------------------------------------------------------------------------------------------- + +/** + * This function reads n bytes from file to buffer. + */ +eap_status_e eap_am_file_input_symbian_c::file_read_buffer( + eap_variable_data_c * const buffer, + const u32_t required_bytes) +{ + u32_t read_bytes(0ul); + + eap_status_e status = buffer->set_data_length(0ul); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + bool file_end(false); + + while(file_end == false + && read_bytes < required_bytes) + { + if (m_input_buffer->Length() == m_input_buffer_offset) + { + TInt ReadStatus = m_File.Read(*m_input_buffer, EAP_AM_FILE_INPUT_BUFFER_SIZE); + if (ReadStatus != KErrNone + || m_input_buffer->Length() == 0UL + || m_input_buffer->Ptr() == 0) + { + file_end = true; + } + + m_input_buffer_offset = 0ul; + } + + const u8_t * const character = m_input_buffer->Ptr() + m_input_buffer_offset; + if (character == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_end_of_file); + } + + u32_t copied_bytes = required_bytes - read_bytes; + if (copied_bytes > (m_input_buffer->Length() - m_input_buffer_offset)) + { + copied_bytes = (m_input_buffer->Length() - m_input_buffer_offset); + } + + status = buffer->add_data(character, copied_bytes); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + read_bytes += copied_bytes; + m_input_buffer_offset += copied_bytes; + + } // while() + + if (file_end == true) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_end_of_file); + } + else + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } +} + +//---------------------------------------------------------------------------------------------------- + +/** + * This function reads line from file. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_file_input_symbian_c::file_read_line( + eap_variable_data_c * const line) +{ + if (line == 0 + || line->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + line->set_data_length(0ul); + + eap_variable_data_c buffer(m_am_tools); + + eap_status_e file_status(eap_status_ok); + + while (file_status == eap_status_ok) + { + file_status = file_read_buffer( + &buffer, + sizeof(u8_t)); + if (file_status != eap_status_ok + && file_status != eap_status_end_of_file) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, file_status); + } + + if (buffer.get_data_length() < sizeof(u8_t)) + { + file_status = EAP_STATUS_RETURN(m_am_tools, eap_status_end_of_file); + break; + } + + const u8_t * const character = buffer.get_data(sizeof(u8_t)); + + if (character == 0 + || *character == '\n') + { + // This is the end of the line. + break; + } + + if (*character != '\r') // Windows files inludes these. + { + eap_status_e status = line->add_data(character, sizeof(*character)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + } // while() + + { + eap_status_e add_status = line->add_end_null(); + if (add_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, add_status); + } + } + + // Note this should return the final file_status. + return EAP_STATUS_RETURN(m_am_tools, file_status); +} + +//---------------------------------------------------------------------------------------------------- + +/** + * This function reads word from file. + */ +eap_status_e eap_am_file_input_symbian_c::file_read_word(eap_variable_data_c * const word) +{ + if (word == 0 + || word->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + word->set_data_length(0ul); + + eap_variable_data_c buffer(m_am_tools); + + eap_status_e file_status(eap_status_ok); + + while (file_status == eap_status_ok) + { + file_status = file_read_buffer( + &buffer, + sizeof(u8_t)); + if (file_status != eap_status_ok + && file_status != eap_status_end_of_file) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, file_status); + } + + if (buffer.get_data_length() < sizeof(u8_t)) + { + file_status = EAP_STATUS_RETURN(m_am_tools, eap_status_end_of_file); + break; + } + + const u8_t * character = buffer.get_data(sizeof(u8_t)); + + if (character == 0 + || m_am_tools->isspace(*character) + || *character == ',') + { + break; + } + else if (*character == '#') + { + while (file_status == eap_status_ok) + { + file_status = file_read_buffer( + &buffer, + sizeof(u8_t)); + if (file_status != eap_status_ok + && file_status != eap_status_end_of_file) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, file_status); + } + + character = buffer.get_data(sizeof(u8_t)); + + if (character == 0 + || *character == '\n') + { + break; + } + } + } + else + { + eap_status_e status = word->add_data(character, sizeof(*character)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } // while() + + + { + eap_status_e add_status = word->add_end_null(); + if (add_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, add_status); + } + } + + + // Note this should return the final file_status. + return EAP_STATUS_RETURN(m_am_tools, file_status); +} + +//---------------------------------------------------------------------------------------------------- + +/** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ +void eap_am_file_input_symbian_c::set_is_valid() +{ + m_is_valid = true; +} + +//---------------------------------------------------------------------------------------------------- + +/** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ +bool eap_am_file_input_symbian_c::get_is_valid() +{ + return m_is_valid; +} + +//---------------------------------------------------------------------------------------------------- + +eap_status_e eap_am_file_input_symbian_c::directory_open( + const eap_variable_data_c * const /* directory_name */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//---------------------------------------------------------------------------------------------------- + +eap_status_e eap_am_file_input_symbian_c::directory_read( + eap_array_c * const /* directory_list */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//---------------------------------------------------------------------------------------------------- + +/** + * This function closes the directory. + */ +eap_status_e eap_am_file_input_symbian_c::directory_close() +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//---------------------------------------------------------------------------------------------------- + +abs_eap_am_file_input_c * abs_eap_am_file_input_c::new_abs_eap_am_file_input_c( + abs_eap_am_tools_c * const tools) +{ + abs_eap_am_file_input_c * const file_input = new eap_am_file_input_symbian_c(tools); + + if (file_input == 0 + || file_input->get_is_valid() == false) + { + delete file_input; + (void) EAP_STATUS_RETURN(tools, eap_status_allocation_error); + return 0; + } + + return file_input; +} + +//---------------------------------------------------------------------------------------------------- + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/common/symbian/dll_entry.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/common/symbian/dll_entry.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 144 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include + +#include "eap_am_export.h" + +// Check if this file is really needed. + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_async_wait_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_async_wait_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// INCLUDE FILES +#include +#include "eap_am_async_wait_symbian.h" + +// --------------------------------------------------------- +// eap_am_async_wait_symbian_c::eap_am_async_wait_symbian_c() +// --------------------------------------------------------- +// +eap_am_async_wait_symbian_c::eap_am_async_wait_symbian_c() : CActive(0) + { + CActiveScheduler::Add(this); + } + +// --------------------------------------------------------- +// eap_am_async_wait_symbian_c::~eap_am_async_wait_symbian_c() +// --------------------------------------------------------- +// +eap_am_async_wait_symbian_c::~eap_am_async_wait_symbian_c() + { + Cancel() ; + } + +// --------------------------------------------------------- +// eap_am_async_wait_symbian_c::Wait() +// --------------------------------------------------------- +// +void eap_am_async_wait_symbian_c::Wait() +{ + SetActive(); + iActiveWait.Start(); +} + +// --------------------------------------------------------- +// eap_am_async_wait_symbian_c::RunL() +// --------------------------------------------------------- +// +void eap_am_async_wait_symbian_c::RunL() +{ + iActiveWait.AsyncStop() ; +} + +// --------------------------------------------------------- +// eap_am_async_wait_symbian_c::DoCancel() +// --------------------------------------------------------- +// +void eap_am_async_wait_symbian_c::DoCancel() +{ + if( iStatus == KRequestPending ) + { + TRequestStatus * reqStat = &iStatus; + User::RequestComplete(reqStat, KErrCancel); + } +} + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_crypto_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_crypto_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3887 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 145 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDES +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "eap_am_crypto_symbian.h" +#include "eap_tools.h" +#include "eap_am_tools_symbian.h" +#include "dss_random.h" + +#include "eap_am_crypto_sha_256.h" +#include "eap_am_crypto_sha1.h" +#include "eap_am_crypto_rc4.h" +#include "eap_am_crypto_md4.h" + +#include "eap_am_memory.h" +#include "eap_am_assert.h" + +// LOCAL DATA +const u32_t BLOCK_SIZE_3DES_EDE = 8ul; +const u32_t MD5_BLOCK_SIZE = 64ul; +const u32_t AES_KEY_SIZE = 16ul; +const u32_t AES_BLOCK_SIZE = 16ul; + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_crypto_symbian_c::~eap_am_crypto_symbian_c() +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_crypto_symbian_c::eap_am_crypto_symbian_c(abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_is_valid(false) +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_crypto_symbian_c::get_is_valid() const +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::configure() +{ + return eap_status_ok; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::use_test_random( + const u8_t * const /* seed */, + const u32_t /* seed_length */, + const bool /* does_continuous_seeding_when_true */) +{ + // This does nothing yet. Later we may need test random generator. +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::add_rand_seed( + const u8_t * const /* bytes */, const u32_t /* length */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return eap_status_ok; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::add_rand_seed_hw_ticks() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + u64_t ticks = m_am_tools->get_hardware_ticks(); + u8_t entropy_bits = static_cast(ticks & 0xff); + add_rand_seed( + reinterpret_cast(&entropy_bits), + sizeof(entropy_bits)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return eap_status_ok; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::get_rand_bytes( + u8_t * const bytes, + const u32_t length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + TPtr8 target(bytes, length, length); + + TRandom::Random(target); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return eap_status_ok; +} + + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::generate_diffie_hellman_keys( + eap_variable_data_c * const own_private_dh_key, + eap_variable_data_c * const own_public_dh_key, + const u8_t * const prime, + const u32_t prime_length, + const u8_t * const group_generator, + const u32_t group_generator_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + eap_status_e status = eap_status_ok; + TRAPD(err, generate_diffie_hellman_keysL( + own_private_dh_key, + own_public_dh_key, + prime, + prime_length, + group_generator, + group_generator_length)); + if (err != KErrNone) + { + status = ((m_am_tools)->convert_am_error_to_eapol_error(err)); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_crypto_symbian_c::generate_diffie_hellman_keysL( + eap_variable_data_c * const own_private_dh_key, + eap_variable_data_c * const own_public_dh_key, + const u8_t * const prime, + const u32_t prime_length, + const u8_t * const group_generator, + const u32_t group_generator_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + eap_status_e status; + + TPtrC8 _prime(prime, prime_length); + TPtrC8 _generator(group_generator, group_generator_length); + + RInteger N = RInteger::NewL(_prime); + CleanupStack::PushL(N); + + RInteger G = RInteger::NewL(_generator); + CleanupStack::PushL(G); + + CDHKeyPair* dh_key = CDHKeyPair::NewL(N, G); + CleanupStack::Pop(&G); // N, G + CleanupStack::Pop(&N); // N, G + + CleanupStack::PushL(dh_key); + + const CDHPublicKey& publicKey = dh_key->PublicKey(); + + const TInteger& X = publicKey.X(); + + HBufC8* p = X.BufferLC(); + // Copy the public key + status = own_public_dh_key->set_copy_of_buffer(p->Des().Ptr(), p->Length()); + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + CleanupStack::PopAndDestroy(p); + + + const CDHPrivateKey& privateKey = dh_key->PrivateKey(); + + const TInteger& x = privateKey.x(); + + p = x.BufferLC(); + // Copy the private key + status = own_private_dh_key->set_copy_of_buffer(p->Des().Ptr(), p->Length()); + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + CleanupStack::PopAndDestroy(p); + + CleanupStack::PopAndDestroy(dh_key); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("own_public_dh_key"), + own_public_dh_key->get_data(own_public_dh_key->get_data_length()), + own_public_dh_key->get_data_length())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("own_private_dh_key is hidden in Symbian.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::generate_g_power_to_xy( + const eap_variable_data_c * const own_private_dh_key, + const eap_variable_data_c * const peer_public_dh_key, + eap_variable_data_c * const shared_dh_key, + const u8_t * const prime, + const u32_t prime_length, + const u8_t * const group_generator, + const u32_t group_generator_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + eap_status_e status = eap_status_ok; + TRAPD(err, generate_g_power_to_xyL( + own_private_dh_key, + peer_public_dh_key, + shared_dh_key, + prime, + prime_length, + group_generator, + group_generator_length)); + if (err != KErrNone) + { + status = ((m_am_tools)->convert_am_error_to_eapol_error(err)); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_crypto_symbian_c::generate_g_power_to_xyL( + const eap_variable_data_c * const own_private_dh_key, + const eap_variable_data_c * const peer_public_dh_key, + eap_variable_data_c * const shared_dh_key, + const u8_t * const prime, + const u32_t prime_length, + const u8_t * const group_generator, + const u32_t group_generator_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + eap_status_e status(eap_status_ok); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("peer_public_dh_key"), + peer_public_dh_key->get_data(peer_public_dh_key->get_data_length()), + peer_public_dh_key->get_data_length())); + + + // PUBLIC KEY + TPtrC8 peer_key( + peer_public_dh_key->get_data(peer_public_dh_key->get_data_length()), + peer_public_dh_key->get_data_length()); + if (peer_key.Ptr() == 0) + { + User::Leave(KErrArgument); + } + + RInteger Y = RInteger::NewL(peer_key); + CleanupStack::PushL(Y); + + + TPtrC8 peer_prime( + prime, + prime_length); + if (peer_prime.Ptr() == 0) + { + User::Leave(KErrArgument); + } + + RInteger N = RInteger::NewL(peer_prime); + CleanupStack::PushL(N); + + TPtrC8 peer_generator( + group_generator, + group_generator_length); + if (peer_prime.Ptr() == 0) + { + User::Leave(KErrArgument); + } + + RInteger G = RInteger::NewL(peer_generator); + CleanupStack::PushL(G); + + CDHPublicKey* publicKey = CDHPublicKey::NewL(N, G, Y); + CleanupStack::Pop(&G); // The parameters are freed by CDHPublicKey + CleanupStack::Pop(&N); // The parameters are freed by CDHPublicKey + CleanupStack::Pop(&Y); // The parameters are freed by CDHPublicKey + CleanupStack::PushL(publicKey); + + // PRIVATE KEY + RInteger Npriv = RInteger::NewL(peer_prime); + CleanupStack::PushL(Npriv); + + RInteger Gpriv = RInteger::NewL(peer_generator); // ! + CleanupStack::PushL(Gpriv); + + TPtrC8 private_key( + own_private_dh_key->get_data(own_private_dh_key->get_data_length()), + own_private_dh_key->get_data_length()); + if (private_key.Ptr() == 0) + { + User::Leave(KErrArgument); + } + RInteger x = RInteger::NewL(private_key); + CleanupStack::PushL(x); + + CDHPrivateKey* privateKey = CDHPrivateKey::NewL(Npriv, Gpriv, x); + CleanupStack::Pop(&x); + CleanupStack::Pop(&Gpriv); + CleanupStack::Pop(&Npriv); + CleanupStack::PushL(privateKey); + + CDH* dh = CDH::NewL(*privateKey); + CleanupStack::PushL(dh); + + // Have to do const_cast so that the object can be pushed... strange... + HBufC8* p = const_cast(dh->AgreeL(*publicKey)); + CleanupStack::PushL(p); + + // Copy the shared key + status = shared_dh_key->set_copy_of_buffer(const_cast(p)->Des().Ptr(), p->Length()); + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + + CleanupStack::PopAndDestroy(p); // p, dh, publicKey, privateKey + CleanupStack::PopAndDestroy(dh); // p, dh, publicKey, privateKey + CleanupStack::PopAndDestroy(privateKey); // p, dh, publicKey, privateKey + CleanupStack::PopAndDestroy(publicKey); // p, dh, publicKey, privateKey + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL(" shared_dh_key"), + shared_dh_key->get_data(shared_dh_key->get_data_length()), + shared_dh_key->get_data_length())); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dh_cleanup( + const eap_variable_data_c * const /*dh_context*/) +{ + return eap_status_ok; +} + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha_256_digest_length( + eap_variable_data_c * const sha_256_context) +{ + eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast( + sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const))); + if (sha_256 == 0 + || sha_256->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + return sha_256->get_digest_length(); +} + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha_256_block_size( + eap_variable_data_c * const sha_256_context) +{ + eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast( + sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const))); + if (sha_256 == 0 + || sha_256->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + return sha_256->get_block_size(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_init( + eap_variable_data_c * const sha_256_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + eap_am_crypto_sha_256_c * sha_256 = 0; + + if (sha_256_context->get_is_valid_data() == true) + { + sha_256 = reinterpret_cast( + sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const))); + if (sha_256 == 0 + || sha_256->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + } + } + + eap_status_e status = eap_status_process_general_error; + + if (sha_256 == 0) + { + sha_256 = new eap_am_crypto_sha_256_c(m_am_tools); + if (sha_256 == 0 + || sha_256->get_is_valid() == false) + { + delete sha_256; + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = sha_256_context->set_buffer(sha_256, sizeof(sha_256), false, true); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = sha_256->hash_init(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_update( + eap_variable_data_c * const sha_256_context, + const u8_t * const data, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(sha_256_context->get_is_valid_data() == true); + + eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast( + sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const))); + if (sha_256 == 0 + || sha_256->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = sha_256->hash_update( + data, + data_length); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eap_am_crypto_symbian_c::sha_256_update(), failed status = %d\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_final( + eap_variable_data_c * const sha_256_context, + u8_t * const message_digest, + u32_t *md_length_or_null) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(sha_256_context->get_is_valid_data() == true); + + eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast( + sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const))); + if (sha_256 == 0 + || sha_256->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = sha_256->hash_final( + message_digest, + md_length_or_null); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eap_am_crypto_symbian_c::sha_256_final(), failed status = %d\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_cleanup( + eap_variable_data_c * const sha_256_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(sha_256_context->get_is_valid_data() == true); + + eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast( + sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const))); + if (sha_256 == 0 + || sha_256->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + } + + delete sha_256; + + sha_256_context->reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_copy_context( + eap_variable_data_c * const copied_sha_256_context, + const eap_variable_data_c * const original_sha_256_context) +{ + eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast( + original_sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const))); + if (sha_256 == 0 + || sha_256->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_sha_256_c * const sha_256_copy = sha_256->copy(); + if (sha_256_copy == 0 + || sha_256_copy->get_is_valid() == false) + { + delete sha_256_copy; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = copied_sha_256_context->set_buffer(sha_256_copy, sizeof(sha_256_copy), false, true); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha1_digest_length( + eap_variable_data_c * const sha1_context) +{ + eap_am_crypto_sha1_c * const sha1 = reinterpret_cast( + sha1_context->get_data(sizeof(eap_am_crypto_sha1_c))); + + if (sha1 == 0 + || sha1->get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + return sha1->get_digest_length(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha1_block_size( + eap_variable_data_c * const sha1_context) +{ + eap_am_crypto_sha1_c * const sha1 = reinterpret_cast( + sha1_context->get_data(sizeof(eap_am_crypto_sha1_c))); + + if (sha1 == 0 + || sha1->get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + return sha1->get_block_size(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_init( + eap_variable_data_c * const sha1_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + eap_status_e status = eap_status_process_general_error; + + eap_am_crypto_sha1_c * sha1 = 0; + + if (sha1_context->get_is_valid_data() == true) + { + sha1 = reinterpret_cast( + sha1_context->get_data(sizeof(eap_am_crypto_sha1_c))); + + if (sha1 != 0 + && sha1->get_is_valid() == false) + { + // Delete old invalid context. + status = sha1_cleanup(sha1_context); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Next we allocate new context. + sha1 = 0; + } + + } + else + { + // There are no context. + // We will allocate a new one. + } + + if (sha1 == 0) + { + sha1 = new eap_am_crypto_sha1_c(m_am_tools); + if (sha1 == 0 + || sha1->get_is_valid() == false) + { + delete sha1; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = sha1_context->set_buffer(sha1, sizeof(*sha1), false, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = sha1->hash_init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_update( + eap_variable_data_c * const sha1_context, + const u8_t * const data, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + eap_am_crypto_sha1_c * const sha1 = reinterpret_cast( + sha1_context->get_data(sizeof(eap_am_crypto_sha1_c))); + + if (sha1 == 0 + || sha1->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = sha1->hash_update( + data, + data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_final( + eap_variable_data_c * const sha1_context, + u8_t * const message_digest, + u32_t *md_length_or_null) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + eap_am_crypto_sha1_c * const sha1 = reinterpret_cast( + sha1_context->get_data(sizeof(eap_am_crypto_sha1_c))); + + if (sha1 == 0 + || sha1->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = sha1->hash_final( + message_digest, + md_length_or_null); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_cleanup( + eap_variable_data_c * const sha1_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(sha1_context != 0); + EAP_ASSERT(sha1_context->get_is_valid() == true); + if (sha1_context == 0 + || sha1_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_sha1_c * const sha1 = reinterpret_cast( + sha1_context->get_data(sizeof(eap_am_crypto_sha1_c))); + + delete sha1; + + sha1_context->reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_copy_context( + eap_variable_data_c * const copied_sha1_context, + const eap_variable_data_c * const original_sha1_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + eap_am_crypto_sha1_c * const sha1 = reinterpret_cast( + original_sha1_context->get_data(sizeof(eap_am_crypto_sha1_c))); + + if (sha1 == 0 + || sha1->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_sha1_c * const sha1_copy = sha1->copy(); + + if (sha1_copy == 0 + || sha1_copy->get_is_valid() == false) + { + delete sha1_copy; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = copied_sha1_context->set_buffer(sha1_copy, sizeof(*sha1_copy), false, true); + + if (status != eap_status_ok) + { + delete sha1_copy; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::aes_key_length() +{ + return AES_KEY_SIZE; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::aes_block_size() +{ + return AES_BLOCK_SIZE; +} + + +//-------------------------------------------------- + +// NOTE ::dss_pseudo_random is implemented in am/common/DSS_random/dss_random.cpp. +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dss_pseudo_random( + u8_t *out, + u32_t out_length, + u8_t *xkey, + u32_t xkey_length) +{ + eap_status_e status = ::dss_pseudo_random(m_am_tools, out, out_length, xkey, xkey_length); + return status; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::open_crypto_memory_leaks() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::close_crypto_memory_leaks() +{ +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_set_key(eap_variable_data_c * const rc4_context, + const eap_variable_data_c * const key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + if (key == 0 + || key->get_is_valid_data() == false + || key->get_data_length() == 0 + || rc4_context == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_rc4_c * const rc4 = new eap_am_crypto_rc4_c(m_am_tools); + if (rc4 == 0 + || rc4->get_is_valid() == false) + { + delete rc4; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = rc4->set_key(key); + if (status != eap_status_ok) + { + delete rc4; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (rc4_context->get_is_valid_data() == true) + { + status = rc4_cleanup(rc4_context); + if (status != eap_status_ok) + { + delete rc4; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = rc4_context->set_buffer(rc4, sizeof(*rc4), false, true); + if (status != eap_status_ok) + { + delete rc4; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_cleanup( + eap_variable_data_c * const rc4_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(rc4_context != 0); + EAP_ASSERT(rc4_context->get_is_valid() == true); + if (rc4_context == 0 + || rc4_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_rc4_c * const rc4 = reinterpret_cast( + rc4_context->get_data(sizeof(eap_am_crypto_rc4_c))); + + delete rc4; + + rc4_context->reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_encrypt( + const eap_variable_data_c * const rc4_context, + void * const data_in_out, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(rc4_context != 0); + EAP_ASSERT(rc4_context->get_is_valid() == true); + if (rc4_context == 0 + || rc4_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_rc4_c * const rc4 = reinterpret_cast( + rc4_context->get_data(sizeof(eap_am_crypto_rc4_c))); + + if (rc4 == 0 + || rc4->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + eap_status_e status = rc4->encrypt_data( + data_in_out, + data_in_out, + data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_encrypt( + const eap_variable_data_c * const rc4_context, + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(rc4_context != 0); + EAP_ASSERT(rc4_context->get_is_valid() == true); + if (rc4_context == 0 + || rc4_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_rc4_c * const rc4 = reinterpret_cast( + rc4_context->get_data(sizeof(eap_am_crypto_rc4_c))); + + if (rc4 == 0 + || rc4->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + eap_status_e status = rc4->encrypt_data( + data_in, + data_out, + data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_decrypt( + const eap_variable_data_c * const rc4_context, + void * const data_in_out, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(rc4_context != 0); + EAP_ASSERT(rc4_context->get_is_valid() == true); + if (rc4_context == 0 + || rc4_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_rc4_c * const rc4 = reinterpret_cast( + rc4_context->get_data(sizeof(eap_am_crypto_rc4_c))); + + if (rc4 == 0 + || rc4->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + eap_status_e status = rc4->decrypt_data( + data_in_out, + data_in_out, + data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_decrypt( + const eap_variable_data_c * const rc4_context, + const void * const data_in, + void * const data_out, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(rc4_context != 0); + EAP_ASSERT(rc4_context->get_is_valid() == true); + if (rc4_context == 0 + || rc4_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_rc4_c * const rc4 = reinterpret_cast( + rc4_context->get_data(sizeof(eap_am_crypto_rc4_c))); + + if (rc4 == 0 + || rc4->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + eap_status_e status = rc4->decrypt_data( + data_in, + data_out, + data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_init( + eap_variable_data_c * const rsa_context) +{ + EAP_UNREFERENCED_PARAMETER(rsa_context); + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + eap_status_e status = rsa_context->init(0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + rsa_context->set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_encrypt_with_public_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_key(), begins.\n"))); + + eap_status_e status = eap_status_ok; + + TRAPD(err, rsa_encrypt_with_public_keyL( + rsa_context, + public_rsa_key, + input_data, + output_data)); + if (err != KErrNone) + { + status = ((m_am_tools)->convert_am_error_to_eapol_error(err)); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_key() failed, status %d.\n"), + status)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +void eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL( + eap_variable_data_c * const /*rsa_context*/, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), begins.\n"))); + + TPtrC8 ptr( + public_rsa_key->get_data(public_rsa_key->get_data_length()), + public_rsa_key->get_data_length()); + if (ptr.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, public_rsa_key is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + // The public_rsa_key is ASN.1 encoded. + // SEQUENCE { + // INTEGER modulus + // INTEGER exponent + // } + // + // + TASN1DecSequence seq; + TASN1DecInteger asn1; + TASN1DecGeneric* gen; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before DecodeDERLC().\n"))); + + CArrayPtrFlat* arrayPtr; + TInt pos(0); + arrayPtr = seq.DecodeDERLC(ptr, pos); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(0); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 m = gen->Encoding(); + if (m.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + RInteger modulus = asn1.DecodeDERLongL(m, pos); + CleanupStack::PushL(modulus); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(1); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 e = gen->Encoding(); + if (e.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + RInteger exponent = asn1.DecodeDERLongL(e, pos); + CleanupStack::PushL(exponent); + + TPtrC8 input( + input_data->get_data(input_data->get_data_length()), + input_data->get_data_length()); + if (input.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, input_data is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + // The length of the ciphertext in RSA is the next multiple of block size. + TUint output_data_length = ((input_data->get_data_length() / modulus.ByteCount()) + 1) * modulus.ByteCount(); + eap_status_e status = output_data->init(output_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, output_data is invalid, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrNoMemory); + } + + output_data->set_is_valid(); + output_data->set_data_length(output_data_length); + TPtr8 output( + output_data->get_data(output_data->get_data_length()), + output_data->get_data_length()); + if (output.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, output_data is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + CRSAPublicKey* public_key = CRSAPublicKey::NewL(modulus, exponent); + CleanupStack::Pop(&exponent); // Exponent, modulus are freed by CRSAPublicKey + CleanupStack::Pop(&modulus); // Exponent, modulus are freed by CRSAPublicKey + CleanupStack::PushL(public_key); + + CRSAPKCS1v15Encryptor* rsa_encryptor = CRSAPKCS1v15Encryptor::NewL(*public_key); + CleanupStack::PushL(rsa_encryptor); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before EncryptL().\n"))); + + rsa_encryptor->EncryptL(input, output); + + output_data->set_data_length(output.Length()); + + CleanupStack::PopAndDestroy(rsa_encryptor); + CleanupStack::PopAndDestroy(public_key); + CleanupStack::PopAndDestroy(arrayPtr); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), OK.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_decrypt_with_public_key( + eap_variable_data_c * const /*rsa_context*/, + const eap_variable_data_c * const /*public_rsa_key*/, + const eap_variable_data_c * const /*input_data*/, + eap_variable_data_c * const /*output_data*/) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_key(), begins.\n"))); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +void eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL( + eap_variable_data_c * const /*rsa_context*/, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), begins.\n"))); + + TPtrC8 ptr( + public_rsa_key->get_data(public_rsa_key->get_data_length()), + public_rsa_key->get_data_length()); + if (ptr.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, public_rsa_key is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + // The public_rsa_key is ASN.1 encoded. + // SEQUENCE { + // INTEGER modulus + // INTEGER exponent + // } + // + // + TASN1DecSequence seq; + TASN1DecInteger asn1; + TASN1DecGeneric* gen; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecodeDERLC().\n"))); + + CArrayPtrFlat* arrayPtr; + TInt pos(0); + arrayPtr = seq.DecodeDERLC(ptr, pos); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(0); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 m = gen->Encoding(); + if (m.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + RInteger modulus = asn1.DecodeDERLongL(m, pos); + CleanupStack::PushL(modulus); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(1); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 e = gen->Encoding(); + if (e.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + RInteger exponent = asn1.DecodeDERLongL(e, pos); + CleanupStack::PushL(exponent); + + TPtrC8 input( + input_data->get_data(input_data->get_data_length()), + input_data->get_data_length()); + if (input.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, input_data is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + // The length of the plaintext is equal or less than the ciphertext length. + TUint output_data_length = input_data->get_data_length(); + eap_status_e status = output_data->init(output_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, output_data is invalid, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrNoMemory); + } + output_data->set_is_valid(); + output_data->set_data_length(output_data_length); + + TPtr8 output( + output_data->get_data(output_data->get_data_length()), + output_data->get_data_length()); + if (output.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, output_data is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + // The key is actually public key but the class still needs to be CRSAPrivateKey for decryption + CleanupStack::Pop(&exponent); // Next class frees the integers + CleanupStack::Pop(&modulus); // Next class frees the integers + + CRSAPrivateKeyStandard* public_key = CRSAPrivateKeyStandard::NewL(modulus, exponent); + CleanupStack::PushL(public_key); + + CRSAPKCS1v15Decryptor* rsa_decryptor = CRSAPKCS1v15Decryptor::NewL(*public_key); + CleanupStack::PushL(rsa_decryptor); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecryptL().\n"))); + + rsa_decryptor->DecryptL(input, output); + + // Set the real data length + output_data->set_data_length(output.Length()); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), OK.\n"))); + + CleanupStack::PopAndDestroy(rsa_decryptor); + CleanupStack::PopAndDestroy(public_key); + CleanupStack::PopAndDestroy(arrayPtr); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); +} + +//-------------------------------------------------- +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_encrypt_with_private_key( + eap_variable_data_c * const /*rsa_context*/, + const eap_variable_data_c * const /*private_rsa_key*/, + const eap_variable_data_c * const /*input_data*/, + eap_variable_data_c * const /*output_data*/) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_key(), begins.\n"))); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + + +void eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL( + eap_variable_data_c * const /*rsa_context*/, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), begins.\n"))); + + TPtrC8 ptr( + private_rsa_key->get_data(private_rsa_key->get_data_length()), + private_rsa_key->get_data_length()); + if (ptr.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, private_rsa_key is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + // The private_rsa_key is ASN.1 encoded. + // SEQUENCE { + // INTEGER modulus + // INTEGER public_exponent + // INTEGER private_exponent + // ... + // } + // + // + TASN1DecSequence seq; + TASN1DecInteger asn1; + TASN1DecGeneric* gen; + + RInteger modulus; + RInteger private_exponent; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before DecodeDERLC().\n"))); + + CArrayPtrFlat* arrayPtr; + TInt pos(0); + arrayPtr = seq.DecodeDERLC(ptr, pos); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(1); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 m = gen->Encoding(); + if (m.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + modulus = asn1.DecodeDERLongL(m, pos); + CleanupStack::PushL(modulus); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(3); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 priv_e = gen->Encoding(); + if (priv_e.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + private_exponent = asn1.DecodeDERLongL(priv_e, pos); + CleanupStack::PushL(private_exponent); + + TPtrC8 input( + input_data->get_data(input_data->get_data_length()), + input_data->get_data_length()); + if (input.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, input_data is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + // The length of the ciphertext in RSA is the next multiple of block size. + TUint output_data_length = ((input_data->get_data_length() / modulus.ByteCount()) + 1) * modulus.ByteCount(); + eap_status_e status = output_data->init(output_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, output_data is invalid, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrNoMemory); + } + output_data->set_is_valid(); + output_data->set_data_length(output_data_length); + + TPtr8 output( + output_data->get_data(output_data->get_data_length()), + output_data->get_data_length()); + if (output.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, output_data is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + CleanupStack::Pop(&private_exponent); // private exponent & modulus are freed by the next class + CleanupStack::Pop(&modulus); // private exponent & modulus are freed by the next class + CRSAPublicKey* private_key = CRSAPublicKey::NewL(modulus, private_exponent); + CleanupStack::PushL(private_key); + + CRSAPKCS1v15Encryptor* rsa_encryptor = CRSAPKCS1v15Encryptor::NewL(*private_key); + CleanupStack::PushL(rsa_encryptor); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before EncryptL().\n"))); + + rsa_encryptor->EncryptL(input, output); + + output_data->set_data_length(output.Length()); + + CleanupStack::PopAndDestroy(rsa_encryptor); + CleanupStack::PopAndDestroy(private_key); + CleanupStack::PopAndDestroy(arrayPtr); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), OK.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); +} + +//-------------------------------------------------- +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_decrypt_with_private_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_key(), begins.\n"))); + + eap_status_e status = eap_status_ok; + TRAPD(err, rsa_decrypt_with_private_keyL( + rsa_context, + private_rsa_key, + input_data, + output_data)); + if (err != KErrNone) + { + status = ((m_am_tools)->convert_am_error_to_eapol_error(err)); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_key() failed, err %d, status %d.\n"), + err, + status)); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +void eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL( + eap_variable_data_c * const /*rsa_context*/, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), begins.\n"))); + + TPtrC8 ptr( + private_rsa_key->get_data(private_rsa_key->get_data_length()), + private_rsa_key->get_data_length()); + if (ptr.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, private_rsa_key is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + // The private_rsa_key is ASN.1 encoded. + // SEQUENCE { + // INTEGER modulus + // INTEGER public_exponent + // INTEGER private_exponent + // ... + // } + // + // + TASN1DecSequence seq; + TASN1DecInteger asn1; + TASN1DecGeneric* gen; + RInteger modulus; + RInteger private_exponent; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecodeDERLC().\n"))); + + CArrayPtrFlat* arrayPtr; + TInt pos(0); + arrayPtr = seq.DecodeDERLC(ptr, pos); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(1); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 m = gen->Encoding(); + if (m.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + modulus = asn1.DecodeDERLongL(m, pos); + CleanupStack::PushL(modulus); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(3); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 priv_e = gen->Encoding(); + if (priv_e.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + private_exponent = asn1.DecodeDERLongL(priv_e, pos); + CleanupStack::PushL(private_exponent); + + TPtrC8 input( + input_data->get_data(input_data->get_data_length()), + input_data->get_data_length()); + if (input.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, input_data is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + // The length of the plaintext is equal or less than the ciphertext length. + TUint output_data_length = input_data->get_data_length(); + eap_status_e status = output_data->init(output_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, output_data is invalid, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrNoMemory); + } + output_data->set_is_valid(); + output_data->set_data_length(output_data_length); + + TPtr8 output( + output_data->get_data(output_data->get_data_length()), + output_data->get_data_length()); + if (output.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, output_data is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + CRSAPrivateKey* private_key = CRSAPrivateKeyStandard::NewL(modulus, private_exponent); + + CleanupStack::Pop(&private_exponent); // modulus & private_exponent are freed CRSAPrivateKey + CleanupStack::Pop(&modulus); // modulus & private_exponent are freed CRSAPrivateKey + CleanupStack::PushL(private_key); + + CRSAPKCS1v15Decryptor* rsa_decryptor = CRSAPKCS1v15Decryptor::NewL(*private_key); + CleanupStack::PushL(rsa_decryptor); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecryptL().\n"))); + + rsa_decryptor->DecryptL(input, output); + + // Now set the correct length + output_data->set_data_length(output.Length()); + + CleanupStack::PopAndDestroy(rsa_decryptor); + CleanupStack::PopAndDestroy(private_key); + CleanupStack::PopAndDestroy(arrayPtr); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), OK.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); +} + +//-------------------------------------------------- +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_sign( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_sign(), begins.\n"))); + + eap_status_e status = eap_status_ok; + + TRAPD(err, rsa_signL( + rsa_context, + private_rsa_key, + hash, + signed_hash)); + if (err != KErrNone) + { + status = ((m_am_tools)->convert_am_error_to_eapol_error(err)); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_sign() failed, err %d, status %d.\n"), + err, + status)); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +eap_status_e eap_am_crypto_symbian_c::rsa_signL( + eap_variable_data_c * const /*rsa_context*/, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_signL(), begins.\n"))); + + TPtrC8 ptr( + private_rsa_key->get_data(private_rsa_key->get_data_length()), + private_rsa_key->get_data_length()); + if (ptr.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, private_rsa_key is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + // The private_rsa_key is ASN.1 encoded. + // SEQUENCE { + // INTEGER modulus + // INTEGER public_exponent + // INTEGER private_exponent + // ... + // } + // + // + TASN1DecSequence seq; + TASN1DecInteger asn1; + TASN1DecGeneric* gen; + + RInteger modulus; + RInteger private_exponent; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_signL(), before DecodeDERLC().\n"))); + + CArrayPtrFlat* arrayPtr; + TInt pos(0); + arrayPtr = seq.DecodeDERLC(ptr, pos); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_signL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(1); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 m = gen->Encoding(); + if (m.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + pos = 0; + modulus = asn1.DecodeDERLongL(m, pos); + CleanupStack::PushL(modulus); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_signL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(3); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 priv_e = gen->Encoding(); + if (priv_e.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + private_exponent = asn1.DecodeDERLongL(priv_e, pos); + CleanupStack::PushL(private_exponent); + + TPtrC8 input( + hash->get_data(hash->get_data_length()), + hash->get_data_length()); + if (input.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, hash is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + // The length of the ciphertext in RSA is the next multiple of block size. + TUint output_data_length = ((hash->get_data_length() / modulus.ByteCount()) + 1) * modulus.ByteCount(); + + eap_status_e status = signed_hash->init(output_data_length); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, signed_hash is invalid, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrNoMemory); + } + signed_hash->set_is_valid(); + signed_hash->set_data_length(output_data_length); + + TPtr8 output( + signed_hash->get_data(signed_hash->get_data_length()), + signed_hash->get_data_length()); + if (output.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, signed_hash is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + CleanupStack::Pop(&private_exponent); // private exponent & modulus are freed by the next class + CleanupStack::Pop(&modulus); // private exponent & modulus are freed by the next class + CRSAPrivateKeyStandard* private_key = CRSAPrivateKeyStandard::NewL(modulus, private_exponent); + CleanupStack::PushL(private_key); + + CRSAPKCS1v15Signer* rsa_signer = CRSAPKCS1v15Signer::NewL(*private_key); + CleanupStack::PushL(rsa_signer); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_signL(), before SignL().\n"))); + + const CRSASignature* signature = rsa_signer->SignL(input); + const TInteger& sig = signature->S(); + + HBufC8* buf = sig.BufferLC(); + + output.Copy(*buf); + signed_hash->set_data_length(output.Length()); + + CleanupStack::PopAndDestroy(buf); + CleanupStack::PopAndDestroy(rsa_signer); + CleanupStack::PopAndDestroy(private_key); + CleanupStack::PopAndDestroy(arrayPtr); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_signL(), OK.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return eap_status_ok; +} +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_verify( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_verify(), begins.\n"))); + + eap_status_e status = eap_status_ok; + + TRAPD(err, rsa_verifyL( + rsa_context, + public_rsa_key, + hash, + signed_hash)); + if (err != KErrNone) + { + status = ((m_am_tools)->convert_am_error_to_eapol_error(err)); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_verify() failed, err %d, status %d.\n"), + err, + status)); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +eap_status_e eap_am_crypto_symbian_c::rsa_verifyL( + eap_variable_data_c * const /*rsa_context*/, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + TPtrC8 ptr( + public_rsa_key->get_data(public_rsa_key->get_data_length()), + public_rsa_key->get_data_length()); + if (ptr.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, public_rsa_key is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + // The public_rsa_key is ASN.1 encoded. + // SEQUENCE { + // INTEGER modulus + // INTEGER exponent + // } + // + // + TASN1DecSequence seq; + TASN1DecInteger asn1; + TASN1DecGeneric* gen; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before DecodeDERLC().\n"))); + + CArrayPtrFlat* arrayPtr; + TInt pos(0); + arrayPtr = seq.DecodeDERLC(ptr, pos); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(0); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 m = gen->Encoding(); + if (m.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + RInteger modulus = asn1.DecodeDERLongL(m, pos); + CleanupStack::PushL(modulus); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(1); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 e = gen->Encoding(); + if (e.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + RInteger exponent = asn1.DecodeDERLongL(e, pos); + CleanupStack::PushL(exponent); + + TPtrC8 p_hash( + hash->get_data(hash->get_data_length()), + hash->get_data_length()); + if (p_hash.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, hash is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 p_sig( + signed_hash->get_data(signed_hash->get_data_length()), + signed_hash->get_data_length()); + if (p_sig.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, signed_hash is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + CRSAPublicKey* public_key = CRSAPublicKey::NewL(modulus, exponent); + // Modulus and exponent are popped here because CRSAPublicKey frees them + CleanupStack::Pop(&exponent); + CleanupStack::Pop(&modulus); + CleanupStack::PushL(public_key); + + RInteger signature = RInteger::NewL(p_sig); + CleanupStack::PushL(signature); + + CRSASignature* rsa_signature = CRSASignature::NewL(signature); + // signature is popped here because CRSASignature frees it + CleanupStack::Pop(&signature); + CleanupStack::PushL(rsa_signature); + + + CRSAPKCS1v15Verifier* rsa_verifier = CRSAPKCS1v15Verifier::NewL(*public_key); + CleanupStack::PushL(rsa_verifier); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before VerifyL().\n"))); + + TBool result = rsa_verifier->VerifyL(p_hash, *rsa_signature); + eap_status_e status; + if (result) + { + // Verify successful + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("eap_am_crypto_symbian: RSA verify successful.\n"))); + status = eap_status_ok; + } + else + { + // Verify failed + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("eap_am_crypto_symbian: RSA verify failed.\n"))); + status = eap_status_illegal_parameter; + } + + CleanupStack::PopAndDestroy(rsa_verifier); + CleanupStack::PopAndDestroy(rsa_signature); + CleanupStack::PopAndDestroy(public_key); + CleanupStack::PopAndDestroy(arrayPtr); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), OK.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_cleanup( + eap_variable_data_c * const /*rsa_context*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return eap_status_ok; +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_init( + eap_variable_data_c * const dsa_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + eap_status_e status = dsa_context->init(0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + dsa_context->set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return eap_status_ok; +} + +//-------------------------------------------------- +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_sign( + eap_variable_data_c * const dsa_context, + const eap_variable_data_c * const private_dsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_sign(), begins.\n"))); + + eap_status_e status = eap_status_ok; + + TRAPD(err, dsa_signL( + dsa_context, + private_dsa_key, + hash, + signed_hash)); + if (err != KErrNone) + { + status = ((m_am_tools)->convert_am_error_to_eapol_error(err)); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_sign() failed, err %d, status %d.\n"), + err, + status)); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_crypto_symbian_c::dsa_signL( + eap_variable_data_c * const dsa_context, + const eap_variable_data_c * const private_dsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash) +{ + EAP_UNREFERENCED_PARAMETER(dsa_context); + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_signL(), begins.\n"))); + + TPtrC8 ptr( + private_dsa_key->get_data(private_dsa_key->get_data_length()), + private_dsa_key->get_data_length()); + if (ptr.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, private_dsa_key is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + // The private_dsa_key is ASN.1 encoded and contains DSA parameters and public and private keys. + // It must be decoded before it can be used. + // SEQUENCE { + // INTEGER version + // INTEGER p + // INTEGER q + // INTEGER g + // INTEGER Y + // INTEGER X + // } + // + // + TASN1DecSequence seq; + TASN1DecInteger asn1; + TASN1DecGeneric* gen; + RInteger param_p; + RInteger param_q; + RInteger param_g; + RInteger public_key; + RInteger private_key; + CArrayPtrFlat* arrayPtr; + TInt pos(0); + arrayPtr = seq.DecodeDERLC(ptr, pos); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(1); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 p = gen->Encoding(); + if (p.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + param_p = asn1.DecodeDERLongL(p, pos); + CleanupStack::PushL(param_p); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(2); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 q = gen->Encoding(); + if (q.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + param_q = asn1.DecodeDERLongL(q, pos); + CleanupStack::PushL(param_q); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(3); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 g = gen->Encoding(); + if (g.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + param_g = asn1.DecodeDERLongL(g, pos); + CleanupStack::PushL(param_g); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(4); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 Y = gen->Encoding(); + if (Y.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + public_key = asn1.DecodeDERLongL(Y, pos); + CleanupStack::PushL(public_key); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(5); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 X = gen->Encoding(); + if (X.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + pos = 0; + private_key = asn1.DecodeDERLongL(X, pos); + CleanupStack::PushL(private_key); + + CDSAPrivateKey* priv_key = CDSAPrivateKey::NewL(param_p, param_q, param_g, private_key); + CleanupStack::PushL(priv_key); + + CDSASigner* signer = CDSASigner::NewL(*priv_key); + CleanupStack::PushL(signer); + + TPtrC8 data( + hash->get_data(hash->get_data_length()), + hash->get_data_length()); + if (data.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, hash is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + const CDSASignature* signature = signer->SignL(data); + + RInteger R = RInteger::NewL(signature->R()); + CleanupStack::PushL(R); + RInteger S = RInteger::NewL(signature->S()); + CleanupStack::PushL(S); + + CASN1EncSequence* sequence = CASN1EncSequence::NewLC(); + CASN1EncBigInt* enc_r = CASN1EncBigInt::NewLC(R); + CASN1EncBigInt* enc_s = CASN1EncBigInt::NewLC(S); + + sequence->AddChildL(enc_r); + + sequence->AddChildL(enc_s); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before NewLC().\n"))); + + HBufC8* buf = HBufC8::NewLC(sequence->LengthDER()); + TPtr8 tmp = buf->Des(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before WriteDERL().\n"))); + + tmp.SetLength(sequence->LengthDER()); + pos = 0; + sequence->WriteDERL(tmp, (TUint&) pos); + + eap_status_e status = signed_hash->set_copy_of_buffer(tmp.Ptr(), tmp.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, signed_hash is invalid, status %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrNoMemory); + } + + CleanupStack::PopAndDestroy(buf); + CleanupStack::Pop(enc_s); // BigInts are deleted by the sequence + CleanupStack::Pop(enc_r); // BigInts are deleted by the sequence + + CleanupStack::PopAndDestroy(sequence); + CleanupStack::PopAndDestroy(&S); + CleanupStack::PopAndDestroy(&R); + CleanupStack::PopAndDestroy(signer); + CleanupStack::PopAndDestroy(priv_key); + CleanupStack::PopAndDestroy(&private_key); + CleanupStack::PopAndDestroy(&public_key); + CleanupStack::PopAndDestroy(¶m_g); + CleanupStack::PopAndDestroy(¶m_q); + CleanupStack::PopAndDestroy(¶m_p); + CleanupStack::PopAndDestroy(arrayPtr); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_signL(), OK.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_verify( + eap_variable_data_c * const dsa_context, + const eap_variable_data_c * const public_dsa_key, + const eap_variable_data_c * const dsa_param_p, + const eap_variable_data_c * const dsa_param_q, + const eap_variable_data_c * const dsa_param_g, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verify(), begins.\n"))); + + eap_status_e status = eap_status_ok; + + __UHEAP_MARK; + TRAPD(err, dsa_verifyL( + dsa_context, + public_dsa_key, + dsa_param_p, + dsa_param_q, + dsa_param_g, + hash, + signed_hash)); + __UHEAP_MARKEND; + if (err != KErrNone) + { + status = ((m_am_tools)->convert_am_error_to_eapol_error(err)); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_verify() failed, err %d, status %d.\n"), + err, + status)); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_crypto_symbian_c::dsa_verifyL( + eap_variable_data_c * const /*dsa_context*/, + const eap_variable_data_c * const public_dsa_key, + const eap_variable_data_c * const dsa_param_p, + const eap_variable_data_c * const dsa_param_q, + const eap_variable_data_c * const dsa_param_g, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(1), begins.\n"))); + + // Parameters + TPtrC8 p( + dsa_param_p->get_data(dsa_param_p->get_data_length()), + dsa_param_p->get_data_length()); + if (p.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(2) failed, dsa_param_p is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + TPtrC8 q( + dsa_param_q->get_data(dsa_param_q->get_data_length()), + dsa_param_q->get_data_length()); + if (q.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(3) failed, dsa_param_q is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + TPtrC8 g( + dsa_param_g->get_data(dsa_param_g->get_data_length()), + dsa_param_g->get_data_length()); + if (g.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(4) failed, dsa_param_g is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + RInteger P = RInteger::NewL(p); + CleanupStack::PushL(P); + + RInteger Q = RInteger::NewL(q); + CleanupStack::PushL(Q); + + RInteger G = RInteger::NewL(g); + CleanupStack::PushL(G); + + TPtrC8 calculated_hash( + hash->get_data(hash->get_data_length()), + hash->get_data_length()); + if (calculated_hash.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(5) failed, hash is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + + // Public key is ASN.1 encoded so it must be decoded + TPtrC8 pkey ( + public_dsa_key->get_data(public_dsa_key->get_data_length()), + public_dsa_key->get_data_length()); + if (pkey.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(6) failed, public_dsa_key is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TASN1DecInteger asn1; + TInt pos(0); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(7), before DecodeDERLongL().\n"))); + + RInteger public_key_int = asn1.DecodeDERLongL( + pkey, + pos); + + CleanupStack::PushL(public_key_int); + CDSAPublicKey* pub_key = CDSAPublicKey::NewL(P, Q, G, public_key_int); + // RIntegers needs to be popped because CDSAPublicKey frees them + CleanupStack::Pop(&public_key_int); + CleanupStack::Pop(&G); + CleanupStack::Pop(&Q); + CleanupStack::Pop(&P); + CleanupStack::PushL(pub_key); + + TPtrC8 ptr( + signed_hash->get_data(hash->get_data_length()), + signed_hash->get_data_length()); + if (ptr.Ptr() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(8) failed, signed_hash is invalid.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(9), before DecodeDERLC().\n"))); + + TASN1DecSequence seq; + TASN1DecGeneric* gen; + RInteger R; + RInteger S; + CArrayPtrFlat* arrayPtr; + pos = 0; + arrayPtr = seq.DecodeDERLC(ptr, pos); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(10), before DecodeDERLongL().\n"))); + + gen = arrayPtr->At(0); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + TPtrC8 r = gen->Encoding(); + if (r.Length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + pos = 0; + R = asn1.DecodeDERLongL(r, pos); + CleanupStack::PushL(R); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(11), before arrayPtr->At(1).\n"))); + + gen = arrayPtr->At(1); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL() failed, illegal data.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + User::Leave(KErrArgument); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(12), before gen->Encoding().\n"))); + + TPtrC8 s = gen->Encoding(); + pos = 0; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(13), before DecodeDERLongL().\n"))); + + S = asn1.DecodeDERLongL(s, pos); + CleanupStack::PushL(S); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(14), before CDSASignature::NewL().\n"))); + + CDSASignature* signature = CDSASignature::NewL(R, S); + // Parameters needs to be popped because CDSASignature frees them + CleanupStack::Pop(&S); + CleanupStack::Pop(&R); + CleanupStack::PushL(signature); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(15), before CDSAVerifier::NewL().\n"))); + + CDSAVerifier* verifier = CDSAVerifier::NewL(*pub_key); + CleanupStack::PushL(verifier); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(16), before VerifyL().\n"))); + + TBool result = verifier->VerifyL(calculated_hash, *signature); + if (result == EFalse) + { + // Verify failed + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_ERROR, (EAPL("eap_am_crypto_symbian: DSA verify failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_ERROR); + User::Leave(KErrArgument); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_crypto_symbian: DSA verify successful.\n"))); + + CleanupStack::PopAndDestroy(verifier); + CleanupStack::PopAndDestroy(signature); + CleanupStack::PopAndDestroy(arrayPtr); + CleanupStack::PopAndDestroy(pub_key); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(17), OK.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_cleanup( + eap_variable_data_c * const /*dsa_context*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md5_digest_length( + eap_variable_data_c * const md5_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(md5_context->get_is_valid()); + + CMessageDigest *ctx = (CMessageDigest *)md5_context->get_data(md5_context->get_data_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return ctx->HashSize(); +} + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md5_block_size( + eap_variable_data_c * const /* md5_context */) +{ + return MD5_BLOCK_SIZE; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_init( + eap_variable_data_c * const md5_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + CMessageDigest *md5 = 0; + + TRAPD(ret, md5 = CMD5::NewL()); + + if (ret != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (md5_context->get_is_valid_data() == true) + { + md5_cleanup(md5_context); + } + + eap_status_e status = md5_context->set_buffer(md5, sizeof(*md5), false, false); + if (status != eap_status_ok) + { + delete md5; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_update( + eap_variable_data_c * const md5_context, + const u8_t * const data, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(md5_context != 0); + EAP_ASSERT(md5_context->get_is_valid() == true); + if (md5_context == 0 + || md5_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + CMessageDigest *md5 = (CMessageDigest *)md5_context->get_data(sizeof(CMessageDigest)); + + if (md5 == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // This breaks the const type. + TPtr8 tmp(const_cast(data), data_length, data_length); + + md5->Hash(tmp); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_final( + eap_variable_data_c * const md5_context, + u8_t * const message_digest, + u32_t *md_length_or_null) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(md5_context != 0); + EAP_ASSERT(md5_context->get_is_valid() == true); + if (md5_context == 0 + || md5_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + CMessageDigest *md5 = (CMessageDigest *)md5_context->get_data(sizeof(CMessageDigest)); + + if (md5 == 0 + || message_digest == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (md_length_or_null != 0) + { + *md_length_or_null = md5->HashSize(); + } + + TPtrC8 digest = md5->Hash(TPtrC8(0,0)); + + if (digest.Ptr() == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + m_am_tools->memmove(message_digest, digest.Ptr(), md5->HashSize()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_cleanup( + eap_variable_data_c * const md5_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(md5_context != 0); + EAP_ASSERT(md5_context->get_is_valid() == true); + if (md5_context == 0 + || md5_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + CMessageDigest *md5 = (CMessageDigest *)md5_context->get_data(sizeof(CMessageDigest)); + + delete md5; + + md5_context->reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_copy_context( + eap_variable_data_c * const copied_md5_context, + const eap_variable_data_c * const original_md5_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + CMessageDigest *ctx_copy = 0; + + if (original_md5_context == 0 + || original_md5_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + CMessageDigest *ctx = (CMessageDigest *)original_md5_context->get_data(sizeof(CMessageDigest)); + + TRAPD(ret, ctx_copy = ctx->CopyL()); + + if (ret != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = copied_md5_context->set_buffer(ctx_copy, sizeof(*ctx_copy), false, false); + if (status != eap_status_ok) + { + delete ctx_copy; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md4_digest_length( + eap_variable_data_c * const md4_context) +{ + if (md4_context == 0 + || md4_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_md4_c * const md4 = reinterpret_cast( + md4_context->get_data(sizeof(eap_am_crypto_md4_c))); + + if (md4 == 0 + || md4->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + return md4->get_digest_length(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md4_block_size( + eap_variable_data_c * const md4_context) +{ + if (md4_context == 0 + || md4_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_md4_c * const md4 = reinterpret_cast( + md4_context->get_data(sizeof(eap_am_crypto_md4_c))); + + if (md4 == 0 + || md4->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + return md4->get_block_size(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_init( + eap_variable_data_c * const md4_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + if (md4_context == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (md4_context->get_is_valid_data() == true) + { + md4_cleanup(md4_context); + } + + eap_am_crypto_md4_c * const md4 = new eap_am_crypto_md4_c(m_am_tools); + if (md4 == 0 + || md4->get_is_valid() == false) + { + delete md4; + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = md4->hash_init(); + if (status != eap_status_ok) + { + delete md4; + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (md4_context->get_is_valid_data() == true) + { + md4_cleanup(md4_context); + } + + status = md4_context->set_buffer(md4, sizeof(*md4), false, true); + if (status != eap_status_ok) + { + delete md4; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_update( + eap_variable_data_c * const md4_context, + const u8_t * const data, + const u32_t data_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(md4_context != 0); + EAP_ASSERT(md4_context->get_is_valid() == true); + if (md4_context == 0 + || md4_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_md4_c * const md4 = reinterpret_cast( + md4_context->get_data(sizeof(eap_am_crypto_md4_c))); + + if (md4 == 0 + || md4->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = md4->hash_update( + data, + data_length); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_final( + eap_variable_data_c * const md4_context, + u8_t * const message_digest, + u32_t * md_length_or_null) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(md4_context != 0); + EAP_ASSERT(md4_context->get_is_valid() == true); + if (md4_context == 0 + || md4_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_md4_c * const md4 = reinterpret_cast( + md4_context->get_data(sizeof(eap_am_crypto_md4_c))); + + if (md4 == 0 + || md4->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = md4->hash_final( + message_digest, + md_length_or_null); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_cleanup( + eap_variable_data_c * const md4_context) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_ASSERT(md4_context != 0); + EAP_ASSERT(md4_context->get_is_valid() == true); + if (md4_context == 0 + || md4_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_md4_c * const md4 = reinterpret_cast( + md4_context->get_data(sizeof(eap_am_crypto_md4_c))); + + delete md4; + + md4_context->reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_copy_context( + eap_variable_data_c * const copied_md4_context, + const eap_variable_data_c * const original_md4_context) +{ + if (original_md4_context == 0 + || original_md4_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_md4_c * const md4 = reinterpret_cast( + original_md4_context->get_data(sizeof(eap_am_crypto_md4_c))); + + if (md4 == 0 + || md4->get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_crypto_md4_c * const md4_copy = md4->copy(); + if (md4_copy == 0 + || md4_copy->get_is_valid() == false) + { + delete md4_copy; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status = copied_md4_context->set_buffer(md4_copy, sizeof(*md4_copy), false, true); + if (status != eap_status_ok) + { + delete md4_copy; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_set_encryption_key( + eap_variable_data_c * const aes_context, + const u8_t * const key, const u32_t key_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("encryption_key"), + key, key_length)); + + if (key_length != aes_key_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + TPtrC8 aes_key(key, key_length); + + CAESEncryptor* aes = 0; + TRAPD(err, aes = CAESEncryptor::NewL(aes_key)); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // If context is already reserved then cleanup it. + if (aes_context->get_is_valid_data() == true) + { + aes_cleanup(aes_context); + } + + eap_status_e status = aes_context->set_buffer( + aes, + sizeof(*aes), + false, + false); + if (status != eap_status_ok) + { + delete aes; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); + +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_set_decryption_key( + eap_variable_data_c * const aes_context, + const u8_t * const key, const u32_t key_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("decryption_key"), + key, key_length)); + + if (key_length != aes_key_length()) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + TPtrC8 aes_key(key, key_length); + + CAESDecryptor* aes = 0; + TRAPD(err, aes = CAESDecryptor::NewL(aes_key)); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // If context is already reserved then cleanup it. + if (aes_context->get_is_valid_data() == true) + { + aes_cleanup(aes_context); + } + + eap_status_e status = aes_context->set_buffer( + aes, + sizeof(*aes), + false, + false); + if (status != eap_status_ok) + { + delete aes; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); + +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_cleanup( + eap_variable_data_c * const aes_context) +{ + EAP_ASSERT(aes_context != 0); + EAP_ASSERT(aes_context->get_is_valid() == true); + if (aes_context == 0 + || aes_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + CRijndael* aes = reinterpret_cast(aes_context->get_data(sizeof(CRijndael))); + + delete aes; + + aes_context->reset(); + + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_encrypt_block( + eap_variable_data_c * const aes_context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length) +{ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_in"), + data_in, data_length)); + + if (data_length != aes_block_size()) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_encryption_failure); + } + + EAP_ASSERT(aes_context != 0); + EAP_ASSERT(aes_context->get_is_valid() == true); + if (aes_context == 0 + || aes_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + CAESEncryptor* aes = (CAESEncryptor*)aes_context->get_data(sizeof(CAESEncryptor)); + if (aes == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + Mem::Copy(data_out, data_in, data_length); + + TPtr8 ptr(data_out, data_length, data_length); + + aes->Transform(ptr); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_out"), + data_out, data_length)); + + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_decrypt_block( + eap_variable_data_c * const aes_context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length) +{ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_in"), + data_in, data_length)); + + if (data_length != aes_block_size()) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_decryption_failure); + } + + EAP_ASSERT(aes_context != 0); + EAP_ASSERT(aes_context->get_is_valid() == true); + if (aes_context == 0 + || aes_context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + CAESDecryptor* aes = (CAESDecryptor*)aes_context->get_data(sizeof(CAESDecryptor)); + if (aes == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Copy input to output so we can transform it in the output buffer + Mem::Copy(data_out, data_in, data_length); + + TPtr8 ptr(data_out, data_length, data_length); + + aes->Transform(ptr); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_out"), + data_out, data_length)); + + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::key_length_3des_ede() +{ + return 3ul * BLOCK_SIZE_3DES_EDE; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::block_size_3des_ede() +{ + return BLOCK_SIZE_3DES_EDE; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::set_encryption_key_3des_ede( + eap_variable_data_c * const context, + const u8_t * const key, const u32_t key_length) +{ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("encryption_key"), + key, key_length)); + + if (key_length != key_length_3des_ede()) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + TPtrC8 des_key(key, key_length); + + C3DESEncryptor* ede_3des = 0; + TRAPD(err, ede_3des = C3DESEncryptor::NewL(des_key)); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // If context is already reserved then cleanup it. + if (context->get_is_valid_data() == true) + { + cleanup_3des_ede(context); + } + + eap_status_e status = context->set_buffer( + ede_3des, + sizeof(*ede_3des), + false, + false); + if (status != eap_status_ok) + { + delete ede_3des; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::cleanup_3des_ede( + eap_variable_data_c * const context) +{ + EAP_ASSERT(context != 0); + EAP_ASSERT(context->get_is_valid() == true); + if (context == 0 + || context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + C3DES* ede_3des = (C3DES*)context->get_data(sizeof(C3DES)); + + delete ede_3des; + + context->reset(); + + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::set_decryption_key_3des_ede( + eap_variable_data_c * const context, + const u8_t * const key, const u32_t key_length) +{ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("decryption_key"), + key, key_length)); + + if (key_length != key_length_3des_ede()) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); + } + + TPtrC8 des_key(key, key_length); + + C3DESDecryptor* ede_3des = 0; + TRAPD(err, ede_3des = C3DESDecryptor::NewL(des_key)); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // If context is already reserved then cleanup it. + if (context->get_is_valid_data() == true) + { + cleanup_3des_ede(context); + } + + eap_status_e status = context->set_buffer( // + ede_3des, + sizeof(*ede_3des), + false, + false); + if (status != eap_status_ok) + { + delete ede_3des; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::encrypt_block_3des_ede( + eap_variable_data_c * const context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length) +{ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE encrypt data_in"), + data_in, data_length)); + + if (data_length != block_size_3des_ede()) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_encryption_failure); + } + + EAP_ASSERT(context != 0); + EAP_ASSERT(context->get_is_valid() == true); + if (context == 0 + || context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + C3DESEncryptor* ede_3des = (C3DESEncryptor*)context->get_data(sizeof(C3DESEncryptor)); + if (ede_3des == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + Mem::Copy(data_out, data_in, data_length); + + TPtr8 ptr(data_out, data_length, data_length); + + ede_3des->Transform(ptr); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE encrypt data_out"), + data_out, data_length)); + + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::decrypt_block_3des_ede( + eap_variable_data_c * const context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length) +{ + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE decrypt data_in"), + data_in, data_length)); + + if (data_length != block_size_3des_ede()) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_decryption_failure); + } + + EAP_ASSERT(context != 0); + EAP_ASSERT(context->get_is_valid() == true); + if (context == 0 + || context->get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + C3DESDecryptor* ede_3des = (C3DESDecryptor*)context->get_data(sizeof(C3DESDecryptor)); + if (ede_3des == 0) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + Mem::Copy(data_out, data_in, data_length); + + TPtr8 ptr(data_out, data_length, data_length); + + ede_3des->Transform(ptr); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE decrypt data_out"), + data_out, data_length)); + + return eap_status_ok; +} + +//-------------------------------------------------- + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_mutex_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_mutex_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,172 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 602 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +// INCLUDES +#include "eap_am_memory.h" +#include "eap_am_mutex_symbian.h" +#include "abs_eap_am_mutex.h" + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_mutex_symbian_c::~eap_am_mutex_symbian_c() +{ + m_mutex.Close(); + m_owner_thread.Close(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_mutex_symbian_c::eap_am_mutex_symbian_c() + : m_is_valid(false) +{ + if (eap_am_mutex_base_c::get_is_valid() == false) + { + return; + } + + m_mutex.CreateLocal(); + + RThread thisThread; // Generic handle meaning "the current thread" + + TInt err = thisThread.Duplicate(thisThread); // a specific handle + if (err == KErrNone) + { + m_is_valid = true; + } + + m_owner_thread = thisThread; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_mutex_symbian_c::eap_am_mutex_symbian_c(const eap_am_mutex_symbian_c * const owner) + : eap_am_mutex_base_c(owner) + , m_is_valid(false) +{ + if (eap_am_mutex_base_c::get_is_valid() == false) + { + return; + } + + m_mutex = *(owner->get_mutex()); + m_mutex.Duplicate(*(owner->get_owner_thread())); + + RThread thisThread; // Generic handle meaning "the current thread" + + TInt err = thisThread.Duplicate(thisThread); // a specific handle + if (err == KErrNone) + { + m_is_valid = true; + } + + m_owner_thread = thisThread; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const RMutex * eap_am_mutex_symbian_c::get_mutex() const +{ + return &m_mutex; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const RThread * eap_am_mutex_symbian_c::get_owner_thread() const +{ + return &m_owner_thread; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_mutex_symbian_c::mutex_enter() +{ +#if !defined(NO_EAP_MUTEX) + m_mutex.Wait(); + get_reference()->set_is_reserved(true); +#endif //#if !defined(NO_EAP_MUTEX) + + return eap_status_ok; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_mutex_symbian_c::mutex_leave(abs_eap_am_tools_c * const m_am_tools) +{ + EAP_UNREFERENCED_PARAMETER(m_am_tools); + +#if !defined(NO_EAP_MUTEX) + EAP_ASSERT(get_reference()->get_is_reserved() == true); + + get_reference()->set_is_reserved(false); + m_mutex.Signal(); +#endif //#if !defined(NO_EAP_MUTEX) + + return eap_status_ok; +} + +//-------------------------------------------------- + +// +// The mutex handle must be dublicated in Symbian operating system for each thread. +EAP_FUNC_EXPORT abs_eap_am_mutex_c * eap_am_mutex_symbian_c::dublicate_mutex() +{ + eap_am_mutex_symbian_c *dublicate = new eap_am_mutex_symbian_c(this); + return dublicate; +} + +//-------------------------------------------------- + +// +// This is used in debug asserts. Those will check the mutex is really reserved when critical code is entered. +EAP_FUNC_EXPORT bool eap_am_mutex_symbian_c::get_is_reserved() const +{ + // In Symbian we need this object to test reference flag, + // because each thread has own duplicated mutex object. + return get_reference()->get_is_reserved(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_mutex_symbian_c::get_is_valid() const +{ + return m_is_valid; +} + +//-------------------------------------------------- + + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_semaphore_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_semaphore_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,171 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 146 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +// INCLUDES +#include "eap_am_memory.h" +#include "eap_am_trace_symbian.h" + +#include "eap_am_semaphore_symbian.h" + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_semaphore_symbian_c::~eap_am_semaphore_symbian_c() +{ + m_semaphore.Close(); + m_owner_thread.Close(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_semaphore_symbian_c::eap_am_semaphore_symbian_c( + const i32_t initial_count, + const i32_t maximum_count) + : m_count(initial_count) + , m_is_valid(false) +{ + if (eap_am_semaphore_base_c::get_is_valid() == false) + { + return; + } + + TInt err = m_semaphore.CreateLocal(initial_count); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("\n ERROR: eap_am_semaphore_symbian_c::eap_am_semaphore_symbian_c : Semaphore CreateLocal returned err = %d"), err)); + return; + } + + RThread thisThread; // Generic handle meaning "the current thread" + + err = thisThread.Duplicate(thisThread); // a specific handle + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("\n ERROR: eap_am_semaphore_symbian_c::eap_am_semaphore_symbian_c : Thread Duplicate returned err = %d"), err)); + return; + } + + m_owner_thread = thisThread; + + m_is_valid = true; +} + +EAP_FUNC_EXPORT eap_am_semaphore_symbian_c::eap_am_semaphore_symbian_c( + const eap_am_semaphore_symbian_c * const owner) + : eap_am_semaphore_base_c(owner) + , m_count(0ul) + , m_is_valid(false) +{ + if (eap_am_semaphore_base_c::get_is_valid() == false) + { + return; + } + + m_semaphore = *(owner->get_semaphore()); + + TInt err = m_semaphore.Duplicate(*(owner->get_owner_thread())); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("\n ERROR: eap_am_semaphore_symbian_c::eap_am_semaphore_symbian_c(): Semaphore Duplicate returned err = %d"), err)); + return; + } + + RThread thisThread; // Generic handle meaning "the current thread" + + err = thisThread.Duplicate(thisThread); // a specific handle + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("\n ERROR: eap_am_semaphore_symbian_c::eap_am_semaphore_symbian_c(): Thread Duplicate returned err = %d"), err)); + return; + } + + m_owner_thread = thisThread; + + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const RSemaphore * eap_am_semaphore_symbian_c::get_semaphore() const +{ + return &m_semaphore; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const RThread * eap_am_semaphore_symbian_c::get_owner_thread() const +{ + return &m_owner_thread; +} + +//-------------------------------------------------- + + + +EAP_FUNC_EXPORT eap_status_e eap_am_semaphore_symbian_c::semaphore_reserve() +{ + m_semaphore.Wait(); + m_count--; + + return eap_status_ok; +} + +EAP_FUNC_EXPORT eap_status_e eap_am_semaphore_symbian_c::semaphore_release() +{ + m_count++; + m_semaphore.Signal(); + + return eap_status_ok; +} + +EAP_FUNC_EXPORT abs_eap_am_semaphore_c * eap_am_semaphore_symbian_c::dublicate_semaphore() +{ + eap_am_semaphore_symbian_c *dublicate = new eap_am_semaphore_symbian_c(this); + return dublicate; +} + +EAP_FUNC_EXPORT u32_t eap_am_semaphore_symbian_c::get_count() const +{ + return m_count; +} + +EAP_FUNC_EXPORT bool eap_am_semaphore_symbian_c::get_is_valid() const +{ + return m_is_valid; +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + + + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_tools_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_tools_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1539 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 147 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_tools_symbian.h" +#include "eap_am_types.h" +#include +#include + +const TUint MAX_DB_TRANSACTION_RETRY_COUNT = 10; +const u32_t EAP_TIMER_MAX_AFTER_TIME_MILLISECONDS_SYMBIAN = 2100000ul; + +//-------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_tools_symbian_c::~eap_am_tools_symbian_c() +{ + // If multithreading is used the log file is not kept open all the time + // so no need to close the handles here. +#if defined(USE_EAP_FILE_TRACE) +#if !defined (USE_MULTITHREADING) + m_LogFile.Close(); + m_Fs.Close(); +#endif //#if !defined (USE_MULTITHREADING) +#endif //#if defined(USE_EAP_FILE_TRACE) +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_tools_symbian_c::eap_am_tools_symbian_c(eap_const_string /*pfilename*/) + : eap_am_tools_c() + , CTimer(CTimer::EPriorityStandard) + , m_start_ticks(0) + , m_directory_exists(false) + , m_crypto(this) + , m_timer_queue(this, EAP_TIMER_RESOLUTION) + , m_run_thread(true) + , m_is_valid(false) + , m_configure_called(false) + , iInterval(0ul) + , iStartTime(0ul) + , iLastTime(0ul) + , m_logfile_open(false) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + +#if defined(USE_EAP_HARDWARE_TRACE) + set_trace_mask( + eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_error + | eap_am_tools_c::eap_trace_mask_debug + | eap_am_tools_c::eap_trace_mask_message_data); +#endif //#if defined(USE_EAP_HARDWARE_TRACE) + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_tools_symbian_c::eap_am_tools_symbian_c()\n"))); + + if (m_crypto.get_is_valid() == false) + { + EAP_TRACE_ERROR( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: m_crypto.get_is_valid() == false\n"))); + return; + } + + if (m_timer_queue.get_is_valid() == false) + { + EAP_TRACE_ERROR( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: m_timer_queue.get_is_valid() == false\n"))); + return; + } + + if (m_global_mutex.get_is_valid() == false) + { + EAP_TRACE_ERROR( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: m_global_mutex.get_is_valid() == false\n"))); + return; + } + + if (m_trace_mutex.get_is_valid() == false) + { + EAP_TRACE_ERROR( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: m_trace_mutex.get_is_valid() == false\n"))); + return; + } + + m_is_valid = true; + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::set_use_eap_milli_second_timer( + const bool use_eap_millisecond_timer) +{ + m_timer_queue.set_use_eap_milli_second_timer(use_eap_millisecond_timer); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_tools_symbian_c::get_use_eap_milli_second_timer() +{ + return m_timer_queue.get_use_eap_milli_second_timer(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::configure() +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_tools_symbian_c::configure()\n"))); + + if (m_configure_called == true) + { + return EAP_STATUS_RETURN(this, eap_status_ok); + } + +#if defined(USE_EAP_HARDWARE_TRACE) + set_trace_mask( + eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_error + | eap_am_tools_c::eap_trace_mask_debug + | eap_am_tools_c::eap_trace_mask_message_data); +#endif //#if defined(USE_EAP_HARDWARE_TRACE) + + m_start_ticks = get_clock_ticks(); + iLastTime = m_start_ticks; + + eap_status_e status = m_crypto.configure(); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(this, status); + } + + m_crypto.add_rand_seed_hw_ticks(); + + if (m_crypto.get_is_valid() == false) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + + if (m_timer_queue.get_is_valid() == false) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + + if (m_global_mutex.get_is_valid() == false) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + + if (m_trace_mutex.get_is_valid() == false) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_allocation_error); + } + +#if defined(USE_EAP_FILE_TRACE) +#if !defined (USE_MULTITHREADING) + TInt result = m_Fs.Connect(); + if (result != KErrNone) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_process_general_error); + } +#endif //#if !defined (USE_MULTITHREADING) +#endif //#if defined(USE_EAP_FILE_TRACE) + + { + set_use_timer_queue(); + set_use_eap_milli_second_timer(true); + + TRAPD(err, CTimer::ConstructL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("CTimer::ConstructL() failed, err %d.\n"), + err)); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_process_general_error); + } + + CActiveScheduler::Add(this); + } + + m_configure_called = true; + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::enter_global_mutex() +{ + EAP_ASSERT_ALWAYS_TOOLS(this, m_configure_called == true); + + m_global_mutex.mutex_enter(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::leave_global_mutex() +{ + m_global_mutex.mutex_leave(this); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT abs_eap_am_mutex_c * eap_am_tools_symbian_c::get_global_mutex() +{ + return &m_global_mutex; +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::enter_trace_mutex() +{ + m_trace_mutex.mutex_enter(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::leave_trace_mutex() +{ + m_trace_mutex.mutex_leave(this); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT abs_eap_am_mutex_c * eap_am_tools_symbian_c::get_trace_mutex() +{ + return &m_trace_mutex; +} + + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_am_tools_symbian_c::get_timer_resolution_ms() +{ + enter_global_mutex(); + const u32_t res = m_timer_queue.get_timer_resolution_ms(); + leave_global_mutex(); + return res; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::set_timer_resolution_ms(const u32_t timer_resolution_ms) +{ + enter_global_mutex(); + m_timer_queue.set_timer_resolution_ms(timer_resolution_ms); + leave_global_mutex(); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u32_t eap_am_tools_symbian_c::pulse_timer(const u32_t elapsed_time_in_ms) +{ + return m_timer_queue.pulse_timer(elapsed_time_in_ms, true); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::sprint(TDes& /*KPrintBuf*/, eap_const_string /*format*/, ...) +{ +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_am_tools_symbian_c::snprintf(u8_t * const buffer, u32_t buffer_size, eap_format_string format, ...) +{ + if (buffer == 0) + { + return 0ul; + } + + u32_t result = 0; + m_format_buf.Copy((const TUint8 *)format); + VA_LIST args = {0,}; + VA_START(args, format); + m_trace_buf.FormatList(m_format_buf, args); + VA_END(args); + result = (static_cast(m_trace_buf.Size()) < buffer_size) ? static_cast(m_trace_buf.Size()) : buffer_size; + memmove(buffer, m_trace_buf.PtrZ(), result); + + return result; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::formatted_print(eap_format_string format, ...) +{ + EAP_UNREFERENCED_PARAMETER(format); + +#if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS) + + enter_trace_mutex(); + + u64_t time_stamp = get_clock_ticks(); + TInt64 *_time_stamp = (TInt64 *)&time_stamp; + if (get_use_seconds_timestamp_in_traces() == true) + { + u64_t hw_ticks_of_second = get_clock_ticks_of_second(); + TInt64 *_hw_ticks_of_second = (TInt64 *)&hw_ticks_of_second; + time_stamp -= m_start_ticks; + + { + TInt64 _seconds = (*_time_stamp) / (*_hw_ticks_of_second); + TInt64 _remainder = (*_time_stamp) % (*_hw_ticks_of_second); + TInt64 _multiplier((TUint)1000000ul); + TInt64 _tmp = _multiplier * _remainder; + TInt64 _micro_seconds = _tmp / (*_hw_ticks_of_second); + TInt64 _div_60((TUint)60ul); + + TInt64 _minutes = _seconds / _div_60; + _seconds = _seconds - _minutes * _div_60; + TInt64 _hours = _minutes / _div_60; + _minutes = _minutes - _hours* _div_60; + + _LIT8(KFormat1, "%02d:%02d:%02d.%06d:EAPOL:"); + + m_trace_buf.Format( + KFormat1, + static_cast(_hours), + static_cast(_minutes), + static_cast(_seconds), + static_cast(_micro_seconds)); + } + + } + else + { + _LIT8(KFormat2, "%08x%08x:EAPOL:"); + + u32_t *time_stamp_u32_t = reinterpret_cast(&time_stamp); + m_trace_buf.Format(KFormat2, time_stamp_u32_t[1], time_stamp_u32_t[0]); + } + + VA_LIST args = {0,}; + VA_START(args, format); + m_format_buf.Copy((const TUint8 *)format); + + m_args_buf.FormatList(m_format_buf, args); + m_trace_buf.Append(m_args_buf); + VA_END(args); + + +#if defined(USE_EAP_HARDWARE_TRACE) + + { + #if !defined(USE_EAP_HARDWARE_TRACE_RAW_PRINT) + { + TInt length = m_trace_buf.Length(); + if (length >= 2ul) + { + --length; + const TUint8 *last_char = m_trace_buf.Ptr() + length; + + if (last_char != 0 + && *last_char == '\n') + { + // This removes the ending new line character. + // RDebug::Print() will write new line automatically. + m_trace_buf.SetLength(length); + } + } + } + #endif //#if !defined(USE_EAP_HARDWARE_TRACE_RAW_PRINT) + + m_trace_buf_16.Copy(m_trace_buf); + + #if defined(USE_EAP_HARDWARE_TRACE_RAW_PRINT) + RDebug::RawPrint(m_trace_buf_16); + #else + RDebug::Print(_L("%S"), &m_trace_buf_16); + #endif //#if defined(USE_EAP_HARDWARE_TRACE_RAW_PRINT) + } + +#endif //#if defined(USE_EAP_HARDWARE_TRACE) + + +#if defined(USE_EAP_FILE_TRACE) + + #if defined (USE_MULTITHREADING) + if (m_filename.Length() > 0ul) + { + RFs session; + + TInt result = session.Connect(); + if (result != KErrNone) + { + leave_trace_mutex(); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return; + } + + TInt err = m_LogFile.Open(session, m_filename, EFileWrite | EFileShareAny); + if (err != KErrNone) + { + session.Close(); + leave_trace_mutex(); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return; + } + m_logfile_open = true; + } + #endif //#if defined (USE_MULTITHREADING) + + + if (m_logfile_open == true) + { + // possible errors in the write because we can't do anything if + // for example disk is full. + TInt pos = 0; + + // Seek to the end of file for appending + m_LogFile.Seek(ESeekEnd, pos); + m_LogFile.Write(m_trace_buf); + // This flush crashed sometimes for an unknown reason... + m_LogFile.Flush(); + } + + #if defined (USE_MULTITHREADING) + if (m_logfile_open == true) + { + m_logfile_open = false; + m_LogFile.Close(); + } + session.Close(); + #endif //#if defined (USE_MULTITHREADING) + +#endif //#if defined(USE_EAP_FILE_TRACE) + + + leave_trace_mutex(); + +#endif //#if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS) + +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_tools_symbian_c::get_timer_queue_is_empty() +{ + return m_timer_queue.get_timer_queue_is_empty(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_tools_symbian_c::get_is_timer_thread_active() +{ + return m_run_thread; +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::set_trace_file_name( + const eap_variable_data_c * const trace_output_file) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(trace_output_file); + +#if defined(USE_EAP_FILE_TRACE) +#if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS) + TBuf8<64> tmpFilename((TUint8 *)trace_output_file->get_data(trace_output_file->get_data_length())); + tmpFilename.SetLength(trace_output_file->get_data_length()); + enter_trace_mutex(); + + m_filename.Copy(tmpFilename); + +#if defined (USE_MULTITHREADING) + TInt result = m_Fs.Connect(); + if (result != KErrNone) + { + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return convert_am_error_to_eapol_error(result); + } +#endif //#if defined (USE_MULTITHREADING) + + TInt err(KErrPathNotFound); + + if (m_filename.Length() > 0ul) + { + err = m_LogFile.Create(m_Fs, m_filename, EFileWrite | EFileShareAny); + if (err == KErrAlreadyExists) + { + err = m_LogFile.Open(m_Fs, m_filename, EFileWrite | EFileShareAny); + } + else if (err == KErrPathNotFound) + { +#if !defined(USE_EAP_HARDWARE_TRACE) + // No directory neither RDEBUG -> Disable traces + set_trace_mask(eap_am_tools_c::eap_trace_mask_none); +#endif //#if !defined(USE_EAP_HARDWARE_TRACE) + } + } + + if (err != KErrNone) + { + m_logfile_open = false; +#if defined (USE_MULTITHREADING) + m_Fs.Close(); +#endif //#if defined (USE_MULTITHREADING) + leave_trace_mutex(); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return convert_am_error_to_eapol_error(err); + } + else + { + // Trace file opened OK. + m_logfile_open = true; + } + +#if defined (USE_MULTITHREADING) + m_LogFile.Close(); + m_logfile_open = false; + m_Fs.Close(); +#endif //#if defined (USE_MULTITHREADING) + + leave_trace_mutex(); + +#endif //#if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS) +#endif //#if defined(USE_EAP_FILE_TRACE) + + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::set_max_trace_file_size(const u32_t max_trace_file_size) +{ +#if defined(USE_EAP_TRACE_FILE_MAX_SIZE) + m_max_trace_file_size = max_trace_file_size; +#else + EAP_UNREFERENCED_PARAMETER(max_trace_file_size); +#endif //#if defined(USE_EAP_TRACE_FILE_MAX_SIZE) +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::memmove(void *dest, const void *src, const u32_t count) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + Mem::Copy(dest, src, count); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT i32_t eap_am_tools_symbian_c::memcmp(const void * const dest, const void * const src, const u32_t count) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return Mem::Compare((const TUint8*)dest, count, (const TUint8*)src, count); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::memset(void * const src, const i32_t fill_byte, const u32_t count) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + Mem::Fill(src, count, fill_byte); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void *eap_am_tools_symbian_c::memchr( + const void *buf, + u8_t character, + u32_t count) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + + const u8_t * const tmp = reinterpret_cast(buf); + + for (u32_t ind = 0u; ind < count; ind++) + { + if (tmp[ind] == character) + { + return reinterpret_cast(const_cast(&(tmp[ind]))); + } + } + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + + return 0; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void *eap_am_tools_symbian_c::memrchr( + const void *buf, + u8_t character, + u32_t count) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + + const u8_t * const tmp = reinterpret_cast(buf); + + for (i32_t ind = count-1ul; ind >= 0; ind--) + { + if (tmp[ind] == character) + { + return reinterpret_cast(const_cast(&(tmp[ind]))); + } + } + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + + return 0; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_am_tools_symbian_c::strlen( + eap_const_string string) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + + u32_t count = config_strlen(string); + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return count; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eap_am_tools_symbian_c::config_strlen( + eap_config_string string) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + u32_t count = 0; + const u8_t *tmp = reinterpret_cast(string); + while((*tmp) != 0) + { + tmp++; + count++; + } + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return count; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT abs_eap_am_crypto_c * eap_am_tools_symbian_c::get_crypto() +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return &m_crypto; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u64_t eap_am_tools_symbian_c::get_hardware_ticks() +{ + return get_clock_ticks(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u64_t eap_am_tools_symbian_c::get_hardware_ticks_of_second() +{ + return get_clock_ticks_of_second(); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u64_t eap_am_tools_symbian_c::get_clock_ticks() +{ + #if defined(__SYMBIAN32__) + TTime time; + time.UniversalTime(); + return *(reinterpret_cast(&time)); + #else + #error get_clock_ticks() not supported, please do something + #endif +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u64_t eap_am_tools_symbian_c::get_clock_ticks_of_second() +{ + return 1000000u; +} + +//-------------------------------------------------- + +/** + * This function adds EAP timer to queue and sets the platform specific timer for first timer in the queue. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::am_set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + + if (get_use_timer_queue() == false) + { + // We do not need timers. + initializer->timer_delete_data(id, data); + + EAP_TRACE_DEBUG(this, TRACE_FLAGS_TIMER, (EAPL("end am_set_timer().\n"))); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_not_supported); + } + else + { + const eap_status_e status = m_timer_queue.set_timer( + initializer, + id, + data, + p_time_ms); + + if (IsActive()) + { + // This call cancels the current symbian timer. + // We will start new symbian timer with new + // timeout read from timer queue. + Cancel(); + } + + u64_t currentTime = get_clock_ticks(); + u32_t tics_of_millisecond = static_cast(get_hardware_ticks_of_second())/1000ul; + u32_t spend_time = static_cast(currentTime - iLastTime)/tics_of_millisecond; + + iLastTime = currentTime; + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_TIMER, + (EAPL("eap_status_e eap_am_tools_symbian_c::am_set_timer(): pulse_timer(%d ms).\n"), + spend_time)); + + u32_t next_timeout_milliseconds = m_timer_queue.pulse_timer(spend_time, false); + + After(limit_microsecond_timeout(next_timeout_milliseconds)); + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_TIMER, + (EAPL("end eap_am_tools_symbian_c::am_set_timer(): After(%d millisecond).\n"), + next_timeout_milliseconds)); + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::am_cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id) +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + + if (get_use_timer_queue() == false) + { + // We do not need timers. + EAP_TRACE_DEBUG(this, TRACE_FLAGS_TIMER, (EAPL("end am_cancel_timer().\n"))); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_not_supported); + } + else + { + const eap_status_e status = m_timer_queue.cancel_timer(initializer, id); + + EAP_TRACE_DEBUG(this, TRACE_FLAGS_TIMER, (EAPL("end am_cancel_timer().\n"))); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return status; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::am_cancel_all_timers() +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(this, TRACE_FLAGS_TIMER, (EAPL("begin am_cancel_all_timers().\n"))); + + if (get_use_timer_queue() == false) + { + // We do not need timers. + EAP_TRACE_DEBUG(this, TRACE_FLAGS_TIMER, (EAPL("end am_cancel_all_timers().\n"))); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, eap_status_not_supported); + } + else + { + enter_global_mutex(); + const eap_status_e status = m_timer_queue.cancel_all_timers(); + leave_global_mutex(); + + EAP_TRACE_DEBUG(this, TRACE_FLAGS_TIMER, (EAPL("end am_cancel_all_timers().\n"))); + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return status; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::re_activate_timer_queue() +{ + EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("re_activate_timer_queue().\n"))); + + const eap_status_e status = m_timer_queue.re_activate_timer_queue(); + + EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(this, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::enter_crypto_cs() +{ + +} + +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::leave_crypto_cs() +{ + +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::timer_sleep(u32_t milli_seconds) +{ + sleep(milli_seconds); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_tools_symbian_c::sleep(u32_t milli_seconds) +{ + User::After(limit_microsecond_timeout(milli_seconds)); +} + +//-------------------------------------------------- +EAP_FUNC_EXPORT u32_t eap_am_tools_symbian_c::get_gmt_unix_time() +{ + _LIT(KStart, "19700000:000000.000000"); + TTime start(KStart); + TTime now; + now.UniversalTime(); + TTimeIntervalSeconds interval; + now.SecondsFrom(start, interval); + return interval.Int(); +} +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_am_tools_symbian_c::get_is_valid() const +{ + return m_is_valid; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::convert_am_error_to_eapol_error(const i32_t aErr) +{ + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_tools_symbian_c::convert_am_error_to_eapol_error: error=%d\n"), + aErr)); + + eap_status_e status; + switch (aErr) + { + case KErrNone: + status = eap_status_ok; + break; + + case KErrNoMemory: + status = eap_status_allocation_error; + break; + + case KErrNotSupported: + status = eap_status_not_supported; + break; + + case KErrBadHandle: + status = eap_status_illegal_handle; + break; + + case KErrCompletion: + status = eap_status_pending_request; + break; + + case KErrNotFound: + status = eap_status_illegal_configure_field; + break; + + case KErrGeneral: + case KErrUnknown: + case KErrCancel: + case KErrArgument: + case KErrTotalLossOfPrecision: + case KErrOverflow: + case KErrUnderflow: + case KErrAlreadyExists: + case KErrPathNotFound: + case KErrDied: + case KErrInUse: + case KErrServerTerminated: + case KErrServerBusy: + case KErrNotReady: + case KErrCorrupt: + case KErrAccessDenied: + case KErrLocked: + case KErrWrite: + case KErrDisMounted: + case KErrEof: + case KErrDiskFull: + case KErrBadDriver: + case KErrBadName: + case KErrCommsLineFail: + case KErrCommsFrame: + case KErrCommsOverrun: + case KErrCommsParity: + case KErrTimedOut: + case KErrCouldNotConnect: + case KErrCouldNotDisconnect: + case KErrDisconnected: + case KErrBadLibraryEntryPoint: + case KErrBadDescriptor: + case KErrAbort: + case KErrTooBig: + case KErrDivideByZero: + case KErrBadPower: + case KErrDirFull: + case KErrHardwareNotAvailable: + default: + status = eap_status_process_general_error; + break; + } + return status; +} + +EAP_FUNC_EXPORT i32_t eap_am_tools_symbian_c::convert_eapol_error_to_am_error(eap_status_e aErr) +{ + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_tools_symbian_c::convert_am_error_to_eapol_error: error=%d\n"), + aErr)); + + TInt status; + switch (aErr) + { + case eap_status_ok: + case eap_status_success: + status = KErrNone; + break; + + case eap_status_allocation_error: + status = KErrNoMemory; + break; + + case eap_status_not_supported: + status = KErrNotSupported; + break; + + + case eap_status_illegal_handle: + status = KErrBadHandle; + break; + + case eap_status_pending_request: + status = KErrCompletion; + break; + + case eap_status_illegal_configure_field: + status = KErrNotFound; + break; + + case eap_status_completed_request: + case eap_status_drop_packet_quietly: + case eap_status_process_general_error: + case eap_status_type_does_not_exists_error: + case eap_status_process_illegal_packet_error: + case eap_status_ethernet_type_not_supported: + case eap_status_illegal_eap_code: + case eap_status_illegal_eap_type: + case eap_status_illegal_eap_identity: + case eap_status_authentication_failure: + case eap_status_encryption_failure: + case eap_status_illegal_padding: + case eap_status_randomize_failure: + case eap_status_handler_exists_error: + case eap_status_handler_does_not_exists_error: + case eap_status_wrong_sae_state: + case eap_status_wrong_eapol_version: + case eap_status_wrong_eapol_type: + case eap_status_header_corrupted: + case eap_status_wrong_sae_sequence_number: + case eap_status_wrong_isakmp_header_version: + case eap_status_wrong_isakmp_exchange_type: + case eap_status_wrong_isakmp_flags: + case eap_status_wrong_isakmp_message_id: + case eap_status_wrong_isakmp_cookie: + case eap_status_unsupported_isakmp_payload: + case eap_status_key_error: + case eap_status_too_many_offers: + case eap_status_send_failed: + case eap_status_data_length_not_aligned_to_block_size: + case eap_status_wrong_network_id: + case eap_status_wrong_sae_header_version: + case eap_status_wrong_sae_exchange_type: + case eap_status_wrong_sae_flags: + case eap_status_unsupported_sae_payload: + case eap_status_wrong_sae_cookie: + case eap_status_illegal_encryption_parameter_size: + case eap_status_state_reference_count_not_zero: + case eap_status_illegal_nai: + case eap_status_illegal_nai_payload: + case eap_status_illegal_data_payload: + case eap_status_illegal_payload: + case eap_status_illegal_hashed_index: + case eap_status_wrong_gsmsim_state: + case eap_status_unsupported_gsmsim_payload: + case eap_status_gsmsim_triplet_query_failed: + case eap_status_illegal_index: + case eap_status_timed_out: + case eap_status_wrong_eap_subtype: + case eap_status_exit_test: + case eap_status_no_matching_protocol_version: + default: + status = KErrGeneral; + break; + } + + return status; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::begin_db_transaction(RDbNamedDatabase& aDatabase) +{ + TUint retries(0); + TInt result; + eap_status_e status(eap_status_access_denied); + + if (aDatabase.InTransaction()) + { + // Previous database operation failed + aDatabase.Rollback(); + } + + // Seed the PRNG with time + TTime now; + now.HomeTime(); + TInt64 seed = now.Int64(); + TInt randomWait; + + // Try to begin transaction MAX_DB_TRANSACTION_RETRY_COUNT times + while (retries < MAX_DB_TRANSACTION_RETRY_COUNT) + { + result = aDatabase.Begin(); + if (result == KErrNone) + { + // We got read lock to database! + status = eap_status_ok; + break; + } + EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("begin_db_transaction(): database locked.\n"))); + retries++; + randomWait = Math::Rand(seed); + + // Wait 0 - 524287 microseconds + randomWait = randomWait & 0x7ffff; + User::After(randomWait); + } + return EAP_STATUS_RETURN(this, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::begin_db_update(RDbView& aView) +{ + TUint retries(0); + eap_status_e status(eap_status_access_denied); + + // Seed the PRNG with time + TTime now; + now.HomeTime(); + TInt64 seed = now.Int64(); + + TInt randomWait; + TInt err; + // Try to begin transaction MAX_DB_TRANSACTION_RETRY_COUNT times + while (retries < MAX_DB_TRANSACTION_RETRY_COUNT) + { + TRAP(err, aView.UpdateL()); + if (err == KErrNone) + { + // We got write lock to database! + status = eap_status_ok; + break; + } + EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("begin_db_update(): database locked.\n"))); + retries++; + randomWait = Math::Rand(seed); + + // Wait 0 - 524287 microseconds + randomWait = randomWait & 0x7ffff; + User::After(randomWait); + } + return EAP_STATUS_RETURN(this, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::begin_db_delete(RDbView& aView) +{ + TUint retries(0); + eap_status_e status(eap_status_access_denied); + + // Seed the PRNG with time + TTime now; + now.HomeTime(); + TInt64 seed = now.Int64(); + + TInt randomWait; + TInt err; + // Try to begin transaction MAX_DB_TRANSACTION_RETRY_COUNT times + while (retries < MAX_DB_TRANSACTION_RETRY_COUNT) + { + TRAP(err, aView.DeleteL()); + if (err == KErrNone) + { + // We got write lock to database! + status = eap_status_ok; + break; + } + EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("begin_db_delete(): database locked.\n"))); + retries++; + randomWait = Math::Rand(seed); + + // Wait 0 - 524287 microseconds + randomWait = randomWait & 0x7ffff; + User::After(randomWait); + } + return EAP_STATUS_RETURN(this, status); +} + +//-------------------------------------------------- + +/// This function must call eap_am_tools_c::shutdown_am_tools(). +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::shutdown() +{ + EAP_TRACE_ALWAYS( + this, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_tools_symbian_c::shutdown(): this = 0x%08x => 0x%08x, "), + this, + dynamic_cast(this))); + + StopTimer(); + + return eap_am_tools_c::shutdown_am_tools(); +} + +//-------------------------------------------------- + +/// This function converts unicode string to UTF8 string. +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::convert_unicode_to_utf8( + eap_variable_data_c & dest, + const eap_variable_data_c & src) +{ + eap_status_e status = eap_status_allocation_error; + + HBufC8* outputBuffer = NULL; + // src is unicode string, length = size / 2, one utf8 char takes 1...6 bytes + TRAPD(err, outputBuffer = HBufC8::NewL((src.get_data_length() / 2) * 6)) + if (err != KErrNone) + { + status = convert_am_error_to_eapol_error(err); + return EAP_STATUS_RETURN(this, status); + } + + const TPtrC16 unicode( + reinterpret_cast(src.get_data(src.get_data_length())), + src.get_data_length() / 2); // Length in unicode characters + + TPtr8 utf8 = outputBuffer->Des(); + + CnvUtfConverter::ConvertFromUnicodeToUtf8(utf8, unicode); + + status = dest.set_copy_of_buffer(outputBuffer->Ptr(), outputBuffer->Length()); + + delete outputBuffer; + + return EAP_STATUS_RETURN(this, status); +} + +//-------------------------------------------------- + +/// This function converts UTF8 string to unicode string. +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::convert_utf8_to_unicode( + eap_variable_data_c & dest, + const eap_variable_data_c & src) +{ + eap_status_e status = eap_status_allocation_error; + + HBufC16* outputBuffer = NULL; + // src is UTF8 string, unicode max length is then the length of UTF8 string. + // NOTE, HBufC16 length means count of 16-bit objects. + TRAPD(err, outputBuffer = HBufC16::NewL(src.get_data_length())) + if (err != KErrNone) + { + status = convert_am_error_to_eapol_error(err); + return EAP_STATUS_RETURN(this, status); + } + + const TPtrC8 utf8( + (src.get_data(src.get_data_length())), + src.get_data_length()); // Length in bytes + + TPtr16 unicode = outputBuffer->Des(); + + CnvUtfConverter::ConvertToUnicodeFromUtf8(unicode, utf8); + + status = dest.set_copy_of_buffer(outputBuffer->Ptr(), outputBuffer->Size()); + + delete outputBuffer; + + return EAP_STATUS_RETURN(this, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_tools_symbian_c::getenv( + const eap_variable_data_c * const /* environment_variable_name */, + eap_variable_data_c * const /* environment_variable_value */) +{ + return eap_status_not_supported; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_am_tools_symbian_c::isspace(const u8_t character) +{ + if (character >= 0x09 && character <= 0x0D + || character == 0x20) + { + return true; + } + else + { + return false; + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u64_struct eap_am_tools_symbian_c::u64_t_to_u64_struct(const u64_t value) +{ + return *reinterpret_cast(&value); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT u64_t eap_am_tools_symbian_c::u64_struct_to_u64_t(const u64_struct value) +{ + return *reinterpret_cast(&value); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +void eap_am_tools_symbian_c::StartTimer(const TUint aInterval) +{ + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_TIMER, + (EAPL("eap_am_tools_symbian_c::StartTimer().\n"))); + + iInterval = aInterval; + iStartTime = get_clock_ticks(); + + iLastTime = iStartTime; + + // Start the timer + After(limit_microsecond_timeout(iInterval)); +} + +//-------------------------------------------------- + +void eap_am_tools_symbian_c::StopTimer() +{ + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_TIMER, + (EAPL("eap_am_tools_symbian_c::StopTimer().\n"))); + + Cancel(); +} + +//-------------------------------------------------- + +TBool eap_am_tools_symbian_c::TimerRunning() +{ + if (!IsActive()) + { + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_TIMER, + (EAPL("eap_am_tools_symbian_c::TimerRunning(): EFalse.\n"))); + + return EFalse; + } + else + { + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_TIMER, + (EAPL("eap_am_tools_symbian_c::TimerRunning(): ETrue.\n"))); + + return ETrue; + } +} + +//-------------------------------------------------- + +u32_t eap_am_tools_symbian_c::limit_microsecond_timeout(u32_t next_timeout_millisecond) +{ + if (next_timeout_millisecond > EAP_TIMER_MAX_AFTER_TIME_MILLISECONDS_SYMBIAN) + { + next_timeout_millisecond = EAP_TIMER_MAX_AFTER_TIME_MILLISECONDS_SYMBIAN; + } + + u32_t next_timeout_microsecond = next_timeout_millisecond * 1000ul; + + return (next_timeout_microsecond); +} + +//-------------------------------------------------- + +void eap_am_tools_symbian_c::RunL() +{ + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_TIMER, + (EAPL("eap_am_tools_symbian_c::RunL().\n"))); + + u32_t next_timeout_milliseconds = iInterval; + + enter_global_mutex(); + if (get_is_timer_thread_active()) + { + u64_t currentTime = get_clock_ticks(); + u32_t tics_of_millisecond = static_cast(get_hardware_ticks_of_second())/1000ul; + u32_t spend_time = static_cast(currentTime - iLastTime)/tics_of_millisecond; + + iLastTime = currentTime; + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_TIMER, + (EAPL("eap_am_tools_symbian_c::RunL(): pulse_timer(%d ms).\n"), + spend_time)); + + next_timeout_milliseconds = m_timer_queue.pulse_timer(spend_time, true); + } + leave_global_mutex(); + + // Setup timer again (if somebody inside pulse_timer has not already done it...) + if (!IsActive()) + { + After(limit_microsecond_timeout(next_timeout_milliseconds)); + + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_TIMER, + (EAPL("eap_am_tools_symbian_c::RunL(): After(%d millisecond).\n"), + next_timeout_milliseconds)); + } + else + { + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_TIMER, + (EAPL("eap_am_tools_symbian_c::RunL(): is active.\n"))); + } +} + +//-------------------------------------------------- + +void eap_am_tools_symbian_c::DoCancel() +{ + EAP_TRACE_DEBUG( + this, + TRACE_FLAGS_TIMER, + (EAPL("eap_am_tools_symbian_c::DoCancel().\n"))); + + // Base class + CTimer::DoCancel(); +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT_INTERFACE abs_eap_am_tools_c * abs_eap_am_tools_c::new_abs_eap_am_tools_c() +{ + abs_eap_am_tools_c *am_tools = new eap_am_tools_symbian_c(EAP_DEFAULT_TRACE_FILE); + + if (am_tools != 0) + { + eap_status_e status = am_tools->configure(); + + if (status != eap_status_ok) + { + abs_eap_am_tools_c::delete_abs_eap_am_tools_c(am_tools); + am_tools = 0; + } + else + { + EAP_TRACE_DEBUG( + am_tools, + TRACE_FLAGS_TIMER, + (EAPL("abs_eap_am_tools_c::new_abs_eap_am_tools_c() => 0x%08x success\n"), + am_tools)); + } + } + + return am_tools; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT_INTERFACE void abs_eap_am_tools_c::delete_abs_eap_am_tools_c(abs_eap_am_tools_c * const am_tools) +{ + EAP_TRACE_DEBUG( + am_tools, + TRACE_FLAGS_TIMER, + (EAPL("abs_eap_am_tools_c::delete_abs_eap_am_tools_c(0x%08x)\n"), + am_tools)); + + (void)am_tools->shutdown(); + + delete am_tools; +} + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + + + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_trace_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_trace_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,250 @@ +/* +* Copyright (c) 2001-2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#if defined(_DEBUG) || defined(DEBUG) + +#include "eap_am_trace_symbian.h" + +const TInt KMaxBufferSize = 256; + +u8_t octet_to_ascii(i32_t octet) +{ + if (0 <= octet && octet <= 9) + { + return static_cast('0' + octet); + } + else if (10 <= octet && octet <= 16) + { + return static_cast('a' + (octet-10u)); + } + else + { + return 0; + } +} + +void formatted_print(eap_format_string format, ...) +{ + EAP_UNREFERENCED_PARAMETER(format); + +#if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS) + + HBufC8* args_buf = NULL; + HBufC8* format_buf = NULL; + HBufC8* trace_buf = NULL; + HBufC16* trace_buf_16 = NULL; + + TRAPD(error, + args_buf= HBufC8::NewL(KMaxBufferSize); + format_buf= HBufC8::NewL(KMaxBufferSize); + trace_buf= HBufC8::NewL(KMaxBufferSize); + trace_buf_16= HBufC16::NewL(KMaxBufferSize); ); + + if(error != KErrNone) + { + // Not enough memory. + RDebug::Print(_L("formatted_print: ERROR - Not enough Memory!\n")); + + delete args_buf; + delete format_buf; + delete trace_buf; + delete trace_buf_16; + + return; + } + + TPtr8 m_args_buf = args_buf->Des(); + TPtr8 m_format_buf = format_buf->Des(); + TPtr8 m_trace_buf = trace_buf->Des(); + TPtr16 m_trace_buf_16 = trace_buf_16->Des(); + + VA_LIST args; + VA_START(args, format); + m_format_buf.Copy((const TUint8 *)format); + + m_args_buf.FormatList(m_format_buf, args); + m_trace_buf.Append(m_args_buf); + VA_END(args); + +#if defined(USE_EAP_HARDWARE_TRACE) + + { + #if !defined(USE_EAP_HARDWARE_TRACE_RAW_PRINT) + { + TInt length = m_trace_buf.Length(); + if (length >= 2ul) + { + --length; + const TUint8 *last_char = m_trace_buf.Ptr() + length; + + if (last_char != 0 + && *last_char == '\n') + { + // This removes the ending new line character. + // formatted_print() will write new line automatically. + m_trace_buf.SetLength(length); + } + } + } + #endif //#if !defined(USE_EAP_HARDWARE_TRACE_RAW_PRINT) + + m_trace_buf_16.Copy(m_trace_buf); + + #if defined(USE_EAP_HARDWARE_TRACE_RAW_PRINT) + RDebug::RawPrint(m_trace_buf_16); + #else + formatted_print(_L("%S"), &m_trace_buf_16); + #endif //#if defined(USE_EAP_HARDWARE_TRACE_RAW_PRINT) + } + +#endif //#if defined(USE_EAP_HARDWARE_TRACE) + + delete args_buf; + delete format_buf; + delete trace_buf; + delete trace_buf_16; + +#endif //#if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS) + +} + + +void trace_data( + eap_const_string prefix, + const void * const p_data, + const u32_t data_length) +{ + + u8_t* m_tmp_buffer = NULL; + u8_t* m_tmp_ascii_buffer = NULL; + + m_tmp_buffer = new u8_t[KMaxBufferSize]; + m_tmp_ascii_buffer = new u8_t[KMaxBufferSize]; + + if( m_tmp_buffer == NULL || m_tmp_ascii_buffer == NULL) + { + // Not enough memory. + RDebug::Print(_L("trace_data: ERROR - Not enough Memory!\n")); + + delete [] m_tmp_buffer; + delete [] m_tmp_ascii_buffer; + + return; + } + + u8_t *cursor = m_tmp_buffer; + u8_t *cursor_ascii = m_tmp_ascii_buffer; + + const u8_t *data = reinterpret_cast(p_data); + u32_t ind; + bool must_print = false; + u32_t data_start = 0u; + + const u32_t EAP_DATA_TRACE_BYTE_GROUP_SIZE = 1; + u32_t byte_group_size = EAP_DATA_TRACE_BYTE_GROUP_SIZE; + +#if !defined(USE_EAP_DEBUG_TRACE) + // This does not trace the pointer of the data. + formatted_print( + "%s: data: %d (0x%x) bytes\n", + prefix, + data_length, + data_length); +#else + formatted_print( + "%s: data 0x%08x: %d (0x%x) bytes\n", + prefix, + p_data, + data_length, + data_length); +#endif + + if (p_data == 0) + { + delete [] m_tmp_buffer; + delete [] m_tmp_ascii_buffer; + + return; + } + + for (ind = 0u; ind < data_length; ind++) + { + if ((cursor-m_tmp_buffer)+5u >= KMaxBufferSize) + { + must_print = true; + formatted_print( + "ERROR: eap_am_tools_c::trace_data local buffer (%d bytes) too small.\n", + KMaxBufferSize); + break; + } + + + if (ind > 0u + && (ind % 16) == 0) + { + *cursor++ = 0; + *cursor_ascii++ = 0; + + formatted_print( + "%s: 0x%04x: %-48s |%-16s|\n", + prefix, + data_start, + m_tmp_buffer, + m_tmp_ascii_buffer); + + cursor = m_tmp_buffer; + cursor_ascii = m_tmp_ascii_buffer; + must_print = false; + data_start = ind; + } + + *cursor_ascii++ = (*data >= 32 && *data < 128) ? *data : '.'; + + *cursor++ = octet_to_ascii(((*data) & 0xf0) >> 4); + *cursor++ = octet_to_ascii(((*data) & 0x0f)); + data++; + + if (ind > 0u + && ((ind+1) % byte_group_size) == 0 + || byte_group_size == 1ul) + { + *cursor++ = ' '; + } + + must_print = true; + } + + if (must_print == true) + { + *cursor++ = 0; + *cursor_ascii = 0; + formatted_print( + "%s: 0x%04x: %-48s |%-16s|\n", + prefix, + data_start, + m_tmp_buffer, + m_tmp_ascii_buffer); + } + + delete [] m_tmp_buffer; + delete [] m_tmp_ascii_buffer; +} + +#endif + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/core/symbian/Eapol.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/core/symbian/Eapol.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,155 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 153 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include +#include "eap_am_memory.h" +#include +#include "eapol_am_core_symbian.h" + +//-------------------------------------------------- + +// + +CEapol::~CEapol() +{ + delete iEapolCore; +} + +//-------------------------------------------------- + +// + +CEapol::CEapol() +: iEapolCore(0) +{ +} + +//-------------------------------------------------- + +// + +EXPORT_C CEapol* CEapol::NewL(MEapolToWlmIf* const aPartner, const TBool aIsClient, const TUint aServerIndex) +{ + CEapol* self = new(ELeave) CEapol; + CleanupStack::PushL(self); + self->ConstructL(aPartner, aIsClient, aServerIndex); + CleanupStack::Pop(); + return self; +} + +//-------------------------------------------------- + +// + +void CEapol::ConstructL(MEapolToWlmIf* const aPartner, + const TBool aIsClient, + const TUint aServerIndex) +{ + if (aIsClient) + { + iEapolCore = eapol_am_core_symbian_c::NewL(aPartner, true, aServerIndex); + } + else + { + iEapolCore = eapol_am_core_symbian_c::NewL(aPartner, false, aServerIndex); + } +} + +//-------------------------------------------------- + +// + +EXPORT_C TInt CEapol::Start(const TIndexType aIndexType, + const TUint aIndex, + const TSSID& aSSID, + const TBool aWPAOverrideEnabled, + const TUint8* aWPAPSK, + const TUint aWPAPSKLength) +{ + return iEapolCore->Start(aIndexType, aIndex, aSSID, aWPAOverrideEnabled, aWPAPSK, aWPAPSKLength); +} + +//-------------------------------------------------- + +// + +EXPORT_C TInt CEapol::CompleteAssociation( + const TInt aResult, + const TMacAddress& aLocalAddress, + const TMacAddress& aRemoteAddress, + const TUint8* const aReceivedWPAIE, + const TUint aReceivedWPAIELength, + const TUint8* const aSentWPAIE, + const TUint aSentWPAIELength, + const TWPACipherSuite aGroupKeyCipherSuite, + const TWPACipherSuite aPairwiseKeyCipherSuite + ) +{ + return iEapolCore->CompleteAssociation( + aResult, + aLocalAddress, + aRemoteAddress, + aReceivedWPAIE, + aReceivedWPAIELength, + aSentWPAIE, + aSentWPAIELength, + aGroupKeyCipherSuite, + aPairwiseKeyCipherSuite + ); +} + +//-------------------------------------------------- + +// + +EXPORT_C TInt CEapol::Disassociated() +{ + return iEapolCore->Disassociated(); +} + +//-------------------------------------------------- + +// + +EXPORT_C TInt CEapol::ReceivePacket(const TUint aLength, const TUint8* const aData) +{ + return iEapolCore->ReceivePacket(aLength, aData); +} + +//-------------------------------------------------- + +// + +EXPORT_C TInt CEapol::SendWPAMICFailureReport( + TBool aFatalMICFailure, + const TMICFailureType aMICFailureType) +{ + return iEapolCore->SendWPAMICFailureReport(aFatalMICFailure, aMICFailureType); +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/core/symbian/EapolTimer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/core/symbian/EapolTimer.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,181 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 164 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include "eap_am_memory.h" +#include "EapolTimer.h" +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "abs_eap_am_tools.h" +#include "abs_eap_am_mutex.h" +#include "eap_am_tools_symbian.h" + +// ================= MEMBER FUNCTIONS ======================= + +CEapolTimer::CEapolTimer(abs_eap_am_tools_c * const aTools) +: CTimer(CTimer::EPriorityStandard) +, iTools(aTools) +{ + // Set a flag in EAPOL that specifies that timer queue can be used. + reinterpret_cast(iTools)->set_use_timer_queue(); +} + + +//-------------------------------------------------- + +void CEapolTimer::ConstructL() +{ + CTimer::ConstructL(); +} + +//-------------------------------------------------- + +CEapolTimer* CEapolTimer::NewL(abs_eap_am_tools_c * const aTools) +{ + CEapolTimer* self = new (ELeave) CEapolTimer(aTools); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; +} + +//-------------------------------------------------- + +CEapolTimer::~CEapolTimer() +{ + Cancel(); +} + +//-------------------------------------------------- + +void CEapolTimer::StartTimer(const TUint aInterval) +{ + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapolTimer::StartTimer().\n"))); + + iInterval = aInterval; + iStartTime = iTools->get_clock_ticks(); + + iLastTime = iStartTime; + + // Start the timer + After(iInterval*1000); +} + +//-------------------------------------------------- +void CEapolTimer::StopTimer() +{ + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapolTimer::StopTimer().\n"))); + + Cancel(); +} +//-------------------------------------------------- + +TBool CEapolTimer::TimerRunning() +{ + if (!IsActive()) + { + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapolTimer::TimerRunning(): EFalse.\n"))); + + return EFalse; + } + else + { + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapolTimer::TimerRunning(): ETrue.\n"))); + + return ETrue; + } +} + +void CEapolTimer::RunL() +{ + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapolTimer::RunL().\n"))); + + u64_t currentTime = iTools->get_clock_ticks(); + + iLastTime = currentTime; + + u32_t next_sleep_time = iInterval; + + iTools->enter_global_mutex(); + if (iTools->get_is_timer_thread_active()) + { + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapolTimer::RunL(): pulse_timer().\n"))); + + next_sleep_time = iTools->pulse_timer(next_sleep_time); + } + iTools->leave_global_mutex(); + + // Setup timer again (if somebody inside pulse_timer has not already done it...) + if (!IsActive()) + { + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapolTimer::RunL(): After().\n"))); + + After(next_sleep_time*1000); + } + else + { + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapolTimer::RunL(): is active.\n"))); + } +} +//-------------------------------------------------- + +void CEapolTimer::DoCancel() +{ + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapolTimer::DoCancel().\n"))); + + // Base class + CTimer::DoCancel(); +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/core/symbian/eapol_am_core_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/core/symbian/eapol_am_core_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3978 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 148 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "eap_am_memory.h" + +#include "eap_variable_data.h" +#include "eap_tools.h" +#include "eap_type_all.h" + +#include "eapol_am_core_symbian.h" +#include "eapol_ethernet_header.h" +#include "ethernet_core.h" +#include "eap_am_tools_symbian.h" +#include +#include "EapolDbDefaults.h" +#include "EapolDbParameterNames.h" +#include "eap_crypto_api.h" +#include "eap_header_string.h" +#include "eap_am_file_input_symbian.h" +#include "eap_rogue_ap_entry.h" +#include "abs_eap_state_notification.h" +#include "eapol_session_key.h" +#include "eap_buffer.h" +#include "eap_config.h" + +#if defined(USE_EAP_FILECONFIG) + #include "eap_file_config.h" +#endif //#if defined(USE_EAP_FILECONFIG) + +#if defined (USE_EAPOL_KEY_STATE) + #include "eapol_key_state.h" +#endif + +// LOCAL CONSTANTS +const TUint KMaxSqlQueryLength = 2048; +const TUint KMaxConfigStringLength = 256; +const u32_t KMTU = 1500u; +const u32_t KTrailerLength = 0; +const u32_t KHeaderOffset = 0; +const TUint KMaxEapCueLength = 3; + +enum eapol_am_core_timer_id_e +{ + EAPOL_AM_CORE_TIMER_RESTART_AUTHENTICATION_ID, + EAPOL_AM_CORE_TIMER_DELETE_STACK_ID, + EAPOL_AM_CORE_TIMER_FAILED_COMPLETELY_ID, +}; + + +const TUint8 TEST_RSN_IE[] = +{ + 0xdd, // information element id, 221 expressed as Hex value + 0x14, // length in octets, 20 expressed as Hex value + 0x01, 0x00, // Version 1 + 0x00, 0x0f, 0xac, 0x04, // CCMP as group key cipher suite + 0x01, 0x00, // pairwise key cipher suite count + 0x00, 0x0f, 0xac, 0x04, // CCMP as pairwise key cipher suite + 0x01, 0x00, // authentication count + 0x00, 0x0f, 0xac, 0x01, // 802.1X authentication + 0x01, 0x00, // Pre-authentication capabilities +}; + +// ================= MEMBER FUNCTIONS ======================= + +eapol_am_core_symbian_c::eapol_am_core_symbian_c(MEapolToWlmIf * const aPartner, + const bool is_client_when_true, + const TUint aServerIndex) +: CActive(CActive::EPriorityStandard) +, m_partner(aPartner) +, m_ethernet_core(0) +, m_am_tools(0) +, m_enable_random_errors(false) +, m_error_probability(0u) +, m_generate_multiple_error_packets(0u) +, m_authentication_counter(0u) +, m_successful_authentications(0u) +, m_failed_authentications(0u) +, m_is_valid(false) +, m_is_client(is_client_when_true) +, m_eap_index(0u) +, m_index_type(ELan) +, m_index(aServerIndex) +//, m_timer(0) +, m_packet_index(0) +, m_manipulate_ethernet_header(false) +, m_send_original_packet_first(false) +, m_authentication_indication_sent(false) +, m_unicast_wep_key_received(false) +, m_broadcast_wep_key_received(false) +, m_block_packet_sends_and_notifications(false) +, m_success_indication_sent(false) +, m_first_authentication(true) +, m_self_disassociated(false) +, m_802_11_authentication_mode(EAuthModeOpen) +, m_receive_network_id(0) +, m_wpa_override_enabled(false) +, m_wpa_psk_mode_allowed(false) +, m_wpa_psk_mode_active(false) +, m_stack_marked_to_be_deleted(false) +, m_active_type_is_leap(false) +, m_fileconfig(0) +{ +} + +//-------------------------------------------------- + +void eapol_am_core_symbian_c::ConstructL() +{ + if (m_partner == 0) + { + User::Leave(KErrGeneral); + } + + // Create tools class + m_am_tools = new(ELeave) eap_am_tools_symbian_c(EAP_DEFAULT_TRACE_FILE); + if (m_am_tools->get_is_valid() != true) + { + // The real reason most likely is KErrNoMemory but since that is not sure we'll use KErrGeneral + User::Leave(KErrGeneral); + } + if (m_am_tools->configure() != eap_status_ok) + { + User::Leave(KErrGeneral); + } + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL INITIALISATION\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("====================\n"))); + + m_wpa_preshared_key = new (ELeave) eap_variable_data_c(m_am_tools); + + m_ssid = new (ELeave) eap_variable_data_c(m_am_tools); + + m_wpa_psk_password_override = new (ELeave) eap_variable_data_c(m_am_tools); + + // Create/initialise the database + OpenDatabaseL(m_database, m_session); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Database initialized...\n"))); + +#if defined(USE_EAP_FILECONFIG) + + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Initialize file configuration.\n"))); + eap_am_file_input_symbian_c fileio(m_am_tools); + + eap_variable_data_c file_name_c_data(m_am_tools); + + eap_status_e status(eap_status_process_general_error); + + { + eap_const_string const FILECONFIG_FILENAME_C + = "c:\\system\\data\\eap.conf"; + + status = file_name_c_data.set_copy_of_buffer( + FILECONFIG_FILENAME_C, + m_am_tools->strlen(FILECONFIG_FILENAME_C)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + status = file_name_c_data.add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + + eap_variable_data_c file_name_z_data(m_am_tools); + + { + eap_const_string const FILECONFIG_FILENAME_Z + = "z:\\private\\101F8EC5\\eap.conf"; + + status = file_name_z_data.set_copy_of_buffer( + FILECONFIG_FILENAME_Z, + m_am_tools->strlen(FILECONFIG_FILENAME_Z)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + status = file_name_z_data.add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + + if (status == eap_status_ok) + { + // First try open from C: disk. + status = fileio.file_open( + &file_name_c_data, + eap_file_io_direction_read); + if (status == eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Opens configure file %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + else if (status != eap_status_ok) + { + // Second try open from Z: disk. + status = fileio.file_open( + &file_name_z_data, + eap_file_io_direction_read); + if (status == eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Opens configure file %s\n"), + file_name_z_data.get_data(file_name_z_data.get_data_length()))); + } + } + + if (status == eap_status_ok) + { + // Some of the files were opened. + + m_fileconfig = new eap_file_config_c(m_am_tools); + if (m_fileconfig != 0 + && m_fileconfig->get_is_valid() == true) + { + status = m_fileconfig->configure(&fileio); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Configure read from %s failed.\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Configure read from %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + } + else + { + // No file configuration. + delete m_fileconfig; + m_fileconfig = 0; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Cannot create configure object for file %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Cannot open configure file neither %s nor %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()), + file_name_z_data.get_data(file_name_z_data.get_data_length()))); + } + } + } + +#endif //#if defined(USE_EAP_FILECONFIG) + +#if !defined(USE_EAP_HARDWARE_TRACE) + { + // Disable traces. + m_am_tools->set_trace_mask(eap_am_tools_c::eap_trace_mask_none); + + eap_variable_data_c trace_output_file(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_output_file_name.get_field(), + &trace_output_file); + if (status == eap_status_ok + && trace_output_file.get_is_valid_data() == true) + { + status = m_am_tools->set_trace_file_name(&trace_output_file); + if (status == eap_status_ok) + { + // OK, set the default trace mask. + m_am_tools->set_trace_mask( + eap_am_tools_c::eap_trace_mask_debug + | eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_error); + } + } + } +#endif //#if defined(USE_EAP_HARDWARE_TRACE) + + + { + eap_status_e status = configure(); + if (status != eap_status_ok) + { + User::Leave(KErrGeneral); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Configured EAPOL AM...\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Created timer...\n"))); + + // SERVER TEST CODE + if (m_is_client == false) + { + TRAPD(err, ReadEAPSettingsL()); + if (err != KErrNone) + { + // Setting reading from CommDB failed. Use default values instead (only EAP-SIM). + + // SIM + _LIT(KSIM, "18"); + TEap* sim = new(ELeave) TEap; + CleanupStack::PushL(sim); + sim->Enabled = ETrue; + sim->UID.Copy(KSIM); + User::LeaveIfError(m_iap_eap_array.Append(sim)); + CleanupStack::Pop(sim); + } + + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("========================\n"))); + + set_is_valid(); + +} + + +//-------------------------------------------------- + +eapol_am_core_symbian_c* eapol_am_core_symbian_c::NewL(MEapolToWlmIf * const aPartner, + const bool aIsClient, + const TUint aServerIndex) +{ + eapol_am_core_symbian_c* self = new(ELeave) eapol_am_core_symbian_c(aPartner, aIsClient, aServerIndex); + CleanupStack::PushL(self); + self->ConstructL(); + + if (self->get_is_valid() != true) + { + User::Leave(KErrGeneral); + } + + CleanupStack::Pop(); + return self; +} + +//-------------------------------------------------- + +eapol_am_core_symbian_c::~eapol_am_core_symbian_c() +{ + +#if defined(USE_EAP_FILECONFIG) + delete m_fileconfig; + m_fileconfig = 0; +#endif //#if defined(USE_EAP_FILECONFIG) + + shutdown(); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_am_core_symbian_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::shutdown()\n"))); + + // Cancel timer + cancel_all_timers(); + + // Delete upper stack if it still exists + if (m_ethernet_core != 0) + { + m_ethernet_core->shutdown(); + delete m_ethernet_core; + } + + delete m_wpa_preshared_key; + + delete m_ssid; + + delete m_wpa_psk_password_override; + + delete m_receive_network_id; + + m_database.Close(); + m_session.Close(); + + // Print some statistics + if (m_is_client) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_TEST_VECTORS, + (EAPL("client authentication SUCCESS %d, FAILED %d, count %d\n"), + m_successful_authentications, + m_failed_authentications, + m_authentication_counter)); + } + else + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_TEST_VECTORS, + (EAPL("server authentication SUCCESS %d, FAILED %d, count %d\n"), + m_successful_authentications, + m_failed_authentications, + m_authentication_counter)); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL EXITING.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Finally delete tools. No logging is allowed after this. + if (m_am_tools != 0) + { + m_am_tools->shutdown(); + delete m_am_tools; + } + + + // Unload all loaded plugins + // NOTE this must be after the m_am_tools->shutdown() call. + // m_am_tools->shutdown() will run virtual functions of some plugins. + for(int i = 0; i < m_plugin_if_array.Count(); i++) + { + delete m_plugin_if_array[i]; + } + + m_plugin_if_array.Close(); + m_eap_type_array.Close(); + + // Delete the IAP EAP type info array + m_iap_eap_array.ResetAndDestroy(); + + + return eap_status_ok; +} + +//-------------------------------------------------- + +// +void eapol_am_core_symbian_c::RunL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::RunL(): iStatus.Int() = %d\n"), + iStatus.Int())); + + if (iStatus.Int() != KErrNone) + { + return; + } + + // Authentication cancelled. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Authentication cancelled.\n"))); + + // Set block on. + m_block_packet_sends_and_notifications = true; + + // Reset flags + m_success_indication_sent = false; + m_unicast_wep_key_received = false; + m_broadcast_wep_key_received = false; + m_authentication_indication_sent = false; + + m_stack_marked_to_be_deleted = true; + set_timer(this, EAPOL_AM_CORE_TIMER_DELETE_STACK_ID, 0, 0); + + // reset index + m_eap_index = 0; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + + m_partner->EapIndication(EFailedCompletely); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +void eapol_am_core_symbian_c::DoCancel() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::DoCancel()\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +TInt eapol_am_core_symbian_c::Start(const TIndexType aIndexType, + const TUint aIndex, + const TSSID& aSSID, + const TBool aWPAOverrideEnabled, + const TUint8* aWPAPSK, + const TUint aWPAPSKLength) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::Start()\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("STARTING AUTHENTICATION.\n"))); + + eap_status_e status(eap_status_ok); + + if (m_ethernet_core != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Deleting previously used stack.\n"))); + + // It is an error to call start without calling disassociated + if (m_stack_marked_to_be_deleted == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::Start called twice!\n"))); + return KErrAlreadyExists; + } + + // The previously used stack is perhaps still waiting for deletion. + cancel_timer(this, EAPOL_AM_CORE_TIMER_DELETE_STACK_ID); + + // Delete stack + m_ethernet_core->shutdown(); + delete m_ethernet_core; + m_ethernet_core = 0; + + m_stack_marked_to_be_deleted = false; + } + + // Clear packet send and notification blocking. + m_block_packet_sends_and_notifications = false; + + // Store SSID. This is needed for WPA PSK calculation. + if (aSSID.ssidLength > 0) + { + status = m_ssid->set_copy_of_buffer(aSSID.ssid, aSSID.ssidLength); + if (status != eap_status_ok) + { + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)); + } + } + + // Store WPAPSK. This is needed for WPA PSK mode in Easy WLAN. + if (aWPAPSKLength > 0 + && aWPAPSK != 0) + { + status = m_wpa_psk_password_override->set_copy_of_buffer(aWPAPSK, aWPAPSKLength); + if (status != eap_status_ok) + { + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)); + } + } + + if (aWPAOverrideEnabled) + { + m_wpa_override_enabled = true; + } + else + { + m_wpa_override_enabled = false; + } + + /////////////////////////////////// + // Get EAP parameters from CommDbIf + /////////////////////////////////// + m_index_type = aIndexType; + m_index = aIndex; + + TRAPD(err, ReadEAPSettingsL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP settings reading from CommDb failed or cancelled(err %d).\n"), err)); + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return err; + } + + // Start new authentication from scratch. + m_unicast_wep_key_received = false; + m_broadcast_wep_key_received = false; + m_wpa_psk_mode_active = false; + + if (m_wpa_psk_mode_allowed == false + || m_wpa_preshared_key->get_data_length() == 0) + { + // Check the first enabled type + TEap* eapType = 0; + TInt i(0); + for (i = 0; i < m_iap_eap_array.Count(); i++) + { + // Check if type is enabled + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + break; + } + } + if (i >= m_iap_eap_array.Count()) + { + // No enabled EAP types. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("No enabled EAP types.\n"))); + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrNone; + } + + // reset index (start from the first enabled EAP type) + m_eap_index = i; + + // Check if the first enabled type is LEAP. + TLex8 tmp(eapType->UID); + TInt type(0); + tmp.Val(type); + + switch (type) + { + case eap_type_leap: + if (m_security_mode != Wpa + && m_security_mode != Wpa2Only) + { + m_802_11_authentication_mode = EAuthModeLeap; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Start: Trying auth mode LEAP.\n"))); + } + else + { + // If security mode is WPA or WPA2 then even LEAP uses open authentication! + m_802_11_authentication_mode = EAuthModeOpen; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Start: Trying auth mode OPEN (LEAP in WPA mode).\n"))); + } + + m_active_type_is_leap = true; + break; + default: + m_802_11_authentication_mode = EAuthModeOpen; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Start: Trying auth mode OPEN.\n"))); + + m_active_type_is_leap = false; + break; + } + } + else + { + // WPA Pre-shared key mode + m_active_type_is_leap = false; + m_wpa_psk_mode_active = true; + m_802_11_authentication_mode = EAuthModeOpen; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Start: Trying auth mode OPEN.\n"))); + } + + // Ignore return value. Result comes with CompleteAssociation call. + m_partner->Associate(m_802_11_authentication_mode); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)); +} + +//-------------------------------------------------- + +// +TInt eapol_am_core_symbian_c::CompleteAssociation( + const TInt aResult, + const TMacAddress& aLocalAddress, + const TMacAddress& aRemoteAddress, + const TUint8* const aReceivedWPAIE, // WLM must give only the WPA IE to EAPOL + const TUint aReceivedWPAIELength, + const TUint8* const aSentWPAIE, + const TUint aSentWPAIELength, + const TWPACipherSuite aGroupKeyCipherSuite, + const TWPACipherSuite aPairwiseKeyCipherSuite + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::CompleteAssociation(): aResult %d\n"), + aResult)); + + eap_status_e status(eap_status_ok); + + // ASSOCIATION UNSUCCESSFUL + if (aResult != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CompleteAssociation: Unsuccessful.\n"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Got AP MAC address"), + aRemoteAddress.iMacAddress, + KMacAddressLength)); + + // Report rogue AP if we tried LEAP and it failed + if (m_802_11_authentication_mode == EAuthModeLeap) + { + // Only add rogue AP if the error code is correct + if (aResult == E802Dot11StatusAuthAlgorithmNotSupported) + { + eap_rogue_ap_entry_c rogue_entry(m_am_tools); + + rogue_entry.set_mac_address(static_cast(aRemoteAddress.iMacAddress)); + rogue_entry.set_rogue_reason(rogue_ap_association_failed); + + eap_array_c rogue_list(m_am_tools); + status = rogue_list.add_object(&rogue_entry, false); + if (status == eap_status_ok) + { + status = add_rogue_ap(rogue_list); + // Ignore return value on purpose - it's not fatal if this fails + } + } + } + + if (m_wpa_psk_mode_active == false) + { + if (aResult == E802Dot11StatusAuthAlgorithmNotSupported + && m_security_mode != Wpa + && m_security_mode != Wpa2Only) // If security mode is WPA or WPA2 then only OPEN auth should be used + { + // Association failed because we had wrong authentication type. + // Try to find next allowed type that uses different authentication type + m_eap_index++; + + TEap* eapType; + TBool found(EFalse); + TInt i(0); + for (i = m_eap_index; i < m_iap_eap_array.Count(); i++) + { + // Check if type is enabled + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + TLex8 tmp(eapType->UID); + TInt type(0); + tmp.Val(type); + + switch (type) + { + case eap_type_leap: + if (m_802_11_authentication_mode != EAuthModeLeap) + { + // This type will do; it uses different authentication mode. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("CompleteAssociation: Changed auth mode to LEAP.\n"))); + + m_802_11_authentication_mode = EAuthModeLeap; + m_active_type_is_leap = true; + found = ETrue; + } + break; + default: + if (m_802_11_authentication_mode != EAuthModeOpen) + { + // This type will do; it uses different authentication mode. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("CompleteAssociation: Changed auth mode to OPEN.\n"))); + + m_802_11_authentication_mode = EAuthModeOpen; + m_active_type_is_leap = false; + found = ETrue; + } + break; + } + if (found) + { + break; + } + } + } + + m_eap_index = i; + + if (i >= m_iap_eap_array.Count()) + { + // All the remaining allowed types had the same authentication mode. + // Give up this AP. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Could not associate to the AP. Tried all types.\n"))); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EThisAPFailed.\n"))); + + m_partner->EapIndication(EThisAPFailed); + return KErrNone; + + } + + // We found a type with different authentication mode. Try it. + + // Ignore return value. Result comes with CompleteAssociation call. + m_partner->Associate(m_802_11_authentication_mode); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrNone; + } + else + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Could not associate to the AP (error %d).\n"), aResult)); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EThisAPFailed.\n"))); + + m_partner->EapIndication(EThisAPFailed); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrNone; + } + } + else + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Could not associate to the AP with WPA pre-shared-key.\n"))); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EThisAPFailed.\n"))); + + m_partner->EapIndication(EThisAPFailed); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrNone; + } + } + + // ASSOCIATION SUCCESSFUL + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("CompleteAssociation: Successful.\n"))); + + // Store parameters + m_local_address = aLocalAddress; + + m_remote_address = aRemoteAddress; + + m_received_wpa_ie = aReceivedWPAIE; + + m_received_wpa_ie_length = aReceivedWPAIELength; + + m_sent_wpa_ie = aSentWPAIE; + + m_sent_wpa_ie_length = aSentWPAIELength; + + m_group_key_cipher_suite = aGroupKeyCipherSuite; + + m_pairwise_key_cipher_suite = aPairwiseKeyCipherSuite; + + // Create stack if it does not already exist. + status = create_upper_stack(); + if (status != eap_status_ok + && status != eap_status_already_exists) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrNone; + } + + // First create stack object and then copy it to heap object. This is because + // eap_am_network_id_c does not have a constructor that copies the buffers. + eap_am_network_id_c receive_network_id( + m_am_tools, + &aRemoteAddress, + sizeof(TMacAddress), + &aLocalAddress, + sizeof(TMacAddress), + eapol_ethernet_type_pae, + false, + false); + + delete m_receive_network_id; + m_receive_network_id = new eap_am_network_id_c( + m_am_tools); + + if (m_receive_network_id == 0) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrNone; + } + + status = m_receive_network_id->set_copy_of_network_id(&receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrNone; + } + + +#if defined (USE_EAPOL_KEY_STATE) + + // Initialise EAPOL key state + + eapol_key_authentication_type_e authentication_type(eapol_key_authentication_type_802_1X); + + if (aReceivedWPAIE !=0 + && aSentWPAIE != 0) + { + // WPA (in wpa or 802.1x security mode) + if (m_wpa_psk_mode_allowed == false) + { + authentication_type = eapol_key_authentication_type_WPA_EAP; + } + else + { + m_wpa_psk_mode_active = true; + authentication_type = eapol_key_authentication_type_WPA_PSK; + } + + } + else + { + // Non-wpa mode + authentication_type = eapol_key_authentication_type_802_1X; + } + + eap_variable_data_c authenticator_RSNA_IE(m_am_tools); + eap_variable_data_c supplicant_RSNA_IE(m_am_tools); + + // Note: the default values here are only for 802.1x mode. In that mode + // we don't know the WEP key length beforehand so we will have to guess. + // It does not matter in this case if we guess wrong - only thing that matters + // is that it is WEP. + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e + eapol_pairwise_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40); + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e + eapol_group_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40); + + // WPA mode is active if information elements are valid + if (aReceivedWPAIE != 0 + && aSentWPAIE != 0) + { + status = authenticator_RSNA_IE.set_copy_of_buffer(aReceivedWPAIE, aReceivedWPAIELength); + if (status != eap_status_ok) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrNoMemory; + } + status = supplicant_RSNA_IE.set_copy_of_buffer(aSentWPAIE, aSentWPAIELength); + if (status != eap_status_ok) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrNoMemory; + } + + switch (aGroupKeyCipherSuite) + { + case ENoCipherSuite: + eapol_group_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_none; + break; + case EWEP40: + eapol_group_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40; + break; + case EWEP104: + eapol_group_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104; + break; + case ETKIP: + eapol_group_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP; + break; + case ECCMP: + eapol_group_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP; + break; + case EWRAP: + default: + User::Panic(_L("EAPOL"), KErrNotSupported); + } + + switch (aPairwiseKeyCipherSuite) + { + case ENoCipherSuite: + eapol_pairwise_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_none; + break; + case EWEP40: + eapol_pairwise_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40; + break; + case EWEP104: + eapol_pairwise_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104; + break; + case ETKIP: + eapol_pairwise_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP; + break; + case ECCMP: + eapol_pairwise_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP; + break; + case EWRAP: + default: + User::Panic(_L("EAPOL"), KErrNotSupported); + } + } + + if (authentication_type == eapol_key_authentication_type_WPA_PSK) + { + status = m_ethernet_core->association( + m_receive_network_id, + authentication_type, + &authenticator_RSNA_IE, + &supplicant_RSNA_IE, + eapol_pairwise_cipher, + eapol_group_cipher, + m_wpa_preshared_key); + } + else + { + status = m_ethernet_core->association( + m_receive_network_id, + authentication_type, + &authenticator_RSNA_IE, + &supplicant_RSNA_IE, + eapol_pairwise_cipher, + eapol_group_cipher, + 0); + } + if (status != eap_status_ok) + { + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("m_ethernet_core->association call failed.\n"))); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrGeneral; + } + +#endif // USE_EAPOL_KEY_STATE + + if (m_wpa_psk_mode_active == false) + { + // Start authentication if mode is not pre-shared key. If mode is pre-shared key then + // just wait for EAPOL-Key frames. + status = m_ethernet_core->start_authentication(m_receive_network_id, m_is_client); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)); +} + +//-------------------------------------------------- + +// +TInt eapol_am_core_symbian_c::ReceivePacket(const TUint aLength, const TUint8* const aPacket) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::ReceivePacket()\n"))); + + if (aLength < eapol_ethernet_header_wr_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message)); + } + + eapol_ethernet_header_wr_c eth_header(m_am_tools, aPacket, aLength); + eap_am_network_id_c receive_network_id( + m_am_tools, + eth_header.get_source(), + eth_header.get_source_length(), + eth_header.get_destination(), + eth_header.get_destination_length(), + eth_header.get_type(), + false, + false); + eap_status_e status(eap_status_process_general_error); + if (eth_header.get_type() == eapol_ethernet_type_pae) + { + status = create_upper_stack(); + if (status != eap_status_ok + && status != eap_status_already_exists) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrNone; + } + +#if defined (USE_EAPOL_KEY_STATE) + if (m_is_client == false + && status != eap_status_already_exists) + { + // If we are server we need to do associate here. + eapol_key_authentication_type_e authentication_type( + eapol_key_authentication_type_WPA_EAP); + + eap_variable_data_c authenticator_RSNA_IE(m_am_tools); + eap_variable_data_c supplicant_RSNA_IE(m_am_tools); + + status = authenticator_RSNA_IE.set_buffer(TEST_RSN_IE, sizeof(TEST_RSN_IE), false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + status = supplicant_RSNA_IE.set_buffer(TEST_RSN_IE, sizeof(TEST_RSN_IE), false, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e + eapol_pairwise_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP); + eapol_RSNA_key_header_c::eapol_RSNA_cipher_e + eapol_group_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP); + + + if (authentication_type == eapol_key_authentication_type_WPA_PSK) + { + status = m_ethernet_core->association( + &receive_network_id, + authentication_type, + &authenticator_RSNA_IE, + &supplicant_RSNA_IE, + eapol_pairwise_cipher, + eapol_group_cipher, + m_wpa_preshared_key); + } + else + { + status = m_ethernet_core->association( + &receive_network_id, + authentication_type, + &authenticator_RSNA_IE, + &supplicant_RSNA_IE, + eapol_pairwise_cipher, + eapol_group_cipher, + 0); + } + + } +#endif // USE_EAPOL_KEY_STATE + + // Forward the packet to the Ethernet layer of the EAPOL stack. Ignore return value. Failure is signalled using state_notification. + status = m_ethernet_core->packet_process( + &receive_network_id, + ð_header, + aLength); + + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Not supported ethernet type 0x%04x\n"), eth_header.get_type())); + status = eap_status_ethernet_type_not_supported; + } + + status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)); +} + +//-------------------------------------------------- + +void eapol_am_core_symbian_c::set_is_valid() +{ + m_is_valid = true; +} + +bool eapol_am_core_symbian_c::get_is_valid() +{ + return m_is_valid; +} + +void eapol_am_core_symbian_c::increment_authentication_counter() +{ + ++m_authentication_counter; +} + +u32_t eapol_am_core_symbian_c::get_authentication_counter() +{ + return m_authentication_counter; +} + +bool eapol_am_core_symbian_c::get_is_client() +{ + return m_is_client; +} + + +//-------------------------------------------------- + +// +eap_status_e eapol_am_core_symbian_c::packet_data_crypto_keys( + const eap_am_network_id_c * const /*send_network_id*/, + const eap_variable_data_c * const /*master_session_key*/) +{ + // Not needed in Symbian version + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +eap_status_e eapol_am_core_symbian_c::packet_data_session_key( + const eap_am_network_id_c * const /*send_network_id*/, + const eapol_session_key_c * const key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + TInt status(KErrNone); + + const eap_variable_data_c * const key_data = key->get_key(); + if (key_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_key_error; + } + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_data_session_key: index: %d, type %d\n"), + key->get_key_index(), + key->get_key_type())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_data_session_key:"), + key_data->get_data(key_data->get_data_length()), + key_data->get_data_length())); + + switch (key->get_key_type()) + { + case eapol_key_type_broadcast: + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::packet_data_session_key: Got rc4_broadcast key.\n"))); + + status = m_partner->SetCipherKey( + ERC4Broadcast, + static_cast (key->get_key_index()), + key_data->get_data(key_data->get_data_length()), + key_data->get_data_length()); + m_broadcast_wep_key_received = true; + break; + case eapol_key_type_unicast: + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::packet_data_session_key: Got rc4_unicast key.\n"))); + + status = m_partner->SetCipherKey( + ERC4Unicast, + static_cast (key->get_key_index()), + key_data->get_data(key_data->get_data_length()), + key_data->get_data_length()); + m_unicast_wep_key_received = true; + break; + default: + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::packet_data_session_key: Got unsupported key, type %d.\n"), + key->get_key_type())); + status = KErrNotSupported; + break; + } + + if (m_unicast_wep_key_received == true + && m_broadcast_wep_key_received == true + && m_success_indication_sent == false) + { + // Signal success because we have received one unicast (pairwise) key and one broadcast (group) key. + // If there are more keys coming later they are saved also. + if (m_active_type_is_leap == true) + { + // Leap was successful + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: ELeapSuccess.\n"))); + m_partner->EapIndication(ELeapSuccess); + } + else + { + // some other type was successful + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: ESuccess.\n"))); + m_partner->EapIndication(ESuccess); + } + + m_success_indication_sent = true; + m_first_authentication = false; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(status)); +} + +//-------------------------------------------------- + +// + +eap_status_e eapol_am_core_symbian_c::packet_send( + const eap_am_network_id_c * const /*send_network_id*/, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t /*buffer_length*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::packet_send(data_length=%d).\n"), + data_length)); + + if (header_offset != 0u) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_process_general_error; + } + else if (header_offset+data_length != sent_packet->get_data_length()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: packet_send: packet buffer corrupted (data_length != sent_packet->get_data_length()).\n"))); + EAP_ASSERT(data_length == sent_packet->get_buffer_length()); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_process_general_error; + } + + if (m_block_packet_sends_and_notifications == true) + { + // Packet sending block is active. This happens when disassociated has been called. + // start_authentication clears the block. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet ignored because Disassociated() was called.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + TInt status(KErrNone); + if (m_send_original_packet_first == true) + { + if (m_enable_random_errors == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send original packet\n"), + this, + m_packet_index)); + } + + u8_t * const packet_data = sent_packet->get_data_offset(header_offset, data_length); + if (packet_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_buffer_too_short; + } + + // Here we send the original packet. + status = m_partner->EapPacketSend( + data_length, + static_cast(packet_data)); + ++m_packet_index; + } + + if (m_enable_random_errors == true + && status == KErrNone) + { + if (m_generate_multiple_error_packets > 0ul) + { + // First create a copy of sent packet. Original correct packet will will be sent last. + for (u32_t ind = 0ul; ind < m_generate_multiple_error_packets; ind++) + { + eap_buf_chain_wr_c *copy_packet = sent_packet->copy(); + + if (copy_packet != 0 + && copy_packet->get_is_valid_data() == true) + { + // Make a random error to the copy message. + random_error(copy_packet, true, m_packet_index); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send error packet\n"), + this, + m_packet_index)); + + u8_t * const packet_data = copy_packet->get_data_offset(header_offset, data_length); + if (packet_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_buffer_too_short; + } + + // Here we send the copied and manipulated packet. + status = m_partner->EapPacketSend( + data_length, + static_cast(packet_data)); + + ++m_packet_index; + } + delete copy_packet; + } + } + else + { + // Make a random error to the original message. + random_error(sent_packet, false, m_packet_index); + + if (sent_packet->get_is_manipulated() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send error packet\n"), + this, + m_packet_index)); + } + } + } + + + if (m_send_original_packet_first == false + && status == KErrNone) + { + if (m_enable_random_errors == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send original packet\n"), + this, + m_packet_index)); + } + + u8_t * const packet_data = sent_packet->get_data_offset(header_offset, data_length); + if (packet_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_buffer_too_short; + } + + // Here we send the original packet. + status = m_partner->EapPacketSend( + data_length, + static_cast(packet_data)); + ++m_packet_index; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(status)); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_am_core_symbian_c::reassociate( + const eap_am_network_id_c * const /* send_network_id */, + const eapol_key_authentication_type_e /* authentication_type */, + const eap_variable_data_c * const /* PMKID */, + const eap_variable_data_c * const /* WPXM_WPXK1 */, + const eap_variable_data_c * const /* WPXM_WPXK2 */) +{ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +void eapol_am_core_symbian_c::state_notification(const abs_eap_state_notification_c * const state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if(state->get_protocol_layer() == eap_protocol_layer_general) + { + if (state->get_current_state() == eap_general_state_authentication_cancelled) + { + // Authentication was cancelled. Cannot continue. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Authentication was cancelled. Sets timer EAPOL_AM_CORE_TIMER_FAILED_COMPLETELY_ID.\n"))); + + set_timer(this, EAPOL_AM_CORE_TIMER_FAILED_COMPLETELY_ID, 0, 0); + } + else if (state->get_current_state() == eap_general_state_configuration_error) + { + // Configuration error. Cannot continue. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Configuration error. Sets timer EAPOL_AM_CORE_TIMER_FAILED_COMPLETELY_ID.\n"))); + + set_timer(this, EAPOL_AM_CORE_TIMER_FAILED_COMPLETELY_ID, 0, 0); + } + } + + + if (m_block_packet_sends_and_notifications == true) + { + // Notification block is active. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("state_notification: notification ignored because Disassociated() was called.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + + // Check if this is EAP layer notification + if(state->get_protocol_layer() == eap_protocol_layer_eap) + { + switch (state->get_current_state()) + { + case eap_state_none: + break; + case eap_state_identity_request_sent: + // This is for server only so no need to notify WLM. + break; + case eap_state_identity_request_received: + if (m_authentication_indication_sent == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EAuthenticating.\n"))); + m_partner->EapIndication(EAuthenticating); + m_authentication_indication_sent = true; + } + break; + case eap_state_identity_response_received: + // This is for server only so no need to notify WLM. + break; + case eap_state_authentication_finished_successfully: + { + + increment_authentication_counter(); + m_successful_authentications++; + + if (m_wpa_psk_mode_active == false) + { + TEap eap; + eap.Enabled = ETrue; + eap.UID.Num(static_cast(state->get_eap_type())); + + // This moves the successful type to be the top priority type in IAP settings. + TRAPD(err, SetToTopPriorityL(&eap)); + if (err != KErrNone) + { + // Just log the error. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("state_notification: SetToTopPriorityL leaved!\n"))); + } + + // Move the active eap type index to the first type + m_eap_index = 0; + } + + + } + break; + case eap_state_authentication_terminated_unsuccessfully: + { + if (m_wpa_psk_mode_active == false) + { + // Set index to next type. + m_eap_index++; + } + + increment_authentication_counter(); + m_failed_authentications++; + + // Restart authentication + eap_am_network_id_c* send_network_id = new eap_am_network_id_c(m_am_tools, state->get_send_network_id()); + if (send_network_id == 0 + || send_network_id->get_is_valid_data() == false) + { + delete send_network_id; + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + m_partner->EapIndication(EFailedCompletely); + break; + } + set_timer(this, EAPOL_AM_CORE_TIMER_RESTART_AUTHENTICATION_ID, send_network_id, 0); + + } + break; + default: + break; + } + } + else + { + if(state->get_protocol_layer() == eap_protocol_layer_eapol) + { + switch (state->get_current_state()) + { + case eapol_state_no_start_response: + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: ENoResponse.\n"))); + m_partner->EapIndication(ENoResponse); + break; + default: + break; + } + } + else if(state->get_protocol_layer() == eap_protocol_layer_eapol_key) + { + switch (state->get_current_state()) + { + case eapol_key_state_802_11i_authentication_terminated_unsuccessfull: + { + increment_authentication_counter(); + m_failed_authentications++; + + // Consider EAPOL layer failures fatal. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Unsuccessful authentication on EAPOL level.\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EThisAPFailed.\n"))); + m_partner->EapIndication(EThisAPFailed); + } + break; + case eapol_key_state_802_11i_authentication_finished_successfull: + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_KEY: %s: Authentication SUCCESS\n"), + (m_is_client == true ? "client": "server"))); + } + break; + default: + break; + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// + +eap_status_e eapol_am_core_symbian_c::timer_expired( + const u32_t id, void * /* data */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::TimerExpired id = %d.\n"), + id)); + + switch (id) + { + case EAPOL_AM_CORE_TIMER_RESTART_AUTHENTICATION_ID: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_AM_CORE_TIMER_RESTART_AUTHENTICATION_ID elapsed: Stopping stack.\n"))); + + // Stop stack. Do this only if Ethernet core still exists. + if (m_ethernet_core != 0) + { + m_ethernet_core->shutdown(); + delete m_ethernet_core; + m_ethernet_core = 0; + } + if (m_wpa_psk_mode_active == true) + { + // PSK mode active - cannot restart. Just fail. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WPA PSK mode failed.\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EThisAPFailed.\n"))); + m_partner->EapIndication(EThisAPFailed); + break; + + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Checking if more types.\n"))); + + TInt i; + TEap *eapType = 0; + // Search for more EAP types to try + for (i = m_eap_index; i < m_iap_eap_array.Count(); i++) + { + // Find the next enabled EAP type (highest priority) + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + break; + } + } + // Update index to point to next type to be tried + m_eap_index = i; + + if (i >= m_iap_eap_array.Count()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("No more configured EAP types to try.\n"))); + + // No point in trying to restart authentication because there isn't any more + // EAP types left to try... + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EThisAPFailed.\n"))); + m_partner->EapIndication(EThisAPFailed); + break; + } + + // Check if authentication mode must be changed + TLex8 tmp(eapType->UID); + TInt type(0); + tmp.Val(type); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Found new type to try: %d.\n"), type)); + + switch (type) + { + case eap_type_leap: + m_active_type_is_leap = true; + if (m_802_11_authentication_mode != EAuthModeLeap + && m_security_mode != Wpa + && m_security_mode != Wpa2Only) // In WPA or WPA2 even LEAP uses open authentication + { + // New type is LEAP and the old was something else: + // must reassociate with correct authentication mode. + m_self_disassociated = true; + TInt result = m_partner->Disassociate(); + if (result != KErrNone) + { + // Probably unrecoverable error + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TimerExpired: Changing auth type to LEAP.\n"))); + + m_802_11_authentication_mode = EAuthModeLeap; + + m_partner->Associate(EAuthModeLeap); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + break; + default: + m_active_type_is_leap = false; + if (m_802_11_authentication_mode != EAuthModeOpen + && m_security_mode != Wpa + && m_security_mode != Wpa2Only) // In WPA or WPA2 even LEAP uses open authentication) + { + // New type is non-LEAP and the old was LEAP: + // must reassociate with correct authentication mode + m_self_disassociated = true; + TInt result = m_partner->Disassociate(); + if (result != KErrNone) + { + // Probably unrecoverable error + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TimerExpired: Changing auth type to OPEN.\n"))); + + m_802_11_authentication_mode = EAuthModeOpen; + + m_partner->Associate(EAuthModeOpen); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + break; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TimerExpired: No need to change auth type.\n"))); + + if (CompleteAssociation( + KErrNone, + m_local_address, + m_remote_address, + m_received_wpa_ie, + m_received_wpa_ie_length, + m_sent_wpa_ie, + m_sent_wpa_ie_length, + m_group_key_cipher_suite, + m_pairwise_key_cipher_suite) != KErrNone) + { + // Probably unrecoverable error + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + m_partner->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + } + break; + + case EAPOL_AM_CORE_TIMER_DELETE_STACK_ID: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_AM_CORE_TIMER_DELETE_STACK_ID elapsed: Delete stack.\n"))); + + cancel_all_timers(); + + // Delete stack + if (m_ethernet_core != 0) + { + m_ethernet_core->shutdown(); + delete m_ethernet_core; + m_ethernet_core = 0; + } + m_stack_marked_to_be_deleted = false; + + // Re-activates timer queue. + eap_status_e status = m_am_tools->re_activate_timer_queue(); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: re_activate_timer_queue() failed, status = %d\n"))); + } + } + break; + + case EAPOL_AM_CORE_TIMER_FAILED_COMPLETELY_ID: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_AM_CORE_TIMER_FAILED_COMPLETELY_ID elapsed: Indication sent to WLM: EFailedCompletely.\n"))); + + m_partner->EapIndication(EFailedCompletely); + } + break; + + default: + break; + } + return eap_status_ok; +} + +eap_status_e eapol_am_core_symbian_c::timer_delete_data( + const u32_t id, void *data) +{ + switch (id) + { + case EAPOL_AM_CORE_TIMER_RESTART_AUTHENTICATION_ID: + { + eap_am_network_id_c* tmp = static_cast(data); + delete tmp; + } + break; + case EAPOL_AM_CORE_TIMER_DELETE_STACK_ID: + break; + case EAPOL_AM_CORE_TIMER_FAILED_COMPLETELY_ID: + break; + + default: + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::timer_delete_data: deleted unknown timer.\n"))); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + } + return eap_status_ok; +} +//-------------------------------------------------- + +// +u32_t eapol_am_core_symbian_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + *MTU = KMTU; + *trailer_length = KTrailerLength; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KHeaderOffset; +} + +//-------------------------------------------------- + +// +eap_status_e eapol_am_core_symbian_c::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_type_does_not_exists_error); + TInt index = m_eap_type_array.Find(type); + if (index != KErrNotFound) + { + delete m_plugin_if_array[index]; + m_plugin_if_array.Remove(index); + m_eap_type_array.Remove(index); + status = eap_status_ok; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_am_core_symbian_c::eap_acknowledge(const eap_am_network_id_c * const receive_network_id) +{ + // Any Network Protocol packet is accepted as a success indication. + // This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_ethernet_core->eap_acknowledge(receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +eap_status_e eapol_am_core_symbian_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type_if, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::load_module(type %d=%s, tunneling_type %d=%s)\n"), + static_cast(type), + eap_header_string_c::get_eap_type_string(type), + static_cast(tunneling_type), + eap_header_string_c::get_eap_type_string(tunneling_type))); + + eap_status_e status = eap_status_process_general_error; + TBuf8 cue; + cue.Num(static_cast(convert_eap_type_to_u32_t(type))); + CEapType* eapType = 0; + TInt error(KErrNone); + + // Check if this EAP type has already been loaded + TInt eapArrayIndex = m_eap_type_array.Find(type); + if (eapArrayIndex != KErrNotFound) + { + // Yep. It was loaded already. + eapType = m_plugin_if_array[eapArrayIndex]; + } + else + { + // We must have a trap here since the EAPOL core knows nothing about Symbian. + TRAP(error, (eapType = CEapType::NewL(cue, m_index_type, m_index))); + if (error != KErrNone + || eapType == 0) + { + // Interface not found or implementation creation function failed + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ECom could not find/initiate implementation.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + // Set the tunneling type + eapType->SetTunnelingType(convert_eap_type_to_u32_t(tunneling_type)); + + // Create the EAP protocol interface implementation. + TRAP(error, (*eap_type_if = eapType->GetStackInterfaceL(m_am_tools, partner, is_client_when_true, receive_network_id))); + + if (error != KErrNone + || *eap_type_if == 0 + || (*eap_type_if)->get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Could not create EAP type interface instance. Error: %d\n"), error)); + + status = eap_status_allocation_error; + // Unload DLL (two ways, depending whether this type was already loaded...) + if (eapArrayIndex == KErrNotFound) + { + // No need to call shutdown here because GetStackInterfaceL has done it. + delete eapType; + } + else + { + unload_module(type); + } + // Note: even in error cases eap_core_c deletes eap_type_if + } + else + { + status = eap_status_ok; + if (eapArrayIndex == KErrNotFound) + { + // Add plugin information to the member arrays. There is no need to store eap_type pointer because + // the stack takes care of its deletion. + if (m_plugin_if_array.Append(eapType) != KErrNone) + { + delete eapType; + status = eap_status_allocation_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + if (m_eap_type_array.Append(type) != KErrNone) + { + // Remove the eap type added just previously + m_plugin_if_array.Remove(m_plugin_if_array.Count() - 1); + delete eapType; + status = eap_status_allocation_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +TInt eapol_am_core_symbian_c::Disassociated() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::Disassociated()\n"))); + + if (m_self_disassociated == true) + { + // We were expecting this. No need to reset state. + m_self_disassociated = false; + return KErrNone; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::Disassociated.\n"))); + + eap_status_e status(eap_status_ok); + + // Set block on. + m_block_packet_sends_and_notifications = true; + + // Reset flags + m_success_indication_sent = false; + m_unicast_wep_key_received = false; + m_broadcast_wep_key_received = false; + m_authentication_indication_sent = false; + + if (m_ethernet_core != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Stack exists. Set EAPOL_AM_CORE_TIMER_DELETE_STACK_ID timer.\n"))); + + m_stack_marked_to_be_deleted = true; + set_timer(this, EAPOL_AM_CORE_TIMER_DELETE_STACK_ID, 0, 0); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Stack did not exists. EAPOL_AM_CORE_TIMER_DELETE_STACK_ID timer not set.\n"))); + } + + // reset index + m_eap_index = 0; + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)); +} + +//-------------------------------------------------- + +// +TInt eapol_am_core_symbian_c::SendWPAMICFailureReport( + TBool aFatalMICFailure, + const TMICFailureType aMICFailureType) +{ + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::SendWPAMICFailureReport(%d, %d).\n"), + aFatalMICFailure, + aMICFailureType)); + + bool fatal_failure_when_true = true; + + if (!aFatalMICFailure) + { + fatal_failure_when_true = false; + } + + eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type + = eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_pairwise_key; + + if (aMICFailureType == EGroupKey) + { + tkip_mic_failure_type + = eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_group_key; + } + + const eap_status_e status = m_ethernet_core->tkip_mic_failure( + m_receive_network_id, + fatal_failure_when_true, + tkip_mic_failure_type); + + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)); +} + + +//-------------------------------------------------- + +// +void eapol_am_core_symbian_c::ReadEAPSettingsL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::ReadEAPSettingsL()\n"))); + + eap_status_e status(eap_status_ok); + + // Delete old IAP settings + m_iap_eap_array.ResetAndDestroy(); + if (m_index_type == ELan) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Beginning to read IAP settings - Type: %d, Index: %d.\n"), m_index_type, m_index)); + + CWLanSettings* wlan = new(ELeave) CWLanSettings; + CleanupStack::PushL(wlan); + SWLANSettings wlanSettings; + if (wlan->Connect() != KErrNone) + { + // Could not connect to CommDB + User::Leave(KErrCouldNotConnect); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, (EAPL("Connected to CommDbIf.\n"))); + + if (wlan->GetWlanSettingsForService(m_index, wlanSettings) != KErrNone) + { + wlan->Disconnect(); + User::Leave(KErrUnknown); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Got WLAN settings.\n"))); + + wlan->GetEapDataL(m_iap_eap_array); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Got EAP data:\n"))); + + for (TInt i = 0; i < m_iap_eap_array.Count(); i++) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP type %d\n"), + i)); + + TLex8 tmp(m_iap_eap_array[i]->UID); + TInt val(0); + tmp.Val(val); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" UID: %d\n"), val)); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" Enabled: %d\n"), + m_iap_eap_array[i]->Enabled)); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("End EAP data:\n"))); + + if (m_iap_eap_array.Count() == 0) + { + // The EAP field was empty. Allow all types. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Empty EAP field -> enable all types.\n"))); + + RImplInfoPtrArray eapArray; + + REComSession::ListImplementationsL(KEapTypeInterfaceUid, eapArray); + + TEap *eap; + for (TInt i = 0; i < eapArray.Count(); i++) + { + eap = new(ELeave) TEap; + eap->UID.Copy(eapArray[i]->DataType()); + eap->Enabled = ETrue; + m_iap_eap_array.Append(eap); + } + + eapArray.ResetAndDestroy(); + } + + // Get security mode + if (m_wpa_override_enabled == false) + { + m_security_mode = static_cast(wlanSettings.SecurityMode); + + if (wlanSettings.EnableWpaPsk) + { + m_wpa_psk_mode_allowed = true; + } + else + { + m_wpa_psk_mode_allowed = false; + } + } + else + { + // WPA override is enabled + m_security_mode = Wpa; + if (m_wpa_psk_password_override->get_is_valid_data() == true + && m_wpa_psk_password_override->get_data_length() > 0) + { + m_wpa_psk_mode_allowed = true; + } + else + { + m_wpa_psk_mode_allowed = false; + } + } + + + // Get WPA or WPA2 pre shared key & SSID + if ((m_security_mode == Wlan8021x + || m_security_mode == Wpa + || m_security_mode == Wpa2Only) + && m_wpa_psk_mode_allowed == true + && m_is_client == true) + { + eap_variable_data_c * password = new eap_variable_data_c(m_am_tools); + if (password == 0) + { + wlan->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + eap_variable_data_c * ssid = new eap_variable_data_c(m_am_tools); + if (ssid == 0) + { + delete password; + wlan->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + + // When using easy WLAN there might be WPA PSK override + if (m_wpa_psk_password_override->get_is_valid_data() == true + && m_wpa_psk_password_override->get_data_length() > 0) + { + // Use WPA PSK override + status = password->set_copy_of_buffer( + m_wpa_psk_password_override->get_data(m_wpa_psk_password_override->get_data_length()), + m_wpa_psk_password_override->get_data_length()); + if (status != eap_status_ok) + { + delete password; + delete ssid; + wlan->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + else + { + status = password->set_copy_of_buffer(wlanSettings.WPAPreSharedKey.Ptr(), wlanSettings.WPAPreSharedKey.Size()); + if (status != eap_status_ok) + { + delete password; + delete ssid; + wlan->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + + TBuf8 tmp; + tmp.Copy(wlanSettings.SSID); + status = ssid->set_copy_of_buffer(tmp.Ptr(), tmp.Size()); + if (status != eap_status_ok) + { + delete password; + delete ssid; + wlan->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + crypto_wpa_psk_password_hash_c password_hash(m_am_tools); + + if (ssid->get_data_length() == 0) + { + status = ssid->set_copy_of_buffer(m_ssid); + if (status != eap_status_ok) + { + delete password; + delete ssid; + wlan->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + + TPSKEntry pskEntry; + + pskEntry.indexType = m_index_type; + pskEntry.index = m_index; + + TPtr8 ssidPtr( + ssid->get_data(ssid->get_data_length()), + ssid->get_data_length(), + ssid->get_data_length() + ); + + TInt err(KErrNone); + + if (m_wpa_psk_password_override->get_is_valid_data() == false + || m_wpa_psk_password_override->get_data_length() == 0) + { + // Retrieve saved PSK only when override is not in effect + TRAP(err, RetrievePSKL(pskEntry)); + } + + if (err != KErrNone + || pskEntry.ssid.Compare(ssidPtr) != 0 + || pskEntry.password.Compare(wlanSettings.WPAPreSharedKey) != 0) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("No previous PSK found...\n"))); + // No previous PSK or parameters were changed. We need to calculate + // PSK again + + status = password_hash.password_hash( + password, + ssid, + m_wpa_preshared_key, + 0, + 0); + + if (status != eap_status_ok) + { + delete password; + delete ssid; + wlan->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + // return; + } + + if (m_wpa_psk_password_override->get_is_valid_data() == false + || m_wpa_psk_password_override->get_data_length() == 0) + { + // Save new PSK (only if psk override is not in effect) + pskEntry.ssid.Copy(ssidPtr); + + pskEntry.password.Copy(wlanSettings.WPAPreSharedKey); + + pskEntry.psk.Copy( + m_wpa_preshared_key->get_data(m_wpa_preshared_key->get_data_length()), + m_wpa_preshared_key->get_data_length() + ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Saving PSK.\n"))); + SavePSKL(pskEntry); + } + } + else + { + // Copy retrieved psk to member variable + status = m_wpa_preshared_key->set_copy_of_buffer(pskEntry.psk.Ptr(), pskEntry.psk.Size()); + if (status != eap_status_ok) + { + delete password; + delete ssid; + wlan->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + delete password; + delete ssid; + } + + wlan->Disconnect(); + CleanupStack::PopAndDestroy(wlan); + if (m_security_mode != Wlan8021x + && m_security_mode != Wpa + && m_security_mode != Wpa2Only) + { + // Unsupported mode + User::Leave(KErrNotSupported); + } + } + else + { + // At the moment only LAN bearer is supported. + User::Leave(KErrNotSupported); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void eapol_am_core_symbian_c::SetToTopPriorityL(const TEap* const aEapType) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::SetToTopPriorityL()\n"))); + + if (m_index_type == ELan) + { + TInt i(0); + TBuf8<3> uid; + for (i = 0; i < m_iap_eap_array.Count(); i++) + { + TEap* eap = m_iap_eap_array[i]; + if (eap->UID[0] == '0') + { + // Cut the leading zero + uid.Copy(eap->UID.Right(eap->UID.Length()-1)); + } + else + { + uid.Copy(eap->UID); + } + if (eap->Enabled == aEapType->Enabled + && uid.Compare(aEapType->UID) == 0) + { + // Found + break; + } + } + if (i >= m_iap_eap_array.Count()) + { + // This should never happen + User::Leave(KErrNotFound); + } + + TLex8 tmp(aEapType->UID); + TInt val(0); + tmp.Val(val); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Setting to top priority:\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Old index: %d\n"), i)); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" UID: %d\n"), val)); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" Enabled: %d\n"), aEapType->Enabled)); + + if (i == 0) + { + // Already at the highest priority + return; + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Beginning to write IAP EAP settings - Type: %d, Index: %d.\n"), m_index_type, m_index)); + + CWLanSettings* wlan = new(ELeave) CWLanSettings; + CleanupStack::PushL(wlan); + SWLANSettings wlanSettings; + if (wlan->Connect() != KErrNone) + { + // Could not connect to CommDB + User::Leave(KErrCouldNotConnect); + } + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Connected to CommDbIf.\n"))); + if (wlan->GetWlanSettingsForService(m_index, wlanSettings) != KErrNone) + { + wlan->Disconnect(); + User::Leave(KErrUnknown); + } + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got WLAN settings.\n"))); + + // Change the order + TEap* eap = m_iap_eap_array[i]; + + m_iap_eap_array.Remove(i); // This does not delete the object + + m_iap_eap_array.Insert(eap, 0); + + wlan->SetEapDataL(m_iap_eap_array); + + wlan->Disconnect(); + + CleanupStack::PopAndDestroy(wlan); + } + else + { + // At the moment only LAN bearer is supported. + User::Leave(KErrNotSupported); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +eap_status_e eapol_am_core_symbian_c::configure() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::configure()\n"))); + + + //---------------------------------------------------------- + +#if defined(USE_EAP_ERROR_TESTS) + + { + eap_variable_data_c EAP_ERROR_TEST_enable_random_errors(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_ERROR_TEST_enable_random_errors.get_field(), + &EAP_ERROR_TEST_enable_random_errors); + if (status == eap_status_ok + && EAP_ERROR_TEST_enable_random_errors.get_is_valid_data() == true) + { + u32_t *enable_random_errors = reinterpret_cast( + EAP_ERROR_TEST_enable_random_errors.get_data(sizeof(u32_t)); + if (enable_random_errors != 0 + && *enable_random_errors != 0) + { + m_enable_random_errors = true; + } + } + } + + { + eap_variable_data_c EAP_ERROR_TEST_send_original_packet_first(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_ERROR_TEST_send_original_packet_first.get_field(), + &EAP_ERROR_TEST_send_original_packet_first); + if (status == eap_status_ok + && EAP_ERROR_TEST_send_original_packet_first.get_is_valid_data() == true) + { + u32_t *send_original_packet_first = reinterpret_cast( + EAP_ERROR_TEST_send_original_packet_first.get_data(sizeof(u32_t)); + if (send_original_packet_first != 0 + && *send_original_packet_first != 0) + { + m_send_original_packet_first = true; + } + } + } + + { + eap_variable_data_c EAP_ERROR_TEST_generate_multiple_error_packets(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_ERROR_TEST_generate_multiple_error_packets.get_field(), + &EAP_ERROR_TEST_generate_multiple_error_packets); + if (status == eap_status_ok + && EAP_ERROR_TEST_generate_multiple_error_packets.get_is_valid_data() == true) + { + u32_t *generate_multiple_error_packets = reinterpret_cast( + EAP_ERROR_TEST_generate_multiple_error_packets.get_data(sizeof(u32_t)); + if (generate_multiple_error_packets != 0 + && *generate_multiple_error_packets != 0) + { + m_generate_multiple_error_packets = *generate_multiple_error_packets; + } + } + } + + + { + eap_variable_data_c EAP_ERROR_TEST_manipulate_ethernet_header(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_ERROR_TEST_manipulate_ethernet_header.get_field(), + &EAP_ERROR_TEST_manipulate_ethernet_header); + if (status == eap_status_ok + && EAP_ERROR_TEST_manipulate_ethernet_header.get_is_valid_data() == true) + { + u32_t *manipulate_ethernet_header = reinterpret_cast( + EAP_ERROR_TEST_manipulate_ethernet_header.get_data(sizeof(u32_t)); + if (manipulate_ethernet_header != 0 + && *manipulate_ethernet_header != 0) + { + m_manipulate_ethernet_header = true; + } + } + } + + { + eap_variable_data_c EAP_ERROR_TEST_error_probability(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_ERROR_TEST_error_probability.get_field(), + &EAP_ERROR_TEST_error_probability); + if (status == eap_status_ok + && EAP_ERROR_TEST_error_probability.get_is_valid_data() == true) + { + u32_t *error_probability = reinterpret_cast( + EAP_ERROR_TEST_error_probability.get_data(sizeof(u32_t)); + if (error_probability != 0) + { + m_error_probability = *error_probability; + } + } + } + + { + eap_variable_data_c EAP_disable_function_traces(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_enable_function_traces.get_field(), + &EAP_disable_function_traces); + if (status == eap_status_ok + && EAP_disable_function_traces.get_is_valid_data() == true) + { + u32_t *disable_function_traces = reinterpret_cast( + EAP_disable_function_traces.get_data(sizeof(u32_t)); + if (disable_function_traces != 0 + && *disable_function_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | eap_am_tools_c::eap_trace_mask_functions + ); + } + } + } + +#endif //#if defined(USE_EAP_ERROR_TESTS) + + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_disable_traces(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_disable_traces.get_field(), + &EAP_TRACE_disable_traces); + if (status == eap_status_ok + && EAP_TRACE_disable_traces.get_is_valid_data() == true) + { + u32_t *disable_traces = reinterpret_cast( + EAP_TRACE_disable_traces.get_data(sizeof(u32_t))); + if (disable_traces != 0 + && *disable_traces != 0) + { + m_am_tools->set_trace_mask(eap_am_tools_c::eap_trace_mask_none); + } + else + { + // OK, set the default trace mask. + m_am_tools->set_trace_mask( + eap_am_tools_c::eap_trace_mask_debug + | eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_error); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_activate_only_trace_masks_always_and_error(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_activate_only_trace_masks_always_and_error.get_field(), + &EAP_TRACE_activate_only_trace_masks_always_and_error); + if (status == eap_status_ok + && EAP_TRACE_activate_only_trace_masks_always_and_error.get_is_valid_data() == true) + { + u32_t *activate_trace_mask_always + = reinterpret_cast( + EAP_TRACE_activate_only_trace_masks_always_and_error.get_data( + sizeof(u32_t))); + if (activate_trace_mask_always != 0 + && *activate_trace_mask_always != 0) + { + m_am_tools->set_trace_mask( + eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_error + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_activate_trace_on_error(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_activate_trace_on_error.get_field(), + &EAP_TRACE_activate_trace_on_error); + if (status == eap_status_ok + && EAP_TRACE_activate_trace_on_error.get_is_valid_data() == true) + { + u32_t *activate_trace_on_error = reinterpret_cast( + EAP_TRACE_activate_trace_on_error.get_data(sizeof(u32_t))); + if (activate_trace_on_error != 0 + && *activate_trace_on_error != 0) + { + m_am_tools->set_activate_trace_on_error(); + } + } + } + + //---------------------------------------------------------- + + // All of the configuration options are optional. + // So we return OK. + return eap_status_ok; +} + +//-------------------------------------------------- + +eap_status_e eapol_am_core_symbian_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT_ALWAYS(data != NULL); + + // To remove compilation warning in UREL due to KMaxConfigStringLength. + if(field->get_field_length() > KMaxConfigStringLength) + { + return eap_status_process_general_error; + } + + // Trap must be set here because the OS independent portion of EAPOL + // that calls this function does not know anything about Symbian. + eap_status_e status(eap_status_ok); + + // Check if the wanted parameter is default type + + eap_variable_data_c wanted_field(m_am_tools); + eap_variable_data_c type_field(m_am_tools); + eap_variable_data_c type_field_server(m_am_tools); + + status = wanted_field.set_buffer( + field->get_field(), + field->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = type_field.set_buffer( + cf_str_EAP_default_type_u32_t.get_field()->get_field(), + cf_str_EAP_default_type_u32_t.get_field()->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = type_field_server.set_buffer( + cf_str_EAP_server_default_type_u32_t.get_field()->get_field(), + cf_str_EAP_server_default_type_u32_t.get_field()->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + if (!wanted_field.compare(&type_field) + || !wanted_field.compare(&type_field_server)) + { + TInt i; + // We need to return here the next EAP type we should try + for (i = m_eap_index; i < m_iap_eap_array.Count(); i++) + { + // Find the first enabled EAP type (highest priority) + TEap *eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + // Convert the string to integer + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + status = data->set_copy_of_buffer(reinterpret_cast(&val), sizeof(TUint)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL: Trying EAP type: %d.\n"), val)); + break; + } + } + m_eap_index = i; + if (i >= m_iap_eap_array.Count()) + { + // Not found + // Send WLM notification because there is no way that the authentication + // can be successful if we don't have any EAP types to use... + if (m_is_client) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: No configured EAP types or all tried unsuccessfully.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // It was something else than EAP type. Read it from DB. + TRAPD(err, read_configureL( + field->get_field(), + field->get_field_length(), + data)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + +#if defined(USE_EAP_FILECONFIG) + if (m_fileconfig != 0 + && m_fileconfig->get_is_valid() == true) + { + // Here we could try the final configuration option. + status = m_fileconfig->read_configure( + field, + data); + } +#endif //#if defined(USE_EAP_FILECONFIG) + } + + m_am_tools->trace_configuration( + status, + field, + data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eapol_am_core_symbian_c::read_configureL( + eap_config_string field, + const u32_t /*field_length*/, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Create a buffer for the ascii strings - initialised with the argument + HBufC8* asciibuf = HBufC8::NewLC(128); + TPtr8 asciiString = asciibuf->Des(); + asciiString.Copy(reinterpret_cast(field)); + + // Buffer for unicode parameter + HBufC* unicodebuf = HBufC::NewLC(128); + TPtr unicodeString = unicodebuf->Des(); + + // Convert to unicode + unicodeString.Copy(asciiString); + + // Now do the database query + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + _LIT(KSQLQueryRow, "SELECT %S FROM eapol"); + sqlStatement.Format(KSQLQueryRow, &unicodeString); + + RDbView view; + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + if (view.FirstL()) + { + eap_status_e status(eap_status_process_general_error); + view.GetL(); + switch (view.ColType(1)) + { + case EDbColText: + { + unicodeString = view.ColDes(1); + // Convert to 8-bit + asciiString.Copy(unicodeString); + if (asciiString.Size() > 0) + { + status = data->set_copy_of_buffer(asciiString.Ptr(), asciiString.Size()); + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + } + else + { + // Empty field. Do nothing...data remains invalid + // and the stack knows what to do hopefully. + break; + } + } + break; + case EDbColUint32: + { + TUint value; + value = view.ColUint32(1); + status = data->set_copy_of_buffer((const unsigned char *) &value, sizeof(value)); + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + } + break; + default: + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("read_configureL: Unexpected column type.\n"))); + User::Panic(_L("EAPOL"), 1); + } + } + else + { + // Could not find parameter + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("read_configureL: Could not find configuration parameter.\n"))); + User::Leave(KErrNotFound); + } + + // Close database + CleanupStack::PopAndDestroy(4); // session & 3 buffers + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +eap_status_e eapol_am_core_symbian_c::write_configure( + const eap_configuration_field_c * const /*field*/, + eap_variable_data_c * const /*data*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_not_supported; +} + +//-------------------------------------------------- + +// +eap_status_e eapol_am_core_symbian_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_am_tools->am_set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +// +eap_status_e eapol_am_core_symbian_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_am_tools->am_cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +// +eap_status_e eapol_am_core_symbian_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_am_tools->am_cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +eap_status_e eapol_am_core_symbian_c::check_is_valid_eap_type(const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + TEap *eapType = 0; + + eap_status_e status(eap_status_illegal_eap_type); + + for (int i = 0; i < m_iap_eap_array.Count(); i++) + { + // Try next EAP type + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + // Convert the string to integer + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + if (eap_type == static_cast(val)) + { + // Allowed + status = eap_status_ok; + break; + } + } + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eapol_am_core_symbian_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + TEap *eapType = 0; + + eap_status_e status(eap_status_illegal_eap_type); + + status = eap_type_list->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + for (TInt i = 0; i < m_iap_eap_array.Count(); i++) + { + // Check if type is enabled + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + + eap_type_value_e * const eap_type = new eap_type_value_e( + static_cast(val)); + if (eap_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = eap_type_list->add_object(eap_type, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +void eapol_am_core_symbian_c::TryOpenDatabaseL(RDbNamedDatabase& aDatabase, RDbs& aSession) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::TryOpenDatabaseL()\n"))); + + // 1. Open/create a database + + // Connect to the DBMS server. + User::LeaveIfError(aSession.Connect()); + CleanupClosePushL(aSession); + // aSession and aDatabase are pushed to the cleanup stack even though they may be member + // variables of the calling class and would be closed in the destructor anyway. This ensures + // that if they are not member variables they will be closed. Closing the handle twice + // does no harm. + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database (if necessary) with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = aDatabase.Create(aSession, KDatabaseName, KSecureUIDFormat); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TryOpenDatabaseL() - Created Secure DB for eapol.dat. err=%d\n"), err )); + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(aSession, KDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(aDatabase); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + + // Create the database (if necessary) + TInt err = aDatabase.Create(fsSession, KDatabaseName); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TryOpenDatabaseL() - Created Non-Secure DB for eapol.dat. err=%d\n"), err )); + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + CleanupStack::PopAndDestroy(); // close fsSession + + User::LeaveIfError(aDatabase.Open(aSession, KDatabaseName)); + CleanupClosePushL(aDatabase); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // 2. Create the table for pre-shared keys in database (ignore error if exists) + +//// NAME /////////////////////////////////////////////////// TYPE ////////////// Constant /////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| SSID | VARBINARY(255) | KSSID |// +//| Password | VARBINARY(255) | KPassword |// +//| PSK | VARBINARY(255) | KPSK |// +////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable2, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARBINARY(255), \ + %S VARBINARY(255), \ + %S VARBINARY(255))"); + + sqlStatement.Format(KSQLCreateTable2, &KEapolPSKTableName, + &KServiceType, &KServiceIndex, &KSSID, &KPassword, &KPSK); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // buf + CleanupStack::Pop(2); // database, session + + // If compacting is not done the database will start growing + aDatabase.Compact(); +} + +//-------------------------------------------------- + +void eapol_am_core_symbian_c::OpenDatabaseL(RDbNamedDatabase& aDatabase, RDbs& aSession) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::OpenDatabaseL()\n"))); + + // Create the database (if necessary) + TRAPD(err, TryOpenDatabaseL(aDatabase, aSession)); + if (err != KErrNone) + { + // Because of error remove the database file. + RFs fsDataBaseFile; + User::LeaveIfError(fsDataBaseFile.Connect()); + CleanupClosePushL(fsDataBaseFile); + err = fsDataBaseFile.Delete(KDatabaseName); + if(err != KErrNone) + { + User::Leave(KErrCorrupt); + } + CleanupStack::PopAndDestroy(); // close fsDataBaseFile + + // Try open database again. This will leave if fails second time. + TryOpenDatabaseL(aDatabase, aSession); + } +} + +//-------------------------------------------------- + +eap_status_e eapol_am_core_symbian_c::random_error( + eap_buf_chain_wr_c * const sent_packet, + const bool forse_error, + const u32_t packet_index) +{ + EAP_UNREFERENCED_PARAMETER(packet_index); + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::random_error()\n"))); + + eap_status_e status(eap_status_ok); + u8_t *data = sent_packet->get_data(sent_packet->get_data_length()); + + crypto_random_c rand(m_am_tools); + u32_t random_guard(0); + bool error_generated(false); + u32_t minimum_index(0); + + if (m_manipulate_ethernet_header == false) + { + minimum_index = eapol_ethernet_header_wr_c::get_header_length(); + } + + for (u32_t ind = minimum_index; ind < sent_packet->get_data_length(); ind++) + { + status = rand.get_rand_bytes( + reinterpret_cast(&random_guard), + sizeof(random_guard)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This is simple limiter to the probability of an error. + // probability = m_error_probability / (2^32) + if (random_guard < m_error_probability) + { + u8_t rnd(0); + u8_t previous_data(0); + // Create an error. + status = rand.get_rand_bytes( + &rnd, + sizeof(rnd)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + previous_data = data[ind]; + data[ind] ^= rnd; + + if (previous_data != data[ind]) + { + error_generated = true; + sent_packet->set_random_error_type(eap_random_error_type_manipulate_byte); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, data[0x%04x] changed from 0x%02x to 0x%02x.\n"), + this, + packet_index, + ind, + previous_data, + data[ind])); + } + } + } + + if (error_generated == false + && forse_error == true + && sent_packet->get_data_length() > 0ul) + { + // Generate one error. + + // Random error type. + eap_random_error_type error_type = eap_random_error_type_none_keep_this_last_case; + status = rand.get_rand_bytes( + reinterpret_cast(&error_type), + sizeof(error_type)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + error_type = static_cast( + static_cast(error_type % static_cast( + eap_random_error_type_none_keep_this_last_case))); + + sent_packet->set_random_error_type(error_type); + + switch(error_type) + { + case eap_random_error_type_manipulate_byte: + { + u32_t rnd_index(0); + u8_t previous_data(0); + u32_t index(0); + + do + { + do + { + // Create an error index. + status = rand.get_rand_bytes( + reinterpret_cast(&rnd_index), + sizeof(rnd_index)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + index = (rnd_index % (sent_packet->get_data_length() - minimum_index)) + + minimum_index; + } + while(index < minimum_index + || index > sent_packet->get_buffer_length()); + + u8_t rnd(0); + // Create an error. + status = rand.get_rand_bytes( + &rnd, + sizeof(rnd)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + previous_data = data[index]; + data[index] ^= rnd; + } + while(previous_data == data[index]); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, data[0x%04x] changed from 0x%02x to 0x%02x.\n"), + this, + packet_index, + index, + previous_data, + data[index])); + + error_generated = true; + } + break; + case eap_random_error_type_change_packet_length_longer: + { + u8_t delta_length(0); + i32_t new_length(0); + + do + { + status = rand.get_rand_bytes( + reinterpret_cast(&delta_length), + sizeof(delta_length)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + new_length = static_cast(sent_packet->get_data_length() + + static_cast(delta_length)); + } + while (new_length < static_cast( + eapol_ethernet_header_wr_c::get_header_length()) + || new_length > static_cast(sent_packet->get_buffer_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, packet length changed from %lu to %lu.\n"), + this, + packet_index, + sent_packet->get_data_length(), + new_length)); + + sent_packet->set_data_length(new_length); + + error_generated = true; + } + break; + case eap_random_error_type_change_packet_length_shorter: + { + u8_t delta_length(0); + i32_t new_length(0); + + do + { + status = rand.get_rand_bytes( + reinterpret_cast(&delta_length), + sizeof(delta_length)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + delta_length %= static_cast( + sent_packet->get_data_length() + - static_cast(eapol_ethernet_header_wr_c::get_header_length())); + + if (delta_length == 0) + { + continue; + } + + new_length = static_cast( + sent_packet->get_data_length() - static_cast(delta_length)); + } + while (new_length < static_cast( + eapol_ethernet_header_wr_c::get_header_length()) + || new_length > static_cast(sent_packet->get_buffer_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TEST: random_error(): packet_index 0x%08x:%lu, packet length changed from %lu to %lu.\n"), + this, + packet_index, + sent_packet->get_data_length(), + new_length)); + + sent_packet->set_data_length(new_length); + + error_generated = true; + } + break; + default: + User::Panic(_L("EAPOL"), 1); + break; + } + } + + if (error_generated == true) + { + sent_packet->set_is_manipulated(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +eap_status_e eapol_am_core_symbian_c::create_upper_stack() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::create_upper_stack()\n"))); + + eap_status_e status(eap_status_ok); + + if (m_ethernet_core == 0) + { + m_ethernet_core = new ethernet_core_c(m_am_tools, this, m_is_client); + if (m_ethernet_core == 0 + || m_ethernet_core->get_is_valid() != true) + { + if (m_ethernet_core != 0) + { + m_ethernet_core->shutdown(); + delete m_ethernet_core; + m_ethernet_core = 0; + } + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Stack creation failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Initialise upper stack + status = m_ethernet_core->configure(); + + if (status != eap_status_ok) + { + m_ethernet_core->shutdown(); + delete m_ethernet_core; + m_ethernet_core = 0; + + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Stack creation failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + else + { + status = eap_status_already_exists; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +eap_status_e eapol_am_core_symbian_c::add_rogue_ap( + eap_array_c & rogue_ap_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_core_symbian_c::add_rogue_ap()\n"))); + + TInt err(KErrNone); + eap_rogue_ap_entry_c* entry = 0; + + TMacAddress mac; + + TRogueType type; + + for (u32_t i = 0; i < rogue_ap_list.get_object_count(); i++) + { + entry = rogue_ap_list.get_object(i); + + entry->get_mac_address(mac.iMacAddress); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Adding rogue AP - type: %d\n"), + entry->get_rogue_reason())); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Rogue MAC address"), + mac.iMacAddress, + KMacAddressLength)); + + switch (entry->get_rogue_reason()) + { + case rogue_ap_none: + // Ignore this + continue; + case rogue_ap_association_failed: + type = EInvalidAuthenticationType; + break; + case rogue_ap_timeout: + type = EAuthenticationTimeout; + break; + case rogue_ap_challenge_to_client_failed: + type = EChallengeFromAPFailed; + break; + case rogue_ap_challenge_to_ap_failed: + type = EChallengeToAPFailed; + break; + default: + // ignore others + continue; + } + + err = m_partner->AddRogueAP(mac, type); + if (err != KErrNone) + { + break; + } + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(err)); +} + +//-------------------------------------------------- + +void eapol_am_core_symbian_c::RetrievePSKL(TPSKEntry& entry) +{ + HBufC* sqlbuf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = sqlbuf->Des(); + + RDbView view; + + _LIT(KSQL, "SELECT %S, %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &KServiceType, &KServiceIndex, &KSSID, &KPassword, &KPSK, + &KEapolPSKTableName, &KServiceType, entry.indexType, &KServiceIndex, entry.index); + + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + TInt rows = view.CountL(); + + if (rows == 0) + { + // No saved PSK + User::Leave(KErrNotFound); + } + view.FirstL(); + view.GetL(); + + entry.ssid.Copy(view.ColDes8(3)); + entry.password.Copy(view.ColDes8(4)); + entry.psk.Copy(view.ColDes8(5)); + + CleanupStack::PopAndDestroy(2); // view, buf +} + +//-------------------------------------------------- + +void eapol_am_core_symbian_c::SavePSKL(TPSKEntry& entry) +{ + // Connect to CommDBif so that we can delete PSK entries that have no IAP associated anymore. + CWLanSettings* wlan = new(ELeave) CWLanSettings; + CleanupStack::PushL(wlan); + + SWLANSettings wlanSettings; + + if (wlan->Connect() != KErrNone) + { + // Could not connect to CommDB + User::Leave(KErrCouldNotConnect); + } + + HBufC* sqlbuf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = sqlbuf->Des(); + + RDbView view; + + _LIT(KSQL, "SELECT %S, %S, %S, %S, %S FROM %S"); + + sqlStatement.Format(KSQL, &KServiceType, &KServiceIndex, &KSSID, &KPassword, &KPSK, + &KEapolPSKTableName); + + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Delete old row and also rows that have no associated IAP settings. + if (view.FirstL()) + { + do { + view.GetL(); + + if ((wlan->GetWlanSettingsForService(view.ColUint32(colSet->ColNo(KServiceIndex)), wlanSettings) != KErrNone) + || (view.ColUint32(colSet->ColNo(KServiceType)) == static_cast(entry.indexType) + && view.ColUint32(colSet->ColNo(KServiceIndex)) == static_cast(entry.index))) + { + // Not found or current IAP + view.DeleteL(); + } + + } while (view.NextL() != EFalse); + } + + wlan->Disconnect(); + + view.InsertL(); + + view.SetColL(colSet->ColNo(KServiceType), (TUint)entry.indexType); + view.SetColL(colSet->ColNo(KServiceIndex), (TUint)entry.index); + view.SetColL(colSet->ColNo(KSSID), entry.ssid); + view.SetColL(colSet->ColNo(KPassword), entry.password); + view.SetColL(colSet->ColNo(KPSK), entry.psk); + + view.PutL(); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + CleanupStack::PopAndDestroy(3); // CWLanSettings, session, database + +} + + +//-------------------------------------------------- + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/core/symbian/eapol_am_core_symbian_simulator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/core/symbian/eapol_am_core_symbian_simulator.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,917 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 149 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_variable_data.h" +#include "eap_tools.h" +#include "eap_type_all.h" +#include "eapol_am_core_symbian_simulator.h" +#include "eapol_ethernet_header.h" +#include + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_am_core_symbian_c::~eapol_am_core_symbian_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_shutdown_was_called == true); + + m_am_tools->enter_global_mutex(); + delete m_ethernet_core; + m_am_tools->leave_global_mutex(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_am_core_symbian_c::eapol_am_core_symbian_c( + abs_eap_am_tools_c * const tools, + abs_eapol_am_core_symbian_c * const partner, + const bool is_client_when_true) +: m_partner(partner) +, m_ethernet_core(new ethernet_core_c(tools, this, is_client_when_true)) +, m_am_tools(tools) +, m_own_address(tools) +, m_authentication_counter(0u) +, m_error_probability(0u) +, m_is_valid(false) +, m_is_client(is_client_when_true) +, m_enable_random_errors(false) +, m_shutdown_was_called(false) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_am_tools->enter_global_mutex(); + if (m_ethernet_core != 0 + && m_ethernet_core->get_is_valid() == true) + { + set_is_valid(); + } + m_am_tools->leave_global_mutex(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_base_type_c * eapol_am_core_symbian_c::load_type(const eap_type_value_e /*type*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return 0; +} + +//-------------------------------------------------- + +#if defined(USE_EAPOL_LLC_INTERFACE) + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::packet_process( + RMBufChain& aPdu) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + const u32_t packet_length = aPdu.Length(); + + if (packet_length < eapol_ethernet_header_wr_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_too_short_message; + } + + eapol_ethernet_header_wr_c eth_header(aPdu.First()->Ptr()); + + if (eth_header.get_type() == eapol_ethernet_type_pae) + { + u8_t packet_buffer[EAP_MEM_GUARDS(EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH)]; + eap_buf_chain_rd_c response_packet( + eap_read_buffer, m_am_tools, packet_buffer, sizeof(packet_buffer), false); + u32_t offset = 0u; + RMBuf *buf = aPdu.First(); + + while(buf != 0) + { + m_am_tools->memmove(packet_buffer+offset, buf->Ptr(), buf->Length()); + offset += buf->Length(); + buf = buf->Next(); + } + + eapol_ethernet_header_wr_c eth_header(packet_buffer); + + eap_am_network_id_c receive_network_id( + m_am_tools, + eth_header.get_source()->get_address(), + eth_header.get_source()->get_address_length(), + eth_header.get_destination()->get_address(), + eth_header.get_destination()->get_address_length(), + eth_header.get_type(), + false, + false); + + if (m_own_address.get_data_length() != receive_network_id.get_destination_id()->get_data_length() + || m_am_tools->memcmp( + m_own_address.get_data(m_own_address.get_data_length()), + receive_network_id.get_destination_id()->get_data(receive_network_id.get_destination_id()->get_data_length()), + receive_network_id.get_destination_id()->get_data_length())) + { + return eap_status_wrong_network_id; + } + + if (m_ethernet_core == 0) + { + return eap_status_allocation_error; + } + + if (packet_length < eapol_ethernet_header_rd_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_process_illegal_packet_error; + } + + m_am_tools->enter_global_mutex(); + status = m_ethernet_core->packet_process( + &receive_network_id, + ð_header, + packet_length, + NULL); + m_am_tools->leave_global_mutex(); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Not supported ethernet type 0x%04x\n"), eth_header.get_type())); + status = eap_status_ethernet_type_not_supported; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +#endif //#if defined(USE_EAPOL_LLC_INTERFACE) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::packet_process( + const eap_am_network_id_c * const receive_network_id, + eapol_ethernet_header_wr_c * const eth_header, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eapol_am_core_symbian_c::packet_process(): Received packet addresses:\n"))); + + if (m_ethernet_core == 0) + { + return eap_status_allocation_error; + } + + if (packet_length < eapol_ethernet_header_rd_c::get_header_length()) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_process_illegal_packet_error; + } + + if (eth_header->get_type() == eapol_ethernet_type_pae) + { + m_am_tools->enter_global_mutex(); + status = m_ethernet_core->packet_process( + receive_network_id, + eth_header, + packet_length); + m_am_tools->leave_global_mutex(); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Not supported ethernet type 0x%04x\n"), eth_header->get_type())); + status = eap_status_ethernet_type_not_supported; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +#include "eap_crypto_api.h" + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::random_error( + eap_buf_chain_wr_c * const sent_packet) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_ok; + u32_t ind = 0u; + u8_t *data = sent_packet->get_data(sent_packet->get_data_length()); + + crypto_random_c rand(m_am_tools); + u32_t random_guard; + + for (ind = 0u; ind < sent_packet->get_data_length(); ind++) + { + status = rand.get_rand_bytes( + reinterpret_cast(&random_guard, + sizeof(random_guard)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // This is simple limiter to the probability of an error. + // probability = m_error_probability / (2^32) + if (random_guard < m_error_probability) + { + u8_t rnd; + u8_t previous_data; + // Create an error. + status = rand.get_rand_bytes( + &rnd, + sizeof(rnd)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + previous_data = data[ind]; + data[ind] ^= rnd; + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TEST: random_error() data[0x%x] changed from 0x%02x to 0x%02x.\n"), + ind, previous_data, data[ind])); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (header_offset != 0u) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); + return eap_status_process_general_error; + } + else if (header_offset+data_length != sent_packet->get_data_length()) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: packet_send: packet buffer corrupted (data_length != sent_packet->get_data_length()).\n"))); + EAP_ASSERT_ALWAYS(data_length == sent_packet->get_buffer_length()); + return eap_status_process_general_error; + } + + eap_status_e status = eap_status_process_general_error; + + if (m_enable_random_errors == true) + { + // Make a random error to the message. + random_error(sent_packet); + } + + status = m_partner->packet_send( + send_network_id, + sent_packet, + header_offset, + data_length, + buffer_length, + this, + true, + 0ul); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT u32_t eapol_am_core_symbian_c::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + const u32_t offset = m_partner->get_header_offset(MTU, trailer_length); + // (*MTU) + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return offset; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + TInt index = m_eap_type_array.Find(type); + if (index != KErrNotFound) + { + delete m_plugin_if_array[index]; + m_plugin_if_array.Remove(index); + m_eap_type_array.Remove(index); + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::eap_acknowledge(const eap_am_network_id_c * const receive_network_id) +{ + // Any Network Protocol packet is accepted as a success indication. + // This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_ethernet_core == 0) + { + return eap_status_allocation_error; + } + + m_am_tools->enter_global_mutex(); + eap_status_e status = m_ethernet_core->eap_acknowledge(receive_network_id); + m_am_tools->leave_global_mutex(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return status; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type_if, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eapol_am_core_symbian_c::load_module(%d)\n"), type)); + eap_status_e status = eap_status_process_general_error; + TBuf8<3> cue; + cue.Num(type); + CEapType *eapType = NULL; + TInt error; + // NOTE: This works now only with test_eapol simulator. In the future the index & indextype parameters + // are received from WLM. + if (is_client_when_true) + { + // We must have a trap here since the EAPOL core knows nothing about Symbian. + TRAP(error, (eapType = CEapType::NewL(cue, ELan, 666))); + } else { + TRAP(error, (eapType = CEapType::NewL(cue, ELan, 667))); + } + + if (error != KErrNone) + { + // Interface not found or implementation creation function failed + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ECom could not find/initiate implementation.\n"))); + return eap_status_allocation_error; + } + // Create the EAP protocol interface implementation. + TRAP(error, (*eap_type_if = eapType->GetStackInterfaceL(m_am_tools, partner, is_client_when_true, receive_network_id))); + + if (error != KErrNone || + *eap_type_if == 0 || + (*eap_type_if)->get_is_valid() == false) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Could not create EAP type interface instance.\n"))); + status = eap_status_allocation_error; + // Unload DLL + delete eapType; + } + else + { + status = eap_status_ok; + // Add plugin information to the member arrays. There is no need to store eap_type pointer because + // the stack takes care of its deletion. + m_plugin_if_array.Append(eapType); + m_eap_type_array.Append(type); + + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::start_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_ethernet_core == 0) + { + return eap_status_allocation_error; + } + + m_am_tools->enter_global_mutex(); + eap_status_e status = m_ethernet_core->start_authentication(receive_network_id, is_client_when_true); + m_am_tools->leave_global_mutex(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::send_logoff(const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_ethernet_core == 0) + { + return eap_status_allocation_error; + } + + m_am_tools->enter_global_mutex(); + eap_status_e status = m_ethernet_core->send_logoff(receive_network_id); + m_am_tools->leave_global_mutex(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::configure() +{ + m_am_tools->enter_global_mutex(); + eap_status_e status = m_ethernet_core->configure(); + m_am_tools->leave_global_mutex(); + + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_disable_traces(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_disable_traces.get_field(), + &EAP_TRACE_disable_traces); + if (status == eap_status_ok + && EAP_TRACE_disable_traces.get_is_valid() == true) + { + u32_t *disable_traces = reinterpret_cast(EAP_TRACE_disable_traces.get_data(sizeof(u32_t)); + if (disable_traces != 0 + && *disable_traces != 0) + { + m_am_tools->set_trace_mask( + eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_error + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_enable_function_traces(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_enable_function_traces.get_field(), + &EAP_TRACE_enable_function_traces); + if (status == eap_status_ok + && EAP_TRACE_enable_function_traces.get_is_valid() == true) + { + u32_t *enable_function_traces = reinterpret_cast(EAP_TRACE_enable_function_traces.get_data(sizeof(u32_t)); + if (enable_function_traces != 0 + && *enable_function_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | eap_am_tools_c::eap_trace_mask_functions + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_ERROR_TEST_enable_random_errors(m_am_tools); + + status = read_configure( + cf_str_EAP_ERROR_TEST_enable_random_errors.get_field(), + &EAP_ERROR_TEST_enable_random_errors); + if (status == eap_status_ok + && EAP_ERROR_TEST_enable_random_errors.get_is_valid() == true) + { + u32_t *enable_random_errors = reinterpret_cast(EAP_ERROR_TEST_enable_random_errors.get_data(sizeof(u32_t)); + if (enable_random_errors != 0 + && *enable_random_errors != 0) + { + m_enable_random_errors = true; + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_ERROR_TEST_error_probability(m_am_tools); + + status = read_configure( + cf_str_EAP_ERROR_TEST_error_probability.get_field(), + &EAP_ERROR_TEST_error_probability); + if (status == eap_status_ok + && EAP_ERROR_TEST_error_probability.get_is_valid() == true) + { + u32_t *error_probability = reinterpret_cast(EAP_ERROR_TEST_error_probability.get_data(sizeof(u32_t)); + if (error_probability != 0) + { + m_error_probability = *error_probability; + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c trace_output_file(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_output_file_name.get_field(), + &trace_output_file); + if (status == eap_status_ok + && trace_output_file.get_is_valid() == true) + { + status = m_am_tools->set_trace_file_name(&trace_output_file); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_activate_only_trace_masks_always_and_error(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_activate_only_trace_masks_always_and_error.get_field(), + &EAP_TRACE_activate_only_trace_masks_always_and_error); + if (status == eap_status_ok + && EAP_TRACE_activate_only_trace_masks_always_and_error.get_is_valid() == true) + { + u32_t *activate_trace_mask_always + = reinterpret_cast(EAP_TRACE_activate_only_trace_masks_always_and_error.get_data(sizeof(u32_t)); + if (activate_trace_mask_always != 0 + && *activate_trace_mask_always != 0) + { + m_am_tools->set_trace_mask( + eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_error + ); + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_activate_trace_on_error(m_am_tools); + + status = read_configure( + cf_str_EAP_TRACE_activate_trace_on_error.get_field(), + &EAP_TRACE_activate_trace_on_error); + if (status == eap_status_ok + && EAP_TRACE_activate_trace_on_error.get_is_valid() == true) + { + u32_t *activate_trace_on_error = reinterpret_cast(EAP_TRACE_activate_trace_on_error.get_data(sizeof(u32_t)); + if (activate_trace_on_error != 0 + && *activate_trace_on_error != 0) + { + m_am_tools->set_activate_trace_on_error(); + } + } + } + + //---------------------------------------------------------- + + + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::shutdown() +{ + m_am_tools->enter_global_mutex(); + m_ethernet_core->shutdown(); + m_am_tools->leave_global_mutex(); + + // Unload all loaded plugins + for(int i = 0; i < m_plugin_if_array.Count(); i++) + { + delete m_plugin_if_array[i]; + } + m_plugin_if_array.Close(); + m_eap_type_array.Close(); + + m_shutdown_was_called = true; + + return eap_status_ok; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->packet_data_crypto_keys(send_network_id, master_session_key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- +eap_status_e eapol_am_core_symbian_c::packet_data_session_key( + const eap_am_network_id_c * const /*send_network_id*/, + const eapol_session_key_c * const /*key*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + switch (key_type) + { + case eapol_key_type_wep_broadcast: + // m_partner->SetWepKey(key, key_length, key_index) + break; + case eapol_key_type_wep_unicast: + //m_partner->SetWepKey(key, key_length, key_index | 0x80) + break; + default: + return eap_status_not_supported; + } + //TInt status = m_partner->SetKey(EWepKey, master_session_length, master_session_key) + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + const eap_status_e status = m_partner->read_configure(field, data); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + const eap_status_e status = m_partner->write_configure(field, data); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(p_initializer); + EAP_UNREFERENCED_PARAMETER(p_id); + EAP_UNREFERENCED_PARAMETER(p_data); + EAP_UNREFERENCED_PARAMETER(p_time_ms); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_am_tools->am_set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(p_initializer); + EAP_UNREFERENCED_PARAMETER(p_id); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_am_tools->am_cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_am_tools->am_cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::check_is_valid_eap_type(const eap_type_value_e /*eap_type*/) +{ + +#if defined(USE_EAP_TYPE_GSMSIM) + if (eap_type == eap_type_gsmsim) + { + return eap_status_ok; + } + else +#endif +#if defined(USE_SAESIM_EAP_TYPE) + if (eap_type == eap_type_saesim) + { + return eap_status_ok; + } + else +#endif +#if defined(USE_DUMMY_SIM_EAP_TYPE) + if (eap_type == eap_type_sim) + { + return eap_status_ok; + } + else +#endif + { + return eap_status_illegal_eap_type; + } + +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_core_symbian_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + eap_type_value_e eap_type = eap_type_none; + + eap_type_list->reset(); + + eap_status_e status = eap_status_type_does_not_exists_error; + +#if defined(USE_TLS_EAP_TYPE) + { + eap_type = eap_type_tls; + status = eap_type_list->add_data(&eap_type, sizeof(eap_type)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif +#if defined(USE_PEAP_EAP_TYPE) + { + eap_type = eap_type_peap; + status = eap_type_list->add_data(&eap_type, sizeof(eap_type)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif +#if defined(USE_EAP_TYPE_GSMSIM) + { + eap_type = eap_type_gsmsim; + status = eap_type_list->add_data(&eap_type, sizeof(eap_type)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif +#if defined(USE_SAESIM_EAP_TYPE) + { + eap_type = eap_type_saesim; + status = eap_type_list->add_data(&eap_type, sizeof(eap_type)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif +#if defined(USE_MSCHAPV2_EAP_TYPE) + { + eap_type = eap_type_mschapv2; + status = eap_type_list->add_data(&eap_type, sizeof(eap_type)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif +#if defined(USE_DUMMY_SIM_EAP_TYPE) + { + eap_type = eap_type_sim; + status = eap_type_list->add_data(&eap_type, sizeof(eap_type)); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#endif + + if (eap_type == eap_type_none) + { + status = eap_type_list->add_data(&eap_type, sizeof(eap_type)); + } + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/core/symbian/eapol_am_core_symbian_wlm.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/core/symbian/eapol_am_core_symbian_wlm.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 150 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include +#include "eap_am_memory.h" +#include "eapol_am_core_symbian_wlm.h" +#include "eapol_am_core_symbian.h" + +eapol_am_core_symbian_wlm_c::~eapol_am_core_symbian_wlm_c() +{ + delete iEapolCore; +} + +eapol_am_core_symbian_wlm_c::eapol_am_core_symbian_wlm_c() +: iEapolCore(0) +, iLogoffCalled(ETrue) +{ +} + +EXPORT_C eapol_am_core_symbian_wlm_c* eapol_am_core_symbian_wlm_c::NewL(abs_eapol_am_core_symbian_c* const aPartner, const bool aIsClient) +{ + eapol_am_core_symbian_wlm_c* self = new(ELeave) eapol_am_core_symbian_wlm_c; + CleanupStack::PushL(self); + self->ConstructL(aPartner, aIsClient); + CleanupStack::Pop(); + return self; +} + +void eapol_am_core_symbian_wlm_c::ConstructL(abs_eapol_am_core_symbian_c* const aPartner, + const bool aIsClient) +{ + iEapolCore = eapol_am_core_symbian_c::NewL(aPartner, aIsClient); +} + +EXPORT_C TInt eapol_am_core_symbian_wlm_c::ReceivePacket(const TUint aLength, const TUint8* const aData) +{ + return iEapolCore->ReceivePacket(aLength, aData); +} + + +EXPORT_C TInt eapol_am_core_symbian_wlm_c::start_authentication(const TIndexType aIndexType, + const TUint aIndex, + const TMacAddress& aLocalAddress, + const TMacAddress& aRemoteAddress) +{ + __ASSERT_DEBUG(iLogoffCalled, User::Panic(_L("EAPOL"), KErrGeneral)); + iLogoffCalled = EFalse; + return iEapolCore->start_authentication(aIndexType, aIndex, aLocalAddress, aRemoteAddress); +} + +EXPORT_C TInt eapol_am_core_symbian_wlm_c::send_logoff(const TMacAddress& aLocalAddress, + const TMacAddress& aRemoteAddress) +{ + iLogoffCalled = ETrue; + return iEapolCore->send_logoff(aLocalAddress, aRemoteAddress); +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/core/symbian/eapol_am_wlan_authentication_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/core/symbian/eapol_am_wlan_authentication_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3119 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 151 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include "eapol_am_wlan_authentication_symbian.h" +#include "abs_eapol_am_wlan_authentication.h" + +#include "eap_header_string.h" +//#include "eap_type_all.h" +#include "eap_config.h" +#include "eap_file_config.h" +#include "eap_am_file_input_symbian.h" +#include "eap_type_selection.h" +#include "eapol_key_types.h" +#include "eap_timer_queue.h" +#include "eap_crypto_api.h" +#include "abs_eapol_wlan_database_reference_if.h" +#include "abs_eap_state_notification.h" +#include "eap_state_notification.h" +#include "eap_automatic_variable.h" +#include "eap_base_type.h" + +#include "EapolDbDefaults.h" +#include "EapolDbParameterNames.h" + +const TUint KMaxSqlQueryLength = 2048; + +#ifdef USE_EAP_EXPANDED_TYPES + +const TUint KExpandedEAPSize = 8; + +#else + +const TUint KMaxEapCueLength = 3; + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_am_wlan_authentication_symbian_c::~eapol_am_wlan_authentication_symbian_c() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::~eapol_am_wlan_authentication_symbian_c(): this = 0x%08x\n"), + this)); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eapol_am_wlan_authentication_symbian_c::eapol_am_wlan_authentication_symbian_c( + abs_eap_am_tools_c * const tools, + const bool is_client_when_true, + const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference) +: CActive(CActive::EPriorityStandard) +, m_am_partner(0) +#if defined(USE_EAP_SIMPLE_CONFIG) +, m_configuration_if(0) +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) +, m_am_tools(tools) +, m_fileconfig(0) +, m_SSID(tools) +, m_wpa_preshared_key(tools) +, m_wpa_preshared_key_hash(tools) +, m_wlan_database_reference(wlan_database_reference) +#ifdef USE_EAP_EXPANDED_TYPES +, m_eap_type_array(tools) +#endif +, m_receive_network_id(tools) +, m_security_mode(Wpa) +, m_selected_eapol_key_authentication_type(eapol_key_authentication_type_none) +, m_WPA_override_enabled(false) +, m_is_client(is_client_when_true) +, m_is_valid(false) + +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_is_valid = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eapol_am_wlan_authentication_symbian_c::get_is_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_is_valid; +} + +//-------------------------------------------------- + +void eapol_am_wlan_authentication_symbian_c::TryInitDatabaseL() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::TryOpenDatabaseL()\n"))); + + // 1. Open/create a database + RDbNamedDatabase db; + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database (if necessary) with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = db.Create(m_session, KDatabaseName, KSecureUIDFormat); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TryOpenDatabaseL() - Created Secure DB for eapol.dat. err=%d\n"), err )); + + if(err == KErrNone) + { + db.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(db.Open(m_session, KDatabaseName, KSecureUIDFormat)); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + // Create the database (if necessary) + TInt err = db.Create(m_fs, KDatabaseName); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TryOpenDatabaseL() - Created Non-Secure DB for eapol.dat. err=%d\n"), err )); + + if(err == KErrNone) + { + db.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(db.Open(m_session, KDatabaseName)); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + CleanupClosePushL(db); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // 2. Create the table for pre-shared keys in database (ignore error if exists) + + //// NAME /////////////////////////////////////////////////// TYPE ////////////// Constant /////// + //| ServiceType | UNSIGNED INTEGER | KServiceType |// + //| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// + //| SSID | VARBINARY(255) | KSSID |// + //| Password | VARBINARY(255) | KPassword |// + //| PSK | VARBINARY(255) | KPSK |// + ////////////////////////////////////////////////////////////////////////////////////////////////// + _LIT(KSQLCreateTable2, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARBINARY(255), \ + %S VARBINARY(255), \ + %S VARBINARY(255))"); + sqlStatement.Format(KSQLCreateTable2, &KEapolPSKTableName, + &KServiceType, &KServiceIndex, &KSSID, &KPassword, &KPSK); + err = db.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // buf + + // If compacting is not done the database will start growing + db.Compact(); + + CleanupStack::PopAndDestroy(); // Close database +} + +//-------------------------------------------------- + +void eapol_am_wlan_authentication_symbian_c::InitDatabaseL() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::OpenDatabaseL()\n"))); + + // Create the database (if necessary) + TRAPD(err, TryInitDatabaseL()); + if (err != KErrNone) + { + // Because of error remove the database file. + err = m_fs.Delete(KDatabaseName); + if(err != KErrNone) + { + User::Leave(KErrCorrupt); + } + + // Try open database again. This will leave if fails second time. + TryInitDatabaseL(); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::configure(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + TInt error(KErrNone); + + // Open the database session + error = m_session.Connect(); + if (error != KErrNone) + { + eap_status_e status(m_am_tools->convert_am_error_to_eapol_error(error)); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RDbs::Connect() failed %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Database session initialized...\n"))); + + // Connect to FS + error = m_fs.Connect(); + if (error != KErrNone) + { + eap_status_e status(m_am_tools->convert_am_error_to_eapol_error(error)); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RFs::Connect() failed %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Fileserver session initialized...\n"))); + + // Initialize database + TRAPD(err, InitDatabaseL()); + if (err != KErrNone) + { + eap_status_e status(m_am_tools->convert_am_error_to_eapol_error(error)); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("InitDatabaseL failed %d.\n"), + status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Database initialized...\n"))); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_FILECONFIG) + { + eap_am_file_input_symbian_c * const fileio = new eap_am_file_input_symbian_c(m_am_tools); + + eap_automatic_variable_c automatic_fileio(m_am_tools, fileio); + + if (fileio != 0 + && fileio->get_is_valid() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Initialize file configuration.\n"))); + + eap_variable_data_c file_name_c_data(m_am_tools); + + eap_status_e status(eap_status_process_general_error); + + { + #if defined(EAPOL_SYMBIAN_VERSION_7_0_s) + eap_const_string const FILECONFIG_FILENAME_C + = "c:\\system\\data\\eap.conf"; + #else + eap_const_string const FILECONFIG_FILENAME_C + = "c:\\private\\101F8EC5\\eap.conf"; + #endif + + status = file_name_c_data.set_copy_of_buffer( + FILECONFIG_FILENAME_C, + m_am_tools->strlen(FILECONFIG_FILENAME_C)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = file_name_c_data.add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_variable_data_c file_name_z_data(m_am_tools); + + { + #if defined(EAPOL_SYMBIAN_VERSION_7_0_s) + eap_const_string const FILECONFIG_FILENAME_Z + = "z:\\system\\data\\eap.conf"; + #else + eap_const_string const FILECONFIG_FILENAME_Z + = "z:\\private\\101F8EC5\\eap.conf"; + #endif + + status = file_name_z_data.set_copy_of_buffer( + FILECONFIG_FILENAME_Z, + m_am_tools->strlen(FILECONFIG_FILENAME_Z)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = file_name_z_data.add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + + if (status == eap_status_ok) + { + // First try open from C: disk. + status = fileio->file_open( + &file_name_c_data, + eap_file_io_direction_read); + if (status == eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Opens configure file %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + else if (status != eap_status_ok) + { + // Second try open from Z: disk. + status = fileio->file_open( + &file_name_z_data, + eap_file_io_direction_read); + if (status == eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Opens configure file %s\n"), + file_name_z_data.get_data(file_name_z_data.get_data_length()))); + } + } + + if (status == eap_status_ok) + { + // Some of the files were opened. + + m_fileconfig = new eap_file_config_c(m_am_tools); + if (m_fileconfig != 0 + && m_fileconfig->get_is_valid() == true) + { + status = m_fileconfig->configure(fileio); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Configure read from %s failed.\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Configure read from %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + } + else + { + // No file configuration. + delete m_fileconfig; + m_fileconfig = 0; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Cannot create configure object for file %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Cannot open configure file neither %s nor %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()), + file_name_z_data.get_data(file_name_z_data.get_data_length()))); + } + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Skips file configuration.\n"))); + } + } +#endif //#if defined(USE_EAP_FILECONFIG) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_EAP_FILE_TRACE) + { + eap_variable_data_c trace_output_file(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_output_file_name.get_field(), + &trace_output_file); + if (status == eap_status_ok + && trace_output_file.get_is_valid_data() == true) + { + status = m_am_tools->set_trace_file_name(&trace_output_file); + if (status == eap_status_ok) + { + // OK, set the default trace mask. + m_am_tools->set_trace_mask( + eap_am_tools_c::eap_trace_mask_debug + | eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_error + | eap_am_tools_c::eap_trace_mask_message_data); + } + } + } +#endif //#if defined(USE_EAP_FILE_TRACE) + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + eap_variable_data_c EAP_TRACE_enable_timer_queue_traces(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_enable_timer_queue_traces.get_field(), + &EAP_TRACE_enable_timer_queue_traces); + if (status == eap_status_ok + && EAP_TRACE_enable_timer_queue_traces.get_is_valid_data() == true) + { + u32_t *enable_timer_queue_traces = reinterpret_cast( + EAP_TRACE_enable_timer_queue_traces.get_data(sizeof(u32_t))); + if (enable_timer_queue_traces != 0 + && *enable_timer_queue_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | eap_am_tools_c::eap_trace_mask_timer_queue + ); + } + } + } + + { + eap_variable_data_c EAP_TRACE_enable_function_traces(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_enable_function_traces.get_field(), + &EAP_TRACE_enable_function_traces); + if (status == eap_status_ok + && EAP_TRACE_enable_function_traces.get_is_valid_data() == true) + { + u32_t *enable_function_traces = reinterpret_cast( + EAP_TRACE_enable_function_traces.get_data(sizeof(u32_t))); + if (enable_function_traces != 0 + && *enable_function_traces != 0) + { + m_am_tools->set_trace_mask( + m_am_tools->get_trace_mask() + | eap_am_tools_c::eap_trace_mask_functions + ); + } + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Created timer...\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eapol_am_wlan_authentication_symbian_c::reset_eap_plugins() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::reset_eap_plugins(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + // Unload all loaded plugins + for(int ind = 0; ind < m_plugin_if_array.Count(); ind++) + { + delete m_plugin_if_array[ind]; + } + + m_plugin_if_array.Close(); + +#ifdef USE_EAP_EXPANDED_TYPES + + m_enabled_expanded_eap_array.ResetAndDestroy(); + + m_disabled_expanded_eap_array.ResetAndDestroy(); + + m_eap_type_array.reset(); + +#else + + // Delete the IAP EAP type info array + m_iap_eap_array.ResetAndDestroy(); + + m_eap_type_array.Close(); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::shutdown(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + m_session.Close(); + m_fs.Close(); + + delete m_fileconfig; + m_fileconfig = 0; + + (void) reset_eap_plugins(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::set_am_partner( + abs_eapol_am_wlan_authentication_c * am_partner +#if defined(USE_EAP_SIMPLE_CONFIG) + , abs_eap_configuration_if_c * const configuration_if +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_simulator_c::set_am_partner(): %s, this = 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this)); + + m_am_partner = am_partner; + +#if defined(USE_EAP_SIMPLE_CONFIG) + m_configuration_if = configuration_if; +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::reset_eap_configuration() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::reset_eap_configuration(): %s, this = 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this)); + + TRAPD(error, ReadEAPSettingsL()); + if (error != KErrNone) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP settings reading from CommDb failed or cancelled(err %d).\n"), error)); + + eap_status_e status(m_am_tools->convert_am_error_to_eapol_error(error)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +void eapol_am_wlan_authentication_symbian_c::send_error_notification(const eap_status_e error) +{ + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::send_error_notification, error=%d\n"), + error)); + + eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error); + + if (error == eap_status_user_cancel_authentication) + { + general_state_variable = eap_general_state_authentication_cancelled; + } + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + // Notifies the lower level of an authentication error. + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, + eap_type_none, + eap_state_none, + general_state_variable, + 0, + false); + + notification.set_authentication_error(error); + + m_am_partner->state_notification(¬ification); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::set_wlan_parameters( + const eap_variable_data_c * const SSID, + const bool WPA_override_enabled, + const eap_variable_data_c * const wpa_preshared_key, + const eapol_key_authentication_type_e selected_eapol_key_authentication_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::set_wlan_parameters(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + m_WPA_override_enabled = WPA_override_enabled; + + m_selected_eapol_key_authentication_type = selected_eapol_key_authentication_type; + + eap_status_e status = m_SSID.set_copy_of_buffer(SSID); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_wpa_preshared_key.set_copy_of_buffer(wpa_preshared_key); + if (status != eap_status_ok) + { + send_error_notification(eap_status_key_error); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +void eapol_am_wlan_authentication_symbian_c::state_notification( + const abs_eap_state_notification_c * const state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(state); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::association( + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::association(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + eap_status_e status = m_receive_network_id.set_copy_of_network_id(receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::disassociation( + const eap_am_network_id_c * const /* receive_network_id */ ///< source includes remote address, destination includes local address. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::disassociation(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +#ifdef USE_EAP_EXPANDED_TYPES + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::get_selected_eap_types( + eap_array_c * const selected_eap_types) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::get_selected_eap_types(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + eap_status_e status = selected_eap_types->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + // We need to return only the EAP types available as enabled types. + // It means only the ones available in m_enabled_expanded_eap_array. + + for (TInt i = 0; i < m_enabled_expanded_eap_array.Count(); i++) + { + TBuf8 tmpExpEAP(m_enabled_expanded_eap_array[i]->EapExpandedType); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::get_selected_eap_types:Enabled expanded EAP type at index=%d\n"), + i)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Enabled expanded EAP type"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + + // This is for one expanded EAP type (for the above one). + eap_expanded_type_c expandedEAPType; + + // Read the expanded EAP type details from an item in m_enabled_expanded_eap_array. + status = eap_expanded_type_c::read_type(m_am_tools, + 0, + tmpExpEAP.Ptr(), + tmpExpEAP.Size(), + &expandedEAPType); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Add EAP-type to list. + eap_type_selection_c * selection = new eap_type_selection_c( + m_am_tools, + expandedEAPType, + true); + if (selection != 0) + { + status = selected_eap_types->add_object(selection, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("get_selected_eap_types(): added EAP-type=0x%08x=%s\n"), + expandedEAPType.get_vendor_type(), + eap_string.get_eap_type_string(expandedEAPType))); + } + else + { + // On error we ignore this EAP-type. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Some problem with EAP type at index %d in m_enabled_expanded_eap_array\n"), + i)); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +#else // for non-expanded (normal EAP types) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::get_selected_eap_types( + eap_array_c * const selected_eap_types) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::get_selected_eap_types(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + eap_status_e status = selected_eap_types->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + TEap *eapType = 0; + + for (TInt i = 0; i < m_iap_eap_array.Count(); i++) + { + // Check if type is enabled + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("get_selected_eap_types(): adds EAP-type=0x%08x=%s\n"), + static_cast(val), + eap_string.get_eap_type_string( + static_cast( + static_cast(val))))); + + // Add EAP-type to list. + eap_type_selection_c * selection = new eap_type_selection_c( + m_am_tools, + static_cast(static_cast(val)), + true); + if (selection != 0) + { + status = selected_eap_types->add_object(selection, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // On error we ignore this EAP-type. + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::get_wlan_configuration( + eap_variable_data_c * const wpa_preshared_key_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::get_wlan_configuration(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + eap_status_e status = wpa_preshared_key_hash->set_copy_of_buffer(&m_wpa_preshared_key_hash); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::authentication_finished( + const bool when_true_successfull, + const eap_type_value_e eap_type, + const eapol_key_authentication_type_e authentication_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::authentication_finished(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + if (when_true_successfull == true) + { + if (authentication_type != eapol_key_authentication_type_RSNA_PSK + && authentication_type != eapol_key_authentication_type_WPA_PSK) + { + +#ifdef USE_EAP_EXPANDED_TYPES + + // This moves the successful type to be the top priority type in IAP settings. + TRAPD(err, SetToTopPriorityL(eap_type)); + if (err != KErrNone) + { + // Just log the error. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("state_notification: SetToTopPriorityL() Expanded EAP type - leave with error=%d!\n"), + err)); + } + +#else // For normal EAP types + + TEap eap; + eap.Enabled = ETrue; + eap.UID.Num(static_cast(convert_eap_type_to_u32_t(eap_type))); + + // This moves the successful type to be the top priority type in IAP settings. + TRAPD(err, SetToTopPriorityL(&eap)); + if (err != KErrNone) + { + // Just log the error. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("state_notification: SetToTopPriorityL leaved!\n"))); + } + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + // Move the active eap type index to the first type + m_am_partner->set_current_eap_index(0ul); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +eap_status_e eapol_am_wlan_authentication_symbian_c::read_database_reference_values( + TIndexType * const type, + TUint * const index) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::read_database_reference_values(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + eap_variable_data_c database_reference(m_am_tools); + + eap_status_e status = m_wlan_database_reference->get_wlan_database_reference_values(&database_reference); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + const eapol_wlan_database_reference_values_s * const database_reference_values + = reinterpret_cast( + database_reference.get_data(sizeof(eapol_wlan_database_reference_values_s))); + if (database_reference_values == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *type = static_cast(database_reference_values->m_database_index_type); + *index = database_reference_values->m_database_index; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::read_database_reference_values(): Type=%d, Index=%d.\n"), + *type, + *index)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type_if, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::load_module(type %d=%s, tunneling_type %d=%s)\n"), + convert_eap_type_to_u32_t(type), + eap_header_string_c::get_eap_type_string(type), + convert_eap_type_to_u32_t(tunneling_type), + eap_header_string_c::get_eap_type_string(tunneling_type))); + + eap_status_e status(eap_status_process_general_error); + +#ifdef USE_EAP_EXPANDED_TYPES + + CEapType* eapType = 0; + TInt error(KErrNone); + + // Check if this EAP type has already been loaded + TInt eapArrayIndex = find( + &m_eap_type_array, + &type, + m_am_tools); + + if (eapArrayIndex >= 0) + { + // We found the entry in the array. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::load_module(type %d=%s, tunneling_type %d=%s) already loaded.\n"), + convert_eap_type_to_u32_t(type), + eap_header_string_c::get_eap_type_string(type), + convert_eap_type_to_u32_t(tunneling_type), + eap_header_string_c::get_eap_type_string(tunneling_type))); + + // Yep. It was loaded already. + eapType = m_plugin_if_array[eapArrayIndex]; + } + else + { + TIndexType index_type(ELan); + TUint index(0UL); + + status = read_database_reference_values( + &index_type, + &index); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::load_module(type %d=%s, tunneling_type %d=%s) load new, index type=%d, index=%d.\n"), + convert_eap_type_to_u32_t(type), + eap_header_string_c::get_eap_type_string(type), + convert_eap_type_to_u32_t(tunneling_type), + eap_header_string_c::get_eap_type_string(tunneling_type), + index_type, + index)); + + TBuf8 ExpandedCue; + + // Some indirect way of forming the 8 byte string of an EAP type for the cue is needed here. + TUint8 tmpExpCue[KExpandedEAPSize]; + + // This is to make the tmpExpCue in 8 byte string with correct vendor type and vendor id details. + status = eap_expanded_type_c::write_type(m_am_tools, + 0, // index should be zero here. + tmpExpCue, + KExpandedEAPSize, + true, + type); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("load_module: eap_expanded_type_c::write_type failed \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Now copy the 8 byte string to the real expanded cue. + ExpandedCue.Copy(tmpExpCue, KExpandedEAPSize); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL:eapol_am_wlan_authentication_symbian_c::load_module: Expanded CUE:"), + ExpandedCue.Ptr(), + ExpandedCue.Size())); + + + // We must have a trap here since the EAPOL core knows nothing about Symbian. + TRAP(error, (eapType = CEapType::NewL( + ExpandedCue, + index_type, + index))); + if (error != KErrNone + || eapType == 0) + { + // Interface not found or implementation creation function failed + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ECom could not find/initiate implementation.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + +#else // For normal EAP types + + TBuf8 cue; + cue.Num(static_cast(convert_eap_type_to_u32_t(type))); + CEapType* eapType = 0; + TInt error(KErrNone); + + // Check if this EAP type has already been loaded + TInt eapArrayIndex = m_eap_type_array.Find(type); + if (eapArrayIndex != KErrNotFound) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::load_module(type %d=%s, tunneling_type %d=%s) already loaded.\n"), + convert_eap_type_to_u32_t(type), + eap_header_string_c::get_eap_type_string(type), + convert_eap_type_to_u32_t(tunneling_type), + eap_header_string_c::get_eap_type_string(tunneling_type))); + + // Yep. It was loaded already. + eapType = m_plugin_if_array[eapArrayIndex]; + } + else + { + TIndexType index_type(ELan); + TUint index(0UL); + + status = read_database_reference_values( + &index_type, + &index); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::load_module(type %d=%s, tunneling_type %d=%s) load new, index type=%d, index=%d.\n"), + convert_eap_type_to_u32_t(type), + eap_header_string_c::get_eap_type_string(type), + convert_eap_type_to_u32_t(tunneling_type), + eap_header_string_c::get_eap_type_string(tunneling_type), + index_type, + index)); + + // We must have a trap here since the EAPOL core knows nothing about Symbian. + TRAP(error, (eapType = CEapType::NewL( + cue, + index_type, + index))); + if (error != KErrNone + || eapType == 0) + { + // Interface not found or implementation creation function failed + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ECom could not find/initiate implementation.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + // Set the tunneling type + eapType->SetTunnelingType(convert_eap_type_to_u32_t(tunneling_type)); + + // Create the EAP protocol interface implementation. + +#ifdef USE_EAP_SIMPLE_CONFIG + + TRAP(error, (*eap_type_if = eapType->GetStackInterfaceL(m_am_tools, + partner, + is_client_when_true, + receive_network_id, + this))); + +#else + + TRAP(error, (*eap_type_if = eapType->GetStackInterfaceL(m_am_tools, + partner, + is_client_when_true, + receive_network_id))); + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG + + + if (error != KErrNone + || *eap_type_if == 0 + || (*eap_type_if)->get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Could not create EAP type interface instance. Error: %d\n"), error)); + + status = eap_status_allocation_error; + // Unload DLL (two ways, depending whether this type was already loaded...) + if (eapArrayIndex == KErrNotFound) + { + // No need to call shutdown here because GetStackInterfaceL has done it. + delete eapType; + } + else + { + unload_module(type); + } + // Note: even in error cases eap_core_c deletes eap_type_if + } + else + { + status = eap_status_ok; + if (eapArrayIndex == KErrNotFound) + { + // Add plugin information to the member arrays. There is no need to store eap_type pointer because + // the stack takes care of its deletion. + if (m_plugin_if_array.Append(eapType) != KErrNone) + { + delete eapType; + status = eap_status_allocation_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#ifdef USE_EAP_EXPANDED_TYPES + + eap_type_value_e * tmpEAPType = new eap_type_value_e(); + if(tmpEAPType == NULL) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::load_module() eap_type_value_e creation failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *tmpEAPType = type; + + status = m_eap_type_array.add_object(tmpEAPType, true); + + if (status != eap_status_ok) + +#else // For normal EAP type. + + if (m_eap_type_array.Append(type) != KErrNone) + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + { + // Remove the eap type added just previously + m_plugin_if_array.Remove(m_plugin_if_array.Count() - 1); + delete eapType; + status = eap_status_allocation_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::unload_module( + const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::unload_module(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + eap_status_e status(eap_status_type_does_not_exists_error); + +#ifdef USE_EAP_EXPANDED_TYPES + + // Check if this EAP type has already been loaded + TInt index = find( + &m_eap_type_array, + &type, + m_am_tools); + + if (index >= 0) + { + // EAP was loaded before. + + delete m_plugin_if_array[index]; + m_plugin_if_array.Remove(index); + + status = m_eap_type_array.remove_object(index); + } + +#else // For normal EAP types. + + TInt index = m_eap_type_array.Find(type); + if (index != KErrNotFound) + { + delete m_plugin_if_array[index]; + m_plugin_if_array.Remove(index); + m_eap_type_array.Remove(index); + status = eap_status_ok; + } + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT_ALWAYS(data != NULL); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::read_configure(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + // Trap must be set here because the OS independent portion of EAPOL + // that calls this function does not know anything about Symbian. + eap_status_e status(eap_status_ok); + + // Check if the wanted parameter is default type + + eap_variable_data_c wanted_field(m_am_tools); + eap_variable_data_c type_field(m_am_tools); + + status = wanted_field.set_buffer( + field->get_field(), + field->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = type_field.set_buffer( + cf_str_EAP_default_type_hex_data.get_field()->get_field(), + cf_str_EAP_default_type_hex_data.get_field()->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + eap_type_value_e aSelectedEapType; + +#ifdef USE_EAP_EXPANDED_TYPES + + if (!wanted_field.compare(&type_field)) + { + TInt ind; + + // First check do we have read configuration from databases. + if (m_enabled_expanded_eap_array.Count() == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP settings not read from CommsDat\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Now we need to return here the next EAP type we should try + for (ind = m_am_partner->get_current_eap_index(); ind < m_enabled_expanded_eap_array.Count(); ind++) + { + // Find the highest priority EAP with index "ind". + + TBuf8 tmpExpEAP(m_enabled_expanded_eap_array[ind]->EapExpandedType); + + status = data->set_copy_of_buffer(tmpExpEAP.Ptr(), tmpExpEAP.Size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL:eapol_am_wlan_authentication_symbian_c::read_configure: Trying EAP type:"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + status = eap_expanded_type_c::read_type(m_am_tools, + 0, + tmpExpEAP.Ptr(), + tmpExpEAP.Size(), + &aSelectedEapType); + if (status == eap_status_ok) + { + break; + } + } + + // Set the index of new EAP type we are trying now. + m_am_partner->set_current_eap_index(ind); + + if (ind >= m_enabled_expanded_eap_array.Count()) + { + // Not found any other EAP type as enabled. + // Send WLM notification because there is no way that the authentication + // can be successful if we don't have any EAP types to use... + if (m_is_client) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: read_configure: No configured EAP types or all tried unsuccessfully.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#else // For normal non-expanded EAP + + if (!wanted_field.compare(&type_field)) + { + TInt ind; + + // First check do we have read configuration from databases. + if (m_iap_eap_array.Count() == 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP settings not read from CommDb\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // We need to return here the next EAP type we should try + for (ind = m_am_partner->get_current_eap_index(); ind < m_iap_eap_array.Count(); ind++) + { + // Find the first enabled EAP type (highest priority) + TEap *eapType = m_iap_eap_array[ind]; + if (eapType->Enabled == 1) + { + // Convert the string to integer + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + status = data->set_copy_of_buffer(reinterpret_cast(&val), sizeof(TUint)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL: Trying EAP type: %d.\n"), val)); + aSelectedEapType = val; + break; + } + } + + m_am_partner->set_current_eap_index(ind); + if (ind >= m_iap_eap_array.Count()) + { + // Not found + // Send WLM notification because there is no way that the authentication + // can be successful if we don't have any EAP types to use... + if (m_is_client) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: No configured EAP types or all tried unsuccessfully.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + // It was something else than EAP type. Read it from eapol DB. + _LIT( KEapolTableName, "eapol" ); + TRAPD( err, read_configureL( + KDatabaseName, + KEapolTableName, + field->get_field(), + field->get_field_length(), + data) ); + // Try to read it for eap fast DB + HBufC8* fieldBuf = HBufC8::NewLC( field->get_field_length() ); + TPtr8 fieldPtr = fieldBuf->Des(); + fieldPtr.Copy( reinterpret_cast ( field->get_field() )); + + _LIT8(cf_str_EAP_TLS_PEAP_use_identity_privacy_literal, "EAP_TLS_PEAP_use_identity_privacy"); + + if ( err != KErrNone && + fieldPtr.Compare( cf_str_EAP_TLS_PEAP_use_identity_privacy_literal() ) == 0 ) + { + if (aSelectedEapType == eap_type_tls) + { + _LIT(KGeneralSettingsDBTableName, "KTlsDatabaseTableName"); + TRAP( err, read_configureL( + KDatabaseName, + KGeneralSettingsDBTableName, + field->get_field(), + field->get_field_length(), + data) ); + + } + if (aSelectedEapType == eap_type_peap) + { + _LIT(KGeneralSettingsDBTableName, "KPeapDatabaseTableName"); + TRAP( err, read_configureL( + KDatabaseName, + KGeneralSettingsDBTableName, + field->get_field(), + field->get_field_length(), + data) ); + } + if (aSelectedEapType == eap_type_ttls) + { + _LIT(KGeneralSettingsDBTableName, "KTtlsDatabaseTableName"); + TRAP( err, read_configureL( + KDatabaseName, + KGeneralSettingsDBTableName, + field->get_field(), + field->get_field_length(), + data) ); + } +#if defined (USE_FAST_EAP_TYPE) + if ( aSelectedEapType == eap_type_fast) + { + _LIT(KFastGeneralSettingsDBTableName, "eapfast_general_settings"); + TRAP( err, read_configureL( + KFastDatabaseName, + KFastGeneralSettingsDBTableName, + field->get_field(), + field->get_field_length(), + data) ); + } +#endif + } + CleanupStack::PopAndDestroy( fieldBuf ); + + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + +#if defined(USE_EAP_FILECONFIG) + if (m_fileconfig != 0 + && m_fileconfig->get_is_valid() == true) + { + // Here we could try the final configuration option. + status = m_fileconfig->read_configure( + field, + data); + } +#endif //#if defined(USE_EAP_FILECONFIG) + } + m_am_tools->trace_configuration( + status, + field, + data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eapol_am_wlan_authentication_symbian_c::read_configureL( + const TDesC& aDbName, + const TDesC& aTableName, + eap_config_string field, + const u32_t /*field_length*/, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Open database + RDbNamedDatabase db; + +#ifdef SYMBIAN_SECURE_DBMS + User::LeaveIfError(db.Open(m_session, aDbName, KSecureUIDFormat)); +#else + User::LeaveIfError(db.Open(m_session, aDbName)); +#endif // #ifdef SYMBIAN_SECURE_DBMS + + CleanupClosePushL(db); + + + // Create a buffer for the ascii strings - initialised with the argument + HBufC8* asciibuf = HBufC8::NewLC(128); + TPtr8 asciiString = asciibuf->Des(); + asciiString.Copy(reinterpret_cast(field)); + + // Buffer for unicode parameter + HBufC* unicodebuf = HBufC::NewLC(128); + TPtr unicodeString = unicodebuf->Des(); + + // Convert to unicode + unicodeString.Copy(asciiString); + + // Now do the database query + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + _LIT(KSQLQueryRow, "SELECT %S FROM %S"); + sqlStatement.Format( KSQLQueryRow, &unicodeString, &aTableName ); + + RDbView view; + User::LeaveIfError(view.Prepare(db, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + if (view.FirstL()) + { + eap_status_e status(eap_status_process_general_error); + view.GetL(); + switch (view.ColType(1)) + { + case EDbColText: + { + unicodeString = view.ColDes(1); + // Convert to 8-bit + asciiString.Copy(unicodeString); + if (asciiString.Size() > 0) + { + status = data->set_copy_of_buffer(asciiString.Ptr(), asciiString.Size()); + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + } + else + { + // Empty field. Do nothing...data remains invalid and the stack knows what to do hopefully. + break; + } + } + break; + case EDbColUint32: + { + TUint value; + value = view.ColUint32(1); + status = data->set_copy_of_buffer((const unsigned char *) &value, sizeof(value)); + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + } + break; + default: + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("read_configureL: Unexpected column type.\n"))); + User::Panic(_L("EAPOL"), 1); + } + } + else + { + // Could not find parameter + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("read_configureL: Could not find configuration parameter.\n"))); + User::Leave(KErrNotFound); + } + + // Close database + CleanupStack::PopAndDestroy(5); // view, 3 buffers and database + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::write_configure( + const eap_configuration_field_c * const /* field */, + eap_variable_data_c * const /* data */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = eap_status_illegal_configure_field; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_am_tools->am_set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_am_tools->am_cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_am_tools->am_cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::check_is_valid_eap_type(const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::check_is_valid_eap_type(): %s, this = 0x%08x => 0x%08x, EAP-type=0x%08x=%s\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this), + convert_eap_type_to_u32_t(eap_type), + eap_string.get_eap_type_string(eap_type))); + +#ifdef USE_EAP_EXPANDED_TYPES + + for (int i = 0; i < m_enabled_expanded_eap_array.Count(); i++) + { + TBuf8 tmpExpEAP(m_enabled_expanded_eap_array[i]->EapExpandedType); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::check_is_valid_eap_type:Enabled expanded EAP type at index=%d\n"), + i)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Enabled expanded EAP type:"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + + // This is for one expanded EAP type (for the above one). + eap_expanded_type_c expandedEAPType; + + // Read the expanded EAP type details for this item in m_enabled_expanded_eap_array. + eap_status_e status = eap_expanded_type_c::read_type(m_am_tools, + 0, + tmpExpEAP.Ptr(), + tmpExpEAP.Size(), + &expandedEAPType); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (eap_type == expandedEAPType) + { + // This is Allowed and Valid. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + +#else // For normal unexpanded EAP type + + TEap *eapType = 0; + + for (int i = 0; i < m_iap_eap_array.Count(); i++) + { + // Try next EAP type + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + // Convert the string to integer + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + + if (eap_type == static_cast(val)) + { + // Allowed + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + } + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s: check_is_valid_eap_type(): not supported EAP-type=0x%08x=%s\n"), + (m_is_client == true ? "client": "server"), + convert_eap_type_to_u32_t(eap_type), + eap_string.get_eap_type_string(eap_type))); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::get_eap_type_list(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + + eap_status_e status(eap_status_illegal_eap_type); + + status = eap_type_list->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + +#ifdef USE_EAP_EXPANDED_TYPES + + // This function is same as get_selected_eap_types in behavior. + + // We need to return only the EAP types available as enabled types. + // It means only the ones available in m_enabled_expanded_eap_array. + + for (TInt i = 0; i < m_enabled_expanded_eap_array.Count(); i++) + { + TBuf8 tmpExpEAP(m_enabled_expanded_eap_array[i]->EapExpandedType); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::get_eap_type_list:Enabled expanded EAP type at index=%d\n"), + i)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Enabled expanded EAP type:"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + + // This is for one expanded EAP type (for the above one). + eap_expanded_type_c * expandedEAPType = new eap_type_value_e(); + + // Read the expanded EAP type details from an item in m_enabled_expanded_eap_array. + status = eap_expanded_type_c::read_type(m_am_tools, + 0, + tmpExpEAP.Ptr(), + tmpExpEAP.Size(), + expandedEAPType); + if (status != eap_status_ok) + { + delete expandedEAPType; + expandedEAPType = 0; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Add EAP-type to list. + status = eap_type_list->add_object(expandedEAPType, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("get_eap_type_list():added EAP-type=0x%08x=%s\n"), + expandedEAPType->get_vendor_type(), + eap_string.get_eap_type_string(*expandedEAPType))); + } + +#else // for normal EAP types. + + TEap *eapType = 0; + + for (TInt i = 0; i < m_iap_eap_array.Count(); i++) + { + // Check if type is enabled + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("get_eap_type_list(): adds EAP-type=0x%08x=%s\n"), + static_cast(val), + eap_string.get_eap_type_string( + static_cast( + static_cast(val))))); + + eap_type_value_e * const eap_type = new eap_type_value_e( + static_cast(val)); + if (eap_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = eap_type_list->add_object(eap_type, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +void eapol_am_wlan_authentication_symbian_c::RunL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::RunL(): iStatus.Int() = %d\n"), + iStatus.Int())); + + if (iStatus.Int() != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + // Authentication cancelled. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Authentication cancelled.\n"))); + + eap_status_e status = m_am_partner->disassociation( + &m_receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("set_timer(EAPOL_AM_CORE_TIMER_DELETE_STACK_ID) failed in RunL().\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + // Reset index of current EAP-type. + m_am_partner->set_current_eap_index(0ul); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to WLM: EFailedCompletely.\n"))); + + m_am_partner->eapol_indication( + &m_receive_network_id, + eapol_wlan_authentication_state_failed_completely); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +void eapol_am_wlan_authentication_symbian_c::DoCancel() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::DoCancel()\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void eapol_am_wlan_authentication_symbian_c::RetrievePSKL(TPSKEntry& entry) +{ + + // Open database + RDbNamedDatabase db; + +#ifdef SYMBIAN_SECURE_DBMS + User::LeaveIfError(db.Open(m_session, KDatabaseName, KSecureUIDFormat)); +#else + User::LeaveIfError(db.Open(m_session, KDatabaseName)); +#endif // #ifdef SYMBIAN_SECURE_DBMS + + CleanupClosePushL(db); + + HBufC* sqlbuf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = sqlbuf->Des(); + + RDbView view; + + CleanupClosePushL(view); + + _LIT(KSQL, "SELECT %S, %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &KServiceType, &KServiceIndex, &KSSID, &KPassword, &KPSK, + &KEapolPSKTableName, &KServiceType, entry.indexType, &KServiceIndex, entry.index); + + User::LeaveIfError(view.Prepare(db, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + User::LeaveIfError(view.EvaluateAll()); + + TInt rows = view.CountL(); + + if (rows == 0) + { + // No saved PSK + User::Leave(KErrNotFound); + } + view.FirstL(); + view.GetL(); + + entry.ssid.Copy(view.ColDes8(3)); + entry.password.Copy(view.ColDes8(4)); + entry.psk.Copy(view.ColDes8(5)); + + CleanupStack::PopAndDestroy(3); // view, buf, database +} + +//-------------------------------------------------- + +void eapol_am_wlan_authentication_symbian_c::SavePSKL(TPSKEntry& entry) +{ + // Connect to CommDBif so that we can delete PSK entries that have no IAP associated anymore. + CWLanSettings* wlan_settings = new(ELeave) CWLanSettings; + CleanupStack::PushL(wlan_settings); + + SWLANSettings wlanSettings; + + if (wlan_settings->Connect() != KErrNone) + { + // Could not connect to CommDB + User::Leave(KErrCouldNotConnect); + } + + // Open database + RDbNamedDatabase db; + +#ifdef SYMBIAN_SECURE_DBMS + User::LeaveIfError(db.Open(m_session, KDatabaseName, KSecureUIDFormat)); +#else + User::LeaveIfError(db.Open(m_session, KDatabaseName)); +#endif // #ifdef SYMBIAN_SECURE_DBMS + + CleanupClosePushL(db); + + HBufC* sqlbuf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = sqlbuf->Des(); + + RDbView view; + + _LIT(KSQL, "SELECT %S, %S, %S, %S, %S FROM %S"); + + sqlStatement.Format(KSQL, &KServiceType, &KServiceIndex, &KSSID, &KPassword, &KPSK, + &KEapolPSKTableName); + + User::LeaveIfError(view.Prepare(db, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Delete old row and also rows that have no associated IAP settings. + if (view.FirstL()) + { + do { + view.GetL(); + + if ((wlan_settings->GetWlanSettingsForService(view.ColUint32(colSet->ColNo(KServiceIndex)), wlanSettings) != KErrNone) + || (view.ColUint32(colSet->ColNo(KServiceType)) == static_cast(entry.indexType) + && view.ColUint32(colSet->ColNo(KServiceIndex)) == static_cast(entry.index))) + { + // Not found or current IAP + view.DeleteL(); + } + + } while (view.NextL() != EFalse); + } + + wlan_settings->Disconnect(); + + view.InsertL(); + + view.SetColL(colSet->ColNo(KServiceType), (TUint)entry.indexType); + view.SetColL(colSet->ColNo(KServiceIndex), (TUint)entry.index); + view.SetColL(colSet->ColNo(KSSID), entry.ssid); + view.SetColL(colSet->ColNo(KPassword), entry.password); + view.SetColL(colSet->ColNo(KPSK), entry.psk); + + view.PutL(); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + CleanupStack::PopAndDestroy(4); // CWLanSettings, database, buffer, view + +} + +//-------------------------------------------------- + +// +void eapol_am_wlan_authentication_symbian_c::ReadEAPSettingsL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::ReadEAPSettingsL(): %s, this = 0x%08x => 0x%08x\n"), + (m_is_client == true) ? "client": "server", + this, + dynamic_cast(this))); + + eap_status_e status(eap_status_ok); + + status = reset_eap_plugins(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + TIndexType index_type(ELan); + TUint index(0UL); + + status = read_database_reference_values( + &index_type, + &index); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + if (index_type == ELan) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Beginning to read IAP settings - Type: %d, Index: %d.\n"), index_type, index)); + + CWLanSettings* wlan_settings = new(ELeave) CWLanSettings; + CleanupStack::PushL(wlan_settings); + SWLANSettings wlanSettings; + if (wlan_settings->Connect() != KErrNone) + { + // Could not connect to CommDB + User::Leave(KErrCouldNotConnect); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, (EAPL("Connected to CommDbIf.\n"))); + + if (wlan_settings->GetWlanSettingsForService(index, wlanSettings) != KErrNone) + { + wlan_settings->Disconnect(); + User::Leave(KErrUnknown); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Got WLAN settings: wlanSettings.EnableWpaPsk=%d, m_WPA_override_enabled=%d\n"), + wlanSettings.EnableWpaPsk, + m_WPA_override_enabled)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WPA-PSK"), + wlanSettings.WPAPreSharedKey.Ptr(), + wlanSettings.WPAPreSharedKey.Size())); + +#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Beginning to read EAP Data using new Comm_DB_if for expanded eap type\n"))); + + wlan_settings->GetEapDataL(m_enabled_expanded_eap_array, m_disabled_expanded_eap_array); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Enabled EAP count=%d, Disabled EAP count=%d\n"), + m_enabled_expanded_eap_array.Count(), m_disabled_expanded_eap_array.Count())); + + + +#else + // Without expanded EAP type. Normal EAP type stuff. + wlan_settings->GetEapDataL(m_iap_eap_array); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Got EAP data:\n"))); + +#ifdef USE_EAP_EXPANDED_TYPES + + // Reading enabled. + for (TInt i = 0; i < m_enabled_expanded_eap_array.Count(); i++) + { + TBuf8 tmpExpEAP(m_enabled_expanded_eap_array[i]->EapExpandedType); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::ReadEAPSettingsL:Enabled expanded EAP type at index=%d\n"), + i)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Enabled expanded EAP type:"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + } + + // Now reading disabled. + for (TInt i = 0; i < m_disabled_expanded_eap_array.Count(); i++) + { + TBuf8 tmpExpEAP(m_disabled_expanded_eap_array[i]->EapExpandedType); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::ReadEAPSettingsL:Disabled expanded EAP type at index=%d\n"), + i)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Disabled expanded EAP type:"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + } + +#else // Normal EAP type. + + for (TInt i = 0; i < m_iap_eap_array.Count(); i++) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP type %d\n"), + i)); + + TLex8 tmp(m_iap_eap_array[i]->UID); + TInt val(0); + tmp.Val(val); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" UID: %d\n"), val)); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" Enabled: %d\n"), + m_iap_eap_array[i]->Enabled)); + } + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("End EAP data:\n"))); + + +#ifndef USE_EAP_EXPANDED_TYPES + +// There can not be a situation where all EAPs are disabled. + + if (m_iap_eap_array.Count() == 0) + { + +#if defined(USE_EAP_ALLOW_ALL_EAP_TYPES_WHEN_NONE_IS_ACTIVATED_IN_CONFIGURATION) + + // The EAP field was empty. Allow all types. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Empty EAP field -> enable all types.\n"))); + + RImplInfoPtrArray eapArray; + + REComSession::ListImplementationsL(KEapTypeInterfaceUid, eapArray); + + TEap *eap; + for (TInt i = 0; i < eapArray.Count(); i++) + { + eap = new(ELeave) TEap; + eap->UID.Copy(eapArray[i]->DataType()); + eap->Enabled = ETrue; + m_iap_eap_array.Append(eap); + } + + eapArray.ResetAndDestroy(); + +#else + + // The EAP field was empty. Allow EAP-SIM only. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Empty EAP field -> enable EAP-SIM only.\n"))); + + { + TBuf8<3> eap_sim_uid = _L8("018"); + + TEap *eap = new(ELeave) TEap; + eap->UID.Copy(eap_sim_uid); + eap->Enabled = ETrue; + m_iap_eap_array.Append(eap); + } + +#endif //#if defined(USE_EAP_ALLOW_ALL_EAP_TYPES_WHEN_NONE_IS_ACTIVATED_IN_CONFIGURATION) + + } + +#endif // #ifndef USE_EAP_EXPANDED_TYPES + + // Get security mode + if (m_WPA_override_enabled == false) + { + m_security_mode = static_cast(wlanSettings.SecurityMode); + } + else + { + // WPA override is enabled + m_security_mode = Wpa; + } + + // Get WPA pre shared key & SSID + if (m_is_client == true + && (wlanSettings.EnableWpaPsk + || m_WPA_override_enabled == true) + && (m_selected_eapol_key_authentication_type == eapol_key_authentication_type_RSNA_PSK + || m_selected_eapol_key_authentication_type == eapol_key_authentication_type_WPA_PSK)) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Uses WPAPSK: wlanSettings.EnableWpaPsk=%d\n"), + wlanSettings.EnableWpaPsk)); + + // When not using easy WLAN there is no WPA PSK override. + if (m_WPA_override_enabled == false) + { + status = m_wpa_preshared_key.set_copy_of_buffer( + wlanSettings.WPAPreSharedKey.Ptr(), + wlanSettings.WPAPreSharedKey.Size()); + if (status != eap_status_ok) + { + send_error_notification(eap_status_key_error); + wlan_settings->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + // Here we copy the SSID read from IAP. + TBuf8 tmp; + tmp.Copy(wlanSettings.SSID); + status = m_SSID.set_copy_of_buffer(tmp.Ptr(), tmp.Size()); + if (status != eap_status_ok) + { + wlan_settings->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + else + { + // In override mode SSID is stored to m_SSID + // and password is stored to m_wpa_preshared_key. + } + + TPSKEntry pskEntry; + pskEntry.indexType = index_type; + pskEntry.index = index; + pskEntry.ssid.Zero(); + pskEntry.password.Zero(); + pskEntry.psk.Zero(); + + TInt err(KErrNone); + + // Retrieve saved PSK only when override is not in effect + TRAP(err, RetrievePSKL(pskEntry)); + + if (err != KErrNone + || m_SSID.compare(pskEntry.ssid.Ptr(), pskEntry.ssid.Size()) != 0 + || m_wpa_preshared_key.compare(pskEntry.password.Ptr(), pskEntry.password.Size()) != 0) + { + // No previous PSK or parameters were changed. + // We need to calculate PSK again + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("No previous PSK found...\n"))); + + crypto_wpa_psk_password_hash_c password_hash(m_am_tools); + + if (m_wpa_preshared_key.get_data_length() == 2ul*EAPOL_WPA_PSK_LENGTH_BYTES) + { + // This is hex ascii 64-digit WWPA-PSK. + // Convert it to 32 octets. + u32_t target_length(EAPOL_WPA_PSK_LENGTH_BYTES); + + status = m_wpa_preshared_key_hash.set_buffer_length(EAPOL_WPA_PSK_LENGTH_BYTES); + if (status != eap_status_ok) + { + send_error_notification(eap_status_key_error); + wlan_settings->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + status = m_wpa_preshared_key_hash.set_data_length(EAPOL_WPA_PSK_LENGTH_BYTES); + if (status != eap_status_ok) + { + send_error_notification(eap_status_key_error); + wlan_settings->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + status = m_am_tools->convert_hex_ascii_to_bytes( + m_wpa_preshared_key.get_data(m_wpa_preshared_key.get_data_length()), + m_wpa_preshared_key.get_data_length(), + m_wpa_preshared_key_hash.get_data(EAPOL_WPA_PSK_LENGTH_BYTES), + &target_length); + if (status != eap_status_ok + || target_length != EAPOL_WPA_PSK_LENGTH_BYTES) + { + send_error_notification(eap_status_key_error); + wlan_settings->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + else + { + status = password_hash.password_hash( + &m_wpa_preshared_key, + &m_SSID, + &m_wpa_preshared_key_hash, + 0, + 0); + + if (status != eap_status_ok) + { + send_error_notification(eap_status_key_error); + wlan_settings->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("new WPA-PSK SSID"), + m_SSID.get_data(), + m_SSID.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("new WPA-PSK preshared key"), + m_wpa_preshared_key.get_data(), + m_wpa_preshared_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("new WPA-PSK hash"), + m_wpa_preshared_key_hash.get_data(), + m_wpa_preshared_key_hash.get_data_length())); + + // Save new PSK. + pskEntry.ssid.Copy( + m_SSID.get_data(), + m_SSID.get_data_length() + ); + + pskEntry.password.Copy( + m_wpa_preshared_key.get_data(), + m_wpa_preshared_key.get_data_length() + ); + + pskEntry.psk.Copy( + m_wpa_preshared_key_hash.get_data(), + m_wpa_preshared_key_hash.get_data_length() + ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Saving PSK.\n"))); + + SavePSKL(pskEntry); + } + else + { + // Copy retrieved WPAPSK hash to member variable + status = m_wpa_preshared_key_hash.set_copy_of_buffer(pskEntry.psk.Ptr(), pskEntry.psk.Size()); + if (status != eap_status_ok) + { + send_error_notification(eap_status_key_error); + wlan_settings->Disconnect(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("old WPA-PSK SSID"), + m_SSID.get_data(), + m_SSID.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("old WPA-PSK preshared key"), + m_wpa_preshared_key.get_data(), + m_wpa_preshared_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("old WPA-PSK hash"), + m_wpa_preshared_key_hash.get_data(), + m_wpa_preshared_key_hash.get_data_length())); + } + } + + wlan_settings->Disconnect(); + CleanupStack::PopAndDestroy(wlan_settings); + + if (m_security_mode != Wlan8021x + && m_security_mode != Wpa + && m_security_mode != Wpa2Only) + { + // Unsupported mode + User::Leave(KErrNotSupported); + } + } + else + { + // At the moment only LAN bearer is supported. + User::Leave(KErrNotSupported); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +#ifdef USE_EAP_EXPANDED_TYPES + +void eapol_am_wlan_authentication_symbian_c::SetToTopPriorityL(const eap_type_value_e aEapType) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::SetToTopPriorityL() - for EXP EAP types\n"))); + + TIndexType index_type(ELan); + TUint index(0UL); + TInt priorityIndex (0); + + eap_status_e status = read_database_reference_values( + &index_type, + &index); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + if (index_type == ELan) + { + for (TInt i = 0; i < m_enabled_expanded_eap_array.Count(); i++) + { + TBuf8 tmpExpEAP(m_enabled_expanded_eap_array[i]->EapExpandedType); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::SetToTopPriorityL:Enabled expanded EAP type at index=%d\n"), + i)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Enabled expanded EAP type:"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + + // This is for one expanded EAP type (for the above one). + eap_expanded_type_c expandedEAPType; + + // Read the expanded EAP type details for this item in m_enabled_expanded_eap_array. + eap_status_e status = eap_expanded_type_c::read_type(m_am_tools, + 0, + tmpExpEAP.Ptr(), + tmpExpEAP.Size(), + &expandedEAPType); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + if (aEapType == expandedEAPType) + { + // Found it. This is the EAP type which should be at top priority. + priorityIndex = i; + break; + } + } + + if(priorityIndex == 0) + { + // This means this EAP type is already at the top priority. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::SetToTopPriorityL() - This is already at top\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (priorityIndex >= m_enabled_expanded_eap_array.Count()) + { + // No such EAP type in enabled list. This should never happen. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eapol_am_wlan_authentication_symbian_c::SetToTopPriorityL() - No such EAP in the enabled list\n"))); + + User::Leave(KErrNotFound); + } + + CWLanSettings* wlan = new(ELeave) CWLanSettings; + CleanupStack::PushL(wlan); + SWLANSettings wlanSettings; + if (wlan->Connect() != KErrNone) + { + // Could not connect to CommDB + User::Leave(KErrCouldNotConnect); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("SetToTopPriorityL():Connected to CommDbIf.\n"))); + + if (wlan->GetWlanSettingsForService(index, wlanSettings) != KErrNone) + { + wlan->Disconnect(); + User::Leave(KErrUnknown); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("SetToTopPriorityL():Got WLAN settings.\n"))); + + // Change the order + SEapExpandedType* TopPriorityEAP(m_enabled_expanded_eap_array[priorityIndex]); + + m_enabled_expanded_eap_array.Remove(priorityIndex); // This does not delete the object + + m_enabled_expanded_eap_array.Insert(TopPriorityEAP, 0); // Insert in the beginning. + + wlan->SetEapDataL(m_enabled_expanded_eap_array, m_disabled_expanded_eap_array); + + wlan->Disconnect(); + + CleanupStack::PopAndDestroy(wlan); + } + else + { + // At the moment only LAN bearer is supported. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::SetToTopPriorityL() - LEAVE - only LAN bearer is supported\n"))); + + User::Leave(KErrNotSupported); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +#else // For normal EAP types + +void eapol_am_wlan_authentication_symbian_c::SetToTopPriorityL(const TEap* const aEapType) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::SetToTopPriorityL()\n"))); + + TIndexType index_type(ELan); + TUint index(0UL); + + eap_status_e status = read_database_reference_values( + &index_type, + &index); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + if (index_type == ELan) + { + TInt i(0); + TBuf8<3> uid; + for (i = 0; i < m_iap_eap_array.Count(); i++) + { + TEap* eap = m_iap_eap_array[i]; + if (eap->UID[0] == '0') + { + // Cut the leading zero + uid.Copy(eap->UID.Right(eap->UID.Length()-1)); + } + else + { + uid.Copy(eap->UID); + } + if (eap->Enabled == aEapType->Enabled + && uid.Compare(aEapType->UID) == 0) + { + // Found + break; + } + } + if (i >= m_iap_eap_array.Count()) + { + // This should never happen + User::Leave(KErrNotFound); + } + + TLex8 tmp(aEapType->UID); + TInt val(0); + tmp.Val(val); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Setting to top priority:\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Old index: %d\n"), i)); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" UID: %d\n"), val)); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" Enabled: %d\n"), aEapType->Enabled)); + + if (i == 0) + { + // Already at the highest priority + return; + } + + CWLanSettings* wlan = new(ELeave) CWLanSettings; + CleanupStack::PushL(wlan); + SWLANSettings wlanSettings; + if (wlan->Connect() != KErrNone) + { + // Could not connect to CommDB + User::Leave(KErrCouldNotConnect); + } + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Connected to CommDbIf.\n"))); + + if (wlan->GetWlanSettingsForService(index, wlanSettings) != KErrNone) + { + wlan->Disconnect(); + User::Leave(KErrUnknown); + } + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got WLAN settings.\n"))); + + // Change the order + TEap* eap = m_iap_eap_array[i]; + + m_iap_eap_array.Remove(i); // This does not delete the object + + m_iap_eap_array.Insert(eap, 0); + + wlan->SetEapDataL(m_iap_eap_array); + + wlan->Disconnect(); + + CleanupStack::PopAndDestroy(wlan); + } + else + { + // At the moment only LAN bearer is supported. + User::Leave(KErrNotSupported); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + +//-------------------------------------------------- + +#if defined(USE_EAP_SIMPLE_CONFIG) + +EAP_FUNC_EXPORT eap_status_e eapol_am_wlan_authentication_symbian_c::save_simple_config_session( + const simple_config_state_e state, + EAP_TEMPLATE_CONST eap_array_c * const credential_array, + const eap_variable_data_c * const new_password, + const simple_config_Device_Password_ID_e Device_Password_ID, + const simple_config_payloads_c * const other_configuration) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_am_wlan_authentication_simulator_c::save_simple_config_session()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_ok); + + status = m_configuration_if->save_simple_config_session( + state, + credential_array, + new_password, + Device_Password_ID, + other_configuration); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eapol_am_wlan_authentication_c * eapol_am_wlan_authentication_c::new_eapol_am_wlan_authentication( + abs_eap_am_tools_c * const tools, + const bool is_client_when_true, + const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference) +{ + EAP_TRACE_BEGIN(tools, TRACE_FLAGS_DEFAULT); + + eapol_am_wlan_authentication_c * const wauth = new eapol_am_wlan_authentication_symbian_c( + tools, + is_client_when_true, + wlan_database_reference); + + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + return wauth; +} + + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/core/symbian/file_config/eap_symbian.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/core/symbian/file_config/eap_symbian.conf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,156 @@ +# +# Name : ./wlan_symbian/wlaneapol_symbian/am/core/symbian/file_config/eap_symbian.conf +# Part of : EAPOL / +# Description : Configuration file for EAPOL. +# Version : %version: 15 % +# +# Copyright © 2001-2005 Nokia. All rights reserved. +# This material, including documentation and any related +# computer programs, is protected by copyright controlled by +# Nokia. All rights are reserved. Copying, including +# reproducing, storing, adapting or translating, any +# or all of this material requires the prior written consent of +# Nokia. This material also contains confidential +# information which may not be disclosed to others without the +# prior written consent of Nokia. +# + +EAP_TRACE_disable_traces = bool:false + +EAP_TRACE_enable_timer_traces = bool:false + +EAP_TRACE_enable_timer_queue_traces = bool:false + +EAP_TRACE_output_file_name = string:e:\logs\eapol\eap_core.txt + +EAP_TRACE_max_trace_file_size = u32_t:1000000 + +EAP_TRACE_activate_only_trace_masks_always_and_error = bool:false + +EAP_TRACE_activate_trace_on_error = bool:false + +EAP_CORE_session_timeout = u32_t:60000 + +EAP_CORE_failure_received_timeout = u32_t:2000 + +EAP_CORE_remove_session_timeout = u32_t:10000 + +EAP_SESSION_use_reset_session = bool:false + +EAP_GSMSIM_failure_message_delay_time = u32_t:4000 + +EAP_GSMSIM_minimum_rand_count = u32_t:2 + +EAP_GSMSIM_wait_eap_success_packet = bool:false + +EAP_GSMSIM_client_responds_retransmitted_packets = bool:true + +EAP_GSMSIM_do_rand_uniqueness_check = bool:true + +EAP_GSMSIM_allow_use_result_indication = bool:true + +EAP_AKA_GSMSIM_2_digit_mnc_map_of_mcc_of_imsi_array \ + = u32array:202,204,206,208,213,214,216,218, \ + 219,220,222,226,228,230,231,232, \ + 234,238,240,242,244,246,247,248, \ + 250,255,257,258,259,260,262,266, \ + 268,270,272,274,276,278,280,282, \ + 283,284,286,288,290,293,294,295, \ + 308,334,338,340,346,348,350,352, \ + 354,356,358,360,362,363,364,366, \ + 370,372,374,376,400,401,402,404, \ + 405,410,412,413,414,415,416,417, \ + 418,419,420,421,422,424,425,426, \ + 427,428,429,432,434,436,437,438, \ + 440,441,450,452,454,455,456,457, \ + 460,466,467,470,472,502,505,510, \ + 514,515,520,525,528,530,537,539, \ + 540,541,542,546,547,549,550,602, \ + 603,604,605,607,608,609,610,611, \ + 612,613,614,615,616,617,618,619, \ + 620,621,622,623,624,625,626,627, \ + 628,629,630,631,632,633,634,635, \ + 636,637,638,639,640,641,642,643, \ + 645,646,647,648,649,650,651,652, \ + 653,654,655,702,704,706,708,710, \ + 712,714,716,724,730,734,736,738, \ + 740,744,746,795,901 + +EAP_AKA_failure_message_delay_time = u32_t:4000 + +EAP_AKA_wait_eap_success_packet = bool:false + +EAP_AKA_client_responds_retransmitted_packets = bool:true + +EAP_AKA_allow_use_result_indication = bool:true + +TLS_use_separate_tls_record = bool:true + +TLS_client_allows_empty_certificate_authorities_list = bool:true + +TLS_server_authenticates_client_policy_in_client = bool:true + +EAP_TLS_PEAP_use_tppd_tls_peap = bool:true + +EAP_TLS_use_tppd_peapv1_acknowledge_hack = bool:true + +PEAP_allow_tunneled_session_resumption=bool:true + +EAP_TLS_PEAP_wait_eap_success_packet = bool:true + +EAP_TLS_PEAP_check_nai_realm = bool:false + +EAPOL_CORE_starts_max_count = u32_t:3 + +EAPOL_CORE_send_start_interval = u32_t:2000 + +EAPOL_key_state_retransmission_counter = u32_t:3 + +EAPOL_key_state_retransmission_time = u32_t:500 + +EAPOL_key_state_handshake_timeout=u32_t:15000 + +EAPOL_key_state_wpxm_reassociate_timeout=u32_t:500 + +EAPOL_key_state_pmksa_caching_timeout = u32_t:43200000 + +EAPOL_key_state_allow_missing_PMKID_in_message_1 = bool:true + +EAPOL_key_state_allow_non_zero_mic_in_message_1 = bool:true + +EAPOL_key_state_indicate_pmkid_to_lower_layer = bool:false + +EAP_TRACE_enable_function_traces = bool:false + +### Maximum Session Validity Time in seconds for different EAP types.### + +EAP_GSMSIM_max_session_validity_time = u32_t:43200 + +EAP_AKA_max_session_validity_time = u32_t:43200 + +EAP_TLS_max_session_validity_time = u32_t:43200 + +EAP_PEAP_max_session_validity_time = u32_t:43200 + +EAP_TTLS_max_session_validity_time = u32_t:43200 + +EAP_TLS_PEAP_ttls_pap_max_session_validity_time = u32_t:43200 + +EAP_LEAP_max_session_validity_time = u32_t:43200 + +EAP_MSCHAPv2_max_session_validity_time = u32_t:43200 + +EAP_GTC_max_session_validity_time = u32_t:43200 + +EAP_SECUREID_max_session_validity_time = u32_t:43200 + +EAP_FAST_max_session_validity_time = u32_t:43200 + +SIMPLE_CONFIG_Device_Password_ID = string:PIN +#SIMPLE_CONFIG_Device_Password_ID = string:PushButton + +EAP_SIMPLE_CONFIG_use_manual_username = bool:true + +EAP_SIMPLE_CONFIG_manual_username = string:WFA-SimpleConfig-Enrollee-1-0 + +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/core/symbian/file_config/eap_trace.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/core/symbian/file_config/eap_trace.conf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,37 @@ +#-------------------------------------------------------------------- + +# This string configuration option selects file and path name of trace log file. +# Default value is /tmp/eap_core.log. +EAP_TRACE_output_file_name = string:c:\logs\eapol\eap_core.txt + +# This variable is true or false. +# True value means EAP AM disables traces. +# False value means EAP AM activates traces. +EAP_TRACE_disable_traces = bool:false +#EAP_TRACE_disable_traces = bool:true + +# This string configuration option sets the maximum size of trace log file in bytes. +# Note this is not absolute value. New file is generated when size of trace log file +# exceeds this limitation. +# Default value is 100000000 bytes. +EAP_TRACE_max_trace_file_size = u32_t:10000000 + +# This boolean configuration option with true value enables only +# always active traces and error traces. +# set_trace_mask(eap_trace_mask_always|eap_trace_mask_error). +# Default value is false. +#EAP_TRACE_activate_only_trace_masks_always_and_error = bool:true +EAP_TRACE_activate_only_trace_masks_always_and_error = bool:false + +# This boolean configuration option with true value enables activation of traces +# when error occurs. +# Look at the set_activate_trace_on_error() and eap_status_return() +# functions. NOTE the always active traces are only left active. +# That means set_activate_trace_on_error() function calls +# set_trace_mask(eap_trace_mask_always). +# Default value is false. +#EAP_TRACE_activate_trace_on_error = bool:true +EAP_TRACE_activate_trace_on_error = bool:false + +#-------------------------------------------------------------------- +# end diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eap_test_timer/symbian/eap_test_timer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eap_test_timer/symbian/eap_test_timer.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,108 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 165 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +//#include "eap_test_timer.h" +#include "abs_eap_am_mutex.h" +#include "eap_am_tools_symbian.h" + + +LOCAL_C TInt mainL(TAny *lpParam) +{ + if (lpParam == 0) + { + return eap_status_process_general_error; + } + + abs_eap_am_tools_c * const tools = reinterpret_cast(lpParam); + + eap_status_e status = tools->timer_thread_function(); + return status; +} + + +_LIT(K_eap_test_timer,"eap_test_timer"); + + +eap_status_e eap_am_tools_symbian_c::start_timer_thread() +{ + EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("Create timer thread.\n"))); + + RThread thread; + + set_use_timer_queue(); + + TInt res=thread.Create(K_eap_test_timer, // create new server thread + mainL, // thread's main function + KDefaultStackSize, + KDefaultStackSize, + KDefaultStackSize, + this, // passed as TAny* argument to thread function + EOwnerProcess + ); + + if (res == KErrNone) + { + thread.SetPriority(EPriorityMuchMore); + thread.Resume(); // start it going + } + else + { + thread.Close(); // therefore we've no further interest in it + return eap_status_process_general_error; + } + return eap_status_ok; +} + + +eap_status_e eap_am_tools_symbian_c::stop_timer_thread() +{ + EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("Trigger timer thread stops.\n"))); + + m_run_thread = false; + + bool sleep_more = true; + + sleep(0u); + + while(get_thread_stopped() == false) + { + sleep(get_timer_resolution_ms()); + sleep_more = false; + } + + if (sleep_more == true) + { + // This is not absolute indication that the thread is really finished, + // so we sleep a while to make it more probable. + sleep(get_timer_resolution_ms()); + } + + EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("Trigger timer thread returns.\n"))); + return eap_status_ok; +} + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/data/10200ec9.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/data/10200ec9.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Resource file used to register ecom dll's with registry. +* +*/ + + +#include + +RESOURCE REGISTRY_INFO theInfo + { + // UID for the DLL + dll_uid = 0x10200ec9; + // Declare array of interface info + interfaces = + { + INTERFACE_INFO + { + // UID of interface that is implemented + interface_uid = 0x10206999; + implementations = + { + // Info for default impl. + IMPLEMENTATION_INFO + { + implementation_uid = 0x1020699a; + version_no = 1; + display_name = "EAP over IKEv2"; + default_data = "EAPVPNIF"; + opaque_data = ""; + } + }; + } + }; + } + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/data/10200eca.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/data/10200eca.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Custom Resolver registration file. +* +*/ + + +#include + +RESOURCE REGISTRY_INFO theInfo + { + dll_uid = 0x10200eca; + interfaces = + { + INTERFACE_INFO + { + // Interface UID of resolvers + interface_uid = 0x10009D90; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = 0x1020699b; + version_no = 1; + display_name = ""; + default_data = ""; + opaque_data = ""; + } + }; + } + }; + } + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/inc/eap_vpn_if_implementation.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/inc/eap_vpn_if_implementation.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,435 @@ +/* +* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: CEapVpnInterfaceImplementation +* +*/ + + +#ifndef __EAPPLUGIN_H__ +#define __EAPPLUGIN_H__ + +// INCLUDES +#include + +#include +#include "eap_vpn_if.h" +#include "abs_eap_core.h" +#include "eapol_session_key.h" +#include "eap_core.h" +#include "eap_am_tools_symbian.h" +#include "EapType.h" +#include "EapolTimer.h" + +// FORWARD DECLARATIONS +class CEapType; +class eap_am_tools_symbian_c; +class eap_file_config_c; + +/** + * Class: CEapVpnInterfaceImplementation + * + * Description: Implements the EAP over IKEv2 adaptation + * This is concrete class, instance of which + * ECOM framework gives to ECOM clients. + */ +class CEapVpnInterfaceImplementation + : public CEapVpnInterface + , public abs_eap_core_c + , public abs_eap_base_timer_c +{ +public: + /** + * Function: NewL + * + * Description: Create instance of concrete implementation. Note that ECOM + * interface implementations can only have two signatures for + * NewL: + * - NewL without parameters (used here) + * - NewL with TAny* pointer, which may provide some client + * data + * + * @return Instance of this class. + * + * Note: The interface, which is abstract base class of this + * implementation, also provides NewL method. Normally abstract + * classes do not provide NewL, because they cannot create + * instances of themselves. + */ + static CEapVpnInterfaceImplementation* NewL(TAbsEapVpnInterfaceParams* aParams); + + virtual ~CEapVpnInterfaceImplementation(); + // Virtual functions from CEapVpnInterface + /** + * Function: StartL + * + * Description: Initializes the eap plugin + * + * @param aType name of requested eap type implementation. + * + */ + virtual TInt StartL(const TUint8 aEapType); + /** + * Function: EapConfigure + * + * Description: Configures the eap plugin + * + * @param aManualUsername The username, if not zero + * @param aManualRealm The realm, if not zero + * @param aManualRealmPrefix The realm prefix, if not zero + * @param aHideInitialIdentity Scramble username, if true + * + */ + virtual TInt EapConfigure(TDesC8& aManualUsername, TDesC8& aManualRealm, TDesC8& aRealmPrefix, TBool aHideInitialIdentity); + + /** + * Function: QueryIdentity + * + * Description: Ask the identity + */ + virtual TInt QueryIdentity(); + + /** + * Function: EapInbound + * + * Description: Handle incoming Eap message + * + * @param aMessage incoming eap message. + * + */ + virtual TInt EapInbound(const TDesC8& aMessage); + +// Virtual callback functions, called by the eap_core + + /** + * The derived class could send packets to partner class with this function. + * @see abs_eap_base_type_c::packet_send(). + */ + virtual eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + /** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @see abs_eap_base_type_c::get_header_offset(). + */ + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + /** + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + * @param receive_network_id includes the addresses (network identity) and packet type. + */ + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + /** + * The unload_module() function unloads the module of a EAP-type. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e unload_module(const eap_type_value_e eap_type); + + void set_is_valid(); + + bool get_is_valid(); + + void increment_authentication_counter(); + + u32_t get_authentication_counter(); + + bool get_is_client(); + + eap_status_e configure(); + + eap_status_e shutdown(); + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @see abs_eap_base_type_c::packet_data_crypto_keys(). + */ + virtual eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ); + + /** + * The packet_data_session_key() function passes one traffic encryption key to + * the lower layers. Ultimately the key can end up to the WLAN hardware. + * @param send_network_id carries the addresses (network identity) and type of the packet. + * @param key is the encryption key + * @param key_length is the length of the key + * @param key_type describes the type of the key (WEP or something else...) + * @param key_index is the index of the encryption key (there can be four broadcast keys in WEP for example) + */ + virtual eap_status_e packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key + ); + + /** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + * These two notifications tells the end state of authentication session. These are the only + * reliable indications of the final status of authentication session. + * You MUST NOT make decision based on the return value of abs_eap_stack_interface_c::packet_process(). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state); + + /** + * The set_timer() function initializes timer to be elapsed after time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * @param time_ms is the time of timer in milli seconds. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t time_ms); + + /** + * The cancel_timer() function cancels the timer id initiated by initializer. + * @param initializer is pointer to object which set the cancelled timer. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id); + + /** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ + virtual eap_status_e cancel_all_timers(); + + /** + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + * @param eap_type is the requested EAP-type. + */ + virtual eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + virtual eap_status_e get_eap_type_list(eap_array_c * const eap_type_list); + + virtual eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + + /** + * The adaptation module calls the restart_authentication() function + * when EAP-authentication is needed with another peer. + * @see abs_eap_core_c::restart_authentication(). + */ + eap_status_e restart_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true, + const bool force_clean_restart, + const bool from_timer = false); + + /** + * This function tells lower layer to remove EAP session object asyncronously. + * @param send_network_id is pointer to network id that identifies the removed EAP session. + */ + eap_status_e asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const send_network_id); + + // This is documented in abs_eap_core_c::set_session_timeout(). + eap_status_e set_session_timeout( + const u32_t session_timeout_ms); + + // See abs_eap_base_timer_c::timer_expired(). + eap_status_e timer_expired( + const u32_t id, void *data); + + // See abs_eap_base_timer_c::timer_delete_data(). + eap_status_e timer_delete_data( + const u32_t id, void *data); + +private: + + TInt CompleteAssociation(const TInt aResult); + eap_status_e send_eap_identity_request(); + + eap_status_e create_upper_stack(); + +protected: + + /** + * Function: CEapVpnInterfaceImplementation + * + * Discussion: Perform the first phase of two phase construction + */ + CEapVpnInterfaceImplementation(); + + /** + * Function: ConstructL + * + * Discussion: Perform the second phase construction + */ + void ConstructL(MAbsEapVpnInterface* aCaller, TBool aClient); + + void RunL(); + void DoCancel(); + +private: // implementation + static void CleanupImplArray( TAny* aAny ); + +private: + // From eapol_am_core_symbian.h + + TBool iQueryIdentity; + + /// Pointer to the lower layer in the stack + MAbsEapVpnInterface* iCaller; + + /// Pointer to the upper layer in the stack + eap_core_c* iEapCore; + +#ifdef USE_EAP_EXPANDED_TYPES + + eap_type_value_e iRequestedEapType; + +#else + + TUint8 iRequestedEapType; + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + /// Pointer to the tools class + eap_am_tools_symbian_c* m_am_tools; + + eap_am_network_id_c* m_receive_network_id; + + eap_variable_data_c * m_trace_log_file_name; + + u32_t m_authentication_counter; + + u32_t m_successful_authentications; + + u32_t m_failed_authentications; + + bool m_is_valid; + + bool m_is_client; + + /// Array for storing the loaded EAP types. + RPointerArray m_plugin_if_array; + +#ifdef USE_EAP_EXPANDED_TYPES + + /// Enabled expanded EAP configuration data from CommsDat + // This is for the outer most EAP (not tunneled) + RExpandedEapTypeArray m_enabled_expanded_eap_array; + + /// Disabled expanded EAP configuration data from CommsDat + // This is for the outer most EAP (not tunneled) + RExpandedEapTypeArray m_disabled_expanded_eap_array; + + /// Array which corresponds with m_plugin_if_array and indicates the types of the loaded EAP types. + eap_array_c * m_eap_type_array; + +#else + + /// EAP configuration data from CommDb + TEapArray m_iap_eap_array; + + /// Array which corresponds with m_plugin_if_array and indicates the types of the loaded EAP types. + RArray m_eap_type_array; + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + /// Indicates the bearer type + TIndexType m_index_type; + + /// Indicates the service index in CommDb + TInt m_index; + + eap_file_config_c* m_fileconfig; + + u32_t m_packet_index; + + bool m_block_packet_sends_and_notifications; + + bool m_stack_marked_to_be_deleted; + + HBufC8* iManualUsername; + HBufC8* iManualRealm; + HBufC8* iRealmPrefix; + TBool iHideInitialIdentity; +}; + +#endif //#ifndef __EAPPLUGIN_H__ + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/inc/eap_vpn_if_resolver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/inc/eap_vpn_if_resolver.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,143 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Impelementation of a custom resolver. +* +*/ + + +#ifndef __EAPPLUGINRESOLVER_H__ +#define __EAPPLUGINRESOLVER_H__ + +// INCLUDES +#include + + +/** + * Class: CEapVpnInterfaceResolver + * + * Description: An implementation of the CResolver definition. This controls + * the identification, (resolution), of which implementation + * will be used to satisfy an interface implementation + * instantiation. + */ +class CEapVpnInterfaceResolver : public CResolver + { +public: + /** + * Function: NewL + * + * Description: Create instance of concrete implementation. The method + * takes a MPublicRegistry, allowing access to a list of + * implementations for a particular interface + * + * @param aRegistry provides a list of implementations of a specified + * interface. + * + * @return Instance of this class. + * + */ + static CEapVpnInterfaceResolver* NewL (MPublicRegistry& aRegistry); + + /** + * Function: ~CEapVpnInterfaceResolver + * + * Description: Destroy the object + */ + virtual ~CEapVpnInterfaceResolver(); + +public: // CResolver + /** + * Function: IdentifyImplementationL + * + * Description: Identifies the most appropriate implementation of a + * specified interface. + * + * @param aInterfaceUid is a unique id specific to definition + * interface. + * @param aAdditionalParameters The parameters which must match for an + * implementation to be suitable. + * + * @return The UID of the implementation which satisfies the + * specified parameters. If there is no suitable + * implementation, then KNullUid is returned. + */ + virtual TUid IdentifyImplementationL(TUid aInterfaceUid, + const TEComResolverParams& aAdditionalParameters) const; + + /** + * Function: ListAllL + * + * Description: Lists all the implementations of the specified interface + * definition that satisfy the supplied resolution parameters. + * + * @param aInterfaceUid The UID of the interface of which to list + * implementations + * @param aAdditionalParameters The parameters that must match for an + * implementation to be suitable + * implementation to be suitable + * + * @return Pointer to an array of suitable implementations. Ownership + * of this array is passed to the calling function, which + * should close and delete the array when its use is complete + */ + virtual RImplInfoArray* ListAllL(TUid aInterfaceUid, + const TEComResolverParams& aAdditionalParameters) const; + +private: + /** + * Function: CEapVpnInterfaceResolver + * + * Discussion: Constructor for this object. + * + * @param aRegistry provides a list of implementations of a specified + * interface. + */ + CEapVpnInterfaceResolver(MPublicRegistry& aRegistry); + + /** + * Function: Resolve + * + * Description: Search algorithm implemented to find the requested + * interface implementation. + * + * @param aImplementationsInfo Information on the potential + * implementations + * @param aAdditionalParameters The data to match against to detemine + * the implementation + * + * @return If found returns the Uid of the implementation, else it + * returns KNullUid + */ + TUid Resolve(const RImplInfoArray& aImplementationsInfo, + const TEComResolverParams& aAdditionalParameters) const; + + /** + * Function: IdentifyImplementationL + * + * Description: Method used to find a match between two implementation + * types + * + * @param aImplementationType The implementation data type to search + * for a match + * @param aMatchType The data to search against + * @param aUseWildcards ETrue if wildcard matching should be allowed + * + * @return ETrue is returned if found else EFalse + */ + TBool Match(const TDesC8& aImplementationType, const TDesC8& aMatchType, + TBool aUseWildcards) const; + }; + +#endif diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/inc/eap_vpn_if_timer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/inc/eap_vpn_if_timer.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#if !defined(_EAPOL_TIMER_H_) +#define _EAPOL_TIMER_H_ + +// INCLUDES +#include +#include "eap_am_types.h" + +// FORWARD DECLARATIONS +class abs_eap_am_tools_c; + +// CLASS DECLARATION +class CEapVpnInterfaceTimer +: public CTimer +{ +public: + static CEapVpnInterfaceTimer* NewL(abs_eap_am_tools_c * const aTools); + virtual ~CEapVpnInterfaceTimer(); + void StartTimer(const TUint aInterval); + void StopTimer(); + TBool TimerRunning(); + void RunL(); + void DoCancel(); +protected: + CEapVpnInterfaceTimer(abs_eap_am_tools_c * const aTools); + void ConstructL(); + +private: + abs_eap_am_tools_c* const iTools; + + TUint iInterval; + + u64_t iStartTime; + u64_t iLastTime; + +}; + +#endif //#if !defined(_EAPOL_TIMER_H_) + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_implementation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_implementation.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2656 @@ +/* +* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: CEapVpnInterfaceImplementation +* +*/ + + +// INCLUDE FILES +#include +#include + +#include "eap_vpn_if_implementation.h" +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_type_all.h" +#include "eap_am_tools_symbian.h" +#include "eap_crypto_api.h" +#include "eap_type_gsmsim.h" +#include "eap_type_aka.h" +#include "eap_header_string.h" +#include "EapolDbDefaults.h" +#include "EapolDbParameterNames.h" +#include "eap_am_file_input_symbian.h" +#include "abs_eap_vpn_if.h" +#include "eap_array_algorithms.h" + +#include "EapSimDbDefaults.h" + +// LOCAL CONSTANTS +const TUint KMaxConfigStringLength = 256; +const u32_t KMTU = 1500u; +const u32_t KTrailerLength = 0; +const u32_t KHeaderOffset = 0; + +#ifndef USE_EAP_EXPANDED_TYPES + +static const TUint KMaxEapCueLength = 3; + +#endif //#ifndef USE_EAP_EXPANDED_TYPES + +#define KEapIdentityOffset 5 +const eap_const_string EAPPLUGIN_TRACE_FILE = EAPL("logs\\eapol\\eap_vpn_if.txt"); + +enum eapol_am_core_timer_id_e +{ + EAPOL_AM_CORE_TIMER_RESTART_AUTHENTICATION_ID, + EAPOL_AM_CORE_TIMER_DELETE_STACK_ID, + EAPOL_AM_CORE_TIMER_FAILED_COMPLETELY_ID, +}; + +// ================= MEMBER FUNCTIONS ======================= +// Create instance of concrete ECOM interface implementation +CEapVpnInterfaceImplementation* CEapVpnInterfaceImplementation::NewL(TAbsEapVpnInterfaceParams* aParams) +{ + CEapVpnInterfaceImplementation* self = new (ELeave) CEapVpnInterfaceImplementation; + CleanupStack::PushL(self); + self->ConstructL(aParams->iCaller, aParams->iClient); + + if (self->get_is_valid() != true) + { + User::Leave(KErrGeneral); + } + + CleanupStack::Pop(); + return self; +} + + +//-------------------------------------------------- +// Constructor +//-------------------------------------------------- + +/// VPN does not have any IAP setting at all but we use index 1 in the EAP databases +/// for all VPN related settings. +const TInt EAP_VPN_DEFAULT_SERVICE_TABLE_INDEX = 1; + +CEapVpnInterfaceImplementation::CEapVpnInterfaceImplementation() +: m_trace_log_file_name(0) +, m_is_client(true) +#ifdef USE_EAP_EXPANDED_TYPES +, m_eap_type_array(0) +#endif //#ifdef USE_EAP_EXPANDED_TYPES +, m_index_type(EVpn) +, m_index(EAP_VPN_DEFAULT_SERVICE_TABLE_INDEX) +{ +} + +//-------------------------------------------------- +// Second phase construction. +//-------------------------------------------------- +void CEapVpnInterfaceImplementation::ConstructL(MAbsEapVpnInterface* aCaller, TBool aClient) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::ConstructL()\n"))); + + iCaller = aCaller; + if(aClient) + { + m_is_client = true; + } + else + { + m_is_client = false; + } + + if (iCaller == 0) + { + User::Leave(KErrGeneral); + } + + // Create tools class + m_am_tools = new(ELeave) eap_am_tools_symbian_c(0); + + if (m_am_tools->get_is_valid() != true) + { + // The real reason most likely is KErrNoMemory but since that is not sure we'll use KErrGeneral + User::Leave(KErrGeneral); + } + + if (m_am_tools->configure() != eap_status_ok) + { + User::Leave(KErrGeneral); + } + + + { + TFileName drivePath( PathInfo::MemoryCardRootPath() ); + + const TInt MAXPATHNAME=256ul; + + HBufC* buf = HBufC::NewLC(MAXPATHNAME); + TPtr pathbuffer = buf->Des(); + + pathbuffer.Append( TParsePtrC( drivePath ).DriveAndPath() ); + + { + eap_variable_data_c unicode_drivepath(m_am_tools); + if (unicode_drivepath.get_is_valid() == false) + { + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + User::Leave(KErrGeneral); + } + + eap_status_e status = unicode_drivepath.set_buffer(pathbuffer.Ptr(), pathbuffer.Length(), false, false); + if (status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, status); + User::Leave(KErrGeneral); + } + + eap_variable_data_c utf8_drivepath(m_am_tools); + if (utf8_drivepath.get_is_valid() == false) + { + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + User::Leave(KErrGeneral); + } + + status = m_am_tools->convert_unicode_to_utf8( + utf8_drivepath, + unicode_drivepath); + if (status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, status); + User::Leave(KErrGeneral); + } + + delete m_trace_log_file_name; + m_trace_log_file_name = new eap_variable_data_c(m_am_tools); + + if (m_trace_log_file_name == 0 + || m_trace_log_file_name->get_is_valid() == false) + { + (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + User::Leave(KErrGeneral); + } + + status = m_trace_log_file_name->set_copy_of_buffer(&utf8_drivepath); + if (status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, status); + User::Leave(KErrGeneral); + } + + status = m_trace_log_file_name->add_data(EAPPLUGIN_TRACE_FILE, sizeof(EAPPLUGIN_TRACE_FILE)-1); + if (status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, status); + User::Leave(KErrGeneral); + } + + status = m_trace_log_file_name->add_end_null(); + if (status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, status); + User::Leave(KErrGeneral); + } + } + + CleanupStack::PopAndDestroy(buf); // Delete pathbuffer. + } + + +#ifdef USE_EAP_EXPANDED_TYPES + + m_eap_type_array = new eap_array_c(m_am_tools); + if (m_eap_type_array == 0) + { + User::Leave(KErrGeneral); + } + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + + //------ Create network id + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: Create network ID\n"))); + + u32_t NWID_SRC = 0; + u32_t NWID_DEST = 1; + const u16_t EAP_DUMMY_PACKET_TYPE = 1; + + m_receive_network_id = new eap_am_network_id_c( + m_am_tools); + + if (m_receive_network_id == NULL + || m_receive_network_id->get_is_valid() != true) + { + delete m_receive_network_id; + m_receive_network_id = 0; + User::Leave(KErrGeneral); + } + + eap_status_e status = m_receive_network_id->set_copy_of_am_network_id( + &NWID_SRC, + sizeof(NWID_SRC), + &NWID_DEST, + sizeof(NWID_DEST), + EAP_DUMMY_PACKET_TYPE); + if (status != eap_status_ok) + { + delete m_receive_network_id; + m_receive_network_id = 0; + User::Leave(KErrGeneral); + } + } + + + m_am_tools->set_trace_mask( + eap_am_tools_c::eap_trace_mask_debug + | eap_am_tools_c::eap_trace_mask_always + | eap_am_tools_c::eap_trace_mask_functions + | eap_am_tools_c::eap_trace_mask_error + | eap_am_tools_c::eap_trace_mask_message_data); + + +#if !defined(USE_EAP_RDEBUG_TRACE) + { + eap_variable_data_c trace_output_file(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_output_file_name.get_field(), + &trace_output_file); + + if (status == eap_status_ok + && trace_output_file.get_is_valid_data() == true) + { + (void) m_am_tools->set_trace_file_name(&trace_output_file); + } + } +#endif //#if defined(USE_EAP_RDEBUG_TRACE) + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: configure\n"))); + + if (configure() != eap_status_ok) + { + User::Leave(KErrGeneral); + } + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Configured EAPPlugin...\n"))); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("==================\n"))); + + set_is_valid(); +} + + +//-------------------------------------------------- +// Destructor +//-------------------------------------------------- + +CEapVpnInterfaceImplementation::~CEapVpnInterfaceImplementation() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::~CEapVpnInterfaceImplementation() - destructor\n"))); + + delete m_trace_log_file_name; + m_trace_log_file_name = 0; + + shutdown(); +} + + + +//-------------------------------------------------- +// Shutdown() +//-------------------------------------------------- +eap_status_e CEapVpnInterfaceImplementation::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: Shutdown called\n"))); + + // Cancel timer + cancel_all_timers(); + + // Delete upper stack if it still exists + if (iEapCore != 0) + { + iEapCore->shutdown(); + delete iEapCore; + iEapCore = NULL; + } + + // Print some statistics + if (m_is_client) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_TEST_VECTORS, + (EAPL("client authentication SUCCESS %d, FAILED %d\n"), + m_successful_authentications, + m_failed_authentications)); + } + else + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_TEST_VECTORS, + (EAPL("server authentication SUCCESS %d, FAILED %d\n"), + m_successful_authentications, + m_failed_authentications)); + } + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPPlugin EXITING.\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + if(m_receive_network_id != 0) + { + delete m_receive_network_id; + } + + // Unload all loaded plugins + for(int i = 0; i < m_plugin_if_array.Count(); i++) + { + delete m_plugin_if_array[i]; + } + + m_plugin_if_array.Close(); + +#ifdef USE_EAP_EXPANDED_TYPES + + m_enabled_expanded_eap_array.ResetAndDestroy(); + + m_disabled_expanded_eap_array.ResetAndDestroy(); + + m_eap_type_array->reset(); + + delete m_eap_type_array; + m_eap_type_array = 0; + +#else // For normal EAP type. + + // Delete the IAP EAP type info array + m_iap_eap_array.ResetAndDestroy(); + + m_eap_type_array.Close(); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + delete iManualUsername; + iManualUsername = NULL; + + delete iManualRealm; + iManualRealm = NULL; + + delete iRealmPrefix; + iRealmPrefix = NULL; + + // Finally delete tools. No logging is allowed after this. + if (m_am_tools != 0) + { + m_am_tools->shutdown(); + delete m_am_tools; + } + + return eap_status_ok; +} + + + +//-------------------------------------------------- + +// +void CEapVpnInterfaceImplementation::RunL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: RunL(): iStatus.Int() = %d\n"), + iStatus.Int())); + + if (iStatus.Int() != KErrNone) + { + return; + } + + // Authentication cancelled. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Authentication cancelled.\n"))); + + // Set block on. + m_block_packet_sends_and_notifications = true; + + // Reset flags + m_stack_marked_to_be_deleted = true; + set_timer(this, EAPOL_AM_CORE_TIMER_DELETE_STACK_ID, 0, 0); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent: EFailedCompletely.\n"))); + + iCaller->EapIndication(EFailedCompletely); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +void CEapVpnInterfaceImplementation::DoCancel() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_vpn_if::DoCancel()\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + + +//-------------------------------------------------- +// Configure() +//-------------------------------------------------- + +eap_status_e CEapVpnInterfaceImplementation::configure() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::configure()\n"))); + + //---------------------------------------------------------- + + { + eap_variable_data_c EAP_TRACE_activate_trace_on_error(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAP_TRACE_activate_trace_on_error.get_field(), + &EAP_TRACE_activate_trace_on_error); + + if (status == eap_status_ok + && EAP_TRACE_activate_trace_on_error.get_is_valid_data() == true) + { + u32_t *activate_trace_on_error = (u32_t *)EAP_TRACE_activate_trace_on_error.get_data(sizeof(u32_t)); + + if (activate_trace_on_error != 0 + && *activate_trace_on_error != 0) + { + m_am_tools->set_activate_trace_on_error(); + } + } + } + + //---------------------------------------------------------- + + // All of the configuration options are optional. + // So we return OK. + return eap_status_ok; +} + + +//---------------------------------------------------------- +// Implementations of virtual functions from CEapVpnInterface +//---------------------------------------------------------- + +/** + * Function: EapConfigure + * + * Description: Configures the eap plugin + * + * @param aManualUsername The username, if not zero + * @param aManualRealm The realm, if not zero + * @param aManualRealmPrefix The realm prefix, if not zero + * @param aHideInitialIdentity Scramble username, if true + * + */ +TInt CEapVpnInterfaceImplementation::EapConfigure( + TDesC8& aManualUsername, + TDesC8& aManualRealm, + TDesC8& aRealmPrefix, + TBool aHideInitialIdentity) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::EapConfigure()\n"))); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::EapConfigure(): aManualUsername\n"), + aManualUsername.Ptr(), + aManualUsername.Size())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::EapConfigure(): aManualRealm\n"), + aManualRealm.Ptr(), + aManualRealm.Size())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::EapConfigure(): aRealmPrefix\n"), + aRealmPrefix.Ptr(), + aRealmPrefix.Size())); + + iHideInitialIdentity = aHideInitialIdentity; + + delete iManualUsername; + iManualUsername = NULL; + + delete iManualRealm; + iManualRealm = NULL; + + delete iRealmPrefix; + iRealmPrefix = NULL; + + TRAPD(error, + iManualUsername = aManualUsername.AllocL(); + iManualRealm = aManualRealm.AllocL(); + iRealmPrefix = aRealmPrefix.AllocL(); + ); + + if (error != KErrNone) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::EapConfigure(): error = %d\n"), + error)); + return error; + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::EapConfigure(): iManualUsername\n"), + iManualUsername->Ptr(), + iManualUsername->Size())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::EapConfigure(): iManualRealm\n"), + iManualRealm->Ptr(), + iManualRealm->Size())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::EapConfigure(): iRealmPrefix\n"), + iRealmPrefix->Ptr(), + iRealmPrefix->Size())); + + return KErrNone; +} + + +/** + * Function: StartL + * + * Description: Initializes the eap plugin + * + */ +TInt CEapVpnInterfaceImplementation::StartL(const TUint8 aEapType) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::StartL()\n"))); + + eap_status_e status(eap_status_ok); + iQueryIdentity = EFalse; + + iRequestedEapType = static_cast(aEapType); + + if (iEapCore != 0) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Deleting previously used stack.\n"))); + + // It is an error to call start without calling disassociated + if (m_stack_marked_to_be_deleted == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_vpn_if::Start called twice!\n"))); + return KErrAlreadyExists; + } + + // The previously used stack is perhaps still waiting for deletion. + cancel_timer(this, EAPOL_AM_CORE_TIMER_DELETE_STACK_ID); + + // Delete stack + iEapCore->shutdown(); + delete iEapCore; + iEapCore = 0; + + m_stack_marked_to_be_deleted = false; + } + + // Clear packet send and notification blocking. + m_block_packet_sends_and_notifications = false; + +#ifdef USE_EAP_EXPANDED_TYPES + + if (m_enabled_expanded_eap_array.Count() == 0) + { + // The EAP field was empty. Allow all types. + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Empty EAP field -> enable all types.\n"))); + + RImplInfoPtrArray eapArray; + CleanupStack::PushL( TCleanupItem( CleanupImplArray, &eapArray ) ); + + REComSession::ListImplementationsL(KEapTypeInterfaceUid, eapArray); + + for (TInt i = 0; i < eapArray.Count(); i++) + { + SEapExpandedType * expandedEAPType = new (ELeave) SEapExpandedType; + expandedEAPType->EapExpandedType = eapArray[i]->DataType(); + + eap_expanded_type_c tmpExpEAPType; + + // This is to make the tmpExpEAPType in 8 byte string with correct vendor type and vendor id details. + status = eap_expanded_type_c::read_type(m_am_tools, + 0, // index should be zero here. + expandedEAPType->EapExpandedType.Ptr(), + KExpandedEapTypeSize, + &tmpExpEAPType); + if (status != eap_status_ok) + { + delete expandedEAPType; + expandedEAPType = 0; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::StartL: eap_expanded_type_c::write_type failed \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Now add the EAP types to the array + if(tmpExpEAPType == iRequestedEapType) + { + // This is the requested EAP type. + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::StartL:Enabled (Requested) EAP type:"), + expandedEAPType->EapExpandedType.Ptr(), + expandedEAPType->EapExpandedType.Size())); + + m_enabled_expanded_eap_array.Insert(expandedEAPType, 0); // This goes to the beginning. + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::StartL:Disabled EAP type:"), + expandedEAPType->EapExpandedType.Ptr(), + expandedEAPType->EapExpandedType.Size())); + + delete expandedEAPType; + expandedEAPType = 0; + + } + } // for() + + CleanupStack::PopAndDestroy(&eapArray); + } + +#else // For normal EAP type. + + if (m_iap_eap_array.Count() == 0) + { + // The EAP field was empty. Allow all types. + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Empty EAP field -> enable all types.\n"))); + + RImplInfoPtrArray eapArray; + CleanupStack::PushL( TCleanupItem( CleanupImplArray, &eapArray ) ); + + REComSession::ListImplementationsL(KEapTypeInterfaceUid, eapArray); + + for (TInt i = 0; i < eapArray.Count(); i++) + { + TEap *eap = new(ELeave) TEap; + eap->UID.Copy(eapArray[i]->DataType()); + eap->Enabled = EFalse; + + // Convert the string to integer + TLex8 tmp(eap->UID); + TInt val(0); + tmp.Val(val); + + if(val == iRequestedEapType) + { + eap->Enabled = ETrue; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-Type %d enabled\n"), val)); + + m_iap_eap_array.Insert(eap, 0); + } + else + { + m_iap_eap_array.Append(eap); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-Type %d disabled\n"), val)); + } + } // for() + + CleanupStack::PopAndDestroy(&eapArray); + } + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + CompleteAssociation(status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)); +} + +//-------------------------------------------------- + +// +TInt CEapVpnInterfaceImplementation::CompleteAssociation( + const TInt aResult + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::CompleteAssociation(): aResult=%d\n"), + aResult)); + + eap_status_e status(eap_status_ok); + + // ASSOCIATION UNSUCCESSFUL + if (aResult != KErrNone) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CompleteAssociation: Unsuccessful.\n"))); + iCaller->EapIndication(EFailedCompletely); + return KErrNone; + } + + // ASSOCIATION SUCCESSFUL + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("CompleteAssociation: Successful.\n"))); + + // Create stack if it does not already exist. + status = create_upper_stack(); + + if (status != eap_status_ok + && status != eap_status_already_exists) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent to VPN: EFailedCompletely.\n"))); + + iCaller->EapIndication(EFailedCompletely); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return KErrNone; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)); +} + +/** + * Function: QueryIdentity + * + * Description: Ask the identity + * + * @param aType name of requested eap type implementation. + */ +TInt CEapVpnInterfaceImplementation::QueryIdentity() +{ + // Build Eap Identity reques message + // and send it to eap_core. + // Eap core determines the identity and + // responses with packet_send() callback + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::QueryIdentity()\n"))); + + // Build identity request only if GSM/SIM or AKA + if((iRequestedEapType != eap_type_gsmsim) && (iRequestedEapType != eap_type_aka)) + { + TRAPD(error, (iCaller->EapIdentityResponseL(NULL))); + if(error != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(error)); + } + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, eap_status_ok)); + } + + iQueryIdentity = ETrue; + eap_status_e status(eap_status_ok); + + status = send_eap_identity_request(); + + if(status == eap_status_pending_request) + { + // Request pending, it's OK + status = eap_status_ok; + } + + if(status != eap_status_ok) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_vpn_if::QueryIdentity() error, status = %d\n"), status)); + + iQueryIdentity = EFalse; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)); +} + +//-------------------------------------------------- + +// +eap_status_e CEapVpnInterfaceImplementation::send_eap_identity_request() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::send_eap_identity_request()\n"))); + + // Creates a identity request message. + eap_buf_chain_wr_c request_packet( + eap_write_buffer, + m_am_tools, + EAP_CORE_PACKET_BUFFER_LENGTH); + + if (request_packet.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_eap_identity_request(): %s, %s, packet buffer corrupted.\n"), + (m_is_client == true) ? "client": "server" + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t buffer_size = EAP_CORE_PACKET_BUFFER_LENGTH; + + eap_header_wr_c eap_request( + m_am_tools, + request_packet.get_data_offset(0, buffer_size), + buffer_size); + + if (eap_request.get_is_valid() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("send_eap_identity_request():packet buffer corrupted.\n") + )); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + eap_request.set_length((u16_t)(EAP_CORE_PACKET_BUFFER_LENGTH), true); + eap_request.set_code(eap_code_request); + eap_request.set_identifier(0); + eap_request.set_type_data_length(0u, false); + eap_request.set_type(eap_type_identity, false); + + EAP_ASSERT(eap_request.get_length() >= 4); + + status = iEapCore->packet_process( + m_receive_network_id, + &eap_request, + eap_request.get_length()); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::send_identity_request(): iEapCore->packet_process() = %d\n"), status)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +/** + * Function: EapInbound + * + * Description: Handle incoming eap message. + * + * @param aMessage incoming eap message. + * + */ +TInt CEapVpnInterfaceImplementation::EapInbound(const TDesC8& aMessage) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // from eapol_am_core_symbian.cpp ReceivePacket + iQueryIdentity = EFalse; + eap_status_e status(eap_status_ok); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::EapInbound()\n"))); + + TInt length = aMessage.Length(); + if (length < 4) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message)); + } + + // Creates a identity request message. + eap_buf_chain_wr_c request_packet( + eap_write_buffer, + m_am_tools, + aMessage.Length()); + + request_packet.add_data(aMessage.Ptr(), aMessage.Length()); + + eap_header_wr_c eap_request( + m_am_tools, + request_packet.get_data_offset(0, aMessage.Length()), + aMessage.Length()); + + // Forward the packet to the Eap layer of the EAPOL stack. Ignore return value. Failure is signalled using state_notification. + status = iEapCore->packet_process( + m_receive_network_id, + &eap_request, + length); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::iEapCore->packet_process() = %d\n"), status)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)); +} + +//-------------------------------------------------- +// create_upper_stack +//-------------------------------------------------- +eap_status_e CEapVpnInterfaceImplementation::create_upper_stack() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::create_upper_stack()\n"))); + + eap_status_e status(eap_status_ok); + + if (iEapCore == 0) + { + iEapCore = new eap_core_c(m_am_tools, this, m_is_client, m_receive_network_id, EFalse); + + if (iEapCore == 0 + || iEapCore->get_is_valid() != true) + { + if (iEapCore != 0) + { + iEapCore->shutdown(); + delete iEapCore; + iEapCore = 0; + } + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Stack creation failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Initialise upper stack + status = iEapCore->configure(); + + if (status != eap_status_ok) + { + iEapCore->shutdown(); + delete iEapCore; + iEapCore = 0; + + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Stack creation failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + else + { + status = eap_status_already_exists; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + + +// Virtual callback function implementations, called by the eap_core + +/** + * The derived class could send packets to partner class with this function. + * @see abs_eap_base_type_c::packet_send(). + */ +eap_status_e CEapVpnInterfaceImplementation::packet_send( + const eap_am_network_id_c * const /*send_network_id*/, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t /*buffer_length*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::packet_send(data_length=%d)\n"), + data_length)); + + if (header_offset != 0u) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet buffer corrupted.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_process_general_error; + } + else if (header_offset+data_length != sent_packet->get_data_length()) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: packet_send: packet buffer corrupted (data_length != sent_packet->get_data_length()).\n"))); + EAP_ASSERT(data_length == sent_packet->get_buffer_length()); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_process_general_error; + } + + if (m_block_packet_sends_and_notifications == true) + { + // Packet sending block is active. This happens when disassociated has been called. + // start_authentication clears the block. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("packet_send: packet ignored because Disassociated() was called.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + } + + eap_header_wr_c eap( + m_am_tools, + sent_packet->get_data_offset( + header_offset, data_length), + data_length); + + TInt status(KErrNone); + if (status == KErrNone) + { + u8_t * const packet_data = sent_packet->get_data_offset(header_offset, data_length); + if (packet_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_buffer_too_short; + } + + // Here we send the original packet. + HBufC8* eapData = NULL; + TInt error = KErrNone; + + if(iQueryIdentity) + { + TPtr8 eapPtr(packet_data + KEapIdentityOffset, data_length - KEapIdentityOffset, data_length - KEapIdentityOffset); + TRAP(error, eapData = eapPtr.Alloc()); + } + else + { + TPtr8 eapPtr(packet_data, data_length, data_length); + TRAP(error, eapData = eapPtr.Alloc()); + } + + if(error != KErrNone) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Allocation error\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if(iQueryIdentity) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::EapIdentityResponseL()\n"))); + + TRAPD(error, (iCaller->EapIdentityResponseL(eapData))); + if(error != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(error)); + } + + iQueryIdentity = EFalse; + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::EapOutboundL()\n"))); + + TRAPD(error, (iCaller->EapOutboundL(eapData))); + if(error != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(error)); + } + } + ++m_packet_index; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(status)); +} + + +/** + * The get_header_offset() function obtains the header offset of EAP-packet. + * @see abs_eap_base_type_c::get_header_offset(). + */ +u32_t CEapVpnInterfaceImplementation::get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + *MTU = KMTU; + *trailer_length = KTrailerLength; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return KHeaderOffset; +} + +/** + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + * @param receive_network_id includes the addresses (network identity) and packet type. + */ +eap_status_e CEapVpnInterfaceImplementation::load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type_if, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::load_module()\n"))); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_vpn_if::load_module(type %d=%s, tunneling_type %d=%s)\n"), + convert_eap_type_to_u32_t(type), + eap_header_string_c::get_eap_type_string(type), + convert_eap_type_to_u32_t(tunneling_type), + eap_header_string_c::get_eap_type_string(tunneling_type))); + + EAP_UNREFERENCED_PARAMETER(type); + EAP_UNREFERENCED_PARAMETER(tunneling_type); + + eap_status_e status = eap_status_process_general_error; + + if (type != iRequestedEapType) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("load_module: eap_expanded_type_c::write_type(): not supported EAP-method\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type); + } + + EAP_ASSERT_TOOLS(m_am_tools, (type == iRequestedEapType)); + +#ifdef USE_EAP_EXPANDED_TYPES + + TBuf8 cue; + + // Some indirect way of forming the 8 byte string of an EAP type for the cue is needed here. + TUint8 tmpExpCue[KExpandedEapTypeSize]; + + // This is to make the tmpExpCue in 8 byte string with correct vendor type and vendor id details. + status = eap_expanded_type_c::write_type(m_am_tools, + 0, // index should be zero here. + tmpExpCue, + KExpandedEapTypeSize, + true, + iRequestedEapType); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("load_module: eap_expanded_type_c::write_type failed \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Now copy the 8 byte string to the real expanded cue. + cue.Copy(tmpExpCue, KExpandedEapTypeSize); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL:CEapVpnInterfaceImplementation::load_module: Expanded CUE:"), + cue.Ptr(), + cue.Size())); + +#else + + TBuf8 cue; + cue.Num(static_cast(iRequestedEapType)); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + CEapType* eapType = 0; + TInt error(KErrNone); + +#ifdef USE_EAP_EXPANDED_TYPES + + // Check if this EAP type has already been loaded + TInt eapArrayIndex = find( + m_eap_type_array, + &iRequestedEapType, + m_am_tools); + + if (eapArrayIndex >= 0) + +#else // For normal EAP type. + + // Check if this EAP type has already been loaded + TInt eapArrayIndex = m_eap_type_array.Find(iRequestedEapType); + + if (eapArrayIndex != KErrNotFound) + +#endif + + { + // Yep. It was loaded already. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: EAP Type Already loaded\n"))); + + eapType = m_plugin_if_array[eapArrayIndex]; + } + else + { + // We must have a trap here since the EAP core knows nothing about Symbian. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: EAP Type new\n"))); + + TRAP(error, (eapType = CEapType::NewL(cue, m_index_type, m_index))); + + if (error != KErrNone + || eapType == 0) + { + // Interface not found or implementation creation function failed + + delete eapType; + eapType = 0; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: EAP Type new, unable to load\n"))); + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ECom could not find/initiate implementation.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + //-------------------------------------------------------- + //-------------------------------------------------------- + // Set the values for realm and user name if there is any. + // If there is no values the default settings will be used( automatic realm and username). + + + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::load_module - About to configure manual/auto username and manual/auto realm \n"))); + + EAPSettings* setSettings = new EAPSettings; + if( setSettings == NULL ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::load_module - EAPSettings allocation error \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if(iRequestedEapType == eap_type_aka) + { + setSettings->iEAPType = EAPSettings::EEapAka; + + } + else if(iRequestedEapType == eap_type_gsmsim) + { + setSettings->iEAPType = EAPSettings::EEapSim; + } + else + { + delete setSettings; + setSettings = 0; + + // Only EAP-SIM and AKA are possible now. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type); + } + + if(iManualUsername && iManualUsername->Length() != 0) + { + setSettings->iUsernamePresent = EGSMSIMUseManualUsernameYes; // Same value for both SIM and AKA. + setSettings->iUsername.Copy(iManualUsername->Des()); + } + else + { + // No user name. we have to set automatic now. + setSettings->iUsernamePresent = EGSMSIMUseManualUsernameNo; // Same value for both SIM and AKA. + } + + if(iManualRealm && iManualRealm->Length() != 0) + { + setSettings->iRealmPresent = EGSMSIMUseManualRealmYes; // Same value for both SIM and AKA. + setSettings->iRealm.Copy(iManualRealm->Des()); + } + else + { + // No realm. we have to set automatic now. + setSettings->iRealmPresent = EGSMSIMUseManualRealmNo; // Same value for both SIM and AKA. + } + + TRAP(error, eapType->SetConfigurationL(*setSettings) ); + if ( error != KErrNone ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::load_module - Setting Manual Username and Realm failed.error=%d, Continuing \n"))); + } + + delete setSettings; + setSettings = 0; + } + + //-------------------------------------------------------- + //-------------------------------------------------------- + + // Create the EAP protocol interface implementation. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: EAP Type new, GetStackInterfaceL()\n"))); + +#ifdef USE_EAP_SIMPLE_CONFIG + + TRAP(error, (*eap_type_if = eapType->GetStackInterfaceL( + m_am_tools, + partner, + is_client_when_true, + receive_network_id, + 0))); // Check this up. + +#else + + TRAP(error, (*eap_type_if = eapType->GetStackInterfaceL( + m_am_tools, + partner, + is_client_when_true, + receive_network_id))); + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG + + if (error != KErrNone + || *eap_type_if == 0 + || (*eap_type_if)->get_is_valid() == false) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: EAP Type new, GetStackInterfaceL(), failed = %d\n"), error)); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Could not create EAP type interface instance. Error: %d\n"), error)); + + status = eap_status_allocation_error; + + // Unload DLL (two ways, depending whether this type was already loaded...) + if (eapArrayIndex == KErrNotFound) + { + // No need to call shutdown here because GetStackInterfaceL has done it. + delete eapType; + } + else + { + unload_module((eap_type_value_e)iRequestedEapType); + } + // Note: even in error cases eap_core_c deletes eap_type_if + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: EAP Type new, GetStackInterfaceL(), success\n"))); + + status = eap_status_ok; + + if (eapArrayIndex == KErrNotFound) + { + // Add plugin information to the member arrays. There is no need to store eap_type pointer because + // the stack takes care of its deletion. + if (m_plugin_if_array.Append(eapType) != KErrNone) + { + delete eapType; + status = eap_status_allocation_error; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#ifdef USE_EAP_EXPANDED_TYPES + + eap_type_value_e * tmpEAPType = new eap_type_value_e(); + if(tmpEAPType == NULL) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eapol_am_wlan_authentication_symbian_c::load_module() eap_type_value_e creation failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *tmpEAPType = type; + + status = m_eap_type_array->add_object(tmpEAPType, true); + + if (status != eap_status_ok) + +#else // For normal EAP type. + + if (m_eap_type_array.Append(iRequestedEapType) != KErrNone) + +#endif + { + // Remove the eap type added just previously + m_plugin_if_array.Remove(m_plugin_if_array.Count() - 1); + delete eapType; + status = eap_status_allocation_error; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +/** + * The unload_module() function unloads the module of a EAP-type. + * @param eap_type is the requested EAP-type. + */ +eap_status_e CEapVpnInterfaceImplementation::unload_module(const eap_type_value_e type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_type_does_not_exists_error); + +#ifdef USE_EAP_EXPANDED_TYPES + + // Check if this EAP type has already been loaded + TInt index = find( + m_eap_type_array, + &type, + m_am_tools); + + if (index >= 0) + { + // EAP was loaded before. + + delete m_plugin_if_array[index]; + m_plugin_if_array.Remove(index); + + status = m_eap_type_array->remove_object(index); + } + +#else // For normal EAP types. + + TInt index = m_eap_type_array.Find(type); + + if (index != KErrNotFound) + { + delete m_plugin_if_array[index]; + m_plugin_if_array.Remove(index); + m_eap_type_array.Remove(index); + status = eap_status_ok; + } + +#endif + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} +//-------------------------------------------------- + +void CEapVpnInterfaceImplementation::set_is_valid() +{ + m_is_valid = true; +} + +bool CEapVpnInterfaceImplementation::get_is_valid() +{ + return m_is_valid; +} + +void CEapVpnInterfaceImplementation::increment_authentication_counter() +{ + ++m_authentication_counter; +} + +u32_t CEapVpnInterfaceImplementation::get_authentication_counter() +{ + return m_authentication_counter; +} + +bool CEapVpnInterfaceImplementation::get_is_client() +{ + return m_is_client; +} + +/** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @see abs_eap_base_type_c::packet_data_crypto_keys(). + */ +eap_status_e CEapVpnInterfaceImplementation::packet_data_crypto_keys( + const eap_am_network_id_c * const /*send_network_id*/, + const eap_master_session_key_c * const master_session_key + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + HBufC8* sharedKey = NULL; + TPtr8 keyPtr( + master_session_key->get_data( + master_session_key->get_data_length()/2), + master_session_key->get_data_length()/2, + master_session_key->get_data_length()/2); + + TRAPD(error, (sharedKey = keyPtr.AllocL())); + if(error != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: EapSharedKeyL()\n"))); + + TRAP(error, (iCaller->EapSharedKeyL(sharedKey))); + if(error != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(error)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +/** + * The packet_data_session_key() function passes one traffic encryption key to + * the lower layers. Ultimately the key can end up to the WLAN hardware. + * @param send_network_id carries the addresses (network identity) and type of the packet. + * @param key is the encryption key + * @param key_length is the length of the key + * @param key_type describes the type of the key (WEP or something else...) + * @param key_index is the index of the encryption key (there can be four broadcast keys in WEP for example) + */ +eap_status_e CEapVpnInterfaceImplementation::packet_data_session_key( + const eap_am_network_id_c * const /*send_network_id*/, + const eapol_session_key_c * const /*key*/ + ) +{ + // Not used, but might be called? + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + TInt status(KErrNone); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(status)); +} + +/** + * The read_configure() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @see abs_eap_base_type_c::read_configure(). + */ +eap_status_e CEapVpnInterfaceImplementation::read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT_ALWAYS(data != NULL); + EAP_ASSERT_ALWAYS(field->get_field_length() <= KMaxConfigStringLength); + + EAP_UNREFERENCED_PARAMETER(KMaxConfigStringLength); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::read_configure()\n"))); + + eap_status_e status(eap_status_ok); + + m_am_tools->trace_configuration( + status, + field, + data); + + + // Check if the wanted parameter is default type + + { + eap_variable_data_c wanted_field(m_am_tools); + + status = wanted_field.set_buffer( + field->get_field(), + field->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + + if (wanted_field.compare( + cf_str_EAP_default_type_u32_t.get_field()->get_field(), + cf_str_EAP_default_type_u32_t.get_field()->get_field_length()) == 0 + || wanted_field.compare( + cf_str_EAP_server_default_type_u32_t.get_field()->get_field(), + cf_str_EAP_server_default_type_u32_t.get_field()->get_field_length()) == 0) + { + // We need to return here the next EAP type we should try + +#ifdef USE_EAP_EXPANDED_TYPES + + if(m_enabled_expanded_eap_array.Count() < 1) + { + // No enabled EAP types. + + // Send WLM notification because there is no way that the authentication + // can be successful if we don't have any EAP types to use... + if (m_is_client) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: No configured EAP types or all tried unsuccessfully.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + + // Now there are enabled EAP type, we need to take the first EAP type from the arrary. + SEapExpandedType * expandedEAPType = m_enabled_expanded_eap_array[0]; //First item. + + status = data->set_copy_of_buffer(expandedEAPType->EapExpandedType.Ptr(), KExpandedEapTypeSize); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // This is to check if this is the requested EAP type. + + eap_expanded_type_c tmpExpEAPType; + + // This is to make the tmpExpEAPType in 8 byte string with correct vendor type and vendor id details. + status = eap_expanded_type_c::read_type(m_am_tools, + 0, // index should be zero here. + expandedEAPType->EapExpandedType.Ptr(), + KExpandedEapTypeSize, + &tmpExpEAPType); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::read_configure: eap_expanded_type_c::write_type failed \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if(tmpExpEAPType == iRequestedEapType) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::StartL:Trying EAP type:"), + expandedEAPType->EapExpandedType.Ptr(), + expandedEAPType->EapExpandedType.Size())); + } + +#else // For normal EAP types + + TInt i; + + for (i = 0; i < m_iap_eap_array.Count(); i++) + { + // Find the first enabled EAP type (highest priority) + TEap *eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + // Convert the string to integer + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + + status = data->set_copy_of_buffer((u8_t*) &val, sizeof(TUint)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if(val == iRequestedEapType) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL: Trying EAP type: %d.\n"), val)); + break; + } + else + { + continue; + } + } + } // for() + + if (i >= m_iap_eap_array.Count()) + { + // Not found + // Send WLM notification because there is no way that the authentication + // can be successful if we don't have any EAP types to use... + if (m_is_client) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: No configured EAP types or all tried unsuccessfully.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (wanted_field.compare( + cf_str_EAP_GSMSIM_UMA_profile.get_field()->get_field(), + cf_str_EAP_GSMSIM_UMA_profile.get_field()->get_field_length()) == 0 + || wanted_field.compare( + cf_str_EAP_AKA_UMA_profile.get_field()->get_field(), + cf_str_EAP_AKA_UMA_profile.get_field()->get_field_length()) == 0) + { + // Set uma profile of EAP-SIM and EAP-AKA. + TInt val(1); + status = data->set_copy_of_buffer((u8_t*) &val, sizeof(TUint)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (wanted_field.compare( + cf_str_EAP_GSMSIM_wait_eap_success_packet.get_field()->get_field(), + cf_str_EAP_GSMSIM_wait_eap_success_packet.get_field()->get_field_length()) == 0 + || wanted_field.compare( + cf_str_EAP_AKA_wait_eap_success_packet.get_field()->get_field(), + cf_str_EAP_AKA_wait_eap_success_packet.get_field()->get_field_length()) == 0) + { + // Set wait eap success of EAP-SIM and EAP-AKA. + TInt val(1); + status = data->set_copy_of_buffer((u8_t*) &val, sizeof(TUint)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (wanted_field.compare( + cf_str_EAP_GSMSIM_UMA_realm_prefix.get_field()->get_field(), + cf_str_EAP_GSMSIM_UMA_realm_prefix.get_field()->get_field_length()) == 0 + || wanted_field.compare( + cf_str_EAP_AKA_UMA_realm_prefix.get_field()->get_field(), + cf_str_EAP_AKA_UMA_realm_prefix.get_field()->get_field_length()) == 0) + { + // Set uma realm prefix of EAP-SIM and EAP-AKA. + status = data->set_copy_of_buffer(iRealmPrefix->Ptr(), iRealmPrefix->Length()); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (wanted_field.compare( + cf_str_EAP_GSMSIM_use_manual_realm.get_field()->get_field(), + cf_str_EAP_GSMSIM_use_manual_realm.get_field()->get_field_length()) == 0 + || wanted_field.compare( + cf_str_EAP_AKA_use_manual_realm.get_field()->get_field(), + cf_str_EAP_AKA_use_manual_realm.get_field()->get_field_length()) == 0) + { + // Use ManualRealm of EAP-SIM and EAP-AKA. + TInt val(1); + if(iManualRealm == NULL || (iManualRealm && (iManualRealm->Length() == 0))) + { + val = 0; + } + status = data->set_copy_of_buffer((u8_t*) &val, sizeof(TUint)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (wanted_field.compare( + cf_str_EAP_GSMSIM_manual_realm.get_field()->get_field(), + cf_str_EAP_GSMSIM_manual_realm.get_field()->get_field_length()) == 0 + || wanted_field.compare( + cf_str_EAP_AKA_manual_realm.get_field()->get_field(), + cf_str_EAP_AKA_manual_realm.get_field()->get_field_length()) == 0) + { + // ManualRealm of EAP-SIM and EAP-AKA. + status = data->set_copy_of_buffer(iManualRealm->Ptr(), iManualRealm->Length()); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (wanted_field.compare( + cf_str_EAP_GSMSIM_use_manual_username.get_field()->get_field(), + cf_str_EAP_GSMSIM_use_manual_username.get_field()->get_field_length()) == 0 + || wanted_field.compare( + cf_str_EAP_AKA_use_manual_username.get_field()->get_field(), + cf_str_EAP_AKA_use_manual_username.get_field()->get_field_length()) == 0) + { + // Use ManualUsername of EAP-SIM and EAP-AKA. + TInt val(1); + if(iManualUsername == NULL || (iManualUsername && (iManualUsername->Length() == 0))) + { + val = 0; + } + status = data->set_copy_of_buffer((u8_t*) &val, sizeof(TUint)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (wanted_field.compare( + cf_str_EAP_GSMSIM_manual_username.get_field()->get_field(), + cf_str_EAP_GSMSIM_manual_username.get_field()->get_field_length()) == 0 + || wanted_field.compare( + cf_str_EAP_AKA_manual_username.get_field()->get_field(), + cf_str_EAP_AKA_manual_username.get_field()->get_field_length()) == 0) + { + // ManualUsername of EAP-SIM and EAP-AKA. + status = data->set_copy_of_buffer(iManualUsername->Ptr(), iManualUsername->Length()); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (wanted_field.compare( + cf_str_EAP_GSMSIM_2_digit_mnc_map_of_mcc_of_imsi_array.get_field()->get_field(), + cf_str_EAP_GSMSIM_2_digit_mnc_map_of_mcc_of_imsi_array.get_field()->get_field_length()) == 0 + || wanted_field.compare( + cf_str_EAP_AKA_2_digit_mnc_map_of_mcc_of_imsi_array.get_field()->get_field(), + cf_str_EAP_AKA_2_digit_mnc_map_of_mcc_of_imsi_array.get_field()->get_field_length()) == 0) + { + // 2-digit MNC configuration of EAP-SIM and EAP-AKA. + const TUint32 K2DigitMncMccList[] + = { + 202,204,206,208,213,214,216,218, + 219,220,222,226,228,230,231,232, + 234,238,240,242,244,246,247,248, + 250,255,257,259,260,262,266,268, + 270,272,274,276,278,280,282,284, + 286,288,290,293,294,295,308,340, + 362,363,400,401,402,404,410,413, + 414,415,416,417,419,420,421,422, + 424,425,426,427,428,429,432,434, + 436,437,438,440,441,452,454,455, + 456,457,460,470,472,502,505,510, + 515,520,525,528,530,537,539,541, + 546,547,549,602,603,604,605,607, + 608,609,610,611,612,613,614,615, + 616,617,619,620,621,622,623,624, + 625,626,628,629,630,631,633,634, + 635,636,638,639,640,641,642,643, + 645,646,647,648,649,650,651,652, + 653,654,655,702,704,706,710,712, + 714,716,724,730,734,744,746,901 + }; + + status = data->set_copy_of_buffer((u32_t*) K2DigitMncMccList, sizeof(K2DigitMncMccList)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (wanted_field.compare( + cf_str_EAP_TRACE_output_file_name.get_field()->get_field(), + cf_str_EAP_TRACE_output_file_name.get_field()->get_field_length()) == 0) + { + // Trace output file name. + status = data->set_copy_of_buffer( + m_trace_log_file_name); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (wanted_field.compare( + cf_str_EAP_GSMSIM_max_session_validity_time.get_field()->get_field(), + cf_str_EAP_GSMSIM_max_session_validity_time.get_field()->get_field_length()) == 0 + || wanted_field.compare( + cf_str_EAP_AKA_max_session_validity_time.get_field()->get_field(), + cf_str_EAP_AKA_max_session_validity_time.get_field()->get_field_length()) == 0) + { + u32_t session_validity_time_in_seconds(43200ul); + + status = data->set_copy_of_buffer(reinterpret_cast(&session_validity_time_in_seconds), sizeof(session_validity_time_in_seconds)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (wanted_field.compare( + cf_str_EAP_CORE_wait_eap_request_type_timeout.get_field()->get_field(), + cf_str_EAP_CORE_wait_eap_request_type_timeout.get_field()->get_field_length()) == 0) + { + u32_t wait_eap_request_type_timeout_in_milli_seconds(30000ul); + + status = data->set_copy_of_buffer(reinterpret_cast(&wait_eap_request_type_timeout_in_milli_seconds), sizeof(wait_eap_request_type_timeout_in_milli_seconds)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: CEapVpnInterfaceImplementation: read_configure(): Unknown configuration\n"), + field->get_field(), + field->get_field_length())); + } + } + + // Otherways just use the default value + m_am_tools->trace_configuration( + status, + field, + data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +/** + * The write_configure() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @see abs_eap_base_type_c::write_configure(). + */ +eap_status_e CEapVpnInterfaceImplementation::write_configure( + const eap_configuration_field_c * const /*field*/, + eap_variable_data_c * const /*data*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_not_supported; +} + +/** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + * These two notifications tells the end state of authentication session. These are the only + * reliable indications of the final status of authentication session. + * You MUST NOT make decision based on the return value of abs_eap_stack_interface_c::packet_process(). + */ +void CEapVpnInterfaceImplementation::state_notification( + const abs_eap_state_notification_c * const state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::state_notification() = %d\n"), state->get_current_state())); + + if (m_block_packet_sends_and_notifications == true) + { + // Notification block is active. + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("state_notification: notification ignored because Disassociated() was called.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + // Check if this is EAP layer notification + if(state->get_protocol_layer() == eap_protocol_layer_eap) + { + switch (state->get_current_state()) + { + case eap_state_none: + break; + case eap_state_identity_request_sent: + // This is for server only so no need to notify WLM. + break; + case eap_state_identity_request_received: + break; + case eap_state_identity_response_received: + // This is for server only so no need to notify WLM. + break; + case eap_state_authentication_finished_successfully: + { + increment_authentication_counter(); + m_successful_authentications++; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent: ESuccess.\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: Indication sent: ESuccess\n"))); + iCaller->EapIndication(ESuccess); + break; + } + case eap_state_authentication_terminated_unsuccessfully: + { + increment_authentication_counter(); + m_failed_authentications++; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation: Indication sent: EFailure\n"))); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Indication sent: EFailure.\n"))); + iCaller->EapIndication(EFailure); + break; + } + default: + break; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +/** + * The set_timer() function initializes timer to be elapsed after time_ms milliseconds. + * @param initializer is pointer to object which timer_expired() function will + * be called after timer elapses. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * @param data is pointer to any user selected data which will be returned in timer_expired() function. + * @param time_ms is the time of timer in milli seconds. + * + * Adaptation module internally implements the timer. + */ +eap_status_e CEapVpnInterfaceImplementation::set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_am_tools->am_set_timer( + p_initializer, + p_id, + p_data, + p_time_ms); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +/** + * The cancel_timer() function cancels the timer id initiated by initializer. + * @param initializer is pointer to object which set the cancelled timer. + * @param id is identifier which will be returned in timer_expired() function. + * The user selects and interprets the id for this timer. + * + * Adaptation module internally implements the timer. + */ +eap_status_e CEapVpnInterfaceImplementation::cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_am_tools->am_cancel_timer( + p_initializer, + p_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +/** + * The cancel_all_timers() function cancels all timers. + * User should use this in termination of the stack before + * the adaptation module of tools is deleted. + * Preferred mode is to cancel each timer directly + * using cancel_timer() function. + * + * Adaptation module internally implements the timer. + */ +eap_status_e CEapVpnInterfaceImplementation::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const eap_status_e status = m_am_tools->am_cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +/** + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + * @param eap_type is the requested EAP-type. + */ +eap_status_e CEapVpnInterfaceImplementation::check_is_valid_eap_type(const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_illegal_eap_type); + +#ifdef USE_EAP_EXPANDED_TYPES + + for (int i = 0; i < m_enabled_expanded_eap_array.Count(); i++) + { + TBuf8 tmpExpEAP(m_enabled_expanded_eap_array[i]->EapExpandedType); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::check_is_valid_eap_type:Enabled expanded EAP type at index=%d\n"), + i)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Enabled expanded EAP type:"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + + // This is for one expanded EAP type (for the above one). + eap_expanded_type_c expandedEAPType; + + // Read the expanded EAP type details for this item in m_enabled_expanded_eap_array. + eap_status_e status = eap_expanded_type_c::read_type(m_am_tools, + 0, + tmpExpEAP.Ptr(), + tmpExpEAP.Size(), + &expandedEAPType); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (eap_type == expandedEAPType) + { + // This is Allowed and Valid. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } // End of for() + +#else // For normal unexpanded EAP type + + TEap *eapType = 0; + + for (int i = 0; i < m_iap_eap_array.Count(); i++) + { + // Try next EAP type + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + // Convert the string to integer + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + + if (val == eap_type) + { + // Allowed + status = eap_status_ok; + break; + } + } + } // for() + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +/** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ +eap_status_e CEapVpnInterfaceImplementation::get_eap_type_list(eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_illegal_eap_type); + + status = eap_type_list->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + +#ifdef USE_EAP_EXPANDED_TYPES + + // This function is same as get_selected_eap_types in behavior. + + // We need to return only the EAP types available as enabled types. + // It means only the ones available in m_enabled_expanded_eap_array. + + for (TInt i = 0; i < m_enabled_expanded_eap_array.Count(); i++) + { + TBuf8 tmpExpEAP(m_enabled_expanded_eap_array[i]->EapExpandedType); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::get_eap_type_list:Enabled expanded EAP type at index=%d\n"), + i)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Enabled expanded EAP type:"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + + // This is for one expanded EAP type (for the above one). + eap_expanded_type_c * expandedEAPType = new eap_type_value_e(); + + // Read the expanded EAP type details from an item in m_enabled_expanded_eap_array. + status = eap_expanded_type_c::read_type(m_am_tools, + 0, + tmpExpEAP.Ptr(), + tmpExpEAP.Size(), + expandedEAPType); + if (status != eap_status_ok) + { + delete expandedEAPType; + expandedEAPType = 0; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Add EAP-type to list. + status = eap_type_list->add_object(expandedEAPType, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("get_eap_type_list():added EAP-type=0x%08x=%s\n"), + expandedEAPType->get_vendor_type(), + eap_string.get_eap_type_string(*expandedEAPType))); + } + +#else // for normal EAP types. + + TEap *eapType = 0; + + for (TInt i = 0; i < m_iap_eap_array.Count(); i++) + { + // Check if type is enabled + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + + eap_type_value_e * const eap_type = new eap_type_value_e( + static_cast(val)); + if (eap_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = eap_type_list->add_object(eap_type, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } // for() + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} +//-------------------------------------------------- + + +eap_status_e CEapVpnInterfaceImplementation::add_rogue_ap(eap_array_c & /*rogue_ap_list*/) +{ + // Not used, but might be called + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + TInt err = KErrNone; + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_vpn_if::add_rogue_ap()\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(err)); +} + + +eap_status_e CEapVpnInterfaceImplementation::restart_authentication( + const eap_am_network_id_c * const /*receive_network_id*/, + const bool /*is_client_when_true*/, + const bool /*force_clean_restart*/, + const bool /*from_timer*/) +{ + // Not used, but might be called + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_vpn_if::restart_authentication()\n"))); + + eap_status_e status = eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +eap_status_e CEapVpnInterfaceImplementation::asynchronous_init_remove_eap_session( + const eap_am_network_id_c * const /* send_network_id */) +{ + // eapol_core_c object does not support asynchronous_init_remove_eap_session(). + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +eap_status_e CEapVpnInterfaceImplementation::set_session_timeout( + const u32_t /* session_timeout_ms */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + + +//-------------------------------------------------- + +// +eap_status_e CEapVpnInterfaceImplementation::timer_expired( + const u32_t id, + void * /*data*/) +{ + // Not used, but might be called + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapVpnInterfaceImplementation::timer_expired()\n"))); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_vpn_if::timer_expired(id 0x%02x).\n"), + this, + id)); + + switch (id) + { + case EAPOL_AM_CORE_TIMER_DELETE_STACK_ID: + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAPOL_AM_CORE_TIMER_DELETE_STACK_ID elapsed: Delete stack.\n"))); + + cancel_all_timers(); + + // Delete stack + if (iEapCore != 0) + { + iEapCore->shutdown(); + delete iEapCore; + iEapCore = 0; + } + m_stack_marked_to_be_deleted = false; + + // Re-activates timer queue. + eap_status_e status = m_am_tools->re_activate_timer_queue(); + if (status != eap_status_ok) + { + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: re_activate_timer_queue() failed, status = %d\n"))); + } + + break; + } + + default: + break; + } // switch() + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +eap_status_e CEapVpnInterfaceImplementation::timer_delete_data( + const u32_t /*id*/, void * /*data*/) +{ + // Not used, but might be called + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_ALWAYS( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TIMER: [0x%08x]->eap_vpn_if::timer_delete_data().\n"), + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +// ----------------------------------------------------------------------------- +// CleanupImplArray +// ----------------------------------------------------------------------------- +// +void CEapVpnInterfaceImplementation::CleanupImplArray( TAny* aAny ) +{ + RImplInfoPtrArray* implArray = + reinterpret_cast( aAny ); + + implArray->ResetAndDestroy(); + implArray->Close(); +} + +//-------------------------------------------------- + +// End diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_main.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2000 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Standard enrty point for a DLL. +* +*/ + + +// INCLUDE FILES +#include + +// DLL Entry point + GLDEF_C TInt E32Dll() + { + return(KErrNone); + } + +// End diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_proxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_proxy.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Provides a proxy table for Interface implementations. +* +*/ + + +// INCLUDE FILES +#include +#include + +#include "eap_vpn_if_implementation.h" + +#ifndef IMPLEMENTATION_PROXY_ENTRY +#define IMPLEMENTATION_PROXY_ENTRY(aUid, aFuncPtr) {{aUid},(TProxyNewLPtr)(aFuncPtr)} +#endif + +// Provides a key value pair table, this is used to identify +// the correct construction function for the requested interface. +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY(0x1020699a, CEapVpnInterfaceImplementation::NewL) + }; + +// Function used to return an instance of the proxy table. +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) + { + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + return ImplementationTable; + } diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_resolver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_resolver.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,131 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Standard enrty point for a DLL. +* +*/ + + +// INCLUDE FILES +#include +#include +#include +#include +#include + +#include "eap_vpn_if_resolver.h" + +/// Creates an instance of CEapVpnInterfaceResolver +CEapVpnInterfaceResolver* CEapVpnInterfaceResolver::NewL (MPublicRegistry& aRegistry) + { + return new(ELeave) CEapVpnInterfaceResolver (aRegistry); + } + +// Destructor. +CEapVpnInterfaceResolver::~CEapVpnInterfaceResolver() + { + } + +/// Constructor of CEapVpnInterfaceResolver +CEapVpnInterfaceResolver::CEapVpnInterfaceResolver (MPublicRegistry& aRegistry) : + CResolver (aRegistry) + { + } + +/// This method determines if it can find an appriate implementation +/// requested +TUid CEapVpnInterfaceResolver::IdentifyImplementationL(TUid aInterfaceUid, + const TEComResolverParams& aAdditionalParameters) const + { + // Aquire a list of implementations for a specific implementation defintion + RImplInfoArray& implementationsInfo = iRegistry.ListImplementationsL ( + aInterfaceUid); + TUid found = KNullUid; + + if (implementationsInfo.Count()) + { + found = Resolve (implementationsInfo, aAdditionalParameters); + } + return found; + } + +/// This method iterates through a list of RImplInfoArray() objects to +/// find the most appropriate implementation. +TUid CEapVpnInterfaceResolver::Resolve(const RImplInfoArray& aImplementationsInfo, + const TEComResolverParams& aAdditionalParameters) const + { + const TInt count = aImplementationsInfo.Count(); + for (TInt i = 0; i < count; ++i) + { + const CImplementationInformation& impData = *aImplementationsInfo[i]; + + // Checks each item in the list to see if theres a match. + if (Match (impData.DataType(), aAdditionalParameters.DataType(), + aAdditionalParameters.IsWildcardMatch())) + { + // Returns the Uid of the interface + return impData.ImplementationUid(); + } + } + + // Nothing found + return KNullUid; + } + +/// Lists all the implementations of the specified interface definition that +/// satisfy the supplied resolution parameters. +RImplInfoArray* CEapVpnInterfaceResolver::ListAllL(TUid aInterfaceUid, + const TEComResolverParams& aAdditionalParameters) const + { + RImplInfoArray* retList = new(ELeave) RImplInfoArray; + CleanupStack::PushL (retList); + + RImplInfoArray& fullList = iRegistry.ListImplementationsL (aInterfaceUid); + + const TBool useWildcards = aAdditionalParameters.IsWildcardMatch(); + const TDesC8& matchType = aAdditionalParameters.DataType(); + const TInt numImps = fullList.Count(); + + // Iterates through each item in the list to determine the correct + // interfaces to select. + for (TInt i = 0; i < numImps; ++i) + { + if (Match (fullList[i]->DataType(), matchType, useWildcards)) + { + // Adds interface to the list. + User::LeaveIfError (retList->Append (fullList[i])); + } + } + + CleanupStack::Pop (retList); + + return retList; + } + +/// The first two parameters is used for comparaison between the two interfaces +/// and the third parameter is used to determine the use of wild cards or not. +TBool CEapVpnInterfaceResolver::Match(const TDesC8& aImplementationType, + const TDesC8& aMatchType, TBool aUseWildcards) const + { + TInt matchPos = KErrNotFound; + + // If wild cards have been set, it will use the correct method to determine + // the correct interface. + if (aUseWildcards) + matchPos = aImplementationType.MatchF (aMatchType); + else + matchPos = aImplementationType.CompareF (aMatchType); + + return matchPos != KErrNotFound; + } + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_resolvermain.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_resolvermain.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2000 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Standard enrty point for a DLL. +* +*/ + + +// INCLUDE FILES +#include + +/** DLL Entry point */ + GLDEF_C TInt E32Dll() + { + return(KErrNone); + } + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_resolverproxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_resolverproxy.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Standard enrty point for a DLL. +* +*/ + + +// INCLUDE FILES +#include +#include + +#include "eap_vpn_if_resolver.h" + +#ifndef IMPLEMENTATION_PROXY_ENTRY +#define IMPLEMENTATION_PROXY_ENTRY(aUid, aFuncPtr) {{aUid},(TProxyNewLPtr)(aFuncPtr)} +#endif + +// Provides a key value pair table, this is used to identify +// the correct construction function for the requested interface. +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY(0x101F614E, CEapVpnInterfaceResolver::NewL) + }; + +// Function used to return an instance of the proxy table. +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) + { + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + + return ImplementationTable; + } diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_timer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/eapvpnif/src/eap_vpn_if_timer.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,175 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Active object timer for EAPOL. +* +*/ + + +// INCLUDE FILES +#include "eap_am_memory.h" +#include "eap_vpn_if_timer.h" +#include "eap_tools.h" +#include "eap_am_tools.h" +#include "abs_eap_am_tools.h" +#include "abs_eap_am_mutex.h" +#include "eap_am_tools_symbian.h" + +// ================= MEMBER FUNCTIONS ======================= + +CEapVpnInterfaceTimer::CEapVpnInterfaceTimer(abs_eap_am_tools_c * const aTools) +: CTimer(CTimer::EPriorityStandard) +, iTools(aTools) +, iInterval(0) +, iStartTime(0) +, iLastTime(0) +{ + // Set a flag in EAPOL that specifies that timer queue can be used. + reinterpret_cast(iTools)->set_use_timer_queue(); +} + + +//-------------------------------------------------- + +void CEapVpnInterfaceTimer::ConstructL() +{ + CTimer::ConstructL(); +} + +//-------------------------------------------------- + +CEapVpnInterfaceTimer* CEapVpnInterfaceTimer::NewL(abs_eap_am_tools_c * const aTools) +{ + CEapVpnInterfaceTimer* self = new (ELeave) CEapVpnInterfaceTimer(aTools); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; +} + +//-------------------------------------------------- + +CEapVpnInterfaceTimer::~CEapVpnInterfaceTimer() +{ + Cancel(); +} + +//-------------------------------------------------- + +void CEapVpnInterfaceTimer::StartTimer(const TUint aInterval) +{ + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapVpnInterfaceTimer::StartTimer().\n"))); + + iInterval = aInterval; + iStartTime = iTools->get_clock_ticks(); + + iLastTime = iStartTime; + + // Start the timer + After(iInterval*1000); +} + +//-------------------------------------------------- +void CEapVpnInterfaceTimer::StopTimer() +{ + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapVpnInterfaceTimer::StopTimer().\n"))); + + Cancel(); +} +//-------------------------------------------------- + +TBool CEapVpnInterfaceTimer::TimerRunning() +{ + if (!IsActive()) + { + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapVpnInterfaceTimer::TimerRunning(): EFalse.\n"))); + + return EFalse; + } + else + { + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapVpnInterfaceTimer::TimerRunning(): ETrue.\n"))); + + return ETrue; + } +} + +void CEapVpnInterfaceTimer::RunL() +{ + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapVpnInterfaceTimer::RunL().\n"))); + + u64_t currentTime = iTools->get_clock_ticks(); + + iLastTime = currentTime; + + u32_t next_sleep_time = iInterval; + + iTools->enter_global_mutex(); + if (iTools->get_is_timer_thread_active()) + { + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapVpnInterfaceTimer::RunL(): pulse_timer().\n"))); + + next_sleep_time = iTools->pulse_timer(next_sleep_time); + } + iTools->leave_global_mutex(); + + // Setup timer again (if somebody inside pulse_timer has not already done it...) + if (!IsActive()) + { + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapVpnInterfaceTimer::RunL(): After().\n"))); + + After(next_sleep_time*1000); + } + else + { + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapVpnInterfaceTimer::RunL(): is active.\n"))); + } +} +//-------------------------------------------------- + +void CEapVpnInterfaceTimer::DoCancel() +{ + EAP_TRACE_DEBUG( + iTools, + TRACE_FLAGS_TIMER_QUEUE, + (EAPL("CEapVpnInterfaceTimer::DoCancel().\n"))); + + // Base class + CTimer::DoCancel(); +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/102072e9.spd Binary file eapol/eapol_framework/eapol_symbian/am/include/102072e9.spd has changed diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/102072e9.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/102072e9.txt Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,16 @@ +; +; Policy file to allow the eapol and eap type databases to be shared +; +; \EPOC32\RELEASE\WINSCW\UDEB\EDBSPCONV.EXE /f=c:\102072e9.txt /b=c:\102072e9.spd +; c: is Symbian specfic c drive (it is /epoc32\winscw\c for winscw paltform) +; +[database] +read +capability = ReadUserData WriteUserData +write +capability = ReadUserData WriteUserData +schema +capability = ReadUserData WriteUserData + +[BACKUP] +SID=101F8EC5 diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapAkaInterface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapAkaInterface.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPAKAINTERFACE_H_ +#define _EAPAKAINTERFACE_H_ + +// INCLUDES +#include +#include "eap_tools.h" +#include "eap_am_type_aka_symbian.h" + +#include +#include + +// CLASS DECLARATION +/** +* Class (active object) that handles the communications with the 3G SIM. +*/ +class CEapAkaInterface +: public CActive +{ +public: + + // For differentiating the query type. + enum TQueryType + { + EQueryNone, + EQueryIMSI, + EQueryRES + }; + /** + * Initialisation function. + * @param aTools Tools class pointer. + * @param aParent Pointer to the parent class. + */ + static CEapAkaInterface* NewL( + abs_eap_am_tools_c* const aTools, + eap_am_type_aka_symbian_c* const aParent); + + /** + * Destructor + */ + virtual ~CEapAkaInterface(); + + /** + * This function queries the IMSI from 3G SIM. After the request has been completed + * complete_SIM_imsi is called in the parent. + */ + void QueryIMSIL(); + + /** + * This function queries RES, CK, IK and AUTS from 3G SIM. After the request has been completed + * complete_AKA_RES_L is called in the parent. + * @param aRand Random value + * @param aAUTN Authentication Token + */ + void QueryRESL( eap_variable_data_c * const aRand, eap_variable_data_c * const aAUTN ); + +protected: + + CEapAkaInterface(abs_eap_am_tools_c* const aTools, eap_am_type_aka_symbian_c* const aParent); + + void ConstructL(); + + void RunL(); + + void DoCancel(); + +private: + + // Creates the MMETel connection and loads the phone module. + TInt CreateMMETelConnectionL(); + void DisconnectMMETel(); + +private: + + eap_am_type_aka_symbian_c * const iParent; + + abs_eap_am_tools_c * const m_am_tools; + + // ETel connection. + RTelServer iServer; + RMobilePhone iPhone; + + //For custom API. + RMmCustomAPI iCustomAPI; + + // Stores the last queried Subscriber Id ( IMSI ). + RMobilePhone::TMobilePhoneSubscriberId iSubscriberId; + + // Stores the SIM authentication details. + RMmCustomAPI::TSimAuthenticationEapAka iEAPAka; + + // For the packaged authentication data. + RMmCustomAPI::TAkaDataPckg *iAuthenticationData; + + // Stores the query identifier. Used to check if IMSI query or KC & SRES query. + TQueryType iQueryId; + + // Tells if MMETEL is connected already or not. + TBool iMMETELConnectionStatus; + +}; + +#endif // _EAPAKAINTERFACE_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapLeapNotifierStructs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapLeapNotifierStructs.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPLEAPNOTIFIERSTRUCTS_H +#define EAPLEAPNOTIFIERSTRUCTS_H + +struct TEapLeapUsernamePasswordInfo +{ + TBool iPasswordPromptEnabled; + TBool iIsIdentityQuery; + TBuf16<256> iUsername; + TBuf16<256> iPassword; +}; + +#endif // EAPLEAPNOTIFIERSTRUCTS_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapLeapNotifierUids.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapLeapNotifierUids.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +/** + List of Uids for available connection notifiers +*/ + +#ifndef EAPLEAPNOTIFIERUIDS_H +#define EAPLEAPNOTIFIERUIDS_H + +#include "EapolUID.h" + +const TUid KEapLeapNotifierDllUid = {EAP_LEAP_NOTIFIERS_DLL_UID}; +const TUid KEapLeapUsernamePasswordUid = {EAP_LEAP_USERNAME_PASSWORD_NOTIFIER_UID}; + +#endif // EAPLEAPNOTIFIERUIDS_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapMsChapV2NotifierStructs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapMsChapV2NotifierStructs.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef EAPMSCHAPV2NOTIFIERSTRUCTS_H +#define EAPMSCHAPV2NOTIFIERSTRUCTS_H + +struct TEapMsChapV2UsernamePasswordInfo +{ + TBool iIsIdentityQuery; + TBool iPasswordPromptEnabled; + TBuf16<256> iUsername; + TBuf16<256> iPassword; + TBuf16<256> iOldPassword; +}; + +#endif diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapMsChapV2NotifierUids.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapMsChapV2NotifierUids.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +// +// Copyright (c) Nokia Corporation 2002. All rights reserved. +// +// EapMsChapV2NotifierUids.h + +/** + List of Uids for available connection notifiers +*/ + +#ifndef EAPMSCHAPV2NOTIFIERUIDS_H +#define EAPMSCHAPV2NOTIFIERUIDS_H + +#include "EapolUID.h" + +const TUid KEapMsChapV2NotifierDllUid = {EAP_MSCHAPV2_NOTIFIERS_DLL_UID}; +const TUid KEapMsChapV2UsernamePasswordUid = {EAP_MSCHAPV2_USERNAME_PASSWORD_NOTIFIER_UID}; +const TUid KEapMsChapV2ChangePasswordUid = {EAP_MSCHAPV2_CHANGE_PASSWORD_NOTIFIER_UID}; + +#endif diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapProtectedSetupInterface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapProtectedSetupInterface.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPPROTECTEDSETUPINTERFACE_H_ +#define _EAPPROTECTEDSETUPINTERFACE_H_ + +// INCLUDES +#include +#include "eap_tools.h" + +#include + +// FORWARD DECLARATIONS +class eap_am_type_protected_setup_symbian_c; + +// CLASS DECLARATION +/** +* Class (active object) that handles the communications with the 3G SIM. +*/ +class CEapProtectedSetupInterface +: public CActive +{ +public: + + // For differentiating the query type. + enum TQueryType + { + EQueryNone, + EQueryDeviceParams + }; + + /** + * Initialisation function. + * @param aTools Tools class pointer. + * @param aParent Pointer to the parent class. + */ + static CEapProtectedSetupInterface* NewL( + abs_eap_am_tools_c* const aTools, + eap_am_type_protected_setup_symbian_c* const aParent); + + /** + * Destructor + */ + virtual ~CEapProtectedSetupInterface(); + + /** + * This function queries the device parameters. + * After the request has been completed complete_protetced_setup_device_params_L is called in the parent. + */ + void QueryDeviceParametersL(); + +protected: + + CEapProtectedSetupInterface(abs_eap_am_tools_c* const aTools, eap_am_type_protected_setup_symbian_c* const aParent); + + void ConstructL(); + + void RunL(); + + void DoCancel(); + +private: + + // Creates the MMETel connection and loads the phone module. + TInt CreateMMETelConnectionL(); + void DisconnectMMETel(); + +private: + + eap_am_type_protected_setup_symbian_c * const iParent; + + abs_eap_am_tools_c * const m_am_tools; + + // ETel connection. + RTelServer iServer; + RMobilePhone iPhone; + + // Stores the last queried Phone identities like manufacturer, model, + // revision and serial number + RMobilePhone::TMobilePhoneIdentityV1 iDeviceId; + + // Stores the query identifier. Used to check if IMSI query or KC & SRES query. + TQueryType iQueryId; + + // Tells if MMETEL is connected already or not. + TBool iMMETELConnectionStatus; + +}; + +#endif // _EAPPROTECTEDSETUPINTERFACE_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapSecurIDNotifierStructs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapSecurIDNotifierStructs.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPSECURIDNOTIFIERSTRUCTS_H +#define EAPSECURIDNOTIFIERSTRUCTS_H + +struct TEapSecurIDStruct +{ + TBool iIsFirstQuery; + TBuf16<128> iIdentity; + TBuf16<256> iPasscode; + TPassword iPincode; +}; + +#endif // EAPSECURIDNOTIFIERSTRUCTS_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapSecurIDNotifierUids.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapSecurIDNotifierUids.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +/** + List of Uids for available connection notifiers +*/ + +#ifndef EAPSECURIDNOTIFIERUIDS_H +#define EAPSECURIDNOTIFIERUIDS_H + +#include "EapolUID.h" + +const TUid KEapSecurIDDllUid = {EAP_SECURID_NOTIFIERS_DLL_UID}; + +const TUid KEapSecurIDIdentityQueryUid = {EAP_SECURID_IDENTITY_NOTIFIER_UID}; +const TUid KEapSecurIDPasscodeQueryUid = {EAP_SECURID_PASSCODE_NOTIFIER_UID}; +const TUid KEapSecurIDPincodeQueryUid = {EAP_SECURID_PINCODE_NOTIFIER_UID}; + +const TUid KEapGtcIdentityQueryUid = {EAP_GTC_IDENTITY_NOTIFIER_UID}; +const TUid KEapGtcUserInputQueryUid = {EAP_GTC_USER_INPUT_NOTIFIER_UID}; + +#endif // EAPSECURIDNOTIFIERUIDS_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapSimInterface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapSimInterface.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,120 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPSIMINTERFACE_H_ +#define _EAPSIMINTERFACE_H_ + +// INCLUDES +#include +#include "eap_tools.h" +#include "eap_am_type_gsmsim_symbian.h" + +#include +#include + +// CLASS DECLARATION +/** +* Class (active object) that handles the communications with the SIM. +*/ +class CEapSimIsaInterface +: public CActive +{ +public: + + // For differentiating the query type. + enum TQueryType + { + EQueryNone, + EQueryIMSI, + EQuerySRESandKC + }; + /** + * Initialisation function. + * @param aTools Tools class pointer. + * @param aParent Pointer to the parent class. + */ + static CEapSimIsaInterface* NewL( + abs_eap_am_tools_c* const aTools, + eap_am_type_gsmsim_symbian_c* const aParent); + + /** + * Destructor + */ + virtual ~CEapSimIsaInterface(); + + /** + * This function queries the IMSI from SIM. After the request has been completed + * complete_SIM_imsi is called in the parent. + */ + void QueryIMSIL(); + + /** + * This function queries Kc and SRES from SIM. After the request has been completed + * complete_SIM_kc_and_sres is called in the parent. + * @param aRand Random value + */ + void QueryKcAndSRESL(const TDesC8& aRand); + +protected: + + CEapSimIsaInterface(abs_eap_am_tools_c* const aTools, eap_am_type_gsmsim_symbian_c* const aParent); + + void ConstructL(); + + void RunL(); + + void DoCancel(); + +private: + + // Creates the MMETel connection and loads the phone module. + TInt CreateMMETelConnectionL(); + +private: + + eap_am_type_gsmsim_symbian_c * const iParent; + + abs_eap_am_tools_c * const m_am_tools; + + // ETel connection. + RTelServer iServer; + RMobilePhone iPhone; + + //For custom API. + RMmCustomAPI iCustomAPI; + + // Stores the last queried Subscriber Id ( IMSI ). + RMobilePhone::TMobilePhoneSubscriberId iSubscriberId; + + // Stores the SIM authentication details. + RMmCustomAPI::TSimAuthenticationEapSim iEAPSim; + + // For the packaged authentication data. + RMmCustomAPI::TSimDataPckg *iAuthenticationData; + + // Stores the query identifier. Used to check if IMSI query or KC & SRES query. + TQueryType iQueryId; + + // Tells if MMETEL is connected already or not. + TBool iMMETELConnectionStatus; + +}; + +#endif // _EAPSIMINTERFACE_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapSimIsaInterface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapSimIsaInterface.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPSIMISAINTERFACE_H_ +#define _EAPSIMISAINTERFACE_H_ + +// INCLUDES +#include +#include "eap_tools.h" +#include "eap_am_type_gsmsim_symbian.h" +#include "isaapi.h" + +// CLASS DECLARATION +/** +* Class (active object) that handles the communications with the SIM. +*/ +class CEapSimIsaInterface +: public CActive +{ +public: + /** + * Initialisation function. + * @param aTools Tools class pointer. + * @param aParent Pointer to the parent class. + */ + static CEapSimIsaInterface* NewL( + abs_eap_am_tools_c* const aTools, + eap_am_type_gsmsim_symbian_c* const aParent); + + /** + * Destructor + */ + virtual ~CEapSimIsaInterface(); + + /** + * This function queries the IMSI from SIM. After the request has been completed + * complete_SIM_imsi is called in the parent. + */ + void QueryIMSIL(); + + /** + * This function queries Kc and SRES from SIM. After the request has been completed + * complete_SIM_kc_and_sres is called in the parent. + * @param aRand Random value + */ + void QueryKcAndSRESL(const TDesC8& aRand); + + /** + * Checks whether the device is in GSM online mode. Leaves with KErrNotSupported if + * the device is in pda or flight mode. + */ + void CheckSystemModeL(); + +protected: + + CEapSimIsaInterface(abs_eap_am_tools_c* const aTools, eap_am_type_gsmsim_symbian_c* const aParent); + + void ConstructL(); + + void RunL(); + + void DoCancel(); + +private: + + eap_am_type_gsmsim_symbian_c * const iParent; + + abs_eap_am_tools_c * const m_am_tools; + + /// ISA API handle + RIsaApi iIsaApi; + + /// Buffer for received ISA API messages + CPnMsg *iMsgReceiveBuffer; + + /// Buffer for sent ISA API messages + CPnMsg *iMsgSendBuffer; + + TPnReceiveAllocationLengthPckg iMsgReceiveBufferLength; + + /// Stores the last queried IMSI + eap_variable_data_c iLastIMSI; +}; + +#endif // _EAPSIMISAINTERFACE_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapTlsPeapCertInterface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapTlsPeapCertInterface.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,213 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPTLSPEAPCERTINTERFACE_H_ +#define _EAPTLSPEAPCERTINTERFACE_H_ + +// INCLUDES +#include +#include "eap_tools.h" +#include "eap_am_type_tls_peap_symbian.h" +#include +#include +#include +#include +#include +#include "EapTlsPeapUtils.h" + +const TInt KMaxHashLength = 128; +// FORWARD DECLARATIONS + + +// CLASS DECLARATION +class CEapTlsPeapCertInterface +: public CActive +{ +public: + + static CEapTlsPeapCertInterface* NewL(abs_eap_am_tools_c* const aTools, + eap_am_type_tls_peap_symbian_c* const aParent); + + virtual ~CEapTlsPeapCertInterface(); + + void ReadCertificateL(SCertEntry& aCertInfo, const TBool aRetrieveChain); + + void ReadCACertificateL(SCertEntry& aCertInfo); + + void ReadPrivateKeyL(TKeyIdentifier& aHash); + + void ValidateChainL(TDesC8& aCertChain, RArray& aCACerts); + + + void GetMatchingCertificatesL( + const RArray& aAllowedUserCerts, + const TBool aUseCertAuthoritiesFilter, + EAP_TEMPLATE_CONST eap_array_c * const aCertAuthorities, + const TBool aUseCertTypesFilter, + EAP_TEMPLATE_CONST eap_array_c * const aCertTypes, + const TBool aUseAllowedCipherSuitesFilter, + const RArray& aAllowedCipherSuites); + + void SignL( + TKeyIdentifier& aKeyId, + const TDesC8& aHashIn, + const TUint aSignatureLength); + + void DecryptL( + TKeyIdentifier& aKeyId, + const TDesC8& aData); + + void CancelSignWithPrivateKey(); + +protected: + + CEapTlsPeapCertInterface(abs_eap_am_tools_c* const aTools, eap_am_type_tls_peap_symbian_c* const aParent); + + void ConstructL(); + + void RunL(); + + void DoCancel(); + +private: + + enum TState + { + EReadCertInitStore, + EReadCertList, + EReadCert, + EValidateChainInitStore, + EValidateChainGetCACertList, + EValidateChainGetCACert, + EValidateChainEnd, + EGetMatchingCertsInitStore, + EGetMatchingCertsInitialize, + EGetMatchingCertsLoop, + ESignInitStore, + ESignList, + ESignOpenKeyStore, + ESign, + EDecryptInitStore, + EDecryptList, + EDecryptOpenKeyStore, + EDecrypt, + EGetAllCerts, + ECreateCertChain, + ERetrieveChainInitStore, + ESetPassphraseTimeout, + EReadCACertInitStore, + EReadCACertList, + EReadCACert + }; + + TState iState; + + eap_am_type_tls_peap_symbian_c * const iParent; + + abs_eap_am_tools_c * const m_am_tools; + + CUnifiedCertStore* iCertStore; + + MRSASigner* iRSASigner; + + MDSASigner* iDSASigner; + + MCTDecryptor* iDecryptor; + + RFs iFs; + + RArray iAllowedUserCerts; + + TBool iUseCertAuthoritiesFilter; + + TBool iUseCertTypesFilter; + + TBool iUseAllowedCipherSuitesFilter; + + TBool iRSACertsAllowed; + + TBool iDSACertsAllowed; + + RPointerArray iCertAuthorities; + + const eap_array_c* iCertTypes; + + RMPointerArray iCertInfos; + + RMPointerArray iKeyInfos; + + HBufC8* iEncodedCertificate; + TPtr8 iCertPtr; + + CCertAttributeFilter* iCertFilter; + + TCTKeyAttributeFilter* iKeyFilter; + + CPKIXCertChain* iCertChain; + + CPKIXValidationResult* iValidationResult; + + TTime iTime; + + RPointerArray iRootCerts; + + RPointerArray iMatchingUserCerts; + + RPointerArray iUserCertChain; + + CArrayFixFlat iMatchingUserCertInfos; + + TUint iCAIndex; + + TUint iUserCertIndex; + + RArray iAllowedCACerts; + + HBufC8* iInputCertChain; + + SCertEntry iCertInfo; + + TAny *iResArray; + + // SignL + TKeyIdentifier iKeyIdentifier; + + TBuf8 iHashIn; + + HBufC8* iDataIn; + + HBufC8* iDataOut; + + HBufC8* iSignature; + + CRSASignature* iRSASignature; + + CDSASignature* iDSASignature; + + TPtr8* iSignaturePtr; + + TPtr8* iPtrOut; + + CUnifiedKeyStore* iKeyStore; + + TBool iRetrieveChain; +}; + +#endif // _EAPTLSPEAPCERTINTERFACE_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapTlsPeapNotifierStructs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapTlsPeapNotifierStructs.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#ifndef _CERTIFICATESELECTIONINFO_H_ +#define _CERTIFICATESELECTIONINFO_H_ + +#include "EapTlsPeapUtils.h" + +const TUint KIdentityFieldLength = 64; + +struct TCertificateSelectionInfo +{ + TInt iCount; + TFixedArray iCertificates; +}; + +struct TIdentityInfo +{ + TBool iUseManualUsername; + TBuf iUsername; + TBuf iRealm; +}; + +#endif // _CERTIFICATESELECTIONINFO_H_ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapTlsPeapTimerValues.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapTlsPeapTimerValues.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPTLSPEAPTIMERVALUES_H_ +#define _EAPTLSPEAPTIMERVALUES_H_ + +// This is the timeout in EAP-TLS/PEAP in milliseconds + +const TUint KDefaultTimeoutEAPTlsPeap = 120000; + +#endif // _EAPTLSPEAPTIMERVALUES_H_ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapTtlsPapDbInfoStruct.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapTtlsPapDbInfoStruct.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPTTLSPAPDBINFOSTRUCT_H +#define EAPTTLSPAPDBINFOSTRUCT_H + + +#include "EapTtlsPapNotifierStruct.h" + +/** +* Structure helps to unify read/write TTLS-PAP +* database operations. +*/ +struct TTtlsPapDbInfo + { + /** + * Notifier data structure. Contains prompt value, + * user name and password. + */ + TPapUserNamePasswordInfo iUsrPwdInfo; + + /** + * Maximum cache time for PAP session. + */ + TInt64 iMaxSessionTime; + + /** + * Last time when data was updated in cache. + */ + TInt64 iLastFullAuthTime; + }; + +#endif // EAPTTLSPAPDBINFOSTRUCT_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/Eapol.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/Eapol.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,175 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined(_EAPOL_H_) +#define _EAPOL_H_ + +// INCLUDES +#include // For TMacAddress +#include // For MWlanMgmtPacket +#include // For TIndexType + +// DATA TYPES +enum TWPACipherSuite { + ENoCipherSuite, // Unsupported + EWEP40, // TBC: Unsupported + EWEP104, + ETKIP, + ECCMP, // Unsupported + EWRAP // Unsupported +}; + +enum TMICFailureType { + EGroupKey, + EPairwiseKey +}; + +// FORWARD DECLARATIONS +class eapol_am_core_symbian_c; +class MEapolToWlmIf; + +// CLASS DECLARATION + +/** +* Class for WLM interface. These are the functions that WLM can call in EAPOL DLL. +* WLM could use eapol_am_core_symbian_c directly but +* that way we would need to export dozens of headers from eapol. This way we need to +* export only a few. +*/ +class CEapol +: public CBase, public MWlanMgmtPacket // From WLM +{ +public: + /** + * Static constructor. + * @param aPartner Pointer to creator of this class + * @param aIsClient Specifies whether this EAPOL instance will + * act as a client or server + * @return Pointer to instantiated class + */ + IMPORT_C static CEapol* NewL( + MEapolToWlmIf* const aPartner, + const TBool aIsClient = ETrue, + const TUint aServerIndex = 0); + + /** + * Destructor. + */ + virtual ~CEapol(); + + /** + * Starts the authentication process. After this is called EAPOL + * reads IAP configuration and starts associations. + * @param aIndexType IAP index type + * @param aIndex IAP index + * @param aSSID SSID of the network + * @param aWPAOverrideEnabled State whether WPA override is active (used with Easy WLAN) + * @param aWPAPSK WPA PSK override (used with Easy WLAN) + * @param aWPAPSKLength WPA PSK override length + * @return TInt result + */ + IMPORT_C TInt Start( // Non-Leaving functions OK for WLM? + const TIndexType aIndexType, + const TUint aIndex, + const TSSID& aSSID, + const TBool aWPAOverrideEnabled, + const TUint8* aWPAPSK, + const TUint aWPAPSKLength + ); + /** + * Called by WLM when association has been done (or failed). + * After this is called EAPOL starts sending EAPOL-starts. + * @param aResult Result code indicating whether association was successful + * @param aLocalAddress Local MAC address + * @param aRemoteAddress Remote MAC address + * @param aReceivedWPAIE WPA IE received from the AP if available (NULL otherwise). + * @param aReceivedWPAIELength Received WPA IE length. + * @param aSentWPAIE WPA IE sent to the AP if available (NULL otherwise). + * @param aSentWPAIELength Sent WPA IE length. + * @param aGroupKeyCipherSuite If security mode is WPA then this is the used + * group key cipher suite. + * @param aPairwiseKeyCipherSuite If security mode is WPA then this is the used + * pairwise key cipher suite. + * @return TInt result + */ + IMPORT_C TInt CompleteAssociation( + const TInt aResult, + const TMacAddress& aLocalAddress, + const TMacAddress& aRemoteAddress, + const TUint8* const aReceivedWPAIE, // WLM must give only the WPA IE to EAPOL + const TUint aReceivedWPAIELength, + const TUint8* const aSentWPAIE, + const TUint aSentWPAIELength, + const TWPACipherSuite aGroupKeyCipherSuite, + const TWPACipherSuite aPairwiseKeyCipherSuite + ); + + /** + * Indicates that we have disassociated from the AP. + * This causes EAPOL to stop everything it is doing and go to idle state. + * @return TInt result + */ + IMPORT_C TInt Disassociated(); + + /** + * Processes received EAPOL packets. + * @param aLength Packet length + * @param aData Packet data + * @return TInt result + */ + IMPORT_C TInt ReceivePacket( + const TUint aLength, + const TUint8* const aData); + + /** + * Sends WPA MIC failure report. + * @param aFatalMICFailure Flag indicating if this is the second MIC failure + * in 60 seconds. + * @param aMICFailureType Indicates whether the failure occurred in pairwise or + * group key decoding. + * @return TInt result + */ + IMPORT_C TInt SendWPAMICFailureReport( + TBool aFatalMICFailure, + const TMICFailureType aMICFailureType); + +protected: + + CEapol(); + + void ConstructL( + MEapolToWlmIf* const aPartner, + const TBool aIsClient, + const TUint aServerIndex); + +private: + + /// Pointer to next upper stack layer + eapol_am_core_symbian_c* iEapolCore; + //-------------------------------------------------- +}; + +#endif //#if !defined(_EAPOL_H_) + +//-------------------------------------------------- + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/Eapol.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/Eapol.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource headers for project EAPOL +* +*/ + + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapolDbDefaults.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapolDbDefaults.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOLDBDEFAULTS_H_) +#define _EAPOLDBDEFAULTS_H_ + +// LOCAL CONSTANTS + +#ifdef SYMBIAN_SECURE_DBMS +// For EAPOL secure database. +// Full path is not needed. The database eapol.dat will be saved in the +// data cage path for DBMS. So it will be in "\private\100012a5\eapol.dat" in C: drive. +// The maximum length of database name is 0x40 (KDbMaxName) , which is defined in d32dbms.h. + +_LIT(KDatabaseName, "c:eapol.dat"); + +_LIT(KSecureUIDFormat, "SECURE[102072e9]"); // For the security policy. + +#else + +_LIT(KDatabaseName, "c:\\system\\data\\eapol.dat"); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + +#if !defined(USE_EAP_FILECONFIG) + const TInt default_EAP_TRACE_disable_traces = 0; + const TInt default_EAP_TRACE_enable_function_traces = 0; + const TInt default_EAP_TRACE_only_trace_messages = 0; + const TInt default_EAP_TRACE_only_test_vectors = 0; +#endif //#if !defined(USE_EAP_FILECONFIG) + +_LIT(default_EAP_TRACE_output_file_name, "c:\\logs\\eapol\\eap_core.txt"); + +#if !defined(USE_EAP_FILECONFIG) + const TInt default_EAP_CORE_session_timeout = 120000; // ms = 120 seconds = 2 minutes. + const TInt default_EAPOL_CORE_starts_max_count = 3; + const TInt default_EAPOL_CORE_send_start_interval = 2000; // ms + const TInt default_EAP_ERROR_TEST_enable_random_errors = 0; + const TInt default_EAP_ERROR_TEST_send_original_packet_first = 0; + const TInt default_EAP_ERROR_TEST_generate_multiple_error_packets = 2; + const TInt default_EAP_ERROR_TEST_manipulate_ethernet_header = 0; + const TInt default_EAP_ERROR_TEST_error_probability = 8000000; + const TInt default_EAP_test_default_type = 18; // EAP-SIM + const TInt default_EAP_CORE_retransmission_counter = 0; +#endif //#if !defined(USE_EAP_FILECONFIG) + +#endif // _EAPOLDBDEFAULTS_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapolDbParameterNames.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapolDbParameterNames.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_EAPOLDBPARAMETERNAMES_H_) +#define _EAPOLDBPARAMETERNAMES_H_ + +#include "eap_config.h" + +// LOCAL CONSTANTS +_LIT(KEapolTableName, "eapol"); +_LIT(KEapolPSKTableName, "psk"); +_LIT(KServiceType, "service_type"); +_LIT(KServiceIndex, "service_index"); +_LIT(KSSID, "SSID"); +_LIT(KPassword, "Password"); +_LIT(KPSK, "PSK"); + +#endif // _EAPOLDBPARAMETERNAMES_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapolTimer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapolTimer.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#if !defined(_EAPOL_TIMER_H_) +#define _EAPOL_TIMER_H_ + +// INCLUDES +#include +#include "eap_am_types.h" + +// FORWARD DECLARATIONS +class abs_eap_am_tools_c; + +// CLASS DECLARATION +class CEapolTimer +: public CTimer +{ +public: + static CEapolTimer* NewL(abs_eap_am_tools_c * const aTools); + virtual ~CEapolTimer(); + void StartTimer(const TUint aInterval); + void StopTimer(); + TBool TimerRunning(); + void RunL(); + void DoCancel(); +protected: + CEapolTimer(abs_eap_am_tools_c * const aTools); + void ConstructL(); + +private: + TUint iInterval; + abs_eap_am_tools_c* const iTools; + + u64_t iStartTime; + u64_t iLastTime; + +}; + +#endif //#if !defined(_EAPOL_TIMER_H_) + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapolToWlmIf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapolToWlmIf.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,125 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined(_EAPOLTOWLMIF_H_) +#define _EAPOLTOWLMIF_H_ + +#include + +// DATA TYPES + +// These are the possible indications EAPOL can send to WLM. +enum TEapIndication { + EAuthenticating, + ESuccess, + EThisAPFailed, // This AP failed all EAP types. Next AP could be better. + EFailedCompletely, // Configuration failure or something else fatal. + // No point trying other APs. + ENoResponse, + ELeapSuccess // Indicates that EAP-LEAP protocol succeeded. + // This means that rogue AP results must be sent. +}; + +// The possible rogue AP values +enum TRogueType { + EInvalidAuthenticationType = 1, + EAuthenticationTimeout, + EChallengeFromAPFailed, + EChallengeToAPFailed +}; + +// Possible cipher suites +// RC4 keys are used in WEP, TKIP and CKIP cipher suites. +enum TCipherKeyType { + ERC4Unicast, + ERC4Broadcast +}; + +// CLASS DECLARATION +class MEapolToWlmIf +{ +public: + + /** + * Associates the an access point using the specified authentication mode. + * @param aAuthenticationMode Authentication mode (open, shared, LEAP) + * @return TInt result + */ + virtual TInt Associate(TAuthenticationMode aAuthenticationMode) = 0; + + /** + * Disassociates from an access point. + * @return TInt result + */ + virtual TInt Disassociate() = 0; + + /** + * Sends an EAP packet. + * @param aBufferLength Packet length + * @param aBuffer Packet data + * @return TInt result + */ + virtual TInt EapPacketSend( + const TUint aBufferLength, + const TUint8* const aBuffer) = 0; + + /** + * Indication of some event from EAPOL to WLM. + * @param aIndication Event code + * @return TInt result + */ + virtual TInt EapIndication(const TEapIndication aIndication) = 0; + + /** + * Sets the cipher key. When EAPOL has finished authentication it generates cipher keys and + * uses this function to send them to WLM and drivers. + * @param aKeyType Type of the key to be set. + * @param aKeyIndex Index for the key (if applicable) + * @param aKeyData Key data + * @param aKeyLength Key Length + * @return TInt result + */ + virtual TInt SetCipherKey( + const TCipherKeyType aKeyType, + const TUint8 aKeyIndex, + const TUint8* const aKeyData, + const TUint aKeyLength + ) = 0; + + /** + * Report the current AP to be rogue. This happens when LEAP authentication + * fails for some reason + * @param aAddress Address of the rogue AP + * @param aRogueType Indicates the type of the failure. + * @return TInt result + */ + virtual TInt AddRogueAP( + const TMacAddress& aAddress, + const TRogueType aRogueType) = 0; +}; + +#endif //#if !defined(_EAPOLTOWLMIF_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/EapolUID.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/EapolUID.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPOLUID_H_ +#define _EAPOLUID_H_ + +#define PLUGIN_INTERFACE_UID 0x101f8e4a + +// EAPOL +#define EAPOL_DLL_UID 0x101f8e48 +#define EAPOL_NOTIFIERS_DLL_UID 0x101f8e79 +#define EAPOL_PROGRESS_NOTIFIER_UID 0x101f8e7a + +// EAP-SIM +#define EAP_SIM_DLL_UID 0x101f8e49 +#define EAP_SIM_IMPLEMENTATION_UID 0x101f8e4b + +// EAP-TLS/PEAP +#define EAP_TLS_PEAP_DLL_UID 0x101f8e4c +#define EAP_TLS_IMPLEMENTATION_UID 0x101f8e4d +#define EAP_PEAP_IMPLEMENTATION_UID 0x101f8e4e +#define EAP_TTLS_IMPLEMENTATION_UID 0x101f8e4f +#define EAP_TLS_PEAP_NOTIFIERS_DLL_UID 0x101f8e7d +#define EAP_TLS_PEAP_SELECTION_NOTIFIERS_UID 0x101f8e7e +#define EAP_TLS_PEAP_IDENTITY_NOTIFIERS_UID 0x101f8ecf +#define EAP_FAST_IMPLEMENTATION_UID 0x2000BF12 // EAP-FAST + +// TTLS-PAP +#define TTLS_PAP_IMPLEMENTATION_UID 0x2001B2F2 + +// EAP-MSCHAPv2 +#define EAP_MSCHAPV2_DLL_UID 0x101f8e66 +#define EAP_MSCHAPV2_IMPLEMENTATION_UID 0x101f8e67 +#define MSCHAPV2_IMPLEMENTATION_UID 0x101f8e7b +#define EAP_MSCHAPV2_NOTIFIERS_DLL_UID 0x101f8e68 +#define EAP_MSCHAPV2_USERNAME_PASSWORD_NOTIFIER_UID 0x101f8e69 +#define EAP_MSCHAPV2_CHANGE_PASSWORD_NOTIFIER_UID 0x101f8e6a + +// EAP-SecurID +#define EAP_SECURID_NOTIFIERS_DLL_UID 0x101f8e6c +#define EAP_SECURID_DLL_UID 0x101f8e74 +#define EAP_SECURID_IMPLEMENTATION_UID 0x101f8e75 +#define EAP_SECURID_IDENTITY_NOTIFIER_UID 0x101f8e76 +#define EAP_SECURID_PASSCODE_NOTIFIER_UID 0x101f8e77 +#define EAP_SECURID_PINCODE_NOTIFIER_UID 0x101f8e78 + +// EAP-GTC (implemented in EAP-SecurID) +#define EAP_GTC_IMPLEMENTATION_UID 0x101f8e80 +#define EAP_GTC_IDENTITY_NOTIFIER_UID 0x101f8e7c +#define EAP_GTC_USER_INPUT_NOTIFIER_UID 0x101f8e7f + +// EAP-LEAP +#define EAP_LEAP_DLL_UID 0x101f8ea6 +#define EAP_LEAP_IMPLEMENTATION_UID 0x101f8ea7 +#define EAP_LEAP_NOTIFIERS_DLL_UID 0x101f8ea8 +#define EAP_LEAP_USERNAME_PASSWORD_NOTIFIER_UID 0x101f8ea9 + +// EAP-AKA +#define EAP_AKA_DLL_UID 0x102073c1 +#define EAP_AKA_IMPLEMENTATION_UID 0x102073c2 + +// EAP-WSC Protected Setup +#define EAP_PROTECTED_SETUP_DLL_UID 0x2000b003 +#define EAP_PROTECTED_SETUP_IMPLEMENTATION_UID 0x2000b004 + + +// FREE UIDS + + +#endif // _EAPOLUID_H_ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/abs_eapol_am_core_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/abs_eapol_am_core_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined(_ABS_EAPOL_AM_CORE_SYMBIAN_H_) +#define _ABS_EAPOL_AM_CORE_SYMBIAN_H_ + +// DATA TYPES +enum TEapIndication { + EAuthenticating, + ESuccess, + ECancelled, + EFailed, + ELogoff, + ENoResponse +}; + +// CLASS DECLARATION +class abs_eapol_am_core_symbian_c +{ +public: + + virtual ~abs_eapol_am_core_symbian_c() {}; + + virtual TInt EapPacketSend( + const TUint aBufferLength, + const TUint8* const aBuffer) = 0; + + virtual TInt EapIndication(const TEapIndication aIndication) = 0; + + virtual TInt SetWepKey( + const TUint8* const aKeyData, + const TUint aKeyLength, + const TUint8 aKeyIndex) = 0; + +}; + +#endif //#if !defined(_ABS_EAPOL_AM_CORE_SYMBIAN_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/abs_eapol_am_core_symbian_simulator.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/abs_eapol_am_core_symbian_simulator.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_ABS_EAPOL_AM_CORE_SYMBIAN_H_) +#define _ABS_EAPOL_AM_CORE_SYMBIAN_H_ + +#if defined(USE_EAPOL_LLC_INTERFACE) + #include +#endif + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_buffer.h" +#include "eap_base_type.h" +#include "eap_config.h" + +class abs_ethernet_core_c; + + +// +class EAP_EXPORT abs_eapol_am_core_symbian_c +{ +private: + //-------------------------------------------------- + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + virtual ~abs_eapol_am_core_symbian_c() + { + } + + // + abs_eapol_am_core_symbian_c() + { + } + +#if defined(USE_EAPOL_LLC_INTERFACE) & 0 + // + virtual TInt packet_send(RMBufChain &aFrame) = 0; +#endif //#if defined(USE_EAPOL_LLC_INTERFACE) + + // + virtual eap_status_e packet_send( + const eap_am_network_id_c * const network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length, + abs_ethernet_core_c *sender, + const bool when_true_do_length_checks, + const u32_t packet_index) = 0; + + // + virtual u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length) = 0; + + // + virtual eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) = 0; + + // + virtual eap_status_e unload_module(const eap_type_value_e type) = 0; + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @see abs_eap_base_type_c::packet_data_crypto_keys(). + */ + virtual eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key + ) = 0; + + virtual eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + virtual eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) = 0; + + /** + * This is notification of internal state transition. + * This is used for notifications, debugging and protocol testing. + * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully + * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. + * These two notifications are sent from EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap). + */ + virtual void state_notification( + const abs_eap_state_notification_c * const state) = 0; + + //-------------------------------------------------- +}; // class abs_eapol_am_core_symbian_c + +#endif //#if !defined(_ABS_EAPOL_AM_CORE_SYMBIAN_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_async_wait_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_async_wait_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAP_AM_ASYNC_WAIT_SYMBIAN_H_ +#define _EAP_AM_ASYNC_WAIT_SYMBIAN_H_ + + +/** + * eap_am_async_wait_symbian_c class + */ + +class eap_am_async_wait_symbian_c : public CActive + { + public: + + /** + * C++ default constructor. + */ + eap_am_async_wait_symbian_c(); + + /** + * Destructor. + */ + ~eap_am_async_wait_symbian_c() ; + + public: + + /** + * Nested scheduler loop + */ + void Wait() ; + + private: // CActive + + void RunL(); + void DoCancel(); + + + private: // data + + CActiveSchedulerWait iActiveWait ; // nested loop for active scheduler +} ; + +#endif // _EAP_AM_ASYNC_WAIT_SYMBIAN_H_ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_crypto_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_crypto_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,794 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_AM_CRYPTO_SYMBIAN_H_ ) +#define _EAP_AM_CRYPTO_SYMBIAN_H_ + +// INCLUDES +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "eap_am_tools.h" +#include "eap_array.h" +#include "abs_eap_am_crypto.h" + +// FORWARD DECLARATIONS +class abs_eap_am_tools_c; +class eap_variable_data_c; + +// LOCAL CONSTANTS +const u32_t EAP_HW_TICKS_SEED_BUFFER_SIZE = 8u; + +// CLASS DECLARATION + +/// Class eap_am_crypto offers services to authenticate data, encrypt data, +/// decrypt data, generate keys and generate cryptographically strong random data. +class EAP_EXPORT eap_am_crypto_symbian_c +: public abs_eap_am_crypto_c +{ +private: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// This is pointer to the tools class. + abs_eap_am_tools_c * const m_am_tools; + + /// This indicates whether this object was generated successfully. + bool m_is_valid; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - +public: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Destructor does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_am_crypto_symbian_c(); + + /** + * Constructor initializes the member attributes. + */ + EAP_FUNC_IMPORT eap_am_crypto_symbian_c(abs_eap_am_tools_c * const tools); + + EAP_FUNC_IMPORT eap_status_e configure(); + + + /** + * The get_is_valid() function returns the status of the eap_core object. + * True indicates the object is initialized succesfully. + */ + EAP_FUNC_IMPORT bool get_is_valid() const; + + EAP_FUNC_IMPORT void set_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function activates random generator for test use. + * It does generate predictive pseudorandom data. + */ + EAP_FUNC_IMPORT void use_test_random( + const u8_t * const seed, + const u32_t seed_length, + const bool does_continuous_seeding_when_true); + + /** + * The get_rand_bytes() function fills count random bytes to buffer. + */ + EAP_FUNC_IMPORT eap_status_e get_rand_bytes( + u8_t * const buffer, + const u32_t count); + + /** + * The add_rand_seed() function seeds count bytes from buffer to the random data pool. + * The seed bytes could be any data that increases entropy of the random data pool. + * For example time stamps of send and received messages, likewise addresses, + * cookies and nonces included in messages. + */ + EAP_FUNC_IMPORT eap_status_e add_rand_seed( + const u8_t * const buffer, + const u32_t count); + + /** + * The add_rand_seed_hw_ticks() function adds hardware ticks read with + * the abs_eap_am_tools::get_hardware_ticks() function. This could be used to + * seed the random data pool with time stamps. + */ + EAP_FUNC_IMPORT eap_status_e add_rand_seed_hw_ticks(); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The generate_diffie_hellman_keys() function generates private and public + * Diffie-Hellman keys. + * It is used only for sanity checks. Only one well-known group is supported. + * @param own_private_dh_key Saves context here. + */ + EAP_FUNC_IMPORT eap_status_e generate_diffie_hellman_keys( + eap_variable_data_c * const own_private_dh_key, + eap_variable_data_c * const own_public_dh_key, + const u8_t * const prime, + const u32_t prime_length, + const u8_t * const group_generator, + const u32_t group_generator_length); + + /** + * The generate_g_power_to_xy() function generates shared secret + * Diffie-Hellman key from own_private_dh_key and peer_public_dh_key. + * Only one well-known group is supported. + * @param own_private_dh_key Is the context. + */ + EAP_FUNC_IMPORT eap_status_e generate_g_power_to_xy( + const eap_variable_data_c * const own_private_dh_key, + const eap_variable_data_c * const peer_public_dh_key, + eap_variable_data_c * const shared_dh_key, + const u8_t * const prime, + const u32_t prime_length, + const u8_t * const group_generator, + const u32_t group_generator_length); + + /** + * This functions cleans up the diffie-hellman context. + * This is not used in Symbian. + */ + EAP_FUNC_IMPORT eap_status_e dh_cleanup( + const eap_variable_data_c * const dh_context); + + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of SHA1-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_sha_256_digest_length( + eap_variable_data_c * const sha_256_context); + + /** + * This function returns the block size of SHA1-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_sha_256_block_size( + eap_variable_data_c * const sha_256_context); + + /** + * The sha_256_init() function initializes SHA1. + * Internal context of SHA1 is stored to sha_256_context. + */ + EAP_FUNC_IMPORT eap_status_e sha_256_init( + eap_variable_data_c * const sha_256_context); + + /** + * The sha_256_update() function updates the context of + * sha_256_context with data_length bytes of data. + */ + EAP_FUNC_IMPORT eap_status_e sha_256_update( + eap_variable_data_c * const sha_256_context, + const u8_t * const data, + const u32_t data_length); + + /** + * The sha_256_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non NULL. + */ + EAP_FUNC_IMPORT eap_status_e sha_256_final( + eap_variable_data_c * const sha_256_context, + u8_t * const message_digest, + u32_t *md_length_or_null); + + /** + * The hmac_sha_256_cleanup() cleanups the SHA1 context. + */ + EAP_FUNC_IMPORT eap_status_e sha_256_cleanup( + eap_variable_data_c * const sha_256_context); + + /** + * The sha_256_copy_context() copies the SHA1 context. + */ + EAP_FUNC_IMPORT eap_status_e sha_256_copy_context( + eap_variable_data_c * const copied_sha_256_context, + const eap_variable_data_c * const original_sha_256_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of SHA1-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_sha1_digest_length( + eap_variable_data_c * const sha1_context); + + /** + * This function returns the block size of SHA1-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_sha1_block_size( + eap_variable_data_c * const sha1_context); + + /** + * The sha1_init() function initializes SHA1. + * Internal context of SHA1 is stored to sha1_context. + */ + EAP_FUNC_IMPORT eap_status_e sha1_init( + eap_variable_data_c * const sha1_context); + + /** + * The sha1_update() function updates the context of + * sha1_context with data_length bytes of data. + */ + EAP_FUNC_IMPORT eap_status_e sha1_update( + eap_variable_data_c * const sha1_context, + const u8_t * const data, + const u32_t data_length); + + /** + * The sha1_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non NULL. + * It must include the length of the message_digest buffer must be set before + * function call. + */ + EAP_FUNC_IMPORT eap_status_e sha1_final( + eap_variable_data_c * const sha1_context, + u8_t * const message_digest, + u32_t *md_length_or_null); + + /** + * The sha1_cleanup() cleanups the SHA1 context. + */ + EAP_FUNC_IMPORT eap_status_e sha1_cleanup( + eap_variable_data_c * const sha1_context); + + /** + * The sha1_copy_context() copies the SHA1 context. + */ + EAP_FUNC_IMPORT eap_status_e sha1_copy_context( + eap_variable_data_c * const copied_sha1_context, + const eap_variable_data_c * const original_sha1_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The aes_key_length() function returns the length of key AES-algorithm. + * This will be constant 16 bytes (128 bits). Still it is better use function + * to help changes if the length of key is changed in future. + */ + EAP_FUNC_IMPORT u32_t aes_key_length(); + + /** + * The aes_block_size() function returns the block size of AES-algorithm. + * This will be constant 16 bytes (128 bits). Still it is better use function + * to help changes if the size is changed in future. + */ + EAP_FUNC_IMPORT u32_t aes_block_size(); + + + /** + * The aes_set_encryption_key() function initializes the encryption + * context of AES-algorithm to the aes_context using key_length bytes from buffer key. + */ + EAP_FUNC_IMPORT eap_status_e aes_set_encryption_key( + eap_variable_data_c * const aes_context, + const u8_t * const key, + const u32_t key_length); + + /** + * This function cleans the aes_context. + */ + EAP_FUNC_IMPORT eap_status_e aes_cleanup( + eap_variable_data_c * const aes_context); + + /** + * The aes_set_decryption_key() function initializes the decryption context of + * AES-algorithm to the aes_context using key_length bytes from buffer key. + */ + EAP_FUNC_IMPORT eap_status_e aes_set_decryption_key( + eap_variable_data_c * const aes_context, + const u8_t * const key, + const u32_t key_length); + + /** + * The aes_encrypt_block() function encrypts data of data_length bytes + * using encryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of AES-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used taking + * advance from separate buffers. + */ + EAP_FUNC_IMPORT eap_status_e aes_encrypt_block( + eap_variable_data_c * const aes_context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length); + + /** + * The aes_decrypt_block() function decrypts data of data_length bytes + * using decryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of AES-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used + * taking advance from separate buffers. + */ + EAP_FUNC_IMPORT eap_status_e aes_decrypt_block( + eap_variable_data_c * const aes_context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The key_length() function returns the length of key 3DES-EDE-algorithm. + * This will be constant 24 bytes (192 bits). Still it is better use function + * to help changes if the length of key is changed in future. + */ + EAP_FUNC_IMPORT u32_t key_length_3des_ede(); + + /** + * The block_size() function returns the block size of 3DES-EDE-algorithm. + * This will be constant 24 bytes (192 bits). Still it is better use function + * to help changes if the size is changed in future. + */ + EAP_FUNC_IMPORT u32_t block_size_3des_ede(); + + + /** + * The cbc_set_encryption_key() function initializes the encryption + * context of 3DES-EDE-algorithm to the context using key_length bytes from buffer key. + */ + EAP_FUNC_IMPORT eap_status_e set_encryption_key_3des_ede( + eap_variable_data_c * const context, + const u8_t * const key, + const u32_t key_length); + + /** + * The cbc_set_decryption_key() function initializes the decryption context of + * 3DES-EDE-algorithm to the context using key_length bytes from buffer key. + */ + EAP_FUNC_IMPORT eap_status_e set_decryption_key_3des_ede( + eap_variable_data_c * const context, + const u8_t * const key, + const u32_t key_length); + + /** + * This function cleans up context. + */ + EAP_FUNC_IMPORT eap_status_e cleanup_3des_ede( + eap_variable_data_c * const context); + + /** + * The cbc_encrypt_data() function encrypts data of data_length bytes + * using encryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of 3DES-EDE-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used taking + * advance from separate buffers. + */ + EAP_FUNC_IMPORT eap_status_e encrypt_block_3des_ede( + eap_variable_data_c * const context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length); + + /** + * The cbc_decrypt_data() function decrypts data of data_length bytes + * using decryption_IV initialization vector. NOTE the length of data must + * be aligned to block size of 3DES-EDE-algorithm. + * This version takes pointers to input and output buffers as a parameter. + * Those buffers must be fully separated. Some optimizations are used + * taking advance from separate buffers. + */ + EAP_FUNC_IMPORT eap_status_e decrypt_block_3des_ede( + eap_variable_data_c * const context, + const u8_t * const data_in, + u8_t * const data_out, + const u32_t data_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Key derivation is based on the random number generation specified in + * NIST Federal Information Processing Standards (FIPS) Publication + * 186-2 [9]. The random number generator is specified in the change + * notice 1 (2001 October 5) of [9] (Algorithm 1). As specified in the + * change notice (page 74), when Algorithm 1 is used as a general- + * purpose random number generator, the "mod q" term in step 3.3 is + * omitted. The function G used in the algorithm is constructed via + * Secure Hash Standard as specified in Appendix 3.3 of the standard. + + * 160-bit XKEY and XVAL values are used, so b = 160. The initial + * secret seed value XKEY is computed from the n GSM Kc keys and the + * NONCE_MT with the following formula: + * @code + * XKEY = SHA1(n*Kc| NONCE_MT) + * + * Random generator becomes as follows: + * Step 1. Choose a new, secret value for the seed-key, XKEY. + * Step 2. In hexadecimal notation let + * t = 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0. + * This is the initial value for H0 || H1 || H2 || H3 || H4 in the SHS. + * Step 3. For j = 0 to m - 1 do + * c. xj = G(t,XKEY). + * d. XKEY = (1 + XKEY + xj) mod 2^b. + * @endcode + */ + EAP_FUNC_IMPORT eap_status_e dss_pseudo_random( + u8_t *out, + u32_t out_length, + u8_t *xkey, + u32_t xkey_length); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of MD5-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_md5_digest_length( + eap_variable_data_c * const md5_context); + + /** + * This function returns the block size of MD5-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_md5_block_size( + eap_variable_data_c * const md5_context); + + /** + * The sha1_init() function initializes MD5. + * Internal context of MD5 is stored to sha1_context. + */ + EAP_FUNC_IMPORT eap_status_e md5_init( + eap_variable_data_c * const md5_context); + + /** + * The md5_update() function updates the context of + * md5_context with data_length bytes of data. + */ + EAP_FUNC_IMPORT eap_status_e md5_update( + eap_variable_data_c * const md5_context, + const u8_t * const data, + const u32_t data_length); + + /** + * The md5_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non NULL. + * It must include the length of the message_digest buffer before function call. + */ + EAP_FUNC_IMPORT eap_status_e md5_final( + eap_variable_data_c * const md5_context, + u8_t * const message_digest, + u32_t *md_length_or_null); + + /** + * The hmac_md5_cleanup() cleanups the MD5 context. + */ + EAP_FUNC_IMPORT eap_status_e md5_cleanup( + eap_variable_data_c * const md5_context); + + /** + * The md5_copy_context() copies the MD5 context. + */ + EAP_FUNC_IMPORT eap_status_e md5_copy_context( + eap_variable_data_c * const copied_md5_context, + const eap_variable_data_c * const original_md5_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * This function returns the size of message digest of MD4-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_md4_digest_length( + eap_variable_data_c * const md4_context); + + /** + * This function returns the block size of MD4-algorithm. + */ + EAP_FUNC_IMPORT u32_t get_md4_block_size( + eap_variable_data_c * const md4_context); + + /** + * The md4_init() function initializes MD4. + * Internal context of MD4 is stored to sha1_context. + */ + EAP_FUNC_IMPORT eap_status_e md4_init( + eap_variable_data_c * const md4_context); + + /** + * The md4_update() function updates the context of + * md4_context with data_length bytes of data. + */ + EAP_FUNC_IMPORT eap_status_e md4_update( + eap_variable_data_c * const md4_context, + const u8_t * const data, + const u32_t data_length); + + /** + * The md4_final() function writes the message authentication code + * (MAC) to buffer pointed by message_digest. The length of MAC is stored + * to buffer pointed by md_length_or_null, If md_length_or_null is non NULL. + * It must include the length of the message_digest buffer before function call. + */ + EAP_FUNC_IMPORT eap_status_e md4_final( + eap_variable_data_c * const md4_context, + u8_t * const message_digest, + u32_t *md_length_or_null); + + /** + * The hmac_md4_cleanup() cleanups the MD4 context. + */ + EAP_FUNC_IMPORT eap_status_e md4_cleanup( + eap_variable_data_c * const md4_context); + + /** + * The md4_copy_context() copies the MD4 context. + */ + EAP_FUNC_IMPORT eap_status_e md4_copy_context( + eap_variable_data_c * const copied_md4_context, + const eap_variable_data_c * const original_md4_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * Used to set the RC4 key. + */ + EAP_FUNC_IMPORT eap_status_e rc4_set_key( + eap_variable_data_c * const rc4_context, + const eap_variable_data_c * const key); + + /** + * Used to clean up the RC4 context. + */ + EAP_FUNC_IMPORT eap_status_e rc4_cleanup( + eap_variable_data_c * const rc4_context); + + /** + * Encrypts RC4 data. + * Input and output buffers must be non overlapping. + */ + EAP_FUNC_IMPORT eap_status_e rc4_encrypt( + const eap_variable_data_c * const rc4_context, + const void * const data_in, + void * const data_out, + const u32_t data_length); + + /** + * Encrypts RC4 data. + * The same buffer is used for input and output. + */ + EAP_FUNC_IMPORT eap_status_e rc4_encrypt( + const eap_variable_data_c * const rc4_context, + void * const data_in_out, + const u32_t data_length); + + /** + * Decrypts RC4 data. + * The same buffer is used for input and output. + */ + EAP_FUNC_IMPORT eap_status_e rc4_decrypt( + const eap_variable_data_c * const rc4_context, + void * const data_in_out, + const u32_t data_length); + + /** + * Decrypts RC4 data. + * Input and output buffers must be non overlapping. + */ + EAP_FUNC_IMPORT eap_status_e rc4_decrypt( + const eap_variable_data_c * const rc4_context, + const void * const data_in, + void * const data_out, + const u32_t data_length); + + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The rsa_init() function initializes context of RSA. + * Internal context of RSA is stored to rsa_context. + */ + EAP_FUNC_IMPORT eap_status_e rsa_init( + eap_variable_data_c * const rsa_context); + + /** + * Function encrypts input data to output data using RSA algorithm with public RSA key. + */ + EAP_FUNC_IMPORT eap_status_e rsa_encrypt_with_public_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + /** + * Function decrypts input data to output data using RSA algorithm with public RSA key. + */ + EAP_FUNC_IMPORT eap_status_e rsa_decrypt_with_public_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + /** + * Function encrypts input data to output data using RSA algorithm with private RSA key. + */ + EAP_FUNC_IMPORT eap_status_e rsa_encrypt_with_private_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + /** + * Function decrypts input data to output data using RSA algorithm with private RSA key. + */ + EAP_FUNC_IMPORT eap_status_e rsa_decrypt_with_private_key( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + /** + * Function signs hash to signed hash using RSA algorithm with private RSA key. + */ + EAP_FUNC_IMPORT eap_status_e rsa_sign( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash); + + /** + * Function verifies hash and signed hash using RSA algorithm with public RSA key. + */ + EAP_FUNC_IMPORT eap_status_e rsa_verify( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash); + + EAP_FUNC_IMPORT eap_status_e rsa_cleanup( + eap_variable_data_c * const rsa_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + /** + * The dsa_init() function initializes context of DSA. + * Internal context of DSA is stored to dsa_context. + */ + EAP_FUNC_IMPORT eap_status_e dsa_init( + eap_variable_data_c * const dsa_context); + + /** + * Function signs hash to signed hash using DSA algorithm with private RSA key. + */ + EAP_FUNC_IMPORT eap_status_e dsa_sign( + eap_variable_data_c * const dsa_context, + const eap_variable_data_c * const private_dsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash); + + /** + * Function verifies hash and signed hash using DSA algorithm with public RSA key and DSA parameters. + */ + EAP_FUNC_IMPORT eap_status_e dsa_verify( + eap_variable_data_c * const dsa_context, + const eap_variable_data_c * const public_dsa_key, + const eap_variable_data_c * const dsa_param_p, + const eap_variable_data_c * const dsa_param_q, + const eap_variable_data_c * const dsa_param_g, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash); + + /** + * This function cleans up dsa_context. + */ + EAP_FUNC_IMPORT eap_status_e dsa_cleanup( + eap_variable_data_c * const dsa_context); + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + + /** + * This function initializes crypto memory leak detection. + * In Symbian this is not used. + */ + EAP_FUNC_IMPORT void open_crypto_memory_leaks(); + + /** + * This function ends crypto memory leak detection. + * In Symbian this is not used. + */ + EAP_FUNC_IMPORT void close_crypto_memory_leaks(); + + // - - - - - - - - - - - - - - - - - - - - - - - - +private: + void generate_diffie_hellman_keysL( + eap_variable_data_c * const own_private_dh_key, + eap_variable_data_c * const own_public_dh_key, + const u8_t * const prime, + const u32_t prime_length, + const u8_t * const group_generator, + const u32_t group_generator_length); + + void generate_g_power_to_xyL( + const eap_variable_data_c * const own_private_dh_key, + const eap_variable_data_c * const peer_public_dh_key, + eap_variable_data_c * const shared_dh_key, + const u8_t * const /* prime */, + const u32_t prime_length, + const u8_t * const /* group_generator */, + const u32_t /* group_generator_length */); + + void rsa_encrypt_with_public_keyL( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + void rsa_decrypt_with_public_keyL( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + void rsa_encrypt_with_private_keyL( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + void rsa_decrypt_with_private_keyL( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const input_data, + eap_variable_data_c * const output_data); + + void dsa_signL( + eap_variable_data_c * const dsa_context, + const eap_variable_data_c * const private_dsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash); + + void dsa_verifyL( + eap_variable_data_c * const dsa_context, + const eap_variable_data_c * const public_dsa_key, + const eap_variable_data_c * const dsa_param_p, + const eap_variable_data_c * const dsa_param_q, + const eap_variable_data_c * const dsa_param_g, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash); + + eap_status_e rc4(const eap_variable_data_c * const rc4_context, + const void* data_in, + void* const data_out, + const u32_t data_length); + + eap_status_e rsa_verifyL( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const public_rsa_key, + const eap_variable_data_c * const hash, + const eap_variable_data_c * const signed_hash); + + eap_status_e rsa_signL( + eap_variable_data_c * const rsa_context, + const eap_variable_data_c * const private_rsa_key, + const eap_variable_data_c * const hash, + eap_variable_data_c * const signed_hash); + +}; + +#endif //#if !defined( _EAP_AM_CRYPTO_SYMBIAN_H_ ) + + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_file_input_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_file_input_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,200 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_EAP_AM_FILE_INPUT_SYMBIAN_H_) +#define _EAP_AM_FILE_INPUT_SYMBIAN_H_ + + +#include "eap_tools.h" +#include "abs_eap_am_tools.h" +#include "eap_am_tools.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "abs_eap_am_file_input.h" +#include + +//-------------------------------------------------- + +const u32_t EAP_AM_FILE_INPUT_BUFFER_SIZE = 1024; + +/// This is interface to EAP file input. +/** The EAP file input is used in configuration file read operations. + */ +class EAP_EXPORT eap_am_file_input_symbian_c +: public abs_eap_am_file_input_c +{ + +private: + + abs_eap_am_tools_c *m_am_tools; + + /// Flag tells this object is valid. + bool m_is_valid; + + /// Handle to file session. + RFs m_file_session; + + /// Hamdle to file. + RFile m_File; + + /// Cache input buffer to reduce Symbian read operations. + TBuf8 * m_input_buffer; + + /// Offset of read point in the m_input_buffer. + u32_t m_input_buffer_offset; + + // On purpose unimplemented constructors. + eap_am_file_input_symbian_c(eap_am_file_input_symbian_c &source); + const eap_am_file_input_symbian_c & operator=(const eap_am_file_input_symbian_c& source); + + /** + * The set_is_valid() function sets the state of the object valid. + * The creator of this object calls this function after it is initialized. + */ + void set_is_valid(); + + /** + * This function reads n bytes from file to buffer. + */ + eap_status_e file_read_buffer( + eap_variable_data_c * const buffer, + const u32_t required_bytes); + +public: + + /** + * The destructor of the eap_am_file_input_symbian_c class does nothing special. + */ + EAP_FUNC_IMPORT virtual ~eap_am_file_input_symbian_c(); + + /** + * The constructor of the eap_am_file_input_symbian_c does nothing special. + */ + EAP_FUNC_IMPORT eap_am_file_input_symbian_c( + abs_eap_am_tools_c * const tools); + + /** + * This function checks the file of name file_name exists. + * It returns eap_status_ok if file exists + * in other cases some error status. + * @param file_name is the pathname of the tested file. + */ + EAP_FUNC_IMPORT eap_status_e file_exists( + const eap_variable_data_c * const file_name); + + /** + * This function deletes the file of name if file_name exists. + * It returns eap_status_ok if file did exist and it was deleted + * in other cases some error status. + * @param file_nameis the pathname of the deleted file. + */ + EAP_FUNC_IMPORT eap_status_e file_delete( + const eap_variable_data_c * const file_name); + + /** + * This function copies the file source_file_name to file target_file_name. + * @param target_file_name is the pathname of the target file. + * @param source_file_name is the pathname of the source file. + */ + EAP_FUNC_IMPORT eap_status_e file_copy( + const eap_variable_data_c * const target_file_name, + const eap_variable_data_c * const source_file_name); + + /** + * This function opens file of name file_name. + * @param file_name is the pathname of the opened file. + * @param dir is the I/O direction (eap_file_io_direction_read or eap_file_io_direction_write). + */ + EAP_FUNC_IMPORT eap_status_e file_open( + const eap_variable_data_c * const file_name, + const eap_file_io_direction_e dir); + + /** + * This function closes the file. + */ + EAP_FUNC_IMPORT eap_status_e file_close(); + + /** + * This function returns size of a file. + */ + EAP_FUNC_IMPORT u32_t file_size(); + + /** + * This function reads data from file. + * Maximum size read is the buffer size. + * @param buffer must be initialised to reguired size. + */ + EAP_FUNC_IMPORT eap_status_e file_read(eap_variable_data_c * const buffer); + + /** + * This function write data to a file. + * Maximum size write is the buffer size. + * @param buffer includes the written data. + */ + EAP_FUNC_IMPORT eap_status_e file_write(const eap_variable_data_c * const buffer); + + /** + * This function reads line from file. + * @param The read line will be copied to line parameter. + */ + EAP_FUNC_IMPORT eap_status_e file_read_line(eap_variable_data_c * const line); + + /** + * This function reads word from file. + * @param The read word will be copied to word parameter. + */ + EAP_FUNC_IMPORT eap_status_e file_read_word(eap_variable_data_c * const word); + + + /** + * Object must indicate it's validity. + * If object initialization fails this function must return false. + * @return This function returns the validity of this object. + */ + EAP_FUNC_IMPORT bool get_is_valid(); + + /** + * This function opens directory of name directory_name. + * @param file_name is the pathname of the opened directory. + */ + EAP_FUNC_IMPORT eap_status_e directory_open( + const eap_variable_data_c * const directory_name); + + /** + * This function reads the files and directories from open directory. + * @param directory_list includes the stattus of each file and directory in open directory. + */ + EAP_FUNC_IMPORT eap_status_e directory_read( + eap_array_c * const directory_list); + + /** + * This function closes the directory. + */ + EAP_FUNC_IMPORT eap_status_e directory_close(); + + +}; // class eap_am_bloom_algorithm_c + +#endif //#if !defined(_EAP_AM_FILE_INPUT_SYMBIAN_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_mutex_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_mutex_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_AM_MUTEX_SYMBIAN_H_ ) +#define _EAP_AM_MUTEX_SYMBIAN_H_ + +// INCLUDES +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "abs_eap_am_mutex.h" + +// CLASS DECLARATION +class EAP_EXPORT eap_am_mutex_symbian_c +: public abs_eap_am_mutex_c +, public eap_am_mutex_base_c +{ +private: + + /// Object is Symbian implementation of the mutex. + RMutex m_mutex; + + /// Object is Symbian implementation of the thread which is owner of the mutex. + RThread m_owner_thread; + + bool m_is_valid; + + // On purpose unimplemented constructors. + eap_am_mutex_symbian_c(eap_am_mutex_symbian_c &source); + const eap_am_mutex_symbian_c & operator=(const eap_am_mutex_symbian_c& source); + +public: + + EAP_FUNC_IMPORT virtual ~eap_am_mutex_symbian_c(); + + EAP_FUNC_IMPORT eap_am_mutex_symbian_c(); + + EAP_FUNC_IMPORT eap_am_mutex_symbian_c(const eap_am_mutex_symbian_c * const owner); + + /// Function returns pointer to Symbian mutex. + EAP_FUNC_IMPORT const RMutex * get_mutex() const; + + /// Function returns pointer to owner thread of the mutex. + EAP_FUNC_IMPORT const RThread * get_owner_thread() const; + + // See comments on abs_eap_am_mutex_c. + EAP_FUNC_IMPORT eap_status_e mutex_enter(); + + // See comments on abs_eap_am_mutex_c. + EAP_FUNC_IMPORT eap_status_e mutex_leave(abs_eap_am_tools_c * const m_am_tools); + + // The mutex handle must be dublicated in Symbian operating system for each thread. + // See comments on abs_eap_am_mutex_c. + EAP_FUNC_IMPORT abs_eap_am_mutex_c * dublicate_mutex(); + + // This is used in debug asserts. Those will check the mutex is really reserved when critical code is entered. + // See comments on abs_eap_am_mutex_c. + EAP_FUNC_IMPORT bool get_is_reserved() const; + + // See comments on abs_eap_am_mutex_c. + EAP_FUNC_IMPORT bool get_is_valid() const; + + // - - - - - - - - - - - - - - - - - - - - - - - - + +}; + +#endif //#if !defined( _EAP_AM_MUTEX_SYMBIAN_H_ ) + + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_semaphore_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_semaphore_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,99 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_AM_SEMAPHORE_SYMBIAN_H_ ) +#define _EAP_AM_SEMAPHORE_SYMBIAN_H_ + +// INCLUDES +#include "eap_am_types.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include + +// CLASS DECLARATION +class EAP_EXPORT eap_am_semaphore_symbian_c +: public abs_eap_am_semaphore_c +, public eap_am_semaphore_base_c +{ +private: + + /// Object is Symbian implementation of the semaphore. + RSemaphore m_semaphore; + + /// Object is Symbian implementation of the thread which is owner of the semaphore. + RThread m_owner_thread; + + bool m_is_valid; + + u32_t m_count; + + // On purpose unimplemented constructors. + eap_am_semaphore_symbian_c(eap_am_semaphore_symbian_c &source); + const eap_am_semaphore_symbian_c & operator=(const eap_am_semaphore_symbian_c& source); + +public: + + EAP_FUNC_IMPORT virtual ~eap_am_semaphore_symbian_c(); + + EAP_FUNC_IMPORT eap_am_semaphore_symbian_c( const i32_t initial_count,const i32_t maximum_count); + + EAP_FUNC_IMPORT eap_am_semaphore_symbian_c(const eap_am_semaphore_symbian_c * const owner); + + /// Function returns pointer to Symbian semaphore. + EAP_FUNC_IMPORT const RSemaphore * get_semaphore() const; + + /// Function returns pointer to owner thread of the semaphore. + EAP_FUNC_IMPORT const RThread * get_owner_thread() const; + + + // - - - - - - - - - - - - - - - - - - - - - - - - + // From abs_eap_am_semaphore_c + + /** + * This function reserves the semaphore. Thread will block until the semaphore is released + * by other owner of the semaphore. + */ + EAP_FUNC_IMPORT eap_status_e semaphore_reserve(); + + /** + * This function releases the semaphore. Other blocking thread will continue execution. + */ + EAP_FUNC_IMPORT eap_status_e semaphore_release(); + + /** + * The semaphore handle must be dublicated in Symbian operating system for each thread. + */ + EAP_FUNC_IMPORT abs_eap_am_semaphore_c * dublicate_semaphore(); + + EAP_FUNC_IMPORT u32_t get_count() const; + + /** + * Returns the validity of the semaphore. + */ + EAP_FUNC_IMPORT bool get_is_valid() const; + + // - - - - - - - - - - - - - - - - - - - - - - - - +}; + +#endif //#if !defined( _EAP_AM_SEMAPHORE_SYMBIAN_H_ ) + + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_tools_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_tools_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,265 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +// INCLUDES +#if !defined( _EAP_AM_TOOLS_SYMBIAN_H_ ) +#define _EAP_AM_TOOLS_SYMBIAN_H_ + +#include +#include + +//#include "eap_am_memory.h" + +#include "eap_am_tools.h" +#include "eap_variable_data.h" +#include "eap_tools.h" +#include "eap_status.h" +#include "eap_am_export.h" +#include "eap_am_crypto_symbian.h" +#include "eap_timer_queue.h" +#include "eap_am_mutex_symbian.h" +#include +#include + +/// This class implements functionality of platform adaptation of Symbian. +/** + * See function comments on abs_eap_am_tools_c and eap_am_tools_c. + */ +class EAP_EXPORT eap_am_tools_symbian_c +: public eap_am_tools_c +//, public CActive +, public CTimer +{ +private: + +#if defined(USE_EAP_FILE_TRACE) + /// File server used in filetrace. + RFs m_Fs; + + /// File used in filetrace. + RFile m_LogFile; + + /// File name used in filetrace. + TBuf<64> m_filename; +#endif //#if defined(USE_EAP_FILE_TRACE) + + u64_t m_start_ticks; + + bool m_directory_exists; + + eap_am_crypto_symbian_c m_crypto; + + eap_timer_queue_c m_timer_queue; + + eap_am_mutex_symbian_c m_global_mutex; + + eap_am_mutex_symbian_c m_trace_mutex; + + bool m_run_thread; + + bool m_is_valid; + + bool m_configure_called; + +#if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS) + /// Bufers are used in traces. + TBuf8<1024> m_args_buf; +#if defined(USE_EAP_HARDWARE_TRACE) + TBuf16<1024> m_trace_buf_16; +#endif //#if defined(USE_EAP_HARDWARE_TRACE) +#endif //#if defined(USE_EAP_TRACE) || defined(USE_EAP_TRACE_ALWAYS) + + /// Buffers are used in string conversions. + TBuf8<1024> m_format_buf; + TBuf8<1024> m_trace_buf; + + /// These member variables are used in Symbian timer. + TUint iInterval; + u64_t iStartTime; + u64_t iLastTime; + + // This flag tells whether the trace log file is open. + bool m_logfile_open; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_FUNC_IMPORT void sprint(TDes& KPrintBuf, eap_const_string format, ...); + + EAP_FUNC_IMPORT void KFormatVArgs(TDes& aDes, const TDesC& aFmt, VA_LIST aList); + + // Member function to support active sceduler timer. + void StartTimer(const TUint aInterval); + void StopTimer(); + TBool TimerRunning(); + void RunL(); + void DoCancel(); + + u32_t limit_microsecond_timeout(u32_t next_timeout_millisecond); + + // On purpose unimplemented constructors. + eap_am_tools_symbian_c(eap_am_tools_symbian_c &source); + const eap_am_tools_symbian_c & operator=(const eap_am_tools_symbian_c& source); + +public: + + EAP_FUNC_IMPORT virtual ~eap_am_tools_symbian_c(); + + EAP_FUNC_IMPORT eap_am_tools_symbian_c(eap_const_string pfilename); + + + /// See function comments on abs_eap_am_tools_c and eap_am_tools_c. + + EAP_FUNC_IMPORT eap_status_e configure(); + + EAP_FUNC_IMPORT bool get_use_eap_milli_second_timer(); + + EAP_FUNC_IMPORT void set_use_eap_milli_second_timer( + const bool use_eap_millisecond_timer); + + EAP_FUNC_IMPORT void enter_global_mutex(); + + EAP_FUNC_IMPORT void leave_global_mutex(); + + EAP_FUNC_IMPORT abs_eap_am_mutex_c * get_global_mutex(); + + EAP_FUNC_IMPORT void enter_trace_mutex(); + + EAP_FUNC_IMPORT void leave_trace_mutex(); + + EAP_FUNC_IMPORT abs_eap_am_mutex_c * get_trace_mutex(); + + + EAP_FUNC_IMPORT void set_timer_resolution_ms(const u32_t timer_resolution_ms); + + EAP_FUNC_IMPORT u32_t get_timer_resolution_ms(); + + EAP_FUNC_IMPORT u32_t pulse_timer(const u32_t elapsed_time_in_ms); + + EAP_FUNC_IMPORT bool get_timer_queue_is_empty(); + + + EAP_FUNC_IMPORT eap_status_e start_timer_thread(); + + EAP_FUNC_IMPORT eap_status_e stop_timer_thread(); + + EAP_FUNC_IMPORT bool get_is_timer_thread_active(); + + + EAP_FUNC_IMPORT eap_status_e set_trace_file_name(const eap_variable_data_c * const trace_output_file); + + EAP_FUNC_IMPORT void set_max_trace_file_size(const u32_t max_trace_file_size); + + EAP_FUNC_IMPORT u32_t snprintf(u8_t * const buffer, u32_t buffer_size, eap_format_string format, ...); + + EAP_FUNC_IMPORT void formatted_print(eap_format_string format, ...); + + EAP_FUNC_IMPORT void memmove(void *dest, const void *src, const u32_t count); + + EAP_FUNC_IMPORT i32_t memcmp(const void * const dest, const void * const src, const u32_t count); + + EAP_FUNC_IMPORT void memset(void * const src, const i32_t fill_byte, const u32_t count); + + EAP_FUNC_IMPORT void *memchr( + const void *buf, + u8_t character, + u32_t count); + + EAP_FUNC_IMPORT void *memrchr( + const void *buf, + u8_t character, + u32_t count); + + EAP_FUNC_IMPORT u32_t strlen( + eap_const_string string); + + EAP_FUNC_IMPORT u32_t config_strlen( + eap_config_string string); + + EAP_FUNC_IMPORT abs_eap_am_crypto_c * get_crypto(); + + EAP_FUNC_IMPORT u64_t get_hardware_ticks(); + + EAP_FUNC_IMPORT u64_t get_hardware_ticks_of_second(); + + EAP_FUNC_IMPORT u64_t get_clock_ticks(); + + EAP_FUNC_IMPORT u64_t get_clock_ticks_of_second(); + + EAP_FUNC_IMPORT u32_t get_gmt_unix_time(); + + EAP_FUNC_IMPORT eap_status_e am_set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms); + + EAP_FUNC_IMPORT eap_status_e am_cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id); + + EAP_FUNC_IMPORT eap_status_e am_cancel_all_timers(); + + EAP_FUNC_IMPORT eap_status_e re_activate_timer_queue(); + + EAP_FUNC_IMPORT void enter_crypto_cs(); + EAP_FUNC_IMPORT void leave_crypto_cs(); + + EAP_FUNC_IMPORT void timer_sleep(u32_t milli_seconds); + + EAP_FUNC_IMPORT void sleep(u32_t milli_seconds); + + EAP_FUNC_IMPORT bool get_is_valid() const; + + EAP_FUNC_IMPORT eap_status_e begin_db_transaction(RDbNamedDatabase& aDatabase); + + EAP_FUNC_IMPORT eap_status_e begin_db_update(RDbView& aView); + + EAP_FUNC_IMPORT eap_status_e begin_db_delete(RDbView& aView); + + /// This function must call eap_am_tools_c::shutdown_am_tools(). + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT eap_status_e convert_unicode_to_utf8( + eap_variable_data_c & dest, + const eap_variable_data_c & src); + + EAP_FUNC_IMPORT eap_status_e convert_utf8_to_unicode( + eap_variable_data_c & dest, + const eap_variable_data_c & src); + + EAP_FUNC_IMPORT eap_status_e convert_am_error_to_eapol_error(const i32_t am_error_value); + + EAP_FUNC_IMPORT i32_t convert_eapol_error_to_am_error(eap_status_e aErr); + + EAP_FUNC_IMPORT eap_status_e getenv( + const eap_variable_data_c * const environment_variable_name, + eap_variable_data_c * const environment_variable_value); + + EAP_FUNC_IMPORT bool isspace(const u8_t character); + + EAP_FUNC_IMPORT u64_struct u64_t_to_u64_struct(const u64_t value); + + EAP_FUNC_IMPORT u64_t u64_struct_to_u64_t(const u64_struct value); +}; + +#endif //#if !defined( _EAP_AM_TOOLS_SYMBIAN_H_ ) + + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_trace_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_trace_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2001-2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined( _EAP_AM_TRACE_SYMBIAN_H_ ) +#define _EAP_AM_TRACE_SYMBIAN_H_ + +#if defined(_DEBUG) + +#include "eap_status_string.h" +#include + +#define DEBUG(a) RDebug::Print(_L(a)) +#define DEBUG1(a,b) RDebug::Print(_L(a),b) +#define DEBUG2(a,b,c) RDebug::Print(_L(a),b,c) +#define DEBUG3(a,b,c,d) RDebug::Print(_L(a),b,c,d) +#define DEBUG4(a,b,c,d,e) RDebug::Print(_L(a),b,c,d,e) +#define DEBUG5(a,b,c,d,e,f) RDebug::Print(_L(a),b,c,d,e,f) +#define DEBUG6(a,b,c,d,e,f,g) RDebug::Print(_L(a),b,c,d,e,f,g) +#define DEBUG7(a,b,c,d,e,f,g,h) RDebug::Print(_L(a),b,c,d,e,f,g,h) +#define DEBUG8(a,b,c,d,e,f,g,h,i) RDebug::Print(_L(a),b,c,d,e,f,g,h,i) + +void trace_data( + eap_const_string prefix, + const void * const p_data, + const u32_t data_length); + +#define EAP_TRACE_DEBUG_SYMBIAN(_parameter_list_) \ + { \ + RDebug::Print _parameter_list_ ; \ + } \ + +#define EAP_TRACE_DATA_DEBUG_SYMBIAN(_parameter_list_) \ + { \ + trace_data _parameter_list_ ; \ + } \ + +#else // #if defined(_DEBUG) || defined(DEBUG) + +#define DEBUG(a) +#define DEBUG1(a,b) +#define DEBUG2(a,b,c) +#define DEBUG3(a,b,c,d) +#define DEBUG4(a,b,c,d,e) +#define DEBUG5(a,b,c,d,e,f) +#define DEBUG6(a,b,c,d,e,f,g) +#define DEBUG7(a,b,c,d,e,f,g,h) +#define DEBUG8(a,b,c,d,e,f,g,h,i) + +#define EAP_TRACE_DEBUG_SYMBIAN(_parameter_list_) + +#define EAP_TRACE_DATA_DEBUG_SYMBIAN(_parameter_list_) + +#endif // #if defined(_DEBUG) || defined(DEBUG) + +#endif //#if !defined( _EAP_AM_TRACE_SYMBIAN_H_ ) diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_aka_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_aka_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,513 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_TYPE_AKA_SYMBIAN_H_) +#define _EAP_AM_TYPE_AKA_SYMBIAN_H_ + + +// INCLUDES + +#include +#include +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_base_type.h" + +#include "eap_am_type_aka.h" +#include "abs_eap_am_aka_algorithm.h" + +// FORWARD DECLARATIONS +class eap_am_tools_symbian_c; +class CEapAkaInterface; + +// For the server side. +const u32_t MAX_PSEUDONYM_USE_COUNT = 1; +const u32_t MAX_REAUTH_USE_COUNT = 3; + + +// CLASS DECLARATION + +/** +* Class that implements the operating system dependent portion of +* EAP AKA protocol for Symbian OS. +*/ + + +class EAP_EXPORT eap_am_type_aka_symbian_c +: public CBase, public eap_am_type_aka_c +{ +public: + //-------------------------------------------------- + + EAP_FUNC_IMPORT static eap_am_type_aka_symbian_c* NewL( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + + // + EAP_FUNC_IMPORT virtual ~eap_am_type_aka_symbian_c(); + + + /** From the parent eap_am_type_aka_c **/ + + EAP_FUNC_IMPORT eap_status_e configure(); + + EAP_FUNC_IMPORT eap_status_e reset(); + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + EAP_FUNC_IMPORT eap_status_e shutdown(); + + /** AKA client calls this function. + * AKA AM could store copy of pseudonym identity to favourite place for future use. + * If parameter pseudonym is NULL pointer, AM should reset the existing pseudonym. + */ + EAP_FUNC_IMPORT eap_status_e store_pseudonym_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const pseudonym); + + /** AKA client calls this function. + * AKA AM could store copy of reauthentication identity to favourite place for future use. + * If parameter reauthentication_identity is NULL pointer, AM should reset the existing reauthentication identity. + */ + EAP_FUNC_IMPORT eap_status_e store_reauthentication_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const reauthentication_identity); + + /** AKA server and client calls this function. + * In order to use re-authentication, the client and the server need to + * store the following values: original XKEY, K_aut, K_encr, latest + * counter value and the next re-authentication identity. + * This function stores original XKEY, K_aut, K_encr and latest + * counter value. + */ + EAP_FUNC_IMPORT eap_status_e store_reauth_parameters( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter); + + /** AKA client calls this function. + * AKA AM could do finishing operations to databases etc. based on authentication status and type. + */ + EAP_FUNC_IMPORT eap_status_e authentication_finished( + const bool true_when_successfull, + const eap_aka_authentication_type_e authentication_type, + const eap_type_aka_identity_type identity_type); + + /** AKA server and client calls this function. + * In order to use re-authentication, the client and the server need to + * store the following values: original XKEY, K_aut, K_encr, latest + * counter value and the next re-authentication identity. + */ + EAP_FUNC_IMPORT eap_status_e query_reauth_parameters( + eap_variable_data_c * const XKEY, + eap_variable_data_c * const K_aut, + eap_variable_data_c * const K_encr, + u32_t * const reauth_counter); + + /** AKA server and client calls this function. + * This function increases re-authentication counter after a successfull re-authentication. + */ + EAP_FUNC_IMPORT eap_status_e increase_reauth_counter(); + + /** AKA client calls this function. + * AM could copy IMSI or pseudonym to output parameters. + * AM must copy IMSI or pseudonym to output parameters. + * This function could be completed asyncronously with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + */ + EAP_FUNC_IMPORT eap_status_e query_AKA_IMSI_or_pseudonym_or_reauthentication_id( + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const length_of_mnc, + const aka_payload_AT_type_e required_identity, ///< This parameter indicated the type of identity required. + const eap_type_aka_complete_e required_completion, ///< This parameter tells the required completion after this call is completed, if this is asyncronous. Use this value with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + const u8_t received_eap_identifier ///< This is the EAP-identifier of the received EAP-request message. Use this value with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + ); + + /** AKA client calls this function. + * This call cancels asyncronous query_AKA_IMSI_or_pseudonym_or_reauthentication_id() function call. + * AM must not complete query_AKA_IMSI_or_pseudonym_or_reauthentication_id() + * with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() after + * cancel_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() call. + */ + EAP_FUNC_IMPORT eap_status_e cancel_AKA_IMSI_or_pseudonym_or_reauthentication_id_query(); + + + /** AKA client calls this function. + * Input parameter RAND and AUTN as input to AKA algorithm. + * AM could copy CK, IK and RES to output parameters. + * This function could be completed asyncronously with abs_eap_am_type_aka_c::complete_AKA_RES_query() function call. + */ + EAP_FUNC_IMPORT eap_status_e query_AKA_RES( + eap_type_aka_authentication_vector_c * const authentication_vector); + + /** AKA client calls this function. + * This call cancels asyncronous query_AKA_RES() function call. + * AM must not complete query_AKA_RES() + * with abs_eap_am_type_aka_c::complete_AKA_RES_query() after + * cancel_AKA_RES_query() call. + */ + EAP_FUNC_IMPORT eap_status_e cancel_AKA_RES_query(); + + /** AKA client calls this function. + * Received AT_NOTIFICATION is handled in AM of AKA. + * AM could show localized message to user. + */ + EAP_FUNC_IMPORT eap_status_e handle_aka_notification(eap_aka_notification_codes_e aka_notification_code); + + /** AKA server calls this function. + * AM could copy triplets to output parameters. + * This function could be completed asyncronously with abs_eap_am_type_aka_c::complete_AKA_authentication_vector_query() function call. + */ + EAP_FUNC_IMPORT eap_status_e query_AKA_authentication_vector( + const eap_variable_data_c * const username, ///< // This is payload AT_IDENTITY. If this is uninitialized then imsi must be initialized. + const u8_t next_eap_identifier, + eap_variable_data_c * const imsi, ///< This is the real IMSI. If this is uninitialized then username must be initialized and imsi will be initialized after this call. + eap_type_aka_authentication_vector_c * const authentication_vector, + eap_type_aka_identity_type * const type); + + /** AKA server calls this function. + * This call cancels asyncronous query_AKA_authentication_vector() function call. + * AM must not complete query_AKA_authentication_vector() with abs_eap_am_type_aka_c::complete_AKA_authentication_vector_query() after + * cancel_AKA_authentication_vector_query() call. + */ + EAP_FUNC_IMPORT eap_status_e cancel_AKA_authentication_vector_query(); + + /** AKA server/client calls this function. + * This function call generates with a good source of + * randomness the initialization vector (AT_IV payload). + */ + EAP_FUNC_IMPORT eap_status_e generate_encryption_IV( + eap_variable_data_c * const encryption_IV, + const u32_t IV_length); + + /** AKA server calls this function. + * New pseudonym identity is generated for IMSI. + * Algorithm is freely selected. Look at query_imsi_from_username(). + * Pseudonym identity is copied to pseudonym_identity parameter. + * Maximum length of pseudonym is maximum_pseudonym_length bytes. + */ + EAP_FUNC_IMPORT eap_status_e generate_pseudonym_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const pseudonym_identity, + const u32_t maximum_pseudonym_length); + + /** AKA server calls this function. + * New reauthentication identity is generated for IMSI. + * Algorithm is freely selected. Look at query_imsi_from_username(). + * Reauthentication identity is copied to pseudonym parameter. + * Maximum length of pseudonym is maximum_reauthentication_identity_length bytes. + */ + EAP_FUNC_IMPORT eap_status_e generate_reauthentication_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const reauthentication_identity, + const u32_t maximum_reauthentication_identity_length); + + /** AKA server calls this function. + * Server queries IMSI with username. + * Username could be IMSI, pseudonym or re-authentication identity. + * Adaptation module must verify which username is. + * Adaptation module could map IMSI and username as it wish. + * It can select any algorithm. Look at generate_pseudonym_id() and generate_reauthentication_id(). + * Function must return IMSI and set the identity type of received username. + */ + EAP_FUNC_IMPORT eap_status_e query_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_type_aka_identity_type * const type, + const eap_type_aka_complete_e completion_action); + + /** AKA server calls this function. + * Server queries re-syncronization. + * This function call is completed by complete_re_syncronization_query() function. + */ + EAP_FUNC_IMPORT eap_status_e query_re_syncronization( + const u8_t next_eap_identifier, + eap_type_aka_authentication_vector_c * const authentication_vector + ); + + /** AKA server calls this function. + * This call cancels asyncronous query_imsi_from_username() function call. + * AM must not complete query_imsi_from_username() + * with abs_eap_am_type_aka_c::complete_imsi_from_username() after + * cancel_imsi_from_username_query() call. + */ + EAP_FUNC_IMPORT eap_status_e cancel_imsi_from_username_query(); + + /** + * The type_configure_read() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /** + * The type_configure_write() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT bool get_is_valid(); + +#if defined(__WINS__) + + EAP_FUNC_IMPORT eap_status_e query_SIM_imsi( + u8_t * const imsi, const u32_t max_length, u32_t * const imsi_length); + +#endif //#if defined(__WINS__) + + EAP_FUNC_IMPORT eap_status_e complete_AKA_imsi_L( + const eap_variable_data_c * const IMSI, + const eap_status_e completion_status = eap_status_ok); + + EAP_FUNC_IMPORT eap_status_e complete_AKA_RES_L( + eap_variable_data_c * const aRES, + eap_variable_data_c * const aCK, + eap_variable_data_c * const aIK, + eap_variable_data_c * const aAUTS, + eap_status_e authenticationStatus = eap_status_ok, + const eap_status_e completion_status = eap_status_ok); + + /** + * Returns true if the full authenticated session is valid. + * It finds the difference between current time and the + * last full authentication time. If the difference is less than the + * Maximum Session Validity Time, then session is valid, returns true. + * Otherwise returns false. + * Full authentication should be done if the session is not valid. + */ + EAP_FUNC_IMPORT bool is_session_valid(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + eap_am_type_aka_symbian_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + + + void ConstructL(); + + //-------------------------------------------------- + +private: + + void type_configure_readL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data); + + void store_reauth_parametersL( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter); + + void query_reauth_parametersL( + eap_variable_data_c * const reauth_XKEY, + eap_variable_data_c * const reauth_K_aut, + eap_variable_data_c * const reauth_K_encr, + u32_t * const reauth_counter); + + void increase_reauth_counterL(); + + void query_AKA_IMSI_or_pseudonym_or_reauthentication_idL( + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + const aka_payload_AT_type_e required_identity, + const eap_type_aka_complete_e required_completion, + const u8_t received_eap_identifier); + + void store_pseudonym_idL( + const eap_am_network_id_c * const /*network_id*/, + const eap_variable_data_c * const pseudonym); + + void store_reauthentication_idL( + const eap_am_network_id_c * const /*network_id*/, + const eap_variable_data_c * const /* reauthentication_id */); + +#if defined (USE_EAP_TYPE_SERVER_AKA) + // These functions are used only for server side. + + eap_status_e generate_identity( + const eap_type_aka_identity_type identity_type, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const pseudonym, + const u32_t maximum_pseudonym_length); + + eap_status_e query_imsi_from_username_syncronous( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_type_aka_identity_type * const identity_type); + +#endif // #if defined (USE_EAP_TYPE_SERVER_AKA) + + eap_status_e store_imsi(const eap_variable_data_c * const imsi); + + void store_imsiL(const eap_variable_data_c * const imsi); + + eap_status_e check_is_valid_imsi( const eap_variable_data_c * const username ); + + void send_error_notification(const eap_status_e error); + + /** + * Returns true if the full authenticated session is valid. + * It finds the difference between current time and the + * last full authentication time. If the difference is less than the + * Maximum Session Validity Time, then session is valid, returns true. + * Otherwise returns false. + * Full authentication should be done if the session is not valid. + */ + bool is_session_validL(); + + /** + * Stores current universal time as the the full authentication time + * in the database. Returns KErrNone if storing succeeds. + */ + void store_authentication_timeL(); + +private: + //-------------------------------------------------- + RDbs m_session; + + RDbNamedDatabase m_database; + + eap_am_tools_symbian_c * const m_am_tools; + + abs_eap_base_type_c * const m_partner; + + eap_variable_data_c m_nai_realm; + + TIndexType m_index_type; + + TInt m_index; + + eap_type_value_e m_tunneling_type; + + bool m_is_valid; + + bool m_is_client; + + eap_variable_data_c m_stored_reauth_id; + + eap_variable_data_c m_stored_pseudonym; + + eap_variable_data_c m_previous_imsi; + + eap_type_aka_complete_e m_stored_required_completion; + + u8_t m_stored_received_eap_identifier; + + bool m_shutdown_was_called; + + abs_eap_am_aka_algorithm_c *m_aka_algorithm; + + CEapAkaInterface* m_aka_if; + + eap_variable_data_c m_simulator_aka_K; + eap_variable_data_c m_simulator_aka_OP; + eap_variable_data_c m_simulator_aka_AMF; + + eap_type_aka_authentication_vector_c * m_authentication_vector; + + eap_variable_data_c m_pseudonym_identity; + eap_variable_data_c m_reauthentication_identity; + eap_variable_data_c m_username; + eap_am_network_id_c m_receive_network_id; + + eap_variable_data_c m_IMSI; + + aka_payload_AT_type_e m_required_identity; + eap_type_aka_complete_e m_required_completion; + eap_type_aka_identity_type m_identity_type; + eap_type_aka_complete_e m_completion_action; + u8_t m_next_eap_identifier; + + eap_aka_authentication_vector_status_e m_aka_authentication_vector_status; + u32_t m_pseudonym_key_index; + eap_variable_data_c m_pseudonym_key; + eap_variable_data_c m_pseudonym_MAC_key; + eap_variable_data_c m_prev_pseudonym_key; + eap_variable_data_c m_prev_pseudonym_MAC_key; + u32_t m_pseudonym_key_use_count; + + // These values are needed especially in the case of synchronization failure. + eap_variable_data_c m_RAND; + eap_variable_data_c m_AUTN; + + // This holds the max session time read from the configuration file. + TInt64 m_max_session_time; + + // This is the vendor-type for tunneling EAP type. + // Valid for both expanded and non-expanded EAP types. + // This is used since m_tunneling_type can not be used in the same way + // in expanded and non-expanded cases. + // Unlike EAP type, Tunneling type is still non-expanded + // for both cases especially for using in the EAP databases. + u32_t m_tunneling_vendor_type; + +}; // class eap_am_type_aka_symbian_c + + +#endif //#if !defined(_EAP_AM_TYPE_AKA_SYMBIAN_H_) + +//-------------------------------------------------- + + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_gsmsim_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_gsmsim_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,420 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_TYPE_GSMSIM_SYMBIAN_H_) +#define _EAP_AM_TYPE_GSMSIM_SYMBIAN_H_ + +// INCLUDES +#include +#include +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_base_type.h" +#include "eap_am_type_gsmsim.h" +#include "abs_eap_am_sim_algorithm.h" + +#if !defined (USE_EAP_GSMSIM_INTERFACE) +// These are needed only for test environment ( Plugin tester). +// Comment out USE_EAP_GSMSIM_INTERFACE in eapol.mmh for building for the test environment. +#include "eap_am_sim_algorithm_nokia_test.h" +#endif // #if !defined (USE_EAP_GSMSIM_INTERFACE) + +#include "eap_am_network_id.h" + +// FORWARD DECLARATIONS + +class CEapSimIsaInterface; +class eap_am_tools_symbian_c; + +// CLASS DECLARATION + +/** +* Class that implements the operating system dependent portion of EAP SIM protocol. +* For Symbian OS. +*/ +class EAP_EXPORT eap_am_type_gsmsim_symbian_c +: public CBase, public eap_am_type_gsmsim_c +{ +public: + //-------------------------------------------------- + + static eap_am_type_gsmsim_symbian_c* NewL( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + // + EAP_FUNC_IMPORT virtual ~eap_am_type_gsmsim_symbian_c(); + + // + EAP_FUNC_IMPORT eap_status_e configure(); + + // + EAP_FUNC_IMPORT eap_status_e reset(); + + // + EAP_FUNC_IMPORT eap_status_e shutdown(); + +#if defined(__WINS__) + // + EAP_FUNC_IMPORT eap_status_e query_SIM_imsi( + u8_t * const imsi, const u32_t max_length, u32_t * const imsi_length); + +#endif //#if defined(__WINS__) + + // + EAP_FUNC_IMPORT eap_status_e store_pseudonym_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const pseudonym); + + // + EAP_FUNC_IMPORT eap_status_e store_reauthentication_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const reauthentication_identity); + + // + EAP_FUNC_IMPORT eap_status_e query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + const bool must_be_synchronous, + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const length_of_mnc, + const gsmsim_payload_AT_type_e required_identity, + const eap_type_gsmsim_complete_e required_completion, + const u8_t received_eap_identifier + ); + + // + EAP_FUNC_IMPORT eap_status_e cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query(); + + // + EAP_FUNC_IMPORT eap_status_e query_SIM_kc_and_sres( + const u8_t * const rand, + u8_t * const kc, + u8_t * const sres); + + // + EAP_FUNC_IMPORT eap_status_e handle_gsmsim_notification(eap_gsmsim_notification_codes_e gsmsim_notification_code); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + // + EAP_FUNC_IMPORT eap_status_e query_SIM_triplets( + const bool must_be_synchronous, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_type_sim_triplet_array_c * const triplets, + eap_type_gsmsim_identity_type * const type); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + // + EAP_FUNC_IMPORT eap_status_e cancel_SIM_triplets_query(); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + // + EAP_FUNC_IMPORT eap_status_e query_SIM_kc_sres( + const bool must_be_synchronous, + //const eap_variable_data_c * const imsi, + const eap_variable_data_c * const n_rands, + eap_variable_data_c * const n_kc, + eap_variable_data_c * const n_sres); + + // + EAP_FUNC_IMPORT eap_status_e cancel_SIM_kc_sres_query(); + + // + EAP_FUNC_IMPORT eap_status_e generate_encryption_IV( + eap_variable_data_c * const encryption_IV, + const u32_t IV_length); + + // + EAP_FUNC_IMPORT eap_status_e generate_pseudonym_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const pseudonym, + const u32_t maximum_pseudonym_length); + + // + EAP_FUNC_IMPORT eap_status_e generate_reauthentication_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const reauthentication_identity, + const u32_t maximum_reauthentication_identity_length); + + // + EAP_FUNC_IMPORT eap_status_e store_reauth_parameters( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter); + + // + EAP_FUNC_IMPORT eap_status_e authentication_finished( + const bool true_when_successfull, + const eap_gsmsim_authentication_type_e authentication_type, + const eap_type_gsmsim_identity_type identity_type); + + // + EAP_FUNC_IMPORT eap_status_e query_reauth_parameters( + eap_variable_data_c * const XKEY, + eap_variable_data_c * const K_aut, + eap_variable_data_c * const K_encr, + u32_t * const reauth_counter); + + // + EAP_FUNC_IMPORT eap_status_e increase_reauth_counter(); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + // + EAP_FUNC_IMPORT eap_status_e query_imsi_from_username( + const bool must_be_synchronous, + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_type_gsmsim_identity_type * const type, + const eap_type_gsmsim_complete_e completion_action); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + // + EAP_FUNC_IMPORT eap_status_e cancel_imsi_from_username_query(); + + // + EAP_FUNC_IMPORT eap_status_e check_is_rand_unused(const eap_variable_data_c * const n_rands); + + EAP_FUNC_IMPORT eap_status_e set_rand_is_used(const eap_variable_data_c * const n_rands); + + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT bool get_is_valid(); + + // + EAP_FUNC_IMPORT eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // + EAP_FUNC_IMPORT eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + eap_status_e complete_SIM_imsi_L( + const eap_variable_data_c * const IMSI, + const eap_status_e completion_status); + + eap_status_e complete_SIM_kc_and_sres_L( + TDesC8& aKc, + TDesC8& aSRES, + const eap_status_e completion_status); + + /** + * Returns true if the full authenticated session is valid. + * It finds the difference between current time and the + * last full authentication time. If the difference is less than the + * Maximum Session Validity Time, then session is valid, returns true. + * Otherwise returns false. + * Full authentication should be done if the session is not valid. + */ + bool is_session_valid(); + + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + eap_am_type_gsmsim_symbian_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + + void ConstructL(); + + //-------------------------------------------------- + +private: + void type_configure_readL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data); + + void store_reauth_parametersL( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter); + + void query_reauth_parametersL( + eap_variable_data_c * const reauth_XKEY, + eap_variable_data_c * const reauth_K_aut, + eap_variable_data_c * const reauth_K_encr, + u32_t * const reauth_counter); + + void increase_reauth_counterL(); + + void store_pseudonym_idL( + const eap_am_network_id_c * const /*network_id*/, + const eap_variable_data_c * const pseudonym); + + void store_reauthentication_idL( + const eap_am_network_id_c * const /*network_id*/, + const eap_variable_data_c * const /* reauthentication_id */); + + void query_SIM_IMSI_or_pseudonym_or_reauthentication_idL( + const bool must_be_synchronous, + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const length_of_mnc, + const gsmsim_payload_AT_type_e required_identity, + const eap_type_gsmsim_complete_e required_completion, + const u8_t received_eap_identifier); + + eap_status_e generate_identity( + const eap_am_network_id_c * const /* network_id */, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const identity, + const u32_t maximum_identity_length); + + eap_status_e store_imsi(const eap_variable_data_c * const imsi); + + void store_imsiL(const eap_variable_data_c * const imsi); + + void send_error_notification(const eap_status_e error); + + +#if defined(USE_EAP_SIM_RESET_RAND_DATABASES) + + eap_status_e reset_rand_check(); + +#endif //#if defined(USE_EAP_SIM_RESET_RAND_DATABASES) + + /** + * Returns true if the full authenticated session is valid. + * It finds the difference between current time and the + * last full authentication time. If the difference is less than the + * Maximum Session Validity Time, then session is valid, returns true. + * Otherwise returns false. + * Full authentication should be done if the session is not valid. + */ + bool is_session_validL(); + + /** + * Stores current universal time as the the full authentication time + * in the database. Returns KErrNone if storing succeeds. + */ + void store_authentication_timeL(); + + +private: + //-------------------------------------------------- + RDbs m_session; + + RDbNamedDatabase m_database; + + eap_am_tools_symbian_c * const m_am_tools; + + abs_eap_base_type_c * const m_partner; + + eap_variable_data_c m_triplet_file; + + eap_variable_data_c m_nai_realm; + + TIndexType m_index_type; + + TInt m_index; + + eap_type_value_e m_tunneling_type; + + bool m_is_valid; + + bool m_is_client; + + CEapSimIsaInterface* m_isa_if; + + eap_variable_data_c m_stored_reauth_id; + + eap_variable_data_c m_stored_pseudonym; + + eap_variable_data_c m_previous_imsi; + + eap_type_gsmsim_complete_e m_stored_required_completion; + + u8_t m_stored_received_eap_identifier; + + bool m_shutdown_was_called; + +#if !defined (USE_EAP_GSMSIM_INTERFACE) + eap_am_sim_algorithm_nokia_test_c m_sim_algorithm; +#endif //#if !defined (USE_EAP_GSMSIM_INTERFACE) + + sim_algorithm_e m_simulator_sim_algorithm; + + eap_variable_data_c m_simulator_sim_ki; + + eap_variable_data_c m_copy_of_n_rands; + + eap_variable_data_c m_n_kc; + + eap_variable_data_c m_n_sres; + + eap_variable_data_c m_uma_automatic_realm_prefix; + + eap_am_network_id_c m_receive_network_id; + + TInt m_rands_handled; + + /// This flag tells whether the client should check uniqueness of RANDs (true) or not (false). + bool m_do_rand_uniqueness_check; + + // This holds the max session time read from the configuration file. + TInt64 m_max_session_time; + + // This is the vendor-type for tunneling EAP type. + // Valid for both expanded and non-expanded EAP types. + // This is used since m_tunneling_type can not be used in the same way + // in expanded and non-expanded cases. + // Unlike EAP type, Tunneling type is still non-expanded + // for both cases especially for using in the EAP databases. + u32_t m_tunneling_vendor_type; + + //-------------------------------------------------- +}; // class eap_am_type_gsmsim_symbian_c + + +#endif //#if !defined(_EAP_AM_TYPE_GSMSIM_SYMBIAN_H_) + +//-------------------------------------------------- + + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_gsmsim_symbian_simulator.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_gsmsim_symbian_simulator.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,223 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_TYPE_GSMSIM_SYMBIAN_SIMULATOR_H_) +#define _EAP_AM_TYPE_GSMSIM_SYMBIAN_SIMULATOR_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_base_type.h" +#include "eap_am_type_gsmsim.h" +#include "EapPluginInterface.h" + +// +class EAP_EXPORT eap_am_type_gsmsim_simulator_c +: public eap_am_type_gsmsim_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + abs_eap_base_type_c * const m_partner; + + eap_variable_data_c saved_pseudonym; + + bool m_is_valid; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~eap_am_type_gsmsim_simulator_c(); + + // + EAP_FUNC_IMPORT eap_am_type_gsmsim_simulator_c( + abs_eap_am_tools_c * const m_am_tools, + abs_eap_base_type_c * const partner, + const CEapPluginInterface::TIndexType aIndexType, + const TInt aIndex); + + EAP_FUNC_IMPORT eap_status_e configure(); + + // + EAP_FUNC_IMPORT eap_status_e shutdown(); + + // + EAP_FUNC_IMPORT eap_status_e query_SIM_imsi( + u8_t * const imsi, const u32_t max_length, u32_t * const imsi_length); + + // + EAP_FUNC_IMPORT eap_status_e store_pseudonym_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const pseudonym); + + // + EAP_FUNC_IMPORT eap_status_e store_reauthentication_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const reauthentication_identity); + + // + EAP_FUNC_IMPORT eap_status_e query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + const bool must_be_synchronous, + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const length_of_mnc, + const gsmsim_payload_AT_type_e required_identity, + const eap_type_gsmsim_complete_e required_completion, + const u8_t received_eap_identifier); + + // + EAP_FUNC_IMPORT eap_status_e cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query(); + + // + EAP_FUNC_IMPORT eap_status_e query_SIM_kc_and_sres( + const u8_t * const imsi, const u32_t imsi_length, + const u8_t * const rand, const u32_t rand_length, + u8_t * const kc, u32_t * const kc_length, + u8_t * const sres, u32_t * const sres_length); + + // + EAP_FUNC_IMPORT eap_status_e handle_gsmsim_notification(eap_gsmsim_notification_codes_e gsmsim_notification_code); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + // + EAP_FUNC_IMPORT eap_status_e query_SIM_triplets( + const bool must_be_synchronous, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_type_sim_triplet_array_c * const triplets, + eap_type_gsmsim_identity_type * const type); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + // + EAP_FUNC_IMPORT eap_status_e cancel_SIM_triplets_query(); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + // + EAP_FUNC_IMPORT eap_status_e query_SIM_kc_sres( + const bool must_be_synchronous, + //const eap_variable_data_c * const imsi, + const eap_variable_data_c * const n_rands, + eap_variable_data_c * const n_kc, + eap_variable_data_c * const n_sres); + + // + EAP_FUNC_IMPORT eap_status_e cancel_SIM_kc_sres_query(); + + // + EAP_FUNC_IMPORT eap_status_e generate_encryption_IV( + eap_variable_data_c * const encryption_IV, + const u32_t IV_length); + + // + EAP_FUNC_IMPORT eap_status_e generate_pseudonym_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const pseudonym, + const u32_t maximum_pseudonym_length); + + // + EAP_FUNC_IMPORT eap_status_e generate_reauthentication_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const reauthentication_identity, + const u32_t maximum_reauthentication_identity_length); + + // + EAP_FUNC_IMPORT eap_status_e store_reauth_parameters( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter); + + // + EAP_FUNC_IMPORT eap_status_e authentication_finished( + const bool true_when_successfull, + const eap_gsmsim_authentication_type_e authentication_type, + const eap_type_gsmsim_identity_type identity_type); + + // + EAP_FUNC_IMPORT eap_status_e query_reauth_parameters( + eap_variable_data_c * const XKEY, + eap_variable_data_c * const K_aut, + eap_variable_data_c * const K_encr, + u32_t * const reauth_counter); + + // + EAP_FUNC_IMPORT eap_status_e increase_reauth_counter(); + + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + // + EAP_FUNC_IMPORT eap_status_e query_imsi_from_username( + const bool must_be_synchronous, + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_type_gsmsim_identity_type * const type, + const eap_type_gsmsim_complete_e completion_action); +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + + // + EAP_FUNC_IMPORT eap_status_e cancel_imsi_from_username_query(); + + // + EAP_FUNC_IMPORT eap_status_e check_is_rand_unused(const eap_variable_data_c * const n_rands); + + EAP_FUNC_IMPORT eap_status_e set_rand_is_used(const eap_variable_data_c * const n_rands); + + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT bool get_is_valid(); + + // + EAP_FUNC_IMPORT eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // + EAP_FUNC_IMPORT eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + //-------------------------------------------------- +}; // class eap_am_type_gsmsim_simulator_c + + +#endif //#if !defined(_EAP_AM_TYPE_GSMSIM_SYMBIAN_SIMULATOR_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_leap_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_leap_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,203 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAP_AM_TYPE_LEAP_SYMBIAN_H +#define EAP_AM_TYPE_LEAP_SYMBIAN_H + +// INCLUDES + +#include "eap_am_tools_symbian.h" +#include "abs_eap_base_type.h" +#include "eap_am_type_leap.h" +#include "eap_am_network_id.h" +#include "EapLeapNotifierStructs.h" +#include +#include + +const TUint KDefaultTimeoutLEAP = 120000; + +// CLASS DECLARATION + +/** +* Class that implements the operating system dependent portion of EAP LEAP protocol. +* For Symbian OS. +*/ +class EAP_EXPORT eap_am_type_leap_symbian_c +: public CActive, public eap_am_type_leap_c +{ +private: + //-------------------------------------------------- + + eap_am_tools_symbian_c * const m_am_tools; + + abs_eap_base_type_c * const m_partner; + + RDbs m_session; + + RDbNamedDatabase m_database; + + RNotifier m_notifier; + + TEapLeapUsernamePasswordInfo * m_input_output_data_ptr; + + TPckg * m_input_output_pckg_ptr; + + eap_am_network_id_c m_receive_network_id; + + TIndexType m_index_type; + + TInt m_index; + + eap_type_value_e m_tunneling_type; + + bool m_is_client; + + bool m_is_valid; + + bool m_is_identity_query; + + bool * m_password_prompt_enabled; + + eap_variable_data_c * m_username_utf8; + + eap_variable_data_c * m_password_utf8; + + bool m_shutdown_was_called; + + bool m_is_notifier_connected; // Tells if notifier server is connected. + + // This holds the max session time read from the configuration file. + TInt64 m_max_session_time; + + // This is the vendor-type for tunneling EAP type. + // Valid for both expanded and non-expanded EAP types. + // This is used since m_tunneling_type can not be used in the same way + // in expanded and non-expanded cases. + // Unlike EAP type, Tunneling type is still non-expanded + // for both cases especially for using in the EAP databases. + u32_t m_tunneling_vendor_type; + + void send_error_notification(const eap_status_e error); + + /** + * Stores current universal time as the the full authentication time + * in the database. Leaves if storing fails. + */ + void store_authentication_timeL(); + + bool is_session_validL(); + + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + eap_am_type_leap_symbian_c( + abs_eap_am_tools_c * const m_am_tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + + void ConstructL(); + + void RunL(); + + void DoCancel(); + + eap_status_e update_username_password(); + + void eap_am_type_leap_symbian_c::type_configure_updateL(); + + void type_configure_readL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data); + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + static eap_am_type_leap_symbian_c* NewL( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + + // + EAP_FUNC_IMPORT virtual ~eap_am_type_leap_symbian_c(); + + eap_status_e show_username_password_dialog( + eap_variable_data_c &username, + eap_variable_data_c &password, + bool &password_prompt_enabled, + bool is_identity_query); + + EAP_FUNC_IMPORT eap_status_e configure(); + + EAP_FUNC_IMPORT eap_status_e reset(); + + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT eap_status_e read_auth_failure_string( + eap_variable_data_c &string); + + EAP_FUNC_IMPORT eap_status_e get_memory_store_key( + eap_variable_data_c * const memory_store_key); + + /** + * Returns true if the full authenticated session is valid. + * It finds the difference between current time and the + * last full authentication time. If the difference is less than the + * Maximum Session Validity Time, then session is valid, returns true. + * Otherwise returns false. + * Full authentication (using pw query) should be done if the session is not valid. + */ + bool is_session_valid(); + + /** + * Stores current universal time as the the full authentication time + * in the database by calling the leaving function store_authentication_time_L. + * Returns appropriate error if storing fails. eap_status_ok for successful storing. + */ + eap_status_e store_authentication_time(); + +}; // class eap_am_type_leap_symbian_c + + +#endif // EAP_AM_TYPE_LEAP_SYMBIAN_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_mschapv2_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_mschapv2_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,207 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAP_AM_TYPE_MSCHAPV2_SYMBIAN_H_ +#define _EAP_AM_TYPE_MSCHAPV2_SYMBIAN_H_ + +// INCLUDES +#include "eap_am_tools_symbian.h" +#include "abs_eap_base_type.h" +#include "eap_am_type_mschapv2.h" +#include "eap_type_mschapv2.h" +#include "EapMsChapV2NotifierStructs.h" +#include +#include + +const TUint KDefaultTimeoutEAPMsChapV2 = 120000; + +/** +* Class that implements the operating system dependent portion of EAP Ms-Chap-v2 protocol. +* For Symbian OS. +*/ +class EAP_EXPORT eap_am_type_mschapv2_symbian_c +: public CActive, public eap_am_type_mschapv2_c +{ +private: + //-------------------------------------------------- + eap_am_tools_symbian_c * const m_am_tools; + + abs_eap_base_type_c * const m_partner; + + RDbs m_session; + + RDbNamedDatabase m_database; + + enum TState + { + EHandlingUsernamePasswordQuery, + EHandlingChangePasswordQuery, + }; + + TState m_state; + + RNotifier m_notifier; + + eap_variable_data_c * m_username_utf8; + eap_variable_data_c * m_password_utf8; + eap_variable_data_c * m_old_password_utf8; + bool * m_password_prompt_enabled; + bool m_is_identity_query; + + TEapMsChapV2UsernamePasswordInfo * m_username_password_io_ptr; + TPckg * m_username_password_io_pckg_ptr; + + eap_am_network_id_c m_receive_network_id; + + TIndexType m_index_type; + + TInt m_index; + + eap_type_value_e m_tunneling_type; + + bool m_is_client; + + bool m_is_valid; + + bool m_shutdown_was_called; + + bool m_is_notifier_connected; // Tells if notifier server is connected. + + // This holds the max session time read from the configuration file. + TInt64 m_max_session_time; + + // This is the vendor-type for tunneling EAP type. + // Valid for both expanded and non-expanded EAP types. + // This is used since m_tunneling_type can not be used in the same way + // in expanded and non-expanded cases. + // Unlike EAP type, Tunneling type is still non-expanded + // for both cases especially for using in the EAP databases. + u32_t m_tunneling_vendor_type; + + void send_error_notification(const eap_status_e error); + + bool is_session_validL(); + + /** + * Stores current universal time as the the full authentication time + * in the database. Leaves if storing fails. + */ + void store_authentication_timeL(); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + eap_am_type_mschapv2_symbian_c( + abs_eap_am_tools_c * const m_am_tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + + void ConstructL(); + + void RunL(); + + void DoCancel(); + + void type_configure_updateL(); + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + static eap_am_type_mschapv2_symbian_c* NewL( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + + // + EAP_FUNC_IMPORT virtual ~eap_am_type_mschapv2_symbian_c(); + + eap_status_e show_username_password_dialog( + eap_variable_data_c & username, + eap_variable_data_c & password, + bool & password_prompt_enabled, + bool is_identity_query); + + eap_status_e show_change_password_dialog( + eap_variable_data_c & username, + eap_variable_data_c & old_password, + eap_variable_data_c & password, + bool & password_prompt_enabled); + + // + EAP_FUNC_IMPORT eap_status_e configure(); + + EAP_FUNC_IMPORT eap_status_e reset(); + + EAP_FUNC_IMPORT eap_status_e update_username_password(); + + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + void type_configure_readL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT eap_status_e read_auth_failure_string(eap_mschapv2_error_e error_code, eap_variable_data_c &string); + + EAP_FUNC_IMPORT eap_status_e get_memory_store_key(eap_variable_data_c * const memory_store_key); + + /** + * Returns true if the full authenticated session is valid. + * It finds the difference between current time and the + * last full authentication time. If the difference is less than the + * Maximum Session Validity Time, then session is valid, returns true. + * Otherwise returns false. + * Full authentication (using pw query) should be done if the session is not valid. + */ + bool is_session_valid(); + + /** + * Stores current universal time as the the full authentication time + * in the database by calling the leaving function store_authentication_time_L. + * Returns appropriate error if storing fails. eap_status_ok for successful storing. + */ + eap_status_e store_authentication_time(); + +}; // class eap_am_type_mschapv2_symbian_c + + +#endif // _EAP_AM_TYPE_MSCHAPV2_SYMBIAN_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_protected_setup_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_protected_setup_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,337 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#if !defined(_EAP_AM_TYPE_PROTECTED_SETUP_SYMBIAN_H_) +#define _EAP_AM_TYPE_PROTECTED_SETUP_SYMBIAN_H_ + + +// INCLUDES + +#include +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_base_type.h" + +#include "abs_eap_am_type_simple_config.h" +#include "eap_am_type_simple_config.h" + +#include +#include "simple_config_payloads.h" +#include "eapol_key_types.h" +#include "eapol_rsna_key_header.h" + +#include "EapProtectedSetupInterface.h" +#include + +// FORWARD DECLARATIONS +class abs_eap_configuration_if_c; + +// CLASS DECLARATION + +/** +* Class that implements the operating system dependent portion of +* EAP Protected setup protocol for Symbian OS. +*/ + + +class EAP_EXPORT eap_am_type_protected_setup_symbian_c +: public eap_am_type_simple_config_c +{ +public: + + //-------------------------------------------------- + + EAP_FUNC_IMPORT static eap_am_type_protected_setup_symbian_c* NewL( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if); + + // + EAP_FUNC_IMPORT ~eap_am_type_protected_setup_symbian_c(); + + EAP_FUNC_IMPORT void set_is_valid(); + + /** From the parent eap_am_type_simple_config_c **/ + + /** Function sets partner object of adaptation module of EAP-SIMPLE_CONFIG. + * Partner object is the EAP-SIMPLE_CONFIG object. + */ + EAP_FUNC_IMPORT void set_am_partner(abs_eap_am_type_simple_config_c * const partner); + + EAP_FUNC_IMPORT eap_status_e configure(); + + /** + * The shutdown() function is called before the destructor of the + * object is executed. During the function call the object + * could shutdown the operations, for example cancel timers. + * Each derived class must define this function. + */ + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT bool get_is_valid(); + + /** Client calls this function. + * EAP-SIMPLE_CONFIG AM could do finishing operations to databases etc. based on authentication status and type. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + /** Client calls this function. + * EAP-SIMPLE_CONFIG AM could make some fast operations here, heavy operations should be done in the reset() function. + */ + EAP_FUNC_IMPORT eap_status_e authentication_finished( + const bool true_when_successfull, + const bool true_when_session_resumed); + + /** Client calls this function. + * AM must copy identity to output parameters if call is syncronous. + * This function could be completed asyncronously with abs_eap_am_type_simple_config_c::complete_query_eap_identity_query() function call. + */ + EAP_FUNC_IMPORT eap_status_e query_eap_identity( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + bool * const use_manual_username, + eap_variable_data_c * const manual_username, + bool *const use_manual_realm, + eap_variable_data_c * const manual_realm + ); + + /** + * Cancels the outstanding indentity query. + */ + EAP_FUNC_IMPORT eap_status_e cancel_identity_query(); + + /** + * The type_configure_read() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /** + * The type_configure_write() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param field_length is length of the field string. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /** + * The load_module() function function indicates the lower level to + * load new module of EAP-type. + * @param type is the requested EAP-type. + * @param partner is pointer to the caller object. + * The partner of the new created EAP-type object is the caller object. + * @param eap_type is a pointer to a pointer of EAP-type object. + * Adaptation module sets eap_type pointer to created EAP-type object. + * @param is_client_when_true parameter indicates whether the network entity should + * act as a client (true) or server (false), in terms of EAP-protocol whether + * this network entity is EAP-supplicant (true) or EAP-authenticator (false). + */ + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + /** + * This is needed by PEAP type. + * This function queries the validity of EAP-type. + * Lower layer should return eap_status_ok if this EAP-type is supported. + */ + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + /** + * This function queries the list of supported EAP-types. + * Lower layer should return eap_status_ok if this call succeeds. + * @param eap_type_list will include the list of supported EAP-types. Each value in list + * is type of u32_t and represent one supported EAP-type. List consists of subsequent u32_t type values. + */ + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + /** + * This is needed by PEAP type. + * The unload_module() function unloads the module of a EAP-type. + * @param type is the requested EAP-type. + */ + EAP_FUNC_IMPORT eap_status_e unload_module(const eap_type_value_e type); + + + /** From simple_config_am_services_c through the parent eap_am_type_simple_config_c **/ + + /// This function sets pointer to adaptation module of SIMPLE_CONFIG. See abs_simple_config_am_services_c. + EAP_FUNC_IMPORT void set_simple_config_am_partner(abs_simple_config_am_services_c * const simple_config_am_partner); + + /** + * This function queries all network and device parameters. + * abs_simple_config_am_services_c::complete_query_network_and_device_parameters() completes this query. + */ + EAP_FUNC_IMPORT eap_status_e query_network_and_device_parameters( + const simple_config_state_e state); + + /** + * This function tells AM to save SIMPLE_CONFIG configuration parameters. + * This is always syncronous call. + */ + EAP_FUNC_IMPORT eap_status_e save_simple_config_session( + const simple_config_state_e state, + EAP_TEMPLATE_CONST eap_array_c * const credential_array, + const eap_variable_data_c * const new_password, + const simple_config_Device_Password_ID_e Device_Password_ID, + const simple_config_payloads_c * const other_configuration + ); + + /** + * This function forwards all payloads received in M2D messages. + * Adaptation layer could show this information to user. + * This is always syncronous call. + */ + EAP_FUNC_IMPORT eap_status_e received_registrar_information( + EAP_TEMPLATE_CONST eap_array_c * const M2D_payloads); + + /** + * This function cancels query_network_and_device_parameters() query. + * After this call AM MUST NOT complete related query. + */ + EAP_FUNC_IMPORT eap_status_e cancel_query_network_and_device_parameters(); + + + /** Own Public functions **/ + + EAP_FUNC_IMPORT eap_status_e complete_protected_setup_device_paramsL( + const RMobilePhone::TMobilePhoneIdentityV1 &phone_identity, + const eap_status_e completion_status); + + //-------------------------------------------------- + +protected: + + //-------------------------------------------------- + + eap_am_type_protected_setup_symbian_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if); + + void ConstructL(); + + //-------------------------------------------------- + +private: + + abs_simple_config_am_services_c * get_simple_config_am_partner(); + + abs_eap_am_type_simple_config_c * get_am_partner(); + + void send_error_notification(const eap_status_e error); + + void read_device_passwordL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data); + + void ConvertUnicodeToAsciiL(const TDesC16& aFromUnicode, TDes8& aToAscii); + + //-------------------------------------------------- + +private: + + //-------------------------------------------------- + + abs_eap_base_type_c *m_partner; + + TInt m_index; + + abs_eap_am_tools_c *m_am_tools; + + abs_eap_am_type_simple_config_c *m_am_partner; + + abs_simple_config_am_services_c * m_simple_config_am_partner; + + abs_eap_configuration_if_c * const m_configuration_if; + + bool m_device_parameters_valid; + simple_config_payloads_c m_network_and_device_parameters; + + eap_variable_data_c m_UUID_E; + + simple_config_Device_Password_ID_e m_Device_Password_ID; + + eap_am_network_id_c m_receive_network_id; + + u8_t m_eap_identifier; + + eap_type_value_e m_eap_type; + + simple_config_state_e m_simple_config_state; + + bool m_is_valid; + bool m_is_client; + + bool m_shutdown_was_called; + + eap_variable_data_c m_manual_username; + + eap_variable_data_c m_manual_realm; + + /// This flag allows use of manually configured username in EAP-Identity/Response. + bool m_use_manual_username; + + /// This flag allows use of manually configured realm in EAP-Identity/Response. + bool m_use_manual_realm; + + /// This flag prevents double configuration. This can happen when + /// this class implements many interfaces. + bool m_configured; + + // This is the connection to the MMETEL interface from here. + CEapProtectedSetupInterface* m_prot_setup_if; + + //----------------------------------------------------------------- + +}; // class eap_am_type_protected_setup_symbian_c + + +#endif //#if !defined(_EAP_AM_TYPE_PROTECTED_SETUP_SYMBIAN_H_) + +//-------------------------------------------------- + +// End of file. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_securid_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_securid_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,209 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAP_AM_TYPE_SECURID_SYMBIAN_H +#define EAP_AM_TYPE_SECURID_SYMBIAN_H + +// INCLUDES +#include "eap_am_tools.h" +#include "abs_eap_base_type.h" +#include "eap_am_type_securid.h" +#include "eap_am_network_id.h" +#include "EapSecurIDNotifierStructs.h" +#include +#include + +const TUint KDefaultTimeoutEAPSecurId = 120000; + +/** +* Class that implements the operating system dependent portion of EAP SecurID protocol. +* For Symbian OS. +*/ +class EAP_EXPORT eap_am_type_securid_symbian_c + : public CActive, public eap_am_type_securid_c +{ +private: + + RDbs m_session; + + RDbNamedDatabase m_database; + + enum TState + { + EHandlingIdentityQuery, + EHandlingPasscodeQuery, + EHandlingPincodeQuery, + EHandlingGTCQuery + }; + + TState m_state; + + RNotifier m_notifier; + + TEapSecurIDStruct * m_dialog_data_ptr; + TPckg * m_dialog_data_pckg_ptr; + + abs_eap_am_tools_c * const m_am_tools; + + abs_eap_base_type_c * const m_partner; + + eap_am_network_id_c m_receive_network_id; + + TIndexType m_index_type; + + TInt m_index; + + eap_type_value_e m_tunneling_type; + + bool m_is_client; + + bool m_is_valid; + + bool m_shutdown_was_called; + + eap_type_value_e m_eap_type; + + HBufC8* m_message_buf; + + bool m_is_notifier_connected; // Tells if notifier server is connected. + + // This holds the max session time read from the configuration file. + TInt64 m_max_session_time; + + // This is the vendor-type for tunneling EAP type. + // Valid for both expanded and non-expanded EAP types. + // This is used since m_tunneling_type can not be used in the same way + // in expanded and non-expanded cases. + // Unlike EAP type, Tunneling type is still non-expanded + // for both cases especially for using in the EAP databases. + u32_t m_tunneling_vendor_type; + + u32_t m_eap_vendor_type; // This is needed in certain cases. + + void send_error_notification(const eap_status_e error); + + bool is_session_validL(); + +protected: + + eap_am_type_securid_symbian_c( + abs_eap_am_tools_c * const m_am_tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + + void ConstructL(); + + void RunL(); + + void DoCancel(); + + void type_configure_readL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data); + + /** + * Stores current universal time as the the full authentication time + * in the database. Leaves if storing fails. + */ + void store_authentication_timeL(); + +public: + + static eap_am_type_securid_symbian_c* NewL( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT virtual ~eap_am_type_securid_symbian_c(); + + eap_status_e show_identity_query_dialog( + eap_type_value_e eap_type, + eap_variable_data_c * const identity); + + eap_status_e show_passcode_query_dialog( + eap_variable_data_c * const passcode, + bool is_first_query); + + eap_status_e show_pincode_query_dialog( + eap_variable_data_c * const passcode, + eap_variable_data_c * const pincode, + bool is_first_query); + + eap_status_e show_gtc_query_dialog( + eap_variable_data_c * const passcode, + const u8_t * const message, + u32_t message_length, + bool is_first_query); + + EAP_FUNC_IMPORT eap_status_e configure(); + + EAP_FUNC_IMPORT eap_status_e reset(); + + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT eap_status_e read_auth_failure_string( + eap_variable_data_c * const string); + + EAP_FUNC_IMPORT eap_status_e get_memory_store_key( + eap_variable_data_c * const memory_store_key); + + /** + * Returns true if the full authenticated session is valid. + * It finds the difference between current time and the + * last full authentication time. If the difference is less than the + * Maximum Session Validity Time, then session is valid, returns true. + * Otherwise returns false. + * Full authentication (using pw query) should be done if the session is not valid. + */ + bool is_session_valid(); + + /** + * Stores current universal time as the the full authentication time + * in the database by calling the leaving function store_authentication_time_L. + * Returns appropriate error if storing fails. eap_status_ok for successful storing. + */ + eap_status_e store_authentication_time(); + +}; // class eap_am_type_securid_symbian_c + + +#endif // EAP_AM_TYPE_SECURID_SYMBIAN_H diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_sim_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_sim_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,100 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_TYPE_SIM_SYMBIAN_H_) +#define _EAP_AM_TYPE_SIM_SYMBIAN_H_ + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eap_base_type.h" +#include "eap_am_type_sim.h" + +// +class EAP_EXPORT eap_am_type_sim_simulator_c +: public eap_am_type_sim_c +{ +private: + //-------------------------------------------------- + + abs_eap_am_tools_c * const m_am_tools; + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~eap_am_type_sim_simulator_c(); + + // + EAP_FUNC_IMPORT eap_am_type_sim_simulator_c( + abs_eap_am_tools_c * const m_am_tools, abs_eap_am_type_sim_c * const partner); + + // + EAP_FUNC_IMPORT eap_status_e query_SIM_imsi( + u8_t * const imsi, const u32_t max_length, u32_t * const imsi_length); + + // + EAP_FUNC_IMPORT eap_status_e query_SIM_kc_and_sres( + const u8_t * const imsi, const u32_t imsi_length, + const u8_t * const rand, const u32_t rand_length, + u8_t * const kc, u32_t * const kc_length, + u8_t * const sres, u32_t * const sres_length); + + // + EAP_FUNC_IMPORT eap_status_e query_SIM_triplets( + //const eap_state_selector_c * const state_selector, + const eap_variable_data_c * const imsi, + eap_type_sim_triplet_array_c * const triplets); + + // + EAP_FUNC_IMPORT eap_status_e query_SIM_kc_sres( + //const eap_state_selector_c * const state_selector, + const eap_variable_data_c * const n_rands, + eap_variable_data_c * const n_kc, + eap_variable_data_c * const n_sres); + + //-------------------------------------------------- +}; // class eap_am_type_sim_simulator_c + + +/** @file */ + +/** + * This function creates a new instance of adaptation module of simple SIM EAP-type. + * @param tools is pointer to the abs_eap_am_tools class created by the adaptation module. + * @param partner is pointer to the caller of the new_eap_am_type_sim(). + * Simple SIM EAP-type will callback caller using the partner pointer. + */ +EAP_C_FUNC_IMPORT eap_am_type_sim_c *new_eap_am_type_sim( + abs_eap_am_tools_c * const tools, + abs_eap_am_type_sim_c * const partner); + + +#endif //#if !defined(_EAP_AM_TYPE_SIM_SYMBIAN_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_tls_peap_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eap_am_type_tls_peap_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1028 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_TYPE_TLS_PEAP_SYMBIAN_H_) +#define _EAP_AM_TYPE_TLS_PEAP_SYMBIAN_H_ + +#include "eap_tools.h" +#include "eap_variable_data.h" +#include "eap_am_export.h" +#include "abs_eap_am_type_tls_peap.h" +#include "eap_am_type_tls_peap.h" +#include "eap_am_network_id.h" +#include +#include +#include +#include +#include +#include "EapTlsPeapNotifierStructs.h" +#include "EapTlsPeapUtils.h" +#include + +#if defined(USE_FAST_EAP_TYPE) +#include "EapFastNotifierStruct.h" +#include +#endif + +#include "EapTtlsPapDbInfoStruct.h" + +class CX509Certificate; +class CEapTlsPeapCertInterface; +class eap_am_tools_symbian_c; +class abs_tls_am_application_eap_fast_c; +#if defined(USE_FAST_EAP_TYPE) +class CEapFastActive; +#endif +class CEapTtlsPapActive; + +#ifdef USE_PAC_STORE +class CPacStoreDatabase; +struct SInfoEntry; +#endif +#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) +class eap_file_config_c; +#endif + +const TInt KMaxLabelLength = 64; +const TInt KMaxDatabaseTableName = 64; + +#if defined(USE_FAST_EAP_TYPE) +const char KEapFastPacProvisResultKey[] = "eap_am_type_tls_peap_symbian_c prov. result"; +const TInt KEapFastPacProvisResultType = 1; +const u32_t KEapFastPacProvisResultDefaultTimeout = 10000; // in milliseconds = 10 seconds +#endif + +/// This class is interface to adaptation module of EAP/TLS and PEAP. +class EAP_EXPORT eap_am_type_tls_peap_symbian_c +: public CActive, public eap_am_type_tls_peap_c +,public abs_eap_base_timer_c +{ + +public: + +#if defined(USE_FAST_EAP_TYPE) + enum TEapFastPacProvisResultValue + { + EEapFastPacProvisResultFailure, /* 0 */ + EEapFastPacProvisResultSuccess /* 1 */ + }; +#endif +private: // data +//-------------------------------------------------- + + RDbs m_session; + + RDbNamedDatabase m_database; + + enum TState + { + EHandlingIdentityQuery, /* 0 */ + EHandlingManualIdentityQuery, /* 1 */ + EHandlingChainQuery, /* 2 */ + EHandlingCipherSuiteQuery, /* 3 */ +#if defined(USE_FAST_EAP_TYPE) /* 4 */ + EHandlingNotifierQuery, /* 5 */ + EPasswordQuery, /* 6 */ + EWrongPassword, /* 7 */ + EFilePasswordQuery, /* 8 */ + EMasterkeyQuery, /* 9 */ + EPasswordCancel, /* 10 */ + EShowProvSuccesstNote, /* 11 */ + EShowProvNotSuccesstNote, /* 12 */ + ENone /* 13 */ +#endif //#if defined(USE_FAST_EAP_TYPE) + + }; + + TState m_state; + TState m_prev_state; + + TIndexType m_index_type; + + TInt m_index; + + eap_type_value_e m_tunneling_type; + + abs_eap_base_type_c *m_partner; + eap_am_tools_symbian_c *m_am_tools; + + abs_eap_am_type_tls_peap_c *m_am_partner; + + abs_tls_am_services_c * m_tls_am_partner; + +#if defined(USE_FAST_EAP_TYPE) + abs_tls_am_application_eap_fast_c * m_tls_application; + CEapFastActive* iEapFastActiveWaitNote; + CEapFastActive* iEapFastActiveNotes; + + enum TAlterTableCmd + { + EAddColumn, + ERemoveColumn + }; + +#endif //#if defined(USE_FAST_EAP_TYPE) + + bool m_is_valid; + bool m_is_client; + + eap_type_value_e m_current_eap_type; + + // These are the vendor-types for EAP type and tunneling EAP type. + // Valid for both expanded and non-expanded EAP types. + u32_t m_current_eap_vendor_type; + u32_t m_tunneling_vendor_type; + + TBufC m_db_table_name; + TBufC m_db_user_cert_table_name; + TBufC m_db_ca_cert_table_name; + TBufC m_db_cipher_suite_table_name; + TBufC m_db_name; + +#if defined (USE_FAST_EAP_TYPE) +TBufC m_db_fast_special_table_name; +RArray m_info_array; +#endif + + u32_t m_max_count_of_session_resumes; + + tls_cipher_suites_e m_cipher_suite; + + CX509Certificate* m_ca_certificate; + + CX509Certificate* m_own_certificate; + + CX509Certificate* m_peer_certificate; + + CEapTlsPeapCertInterface* m_cert_if; + + SCertEntry m_own_certificate_info; + + eap_am_network_id_c m_receive_network_id; + + u8_t m_eap_identifier; + + TKeyIdentifier m_subject_key_id; + + RArray m_allowed_ca_certs; + + RArray m_allowed_user_certs; + + RArray m_allowed_server_certs; + + RArray m_allowed_cipher_suites; + + eap_variable_data_c m_peer_public_key; + + eap_variable_data_c m_param_p; + eap_variable_data_c m_param_q; + eap_variable_data_c m_param_g; + + bool m_shutdown_was_called; + +#ifdef USE_EAP_EXPANDED_TYPES + + /// Tunneling EAP configuration data from EAP database. + RExpandedEapTypePtrArray m_enabled_tunneling_exp_eap_array; + RExpandedEapTypePtrArray m_disabled_tunneling_exp_eap_array; + +#else + + /// Tunneling EAP configuration data from EAP database. + TEapArray m_iap_eap_array; + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + TIdentityInfo* m_identity_info; + + TBuf8<4> m_selector_output; + + eap_type_value_e m_tunneled_type; + + bool m_verify_certificate_realm; + + bool m_allow_subdomain_matching; + + tls_alert_description_e m_latest_alert_description; + + bool m_use_manual_username; + eap_variable_data_c m_manual_username; + + bool m_use_manual_realm; + eap_variable_data_c m_manual_realm; + + bool m_tls_peap_server_authenticates_client_policy_flag; + + /// This flag prevents double configuration. This can happen when + /// this class implements many interfaces. + bool m_configured; + + // This holds the max session time read from the configuration file. + TInt64 m_max_session_time; + +#if defined(USE_EAP_TLS_SESSION_TICKET) + /// This flag allows use of session ticket, see RFC 4507. + bool m_use_session_ticket; +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + +#if defined(USE_FAST_EAP_TYPE) + tls_extension_c * m_received_tunnel_pac_in_session_ticket; + tls_extension_c * m_received_user_authorization_pac_in_session_ticket; + eap_fast_pac_type_e m_saved_pac_type; + eap_fast_completion_operation_e m_completion_operation; + eap_status_e m_verification_status; + eap_fast_pac_type_e m_pac_type; + eap_variable_data_c m_PAC_store_password; + eap_variable_data_c m_imported_PAC_data_password; + eap_variable_data_c m_PAC_store_path; + eap_variable_data_c m_EAP_FAST_IAP_reference; + eap_variable_data_c m_EAP_FAST_Group_reference; + eap_variable_data_c m_EAP_FAST_import_path; + + eap_status_e m_eap_fast_completion_status; + eap_fast_pac_store_pending_operation_e m_eap_fast_pac_store_pending_operation; + eap_array_c m_references_and_data_blocks; + eap_array_c m_new_references_and_data_blocks; + eap_array_c m_ready_references_and_data_blocks; + + bool m_serv_unauth_prov_mode; + bool m_serv_auth_prov_mode; + + // For FAST notifiers + RNotifier m_notifier; + bool m_is_notifier_connected; // Tells if notifier server is connected. + + TEapFastNotifierStruct * m_notifier_data_to_user; + TPckg * m_notifier_data_pckg_to_user; + + TEapFastNotifierStruct * m_notifier_data_from_user; + TPckg * m_notifier_data_pckg_from_user; + + /* For MMETEL */ + + // ETel connection. + RTelServer iServer; + RMobilePhone iPhone; + + // Stores the last queried Phone identities like manufacturer, model, + // revision and serial number + RMobilePhone::TMobilePhoneIdentityV1 iDeviceId; + + // Tells if MMETEL is connected already or not. + TBool iMMETELConnectionStatus; + TBool m_completed_with_zero; + TBool m_verificationStatus; + + HBufC8* m_pacStorePWBuf8; + EEapFastNotifierUserAction m_userAction; + eap_pac_store_data_type_e m_pacStoreDataRefType; + eap_fast_pac_store_data_c m_data_reference; + TBool m_notifier_complete; + eap_variable_data_c m_userResponse; + eap_fast_pac_store_pending_operation_e m_pending_operation; + TInt m_both_completed; + TInt m_both_asked; + TUint m_ready_references_array_index; + eap_fast_completion_operation_e m_provisioning_mode; + + /** + * This member is used to store completion operation value + * in initialize_PAC_store() call from common side. + * The value is given later in complete call. + */ + eap_fast_completion_operation_e iCompletionOperation; + /** + * This member is used to store initialize-pac-store-completion value + * in initialize_PAC_store() call from common side. + * The value is given later in complete call. + */ + eap_fast_initialize_pac_store_completion_e iCompletion; + +#endif //#if defined(USE_FAST_EAP_TYPE) + +#ifdef USE_PAC_STORE + CPacStoreDatabase * iPacStoreDb; +#endif + +#ifdef USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS + TBool m_skip_user_interactions; + /// This is object to handle file configuration. + eap_file_config_c * m_fileconfig; +#endif + + + + /** + * Maximum TTLS-PAP session time read from the configuration file. + */ + TInt64 iEapTtlsPapMaxSessionConfigTime; + + /** + * Provides asynch services used by the caller such as + * query for TTLS-PAP user name and password. + */ + CEapTtlsPapActive* iEapTtlsPapActive; + + +//-------------------------------------------------- +private: // methods +//-------------------------------------------------- + + + EAP_FUNC_IMPORT abs_tls_am_services_c * get_tls_am_partner(); + + abs_eap_am_type_tls_peap_c * get_am_partner(); + + void type_configure_readL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data); + + void verify_certificate_chainL( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain, + const tls_cipher_suites_e required_cipher_suite); + + void WriteBinaryParamL( + eap_config_string field, + const u32_t field_length, + const eap_variable_data_c * const data); + + void WriteIntParamL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data); + + void WriteIntParamL( + eap_config_string field, + const u32_t field_length, + const u32_t value); + + void get_identity_from_alternative_nameL( + const CX509Certificate * const aCertificate, + eap_variable_data_c * const aIdentity); + + void get_identities_from_distinguished_namesL( + const CX509Certificate * const aCertificate, + eap_variable_data_c * const aSubjectIdentity, + eap_variable_data_c * const aIssuerIdentity); + + eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + eap_status_e unload_module(const eap_type_value_e type); + + void complete_signL(const RInteger& aR, const RInteger& aS, eap_status_e aStatus); + + eap_status_e get_realms_from_certificate( + CX509Certificate* certificate, + eap_variable_data_c * const subject_realm, + eap_variable_data_c * const issuer_realm); + + void authentication_finishedL( + const bool true_when_successful, + const tls_session_type_e tls_session_type); + + void read_dsa_parametersL(); + + eap_status_e SaveManualIdentityL( + const TBool use_manual_username, + TDesC& manual_username, + const TBool use_manual_realm, + TDesC& manual_realm); + + void send_error_notification(const eap_status_e error); + + eap_status_e show_certificate_selection_dialog(); + + eap_status_e show_manual_identity_dialog(); + + void ResetSessionIdL(); + + /** + * Returns true if the full authenticated session is valid. + * It finds the difference between current time and the + * last full authentication time. If the difference is less than the + * Maximum Session Validity Time, then session is valid, returns true. + * Otherwise returns false. + * Full authentication should be done if the session is not valid. + */ + bool is_session_validL(); + + /** + * Stores current universal time as the the full authentication time + * in the database. Returns KErrNone if storing succeeds. + */ + void store_authentication_timeL(); + +#ifdef USE_PAC_STORE + + void GetPacStoreDbDataL( + const eap_pac_store_data_type_e aPacStoreDataType, + eap_variable_data_c * aPacStoreData, + const eap_variable_data_c * const aPacStoreReference = NULL); + +#endif // End: #ifdef USE_PAC_STORE + +#if defined(USE_FAST_EAP_TYPE) + + void ReadPACStoredataL( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references); + + void WritePACStoreDataL( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references_and_data_blocks); + + eap_status_e ShowNotifierItemAndGetResponse( + EEapFastNotifierUiItem aNotifierUiItem, TBool aSetActive ); + + eap_status_e RemoveIAPReference(); + + eap_status_e ImportFilesL(); + + eap_status_e PasswordQueryL(); + + eap_status_e CompletePasswordQueryL(); + + eap_status_e CompleteFilePasswordQueryL(); + + eap_status_e CompleteNotifierL(); + + eap_status_e CompleteFilePasswordQuery(); + + eap_status_e FinalCompleteReadPACStoreDataL(eap_status_e status); + + void ConvertUnicodeToAsciiL(const TDesC16& aFromUnicode, TDes8& aToAscii); + + void UpdatePasswordTimeL(); + + void CheckPasswordTimeValidityL(); + + /** + * Alter table: remove/add columns. + * + * @param aDb Reference to database. + * @param aCmd Action type: remove/add column. + * @param aTableName Name of table to be altered. + * @param aColumnName Name of column. + * @param aColumnDef Drop-column-set. + */ + void AlterTableL( RDbNamedDatabase& aDb, + TAlterTableCmd aCmd, + const TDesC& aTableName, + const TDesC& aColumnName, + const TDesC& aColumnDef = KNullDesC ); + + /** + * Fix old tables for password identity time. + * + * Remove password identity time from fast table; + * add password identity time to PAC store table; + * update password identity time. + */ + void FixOldTablesForPwdIdentityTimeL(); + + /** + * Add PAC_store_initialized to PAC store + * if it does not exists. + */ + void FixOldTableForPacStoreInitL(); + + /** + * Read integer column value. + * + * @param aDb Reference to database. + * @param aColumnName Name of the target column. + * @param aSqlStatement SQL statement to be used. + * @return Column value. + **/ + TInt64 ReadIntDbValueL( RDbNamedDatabase& aDb, + const TDesC& aColumnName, + const TDesC& aSqlStatement ); + + eap_status_e ConfigureL(); + + eap_status_e CreateMasterkeyL(); + + eap_status_e QueryUserPermissionForAIDL( + const eap_fast_variable_data_c * const in_pac_attribute_A_ID_info, + const eap_fast_variable_data_c * const in_pac_attribute_A_ID); + + void CompleteAddImportedPACFileL( + const eap_variable_data_c * const in_imported_PAC_filename, + const eap_variable_data_c * const out_used_group_reference); + +#endif //#if defined(USE_FAST_EAP_TYPE) + + + + /** + * Check whether password is older than allowed + * by max TTLS-PAP session timeout. + * + * @return ETrue - session is valid, EFalse - otherwise. + */ + TBool IsTtlsPapSessionValidL(); + + + /** + * Check TTLS-PAP session validity. + * + * @return ETrue if currentTime < aInLastFullAuthTime + aInMaxSessionTime, + * EFalse - otherwise. + */ + TBool CheckTtlsPapSessionValidity( + const TInt64& aInMaxSessionTime, + const TInt64& aInLastFullAuthTime ); + + +//-------------------------------------------------- +protected: // methods +//-------------------------------------------------- + + + eap_am_type_tls_peap_symbian_c( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + + void ConstructL(); + + void RunL(); + + void DoCancel(); + + +//-------------------------------------------------- +public: // methods +//-------------------------------------------------- + + // + static eap_am_type_tls_peap_symbian_c* NewL( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT virtual ~eap_am_type_tls_peap_symbian_c(); + + EAP_FUNC_EXPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT void set_is_valid(); + + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT void set_tls_am_partner(abs_tls_am_services_c * const tls_am_partner); + +#if defined(USE_FAST_EAP_TYPE) + /// This function sets pointer to application of TLS. See abs_tls_am_application_eap_fast_c. + EAP_FUNC_IMPORT void set_tls_application(abs_tls_am_application_eap_fast_c * const tls_application); + + + /** + * Check provisioning mode. + * + * @return ETrue - authenticated provisioning mode, + * EFalse - unauthenticated provisioning mode. + */ + TBool IsProvisioningMode(); + + /** + * Send error notification to common side. + * + * @param aUserAction EEapFastNotifierUserActionOk or + * EEapFastNotifierUserActionCancel. + * @return EAP status. + */ + eap_status_e CompleteQueryUserPermissionForAid( + EEapFastNotifierUserAction aUserAction ); + + + void ContinueInitializePacStore(); + + +#endif //#if defined(USE_FAST_EAP_TYPE) + + /** + * Send error notification to common side. + * + * @param aError EAP status. + */ + void SendErrorNotification( const eap_status_e aError ); + + EAP_FUNC_IMPORT void notify_configuration_error( + const eap_status_e configuration_status); + + EAP_FUNC_IMPORT eap_status_e configure(); + + void set_am_partner(abs_eap_am_type_tls_peap_c * const partner); + + /** Client calls this function. + * EAP-TLS/PEAP AM could do finishing operations to databases etc. based on authentication status and type. + */ + EAP_FUNC_IMPORT eap_status_e reset(); + + /** Client calls this function. + * EAP-TLS/PEAP AM could make some fast operations here, heavy operations should be done in the reset() function. + */ + EAP_FUNC_IMPORT eap_status_e authentication_finished( + const bool true_when_successfull, + const tls_session_type_e tls_session_type); + + /** Client calls this function. + * AM must copy identity to output parameters if call is syncronous. + * This function could be completed asyncronously with abs_eap_am_type_tls_peap_c::complete_query_eap_identity_query() function call. + */ + EAP_FUNC_IMPORT eap_status_e query_eap_identity( + eap_variable_data_c * const identity, + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + bool * const use_manual_username, + eap_variable_data_c * const manual_username, + bool *const use_manual_realm, + eap_variable_data_c * const manual_realm); + + /** Client calls this function. + * This call cancels asyncronous query_SIM_IMSI_or_pseudonym_or_reauthentication_id() function call. + * AM must not complete query_SIM_IMSI_or_pseudonym_or_reauthentication_id() + * with abs_eap_am_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() after + * cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. + */ + EAP_FUNC_IMPORT eap_status_e cancel_identity_query(); + + // + EAP_FUNC_IMPORT eap_status_e timer_expired( + const u32_t id, void *data); + + // + EAP_FUNC_IMPORT eap_status_e timer_delete_data( + const u32_t id, void *data); + + /** + * The type_configure_read() function reads the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the query to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT eap_status_e type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + /** + * The type_configure_write() function writes the configuration data identified + * by the field string of field_length bytes length. Adaptation module must direct + * the action to some persistent store. + * @param field is generic configure string idenfying the required configure data. + * @param data is pointer to existing eap_variable_data object. + */ + EAP_FUNC_IMPORT eap_status_e type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e alert_received( + const tls_alert_level_e alert_level, + const tls_alert_description_e alert_description); + + EAP_FUNC_IMPORT eap_status_e query_cipher_suites_and_previous_session(); + +#if defined(USE_EAP_TLS_SESSION_TICKET) + EAP_FUNC_IMPORT eap_status_e query_new_session_ticket(); +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + + EAP_FUNC_IMPORT eap_status_e select_cipher_suite_and_check_session_id( + EAP_TEMPLATE_CONST eap_array_c * const cipher_suite_proposal, + const eap_variable_data_c * const session_id +#if defined(USE_EAP_TLS_SESSION_TICKET) + , const tls_extension_c * const session_ticket +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + ); + + + EAP_FUNC_IMPORT eap_status_e verify_certificate_chain( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain, + const tls_cipher_suites_e required_cipher_suite); + + EAP_FUNC_IMPORT eap_status_e query_certificate_chain( + EAP_TEMPLATE_CONST eap_array_c * const certificate_authorities, + EAP_TEMPLATE_CONST eap_array_c * const certificate_types, + const tls_cipher_suites_e required_cipher_suite); + + EAP_FUNC_IMPORT eap_status_e query_certificate_authorities_and_types(); + + EAP_FUNC_IMPORT eap_status_e query_dh_parameters( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain, + const tls_cipher_suites_e required_cipher_suite); + + EAP_FUNC_IMPORT eap_status_e query_realm( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain); + + // This is always syncronous call. + EAP_FUNC_IMPORT eap_status_e save_tls_session( + const eap_variable_data_c * const session_id, + const eap_variable_data_c * const master_secret, + const tls_cipher_suites_e used_cipher_suite +#if defined(USE_EAP_TLS_SESSION_TICKET) + , const tls_extension_c * const new_session_ticket +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + ); + + /// This is always syncronous call. + /// Function encrypts data with own RSA private key. + EAP_FUNC_IMPORT eap_status_e rsa_encrypt_with_public_key( + const eap_variable_data_c * const premaster_secret); + + /// This is always syncronous call. + /// Function decrypts data with own RSA private key. + EAP_FUNC_IMPORT eap_status_e rsa_decrypt_with_private_key( + const eap_variable_data_c * const encrypted_premaster_secret); + + /// Function signs data with own PKI private key. + /// NOTE this is syncronous at moment. Asyncronous completion needs many changes. + EAP_FUNC_IMPORT eap_status_e sign_with_private_key( + const eap_variable_data_c * const message_hash); + + /// Function verifies signed data with peer PKI public key. + /// NOTE this is syncronous at moment. Asyncronous completion needs many changes. + EAP_FUNC_IMPORT eap_status_e verify_with_public_key( + const eap_variable_data_c * const message_hash, + const eap_variable_data_c * const signed_message_hash); + + + EAP_FUNC_IMPORT eap_status_e cancel_query_cipher_suites_and_previous_session(); + + EAP_FUNC_IMPORT eap_status_e cancel_select_cipher_suite_and_check_session_id(); + + EAP_FUNC_IMPORT eap_status_e cancel_verify_certificate_chain(); + + EAP_FUNC_IMPORT eap_status_e cancel_query_certificate_chain(); + + EAP_FUNC_IMPORT eap_status_e cancel_query_certificate_authorities_and_types(); + + EAP_FUNC_IMPORT eap_status_e cancel_query_dh_parameters(); + + EAP_FUNC_IMPORT eap_status_e cancel_query_realm(); + + EAP_FUNC_IMPORT eap_status_e cancel_query_dsa_parameters(); + + EAP_FUNC_IMPORT eap_status_e cancel_rsa_encrypt_with_public_key(); + + EAP_FUNC_IMPORT eap_status_e cancel_rsa_decrypt_with_private_key(); + + EAP_FUNC_IMPORT eap_status_e cancel_sign_with_private_key(); + + EAP_FUNC_IMPORT eap_status_e cancel_verify_with_public_key(); + + + eap_status_e complete_read_own_certificate( + const RPointerArray& aCertChain, eap_status_e aStatus); + + eap_status_e complete_read_ca_certificate( + const RPointerArray& aCertChain, eap_status_e aStatus); + + void complete_validate_chain(CPKIXValidationResult& aValidationResult, eap_status_e aStatus); + + void complete_get_matching_certificates(CArrayFixFlat& aMatchingCerts, eap_status_e aStatus); + + void complete_sign(const RInteger& aR, const RInteger& aS, eap_status_e aStatus); + + void complete_decrypt(TDes8& aData, eap_status_e aStatus); + + /** + * Returns true if the full authenticated session is valid. + * It finds the difference between current time and the + * last full authentication time. If the difference is less than the + * Maximum Session Validity Time, then session is valid, returns true. + * Otherwise returns false. + * Full authentication should be done if the session is not valid. + */ + bool is_session_valid(); + + EAP_FUNC_IMPORT void set_peap_version( + const peap_version_e peap_version, + const bool use_tppd_tls_peap, + const bool use_tppd_peapv1_acknowledge_hack); + +#if defined(USE_FAST_EAP_TYPE) + + // This is commented in tls_am_application_eap_fast_c::read_authority_identity(). + // Parameter is the authority identity (A-ID). + EAP_FUNC_IMPORT eap_status_e read_authority_identity(eap_variable_data_c * const authority_identity); + + // This is commented in tls_am_application_eap_fast_c::query_pac_of_type(). + EAP_FUNC_IMPORT eap_status_e query_pac_of_type(const eap_fast_pac_type_e pac_type); + +#if defined(USE_EAP_CORE_SERVER) + /** + * This function call is always asyncronous. + * It will be completed always with complete_verify_pac() function call. + * Function verifies the received PAC is valid. + */ + EAP_FUNC_IMPORT eap_status_e verify_pac(const eap_fast_variable_data_c * const tlv_pac); +#endif //#if defined(USE_EAP_CORE_SERVER) + + // This is commented in eap_am_fast_pac_store_services_c::query_user_permission_for_A_ID(). + EAP_FUNC_IMPORT eap_status_e query_user_permission_for_A_ID( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + const eap_fast_variable_data_c * const in_pac_attribute_A_ID_info, + const eap_fast_variable_data_c * const in_pac_attribute_A_ID); + + // This is commented in eap_am_fast_pac_store_services_c::read_PAC_store_data(). + EAP_FUNC_IMPORT eap_status_e read_PAC_store_data( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references); + + // This is commented in eap_am_fast_pac_store_services_c::write_PAC_store_data(). + EAP_FUNC_IMPORT eap_status_e write_PAC_store_data( + const bool when_true_must_be_synchronous_operation, + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references_and_data_blocks); + + // This is commented in eap_am_fast_pac_store_services_c::complete_add_imported_PAC_file(). + EAP_FUNC_IMPORT eap_status_e complete_add_imported_PAC_file( + const eap_status_e in_completion_status, + const eap_variable_data_c * const in_imported_PAC_filename, + const eap_variable_data_c * const out_used_group_reference); + + // This is commented in eap_am_fast_pac_store_services_c::complete_remove_PAC(). + EAP_FUNC_IMPORT eap_status_e complete_remove_PAC( + const eap_status_e completion_status, + const eap_variable_data_c * const out_used_group_reference); + + // This is commented in eap_am_fast_pac_store_services_c::complete_remove_IAP_reference(). + EAP_FUNC_IMPORT eap_status_e complete_remove_IAP_reference( + const eap_status_e completion_status); + + // This is commented in eap_am_fast_pac_store_services_c::cancel_PAC_store_operations(). + EAP_FUNC_IMPORT eap_status_e cancel_PAC_store_operations(); + + /** + * This function initializes PAC store. + * Imported PACs and other configuration can be done within this function call. + * If asyncronous operations are needed the operations must be completed + * by complete_initialize_PAC_store() function call. + */ + EAP_FUNC_IMPORT eap_status_e initialize_PAC_store( + const eap_fast_completion_operation_e aCompletionOperation, + const eap_fast_initialize_pac_store_completion_e aCompletion ); + + + /** + * Indicate provisioning start. + * + * Common side indicates that PAC provisioning started. + * Waiting note is displayed. + * + * @param provisioning_mode Authenticated or unauthenticated provisioning mode. + * @param pac_type PAC type provisioned by server. + */ + EAP_FUNC_IMPORT eap_status_e indicates_eap_fast_provisioning_starts( + const eap_fast_completion_operation_e provisioning_mode, + const eap_fast_pac_type_e pac_type ); + + /** + * Indicate provisioning end. + * + * Common side indicates that PAC provisioning ended. + * Waiting note is stopped. Provisioning result note is displayed. + * + * @param provisioning_successfull True if provisioning is successful, + * false - otherwise. + * @param provisioning_mode Authenticated or unauthenticated provisioning mode. + * @param pac_type PAC type provisioned by server. + */ + EAP_FUNC_IMPORT eap_status_e indicates_eap_fast_provisioning_ends( + const bool provisioning_successfull, + const eap_fast_completion_operation_e provisioning_mode, + const eap_fast_pac_type_e pac_type ); + +#endif //#if defined(USE_FAST_EAP_TYPE) + + + // from tls_am_services_c + + /** + * Check whether the PAP password is still valid or + * should we prompt user again to enter the password. + * @return True - password is valid, false - otherwise. + */ + EAP_FUNC_IMPORT bool is_ttls_pap_session_valid(); + + /** + * From interface tls_am_services_c. + * + * The interface is defined in common part. Request asynchronously + * user name and password for TTLS-PAP authentication. + * Complete request with abs_tls_am_services_c:: + * complete_query_ttls_pap_username_and_password( ... ). + * * + * @param aInSrvChallenge Server challenge. It could be empty. + * @return EAP status. + */ + EAP_FUNC_IMPORT eap_status_e query_ttls_pap_username_and_password( + const eap_variable_data_c * const aInSrvChallenge ); + + /** + * The method has empty implementation which is defined for + * compilation purpose. + */ + eap_status_e verify_ttls_pap_username_and_password( + const eap_variable_data_c * const aUserName, + const eap_variable_data_c * const aUserPassword); + + // new + + /** + * Complete asynch query for TTLS-PAP user name and password. + * + * @param aEapStatus Status of asynch. query completion. + * @param aUserName PAP user name. + * @param aPassword PAP password. + * @return EAP status. + */ + eap_status_e CompleteQueryTtlsPapUserNameAndPassword( + eap_status_e aEapStatus, + const TDesC8& aUserNameUtf8, + const TDesC8& aPasswordUtf8 ); + + /** + * Delegate the task to m_am_tools. + * + * @param aErr Symbian general error. + * @return Eapol error converted from aErr. + */ + eap_status_e ConvertAmErrorToEapolError( TInt aErr ); + + /** + * Read TTLS-PAP database. + * + * @param aOutDbInfo Reference to structure containing TTLS-PAP + * database information. + */ + void ReadTtlsPapDbL( TTtlsPapDbInfo& aOutDbInfo ); + + /** + * Update TTLS-PAP database. + * + * @param aInDbInfo Reference to structure containing TTLS-PAP + * database information. + */ + void WriteTtlsPapDbL( const TTtlsPapDbInfo& aInDbInfo ); + + /** + * Set value of specified column to NULL. + * + * @param aColName Reference to column name. + */ + void SetTtlsPapColumnToNullL( const TDesC& aColName ); + +#if defined(USE_FAST_EAP_TYPE) +#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) + eap_status_e ReadFileConfig(); +#endif +#endif +}; // class eap_am_type_tls_peap_symbian_c + + +#endif //#if !defined(_EAP_AM_TYPE_TLS_PEAP_SYMBIAN_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eapol_am_core_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eapol_am_core_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,379 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined(_EAPOL_AM_CORE_SYMBIAN_H_) +#define _EAPOL_AM_CORE_SYMBIAN_H_ + +// INCLUDES +#include +#include // For MWlanMgmtPacket + +#include + +#include "abs_ethernet_core.h" +#include "eapol_key_types.h" +#include // For TIndexType +//#include "EapolTimer.h" + +#include + +// FORWARD DECLARATIONS +class MEapolToWlmIf; +class CEapType; +class ethernet_core_c; +class eap_am_tools_symbian_c; +class eap_file_config_c; + +const TInt KMaxWPAPSKPasswordLength = 64; +const TInt KWPAPSKLength = 32; + +// CLASS DECLARATION +class eapol_am_core_symbian_c +: public CActive, public abs_ethernet_core_c, + public abs_eap_base_timer_c + +{ +public: + + struct TPSKEntry { + TIndexType indexType; + TUint index; + TBuf8 ssid; + TBuf8 password; + TBuf8 psk; + }; + + virtual ~eapol_am_core_symbian_c(); + + /////////////////////////////////////////////////////////////// + /* These are called from WLM via CEapol */ + + static eapol_am_core_symbian_c * NewL( + MEapolToWlmIf* const aPartner, + const bool aIsClient = ETrue, + const TUint aServerIndex = 0); + + + TInt Start( + const TIndexType aIndexType, + const TUint aIndex, + const TSSID& aSSID, + const TBool aWPAOverrideEnabled, + const TUint8* aWPAPSK, + const TUint aWPAPSKLength + ); + + TInt CompleteAssociation( + const TInt aResult, + const TMacAddress& aLocalAddress, + const TMacAddress& aRemoteAddress, + const TUint8* const aReceivedWPAIE, // WLM must give only the WPA IE to EAPOL + const TUint aReceivedWPAIELength, + const TUint8* const aSentWPAIE, + const TUint aSentWPAIELength, + const TWPACipherSuite aGroupKeyCipherSuite, + const TWPACipherSuite aPairwiseKeyCipherSuite + ); + + + TInt Disassociated(); + + TInt ReceivePacket( + const TUint aLength, + const TUint8* const aData); + + TInt SendWPAMICFailureReport( + TBool aFatalMICFailure, + const TMICFailureType aMICFailureType); + + ///////////////////////////////////////// + /* These are called from ethernet_core */ + + /** + * Sends packet to lower layers + */ + eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + eap_status_e eap_acknowledge(const eap_am_network_id_c * const receive_network_id); + + eap_status_e reassociate( + const eap_am_network_id_c * const send_network_id, + const eapol_key_authentication_type_e authentication_type, + const eap_variable_data_c * const PMKID, + const eap_variable_data_c * const WPXM_WPXK1, + const eap_variable_data_c * const WPXM_WPXK2); + + /** + * Loads an EAP type plug-in. + * @param type Type to be loaded. + * @param partner Pointer to the partner class for the EAP type. + * @param eap_type The pointer for the loaded type should be set here. + * @param is_client_when_true Indicates whether the loaded EAP type should be client or server. + * @param receive_network_id Network address. + */ + eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + eap_status_e unload_module(const eap_type_value_e type); + + void set_is_valid(); + + bool get_is_valid(); + + void increment_authentication_counter(); + + u32_t get_authentication_counter(); + + bool get_is_client(); + + /** + * This does the initial configuration of the class. + */ + eap_status_e configure(); + + eap_status_e shutdown(); + + /** + * Reads a configuration parameter value from the database. + * In Symbian this function is only a TRAP wrapper for read_configure_L. + */ + eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // See abs_eap_base_type_c::state_notification(). + void state_notification(const abs_eap_state_notification_c * const state); + + eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + eap_status_e cancel_all_timers(); + + eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const master_session_key); + + /** + * Forwards the keys to lower layer (= WLM). + */ + eap_status_e packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key); + + /** + * Packet mangling routine for testing. + */ + + eap_status_e timer_expired(const u32_t id, void *data); + + eap_status_e timer_delete_data(const u32_t id, void *data); + + eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + eap_status_e add_rogue_ap(eap_array_c & rogue_ap_list); + +protected: + + eapol_am_core_symbian_c( + MEapolToWlmIf * const aPartner, + const bool is_client_when_true, + const TUint aServerIndex); + + void ConstructL(); + + void RunL(); + + void DoCancel(); + +private: + + eap_status_e random_error( + eap_buf_chain_wr_c * const sent_packet, + const bool forse_error, + const u32_t packet_index); + + /** + * Tries to open EAPOL parameter database. + */ + void TryOpenDatabaseL(RDbNamedDatabase& aDatabase, RDbs& aSession); + + /** + * Opening function for EAPOL parameter database. + */ + void OpenDatabaseL(RDbNamedDatabase& aDatabase, RDbs& aSession); + + void read_configureL(eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data); + + void ReadEAPSettingsL(); + + void SetToTopPriorityL(const TEap* const aEapType); + + eap_status_e create_upper_stack(); + + void RetrievePSKL(TPSKEntry& entry); + + void SavePSKL(TPSKEntry& entry); + + + +private: + + RDbs m_session; + RDbNamedDatabase m_database; + + /// Pointer to the lower layer in the stack + MEapolToWlmIf* m_partner; + + /// Pointer to the upper layer in the stack + ethernet_core_c* m_ethernet_core; + + /// Pointer to the tools class + eap_am_tools_symbian_c* m_am_tools; + + bool m_enable_random_errors; + + u32_t m_error_probability; + + u32_t m_generate_multiple_error_packets; + + u32_t m_authentication_counter; + + u32_t m_successful_authentications; + + u32_t m_failed_authentications; + + bool m_is_valid; + + bool m_is_client; + + /// Array for storing the loaded EAP types. + RPointerArray m_plugin_if_array; + /// Array which corresponds with m_plugin_if_array and indicates the types of the loaded EAP types. + RArray m_eap_type_array; + + /// EAP configuration data from CommDb + TEapArray m_iap_eap_array; + TUint m_eap_index; + /// Indicates the bearer type + TIndexType m_index_type; + /// Indicates the service index in CommDb + TUint m_index; + + u32_t m_packet_index; + + bool m_manipulate_ethernet_header; + + bool m_send_original_packet_first; + + bool m_authentication_indication_sent; + + bool m_unicast_wep_key_received; + + bool m_broadcast_wep_key_received; + + bool m_block_packet_sends_and_notifications; + + bool m_success_indication_sent; + + bool m_first_authentication; + + bool m_self_disassociated; + + TAuthenticationMode m_802_11_authentication_mode; + + EWlanSecurityMode m_security_mode; + + eap_variable_data_c * m_wpa_preshared_key; + + eap_variable_data_c * m_ssid; + + eap_am_network_id_c* m_receive_network_id; + + eap_variable_data_c * m_wpa_psk_password_override; + + bool m_wpa_override_enabled; + + bool m_wpa_psk_mode_allowed; + + bool m_wpa_psk_mode_active; + + bool m_stack_marked_to_be_deleted; + + TMacAddress m_local_address; + + TMacAddress m_remote_address; + + const TUint8* m_received_wpa_ie; + + TUint m_received_wpa_ie_length; + + const TUint8* m_sent_wpa_ie; + + TUint m_sent_wpa_ie_length; + + TWPACipherSuite m_group_key_cipher_suite; + + TWPACipherSuite m_pairwise_key_cipher_suite; + + bool m_active_type_is_leap; + + eap_file_config_c* m_fileconfig; + + //-------------------------------------------------- +}; // class eapol_am_core_symbian_c + +#endif //#if !defined(_EAPOL_AM_CORE_SYMBIAN_H_) + +//-------------------------------------------------- + + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eapol_am_core_symbian_simulator.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eapol_am_core_symbian_simulator.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,251 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAP_AM_SYMBIAN_H_) +#define _EAP_AM_SYMBIAN_H_ + +#if defined(USE_EAPOL_LLC_INTERFACE) + #include +#endif + +#include "eap_tools.h" +#include "eap_am_export.h" +#include "abs_eapol_am_core_symbian_simulator.h" +#include "abs_ethernet_core.h" +#include "ethernet_core.h" +#include "eap_base_type.h" +#include "eap_variable_data.h" +#include "eap_core_map.h" + +class CEapType; + +// +class EAP_EXPORT eapol_am_core_symbian_c +: public abs_ethernet_core_c +{ +private: + //-------------------------------------------------- + + abs_eapol_am_core_symbian_c *m_partner; + + ethernet_core_c *m_ethernet_core; + + abs_eap_am_tools_c * const m_am_tools; + + eap_variable_data_c m_own_address; + + u32_t m_error_probability; + + u32_t m_authentication_counter; + + bool m_is_valid; + + bool m_is_client; + + bool m_enable_random_errors; + + bool m_shutdown_was_called; + + RPointerArray m_plugin_if_array; + RArray m_eap_type_array; + + EAP_FUNC_IMPORT eap_status_e random_error( + eap_buf_chain_wr_c * const sent_packet); + + //-------------------------------------------------- +protected: + //-------------------------------------------------- + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~eapol_am_core_symbian_c(); + + // + EAP_FUNC_IMPORT eapol_am_core_symbian_c( + abs_eap_am_tools_c * const m_am_tools, + abs_eapol_am_core_symbian_c * const partner, + const bool is_client_when_true); + + // + EAP_FUNC_IMPORT eap_base_type_c * load_type(const eap_type_value_e type); + +#if defined(USE_EAPOL_LLC_INTERFACE) + // + EAP_FUNC_EXPORT eap_status_e packet_process( + RMBufChain& aPdu); +#endif //#if defined(USE_EAPOL_LLC_INTERFACE) + + // + EAP_FUNC_IMPORT eap_status_e packet_process( + const eap_am_network_id_c * const receive_network_id, + eapol_ethernet_header_wr_c * const eth_header, + const u32_t packet_length); + + // + EAP_FUNC_IMPORT eap_status_e packet_send( + const eap_am_network_id_c * const send_network_id, + eap_buf_chain_wr_c * const sent_packet, + const u32_t header_offset, + const u32_t data_length, + const u32_t buffer_length); + + eap_status_e set_address( + const u8_t * const address, + const u32_t length) + { + return m_own_address.set_copy_of_buffer(address, length); + } + + // + EAP_FUNC_IMPORT u32_t get_header_offset( + u32_t * const MTU, + u32_t * const trailer_length); + + // + EAP_FUNC_IMPORT eap_status_e eap_acknowledge(const eap_am_network_id_c * const receive_network_id); + + // + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + + // + EAP_FUNC_IMPORT eap_status_e unload_module(const eap_type_value_e type); + + /** + * This function starts the EAP-authentication. + * The first parameter includes the network addresses of the protocol + * over the EAP-packets are transmitted. + * The type attribute of the eap_am_network_id_c object MUST be set + * either eapol_ethernet_type_e::eapol_ethernet_type_pae + * or eapol_ethernet_type_e::eapol_ethernet_type_preauthentication. + * Value eapol_ethernet_type_e::eapol_ethernet_type_pae starts normal EA-authentication. + * Value eapol_ethernet_type_e::eapol_ethernet_type_preauthentication starts 802.11i preauthentication. + * The second parameter is_client_when_true tells whether this stack + * is client (true) or server (false). + */ + EAP_FUNC_IMPORT eap_status_e start_authentication( + const eap_am_network_id_c * const receive_network_id, + const bool is_client_when_true); + + EAP_FUNC_IMPORT eap_status_e send_logoff(const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT_EMPTY void set_is_valid() + { + m_is_valid = true; + } + + EAP_FUNC_IMPORT_EMPTY bool get_is_valid() + { + return m_is_valid; + } + + const eap_variable_data_c * const get_own_address() + { + return &m_own_address; + } + + void increment_authentication_counter() + { + ++m_authentication_counter; + } + + const u32_t get_authentication_counter() + { + return m_authentication_counter; + } + + bool get_is_client() + { + return m_is_client; + } + + EAP_FUNC_IMPORT eap_status_e configure(); + + EAP_FUNC_IMPORT eap_status_e shutdown(); + + /** + * Note this function is just an example. Parameters will change later. + * The packet_data_crypto_keys() function gives the generated keys to lower level. + * After EAP-authentication has generated the keys it calls this function + * to offer the keys to lower level. + * @see abs_eap_base_type_c::packet_data_crypto_keys(). + */ + EAP_FUNC_IMPORT eap_status_e packet_data_crypto_keys( + const eap_am_network_id_c * const send_network_id, + const eap_master_session_key_c * const master_session_key); + + EAP_FUNC_IMPORT eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + // See abs_eap_base_type_c::state_notification(). + void state_notification( + const abs_eap_state_notification_c * const state) + { + m_partner->state_notification(state); + } + + // + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id, + void * const p_data, + const u32_t p_time_ms); + + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const p_initializer, + const u32_t p_id); + + // + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + // + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + // + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + eap_status_e packet_data_session_key( + const eap_am_network_id_c * const send_network_id, + const eapol_session_key_c * const key); + + //-------------------------------------------------- +}; // class eapol_am_core_symbian_c + +#endif //#if !defined(_EAP_AM_SYMBIAN_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eapol_am_core_symbian_wlm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eapol_am_core_symbian_wlm.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,100 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + + +#if !defined(_EAPOL_AM_CORE_SYMBIAN_WLM_H_) +#define _EAPOL_AM_CORE_SYMBIAN_WLM_H_ + +// INCLUDES +#include // For TMacAddress +#include // For MWlanMgmtPacket +#include // For TIndexType + +// FORWARD DECLARATIONS +class abs_eapol_am_core_symbian_c; +class eapol_am_core_symbian_c; + +// CLASS DECLARATION + +/** +* Class for WLM interface. These are the functions that WLM can call in EAPOL DLL. +* WLM could use eapol_am_core_symbian_c directly but +* that way we would need to export dozens of headers from eapol. This way we need to +* export only a few. +*/ +class eapol_am_core_symbian_wlm_c +: public CBase, public MWlanMgmtPacket // From WLM +{ +public: + /** + * Static constructor. + */ + IMPORT_C static eapol_am_core_symbian_wlm_c* NewL( + abs_eapol_am_core_symbian_c* const aPartner, + const bool aIsClient = true); + + /** + * Destructor. + */ + virtual ~eapol_am_core_symbian_wlm_c(); + + /** + * Processes received EAPOL packets. + */ + IMPORT_C TInt ReceivePacket( + const TUint aLength, + const TUint8* const aData); + /** + * Starts the sending of EAPOL-Starts. + */ + IMPORT_C TInt start_authentication( + const TIndexType aIndexType, + const TUint aIndex, + const TMacAddress& aLocalAddress, + const TMacAddress& aRemoteAddress); + /** + * Resets EAPOL state. Does not actually send EAPOL-Logoff message at the moment. + * Note that send_logoff must be called before start_authentication is called again. + */ + IMPORT_C TInt send_logoff( + const TMacAddress& aLocalAddress, + const TMacAddress& aRemoteAddress); +protected: + + eapol_am_core_symbian_wlm_c(); + + void ConstructL( + abs_eapol_am_core_symbian_c* const aPartner, + const bool aIsClient); + +private: + /// Pointer to next upper stack layer + eapol_am_core_symbian_c* iEapolCore; + + TBool iLogoffCalled; + //-------------------------------------------------- +}; + +#endif //#if !defined(_EAPOL_AM_CORE_SYMBIAN_WLM_H_) + +//-------------------------------------------------- + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/include/eapol_am_wlan_authentication_symbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/include/eapol_am_wlan_authentication_symbian.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,339 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPOL_AM_WLAN_AUTHENTICATION_SYMBIAN_H_) +#define _EAPOL_AM_WLAN_AUTHENTICATION_SYMBIAN_H_ + +#include "eap_am_export.h" +#include "eapol_am_wlan_authentication.h" +#include "eapol_wlan_database_reference.h" +#include "eap_am_network_id.h" +#include "eap_array_algorithms.h" + +#if defined(USE_EAP_SIMPLE_CONFIG) +#include "abs_eap_configuration_if.h" +#include "simple_config_credential.h" +#include "abs_eap_configuration_if.h" +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +#include +#include +#include + +#include + +#include // For TIndexType + + +#ifdef SYMBIAN_SECURE_DBMS +// For EAP TLS, PEAP, TTLS, FAST secure databases. +// Full path is not needed. The database eaptls.dat will be saved in the +// data cage path for DBMS. So it will be in "\private\100012a5\eaptls.dat" in C: drive. +// The maximum length of database name is 0x40 (KDbMaxName) , which is defined in d32dbms.h. + +_LIT(KFastDatabaseName, "c:eapfast.dat"); + + +#else + +#ifdef USE_EAP_FAST_TYPE +_LIT(KFastDatabaseName, "c:\\system\\data\\eapfast.dat"); +#endif + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + +class CEapType; +class abs_eapol_am_wlan_authentication_c; +class abs_eap_am_tools_c; +class eap_file_config_c; + +const TInt KMaxWPAPSKPasswordLength = 64; +const TInt KWPAPSKLength = 32; +// Just to make this different of already existing constant. +const TUint K_Max_SSID_Length = 32; + + +/// This class declares the simulator adaptation module of eapol_am_wlan_authentication_c. +/// See comments of the functions from eapol_am_wlan_authentication_c. +class EAP_EXPORT eapol_am_wlan_authentication_symbian_c +: public CActive +, public eapol_am_wlan_authentication_c +#if defined(USE_EAP_SIMPLE_CONFIG) +, public abs_eap_configuration_if_c +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) +{ +private: + //-------------------------------------------------- + + abs_eapol_am_wlan_authentication_c * m_am_partner; + +#if defined(USE_EAP_SIMPLE_CONFIG) + abs_eap_configuration_if_c * m_configuration_if; +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + abs_eap_am_tools_c * m_am_tools; + + /// This is object to handle file configuration. + eap_file_config_c * m_fileconfig; + + /// SSID of current network. + eap_variable_data_c m_SSID; + + /// WPA(2)-PSK + eap_variable_data_c m_wpa_preshared_key; + + /// HAHS of WPA(2)-PSK + eap_variable_data_c m_wpa_preshared_key_hash; + + /// This pointer is abstract interface to reference of WLAN database of the current connection. + const abs_eapol_wlan_database_reference_if_c * m_wlan_database_reference; + + /// Handle of database session. + RDbs m_session; + + /// Handle of database file. + RFs m_fs; + + /// Array for storing the loaded EAP types. + RPointerArray m_plugin_if_array; + +#ifdef USE_EAP_EXPANDED_TYPES + + /// Enabled expanded EAP configuration data from CommsDat + // This is for the outer most EAP (not tunneled) + RExpandedEapTypeArray m_enabled_expanded_eap_array; + + /// Disabled expanded EAP configuration data from CommsDat + // This is for the outer most EAP (not tunneled) + RExpandedEapTypeArray m_disabled_expanded_eap_array; + + /// Array which corresponds with m_plugin_if_array and indicates the types of the loaded EAP types. + eap_array_c m_eap_type_array; + +#else + + /// EAP configuration data from CommDb + TEapArray m_iap_eap_array; + + /// Array which corresponds with m_plugin_if_array and indicates the types of the loaded EAP types. + RArray m_eap_type_array; + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + /// Network identity of current connection. + eap_am_network_id_c m_receive_network_id; + + /// WLAN security mode as defined in Symbian platform. + EWlanSecurityMode m_security_mode; + + /// WLAN authentication type. + eapol_key_authentication_type_e m_selected_eapol_key_authentication_type; + + /// WPA(2)-PSK override. + bool m_WPA_override_enabled; + + /// This object is client (true). + bool m_is_client; + + /// This object is valid (true). + bool m_is_valid; + + //-------------------------------------------------- + + /// This struct is used in WPA(2)-PSK setting handling. + struct TPSKEntry + { + TIndexType indexType; + TUint index; + TBuf8 ssid; + TBuf8 password; + TBuf8 psk; + }; + + /// This function tries to initialize database. + void TryInitDatabaseL(); + + /// This function tries to initialize database or if it fails + /// tries to create new database. + void InitDatabaseL(); + + /// Function reads one configuration value from database. + void read_configureL( + const TDesC& aDbName, + const TDesC& aTableName, + eap_config_string field, + const u32_t /*field_length*/, + eap_variable_data_c * const data); + + /// Control function of this active-object. + void RunL(); + + /// Cancel function for active-object. + void DoCancel(); + + /// This function reads WPA(2)-PSK from database. + void RetrievePSKL(TPSKEntry& entry); + + /// This function saves WPA(2)-PSK to database. + void SavePSKL(TPSKEntry& entry); + + /// This function reads EAP-settings from database. + void ReadEAPSettingsL(); + +#ifdef USE_EAP_EXPANDED_TYPES + + /// This function set the EAP-type to highest in priority. + void SetToTopPriorityL(const eap_type_value_e aEapType); + +#else // For normal EAP types. + + /// This function set the EAP-type to highest in priority. + void SetToTopPriorityL(const TEap* const aEapType); + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + + /// THis function reads the references to active Internet Access Point (IAP). + eap_status_e read_database_reference_values( + TIndexType * const type, + TUint * const index); + + /// This function resets all EAP-plugings. + eap_status_e reset_eap_plugins(); + + /// This function sends error notification to partner object. + void send_error_notification(const eap_status_e error); + + //-------------------------------------------------- +public: + //-------------------------------------------------- + + // + EAP_FUNC_IMPORT virtual ~eapol_am_wlan_authentication_symbian_c(); + + // + EAP_FUNC_IMPORT eapol_am_wlan_authentication_symbian_c( + abs_eap_am_tools_c * const tools, + const bool is_client_when_true, + const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference); + + + /// See comments of the functions from eapol_am_wlan_authentication_c. + + EAP_FUNC_IMPORT bool get_is_valid(); + + EAP_FUNC_IMPORT eap_status_e configure(); + + EAP_FUNC_IMPORT eap_status_e shutdown(); + + EAP_FUNC_IMPORT eap_status_e set_am_partner( + abs_eapol_am_wlan_authentication_c * am_partner +#if defined(USE_EAP_SIMPLE_CONFIG) + , abs_eap_configuration_if_c * const configuration_if +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + ); + + EAP_FUNC_IMPORT eap_status_e reset_eap_configuration(); + + EAP_FUNC_IMPORT eap_status_e set_wlan_parameters( + const eap_variable_data_c * const SSID, + const bool WPA_override_enabled, + const eap_variable_data_c * const wpa_preshared_key, + const eapol_key_authentication_type_e selected_eapol_key_authentication_type); + + EAP_FUNC_IMPORT eap_status_e association( + const eap_am_network_id_c * const receive_network_id); + + EAP_FUNC_IMPORT eap_status_e disassociation( + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ); + + EAP_FUNC_IMPORT eap_status_e get_selected_eap_types( + eap_array_c * const selected_eap_types); + + EAP_FUNC_IMPORT eap_status_e get_wlan_configuration( + eap_variable_data_c * const wpa_preshared_key_hash); + + EAP_FUNC_IMPORT eap_status_e authentication_finished( + const bool when_true_successfull, + const eap_type_value_e eap_type, + const eapol_key_authentication_type_e authentication_type); + + EAP_FUNC_IMPORT eap_status_e load_module( + const eap_type_value_e type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type_if, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address. + ); + + EAP_FUNC_IMPORT eap_status_e unload_module( + const eap_type_value_e type); + + EAP_FUNC_IMPORT eap_status_e read_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e write_configure( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data); + + EAP_FUNC_IMPORT eap_status_e set_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id, + void * const data, + const u32_t p_time_ms); + + EAP_FUNC_IMPORT eap_status_e cancel_timer( + abs_eap_base_timer_c * const initializer, + const u32_t id); + + EAP_FUNC_IMPORT eap_status_e cancel_all_timers(); + + EAP_FUNC_IMPORT eap_status_e check_is_valid_eap_type(const eap_type_value_e eap_type); + + EAP_FUNC_IMPORT eap_status_e get_eap_type_list( + eap_array_c * const eap_type_list); + + EAP_FUNC_IMPORT void state_notification( + const abs_eap_state_notification_c * const state); + +#if defined(USE_EAP_SIMPLE_CONFIG) + + EAP_FUNC_EXPORT eap_status_e save_simple_config_session( + const simple_config_state_e state, + EAP_TEMPLATE_CONST eap_array_c * const credential_array, + const eap_variable_data_c * const new_password, + const simple_config_Device_Password_ID_e Device_Password_ID, + const simple_config_payloads_c * const other_configuration); + +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + + //-------------------------------------------------- +}; // class eapol_am_wlan_authentication_symbian_c + +#endif //#if !defined(_EAPOL_AM_WLAN_AUTHENTICATION_SYMBIAN_H_) + +//-------------------------------------------------- + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/EapAkaInterface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/EapAkaInterface.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,485 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 603 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +// INCLUDE FILES +#include "EapAkaInterface.h" +#include "eap_type_aka_types.h" + +#include +#include + +// ================= MEMBER FUNCTIONS ======================= + +CEapAkaInterface::CEapAkaInterface(abs_eap_am_tools_c* const aTools, eap_am_type_aka_symbian_c* const aParent) +: CActive(CActive::EPriorityStandard) +, iParent(aParent) +, m_am_tools(aTools) +, iAuthenticationData(NULL) +, iQueryId(EQueryNone) +, iMMETELConnectionStatus(EFalse) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +CEapAkaInterface* CEapAkaInterface::NewL(abs_eap_am_tools_c* const aTools, + eap_am_type_aka_symbian_c* const aParent) +{ + CEapAkaInterface* self = new(ELeave) CEapAkaInterface(aTools, aParent); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; +} + +//-------------------------------------------------- + +void CEapAkaInterface::ConstructL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + CActiveScheduler::Add(this); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +CEapAkaInterface::~CEapAkaInterface() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if(IsActive()) + { + Cancel(); + } + + /* + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Closing RMobilePhone and MMETEL.\n"))); + + iPhone.Close(); + iServer.Close(); // Phone module is unloaded automatically when RTelServer session is closed + */ + DisconnectMMETel(); + + delete iAuthenticationData; + iAuthenticationData = NULL; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapAkaInterface::QueryIMSIL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Querying IMSI.\n"))); + + iQueryId = EQueryIMSI; + + // Create MMETEl connection. + User::LeaveIfError( CreateMMETelConnectionL() ); + + iPhone.GetSubscriberId( iStatus, iSubscriberId ); + + if( !IsActive() ) + { + SetActive(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapAkaInterface::QueryRESL( eap_variable_data_c * const aRand, eap_variable_data_c * const aAUTN ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Querying RES, CK, IK and AUTS.\n"))); + + iQueryId = EQueryRES; + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("RAND"), + aRand->get_data(aRand->get_data_length()), + aRand->get_data_length())); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("AUTN"), + aAUTN->get_data(aAUTN->get_data_length()), + aAUTN->get_data_length())); + + // Rand must be 16 bytes + if (static_cast( aRand->get_data_length() ) != EAP_TYPE_AKA_MINIMUM_RAND_LENGTH) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Illegal RAND - Incorrect length.\n"))); + User::Leave(KErrArgument); + } + + // AUTN must be 16 bytes + if (static_cast( aAUTN->get_data_length() ) != EAP_TYPE_AKA_MINIMUM_AUTN_LENGTH) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Illegal AUTN - Incorrect length.\n"))); + User::Leave(KErrArgument); + } + + // Create MMETEL connection. + User::LeaveIfError( CreateMMETelConnectionL() ); + + // Open CustomAPI. + User::LeaveIfError( iCustomAPI.Open(iPhone) ); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: OPENED CUSTOM API \n"))); + + u8_t *rand = aRand->get_data(aRand->get_data_length()); + u8_t *autn = aAUTN->get_data(aAUTN->get_data_length()); + + iEAPAka.iRandomParameters.Copy( rand, EAP_TYPE_AKA_MINIMUM_RAND_LENGTH); //Copy the rand to iEAPAka + + iEAPAka.iAUTN.Copy( autn, EAP_TYPE_AKA_MINIMUM_AUTN_LENGTH); //Copy the AUTN to iEAPAka + + //Pack iEAPAka to iAuthenticationData for passing it to the custom API. + iAuthenticationData = new (ELeave) RMmCustomAPI::TAkaDataPckg( iEAPAka ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Before querying CustomAPI GetWlanSimAuthenticationData \n"))); + + iCustomAPI.GetWlanSimAuthenticationData( iStatus, *iAuthenticationData ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: After querying CustomAPI. iStatus.Int() =%d \n"), iStatus.Int() )); + + if( !IsActive() ) + { + SetActive(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapAkaInterface::DoCancel() +{ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapAkaInterface::DoCancel() - Cancelling MMETEL query.\n") ) ); + + // Cancel the request. + iCustomAPI.CancelAsyncRequest( ECustomGetSimAuthenticationDataIPC ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapAkaInterface::DoCancel(): CANCELLED CUSTOM API REQUEST \n"))); +} + +//-------------------------------------------------- + +void CEapAkaInterface::RunL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapAkaInterface::RunL(). iStatus.Int() =%d \n"), iStatus.Int() )); + + + TInt error = KErrNone; + eap_status_e completion_status = eap_status_ok; + eap_status_e AuthenticationStatus = eap_status_ok; + + eap_variable_data_c imsi(m_am_tools); // Keeping it here to avoid "error" in ARMV5 build. + + // This is to store the IMSI, which is in Unicode form. + eap_variable_data_c imsiInUnicode(m_am_tools); // Keeping it here to avoid "error" in ARMV5 build. + + eap_variable_data_c res(m_am_tools); + eap_variable_data_c ck(m_am_tools); + eap_variable_data_c ik(m_am_tools); + eap_variable_data_c auts(m_am_tools); + + if (iStatus.Int() == KErrNone) + { + switch( iQueryId ) + { + case EQueryIMSI: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Got IMSI reply.\n"))); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IMSI"), + iSubscriberId.Ptr(), + iSubscriberId.Size())); + + // Convert the IMSI from unicode to UTF8 characters. + + completion_status = imsiInUnicode.set_buffer(iSubscriberId.Ptr(), iSubscriberId.Size(), false, false); + + if (completion_status != eap_status_ok) + { + imsiInUnicode.reset(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for IMSI.\n"))); + + // No need to continue. The request will be completed towards the end, in this kind of error situation. + break; + } + + completion_status = m_am_tools->convert_unicode_to_utf8(imsi, imsiInUnicode); + + if (completion_status != eap_status_ok) + { + imsi.reset(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not convert IMSI from UNICODE to UTF8.\n"))); + break; + } + + // Complete. This happens only if completion_status is eap_status_ok so far. + TRAP(error, iParent->complete_AKA_imsi_L(&imsi, completion_status)); + + break; + + case EQueryRES: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("####AKA interface: Got RES, CK, IK and AUTS reply. ####\n"))); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("RES"), + iEAPAka.iRES.Ptr(), + iEAPAka.iRES.Size())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CK"), + iEAPAka.iCK.Ptr(), + iEAPAka.iCK.Size())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IK"), + iEAPAka.iIK.Ptr(), + iEAPAka.iIK.Size())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AUTS"), + iEAPAka.iAUTS.Ptr(), + iEAPAka.iAUTS.Size())); + + delete iAuthenticationData; + iAuthenticationData = NULL; + + // Close the custom API since we don't need it any more. + iCustomAPI.Close(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapAkaInterface::RunL() - KErrNone case: CLOSED CUSTOM API \n"))); + + completion_status = res.set_buffer(iEAPAka.iRES.Ptr(), iEAPAka.iRES.Size(), false, false); + if (completion_status != eap_status_ok) + { + res.reset(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for RES.\n"))); + break; + } + + completion_status = ck.set_buffer(iEAPAka.iCK.Ptr(), iEAPAka.iCK.Size(), false, false); + if (completion_status != eap_status_ok) + { + ck.reset(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for CK.\n"))); + break; + } + + completion_status = ik.set_buffer(iEAPAka.iIK.Ptr(), iEAPAka.iIK.Size(), false, false); + if (completion_status != eap_status_ok) + { + ik.reset(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for IK.\n"))); + break; + } + + completion_status = auts.set_buffer(iEAPAka.iAUTS.Ptr(), iEAPAka.iAUTS.Size(), false, false); + if (completion_status != eap_status_ok) + { + auts.reset(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for AUTS.\n"))); + break; + } + + // Complete. This happens only if completion_status is eap_status_ok so far. + TRAP(error, iParent->complete_AKA_RES_L( &res, &ck, &ik, &auts ) ); + + break; + } + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Got error reply.\n"))); + + switch( iQueryId ) + { + case EQueryIMSI: + + // Error with IMSI. Reset it and complete the request. + imsi.reset(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Error in IMSI.\n"))); + + TRAP(error, iParent->complete_AKA_imsi_L(&imsi)); + break; + + case EQueryRES: + + // Re-synchronization needed or error with RES or CK or IK. + + // We have to close the custom API anyway. + iCustomAPI.Close(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapAkaInterface::RunL() - error case: CLOSED CUSTOM API \n"))); + + // Just to verify if there is any values set. + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("RES"), + iEAPAka.iRES.Ptr(), + iEAPAka.iRES.Size())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CK"), + iEAPAka.iCK.Ptr(), + iEAPAka.iCK.Size())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IK"), + iEAPAka.iIK.Ptr(), + iEAPAka.iIK.Size())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AUTS"), + iEAPAka.iAUTS.Ptr(), + iEAPAka.iAUTS.Size())); + + // Complete the request after resetting res, ck and ik. + // auts might have some value if the error is related to re-synchronization. So don't reset it. + res.reset(); + ck.reset(); + ik.reset(); + + completion_status = auts.set_buffer(iEAPAka.iAUTS.Ptr(), iEAPAka.iAUTS.Size(), false, false); + if (completion_status != eap_status_ok) + { + auts.reset(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for AUTS.\n"))); + break; + } + + // Check if the failure is due to re-synchronization fail. + if( iStatus.Int() == KErrMMEtelSqnVerificationFailed ) + { + // Re-synchronization failure. + AuthenticationStatus = eap_status_syncronization_failure; + } + else + { + // Authentication failed. Errors could be KErrMMEtelMacVerificationFailed or KErrMMEtelAuthenticateFailed also. + AuthenticationStatus = eap_status_authentication_failure; + } + + // Complete. This happens only if completion_status is eap_status_ok so far. + TRAP(error, iParent->complete_AKA_RES_L( &res, &ck, &ik, &auts, AuthenticationStatus, completion_status ) ); + break; + } + } + + if( completion_status != eap_status_ok && iQueryId == EQueryIMSI ) + { + TRAP(error, iParent->complete_AKA_imsi_L(&imsi, completion_status)); + } + + if( completion_status != eap_status_ok && iQueryId == EQueryRES ) + { + TRAP(error, iParent->complete_AKA_RES_L( &res, &ck, &ik, &auts, AuthenticationStatus, completion_status ) ); + } + + DisconnectMMETel(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +TInt CEapAkaInterface::CreateMMETelConnectionL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Creating MMETel connection.\n"))); + + TInt errorCode = KErrNone; + + // MMETel need to be connected only once. + if( !iMMETELConnectionStatus ) + { + RTelServer::TPhoneInfo phoneInfo; + TInt phoneCount = 0; + + // Connect to ETel server + User::LeaveIfError( iServer.Connect() ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Connected to ETel server.\n"))); + + // This function loads an ETel TSY module, mmtsy. + errorCode = iServer.LoadPhoneModule( KMmTsyModuleName ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Loaded phone module.\n"))); + + if ( errorCode != KErrNone && errorCode != KErrAlreadyExists ) + { + User::Leave( errorCode ); + } + + iServer.SetExtendedErrorGranularity( RTelServer::EErrorExtended ); + + // This function retrieves the total number of phones supported by all + // the currently loaded ETel (TSY) modules. + User::LeaveIfError( iServer.EnumeratePhones( phoneCount ) ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Number of phones supported by the loaded ETel = %d.\n"), phoneCount)); + + // This function retrieves information associated with the specified phone + while ( ( phoneCount-- ) && ( phoneInfo.iName != KMmTsyPhoneName ) ) + { + User::LeaveIfError( iServer.GetPhoneInfo( phoneCount, phoneInfo ) ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got phone info.\n"))); + } + + // This function opens a phone subsession by name. ("DefaultPhone"). + User::LeaveIfError( iPhone.Open( iServer, phoneInfo.iName ) ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Opened phone subsession.\n"))); + + // MMETel connected and the phone module loaded fine. + iMMETELConnectionStatus = ETrue; + } + else + { + // MMETel already connected. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("MMETel connected once already.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return errorCode; +} + +void CEapAkaInterface::DisconnectMMETel() +{ + if( iMMETELConnectionStatus ) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Closing RMobilePhone and MMETEL.\n"))); + + iPhone.Close(); + iServer.Close(); // Phone module is unloaded automatically when RTelServer session is closed + + iMMETELConnectionStatus = EFalse; + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("RMobilePhone and MMETEL already closed.\n"))); + } +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/eap_am_type_aka_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/eap_am_type_aka_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3187 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 604 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +// INCLUDE FILES + +#include "eap_tools.h" +#include "eap_am_type_aka_symbian.h" +#include "eap_am_tools_symbian.h" +#include "eap_state_notification.h" +#include "EapAkaDbDefaults.h" +#include "EapAkaDbParameterNames.h" +#include "EapAkaDbUtils.h" +#include "eap_am_trace_symbian.h" + +#include // For DBMS +#include // For RReadStream + +#if defined (USE_EAP_TYPE_SERVER_AKA) +// These are needed only for the server and test environment (Plugin tester) +// Enable USE_EAP_TYPE_SERVER_AKA in eapol.mmh to build for test environment. +#include "eap_crypto_api.h" +#include "eap_am_aka_milenage_algorithm.h" +#endif // #if defined (USE_EAP_TYPE_SERVER_AKA) + +#if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__) + #include "EapAkaInterface.h" +#endif // End of #if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__) + +// This is needed for cf_str_EAP_AKA_2_digit_mnc_map_of_mcc_of_imsi_array. +#include "eap_type_aka_types.h" + +const TUint AKA_IMSI_LENGTH = 15u; +const TUint KMaxSqlQueryLength = 512; +const TUint KMaxDBFieldNameLength = 255; +const TInt KDefaultColumnInView_One = 1; // For DB view. +const TInt KMicroSecsInASecond = 1000000; // 1000000 micro seconds is 1 second. + +const u8_t EAP_AKA_DEFAULT_REAUTHENTICATION_REALM[] = "dymmy.reauth.org"; +const u32_t EAP_AKA_DEFAULT_REAUTHENTICATION_REALM_LENGTH = sizeof(EAP_AKA_DEFAULT_REAUTHENTICATION_REALM)-1ul; + +#if defined (USE_EAP_TYPE_SERVER_AKA) || defined(__WINS__) + +const char TEST_IMSI[] = "244070100000001"; + +#endif + +#if defined (USE_EAP_TYPE_SERVER_AKA) +// For the server side. + +struct eap_aka_encryption_imsi_block_s +{ + u8_t id_type:1; + u8_t imsi_length:7; + u8_t imsi_and_padding[AKA_IMSI_LENGTH]; +}; + +struct eap_aka_pseudonym_s +{ + u32_t encryption_key_index; + union _IV + { + u8_t IV_8[EAP_AES_BLOCK_SIZE]; + u32_t IV_32[EAP_AES_BLOCK_SIZE/sizeof(u32_t)]; + } encryption_IV; + + eap_aka_encryption_imsi_block_s imsi_block; + + u8_t MAC[HMAC_SHA1_128_SIZE]; +}; + +const u32_t ENCRYPTION_KEY_INDEX_SCRAMBLE_CONST = 0xa7b3c922; + +#endif //#if defined (USE_EAP_TYPE_SERVER_AKA) + +// ================= MEMBER FUNCTIONS ======================= + + +eap_am_type_aka_symbian_c::eap_am_type_aka_symbian_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id) +: eap_am_type_aka_c(tools) +, m_am_tools(static_cast(tools)) // Tools class must be of type eap_am_tools_symbian because + // this is Symbian specific code. +, m_partner(partner) +, m_nai_realm(tools) +, m_index_type(aIndexType) +, m_index(aIndex) +, m_tunneling_type(aTunnelingType) +, m_is_valid(false) +, m_is_client(aIsClient) +, m_stored_reauth_id(tools) +, m_stored_pseudonym(tools) +, m_previous_imsi(tools) +, m_stored_required_completion(eap_type_aka_complete_none) +, m_stored_received_eap_identifier(0) +, m_shutdown_was_called(false) +, m_aka_algorithm(0) +, m_aka_if(0) +, m_simulator_aka_K(tools) +, m_simulator_aka_OP(tools) +, m_simulator_aka_AMF(tools) +, m_authentication_vector(0) +, m_pseudonym_identity(tools) +, m_reauthentication_identity(tools) +, m_username(tools) +, m_receive_network_id(tools) +, m_IMSI(tools) +, m_required_identity(aka_payload_NONE) +, m_required_completion(eap_type_aka_complete_none) +, m_identity_type(AKA_IDENTITY_TYPE_NONE) +, m_completion_action(eap_type_aka_complete_none) +, m_next_eap_identifier(0) +, m_aka_authentication_vector_status(eap_aka_authentication_vector_status_ok) +, m_pseudonym_key_index(0u) +, m_pseudonym_key(tools) +, m_pseudonym_MAC_key(tools) +, m_prev_pseudonym_key(tools) +, m_prev_pseudonym_MAC_key(tools) +, m_pseudonym_key_use_count(0u) +, m_RAND(tools) +, m_AUTN(tools) +, m_max_session_time(0) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#ifdef USE_EAP_EXPANDED_TYPES + + m_tunneling_vendor_type = m_tunneling_type.get_vendor_type(); + +#else + + m_tunneling_vendor_type = static_cast(m_tunneling_type); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + if (receive_network_id != 0 + && receive_network_id->get_is_valid_data() == true) + { + eap_status_e status = m_receive_network_id.set_copy_of_network_id( + receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + + +//-------------------------------------------------- + +void eap_am_type_aka_symbian_c::ConstructL() +{ + +#if defined (USE_EAP_TYPE_SERVER_AKA) + + // For the server. + m_aka_algorithm = new eap_am_aka_milenage_algorithm_c(m_am_tools, m_is_client); + if (m_aka_algorithm == 0 + || m_aka_algorithm->get_is_valid() == false) + { + if (m_aka_algorithm != 0) + { + m_aka_algorithm->shutdown(); + } + delete m_aka_algorithm; + m_aka_algorithm = 0; + return; + } +#endif // #if defined (USE_EAP_TYPE_SERVER_AKA) + + // Open/create database + EapAkaDbUtils::OpenDatabaseL(m_database, m_session, m_index_type, m_index, m_tunneling_type); + + // SIM IMSI, RES, CK, IK and AUTS are queried from SIM using AKA interface. + // If this is not used then Nokia test algorithms and test values are used. +#if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__) + if (m_is_client == true) + { + m_aka_if = CEapAkaInterface::NewL(m_am_tools, this); + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAP-AKA server does not work at the moment in plugintester.\n"))); + User::Leave(KErrNotSupported); + } +#endif //#if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__) +} + +//-------------------------------------------------- + +eap_am_type_aka_symbian_c* eap_am_type_aka_symbian_c::NewL( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id) +{ + eap_am_type_aka_symbian_c* self = new(ELeave) eap_am_type_aka_symbian_c( + aTools, + aPartner, + aIndexType, + aIndex, + aTunnelingType, + aIsClient, + receive_network_id); + + CleanupStack::PushL(self); + + self->ConstructL(); + + if (self->get_is_valid() != true) + { + User::Leave(KErrGeneral); + } + + CleanupStack::Pop(); + return self; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_type_aka_symbian_c::~eap_am_type_aka_symbian_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::~eap_am_type_aka_symbian_c(): this = 0x%08x\n"), + this)); + + m_database.Close(); + m_session.Close(); + +#if defined(USE_EAP_AKA_INTERFACE) && !defined(__WINS__) + if (m_is_client == true) + { + delete m_aka_if; + } +#endif + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + { + eap_status_e status = type_configure_read( + cf_str_EAP_AKA_manual_realm.get_field(), + &m_nai_realm); + if (status == eap_status_ok + && m_nai_realm.get_is_valid_data() == true) + { + // OK NAI realm configured. + } + else + { + // No NAI realm configured. + // Lets use dummy. + status = m_nai_realm.set_copy_of_buffer(EAP_AKA_DEFAULT_REAUTHENTICATION_REALM, + EAP_AKA_DEFAULT_REAUTHENTICATION_REALM_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + + { + // Read Maximum Session Validity Time from the config file + eap_variable_data_c sessionTimeFromFile(m_am_tools); + + eap_status_e status = m_partner->read_configure( + cf_str_EAP_AKA_max_session_validity_time.get_field(), + &sessionTimeFromFile); + + if (status == eap_status_ok + && sessionTimeFromFile.get_is_valid_data() == true + && sessionTimeFromFile.get_data_length() == sizeof(u32_t)) + { + u32_t *session = reinterpret_cast(sessionTimeFromFile.get_data()); + if (session != 0) + { + // Update the max session time (in micro seconds). + // configuration file saves the time in seconds. We have to convert it to micro seconds. + m_max_session_time = static_cast(*session) * static_cast(KMicroSecsInASecond); + } + } + } + +#if defined (USE_EAP_TYPE_SERVER_AKA) + + // We have to set the values for K, OP and AMF in simulator. + + { + eap_status_e status = m_partner->read_configure( + cf_str_EAP_AKA_simulator_aka_k.get_field(), + &m_simulator_aka_K); + if (status == eap_status_ok + && m_simulator_aka_K.get_is_valid_data() == true + && m_simulator_aka_K.get_data_length() > 0ul + && m_simulator_aka_K.get_data( + m_simulator_aka_K.get_data_length()) != 0) + { + // OK. + eap_status_e status = m_aka_algorithm->set_simulator_aka_k(&m_simulator_aka_K); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_AKA_simulator_aka_k.get_field()->get_field())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + { + eap_status_e status = m_partner->read_configure( + cf_str_EAP_AKA_simulator_aka_op.get_field(), + &m_simulator_aka_OP); + if (status == eap_status_ok + && m_simulator_aka_OP.get_is_valid_data() == true + && m_simulator_aka_OP.get_data_length() > 0ul + && m_simulator_aka_OP.get_data( + m_simulator_aka_OP.get_data_length()) != 0) + { + // OK. + eap_status_e status = m_aka_algorithm->set_simulator_aka_op(&m_simulator_aka_OP); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_AKA_simulator_aka_op.get_field()->get_field())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + { + eap_status_e status = m_partner->read_configure( + cf_str_EAP_AKA_simulator_aka_amf.get_field(), + &m_simulator_aka_AMF); + if (status == eap_status_ok + && m_simulator_aka_AMF.get_is_valid_data() == true + && m_simulator_aka_AMF.get_data_length() == sizeof(u16_t) + && m_simulator_aka_AMF.get_data( + m_simulator_aka_AMF.get_data_length()) != 0) + { + // OK. + eap_status_e status = m_aka_algorithm->set_simulator_aka_amf(&m_simulator_aka_AMF); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_AKA_simulator_aka_amf.get_field()->get_field())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + if (m_pseudonym_key.get_is_valid_data() == false) + { + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Note this function generates cryptographically strong random bytes. + // Here we use those bytes as a secret encryption key. + eap_status_e status = generate_encryption_IV( + &m_pseudonym_key, + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = generate_encryption_IV( + &m_pseudonym_MAC_key, + aes.get_block_size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + ++m_pseudonym_key_index; + } + +#endif // #if defined (USE_EAP_TYPE_SERVER_AKA) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_am_type_aka_symbian_c::shutdown(), m_shutdown_was_called=%d\n"), + (m_is_client == true) ? "client": "server", + m_shutdown_was_called)); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + m_shutdown_was_called = true; + + + if (m_aka_algorithm != 0) + { + m_aka_algorithm->shutdown(); + delete m_aka_algorithm; + m_aka_algorithm = 0; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +void eap_am_type_aka_symbian_c::send_error_notification(const eap_status_e error) +{ + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + // Notifies the lower level of an authentication error. + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, + eap_type_aka, + eap_state_none, + eap_general_state_authentication_error, + 0, + false); + + notification.set_authentication_error(error); + + m_partner->state_notification(¬ification); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::store_pseudonym_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const pseudonym) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Send error if the pseudonym is too long. + if(pseudonym != NULL && pseudonym->get_data_length() > KMaxPseudonymIdLengthInDB) + { + // Pseudonym too long. Can't store this in DB. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::store_pseudonym_id: ") + EAPL("Too long Pseudonym. Length=%d\n"), + pseudonym->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_ok); + + TRAPD(err, store_pseudonym_idL(send_network_id, pseudonym)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_aka_symbian_c::store_pseudonym_idL( + const eap_am_network_id_c * const /*network_id*/, + const eap_variable_data_c * const pseudonym) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Form the insertion command + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, &KPseudonymId, &KAkaTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Update the columns in the database + view.FirstL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Create pointer to the data + if ((pseudonym != NULL) + && (pseudonym->get_is_valid_data() == true)) + { + TPtrC8 pseudonymId( + pseudonym->get_data(pseudonym->get_data_length()), + pseudonym->get_data_length()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("pseudonymId to DB"), + pseudonymId.Ptr(), + pseudonymId.Length())); + + view.SetColL(colSet->ColNo(KPseudonymId), pseudonymId); + } + else + { + // If passed pseudonym was 0 that means the field must be cleared. + view.SetColNullL(colSet->ColNo(KPseudonymId)); + } + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + view.PutL(); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::store_reauthentication_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const reauthentication_identity) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Send error if the reauthentication id is too long. + if(reauthentication_identity != NULL + && reauthentication_identity->get_data_length() > KMaxReauthIdLengthInDB) + { + // Reauth id too long. Can't store this in DB. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::store_reauthentication_id: ") + EAPL("Too long reauth id. Length=%d\n"), + reauthentication_identity->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_ok); + + TRAPD(err, store_reauthentication_idL(send_network_id, reauthentication_identity)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_aka_symbian_c::store_reauthentication_idL( + const eap_am_network_id_c * const /*network_id*/, + const eap_variable_data_c * const reauthentication_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Form the insertion command + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, &KReauthId, &KAkaTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + view.FirstL(); + + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Create pointer to the data + if ((reauthentication_id != NULL) + && (reauthentication_id->get_is_valid_data() == true)) + { + TPtrC8 reauthId( + reauthentication_id->get_data(reauthentication_id->get_data_length()), + reauthentication_id->get_data_length()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("reauthId to DB"), + reauthId.Ptr(), + reauthId.Length())); + + view.SetColL(colSet->ColNo(KReauthId), reauthId); + + } + else + { + // If passed reauthentication_id was 0 that means the field must be cleared. + view.SetColNullL(colSet->ColNo(KReauthId)); + } + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + view.PutL(); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::store_reauth_parameters( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter) +{ + // These kind of wrapper functions are needed because the Symbian L-functions must be executed in + // trap harness. + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Send error if any of the parameters are invalid. + if(XKEY == NULL + || K_aut == NULL + || K_encr == NULL) + { + // Some of the parameters are invalid. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::store_reauth_parameters: ") + EAPL("ERROR: Invalid parameters\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Send error if any of the parameters are too long. + if(XKEY->get_data_length() > KMaxXKeyLengthInDB + || K_aut->get_data_length() > KMaxK_autLengthInDB + || K_encr->get_data_length() > KMaxK_encrLengthInDB ) + { + // Some of the parameters are too long. Can't store them in DB. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::store_reauth_parameters: ") + EAPL("Too long parameters. Length: XKEY=%d, K_aut=%d, K_encr=%d\n"), + XKEY->get_data_length(), K_aut->get_data_length(), K_encr->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_ok); + + TRAPD(err, store_reauth_parametersL(XKEY, K_aut, K_encr, reauth_counter)); + if (err != KErrNone) + { + // Convert the leave error code to EAPOL stack error code. + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_aka_symbian_c::store_reauth_parametersL( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter) +{ + // The _L functions do the actual thing. + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Form the insertion command + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, &KXKey, &KK_aut, &KK_encr, &KReauthCounter, &KAkaTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Create pointers to the data + TPtrC8 key(XKEY->get_data(XKEY->get_data_length()), XKEY->get_data_length()); + TPtrC8 aut(K_aut->get_data(K_aut->get_data_length()), K_aut->get_data_length()); + TPtrC8 enc(K_encr->get_data(K_encr->get_data_length()), K_encr->get_data_length()); + + // Update the columns in the database + view.FirstL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("XKEY to DB"), key.Ptr(), key.Length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("K_aut to DB"), aut.Ptr(), aut.Length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("K_encr to DB"), enc.Ptr(), enc.Length())); + + view.SetColL(colSet->ColNo(KXKey), key); // XKEY + view.SetColL(colSet->ColNo(KK_aut), aut); // K_aut + view.SetColL(colSet->ColNo(KK_encr), enc); // K_encr + view.SetColL(colSet->ColNo(KReauthCounter), reauth_counter); // ReauthCounter + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + view.PutL(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::store_reauth_keys_L(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + reauth_counter)); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::authentication_finished( + const bool true_when_successfull, + const eap_aka_authentication_type_e authentication_type, + const eap_type_aka_identity_type identity_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + TInt err(KErrNone); + + // Store the authentication time if the full authentication is successful + if (true_when_successfull == true + && authentication_type == AKA_AUTHENTICATION_TYPE_FULL_AUTH) + { + TRAP(err,store_authentication_timeL()); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + } + + if (true_when_successfull == false) + { + if( identity_type == AKA_IDENTITY_TYPE_IMSI_ID + || identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID ) + { + (void) store_pseudonym_id(0,0); + } + + if( identity_type == AKA_IDENTITY_TYPE_IMSI_ID + || identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID ) + { + (void) store_reauthentication_id(0,0); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_reauth_parameters( + eap_variable_data_c * const XKEY, + eap_variable_data_c * const K_aut, + eap_variable_data_c * const K_encr, + u32_t * const reauth_counter) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_ok); + + TRAPD(err, query_reauth_parametersL(XKEY, K_aut, K_encr, reauth_counter)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_aka_symbian_c::query_reauth_parametersL( + eap_variable_data_c * const XKEY, + eap_variable_data_c * const reauth_K_aut, + eap_variable_data_c * const reauth_K_encr, + u32_t * const reauth_counter) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Form the query + _LIT(KSQLQuery, "SELECT %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KXKey, &KK_aut, &KK_encr, &KReauthCounter, &KAkaTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the values from DB + TPtrC8 key = view.ColDes8(colSet->ColNo(KXKey)); + TPtrC8 aut = view.ColDes8(colSet->ColNo(KK_aut)); + TPtrC8 enc = view.ColDes8(colSet->ColNo(KK_encr)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("XKEY from DB"), key.Ptr(), key.Length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("K_aut from DB"), aut.Ptr(), aut.Length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("K_encr from DB"), enc.Ptr(), enc.Length())); + + eap_status_e status(eap_status_process_general_error); + + // Store the values to the supplied buffers + status = XKEY->set_copy_of_buffer(key.Ptr(),key.Length()); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + + status = reauth_K_aut->set_copy_of_buffer(aut.Ptr(),aut.Length()); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + + status = reauth_K_encr->set_copy_of_buffer(enc.Ptr(),enc.Length()); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + + *reauth_counter = view.ColUint(colSet->ColNo(KReauthCounter)); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::query_reauth_parametersL(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + *reauth_counter)); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::increase_reauth_counter() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_ok); + + TRAPD(err, increase_reauth_counterL()); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_aka_symbian_c::increase_reauth_counterL() +{ + // Form the insertion command + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, &KReauthCounter, &KAkaTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the previous value + TUint counter = view.ColUint(colSet->ColNo(KReauthCounter)); + + view.UpdateL(); + + // Increment the value + view.SetColL(colSet->ColNo(KReauthCounter), counter + 1); + + counter = view.ColUint(colSet->ColNo(KReauthCounter)); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::increase_reauth_counterL(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + counter)); + + view.PutL(); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_AKA_IMSI_or_pseudonym_or_reauthentication_id( + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const /*length_of_mnc*/, + const aka_payload_AT_type_e required_identity, ///< This parameter indicated the type of identity required. + const eap_type_aka_complete_e required_completion, ///< This parameter tells the required completion after this call is completed, if this is asyncronous. Use this value with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + const u8_t received_eap_identifier ///< This is the EAP-identifier of the received EAP-request message. Use this value with abs_eap_am_type_aka_c::complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() function call. + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + EAP_ASSERT((IMSI != 0) && (pseudonym_identity != 0) && (reauthentication_identity != 0)); + + m_stored_required_completion = required_completion; + m_stored_received_eap_identifier = received_eap_identifier; + + TRAPD(err, query_AKA_IMSI_or_pseudonym_or_reauthentication_idL(IMSI, + pseudonym_identity, + reauthentication_identity, + automatic_realm, + required_identity, + required_completion, + received_eap_identifier)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + + if (status != eap_status_pending_request) + { + send_error_notification(status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_aka_symbian_c::query_AKA_IMSI_or_pseudonym_or_reauthentication_idL( + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + const aka_payload_AT_type_e required_identity, + const eap_type_aka_complete_e /*required_completion*/, + const u8_t /*received_eap_identifier*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Reset everything + IMSI->reset(); + pseudonym_identity->reset(); + reauthentication_identity->reset(); + automatic_realm->reset(); + m_stored_pseudonym.reset(); + m_stored_reauth_id.reset(); + m_previous_imsi.reset(); + + _LIT(KSQLQuery, "SELECT %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KReauthId, &KReauthCounter, &KPseudonymId, + &KPreviousIMSI, &KAkaTableName, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the values + TUint reauthCount = view.ColUint32(colSet->ColNo(KReauthCounter)); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("query_AKA_IMSI_or_pseudonym_or_reauthentication_idL: ") + EAPL("required_identity=%d, reauthCount from DB %d\n"), + required_identity, reauthCount)); + + // A stream is needed for LONG columns in DB. + RDbColReadStream readStream; + + // Get pseudonym ID from DB. + HBufC8* pseudonymIdBuf = HBufC8::NewLC(KMaxPseudonymIdLengthInDB); // Buffer for pseudonym id. + TPtr8 pseudonymId = pseudonymIdBuf->Des(); + + readStream.OpenLC(view, colSet->ColNo(KPseudonymId)); + readStream.ReadL(pseudonymId, view.ColLength(colSet->ColNo(KPseudonymId))); + readStream.Close(); + CleanupStack::Pop(&readStream); // Pop readStream. + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("pseudonymId from DB"), pseudonymId.Ptr(), pseudonymId.Length())); + + // Get reauthentication ID from DB. + HBufC8* reauthIdBuf = HBufC8::NewLC(KMaxReauthIdLengthInDB); // Buffer for reauthentication id. + TPtr8 reauthId = reauthIdBuf->Des(); + + readStream.OpenLC(view, colSet->ColNo(KReauthId)); + readStream.ReadL(reauthId, view.ColLength(colSet->ColNo(KReauthId))); + readStream.Close(); + CleanupStack::Pop(&readStream); // Pop readStream. + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("reauthId from DB"), reauthId.Ptr(), reauthId.Length())); + +#if defined(USE_EAP_AKA_INTERFACE) && !defined(__WINS__) + + // Get the previous IMSI. Used for checking if SIM has been changed. + // The checking is done in complete_AKA_imsi_L + + TPtrC8 tmp_imsi = view.ColDes8(colSet->ColNo(KPreviousIMSI)); + + status = m_previous_imsi.set_copy_of_buffer(tmp_imsi.Ptr(), tmp_imsi.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("imsi from DB"), tmp_imsi.Ptr(), tmp_imsi.Size())); + +#endif + + if (required_identity == aka_payload_AT_ANY_ID_REQ) + { + if (is_session_valid() ) + { + if(reauthId.Length() > 0) + { + +#if defined(USE_EAP_AKA_INTERFACE) && !defined(__WINS__) + // Store the reauth id in case we are using asynchronous processing (= ISA interface) + status = m_stored_reauth_id.set_copy_of_buffer(reauthId.Ptr(), reauthId.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } +#endif + status = reauthentication_identity->set_copy_of_buffer(reauthId.Ptr(), reauthId.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + } + } + } + + CleanupStack::PopAndDestroy(reauthIdBuf); // Delete reauthIdBuf + + if (required_identity == aka_payload_AT_ANY_ID_REQ + || required_identity == aka_payload_AT_FULLAUTH_ID_REQ) + { + if (pseudonymId.Length() > 0) + { + +#if defined(USE_EAP_AKA_INTERFACE) && !defined(__WINS__) + // Store the pseudonym in case we are using + // asynchronous processing (= ISA interface) + status = m_stored_pseudonym.set_copy_of_buffer( + pseudonymId.Ptr(), + pseudonymId.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } +#endif + status = pseudonym_identity->set_copy_of_buffer( + pseudonymId.Ptr(), + pseudonymId.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + } + } + + CleanupStack::PopAndDestroy(pseudonymIdBuf); // Delete pseudonymIdBuf + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + CleanupStack::PopAndDestroy( &view ); // Close view. + + CleanupStack::PopAndDestroy(buf); // Delete buf + + if (IMSI->get_is_valid_data() == false + || IMSI->get_buffer_length() < AKA_IMSI_LENGTH) + { + status = IMSI->init(AKA_IMSI_LENGTH); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + IMSI->set_is_valid(); + } + + { + +#if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__) + + // For real AKA USIM interface. + // Use real AKA interface active object. + // This gets the IMSI from the real USIM, using Custom API. + + m_aka_if->QueryIMSIL(); + + // KErrCompletion means that the operation is pending. + User::Leave(KErrCompletion); + +#elif defined(__WINS__) // For plugin tester. + + // Here we get the Nokia test SIM IMSI since the USIM interface is disabled. + u32_t imsi_length = 0u; + + status = query_SIM_imsi( + IMSI->get_buffer(AKA_IMSI_LENGTH), + AKA_IMSI_LENGTH, + &imsi_length); + + if (status != eap_status_ok + || imsi_length != AKA_IMSI_LENGTH) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + + status = IMSI->set_data_length(imsi_length); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + +#endif // End of #if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__) + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_aka_symbian_c::complete_AKA_imsi_L( + const eap_variable_data_c * const IMSI, + const eap_status_e completion_status ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_process_general_error); + + if (completion_status != eap_status_ok) + { + // IMSI query failed + status = get_am_partner()->complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query( + IMSI, + &m_stored_pseudonym, + &m_stored_reauth_id, + 0, + EAP_TYPE_AKA_DEFAULT_MNC_LENGTH_3_BYTES, + m_stored_required_completion, + m_stored_received_eap_identifier, + completion_status); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + if (IMSI == 0 + || IMSI->get_is_valid_data() == false) + { + // IMSI query failed + status = get_am_partner()->complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query( + IMSI, + &m_stored_pseudonym, + &m_stored_reauth_id, + 0, + EAP_TYPE_AKA_DEFAULT_MNC_LENGTH_3_BYTES, + m_stored_required_completion, + m_stored_received_eap_identifier, + eap_status_hardware_not_ready); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + if (m_previous_imsi.get_data_length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Previous IMSI not valid. Storing new IMSI.\n"))); + + // Store new IMSI + status = store_imsi(IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (IMSI->compare(&m_previous_imsi) != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIM has been changed since last authentication. ") + EAPL("Clear pseudonym & reauth IDs.\n"))); + + // Different IMSI -> SIM has been changed. + // Reset pseudonym and reauthentication ID. + status = store_reauthentication_id(0, 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = store_pseudonym_id(0, 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + // Store new IMSI + status = store_imsi(IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + // Reset stored pseudonym & reauthentication ID + m_stored_pseudonym.reset(); + m_stored_reauth_id.reset(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIM has not been changed.\n"))); + } + + status = get_am_partner()->complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query( + IMSI, + &m_stored_pseudonym, + &m_stored_reauth_id, + 0, + 0ul, + m_stored_required_completion, + m_stored_received_eap_identifier, + eap_status_ok); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return status; +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_aka_symbian_c::store_imsi( + const eap_variable_data_c * const imsi) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Send error if the IMSI is too long. + if(imsi != NULL && imsi->get_data_length() > KMaxIMSILengthInDB) + { + // IMSI too long. Can't store this in DB. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::store_imsi: ") + EAPL("Too long IMSI. Length=%d\n"), + imsi->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_ok); + + TRAPD(err, store_imsiL(imsi)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_aka_symbian_c::store_imsiL( + const eap_variable_data_c * const imsi) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Form the insertion command + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, &KPreviousIMSI, &KAkaTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + // Evaluate view + RDbView view; + + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + view.FirstL(); + + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Create pointer to the data + if ((imsi != 0) + && (imsi->get_is_valid_data() == true)) + { + TPtrC8 tmp_imsi( + imsi->get_data(imsi->get_data_length()), + imsi->get_data_length()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("IMSI to DB"), tmp_imsi.Ptr(), tmp_imsi.Length())); + + view.SetColL(colSet->ColNo(KPreviousIMSI), tmp_imsi); + } + else + { + // If passed IMSI was 0 that means the field must be cleared. + view.SetColNullL(colSet->ColNo(KPreviousIMSI)); + } + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + view.PutL(); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::cancel_AKA_IMSI_or_pseudonym_or_reauthentication_id_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); +#if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__) + if (m_is_client == true) + { + m_aka_if->Cancel(); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +#else + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_not_supported; +#endif +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_AKA_RES( + eap_type_aka_authentication_vector_c * const authentication_vector) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE if user needs to use state_selector or n_rands after return from query_AKA_RES() + // function those parameters MUST be copied using copy() member function of each parameter. + // For example: saved_n_rands = n_rands->copy() + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (authentication_vector == 0 + || authentication_vector->get_is_valid() == false) + { + // Something is really wrong. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + eap_status_e status = eap_status_process_general_error; + + if (authentication_vector->get_RAND()->get_is_valid_data() == false) + { + // No RAND. cannot continue. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + if (authentication_vector->get_AUTN()->get_is_valid_data() == false) + { + // No AUTN. cannot continue. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Update the member variables with current values for RAND and AUTN. + // These are needed for synchronization failure. + status = m_RAND.set_copy_of_buffer( authentication_vector->get_RAND() ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_AUTN.set_copy_of_buffer( authentication_vector->get_AUTN() ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if !defined (USE_EAP_AKA_INTERFACE) + + if (authentication_vector == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = m_aka_algorithm->generate_RES( authentication_vector ); + +#elif !defined(__WINS__) + + TRAPD(err, m_aka_if->QueryRESL( &m_RAND , &m_AUTN ); ); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + if (status == eap_status_process_general_error) + { + status = eap_status_credential_query_failed; + } + send_error_notification(status); + } + else + { + status = eap_status_pending_request; + } +#endif //#if !defined (USE_EAP_AKA_INTERFACE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_aka_symbian_c::complete_AKA_RES_L( + eap_variable_data_c * const aRES, + eap_variable_data_c * const aCK, + eap_variable_data_c * const aIK, + eap_variable_data_c * const aAUTS, + eap_status_e authenticationStatus, + const eap_status_e completion_status ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + +#if !defined(USE_EAP_AKA_INTERFACE) || defined(__WINS__) + + EAP_UNREFERENCED_PARAMETER(aRES); + EAP_UNREFERENCED_PARAMETER(aCK); + EAP_UNREFERENCED_PARAMETER(aIK); + EAP_UNREFERENCED_PARAMETER(aAUTS); + EAP_UNREFERENCED_PARAMETER(authenticationStatus); + EAP_UNREFERENCED_PARAMETER(completion_status); + +#else + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("complete_AKA_RES_L\n"))); + + eap_type_aka_authentication_vector_c authentication_vector( m_am_tools ); + + if (completion_status != eap_status_ok) + { + // Signal upper layer about the failure. + status = get_am_partner()->complete_AKA_RES_query( &authentication_vector, completion_status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (aRES == 0 || aRES->get_is_valid() == false || + aCK == 0 || aCK->get_is_valid() == false || + aIK == 0 || aIK->get_is_valid() == false || + aAUTS == 0 || aAUTS->get_is_valid() == false ) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = authentication_vector.get_RES()->set_copy_of_buffer( aRES ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = authentication_vector.get_CK()->set_copy_of_buffer( aCK ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = authentication_vector.get_IK()->set_copy_of_buffer( aIK ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = authentication_vector.get_AUTS()->set_copy_of_buffer( aAUTS ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Copy RAND and AUTN also. They are needed in case of synchronization failure. + + status = authentication_vector.get_RAND()->set_copy_of_buffer( &m_RAND ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = authentication_vector.get_AUTN()->set_copy_of_buffer( &m_AUTN ); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + authentication_vector.set_vector_status(authenticationStatus); + + // Complete request. + status = get_am_partner()->complete_AKA_RES_query( &authentication_vector, eap_status_ok); + + if (status == eap_status_ok) + { + status = eap_status_completed_request; + } +#endif + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::cancel_AKA_RES_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); +#if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__) + if (m_is_client == true) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_aka_symbian_c::cancel_AKA_RES_query() - cancelling IF query\n"))); + + m_aka_if->Cancel(); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +#else + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +#endif +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::handle_aka_notification( + eap_aka_notification_codes_e aka_notification_code) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + switch ((aka_notification_code & aka_notification_code_value)) + { + case eap_aka_notification_no_F_no_P_user_has_not_subscribed_to_the_requested_service: + send_error_notification(eap_status_user_has_not_subscribed_to_the_requested_service); + break; + + case eap_aka_notification_no_F_no_P_users_calls_are_barred: + send_error_notification(eap_status_users_calls_are_barred); + break; + + default: + // Do nothing + break; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_AKA_authentication_vector( + const eap_variable_data_c * const username, ///< // This is payload AT_IDENTITY. If this is uninitialized then imsi must be initialized. + const u8_t next_eap_identifier, + eap_variable_data_c * const imsi, ///< This is the real IMSI. If this is uninitialized then username must be initialized and imsi will be initialized after this call. + eap_type_aka_authentication_vector_c * const authentication_vector, + eap_type_aka_identity_type * const type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // NOTE if user needs to use state_selector or imsi after return from query_AKA_authentication_vector() + // function those parameters MUST be copied using copy() member function of each parameter. + // For example: saved_imsi = p_imsi_or_pseudonym->copy() + // saved_state_selector = state_selector->copy() + + eap_status_e status = eap_status_process_general_error; + +#if defined (USE_EAP_TYPE_SERVER_AKA) + + if (username == 0 + || imsi == 0 + || authentication_vector == 0 + || type == 0) + { + // Something is really wrong. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (username->get_is_valid_data() == false + && imsi->get_is_valid_data() == false) + { + // Something is really wrong. + // Only one of these must be set. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + if (username->get_is_valid_data() == true + && imsi->get_is_valid_data() == false) + { + // We must query IMSI. + + // This is akaple test. + query_imsi_from_username_syncronous( + 0u, + 0, + username, + imsi, + type); + + if (imsi->get_is_valid_data() == false + || imsi->get_data_length() != m_am_tools->strlen(TEST_IMSI) + || m_am_tools->memcmp(imsi->get_data(imsi->get_data_length()), TEST_IMSI, imsi->get_data_length()) != 0) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: MAC of identity differs.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + else if (imsi->get_is_valid_data() == true) + { + *type = AKA_IDENTITY_TYPE_IMSI_ID; + } + + { + status = m_aka_algorithm->generate_authentication_vector( + authentication_vector); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("query_AKA_authentication_vector(): Used EAP-Identity type %d.\n"), + *type)); + + m_next_eap_identifier = next_eap_identifier; + + m_aka_authentication_vector_status = eap_aka_authentication_vector_status_ok; + + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("AKA: %s: direct_complete_function: complete_AKA_authentication_vector_query()\n"), + (m_is_client == true ? "client": "server"))); + + status = get_am_partner()->complete_AKA_authentication_vector_query( + authentication_vector, + imsi, + m_aka_authentication_vector_status, + *type, + eap_status_ok, + next_eap_identifier); + if (status == eap_status_ok) + { + status = eap_status_completed_request; + } + } +#else + + EAP_UNREFERENCED_PARAMETER(username); + EAP_UNREFERENCED_PARAMETER(next_eap_identifier); + EAP_UNREFERENCED_PARAMETER(imsi); + EAP_UNREFERENCED_PARAMETER(authentication_vector); + EAP_UNREFERENCED_PARAMETER(type); + +#endif // #if !defined (USE_EAP_TYPE_SERVER_AKA) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::cancel_AKA_authentication_vector_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#if !defined (USE_EAP_TYPE_SERVER_AKA) + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("cancel_AKA_authentication_vector_query()\n"))); + + delete m_authentication_vector; + m_authentication_vector = 0; + +#endif // #if !defined (USE_EAP_TYPE_SERVER_AKA) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::generate_encryption_IV( + eap_variable_data_c * const encryption_IV, + const u32_t IV_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_process_general_error; + + status = encryption_IV->init(IV_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + encryption_IV->set_is_valid(); + encryption_IV->set_data_length(IV_length); + + m_am_tools->get_crypto()->add_rand_seed_hw_ticks(); + + status = m_am_tools->get_crypto()->get_rand_bytes( + encryption_IV->get_data(encryption_IV->get_data_length()), + encryption_IV->get_data_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::generate_pseudonym_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const pseudonym_identity, + const u32_t maximum_pseudonym_length) +{ + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + +#if defined (USE_EAP_TYPE_SERVER_AKA) + + // From AKA simulator code. + // This is an example. + + return generate_identity( + AKA_IDENTITY_TYPE_PSEUDONYM_ID, + imsi, + pseudonym_identity, + maximum_pseudonym_length); +#else + + EAP_UNREFERENCED_PARAMETER(send_network_id); + EAP_UNREFERENCED_PARAMETER(imsi); + EAP_UNREFERENCED_PARAMETER(pseudonym_identity); + EAP_UNREFERENCED_PARAMETER(maximum_pseudonym_length); + + // This function shouldn't be called for other than server. + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + +#endif // #if defined (USE_EAP_TYPE_SERVER_AKA) + +} + +//-------------------------------------------------- + +#if defined (USE_EAP_TYPE_SERVER_AKA) + // These functions are used only for server side. + +eap_status_e eap_am_type_aka_symbian_c::generate_identity( + const eap_type_aka_identity_type identity_type, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const pseudonym, + const u32_t maximum_pseudonym_length) +{ + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // From AKA simulator code. + + // This is an example. + + eap_status_e status = eap_status_process_general_error; + + //return eap_status_not_supported; // This will disable pseudonym and re-authentication idetities. + + // Here pseydonym indentity includes encrypted IMSI. + // This causes the client to be database of it's own pseudonym identity. + // Server stores only one or more global encryption key. + // Encryption key is indexed by encryption_key_index attribute of pseudonym. + // Server could store old keys some time after a new key is changed. + // + // --------time------------> + // + // +---Key-1-------+ + // +---Key-2------+ + // +---Key-3------+ + // +---Key-4------+ + // + + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c encryption_IV(m_am_tools); + + { + status = generate_encryption_IV( + &encryption_IV, + aes.get_block_size()); + } + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c tmp_pseudonym(m_am_tools); + status = tmp_pseudonym.set_buffer_length(sizeof(eap_aka_pseudonym_s)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + tmp_pseudonym.set_data_length(sizeof(eap_aka_pseudonym_s)); + eap_aka_pseudonym_s * const str_pseudonym + = reinterpret_cast(tmp_pseudonym.get_data( + sizeof(eap_aka_pseudonym_s))); + + m_am_tools->memset(str_pseudonym, 0, sizeof(*str_pseudonym)); + + str_pseudonym->imsi_block.imsi_length = static_cast(imsi->get_data_length()); + if (identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID) + { + str_pseudonym->imsi_block.id_type = 0; + } + else if (identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID) + { + str_pseudonym->imsi_block.id_type = 1; + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + str_pseudonym->encryption_key_index = m_pseudonym_key_index; + + m_am_tools->memmove( + str_pseudonym->encryption_IV.IV_8, + encryption_IV.get_data(aes.get_block_size()), + sizeof(str_pseudonym->encryption_IV.IV_8)); + m_am_tools->memmove( + str_pseudonym->imsi_block.imsi_and_padding, + imsi->get_data(imsi->get_data_length()), + imsi->get_data_length()); + + u32_t imsi_data_length = sizeof(u8_t)+imsi->get_data_length(); + + u32_t cbc_aes_data_length = 0u; + if ((imsi_data_length % aes.get_block_size()) != 0u) + { + cbc_aes_data_length = imsi_data_length + (aes.get_block_size() - (aes.get_block_size() % imsi_data_length)); + } + else + { + cbc_aes_data_length = imsi_data_length; + } + + u32_t padding_bytes_length = cbc_aes_data_length - imsi_data_length; + + if (padding_bytes_length > 0u) + { + cbc_aes.add_padding_bytes( + &(str_pseudonym->imsi_block.imsi_and_padding[str_pseudonym->imsi_block.imsi_length]), + padding_bytes_length, + 0ul); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym struct"), + reinterpret_cast(str_pseudonym), + sizeof(*str_pseudonym))); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym IV"), + encryption_IV.get_data(encryption_IV.get_data_length()), + encryption_IV.get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym encryption key"), + m_pseudonym_key.get_data(m_pseudonym_key.get_data_length()), + m_pseudonym_key.get_data_length())); + + status = cbc_aes.set_encryption_key( + encryption_IV.get_data(encryption_IV.get_data_length()), + encryption_IV.get_data_length(), + m_pseudonym_key.get_data(m_pseudonym_key.get_data_length()), + m_pseudonym_key.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = cbc_aes.encrypt_data( + &(str_pseudonym->imsi_block), + sizeof(str_pseudonym->imsi_block)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + crypto_sha1_c sha1(m_am_tools); + crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false); + + if (hmac_sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym MAC key"), + m_pseudonym_MAC_key.get_data(m_pseudonym_MAC_key.get_data_length()), + m_pseudonym_MAC_key.get_data_length())); + + if (hmac_sha1.hmac_set_key( + &m_pseudonym_MAC_key + ) != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + hmac_sha1.hmac_update( + reinterpret_cast(str_pseudonym), + sizeof(*str_pseudonym)-sizeof(str_pseudonym->MAC)); + + u32_t length = EAP_TYPE_AKA_MAC_SIZE; + + hmac_sha1.hmac_128_final( + str_pseudonym->MAC, + &length); + + EAP_ASSERT(length == EAP_TYPE_AKA_MAC_SIZE); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym data"), + tmp_pseudonym.get_data(tmp_pseudonym.get_data_length()), + tmp_pseudonym.get_data_length())); + + // NOTE this does not add any security. + // This will only scramble encryption key index. + str_pseudonym->encryption_key_index ^= + (str_pseudonym->encryption_IV.IV_32[0] + + str_pseudonym->encryption_IV.IV_32[1] + + str_pseudonym->encryption_IV.IV_32[2] + + str_pseudonym->encryption_IV.IV_32[3] + + ENCRYPTION_KEY_INDEX_SCRAMBLE_CONST); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym data"), + tmp_pseudonym.get_data(tmp_pseudonym.get_data_length()), + tmp_pseudonym.get_data_length())); + + pseudonym->init(3ul+(sizeof(*str_pseudonym)+1u)*4u/3u); + pseudonym->set_is_valid(); + pseudonym->set_data_length(pseudonym->get_buffer_length()); + + u32_t pseudonym_length = pseudonym->get_data_length(); + + status = m_am_tools->convert_bytes_to_ascii_armor( + tmp_pseudonym.get_data_offset(0u, tmp_pseudonym.get_data_length()), + tmp_pseudonym.get_data_length(), + pseudonym->get_data_offset(0u, pseudonym->get_data_length()), + &pseudonym_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (pseudonym_length > maximum_pseudonym_length) + { + pseudonym_length = maximum_pseudonym_length; + } + pseudonym->set_data_length(pseudonym_length); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym"), + pseudonym->get_data(pseudonym->get_data_length()), + pseudonym->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_aka_symbian_c::query_imsi_from_username_syncronous( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_type_aka_identity_type * const identity_type) +{ + // Note this is syncronous call. + if (network_id == 0 + || username == 0 + || imsi == 0 + || identity_type == 0) + { + // Something is really wrong. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + + crypto_aes_c aes(m_am_tools); + crypto_cbc_c cbc_aes(m_am_tools, &aes, false); + + if (cbc_aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_status_e status = eap_status_process_general_error; + + const u8_t * const username_prefix = username->get_data_offset(0u, 1u); + + if (username->get_data_length() <= AKA_IMSI_LENGTH+1u + && username->get_data_length() > 1u + && username_prefix != 0 + && *username_prefix == *AKA_IMSI_PREFIX_CHARACTER + && check_is_valid_imsi(username) == eap_status_ok) + { + // We have IMSI. + status = imsi->set_copy_of_buffer( + username->get_data_offset(1u, username->get_data_length()-1u), + username->get_data_length()-1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *identity_type = AKA_IDENTITY_TYPE_IMSI_ID; + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IMSI"), + imsi->get_data(imsi->get_data_length()), + imsi->get_data_length())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("query_imsi_from_username(): Used EAP-Identity type %d.\n"), + *identity_type)); + + status = eap_status_ok; + } + else if (username->get_data_length() > aes.get_block_size() + && username->get_data_length() > sizeof(eap_aka_pseudonym_s)) + { + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("username"), + username->get_data(username->get_data_length()), + username->get_data_length())); + + // We have pseudonym_identity. + eap_variable_data_c tmp_imsi(m_am_tools); + tmp_imsi.set_buffer_length(sizeof(eap_aka_pseudonym_s)+1u); + tmp_imsi.set_data_length(sizeof(eap_aka_pseudonym_s)+1u); + u32_t tmp_imsi_length = tmp_imsi.get_data_length(); + + eap_aka_pseudonym_s * const str_pseudonym = reinterpret_cast(tmp_imsi.get_data_offset(0u, tmp_imsi.get_data_length())); + if (str_pseudonym == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + status = m_am_tools->restore_bytes_from_ascii_armor( + username->get_data_offset(0u, username->get_data_length()), + username->get_data_length(), + tmp_imsi.get_data_offset(0u, tmp_imsi.get_data_length()), + &tmp_imsi_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + tmp_imsi.set_data_length(tmp_imsi_length); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym data"), + tmp_imsi.get_data(tmp_imsi.get_data_length()), + tmp_imsi.get_data_length())); + + // NOTE this does not add any security. + // This will only scramble encryption key index. + str_pseudonym->encryption_key_index ^= + (str_pseudonym->encryption_IV.IV_32[0] + + str_pseudonym->encryption_IV.IV_32[1] + + str_pseudonym->encryption_IV.IV_32[2] + + str_pseudonym->encryption_IV.IV_32[3] + + ENCRYPTION_KEY_INDEX_SCRAMBLE_CONST); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym data"), + tmp_imsi.get_data(tmp_imsi.get_data_length()), + tmp_imsi.get_data_length())); + + status = eap_status_illegal_eap_identity; + + if ((m_pseudonym_key_index == str_pseudonym->encryption_key_index + || m_pseudonym_key_index-1u == str_pseudonym->encryption_key_index) + && tmp_imsi.get_data_length() == sizeof(eap_aka_pseudonym_s)) + { + const eap_variable_data_c *test_pseudonym_key = &m_pseudonym_key; + const eap_variable_data_c *test_pseudonym_MAC_key = &m_pseudonym_MAC_key; + + if (m_pseudonym_key_index-1u == str_pseudonym->encryption_key_index) + { + test_pseudonym_key = &m_prev_pseudonym_key; + test_pseudonym_MAC_key = &m_prev_pseudonym_MAC_key; + } + + { + crypto_sha1_c sha1(m_am_tools); + crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false); + + if (hmac_sha1.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym MAC key"), + test_pseudonym_MAC_key->get_data(test_pseudonym_MAC_key->get_data_length()), + test_pseudonym_MAC_key->get_data_length())); + + if (hmac_sha1.hmac_set_key( + test_pseudonym_MAC_key + ) != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + hmac_sha1.hmac_update( + reinterpret_cast(str_pseudonym), + sizeof(*str_pseudonym)-sizeof(str_pseudonym->MAC)); + + u32_t length = EAP_TYPE_AKA_MAC_SIZE; + u8_t tmp_MAC[EAP_TYPE_AKA_MAC_SIZE]; + + hmac_sha1.hmac_128_final( + tmp_MAC, + &length); + + EAP_ASSERT(length == EAP_TYPE_AKA_MAC_SIZE); + + if (m_am_tools->memcmp(tmp_MAC, str_pseudonym->MAC, EAP_TYPE_AKA_MAC_SIZE) != 0) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: MAC of identity differs.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym decryption key"), + test_pseudonym_key->get_data(test_pseudonym_key->get_data_length()), + test_pseudonym_key->get_data_length())); + + status = cbc_aes.set_decryption_key( + str_pseudonym->encryption_IV.IV_8, + sizeof(str_pseudonym->encryption_IV.IV_8), + test_pseudonym_key->get_data(test_pseudonym_key->get_data_length()), + test_pseudonym_key->get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = cbc_aes.decrypt_data( + &(str_pseudonym->imsi_block), + sizeof(str_pseudonym->imsi_block)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym struct"), + reinterpret_cast(str_pseudonym), + sizeof(*str_pseudonym))); + + u32_t imsi_length = static_cast(str_pseudonym->imsi_block.imsi_length); + + if (imsi_length < 0u + || imsi_length > AKA_IMSI_LENGTH) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: IMSI length illegal.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + + if (str_pseudonym->imsi_block.id_type == 0) + { + *identity_type = AKA_IDENTITY_TYPE_PSEUDONYM_ID; + } + else if (str_pseudonym->imsi_block.id_type == 1) + { + *identity_type = AKA_IDENTITY_TYPE_RE_AUTH_ID; + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + + + status = imsi->set_copy_of_buffer( + str_pseudonym->imsi_block.imsi_and_padding, + imsi_length); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IMSI"), + imsi->get_data(imsi->get_data_length()), + imsi->get_data_length())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("query_imsi_from_username(): Used EAP-Identity type %d.\n"), + *identity_type)); + + if (m_pseudonym_key_use_count < MAX_PSEUDONYM_USE_COUNT+MAX_REAUTH_USE_COUNT) + { + ++m_pseudonym_key_use_count; + } + else + { + { + crypto_aes_c aes(m_am_tools); + + if (aes.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Note this function generates cryptographically strong random bytes. + // Here we use those bytes as a secret encryption key. + eap_status_e status = m_prev_pseudonym_key.set_copy_of_buffer(&m_pseudonym_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = generate_encryption_IV( + &m_pseudonym_key, + aes.get_block_size()); + if (status == eap_status_ok) + { + status = m_prev_pseudonym_MAC_key.set_copy_of_buffer(&m_pseudonym_MAC_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = generate_encryption_IV( + &m_pseudonym_MAC_key, + aes.get_block_size()); + if (status == eap_status_ok) + { + } + } + ++m_pseudonym_key_index; + m_pseudonym_key_use_count = 0u; + } + } + } + else + { + if (m_pseudonym_key_index != str_pseudonym->encryption_key_index) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: MAC key index differs, %lu != %lu.\n"), + m_pseudonym_key_index, + str_pseudonym->encryption_key_index)); + } + else if (tmp_imsi.get_data_length() == sizeof(eap_aka_pseudonym_s)) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: pseudonym length differs, %lu != %lu.\n"), + tmp_imsi.get_data_length(), + sizeof(eap_aka_pseudonym_s))); + } + + status = eap_status_illegal_eap_identity; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("WARNING: illegal username.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_illegal_eap_identity; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif // #if defined (USE_EAP_TYPE_SERVER_AKA) + +//-------------------------------------------------- + +eap_status_e eap_am_type_aka_symbian_c::generate_reauthentication_id( + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const reauthentication_identity, + const u32_t maximum_reauthentication_identity_length) +{ + // From AKA simulator code. + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // This is an example. + + eap_status_e status = eap_status_process_general_error; + +#if defined (USE_EAP_TYPE_SERVER_AKA) + + status = generate_identity( + AKA_IDENTITY_TYPE_RE_AUTH_ID, + imsi, + reauthentication_identity, + maximum_reauthentication_identity_length); + if (status != eap_status_ok) + { + reauthentication_identity->reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_nai_realm.get_is_valid_data() == true + && m_nai_realm.get_data_length() > 0ul) + { + status = reauthentication_identity->add_data(reinterpret_cast(AKA_AT_CHARACTER), 1u); + if (status != eap_status_ok) + { + reauthentication_identity->reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = reauthentication_identity->add_data(&m_nai_realm); + if (status != eap_status_ok) + { + reauthentication_identity->reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } +#else + + EAP_UNREFERENCED_PARAMETER(send_network_id); + EAP_UNREFERENCED_PARAMETER(imsi); + EAP_UNREFERENCED_PARAMETER(reauthentication_identity); + EAP_UNREFERENCED_PARAMETER(maximum_reauthentication_identity_length); + +#endif // #if defined (USE_EAP_TYPE_SERVER_AKA) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_imsi_from_username( + const u8_t next_eap_identifier, + const eap_am_network_id_c * const send_network_id, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_type_aka_identity_type * const type, + const eap_type_aka_complete_e completion_action) +{ + // From AKA simulator code. + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Note this is asyncronous call. + + eap_status_e status = eap_status_process_general_error; + +#if defined (USE_EAP_TYPE_SERVER_AKA) + + m_identity_type = AKA_IDENTITY_TYPE_NONE; + m_next_eap_identifier = 0; + m_completion_action = eap_type_aka_complete_none; + m_username.reset(); + m_IMSI.reset(); + + status = query_imsi_from_username_syncronous( + next_eap_identifier, + send_network_id, + username, + imsi, + type); + if (status != eap_status_ok) + { + // Do not return immediately. + // Here we test the asyncronous completion. + } + + { + status = get_am_partner()->complete_imsi_from_username( + next_eap_identifier, + send_network_id, + username, + imsi, + *type, + eap_status_ok, + completion_action); + + if (status == eap_status_ok) + { + status = eap_status_completed_request; + } + } +#else + + EAP_UNREFERENCED_PARAMETER(next_eap_identifier); + EAP_UNREFERENCED_PARAMETER(send_network_id); + EAP_UNREFERENCED_PARAMETER(username); + EAP_UNREFERENCED_PARAMETER(imsi); + EAP_UNREFERENCED_PARAMETER(type); + EAP_UNREFERENCED_PARAMETER(completion_action); + +#endif // #if defined (USE_EAP_TYPE_SERVER_AKA) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_re_syncronization( + const u8_t /*next_eap_identifier*/, + eap_type_aka_authentication_vector_c * const /*authentication_vector*/ + ) +{ + /********** For server.**********/ + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::cancel_imsi_from_username_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT(data != 0); + + eap_status_e status(eap_status_ok); + + // Trap must be set here because the OS independent portion of EAP AKA + // that calls this function does not know anything about Symbian. + TRAPD(err, type_configure_readL( + field->get_field(), + field->get_field_length(), + data)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::type_configure_read(): LEAVE from type_configure_readL, error=%d, Reads configuration from partner.\n"), + err)); + + status = m_partner->read_configure( + field, + data); + } + + m_am_tools->trace_configuration( + status, + field, + data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_aka_symbian_c::type_configure_readL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(field_length); + + // Create a buffer for the ascii strings - initialised with the argument + HBufC8* asciibuf = HBufC8::NewLC(KMaxDBFieldNameLength); + TPtr8 asciiString = asciibuf->Des(); + asciiString.Copy(reinterpret_cast(field)); + + // Buffer for unicode parameter + HBufC* unicodebuf = HBufC::NewLC(KMaxDBFieldNameLength); + TPtr unicodeString = unicodebuf->Des(); + + // Convert to unicode + unicodeString.Copy(asciiString); + + // Now do the database query + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQueryRow, &unicodeString, &KAkaTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + if (view.FirstL()) + { + eap_status_e status; + view.GetL(); + + switch (view.ColType(KDefaultColumnInView_One)) + { + case EDbColText: + { + unicodeString = view.ColDes(KDefaultColumnInView_One); + // Convert to 8-bit + asciiString.Copy(unicodeString); + if (asciiString.Size() > 0) + { + status = data->set_copy_of_buffer(asciiString.Ptr(), asciiString.Size()); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + else + { + status = data->init(0); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + data->set_is_valid(); + break; + } + } + break; + + case EDbColUint32: + { + TUint value; + value = view.ColUint32(KDefaultColumnInView_One); + status = data->set_copy_of_buffer(&value, sizeof(value)); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + break; + + default: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Unexpected column type.\n"))); + User::Leave(KErrGeneral); + break; + } + } + else + { + // Could not find parameter + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Could not find configuration parameter.\n"))); + User::Leave(KErrArgument); + } + + CleanupStack::PopAndDestroy(4); // Close view, & 3 strings + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + // NOTE: At the moment this is not called anywhere. + // NOTE: This is really just for simulation. + // Write is routed to partner object. + eap_status_e status = m_partner->write_configure( + field, + data); + return status; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_type_aka_symbian_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_am_type_aka_symbian_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +#if defined(__WINS__) + +EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_SIM_imsi( + u8_t * const imsi, const u32_t max_length, u32_t * const imsi_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (imsi == 0 || imsi_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // This function returns Nokia test SIM IMSI. + // It is used only when real AKA interface is not used. + + *imsi_length = m_am_tools->strlen(TEST_IMSI); + if (*imsi_length > max_length) + { + // ERROR, too short buffer. + *imsi_length = 0u; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_am_tools->memmove(imsi, TEST_IMSI, m_am_tools->strlen(TEST_IMSI)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +#endif //#if defined(__WINS__) + +//-------------------------------------------------- + +eap_status_e eap_am_type_aka_symbian_c::check_is_valid_imsi( + const eap_variable_data_c * const username) +{ + if (username == 0 + || username->get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + for (u32_t ind = 0ul; ind < username->get_data_length(); ind++) + { + const u8_t * const digit = username->get_data_offset( + ind, + sizeof(u8_t)); + if (digit == 0 + || *digit < '0' + || *digit > '9') + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); + } + } + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +bool eap_am_type_aka_symbian_c::is_session_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + bool sessionValidity(false); + + TRAPD(err, sessionValidity = is_session_validL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_aka_symbian_c::is_session_valid - LEAVE - error=%d, Assuming session is invalid \n"), + err)); + + sessionValidity = false; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return sessionValidity; +} + +//-------------------------------------------------- + +bool eap_am_type_aka_symbian_c::is_session_validL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_aka_symbian_c::is_session_valid - start \n"))); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT(KSQLQuery, "SELECT %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &cf_str_EAP_AKA_max_session_validity_time_literal, + &KAKALastFullAuthTime, &KAkaTableName, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + TInt64 maxSessionTime = view.ColInt64(colSet->ColNo(cf_str_EAP_AKA_max_session_validity_time_literal)); + TInt64 fullAuthTime = view.ColInt64(colSet->ColNo(KAKALastFullAuthTime)); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + CleanupStack::PopAndDestroy(&view); // Close view. + CleanupStack::PopAndDestroy(buf); // Delete buf. + + // If the max session time from DB is zero then we use the + // one read from configuration file. + + if( maxSessionTime == 0) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("Session Validity - Using max session validity time from config file\n"))); + + maxSessionTime = m_max_session_time; // value from configuration file. + } + + // Get the current time. + TTime currentTime; + currentTime.UniversalTime(); + + TTime lastFullAuthTime(fullAuthTime); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + TDateTime fullAuthDateTime = lastFullAuthTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("Session Validity - Current Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1, currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("Session Validity - Last Full Auth Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + fullAuthDateTime.Day()+1, fullAuthDateTime.Month()+1, fullAuthDateTime.Year(), fullAuthDateTime.Hour(), + fullAuthDateTime.Minute(), fullAuthDateTime.Second(), fullAuthDateTime.MicroSecond())); + +#endif + + TTimeIntervalMicroSeconds interval = currentTime.MicroSecondsFrom(lastFullAuthTime); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_aka_symbian_c::is_session_valid:interval in microseconds:"), + &(interval.Int64()), + sizeof(interval.Int64()) ) ); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_aka_symbian_c::is_session_valid:max session time in microseconds:"), + &(maxSessionTime), + sizeof(maxSessionTime) ) ); + + +#if defined(_DEBUG) || defined(DEBUG) + + TTimeIntervalMinutes intervalMins; + TInt error = currentTime.MinutesFrom(lastFullAuthTime, intervalMins); + + if(error == KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::is_session_validL()") + EAPL("interval in Minutes =%d\n"), + intervalMins.Int())); + } + +#endif + + + if( maxSessionTime >= interval.Int64() ) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_aka_symbian_c::is_session_valid - Session Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return true; + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_aka_symbian_c::is_session_valid - Session NOT Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return false; + } +} + +//-------------------------------------------------- + +void eap_am_type_aka_symbian_c::store_authentication_timeL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_aka_symbian_c::store_authentication_timeL - start \n"))); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT(KSQLQuery, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KAKALastFullAuthTime, &KAkaTableName, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row for updation. + view.FirstL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the current universal time. + TTime currentTime; + currentTime.UniversalTime(); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_aka_symbian_c::store_authentication_time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1,currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + +#endif + + TInt64 fullAuthTime = currentTime.Int64(); + + view.SetColL(colSet->ColNo(KAKALastFullAuthTime), fullAuthTime); + + view.PutL(); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + CleanupStack::PopAndDestroy(&view); // Close view. + CleanupStack::PopAndDestroy(buf); // Delete buf. + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/102073c1.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/102073c1.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 1020 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Localization strings for project EAPOL +* +*/ + + + +// LOCALISATION STRINGS: + +// b: 50 +// e: 300 +// f: EDialogLabelFont +// d: This name for the EAP-AKA EAP type is displayed in the EAP type list in IAP UI and in EAP-PEAP +// d: encapsulated EAP type selection. +#define ESPL_GE_NAME "EAP-AKA" + + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/EapAka.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/EapAka.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,170 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPAKA_H_ +#define _EAPAKA_H_ + +// INCLUDES +#include +#include "eap_header.h" + +// FORWARD DECLARATIONS +class eap_am_network_id_c; + +// CLASS DECLARATION +/** +* Class that implements the generic EAP type interface. Implements EAP AKA protocol. +*/ +class CEapAka : public CEapType +{ +public: + + /** + * Construction function. Called by ECom after the EAP AKA plugin has been loaded. + * @param aIapInfo Pointer to the class that contains information about bearer type and unique index. + * @return Pointer to the instance. + */ + static CEapAka* NewL(SIapInfo* aIapInfo); + + /** + * Destructor does nothing. + */ + virtual ~CEapAka(); + +#ifdef USE_EAP_SIMPLE_CONFIG + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @param eap_config_if Pointer used for call back to creater of stack (eapol_am_wlan_authentication_symbian_c class). + * @return Pointer to the implementation. + */ + virtual eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if); + +#else + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @return Pointer to the implementation. + */ + eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG + + /** + * Invokes the configuration UI. + **/ + TInt InvokeUiL(); + + /** + * Gets information about EAP type. + * @return Pointer to a class that contains the EAP type information. Also pushed to cleanup stack. + */ + CEapTypeInfo* GetInfoLC(); + + /** + * Deletes EAP type configuration + */ + void DeleteConfigurationL(); + + /** + * Returns the version of the interface that the EAP type implements. + * The client-side of the interface must always check the version with this function + * and not call the functions that are not implemented. New functions must be + * added to the end of the interface so that the order of the old functions + * does not change. + * @return Integer indicating the version. + */ + TUint GetInterfaceVersion(); + + /** + * Sets the tunneling type. This is used to indicate that this type is run inside another + * EAP type. + * @param aTunnelingType Type number for the tunneling type + */ + void SetTunnelingType(const TInt aTunnelingType); + + /** + * Changes the index of the saved parameters. + * @param aIndexType Indicates the bearer used for this connection. + * @param aIndex Index for the connection. aIndexType and aIndex uniquely specify the connection. + * @return Pointer to the implementation. + */ + void SetIndexL( + const TIndexType aIndexType, + const TInt aIndex ); + + /** + * Sets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void SetConfigurationL(const EAPSettings& aSettings); + + /** + * Gets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void GetConfigurationL(EAPSettings& aSettings); + + /** + * Copies the EAP types configuration + * @param aDestinationIndex ID to where copy the settings. + */ + void CopySettingsL(const TIndexType aDestinationIndexType, const TInt aDestinationIndex); + +protected: + + /** + * Constructor initialises member variables. + */ + CEapAka(const TIndexType aIndexType, const TInt aIndex); + +private: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // Tunneling type + eap_type_value_e iTunnelingType; +}; + +#endif // _EAPAKA_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/EapAkaDbDefaults.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/EapAkaDbDefaults.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPAKADBDEFAULTS_H_) +#define _EAPAKADBDEFAULTS_H_ + +enum TAKAUsePseudonymId +{ + EAKAUsePseudonymIdNo, // False. Don't use pseudonym id. + EAKAUsePseudonymIdYes, // True. Use pseudonym id. + EAKAUsePseudonymIdNotValid // This indicates that the value is not configured. +}; + +enum TAKAUseManualRealm +{ + EAKAUseManualRealmNo, // False. Don't use Manual Realm. + EAKAUseManualRealmYes, // True. Use Manual Realm. +}; + +enum TAKAUseManualUsername +{ + EAKAUseManualUsernameNo, // False. Don't use Manual Username. + EAKAUseManualUsernameYes, // True. Use Manual Username. +}; + +// LOCAL CONSTANTS +const TUint default_EAP_AKA_use_manual_realm = EAKAUseManualRealmNo; +_LIT(default_EAP_AKA_manual_realm, ""); + +const TUint default_EAP_AKA_use_manual_username = EAKAUseManualUsernameNo; +_LIT(default_EAP_AKA_manual_username, ""); + +const TUint default_EAP_AKA_use_pseudonym_identity = EAKAUsePseudonymIdYes; // Default is use pseudonym identity. + +const TInt64 default_MaxSessionTime = 0; // 0 means read from configuration file. +const TInt64 default_FullAuthTime = 0; + +const TUint KMaxPseudonymIdLengthInDB = 1020; // This is the max possible length of an EAP packet. +const TUint KMaxReauthIdLengthInDB = 1020; // pseudonym id or reauth id can't be more than that. + +const TUint KMaxManualUsernameLengthInDB = 255; +const TUint KMaxManualRealmLengthInDB = 255; + +const TUint KMaxIMSILengthInDB = 15; + +const TUint KMaxXKeyLengthInDB = 20; +const TUint KMaxK_autLengthInDB = 16; +const TUint KMaxK_encrLengthInDB = 16; + +#endif // _EAPAKADBDEFAULTS_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/EapAkaDbParameterNames.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/EapAkaDbParameterNames.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_EAPAKADBPARAMETERNAMES_H_) +#define _EAPAKADBPARAMETERNAMES_H_ + +#include "eap_type_aka_types.h" + +// LOCAL CONSTANTS + +_LIT(KServiceType, "ServiceType"); +_LIT(KServiceIndex, "ServiceIndex"); +_LIT(KTunnelingType, "TunnelingType"); +_LIT(KPseudonymId, "PseudonymId"); +_LIT(KXKey, "XKEY"); +_LIT(KK_aut, "K_aut"); +_LIT(KK_encr, "K_encr"); +_LIT(KReauthCounter, "ReauthCounter"); +_LIT(KReauthId, "ReauthId"); +_LIT(KPreviousIMSI, "PreviousIMSI"); + +_LIT(KAKALastFullAuthTime, "EAP_AKA_last_full_authentication_time"); + +#endif // _EAPAKADBPARAMETERNAMES_H_ + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/EapAkaDbUtils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/EapAkaDbUtils.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPAKADBUTILS_H_ +#define _EAPAKADBUTILS_H_ + +// INCLUDES +#include +#include +#include "eap_header.h" + +// LOCAL CONSTANTS + +#ifdef SYMBIAN_SECURE_DBMS +// For EAP AKA secure database. +// Full path is not needed. The database eapaka.dat will be saved in the +// data cage path for DBMS. So it will be in "\private\100012a5\eapaka.dat" in C: drive. +// The maximum length of database name is 0x40 (KDbMaxName) , which is defined in d32dbms.h. + +_LIT(KDatabaseName, "c:eapaka.dat"); + +_LIT(KSecureUIDFormat, "SECURE[102072e9]"); // For the security policy. + +#else + +_LIT(KDatabaseName, "c:\\system\\data\\eapaka.dat"); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + +_LIT(KAkaTableName, "eapaka"); + +// CLASS DECLARATION +class EapAkaDbUtils +{ +public: + + static void OpenDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + /** + * Changes the settings' index + */ + static void SetIndexL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const TIndexType aNewIndexType, + const TInt aNewIndex, + const eap_type_value_e aNewTunnelingType); + + static void SetConfigurationL( + RDbNamedDatabase& aDatabase, + const EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + static void GetConfigurationL( + RDbNamedDatabase& aDatabase, + EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + static void CopySettingsL( + RDbNamedDatabase& aDatabase, + const TIndexType aSrcIndexType, + const TInt aSrcIndex, + const eap_type_value_e aSrcTunnelingType, + const TIndexType aDestIndexType, + const TInt aDestIndex, + const eap_type_value_e aDestTunnelingType); + + static void DeleteConfigurationL( + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + +}; + +#endif // _EAPAKADBUTILS_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/EapAkaGlobal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/inc/EapAkaGlobal.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPAKAGLOBAL_H_ +#define _EAPAKAGLOBAL_H_ + +// LOCAL CONSTANTS + +// Release date must be of format YYYYMMDD:. Will be localised automatically. +// Note that days and months start from 0. +_LIT(KReleaseDate, "20040829:"); +_LIT(KEapTypeVersion, "1.0"); +_LIT(KManufacturer, "Nokia"); +_LIT(KNokiaSignature, ""); // Not used +_LIT(KExtraInfo1, ""); // Not used +_LIT(KExtraInfo2, ""); // Not used + +#endif // _EAPAKAGLOBAL_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/102073c1.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/102073c1.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 1020 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource definitions for project EAPOL +* +*/ + + + +// INCLUDES +#include +#include "102073c1.loc" +#include "EapolUID.h" + +// RESOURCE DEFINITIONS +// --------------------------------------------------------- +// +// theInfo +// Contains the ECom registration information for EAP AKA +// +// --------------------------------------------------------- +// +RESOURCE REGISTRY_INFO theInfo +{ +dll_uid = EAP_AKA_DLL_UID; +interfaces = + { + INTERFACE_INFO + { + interface_uid = PLUGIN_INTERFACE_UID; + implementations = + { + + BINARY_IMPLEMENTATION_INFO + { + implementation_uid = EAP_AKA_IMPLEMENTATION_UID; + version_no = 1; + display_name = ESPL_GE_NAME; + default_data = {0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17}; // AKA + opaque_data = {0x0}; + } + }; + } + }; +} +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAka.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAka.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,335 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 605 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "EapAka.h" +#include "eap_base_type.h" +#include "eap_type_aka.h" +#include "EapAkaGlobal.h" +#include +#include "eap_am_type_aka_symbian.h" +#include "EapAkaDbUtils.h" + +#include +#include "EapAkaUi.h" + + +#include "eap_am_tools_symbian.h" + +// LOCAL CONSTANTS + +// The version number of this interface. +const TUint KInterfaceVersion = 1; + + +// ================= MEMBER FUNCTIONS ======================= + + +CEapAka::CEapAka(const TIndexType aIndexType, + const TInt aIndex) +: iIndexType(aIndexType) +, iIndex(aIndex) +, iTunnelingType(eap_type_none) +{ +} + +// ---------------------------------------------------------- + +CEapAka* CEapAka::NewL(SIapInfo *aIapInfo) +{ + return new (ELeave) CEapAka(aIapInfo->indexType, aIapInfo->index); +} + +// ---------------------------------------------------------- + +CEapAka::~CEapAka() +{ +} + +// ---------------------------------------------------------- + +#ifdef USE_EAP_SIMPLE_CONFIG + +eap_base_type_c* CEapAka::GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const /*configuration_if*/) + +#else + +eap_base_type_c* CEapAka::GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG +{ + // Create AM + eap_am_type_aka_symbian_c* amEapType = eap_am_type_aka_symbian_c::NewL( + aTools, + aPartner, + iIndexType, + iIndex, + iTunnelingType, + is_client_when_true, + receive_network_id); + + if (amEapType->get_is_valid() == false) + { + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrGeneral); + } + + eap_base_type_c* type = 0; + + type = new eap_type_aka_c( + aTools, + aPartner, + amEapType, + true /* free_am */, + is_client_when_true, + receive_network_id); + + if (type == 0) + { + // Out of memory + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrNoMemory); + } + else if (type->get_is_valid() == false) + { + type->shutdown(); + // amEapType is freed by eap_type_aka_c + delete type; + User::Leave(KErrGeneral); + } + return type; +} + +// ---------------------------------------------------------- +TInt CEapAka::InvokeUiL() +{ + TInt buttonId(0); + +#ifdef USE_EAP_EXPANDED_TYPES + + CEapAkaUiConnection uiConn(iIndexType, iIndex, iTunnelingType.get_vendor_type()); + +#else + + CEapAkaUiConnection uiConn(iIndexType, iIndex, iTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + CEapAkaUi* ui = CEapAkaUi::NewL(&uiConn); + CleanupStack::PushL(ui); + buttonId = ui->InvokeUiL(); + CleanupStack::PopAndDestroy(ui); + return buttonId; +} + +// ---------------------------------------------------------- +CEapTypeInfo* CEapAka::GetInfoLC() +{ + CEapTypeInfo* info = new(ELeave) CEapTypeInfo( + (TDesC&)KReleaseDate, + (TDesC&)KEapTypeVersion, + (TDesC&)KManufacturer); + + CleanupStack::PushL(info); + return info; +} + +// ---------------------------------------------------------- +void CEapAka::DeleteConfigurationL() +{ + EapAkaDbUtils::DeleteConfigurationL(iIndexType, iIndex, iTunnelingType); +} + +// ---------------------------------------------------------- + +TUint CEapAka::GetInterfaceVersion() +{ + return KInterfaceVersion; +} + +// ---------------------------------------------------------- + +void CEapAka::SetTunnelingType(const TInt aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + // Vendor id is eap_type_vendor_id_ietf always in this plugin. + iTunnelingType.set_eap_type_values(eap_type_vendor_id_ietf, aTunnelingType); + +#else + + iTunnelingType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES +} + + +// ---------------------------------------------------------- +void CEapAka::SetIndexL( + const TIndexType aIndexType, + const TInt aIndex ) +{ + // First delete the target configuration + TIndexType tmpIndexType = iIndexType; + TInt tmpIndex = iIndex; + + iIndexType = aIndexType; + iIndex = aIndex; + + TInt err(KErrNone); + TRAP(err, DeleteConfigurationL()); + // Ignore error on purpose + + // Return the indices + iIndexType = tmpIndexType; + iIndex = tmpIndex; + + RDbNamedDatabase db; + + RDbs session; + + EapAkaDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapAkaDbUtils::SetIndexL( + db, + iIndexType, + iIndex, + iTunnelingType, + aIndexType, + aIndex, + iTunnelingType); + + iIndexType = aIndexType; + iIndex = aIndex; + + CleanupStack::PopAndDestroy(2); // db +} + +// ---------------------------------------------------------- + +void CEapAka::SetConfigurationL(const EAPSettings& aSettings) +{ + RDbNamedDatabase db; + + RDbs session; + + // This also creates the IAP entry if it doesn't exist + EapAkaDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapAkaDbUtils::SetConfigurationL( + db, + aSettings, + iIndexType, + iIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db, session +} + +// ---------------------------------------------------------- + +void CEapAka::GetConfigurationL(EAPSettings& aSettings) +{ + RDbNamedDatabase db; + + RDbs session; + + // This also creates the IAP entry if it doesn't exist + EapAkaDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapAkaDbUtils::GetConfigurationL( + db, + aSettings, + iIndexType, + iIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db, session +} + +// ---------------------------------------------------------- + +void CEapAka::CopySettingsL( + const TIndexType aDestinationIndexType, + const TInt aDestinationIndex) +{ + // First delete the target configuration + TIndexType tmpIndexType = iIndexType; + TInt tmpIndex = iIndex; + + iIndexType = aDestinationIndexType; + iIndex = aDestinationIndex; + + TInt err(KErrNone) ; + TRAP(err, DeleteConfigurationL()); + // Ignore error on purpose + + // Return the indices + iIndexType = tmpIndexType; + iIndex = tmpIndex; + + RDbNamedDatabase db; + + RDbs session; + + EapAkaDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapAkaDbUtils::CopySettingsL( + db, + iIndexType, + iIndex, + iTunnelingType, + aDestinationIndexType, + aDestinationIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db + +} +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAkaDbUtils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAkaDbUtils.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,805 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 177 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDES +#include "EapAkaDbUtils.h" +#include "EapAkaDbDefaults.h" +#include "EapAkaDbParameterNames.h" +#include "eap_type_aka_types.h" + +#include "eap_am_trace_symbian.h" + +const TInt KMaxSqlQueryLength = 2048; +const TInt KMicroSecsInAMinute = 60000000; // 60000000 micro seconds is 1 minute. + +// ================= MEMBER FUNCTIONS ======================= + +void EapAkaDbUtils::OpenDatabaseL(RDbNamedDatabase& aDatabase, RDbs& aSession, const TIndexType aIndexType, + const TInt aIndex, const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapAkaDbUtils::OpenDatabaseL -Start- aIndexType=%d, aIndex=%d, aTunnelingVendorType=%d \n"), + aIndexType,aIndex,aTunnelingVendorType) ); + + // 1. Open/create a database + + // Connect to the DBMS server. + User::LeaveIfError(aSession.Connect()); + CleanupClosePushL(aSession); + // aSession and aDatabase are pushed to the cleanup stack even though they may be member + // variables of the calling class and would be closed in the destructor anyway. This ensures + // that if they are not member variables they will be closed. Closing the handle twice + // does no harm. + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = aDatabase.Create(aSession, KDatabaseName, KSecureUIDFormat); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapAkaDbUtils::OpenDatabaseL - Created Secure DB for eapaka.dat. err=%d\n"), err)); + + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(aSession, KDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(aDatabase); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = aDatabase.Create(fsSession, KDatabaseName); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapAkaDbUtils::OpenDatabaseL - Created Non-Secure DB for eapaka.dat. err=%d\n"), err)); + + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + CleanupStack::PopAndDestroy( &fsSession ); // close fsSession + + User::LeaveIfError(aDatabase.Open(aSession, KDatabaseName)); + CleanupClosePushL(aDatabase); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + // 2. Create the eapaka table to database (ignore error if exists) + +// Table columns: +//// NAME ///////////////////////////////////////////////// TYPE ////////////// Constant ///////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| EAP_AKA_use_manual_realm | UNSIGNED INTEGER | cf_str_EAP_AKA_use_manual_realm_literal |// +//| EAP_AKA_manual_realm | VARCHAR(255) | cf_str_EAP_AKA_manual_realm_literal |// +//| EAP_AKA_use_manual_username | UNSIGNED INTEGER | cf_str_EAP_AKA_use_manual_username_literal|// +//| EAP_AKA_manual_username | VARCHAR(255) | cf_str_EAP_AKA_manual_username_literal|// +//| PseudonymId | LONG VARBINARY | KPseudonymId |// +//| XKEY | BINARY(20) | KXKey |// +//| K_aut | BINARY(16) | KK_aut |// +//| K_encr | BINARY(16) | KK_encr |// +//| ReauthCounter | UNSIGNED INTEGER | KReauthCounter |// +//| ReauthId | LONG VARBINARY | KReauthId |// +//| PreviousIMSI | VARBINARY(15) | KPreviousIMSI |// +//| EAP_AKA_use_pseudonym_identity | UNSIGNED INTEGER | cf_str_EAP_AKA_use_pseudonym_identity_literal |// +//| EAP_AKA_max_session_validity_time | BIGINT | cf_str_EAP_AKA_max_session_validity_time_literal |// +//| EAP_AKA_last_full_authentication_time | BIGINT | KAKALastFullAuthTime |// +////////////////////////////////////////////////////////////////////////////////////////////////// + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLCreateTable, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S LONG VARBINARY, \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S UNSIGNED INTEGER, \ + %S LONG VARBINARY, \ + %S VARBINARY(%d), \ + %S UNSIGNED INTEGER, \ + %S BIGINT, \ + %S BIGINT)"); + + sqlStatement.Format(KSQLCreateTable, &KAkaTableName, &KServiceType, + &KServiceIndex, + &KTunnelingType, + &cf_str_EAP_AKA_use_manual_realm_literal, + &cf_str_EAP_AKA_manual_realm_literal,KMaxManualRealmLengthInDB, + &cf_str_EAP_AKA_use_manual_username_literal, + &cf_str_EAP_AKA_manual_username_literal, KMaxManualUsernameLengthInDB, + &KPseudonymId, + &KXKey, KMaxXKeyLengthInDB, + &KK_aut, KMaxK_autLengthInDB, + &KK_encr, KMaxK_encrLengthInDB, + &KReauthCounter, + &KReauthId, + &KPreviousIMSI, KMaxIMSILengthInDB, + &cf_str_EAP_AKA_use_pseudonym_identity_literal, + &cf_str_EAP_AKA_max_session_validity_time_literal, + &KAKALastFullAuthTime); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // 4. Check if database table contains a row for this service type and id + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQueryRow, &cf_str_EAP_AKA_manual_realm_literal, &KAkaTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // 5. If row is not found then add it + + TInt rows = view.CountL(); + CleanupStack::PopAndDestroy( &view ); // Close view. + + if (rows == 0) + { + _LIT(KSQLInsert, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert, &KAkaTableName); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly)); + CleanupClosePushL(view); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_use_manual_realm_literal), default_EAP_AKA_use_manual_realm); + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_manual_realm_literal), default_EAP_AKA_manual_realm); + + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_use_manual_username_literal), default_EAP_AKA_use_manual_username); + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_manual_username_literal), default_EAP_AKA_manual_username); + + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_use_pseudonym_identity_literal), default_EAP_AKA_use_pseudonym_identity); + + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_max_session_validity_time_literal), default_MaxSessionTime); + + view.SetColL(colSet->ColNo(KAKALastFullAuthTime), default_FullAuthTime); + + view.PutL(); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + CleanupStack::PopAndDestroy( &view ); // Close view. + } + + CleanupStack::PopAndDestroy( buf ); // Delete buf + + CleanupStack::Pop( &aDatabase ); + CleanupStack::Pop( &aSession ); + + aDatabase.Compact(); +} + +void EapAkaDbUtils::SetIndexL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const TIndexType aNewIndexType, + const TInt aNewIndex, + const eap_type_value_e aNewTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aNewTunnelingVendorType = aNewTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aNewTunnelingVendorType = static_cast(aNewTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &KAkaTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + TInt rows = view.CountL(); + + if (rows == 0) + { + User::Leave(KErrNotFound); + } + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + view.UpdateL(); + + view.SetColL(colSet->ColNo(KServiceType), aNewIndexType); + + view.SetColL(colSet->ColNo(KServiceIndex), aNewIndex); + + view.SetColL(colSet->ColNo(KTunnelingType), aNewTunnelingVendorType); + + view.PutL(); + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapAkaDbUtils::SetConfigurationL( + RDbNamedDatabase& aDatabase, + const EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapAkaDbUtils::SetConfigurationL -Start- aIndexType=%d, aIndex=%d, aTunnelingVendorType=%d\n"), + aIndexType,aIndex, aTunnelingVendorType)); + + EAP_TRACE_DEBUG_SYMBIAN((_L("*************************** SetConfigurationL - Set the below values: ***************************\n")) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - Set these values for EAPType=%d"),aSettings.iEAPType) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Username=%S"),aSettings.iUsernamePresent, &(aSettings.iUsername)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Password=%S"),aSettings.iPasswordPresent, &(aSettings.iPassword)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Realm=%S"),aSettings.iRealmPresent, &(aSettings.iRealm)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, UsePseudonyms=%d"),aSettings.iUsePseudonymsPresent, aSettings.iUsePseudonyms) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, VerifyServerRealm=%d"), + aSettings.iVerifyServerRealmPresent, aSettings.iVerifyServerRealm) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, RequireClientAuthentication=%d"), + aSettings.iRequireClientAuthenticationPresent, aSettings.iRequireClientAuthentication) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, SessionValidityTime=%d minutes"), + aSettings.iSessionValidityTimePresent, aSettings.iSessionValidityTime) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, CipherSuites Count=%d"), + aSettings.iCipherSuitesPresent, aSettings.iCipherSuites.Count()) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, PEAPv0Allowed=%d, PEAPv1Allowed=%d, PEAPv2Allowed=%d"), + aSettings.iPEAPVersionsPresent, aSettings.iPEAPv0Allowed,aSettings.iPEAPv1Allowed, aSettings.iPEAPv2Allowed ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Certificates Count=%d"), + aSettings.iCertificatesPresent, aSettings.iCertificates.Count()) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - Certificate details below: \n")) ); + + for( TInt n=0; n < aSettings.iCertificates.Count(); n++ ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - Certificate type:%d \n"), aSettings.iCertificates[n].iCertType) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - present=%d, SubjectName=%S"), + aSettings.iCertificates[n].iSubjectNamePresent, &(aSettings.iCertificates[n].iSubjectName) ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - present=%d, IssuerName=%S"), + aSettings.iCertificates[n].iIssuerNamePresent, &(aSettings.iCertificates[n].iIssuerName) ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - present=%d, SerialNumber=%S"), + aSettings.iCertificates[n].iSerialNumberPresent, &(aSettings.iCertificates[n].iSerialNumber) ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - SubjectKeyID present=%d"), + aSettings.iCertificates[n].iSubjectKeyIDPresent ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "SubjectKeyID:", aSettings.iCertificates[n].iSubjectKeyID.Ptr(), + aSettings.iCertificates[n].iSubjectKeyID.Size() ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - present=%d, Thumbprint=%S"), + aSettings.iCertificates[n].iThumbprintPresent, &(aSettings.iCertificates[n].iThumbprint) ) ); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, EncapsulatedEAPTypes Count=%d"), + aSettings.iEncapsulatedEAPTypesPresent, aSettings.iEncapsulatedEAPTypes.Count()) ); + for( TInt m=0; m < aSettings.iEncapsulatedEAPTypes.Count(); m++ ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - EncapsulatedEAPTypes=%d"), + aSettings.iEncapsulatedEAPTypes[m]) ); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("*************************** SetConfigurationL - Set the above values: ***************************\n")) ); + + // Check if the settings are for the correct type + if (aSettings.iEAPType != EAPSettings::EEapAka) + { + User::Leave(KErrNotSupported); + } + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + RDbView view; + + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KAkaTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + view.FirstL(); + + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Manual username + //if (aSettings.iUsernamePresent) // no need to check as there may be empty usernames with the present status is EFlase. + { + // Check if length of username is less than the max length. + if(aSettings.iUsername.Length() > KMaxManualUsernameLengthInDB) + { + // Username too long. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapAkaDbUtils::SetConfigurationL: Too long Username. Length=%d \n"), + aSettings.iUsername.Length())); + + User::Leave(KErrArgument); + } + + // Length is ok. Set the value in DB. + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_manual_username_literal), aSettings.iUsername); + + // This is to set the automatic or manual status. + TUint useManualUsernameStatus; + + if (aSettings.iUsernamePresent) + { + useManualUsernameStatus = EAKAUseManualUsernameYes; + } + else + { + useManualUsernameStatus = EAKAUseManualUsernameNo; + } + + // Set the value. + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_use_manual_username_literal), useManualUsernameStatus); + } + + // Manual realm + //if (aSettings.iRealmPresent) // no need to check as there may be empty realms with the present status is EFlase. + { + // Check if length of realm is less than the max length. + if(aSettings.iRealm.Length() > KMaxManualRealmLengthInDB) + { + // Realm too long. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapAkaDbUtils::SetConfigurationL: Too long Realm. Length=%d \n"), + aSettings.iRealm.Length())); + + User::Leave(KErrArgument); + } + + // Length is ok. Set the value in DB. Value could be empty. It doesn't matter. + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_manual_realm_literal), aSettings.iRealm); + + // This is to set the automatic or manual status. + TUint useManualRealmStatus; + + if (aSettings.iRealmPresent) + { + useManualRealmStatus = EAKAUseManualRealmYes; + } + else + { + useManualRealmStatus = EAKAUseManualRealmNo; + } + + // Set the value. + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_use_manual_realm_literal), useManualRealmStatus); + } + + // UsePseudonym + if (aSettings.iUsePseudonymsPresent) + { + if (aSettings.iUsePseudonyms) + { + // Use pseudonym. + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_use_pseudonym_identity_literal), EAKAUsePseudonymIdYes); + } + else + { + // Don't use pseudonym. + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_use_pseudonym_identity_literal), EAKAUsePseudonymIdNo); + } + } + else + { + // Value is not configured. Value is read from config file if needed. + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_use_pseudonym_identity_literal), EAKAUsePseudonymIdNotValid); + } + + // Session validity time + if (aSettings.iSessionValidityTimePresent) + { + // User or device management wants to store the session validity time. + // Convert the time to micro seconds and save. + + TInt64 validityInMicro = (aSettings.iSessionValidityTime) * KMicroSecsInAMinute; + + view.SetColL(colSet->ColNo(cf_str_EAP_AKA_max_session_validity_time_literal), validityInMicro); + } + + if (aIndexType != EVpn) // This allows current VPN IF to use reauthentication. VPN does not zero last full authentication time. + { + // Last full authentication time should be made zero when EAP configurations are modified. + // This makes sure that the next authentication with this EAP would be full authentication + // instead of reauthentication even if the session is still valid. + + view.SetColL(colSet->ColNo(KAKALastFullAuthTime), default_FullAuthTime); + + EAP_TRACE_DEBUG_SYMBIAN((_L("Session Validity: EAP-Type=%d, Resetting Full Auth Time since settings are modified\n"), + aSettings.iEAPType )); + } + + view.PutL(); + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapAkaDbUtils::GetConfigurationL( + RDbNamedDatabase& aDatabase, + EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + RDbView view; + + // Form the query + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KAkaTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + aSettings.iEAPType = EAPSettings::EEapAka; + + // Username + TPtrC username = view.ColDes(colSet->ColNo(cf_str_EAP_AKA_manual_username_literal)); + aSettings.iUsername.Copy(username); + + // For manual or automatic status. + TUint useUsername = view.ColUint(colSet->ColNo(cf_str_EAP_AKA_use_manual_username_literal)); + if(useUsername == EAKAUseManualUsernameNo) + { + aSettings.iUsernamePresent = EFalse; + } + else + { + aSettings.iUsernamePresent = ETrue; + } + + // Realm + TPtrC realm = view.ColDes(colSet->ColNo(cf_str_EAP_AKA_manual_realm_literal)); + aSettings.iRealm.Copy(realm); + + // For manual or automatic status. + TUint useRealm = view.ColUint(colSet->ColNo(cf_str_EAP_AKA_use_manual_realm_literal)); + if(useRealm == EAKAUseManualRealmNo) + { + aSettings.iRealmPresent = EFalse; + } + else + { + aSettings.iRealmPresent = ETrue; + } + + TInt usePseudonym = view.ColUint(colSet->ColNo(cf_str_EAP_AKA_use_pseudonym_identity_literal)); + + if (usePseudonym == EAKAUsePseudonymIdNotValid) + { + aSettings.iUsePseudonymsPresent = EFalse; + } + else + { + if (usePseudonym == EAKAUsePseudonymIdNo) + { + aSettings.iUsePseudonyms = EFalse; + } + else + { + aSettings.iUsePseudonyms = ETrue; + } + + aSettings.iUsePseudonymsPresent = ETrue; + } + + // Session validity time + TInt64 maxSessionTimeMicro = view.ColInt64(colSet->ColNo(cf_str_EAP_AKA_max_session_validity_time_literal)); + + // Convert the time to minutes. + TInt64 maxSessionTimeMin = maxSessionTimeMicro / KMicroSecsInAMinute; + + aSettings.iSessionValidityTime = static_cast(maxSessionTimeMin); + aSettings.iSessionValidityTimePresent = ETrue; + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapAkaDbUtils::CopySettingsL( + RDbNamedDatabase& aDatabase, + const TIndexType aSrcIndexType, + const TInt aSrcIndex, + const eap_type_value_e aSrcTunnelingType, + const TIndexType aDestIndexType, + const TInt aDestIndex, + const eap_type_value_e aDestTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aSrcTunnelingVendorType = aSrcTunnelingType.get_vendor_type(); + TUint aDestTunnelingVendorType = aDestTunnelingType.get_vendor_type(); + +#else + + TUint aSrcTunnelingVendorType = static_cast(aSrcTunnelingType); + TUint aDestTunnelingVendorType = static_cast(aDestTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &KAkaTableName, + &KServiceType, aSrcIndexType, &KServiceIndex, aSrcIndex, &KTunnelingType, aSrcTunnelingVendorType); + + RDbView view; + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + TInt rows = view.CountL(); + + if (rows == 0) + { + User::Leave(KErrNotFound); + } + + // Get the first (and only) row + view.FirstL(); + + view.GetL(); + + view.InsertCopyL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + + CleanupStack::PushL(colSet); + + view.SetColL(colSet->ColNo(KServiceType), static_cast(aDestIndexType)); + + view.SetColL(colSet->ColNo(KServiceIndex), aDestIndex); + + view.SetColL(colSet->ColNo(KTunnelingType), static_cast(aDestTunnelingVendorType)); + + view.PutL(); + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapAkaDbUtils::DeleteConfigurationL( + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + RDbs session; + RDbNamedDatabase database; + // Connect to the DBMS server. + User::LeaveIfError(session.Connect()); + CleanupClosePushL(session); + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = database.Create(session, KDatabaseName, KSecureUIDFormat); + + if(err == KErrNone) + { + // Database was created so it was empty. No need for further actions. + database.Destroy(); + CleanupStack::PopAndDestroy(); + return; + + } + else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + // Database existed, open it. + User::LeaveIfError(database.Open(session, KDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(database); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = database.Create(fsSession, KDatabaseName); + + if(err == KErrNone) + { + // Database was created so it was empty. No need for further actions. + database.Destroy(); + CleanupStack::PopAndDestroy(2); // fsSession, database session + return; + + } + else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + CleanupStack::PopAndDestroy(); // close fsSession + + User::LeaveIfError(database.Open(session, KDatabaseName)); + CleanupClosePushL(database); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Main settings table + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQL, &KAkaTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Delete rows + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + // Close database + CleanupStack::PopAndDestroy(4); // view, buf, database, session +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAkaProxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAkaProxy.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 606 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include "EapAka.h" +#include +#include +#include "EapolUID.h" + +const TImplementationProxy ImplementationTable[] = +{ + {{EAP_AKA_IMPLEMENTATION_UID}, reinterpret_cast (CEapAka::NewL)} +}; + +// ================= OTHER EXPORTED FUNCTIONS ============== + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) +{ + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + + return ImplementationTable; +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAkaUiAkaData.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAkaUiAkaData.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 180 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include + + +CEapAkaUiAkaData::CEapAkaUiAkaData() +{ +} + + +CEapAkaUiAkaData::~CEapAkaUiAkaData() +{ +} + + +TDes& CEapAkaUiAkaData::GetManualUsername() +{ + return iManualUsername; +} + + +TDes& CEapAkaUiAkaData::GetManualRealm() +{ + return iManualRealm; +} + + +TBool * CEapAkaUiAkaData::GetUseManualUsername() +{ + return &iUseManualUsername; +} + + +TBool * CEapAkaUiAkaData::GetUseManualRealm() +{ + return &iUseManualRealm; +} diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAkaUiConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAkaUiConnection.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,127 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 182 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include "EapAkaDbUtils.h" +#include +#include +#include "eap_header.h" + +CEapAkaUiConnection::CEapAkaUiConnection( + const TIndexType aIndexType, + const TInt aIndex, + const TInt aTunnelingType) + : iIndexType(aIndexType) + , iIndex(aIndex) + , iTunnelingType(aTunnelingType) + , iIsConnected(EFalse) + , iDataConn(NULL) +{ +} + + +CEapAkaUiConnection::~CEapAkaUiConnection() +{ +} + + +TInt CEapAkaUiConnection::Connect() +{ +#ifdef USE_EAP_EXPANDED_TYPES + + eap_type_value_e tunnelingType(static_cast(iTunnelingType)); + +#else + + eap_type_value_e tunnelingType = static_cast(iTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + TRAPD(err, EapAkaDbUtils::OpenDatabaseL( + iDbNamedDatabase, + iDbs, + iIndexType, + iIndex, + tunnelingType)); + if (err == KErrNone) + { + iIsConnected = ETrue; + } + + return err; +} + + +TInt CEapAkaUiConnection::Close() +{ + if (iIsConnected) + { + iDbNamedDatabase.Close(); + iDbs.Close(); + } + iIsConnected = EFalse; + + return KErrNone; +} + + +CEapAkaUiDataConnection * CEapAkaUiConnection::GetDataConnection() +{ + if (!iDataConn) + { + iDataConn = new CEapAkaUiDataConnection(this); + } + + return iDataConn; +} + +TInt CEapAkaUiConnection::GetDatabase(RDbNamedDatabase & aDatabase) +{ + if (iIsConnected == EFalse) + { + return KErrSessionClosed; + } + + aDatabase = iDbNamedDatabase; + return KErrNone; +} + + +TIndexType CEapAkaUiConnection::GetIndexType() +{ + return iIndexType; +} + + +TInt CEapAkaUiConnection::GetIndex() +{ + return iIndex; +} + + +TInt CEapAkaUiConnection::GetTunnelingType() +{ + return iTunnelingType; +} diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAkaUiDataConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/plugin/src/EapAkaUiDataConnection.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,273 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 184 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include +#include "EapAkaDbUtils.h" +#include "EapAkaDbParameterNames.h" +#include "EapAkaDbDefaults.h" +#include +#include +#include +#include "eap_am_trace_symbian.h" + +const TUint KMaxSqlQueryLength = 256; + +CEapAkaUiDataConnection::CEapAkaUiDataConnection(CEapAkaUiConnection * aUiConn) +: iIsOpened(EFalse) +, iUiConn(aUiConn) +, iColSet(NULL) +, iDataPtr(NULL) +{ +} + + +CEapAkaUiDataConnection::~CEapAkaUiDataConnection() +{ + if (iUiConn) + { + Close(); + iUiConn = NULL; + } +} + + +TInt CEapAkaUiDataConnection::Open() +{ + if (iIsOpened) + { + return KErrAlreadyExists; + } + + TInt err = iUiConn->GetDatabase(iDatabase); + if (err != KErrNone) + { + return err; + } + + iIsOpened = ETrue; + return KErrNone; +} + + +TInt CEapAkaUiDataConnection::GetData(CEapAkaUiAkaData ** aDataPtr) +{ + if (aDataPtr == NULL) + { + return KErrArgument; + } + if (iIsOpened == EFalse) + { + return KErrSessionClosed; + } + iDataPtr = new CEapAkaUiAkaData(); + if (!iDataPtr) + { + return KErrNoMemory; + } + + TRAPD(err, FetchDataL()); + if (err != KErrNone) + { + delete iDataPtr; + iDataPtr = NULL; + + delete iColSet; + iColSet = NULL; + + iView.Close(); + + return err; + } + + *aDataPtr = iDataPtr; + + return KErrNone; +} + + +TInt CEapAkaUiDataConnection::Update() +{ + TRAPD(err, iView.UpdateL()); + if (err != KErrNone) + { + return err; + } + + // Check if length of username and realm are less than the max length possible in DB. + if(iDataPtr->GetManualUsername().Length() > KMaxManualUsernameLengthInDB + || iDataPtr->GetManualRealm().Length() > KMaxManualRealmLengthInDB) + { + // Username or realm too long. Can not be stored in DB. + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapAkaUiDataConnection::Update: Too long username or realm. Length: UN=%d, Realm=%d\n"), + iDataPtr->GetManualUsername().Length(), + iDataPtr->GetManualRealm().Length())); + + return KErrArgument; + } + + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_AKA_manual_username_literal), iDataPtr->GetManualUsername())); + if (err != KErrNone) + { + return err; + } + + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_AKA_manual_realm_literal), iDataPtr->GetManualRealm())); + if (err != KErrNone) + { + return err; + } + + if (*(iDataPtr->GetUseManualUsername())) + { + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_AKA_use_manual_username_literal), EAKAUseManualUsernameYes)); + if (err != KErrNone) + { + return err; + } + } + else + { + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_AKA_use_manual_username_literal), EAKAUseManualUsernameNo)); + if (err != KErrNone) + { + return err; + } + } + + if (*(iDataPtr->GetUseManualRealm())) + { + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_AKA_use_manual_realm_literal), EAKAUseManualRealmYes)); + if (err != KErrNone) + { + return err; + } + } + else + { + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_AKA_use_manual_realm_literal), EAKAUseManualRealmNo)); + if (err != KErrNone) + { + return err; + } + } + + // Last full authentication time should be made zero when EAP configurations are modified. + // This makes sure that the next authentication with this EAP would be full authentication + // instead of reauthentication even if the session is still valid. + + TRAP(err, iView.SetColL(iColSet->ColNo(KAKALastFullAuthTime), default_FullAuthTime)); + if (err != KErrNone) + { + return err; + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("Session Validity: Resetting Full Auth Time since EAP-AKA settings are modified\n"))); + + TRAP(err, iView.PutL()); + + return err; +} + + +TInt CEapAkaUiDataConnection::Close() +{ + if (iIsOpened == EFalse) + { + return KErrNone; + } + + delete iDataPtr; + iDataPtr = NULL; + + delete iColSet; + iColSet = NULL; + + iView.Close(); + + iUiConn = NULL; + + return KErrNone; +} + + +void CEapAkaUiDataConnection::FetchDataL() +{ + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Form the query. Query everything. + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, + &KAkaTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + // Evaluate view + User::LeaveIfError(iView.Prepare(iDatabase, TDbQuery(sqlStatement))); + User::LeaveIfError(iView.EvaluateAll()); + // Get the first (and only) row + iView.FirstL(); + iView.GetL(); + // Get column set so we get the correct column numbers + delete iColSet; + iColSet = NULL; + iColSet = iView.ColSetL(); + + // Start fetching the values + + // use manual username + TUint intValue = iView.ColUint(iColSet->ColNo(cf_str_EAP_AKA_use_manual_username_literal)); + if (intValue == 0) + { + *(iDataPtr->GetUseManualUsername()) = EFalse; + } + else + { + *(iDataPtr->GetUseManualUsername()) = ETrue; + } + + // use manual realm + intValue = iView.ColUint(iColSet->ColNo(cf_str_EAP_AKA_use_manual_realm_literal)); + if (intValue == 0) + { + *(iDataPtr->GetUseManualRealm()) = EFalse; + } + else + { + *(iDataPtr->GetUseManualRealm()) = ETrue; + } + + // manual username + iDataPtr->GetManualUsername().Copy(iView.ColDes16(iColSet->ColNo(cf_str_EAP_AKA_manual_username_literal))); + + // manual realm + iDataPtr->GetManualRealm().Copy(iView.ColDes16(iColSet->ColNo(cf_str_EAP_AKA_manual_realm_literal))); + + CleanupStack::PopAndDestroy(buf); +} diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/EapSimInterface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/EapSimInterface.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,346 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 195 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include "EapSimInterface.h" + +#include +#include "eap_sim_triplets.h" // For SIM_SRES_LENGTH. + + +// ================= MEMBER FUNCTIONS ======================= + +CEapSimIsaInterface::CEapSimIsaInterface(abs_eap_am_tools_c* const aTools, eap_am_type_gsmsim_symbian_c* const aParent) +: CActive(CActive::EPriorityStandard) +, iParent(aParent) +, m_am_tools(aTools) +, iAuthenticationData(NULL) +, iQueryId(EQueryNone) +, iMMETELConnectionStatus(EFalse) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +CEapSimIsaInterface* CEapSimIsaInterface::NewL(abs_eap_am_tools_c* const aTools, + eap_am_type_gsmsim_symbian_c* const aParent) +{ + CEapSimIsaInterface* self = new(ELeave) CEapSimIsaInterface(aTools, aParent); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; +} + +//-------------------------------------------------- + +void CEapSimIsaInterface::ConstructL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + CActiveScheduler::Add(this); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +CEapSimIsaInterface::~CEapSimIsaInterface() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if(IsActive()) + { + Cancel(); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Closing RMobilePhone and MMETEL.\n"))); + + iPhone.Close(); + iServer.Close(); // Phone module is unloaded automatically when RTelServer session is closed + + delete iAuthenticationData; + iAuthenticationData = NULL; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapSimIsaInterface::QueryIMSIL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ISA interface: Querying IMSI.\n"))); + + iQueryId = EQueryIMSI; + + // Create MMETEl connection. + User::LeaveIfError( CreateMMETelConnectionL() ); + + iPhone.GetSubscriberId( iStatus, iSubscriberId ); + + if( !IsActive() ) + { + SetActive(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapSimIsaInterface::QueryKcAndSRESL(const TDesC8& aRand) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ISA interface: Querying Kc and SRES.\n"))); + + iQueryId = EQuerySRESandKC; + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("RAND"), + aRand.Ptr(), + aRand.Size())); + + // Rand must be 16 bytes + if (static_cast(aRand.Length()) != SIM_RAND_LENGTH) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ISA interface: Illegal RAND - Incorrect length.\n"))); + User::Leave(KErrArgument); + } + + // Create MMETEL connection. + User::LeaveIfError( CreateMMETelConnectionL() ); + + // Open CustomAPI. + User::LeaveIfError( iCustomAPI.Open(iPhone) ); + + iEAPSim.iRandomParameters.Copy( aRand ); //Copy the rand to iEAPSim + + //Pack iEAPSim to iAuthenticationData for passing it to the custom API. + iAuthenticationData = new (ELeave) RMmCustomAPI::TSimDataPckg( iEAPSim ); + + iCustomAPI.GetWlanSimAuthenticationData( iStatus, *iAuthenticationData ); + + if( !IsActive() ) + { + SetActive(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapSimIsaInterface::DoCancel() +{ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapSimIsaInterface::DoCancel() - Cancelling MMETEL query.\n") ) ); + + // Cancel the request. + iCustomAPI.CancelAsyncRequest( ECustomGetSimAuthenticationDataIPC ); +} + +//-------------------------------------------------- + +void CEapSimIsaInterface::RunL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapSimIsaInterface::RunL(). iStatus.Int() =%d \n"), iStatus.Int() )); + + TInt error = KErrNone; + eap_variable_data_c imsi(m_am_tools); // Keeping it here to avoid "error" in ARMV5 build. + + // This is to store the IMSI, which is in Unicode form. + eap_variable_data_c imsiInUnicode(m_am_tools); // Keeping it here to avoid "error" in ARMV5 build. + + // Keeping it here to remove compiler warning. + eap_status_e completion_status(eap_status_ok); + + if (iStatus.Int() == KErrNone) + { + switch( iQueryId ) + { + case EQueryIMSI: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ISA interface: Got IMSI reply.\n"))); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IMSI"), + iSubscriberId.Ptr(), + iSubscriberId.Size())); + + // Convert the IMSI from unicode to UTF8 characters. + + completion_status = imsiInUnicode.set_buffer(iSubscriberId.Ptr(), iSubscriberId.Size(), false, false); + + if (completion_status != eap_status_ok) + { + imsiInUnicode.reset(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ISA interface: Could not set buffer for IMSI. Not proceeding further here.\n"))); + } + else + { + completion_status = m_am_tools->convert_unicode_to_utf8(imsi, imsiInUnicode); + + if (completion_status != eap_status_ok) + { + imsi.reset(); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ISA interface: Could not convert IMSI from UNICODE to UTF8. Not proceeding further here.\n"))); + } + } + + TRAP(error, iParent->complete_SIM_imsi_L(&imsi, completion_status)); + + break; + + case EQuerySRESandKC: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("####ISA interface: Got KC and SRES reply. ####\n"))); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("SRES before trimming"), + iEAPSim.iSRES.Ptr(), + iEAPSim.iSRES.Size())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("KC"), + iEAPSim.iKC.Ptr(), + iEAPSim.iKC.Size())); + + // Trim the length of SRES - Remove once the correct length is set for SRES, may be by the API or some where else. + iEAPSim.iSRES.SetLength(SIM_SRES_LENGTH); + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("SRES after Trimming"), + iEAPSim.iSRES.Ptr(), + iEAPSim.iSRES.Size())); + + delete iAuthenticationData; + iAuthenticationData = NULL; + + // Close the custom API since we don't need it any more. + iCustomAPI.Close(); + + // Complete + TRAP(error, iParent->complete_SIM_kc_and_sres_L(iEAPSim.iKC, iEAPSim.iSRES, completion_status)); + + break; + } + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ISA interface: Got error reply.\n"))); + + if( EQuerySRESandKC == iQueryId ) + { + // We have to close the custom API anyway. + // Rest will be taken care in destructor. + iCustomAPI.Close(); + + // Handle duplicate RAND values. + // If duplicate RAND values are being used, we get KErrArgument here. + if(iStatus.Int() == KErrArgument) + { + completion_status = eap_status_not_fresh_challenges; + } + else + { + // For all other errors. + completion_status = m_am_tools->convert_am_error_to_eapol_error(iStatus.Int()); + } + + // Complete the request. + TRAP(error, iParent->complete_SIM_kc_and_sres_L(iEAPSim.iKC, iEAPSim.iSRES, completion_status)); + } + else if(EQueryIMSI == iQueryId) + { + completion_status = m_am_tools->convert_am_error_to_eapol_error(iStatus.Int()); + + TRAP(error, iParent->complete_SIM_imsi_L(&imsi, completion_status)); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +TInt CEapSimIsaInterface::CreateMMETelConnectionL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Creating MMETel connection.\n"))); + + TInt errorCode = KErrNone; + + // MMETel need to be connected only once. + if( !iMMETELConnectionStatus ) + { + RTelServer::TPhoneInfo phoneInfo; + TInt phoneCount = 0; + + // Connect to ETel server + User::LeaveIfError( iServer.Connect() ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Connected to ETel server.\n"))); + + //This function loads an ETel TSY module. mmtsy. + errorCode = iServer.LoadPhoneModule( KMmTsyModuleName ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Loaded phone module.\n"))); + + if ( errorCode != KErrNone && errorCode != KErrAlreadyExists ) + { + User::Leave( errorCode ); + } + + iServer.SetExtendedErrorGranularity( RTelServer::EErrorExtended ); + + //This function retrieves the total number of phones supported by all + //the currently loaded ETel (TSY) modules. + User::LeaveIfError( iServer.EnumeratePhones( phoneCount ) ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Number of phones supported by the loaded ETel = %d.\n"), phoneCount)); + + // This function retrieves information associated with the specified phone + while ( ( phoneCount-- ) && ( phoneInfo.iName != KMmTsyPhoneName ) ) + { + User::LeaveIfError( iServer.GetPhoneInfo( phoneCount, phoneInfo ) ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got phone info.\n"))); + } + + // This function opens a phone subsession by name, + User::LeaveIfError( iPhone.Open( iServer, phoneInfo.iName ) ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Opened phone subsession.\n"))); + + // MMETel connected and the phone module loaded fine. + iMMETELConnectionStatus = ETrue; + } + else + { + // MMETel already connected. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("MMETel connected once already.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return errorCode; +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/eap_am_type_gsmsim_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/eap_am_type_gsmsim_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2799 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 193 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_type_gsmsim_symbian.h" +#include "abs_eap_am_crypto.h" +#include "abs_eap_am_mutex.h" +#include "eap_am_tools_symbian.h" +#include "eap_state_notification.h" +#include "EapSimDbDefaults.h" +#include "EapSimDbParameterNames.h" +#include "EapSimDbUtils.h" +#include "eap_am_trace_symbian.h" + +#include // For DBMS +#include // For RReadStream + +#if defined (USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + +#include "EapSimInterface.h" + +#endif // End of #if defined (USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + +const TUint SIM_IMSI_LENGTH = 15u; +const TUint KIdentityHeaderLength = 2; +const TUint KMaxSqlQueryLength = 512; +const TUint KMaxDBFieldNameLength = 255; +const TInt KDefaultColumnInView_One = 1; // For DB view. +const TInt KMicroSecsInASecond = 1000000; // 1000000 micro seconds is 1 second. + +#if defined(__WINS__) + +const char TEST_IMSI[] = "244070100000001"; + +#endif + +// ================= MEMBER FUNCTIONS ======================= + +eap_am_type_gsmsim_symbian_c::eap_am_type_gsmsim_symbian_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id) +: eap_am_type_gsmsim_c(tools) +, m_am_tools(static_cast(tools)) // Tools class must be of type eap_am_tools_symbian because + // this is Symbian specific code. +, m_partner(partner) +, m_triplet_file(tools) +, m_nai_realm(tools) +, m_index_type(aIndexType) +, m_index(aIndex) +, m_tunneling_type(aTunnelingType) +, m_is_valid(false) +, m_is_client(aIsClient) +, m_stored_reauth_id(tools) +, m_stored_pseudonym(tools) +, m_previous_imsi(tools) +, m_stored_required_completion(eap_type_gsmsim_complete_none) +, m_stored_received_eap_identifier(0) +, m_shutdown_was_called(false) + +#if !defined (USE_EAP_GSMSIM_INTERFACE) +, m_sim_algorithm(tools) +#endif // #if !defined (USE_EAP_GSMSIM_INTERFACE) + +, m_simulator_sim_algorithm(sim_algorithm_nokia_test_network_xor) +, m_simulator_sim_ki(tools) +, m_copy_of_n_rands(tools) +, m_n_kc(tools) +, m_n_sres(tools) +, m_uma_automatic_realm_prefix(tools) +, m_receive_network_id(tools) +, m_rands_handled(0) +, m_do_rand_uniqueness_check(true) +, m_max_session_time(0) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#ifdef USE_EAP_EXPANDED_TYPES + + m_tunneling_vendor_type = m_tunneling_type.get_vendor_type(); + +#else + + m_tunneling_vendor_type = static_cast(m_tunneling_type); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + if (receive_network_id != 0 + && receive_network_id->get_is_valid_data() == true) + { + eap_status_e status = m_receive_network_id.set_copy_of_network_id( + receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + + +//-------------------------------------------------- + +void eap_am_type_gsmsim_symbian_c::ConstructL() +{ + // Open/create database + EapSimDbUtils::OpenDatabaseL(m_database, m_session, m_index_type, m_index, m_tunneling_type); + + // SIM IMSI, Kc and SRES are queried from SIM using SIM interface. + // If this is not used then Nokia test algorithms and test IMSI is used. +#if defined (USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + if (m_is_client == true) + { + m_isa_if = CEapSimIsaInterface::NewL(m_am_tools, this); + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAP-SIM server does not work at the moment in plugintester.\n"))); + User::Leave(KErrNotSupported); + } +#endif //#if defined (USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) +} + +//-------------------------------------------------- + +eap_am_type_gsmsim_symbian_c* eap_am_type_gsmsim_symbian_c::NewL( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id) +{ + eap_am_type_gsmsim_symbian_c* self = new(ELeave) eap_am_type_gsmsim_symbian_c( + aTools, + aPartner, + aIndexType, + aIndex, + aTunnelingType, + aIsClient, + receive_network_id); + + CleanupStack::PushL(self); + + if (self->get_is_valid() != true) + { + User::Leave(KErrGeneral); + } + + self->ConstructL(); + + CleanupStack::Pop(); + return self; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_type_gsmsim_symbian_c::~eap_am_type_gsmsim_symbian_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::~eap_am_type_gsmsim_symbian_c(): this = 0x%08x\n"), + this)); + + m_database.Close(); + m_session.Close(); + +#if defined(USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + if (m_is_client == true) + { + delete m_isa_if; + } +#endif //#if defined(USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::store_reauth_parameters( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter) +{ + // These kind of wrapper functions are needed because the Symbian L-functions must be executed in + // trap harness. + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Send error if any of the parameters are invalid. + if(XKEY == NULL + || K_aut == NULL + || K_encr == NULL) + { + // Some of the parameters are invalid. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::store_reauth_parameters: ") + EAPL("ERROR: Invalid parameters\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // Send error if any of the parameters are too long. + if(XKEY->get_data_length() > KMaxXKeyLengthInDB + || K_aut->get_data_length() > KMaxK_autLengthInDB + || K_encr->get_data_length() > KMaxK_encrLengthInDB ) + { + // Some of the parameters are too long. Can't store them in DB. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::store_reauth_parameters: ") + EAPL("Too long parameters. Length: XKEY=%d, K_aut=%d, K_encr=%d\n"), + XKEY->get_data_length(), K_aut->get_data_length(), K_encr->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_ok); + + TRAPD(err, store_reauth_parametersL(XKEY, K_aut, K_encr, reauth_counter)); + if (err != KErrNone) + { + // Convert the leave error code to EAPOL stack error code. + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_type_gsmsim_symbian_c::store_reauth_parametersL( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr, + const u32_t reauth_counter) +{ + // The _L functions do the actual thing. + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Form the insertion command + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, &KXKey, &KK_aut, &KK_encr, &KReauthCounter, &KSimTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Create pointers to the data + TPtrC8 key(XKEY->get_data(XKEY->get_data_length()), XKEY->get_data_length()); + TPtrC8 aut(K_aut->get_data(K_aut->get_data_length()), K_aut->get_data_length()); + TPtrC8 enc(K_encr->get_data(K_encr->get_data_length()), K_encr->get_data_length()); + + // Update the columns in the database + view.FirstL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("XKEY to DB"), key.Ptr(), key.Length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("K_aut to DB"), aut.Ptr(), aut.Length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("K_encr to DB"), enc.Ptr(), enc.Length())); + + view.SetColL(colSet->ColNo(KXKey), key); // XKEY + view.SetColL(colSet->ColNo(KK_aut), aut); // K_aut + view.SetColL(colSet->ColNo(KK_encr), enc); // K_encr + view.SetColL(colSet->ColNo(KReauthCounter), reauth_counter); // ReauthCounter + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + view.PutL(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::store_reauth_keys_L(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + reauth_counter)); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + + +//-------------------------------------------------- + +eap_status_e eap_am_type_gsmsim_symbian_c::authentication_finished( + const bool true_when_successful, + const eap_gsmsim_authentication_type_e authentication_type, + const eap_type_gsmsim_identity_type identity_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + TInt err(KErrNone); + + // Store the authentication time if the full authentication is successful + if (true_when_successful == true + && authentication_type == GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH) + { + TRAP(err,store_authentication_timeL()); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + } + + if (true_when_successful == false) + { + if( identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID + || identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID ) + { + (void) store_pseudonym_id(0,0); + } + + if( identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID + || identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID ) + { + (void) store_reauthentication_id(0,0); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::query_reauth_parameters( + eap_variable_data_c * const reauth_XKEY, + eap_variable_data_c * const reauth_K_aut, + eap_variable_data_c * const reauth_K_encr, + u32_t * const reauth_counter) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_ok); + TRAPD(err, query_reauth_parametersL(reauth_XKEY, reauth_K_aut, reauth_K_encr, reauth_counter)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_type_gsmsim_symbian_c::query_reauth_parametersL( + eap_variable_data_c * const reauth_XKEY, + eap_variable_data_c * const reauth_K_aut, + eap_variable_data_c * const reauth_K_encr, + u32_t * const reauth_counter) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Form the query + _LIT(KSQLQuery, "SELECT %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KXKey, &KK_aut, &KK_encr, &KReauthCounter, &KSimTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the values from DB + TPtrC8 key = view.ColDes8(colSet->ColNo(KXKey)); + TPtrC8 aut = view.ColDes8(colSet->ColNo(KK_aut)); + TPtrC8 enc = view.ColDes8(colSet->ColNo(KK_encr)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("XKEY from DB"), key.Ptr(), key.Length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("K_aut from DB"), aut.Ptr(), aut.Length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("K_encr from DB"), enc.Ptr(), enc.Length())); + + eap_status_e status(eap_status_process_general_error); + + // Store the values to the supplied buffers + status = reauth_XKEY->set_copy_of_buffer(key.Ptr(),key.Length()); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + + status = reauth_K_aut->set_copy_of_buffer(aut.Ptr(),aut.Length()); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + + status = reauth_K_encr->set_copy_of_buffer(enc.Ptr(),enc.Length()); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + *reauth_counter = view.ColUint(colSet->ColNo(KReauthCounter)); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::query_reauth_parametersL(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + *reauth_counter)); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::increase_reauth_counter() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_ok); + TRAPD(err, increase_reauth_counterL()); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_type_gsmsim_symbian_c::increase_reauth_counterL() +{ + // Form the insertion command + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, &KReauthCounter, &KSimTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the previous value + TUint counter = view.ColUint(colSet->ColNo(KReauthCounter)); + + view.UpdateL(); + + // Increment the value + view.SetColL(colSet->ColNo(KReauthCounter), counter + 1); + + counter = view.ColUint(colSet->ColNo(KReauthCounter)); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::increase_reauth_counterL(): %s, m_saved_reauth_counter %d.\n"), + (m_is_client == true ? "client": "server"), + counter)); + + view.PutL(); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + + { + // Read triplet file name + eap_status_e status = type_configure_read( + cf_str_EAP_GSMSIM_triplet_file.get_field(), + &m_triplet_file); + if (status != eap_status_ok + && status != eap_status_illegal_configure_field) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + // This is optional value. Don't care even if the configure fails. + } + +#endif //#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + + { + eap_status_e status = type_configure_read( + cf_str_EAP_GSMSIM_manual_realm.get_field(), + &m_nai_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + if (m_nai_realm.get_is_valid_data() == false) + { + // We should really generate a NAI here but it's too much work. + // So for testing purposes so we'll just use 3gppnetwork.org + + _LIT8(KDefaultRealm, "3gppnetwork.org"); + TBuf8<16> tmp(KDefaultRealm); + status = m_nai_realm.set_copy_of_buffer(tmp.Ptr(), tmp.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + +#if !defined (USE_EAP_GSMSIM_INTERFACE) +// Needed only for test environment. + + { + eap_variable_data_c simulator_sim_algorithm(m_am_tools); + + eap_status_e status = m_partner->read_configure( + cf_str_EAP_GSMSIM_simulator_sim_algorithm.get_field(), + &simulator_sim_algorithm); + if (status == eap_status_ok + && simulator_sim_algorithm.get_is_valid_data() == true + && simulator_sim_algorithm.get_data_length() > 0ul + && simulator_sim_algorithm.get_data( + simulator_sim_algorithm.get_data_length()) != 0) + { + if (cf_str_EAP_GSMSIM_simulator_sim_algorithm_config_value_nokia_test_network_xor + .get_field()->compare( + m_am_tools, + &simulator_sim_algorithm) == true) + { + m_simulator_sim_algorithm = sim_algorithm_nokia_test_network_xor; + } + else if (cf_str_EAP_GSMSIM_simulator_sim_algorithm_config_value_tls_prf_with_shared_secret + .get_field()->compare( + m_am_tools, + &simulator_sim_algorithm) == true) + { + m_simulator_sim_algorithm = sim_algorithm_tls_prf_with_shared_secret; + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: illegal configuration value %s\n"), + cf_str_EAP_GSMSIM_simulator_sim_algorithm.get_field()->get_field())); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + } + + { + eap_status_e status = m_partner->read_configure( + cf_str_EAP_GSMSIM_simulator_sim_ki.get_field(), + &m_simulator_sim_ki); + if (status == eap_status_ok + && m_simulator_sim_ki.get_is_valid_data() == true + && m_simulator_sim_ki.get_data_length() > 0ul + && m_simulator_sim_ki.get_data( + m_simulator_sim_ki.get_data_length()) != 0) + { + // OK. + eap_status_e status = m_sim_algorithm.set_simulator_sim_ki(&m_simulator_sim_ki); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } +#endif // #if !defined (USE_EAP_GSMSIM_INTERFACE) + + +#if defined(USE_EAP_SIM_RESET_RAND_DATABASES) + { + eap_variable_data_c do_rand_uniqueness_check(m_am_tools); + + eap_status_e status = type_configure_read( + cf_str_EAP_GSMSIM_do_rand_uniqueness_check.get_field(), + &do_rand_uniqueness_check); + + if (status == eap_status_ok + && do_rand_uniqueness_check.get_is_valid_data() == true + && do_rand_uniqueness_check.get_data_length() == sizeof(u32_t)) + { + u32_t *flag = reinterpret_cast(do_rand_uniqueness_check.get_data()); + if (flag != 0) + { + if (*flag == 0) + { + m_do_rand_uniqueness_check = false; + (void) reset_rand_check(); + } + } + } + } +#endif //#if defined(USE_EAP_SIM_RESET_RAND_DATABASES) + + { + // Read Maximum Session Validity Time from the config file + eap_variable_data_c sessionTimeFromFile(m_am_tools); + + eap_status_e status = m_partner->read_configure( + cf_str_EAP_GSMSIM_max_session_validity_time.get_field(), + &sessionTimeFromFile); + + if (status == eap_status_ok + && sessionTimeFromFile.get_is_valid_data() == true + && sessionTimeFromFile.get_data_length() == sizeof(u32_t)) + { + u32_t *session = reinterpret_cast(sessionTimeFromFile.get_data()); + if (session != 0) + { + // Update the max session time (in micro seconds). + // configuration file saves the time in seconds. We have to convert it to micro seconds. + m_max_session_time = static_cast(*session) * static_cast(KMicroSecsInASecond); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_rands_handled = 0ul; + +#if defined(USE_EAP_SIM_RESET_RAND_DATABASES) + if (m_do_rand_uniqueness_check == false) + { + (void) reset_rand_check(); + } +#endif //#if defined(USE_EAP_SIM_RESET_RAND_DATABASES) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eap_am_type_gsmsim_symbian_c::shutdown(), m_shutdown_was_called=%d\n"), + (m_is_client == true) ? "client": "server", + m_shutdown_was_called)); + + m_shutdown_was_called = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +#if defined(USE_EAP_SIM_RESET_RAND_DATABASES) + +eap_status_e eap_am_type_gsmsim_symbian_c::reset_rand_check() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + RFs fs; + + TInt error = fs.Connect(); + if (error != KErrNone) + { + eap_status_e status(m_am_tools->convert_am_error_to_eapol_error(error)); + + send_error_notification(status); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RFs::Connect() failed %d.\n"), + status)); + (void) EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + // Remove RAND check databases. + _LIT(KRandDb, "C:\\private\\101f7989\\rand_db.cur"); + _LIT(KRandDbPrev, "C:\\private\\101f7989\\rand_db.prv"); + + TInt err = fs.Delete(KRandDb); + (void) EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(err)); + + err = fs.Delete(KRandDbPrev); + (void) EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(err)); + + fs.Close(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +#endif //#if defined(USE_EAP_SIM_RESET_RAND_DATABASES) + +//-------------------------------------------------- + +#if defined(__WINS__) + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::query_SIM_imsi( + u8_t * const imsi, const u32_t max_length, u32_t * const imsi_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (imsi == 0 || imsi_length == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + // This function returns Nokia test SIM IMSI. + // It is used only when real ISA interface is not used. + + *imsi_length = m_am_tools->strlen(TEST_IMSI); + if (*imsi_length > max_length) + { + // ERROR, too short buffer. + *imsi_length = 0u; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + m_am_tools->memmove(imsi, TEST_IMSI, m_am_tools->strlen(TEST_IMSI)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +#endif //#if defined(__WINS__) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::store_pseudonym_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const pseudonym) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Send error if the pseudonym is too long. + if(pseudonym != NULL && pseudonym->get_data_length() > KMaxPseudonymIdLengthInDB) + { + // Pseudonym too long. Can't store this in DB. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::store_pseudonym_id: ") + EAPL("Too long Pseudonym. Length=%d\n"), + pseudonym->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_ok); + + TRAPD(err, store_pseudonym_idL(network_id, pseudonym)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_type_gsmsim_symbian_c::store_pseudonym_idL( + const eap_am_network_id_c * const /*network_id*/, + const eap_variable_data_c * const pseudonym) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Form the insertion command + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, &KPseudonymId, &KSimTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Update the columns in the database + view.FirstL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Create pointer to the data + if ((pseudonym != NULL) + && (pseudonym->get_is_valid_data() == true)) + { + TPtrC8 pseudonymId( + pseudonym->get_data(pseudonym->get_data_length()), + pseudonym->get_data_length()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("pseudonymId to DB"), pseudonymId.Ptr(), pseudonymId.Length())); + + view.SetColL(colSet->ColNo(KPseudonymId), pseudonymId); + } + else + { + // If passed pseudonym was 0 that means the field must be cleared. + view.SetColNullL(colSet->ColNo(KPseudonymId)); + } + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + view.PutL(); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::store_reauthentication_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const reauthentication_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Send error if the pseudonym is too long. + if(reauthentication_id != NULL + && reauthentication_id->get_data_length() > KMaxReauthIdLengthInDB) + { + // Reauth id too long. Can't store this in DB. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::store_reauthentication_id: ") + EAPL("Too long reauth id. Length=%d\n"), + reauthentication_id->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_ok); + + TRAPD(err, store_reauthentication_idL(network_id, reauthentication_id)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_type_gsmsim_symbian_c::store_reauthentication_idL( + const eap_am_network_id_c * const /*network_id*/, + const eap_variable_data_c * const reauthentication_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Form the insertion command + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, &KReauthId, &KSimTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + view.FirstL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Create pointer to the data + if ((reauthentication_id != NULL) + && (reauthentication_id->get_is_valid_data() == true)) + { + TPtrC8 reauthId( + reauthentication_id->get_data(reauthentication_id->get_data_length()), + reauthentication_id->get_data_length()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("reauthId to DB"), reauthId.Ptr(), reauthId.Length())); + + view.SetColL(colSet->ColNo(KReauthId), reauthId); + } + else + { + // If passed reauthentication_id was 0 that means the field must be cleared. + view.SetColNullL(colSet->ColNo(KReauthId)); + } + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + view.PutL(); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} +//-------------------------------------------------- + +eap_status_e eap_am_type_gsmsim_symbian_c::store_imsi( + const eap_variable_data_c * const imsi) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Send error if the IMSI is too long. + if(imsi != NULL && imsi->get_data_length() > KMaxIMSILengthInDB) + { + // IMSI too long. Can't store this in DB. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::store_imsi: ") + EAPL("Too long IMSI. Length=%d\n"), + imsi->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_status_e status(eap_status_ok); + + TRAPD(err, store_imsiL(imsi)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_type_gsmsim_symbian_c::store_imsiL( + const eap_variable_data_c * const imsi) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Form the insertion command + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, &KPreviousIMSI, &KSimTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + // Evaluate view + RDbView view; + + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + view.FirstL(); + + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Create pointer to the data + if ((imsi != 0) + && (imsi->get_is_valid_data() == true)) + { + TPtrC8 tmp_imsi( + imsi->get_data(imsi->get_data_length()), + imsi->get_data_length()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("IMSI to DB"), tmp_imsi.Ptr(), tmp_imsi.Length())); + + view.SetColL(colSet->ColNo(KPreviousIMSI), tmp_imsi); + } + else + { + // If passed IMSI was 0 that means the field must be cleared. + view.SetColNullL(colSet->ColNo(KPreviousIMSI)); + } + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + view.PutL(); + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + const bool must_be_synchronous, + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const length_of_mnc, + const gsmsim_payload_AT_type_e required_identity, + const eap_type_gsmsim_complete_e required_completion, + const u8_t received_eap_identifier) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + EAP_ASSERT((IMSI != 0) && (pseudonym_identity != 0) && (reauthentication_identity != 0)); + + m_stored_required_completion = required_completion; + m_stored_received_eap_identifier = received_eap_identifier; + + TRAPD(err, query_SIM_IMSI_or_pseudonym_or_reauthentication_idL( + must_be_synchronous, + IMSI, + pseudonym_identity, + reauthentication_identity, + automatic_realm, + length_of_mnc, + required_identity, + required_completion, + received_eap_identifier)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + + if (status != eap_status_pending_request) + { + send_error_notification(status); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_type_gsmsim_symbian_c::query_SIM_IMSI_or_pseudonym_or_reauthentication_idL( + const bool /*must_be_synchronous*/, + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const reauthentication_identity, + eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. + u32_t * const /*length_of_mnc*/, + const gsmsim_payload_AT_type_e required_identity, + const eap_type_gsmsim_complete_e /*required_completion*/, + const u8_t /*received_eap_identifier*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_process_general_error); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Reset everything + IMSI->reset(); + pseudonym_identity->reset(); + reauthentication_identity->reset(); + automatic_realm->reset(); + m_stored_pseudonym.reset(); + m_stored_reauth_id.reset(); + m_previous_imsi.reset(); + + // Query all the relevant parameters + + _LIT(KSQLQuery, "SELECT %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KReauthId, &KReauthCounter, &KPseudonymId, + &KPreviousIMSI, &KSimTableName, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the values from DB + TUint reauthCount = view.ColUint32(colSet->ColNo(KReauthCounter)); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("query_SIM_IMSI_or_pseudonym_or_reauthentication_idL: ") + EAPL("required_identity=%d, reauthCount from DB %d\n"), + required_identity, reauthCount)); + + // A stream is needed for LONG columns in DB. + RDbColReadStream readStream; + + // Get pseudonym ID from DB. + HBufC8* pseudonymIdBuf = HBufC8::NewLC(KMaxPseudonymIdLengthInDB); // Buffer for pseudonym id. + TPtr8 pseudonymId = pseudonymIdBuf->Des(); + + readStream.OpenLC(view, colSet->ColNo(KPseudonymId)); + readStream.ReadL(pseudonymId, view.ColLength(colSet->ColNo(KPseudonymId))); + readStream.Close(); + CleanupStack::Pop(&readStream); // Pop readStream. + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("pseudonymId from DB"), pseudonymId.Ptr(), pseudonymId.Length())); + + // Get reauthentication ID from DB. + HBufC8* reauthIdBuf = HBufC8::NewLC(KMaxReauthIdLengthInDB); // Buffer for reauthentication id. + TPtr8 reauthId = reauthIdBuf->Des(); + + readStream.OpenLC(view, colSet->ColNo(KReauthId)); + readStream.ReadL(reauthId, view.ColLength(colSet->ColNo(KReauthId))); + readStream.Close(); + CleanupStack::Pop(&readStream); // Pop readStream. + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("reauthId from DB"), reauthId.Ptr(), reauthId.Length())); + +#if defined(USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + + // Get the previous IMSI. Used for checking if SIM has been changed. + // The checking is done in complete_SIM_imsi_L + + TPtrC8 tmp_imsi = view.ColDes8(colSet->ColNo(KPreviousIMSI)); + + status = m_previous_imsi.set_copy_of_buffer(tmp_imsi.Ptr(), tmp_imsi.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("imsi from DB"), tmp_imsi.Ptr(), tmp_imsi.Size())); +#endif + + if (required_identity == gsmsim_payload_AT_ANY_ID_REQ) + { + if (is_session_valid()) + { + if(reauthId.Length() > 0) + { + +#if defined(USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + + // Store the reauth id in case we are using asynchronous processing (= ISA interface) + status = m_stored_reauth_id.set_copy_of_buffer(reauthId.Ptr(), reauthId.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } +#endif + + status = reauthentication_identity->set_copy_of_buffer(reauthId.Ptr(), reauthId.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + } + } + } + + CleanupStack::PopAndDestroy(reauthIdBuf); // Delete reauthIdBuf + + if (required_identity == gsmsim_payload_AT_ANY_ID_REQ + || required_identity == gsmsim_payload_AT_FULLAUTH_ID_REQ) + { + if (pseudonymId.Length() > 0) + { + +#if defined(USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + + // Store the pseudonym in case we are using + // asynchronous processing (= ISA interface) + status = m_stored_pseudonym.set_copy_of_buffer( + pseudonymId.Ptr(), + pseudonymId.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } +#endif + + status = pseudonym_identity->set_copy_of_buffer( + pseudonymId.Ptr(), + pseudonymId.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + } + } + + CleanupStack::PopAndDestroy(pseudonymIdBuf); // Delete pseudonymIdBuf + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + + CleanupStack::PopAndDestroy( &view ); // Close view. + + CleanupStack::PopAndDestroy(buf); // Delete buf + + if (IMSI->get_is_valid_data() == false + || IMSI->get_buffer_length() < SIM_IMSI_LENGTH) + { + status = IMSI->init(SIM_IMSI_LENGTH); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + IMSI->set_is_valid(); + } + + { + +#if defined (USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + + // For real GSM SIM interface. + // Use real GSM SIM interface active object. + // This gets the IMSI from the real GSM SIM, using Custom API. + + m_isa_if->QueryIMSIL(); + + // KErrCompletion means that the operation is pending. + User::Leave(KErrCompletion); + +#elif defined(__WINS__) // For plugin tester. + + // Here we get the Nokia test SIM IMSI since the SIM interface is disabled. + u32_t imsi_length = 0u; + + status = query_SIM_imsi( + IMSI->get_buffer(SIM_IMSI_LENGTH), + SIM_IMSI_LENGTH, + &imsi_length); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + else if (imsi_length != SIM_IMSI_LENGTH) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + + status = IMSI->set_data_length(imsi_length); + + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + +#endif // End of #if defined (USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_gsmsim_symbian_c::complete_SIM_imsi_L( + const eap_variable_data_c * const IMSI, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_process_general_error); + + if (completion_status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_SIM_imsi_L: failed status=%d\n"), + completion_status)); + + send_error_notification(eap_status_identity_query_failed); + + // Signal upper layer + status = get_am_partner()->complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query( + IMSI, + &m_stored_pseudonym, + &m_stored_reauth_id, + 0, + EAP_TYPE_GSMSIM_DEFAULT_MNC_LENGTH_3_BYTES, + m_stored_required_completion, + m_stored_received_eap_identifier, + completion_status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (IMSI == 0 + || IMSI->get_is_valid_data() == false) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_SIM_imsi_L: failed no IMSI retrieved.\n"), + completion_status)); + + send_error_notification(eap_status_identity_query_failed); + + // IMSI query failed + status = get_am_partner()->complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query( + IMSI, + &m_stored_pseudonym, + &m_stored_reauth_id, + 0, + EAP_TYPE_GSMSIM_DEFAULT_MNC_LENGTH_3_BYTES, + m_stored_required_completion, + m_stored_received_eap_identifier, + eap_status_hardware_not_ready); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + if (m_previous_imsi.get_data_length() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Previous IMSI not valid. Storing new IMSI.\n"))); + + // Store new IMSI + status = store_imsi(IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else if (IMSI->compare(&m_previous_imsi) != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIM has been changed since last authentication. ") + EAPL("Clear pseudonym & reauth IDs.\n"))); + + // Different IMSI -> SIM has been changed. + // Reset pseudonym and reauthentication ID. + status = store_reauthentication_id(0, 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = store_pseudonym_id(0, 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + // Store new IMSI + status = store_imsi(IMSI); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + // Reset stored pseudonym & reauthentication ID + m_stored_pseudonym.reset(); + m_stored_reauth_id.reset(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIM has not been changed.\n"))); + } + + status = get_am_partner()->complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query( + IMSI, + &m_stored_pseudonym, + &m_stored_reauth_id, + 0, + 0ul, + m_stored_required_completion, + m_stored_received_eap_identifier, + eap_status_ok); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + +//#endif + + return status; +} + +//-------------------------------------------------- + +// +eap_status_e eap_am_type_gsmsim_symbian_c::cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); +#if defined (USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + if (m_is_client == true) + { + m_isa_if->Cancel(); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +#else + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_not_supported; + +#endif //#if defined (USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::query_SIM_kc_and_sres( + const u8_t * const rand, + u8_t * const kc, + u8_t * const sres) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_ok); + +#if !defined (USE_EAP_GSMSIM_INTERFACE) + if (rand == 0 + || kc == 0 + || sres == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + u8_t tmp[SIM_KC_LENGTH + SIM_SRES_LENGTH]; + m_am_tools->memset(tmp, 0, sizeof(tmp)); + + status = m_sim_algorithm.generate_kc_sres( + m_simulator_sim_algorithm, + rand, + SIM_RAND_LENGTH, + tmp, + SIM_KC_LENGTH + SIM_SRES_LENGTH); + + m_am_tools->memmove(sres, tmp, SIM_SRES_LENGTH); + m_am_tools->memmove(kc, tmp + SIM_SRES_LENGTH, SIM_KC_LENGTH); + +#elif defined (USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + + TBuf8 rand_buf; + rand_buf.Copy(rand, SIM_RAND_LENGTH); + TRAPD(err, m_isa_if->QueryKcAndSRESL(rand_buf)); + if (err != KErrNone) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("m_isa_if->QueryKcAndSRESL(): %d"), + err)); + + status = m_am_tools->convert_am_error_to_eapol_error(err); + if (status == eap_status_process_general_error) + { + status = eap_status_credential_query_failed; + } + send_error_notification(status); + } + else + { + status = eap_status_pending_request; + } +#else + + EAP_UNREFERENCED_PARAMETER(rand); + EAP_UNREFERENCED_PARAMETER(kc); + EAP_UNREFERENCED_PARAMETER(sres); + +#endif //#if !defined (USE_EAP_GSMSIM_INTERFACE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_gsmsim_symbian_c::complete_SIM_kc_and_sres_L( + TDesC8& aKc, + TDesC8& aSRES, + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("complete_SIM_kc_and_sres\n"))); + + eap_status_e status(eap_status_ok); + + if (completion_status != eap_status_ok) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_SIM_kc_and_sres_L: failed status=%d\n"), + completion_status)); + + send_error_notification(eap_status_credential_query_failed); + + // Signal upper layer + status = get_am_partner()->complete_SIM_kc_sres( + &m_copy_of_n_rands, + &m_n_kc, + &m_n_sres, + completion_status); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#if !defined(USE_EAP_GSMSIM_INTERFACE) || defined(__WINS__) + EAP_UNREFERENCED_PARAMETER(aKc); + EAP_UNREFERENCED_PARAMETER(aSRES); +#else + + if (static_cast(aKc.Length()) != SIM_KC_LENGTH + || static_cast(aSRES.Length()) != SIM_SRES_LENGTH) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_SIM_kc_and_sres_L: Illegal length Kc or SRES\n"))); + + send_error_notification(eap_status_credential_query_failed); + + status = get_am_partner()->complete_SIM_kc_sres( + &m_copy_of_n_rands, + &m_n_kc, + &m_n_sres, + eap_status_hardware_not_ready); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_rands_handled++; + + TInt rand_count = m_copy_of_n_rands.get_data_length() / SIM_RAND_LENGTH; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("complete_SIM_kc_and_sres: m_rands_handled=%d, rand_count=%d\n"), + m_rands_handled, + rand_count)); + + status = m_n_kc.add_data(aKc.Ptr(), aKc.Size()); + if (status != eap_status_ok) + { + send_error_notification(eap_status_credential_query_failed); + + // Signal upper layer + status = get_am_partner()->complete_SIM_kc_sres( + &m_copy_of_n_rands, + &m_n_kc, + &m_n_sres, + status); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_n_sres.add_data(aSRES.Ptr(), aSRES.Size()); + if (status != eap_status_ok) + { + send_error_notification(eap_status_credential_query_failed); + + // Signal upper layer + status = get_am_partner()->complete_SIM_kc_sres( + &m_copy_of_n_rands, + &m_n_kc, + &m_n_sres, + status); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (m_rands_handled == rand_count) + { + // All rands handled. Complete request. + status = get_am_partner()->complete_SIM_kc_sres( + &m_copy_of_n_rands, + &m_n_kc, + &m_n_sres, + eap_status_ok); + } + else + { + // Handle next rand. + u8_t *rand = m_copy_of_n_rands.get_data_offset( + m_rands_handled*SIM_RAND_LENGTH, + SIM_RAND_LENGTH); + if (rand == 0) + { + send_error_notification(eap_status_credential_query_failed); + + // ERROR: Signal upper layer bacause of allocation error. + status = get_am_partner()->complete_SIM_kc_sres( + &m_copy_of_n_rands, + &m_n_kc, + &m_n_sres, + eap_status_allocation_error); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-SIM next RAND"), + rand, + SIM_RAND_LENGTH)); + + status = query_SIM_kc_and_sres( + rand, + 0, // Kc and SRES are handled in the complete function and ignored here in this asynchronous case + 0); + + if (status != eap_status_ok + && status != eap_status_pending_request) + { + send_error_notification(eap_status_credential_query_failed); + + // Signal upper layer + status = get_am_partner()->complete_SIM_kc_sres( + &m_copy_of_n_rands, + &m_n_kc, + &m_n_sres, + status); + } + + } +#endif // defined(USE_EAP_GSMSIM_INTERFACE) || defined(__WINS__) + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::query_SIM_kc_sres( + const bool must_be_synchronous, + const eap_variable_data_c * const p_n_rands, + eap_variable_data_c * const n_kc, + eap_variable_data_c * const n_sres) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(must_be_synchronous); + + eap_status_e status(eap_status_process_general_error); + // NOTE if user needs to use state_selector or n_rands after return from query_SIM_kc_sres() + // function those parameters MUST be copied using copy() member function of each parameter. + // For example: saved_n_rands = n_rands->copy() + // saved_state_selector = state_selector->copy() + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + if (n_kc == 0 + || n_sres == 0 + || p_n_rands == 0) + { + // Something is really wrong. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + m_rands_handled = 0ul; + +#if !defined(USE_EAP_GSMSIM_INTERFACE) || defined(__WINS__) + + eap_variable_data_c *copy_of_n_rands = p_n_rands->copy(); + + if (copy_of_n_rands == 0) + { + return eap_status_allocation_error; + } + + u32_t count = copy_of_n_rands->get_data_length() / SIM_RAND_LENGTH; + + if (n_kc->get_is_valid_data() == false + || n_kc->get_buffer_length() < count*SIM_KC_LENGTH) + { + n_kc->init(count*SIM_KC_LENGTH); + n_kc->set_is_valid(); + } + + if (n_sres->get_is_valid_data() == false + || n_sres->get_buffer_length() < count*SIM_SRES_LENGTH) + { + n_sres->init(count*SIM_SRES_LENGTH); + n_sres->set_is_valid(); + } + + u8_t *rand = copy_of_n_rands->get_data(copy_of_n_rands->get_data_length()); + u8_t *kc = n_kc->get_data(n_kc->get_data_length()); + u8_t *sres = n_sres->get_data(n_sres->get_data_length()); + + for (u32_t ind = 0u; ind < count; ind++) + { + query_SIM_kc_and_sres( + rand+(ind*SIM_RAND_LENGTH), + kc+(ind*SIM_KC_LENGTH), + sres+(ind*SIM_SRES_LENGTH)); + } + + n_kc->set_data_length(count*SIM_KC_LENGTH); + n_sres->set_data_length(count*SIM_SRES_LENGTH); + + status = get_am_partner()->complete_SIM_kc_sres( + copy_of_n_rands, + n_kc, + n_sres, + eap_status_ok); + + delete copy_of_n_rands; + + if (status == eap_status_ok) + { + status = eap_status_completed_request; + } + +#else + + // This is for ISA interface + status = m_copy_of_n_rands.set_copy_of_buffer(p_n_rands); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u8_t *rand = m_copy_of_n_rands.get_data(SIM_RAND_LENGTH); + if (rand == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_n_kc.reset(); + m_n_sres.reset(); + + status = query_SIM_kc_and_sres( + rand, + 0, // Kc and SRES are handled in the complete function and ignored here in this asynchronous case + 0); + +#endif // !defined(USE_EAP_GSMSIM_INTERFACE) || defined(__WINS__) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//------------------------------------------------- + +// +eap_status_e eap_am_type_gsmsim_symbian_c::cancel_SIM_kc_sres_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#if defined (USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + if (m_is_client == true) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_gsmsim_symbian_c::cancel_SIM_kc_sres_query() - cancelling IF query\n"))); + + m_isa_if->Cancel(); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +#else + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + +#endif //#if defined (USE_EAP_GSMSIM_INTERFACE) && !defined(__WINS__) + +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::handle_gsmsim_notification( + eap_gsmsim_notification_codes_e gsmsim_notification_code ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + switch ((gsmsim_notification_code & gsmsim_notification_code_value)) + { + case eap_gsmsim_notification_no_F_no_P_user_has_not_subscribed_to_the_requested_service: + send_error_notification(eap_status_user_has_not_subscribed_to_the_requested_service); + break; + + case eap_gsmsim_notification_no_F_no_P_users_calls_are_barred: + send_error_notification(eap_status_users_calls_are_barred); + break; + + default: + // Do nothing + break; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_type_gsmsim_symbian_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_am_type_gsmsim_symbian_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT(data != 0); + EAP_ASSERT(field != 0); + + eap_status_e status(eap_status_ok); + + m_am_tools->trace_configuration( + status, + field, + data); + + // Trap must be set here because the OS independent portion of EAP SIM + // that calls this function does not know anything about Symbian. + TRAPD(err, type_configure_readL( + field->get_field(), + field->get_field_length(), + data)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::type_configure_read(): LEAVE from type_configure_readL, error=%d, Reads configuration from partner.\n"), + err)); + + status = m_partner->read_configure( + field, + data); + } + + m_am_tools->trace_configuration( + status, + field, + data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_gsmsim_symbian_c::type_configure_readL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(field_length); + + // Create a buffer for the ascii strings - initialised with the argument + HBufC8* asciibuf = HBufC8::NewLC(KMaxDBFieldNameLength); + TPtr8 asciiString = asciibuf->Des(); + asciiString.Copy(reinterpret_cast(field)); + + // Buffer for unicode parameter + HBufC* unicodebuf = HBufC::NewLC(KMaxDBFieldNameLength); + TPtr unicodeString = unicodebuf->Des(); + + // Convert to unicode + unicodeString.Copy(asciiString); + + // Now do the database query + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQueryRow, &unicodeString, &KSimTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + if (view.FirstL()) + { + eap_status_e status; + view.GetL(); + switch (view.ColType(KDefaultColumnInView_One)) + { + case EDbColText: + { + unicodeString = view.ColDes(KDefaultColumnInView_One); + // Convert to 8-bit + asciiString.Copy(unicodeString); + if (asciiString.Size() > 0) + { + status = data->set_copy_of_buffer(asciiString.Ptr(), asciiString.Size()); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + } + else + { + status = data->init(0); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + data->set_is_valid(); + break; + } + } + break; + + case EDbColUint32: + { + TUint value; + value = view.ColUint32(KDefaultColumnInView_One); + status = data->set_copy_of_buffer(&value, sizeof(value)); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + } + break; + + default: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Unexpected column type.\n"))); + User::Leave(KErrGeneral); + break; + } + } + else + { + // Could not find parameter + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Could not find configuration parameter.\n"))); + User::Leave(KErrArgument); + } + + CleanupStack::PopAndDestroy(4); // Close view, & 3 strings + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void eap_am_type_gsmsim_symbian_c::send_error_notification(const eap_status_e error) +{ + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + // Notifies the lower level of an authentication error. + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, + eap_type_gsmsim, + eap_state_none, + eap_general_state_authentication_error, + 0, + false); + + notification.set_authentication_error(error); + + m_partner->state_notification(¬ification); +} + + +//-------------------------------------------------- +// +// SERVER / TEST CODE BEGINS. +// +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + +#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + #include "read_rand_and_triplets.h" +#endif //#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::query_SIM_triplets( + const bool /*must_be_synchronous*/, + const eap_variable_data_c * const /*p_username*/, + eap_variable_data_c * const /* p_imsi */, + eap_type_sim_triplet_array_c * const triplets, + eap_type_gsmsim_identity_type * const /* type */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Only used in EAP SIM server. + + // NOTE if user needs to use state_selector or imsi after return from query_SIM_triplets() + // function those parameters MUST be copied using copy() member function of each parameter. + // For example: saved_imsi = p_imsi_or_pseudonym->copy() + // saved_state_selector = state_selector->copy() + + eap_status_e status = eap_status_process_general_error; + +#if !defined (USE_EAP_GSMSIM_INTERFACE) + + if (triplets == 0) + { + // Something is really wrong. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_process_general_error; + } + +#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + if (m_triplet_file.get_is_valid() == true) + { + status = read_triplets_from_file(m_am_tools, &m_triplet_file, triplets); + } else +#endif // defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) + { + const u32_t rand_length = 16u; + u8_t test_rand[] = "0123456789abcdef"; + const u32_t triplet_count = 2u; + u32_t ind; + + triplets->set_triplet_count(triplet_count); + + for (ind = 0u; ind < triplet_count; ind++) + { + eap_type_saesim_triplet_c *tripl = triplets->get_triplet(m_am_tools, ind); + u8_t tmp[rand_length] = {0,}; + + status = m_am_tools->get_crypto()->get_rand_bytes( + test_rand, + sizeof(test_rand)-1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = tripl->get_rand()->set_copy_of_buffer(reinterpret_cast(test_rand), rand_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = tripl->get_kc()->init(SIM_KC_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + tripl->get_kc()->set_is_valid(); + tripl->get_kc()->set_data_length(SIM_KC_LENGTH); + + status = tripl->get_sres()->init(SIM_SRES_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + tripl->get_sres()->set_is_valid(); + tripl->get_sres()->set_data_length(SIM_SRES_LENGTH); + + m_sim_algorithm.generate_kc_sres( + m_simulator_sim_algorithm, + test_rand, + rand_length, + tmp, + SIM_KC_LENGTH + SIM_SRES_LENGTH); + + status = tripl->get_sres()->set_copy_of_buffer(tmp, SIM_SRES_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = tripl->get_kc()->set_copy_of_buffer(tmp + SIM_SRES_LENGTH, SIM_KC_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + +#else + EAP_UNREFERENCED_PARAMETER(triplets); +#endif // #if !defined (USE_EAP_GSMSIM_INTERFACE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::cancel_SIM_triplets_query() +{ + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: cancel_SIM_triplets_query() not supported here..\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::generate_encryption_IV( + eap_variable_data_c * const encryption_IV, + const u32_t IV_length) +{ + // EAP SIM server only. + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = encryption_IV->init(IV_length); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + encryption_IV->set_is_valid(); + encryption_IV->set_data_length(IV_length); + + m_am_tools->get_crypto()->add_rand_seed_hw_ticks(); + + status = m_am_tools->get_crypto()->get_rand_bytes( + encryption_IV->get_data(encryption_IV->get_data_length()), + encryption_IV->get_data_length()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::query_imsi_from_username( + const bool must_be_synchronous, + const u8_t next_eap_identifier, + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const username, + eap_variable_data_c * const imsi, + eap_type_gsmsim_identity_type * const identity_type, + const eap_type_gsmsim_complete_e /* completion_action */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(must_be_synchronous); + EAP_UNREFERENCED_PARAMETER(next_eap_identifier); + EAP_UNREFERENCED_PARAMETER(network_id); + // Setup headers for comparison + + _LIT8(KReauthHeader, "RE"); + TBufC8<2> reauthHeader(KReauthHeader); + + _LIT8(KPseudonymHeader, "PS"); + TBufC8<2> pseudonymHeader(KPseudonymHeader); + + if (username->get_data_length() >= 2) + { + TBuf8<2> head; + head.Append(username->get_data(2), KIdentityHeaderLength); + // Note this is syncronous call. + + const u8_t * const username_prefix = username->get_data_offset(0u, 1u); + + if (username->get_data_length() <= SIM_IMSI_LENGTH+1u + && username->get_data_length() > 1u + && username_prefix != 0 + && *username_prefix == *GSMSIM_IMSI_PREFIX_CHARACTER) + { + // We have IMSI. + eap_status_e status = imsi->set_copy_of_buffer( + username->get_data_offset(1u, username->get_data_length()-1u), + username->get_data_length()-1u); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + *identity_type = GSMSIM_IDENTITY_TYPE_IMSI_ID; + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("IMSI"), + imsi->get_data(imsi->get_data_length()), + imsi->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("query_imsi_from_username(): Used EAP-Identity type %d.\n"), + *identity_type)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (head == reauthHeader) + { + eap_status_e status = imsi->add_data( + username->get_data_offset(KIdentityHeaderLength, + SIM_IMSI_LENGTH), + SIM_IMSI_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + *identity_type = GSMSIM_IDENTITY_TYPE_RE_AUTH_ID; + } + else if (head == pseudonymHeader) + { + eap_status_e status = imsi->add_data( + username->get_data_offset( + KIdentityHeaderLength, + SIM_IMSI_LENGTH), + SIM_IMSI_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + *identity_type = GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID; + } + else + { + *identity_type = GSMSIM_IDENTITY_TYPE_NONE; + } + } + else + { + *identity_type = GSMSIM_IDENTITY_TYPE_NONE; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; + +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + +//-------------------------------------------------- + +// +eap_status_e eap_am_type_gsmsim_symbian_c::cancel_imsi_from_username_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::check_is_rand_unused( + const eap_variable_data_c * const /* n_rands */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::set_rand_is_used( + const eap_variable_data_c * const /* n_rands */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::generate_reauthentication_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const reauthentication_identity, + const u32_t maximum_reauthentication_identity_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_process_general_error); + _LIT8(KTmp, "RE"); + TBufC8 header(KTmp); + reauthentication_identity->reset(); + status = reauthentication_identity->add_data(header.Ptr(), KIdentityHeaderLength); + if (status != eap_status_ok) + { + reauthentication_identity->reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = generate_identity(network_id, imsi, reauthentication_identity, + maximum_reauthentication_identity_length); + if (status != eap_status_ok) + { + reauthentication_identity->reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = reauthentication_identity->add_data(GSMSIM_AT_CHARACTER, GSMSIM_AT_CHARACTER_LENGTH); + if (status != eap_status_ok) + { + reauthentication_identity->reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = reauthentication_identity->add_data(&m_nai_realm); + if (status != eap_status_ok) + { + reauthentication_identity->reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::generate_pseudonym_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const pseudonym, + const u32_t maximum_pseudonym_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_process_general_error); + _LIT8(KTmp, "PS"); + TBufC8 header(KTmp); + status = pseudonym->add_data(header.Ptr(), KIdentityHeaderLength); + if (status != eap_status_ok) + { + pseudonym->reset(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = generate_identity(network_id, imsi, pseudonym, maximum_pseudonym_length); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +eap_status_e eap_am_type_gsmsim_symbian_c::generate_identity( + const eap_am_network_id_c * const /* network_id */, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const identity, + const u32_t /*maximum_identity_length*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = identity->add_data(imsi); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_symbian_c::type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + // NOTE: At the moment this is not called anywhere. + // NOTE: This is really just for simulation. + // Write is routed to partner object. + eap_status_e status = m_partner->write_configure( + field, + data); + return status; +} + +//-------------------------------------------------- + +bool eap_am_type_gsmsim_symbian_c::is_session_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + bool sessionValidity(false); + + TRAPD(err, sessionValidity = is_session_validL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_gsmsim_symbian_c::is_session_valid - LEAVE - error=%d, Assuming session is invalid \n"), + err)); + + sessionValidity = false; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return sessionValidity; +} + +//-------------------------------------------------- + +bool eap_am_type_gsmsim_symbian_c::is_session_validL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_gsmsim_symbian_c::is_session_validL - start \n"))); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT(KSQLQuery, "SELECT %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &cf_str_EAP_GSMSIM_max_session_validity_time_literal, + &KGSMSIMLastFullAuthTime, &KSimTableName, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + TInt64 maxSessionTime = view.ColInt64(colSet->ColNo(cf_str_EAP_GSMSIM_max_session_validity_time_literal)); + TInt64 fullAuthTime = view.ColInt64(colSet->ColNo(KGSMSIMLastFullAuthTime)); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + CleanupStack::PopAndDestroy(&view); // Close view. + CleanupStack::PopAndDestroy(buf); // Delete buf. + + // If the max session time from DB is zero then we use the + // one read from configuration file. + + if( maxSessionTime == 0) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("Session Validity - Using max session validity time from config file\n"))); + + maxSessionTime = m_max_session_time; // value from configuration file. + } + + // Get the current time. + TTime currentTime; + currentTime.UniversalTime(); + + TTime lastFullAuthTime(fullAuthTime); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + TDateTime fullAuthDateTime = lastFullAuthTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("Session Validity - Current Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1, currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("Session Validity - Last Full Auth Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + fullAuthDateTime.Day()+1, fullAuthDateTime.Month()+1, fullAuthDateTime.Year(), fullAuthDateTime.Hour(), + fullAuthDateTime.Minute(), fullAuthDateTime.Second(), fullAuthDateTime.MicroSecond())); + +#endif + + TTimeIntervalMicroSeconds interval = currentTime.MicroSecondsFrom(lastFullAuthTime); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_gsmsim_symbian_c::is_session_validL:interval in microseconds:"), + &(interval.Int64()), + sizeof(interval.Int64()) ) ); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_gsmsim_symbian_c::is_session_validL:max session time in microseconds:"), + &(maxSessionTime), + sizeof(maxSessionTime) ) ); + + +#if defined(_DEBUG) || defined(DEBUG) + + TTimeIntervalMinutes intervalMins; + TInt error = currentTime.MinutesFrom(lastFullAuthTime, intervalMins); + + if(error == KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::is_session_validL()") + EAPL("interval in Minutes =%d\n"), + intervalMins.Int())); + } + +#endif + + + if( maxSessionTime >= interval.Int64() ) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_gsmsim_symbian_c::is_session_validL - Session Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return true; + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_gsmsim_symbian_c::is_session_validL - Session NOT Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return false; + } +} + +//-------------------------------------------------- + +void eap_am_type_gsmsim_symbian_c::store_authentication_timeL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_gsmsim_symbian_c::store_authentication_timeL - start \n"))); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT(KSQLQuery, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KGSMSIMLastFullAuthTime, &KSimTableName, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row for updation. + view.FirstL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the current universal time. + TTime currentTime; + currentTime.UniversalTime(); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_gsmsim_symbian_c::store_authentication_time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1,currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + +#endif + + TInt64 fullAuthTime = currentTime.Int64(); + + view.SetColL(colSet->ColNo(KGSMSIMLastFullAuthTime), fullAuthTime); + + view.PutL(); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + CleanupStack::PopAndDestroy(&view); // Close view. + CleanupStack::PopAndDestroy(buf); // Delete buf. + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/eap_am_type_gsmsim_symbian_simulator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/eap_am_type_gsmsim_symbian_simulator.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,708 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 194 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#define EAP_AM_MEMORY_GUARD + #include "eap_am_memory.h" +#undef EAP_AM_MEMORY_GUARD + +#include "eap_tools.h" +#include "eap_am_type_gsmsim_symbian_simulator.h" +#include "eap_am_crypto.h" +#include "abs_eap_am_mutex.h" + +const u32_t SIM_IMSI_LENGTH = 15u; + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_type_gsmsim_simulator_c::~eap_am_type_gsmsim_simulator_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_type_gsmsim_simulator_c::eap_am_type_gsmsim_simulator_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const CEapPluginInterface::TIndexType aIndexType, + const TInt aIndex) +: eap_am_type_gsmsim_c(tools) +, m_am_tools(tools) +, m_partner(partner) +, saved_pseudonym(tools) +, m_is_valid(eap_boolean_true) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(aIndexType); + EAP_UNREFERENCED_PARAMETER(aIndex); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::store_reauth_keys( + const eap_variable_data_c * const XKEY, + const eap_variable_data_c * const K_aut, + const eap_variable_data_c * const K_encr) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(XKEY); + EAP_UNREFERENCED_PARAMETER(K_aut); + EAP_UNREFERENCED_PARAMETER(K_encr); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +const eap_status_e eap_am_type_gsmsim_simulator_c::authentication_finished( + const eap_boolean_e true_when_successfull, + const eap_gsmsim_authentication_type_e authentication_type) +{ + EAP_UNREFERENCED_PARAMETER(true_when_successfull); + EAP_UNREFERENCED_PARAMETER(authentication_type); + + eap_status_e status = eap_status_ok; + return status; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_reauth_parameters( + eap_variable_data_c * const reauth_XKEY, + eap_variable_data_c * const reauth_K_aut, + eap_variable_data_c * const reauth_K_encr, + u32_t * const reauth_counter) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(reauth_XKEY); + EAP_UNREFERENCED_PARAMETER(reauth_K_aut); + EAP_UNREFERENCED_PARAMETER(reauth_K_encr); + EAP_UNREFERENCED_PARAMETER(reauth_counter); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::increase_reauth_counter() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = eap_status_not_supported; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT const eap_status_e eap_am_type_gsmsim_simulator_c::configure() +{ + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_SIM_imsi( + u8_t * const imsi, const u32_t max_length, u32_t * const imsi_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + const char tmp_imsi[] = "244070100000001"; + *imsi_length = m_am_tools->strlen(tmp_imsi); + if (*imsi_length > max_length) + { + // ERROR, too short buffer. + *imsi_length = 0u; + return eap_status_allocation_error; + } + m_am_tools->memcpy(imsi, tmp_imsi, m_am_tools->strlen(tmp_imsi)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::store_pseudonym_id( + const eap_am_network_id_c * const /*network_id*/, + const eap_variable_data_c * const pseudonym) +{ + return saved_pseudonym.set_copy_of_buffer(pseudonym); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::store_reauthentication_id( + const eap_am_network_id_c * const /*network_id*/, + const eap_variable_data_c * const /* reauthentication_id */) +{ + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_SIM_IMSI_or_pseudonym_or_reauthentication_id( + const eap_boolean_e must_be_synchronous, + eap_variable_data_c * const IMSI, + eap_variable_data_c * const pseudonym_identity, + eap_variable_data_c * const /* reauthentication_identity */) +{ + EAP_UNREFERENCED_PARAMETER(must_be_synchronous); + + eap_status_e status = eap_status_process_general_error; + + if (IMSI == 0 + || pseudonym_identity == 0) + { + // Something is really wrong. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_process_general_error; + } + + if (IMSI->get_is_valid() == eap_boolean_false + || IMSI->get_buffer_length() < SIM_IMSI_LENGTH) + { + IMSI->init(SIM_IMSI_LENGTH); + IMSI->set_is_valid(); + } + + if (saved_pseudonym.get_is_valid() == eap_boolean_true) + { + // We have stored pseudonym_identity. + if (pseudonym_identity == 0) + { + // Something is really wrong. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_process_general_error; + } + pseudonym_identity->set_copy_of_buffer(&saved_pseudonym); + } + + + { + u32_t imsi_length = 0u; + + status = query_SIM_imsi( + IMSI->get_data(SIM_IMSI_LENGTH), + SIM_IMSI_LENGTH, + &imsi_length); + + if (status != eap_status_ok + || imsi_length != SIM_IMSI_LENGTH) + { + return status; + } + + IMSI->set_data_length(imsi_length); + } + + if (must_be_synchronous == eap_boolean_false) + { + status = get_am_partner()->complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query( + IMSI, + pseudonym_identity, + 0); + + if (status == eap_status_ok) + { + status = eap_status_completed_request; + } + } + + return status; +} + +//-------------------------------------------------- + +// +eap_status_e eap_am_type_gsmsim_simulator_c::cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_SIM_kc_and_sres( + const u8_t * const /* imsi */, const u32_t /* imsi_length */, + const u8_t * const rand, const u32_t rand_length, + u8_t * const kc, u32_t * const kc_length, + u8_t * const sres, u32_t * const sres_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(rand_length); + + EAP_ASSERT_ALWAYS(rand_length == SIM_RAND_LENGTH); + EAP_ASSERT_ALWAYS(*kc_length == SIM_KC_LENGTH); + EAP_ASSERT_ALWAYS(*sres_length == SIM_SRES_LENGTH); + + const u8_t test_Ki[SIM_RAND_LENGTH] = {0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5}; + + u8_t tmp[SIM_KC_LENGTH + SIM_SRES_LENGTH]; + m_am_tools->memset(tmp, 0, sizeof(tmp)); + + u32_t i = 0; + + for(i = 0; i < (SIM_KC_LENGTH + SIM_SRES_LENGTH); i++) + { + tmp[i] = (u8_t)(rand[i] ^ test_Ki[i]); + } + + m_am_tools->memcpy(sres, tmp, *sres_length); + m_am_tools->memcpy(kc, tmp + *sres_length, *kc_length); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::handle_gsmsim_notification( + eap_gsmsim_triplet_status_e /* gsmsim_notification_code */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_SIM_triplets( + const eap_boolean_e must_be_synchronous, + const eap_variable_data_c * const /* p_username */, + eap_variable_data_c * const /* p_imsi */, + eap_type_sim_triplet_array_c * const triplets, + eap_type_gsmsim_identity_type * const type) +{ + EAP_UNREFERENCED_PARAMETER(must_be_synchronous); + EAP_UNREFERENCED_PARAMETER(type); + + // NOTE if user needs to use state_selector or imsi after return from query_SIM_triplets() + // function those parameters MUST be copied using copy() member function of each parameter. + // For example: saved_imsi = p_imsi_or_pseudonym->copy() + // saved_state_selector = state_selector->copy() + + eap_status_e status = eap_status_process_general_error; + const u32_t rand_length = 16u; + const u8_t test_rand[] = "0123456789abcdef"; + const u8_t test_Ki[rand_length] = {0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5, + 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5}; + const u32_t triplet_count = 2u; + u32_t ind; + u32_t i = 0; + + if (triplets == 0) + { + // Something is really wrong. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_process_general_error; + } + + triplets->set_triplet_count(triplet_count); + + for (ind = 0u; ind < triplet_count; ind++) + { + eap_type_saesim_triplet_c *tripl = triplets->get_triplet(m_am_tools, ind); + u8_t tmp[rand_length] = {0,}; + + status = tripl->get_rand()->set_copy_of_buffer((u8_t *)test_rand, 16); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = tripl->get_kc()->init(SIM_KC_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + tripl->get_kc()->set_is_valid(); + tripl->get_kc()->set_data_length(SIM_KC_LENGTH); + + status = tripl->get_sres()->init(SIM_SRES_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + tripl->get_sres()->set_is_valid(); + tripl->get_sres()->set_data_length(SIM_SRES_LENGTH); + + for (i = 0; i < (SIM_KC_LENGTH + SIM_SRES_LENGTH); i++) + { + tmp[i] = (u8_t)(test_rand[i] ^ test_Ki[i]); + } + + tripl->get_sres()->set_copy_of_buffer(tmp, SIM_SRES_LENGTH); + tripl->get_kc()->set_copy_of_buffer(tmp + SIM_SRES_LENGTH, SIM_KC_LENGTH); + + } + + return status; +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + +//-------------------------------------------------- + +#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::cancel_SIM_triplets_query() +{ + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: cancel_SIM_triplets_query() not supported here..\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +#endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_SIM_kc_sres( + const eap_boolean_e must_be_synchronous, + //const eap_variable_data_c * const p_imsi, + const eap_variable_data_c * const p_n_rands, + eap_variable_data_c * const n_kc, + eap_variable_data_c * const n_sres) +{ + EAP_UNREFERENCED_PARAMETER(must_be_synchronous); + + // NOTE if user needs to use state_selector or n_rands after return from query_SIM_kc_sres() + // function those parameters MUST be copied using copy() member function of each parameter. + // For example: saved_n_rands = n_rands->copy() + // saved_state_selector = state_selector->copy() + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == eap_boolean_true); + + if (n_kc == 0 + || n_sres == 0 + || p_n_rands == 0) + { + // Something is really wrong. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + + eap_status_e status = eap_status_process_general_error; + eap_variable_data_c copy_of_imsi(m_am_tools); + + // First we must query IMSI. + u32_t imsi_length = 0u; + + copy_of_imsi.init(SIM_IMSI_LENGTH); + copy_of_imsi.set_is_valid(); + + status = query_SIM_imsi( + copy_of_imsi.get_data(copy_of_imsi.get_data_length()), + SIM_IMSI_LENGTH, + &imsi_length); + + if (status != eap_status_ok + || imsi_length != SIM_IMSI_LENGTH) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + copy_of_imsi.set_data_length(imsi_length); + + + eap_variable_data_c *copy_of_n_rands = p_n_rands->copy(); + + if (copy_of_n_rands == 0) + { + return eap_status_allocation_error; + } + + + u32_t kc_length = SIM_KC_LENGTH; + u32_t sres_length = SIM_SRES_LENGTH; + + u32_t count = copy_of_n_rands->get_data_length() / SIM_RAND_LENGTH; + + if (n_kc->get_is_valid() == eap_boolean_false + || n_kc->get_buffer_length() < count*SIM_KC_LENGTH) + { + n_kc->init(count*SIM_KC_LENGTH); + n_kc->set_is_valid(); + } + + if (n_sres->get_is_valid() == eap_boolean_false + || n_sres->get_buffer_length() < count*SIM_SRES_LENGTH) + { + n_sres->init(count*SIM_SRES_LENGTH); + n_sres->set_is_valid(); + } + + u8_t *rand = copy_of_n_rands->get_data(copy_of_n_rands->get_data_length()); + u8_t *kc = n_kc->get_data(n_kc->get_data_length()); + u8_t *sres = n_sres->get_data(n_sres->get_data_length()); + + for (u32_t ind = 0u; ind < count; ind++) + { + kc_length = SIM_KC_LENGTH; + sres_length = SIM_SRES_LENGTH; + query_SIM_kc_and_sres( + copy_of_imsi.get_data(copy_of_imsi.get_data_length()), + copy_of_imsi.get_data_length(), + rand+(ind*SIM_RAND_LENGTH), + SIM_RAND_LENGTH, + kc+(ind*SIM_KC_LENGTH), + &kc_length, + sres+(ind*SIM_SRES_LENGTH), + &sres_length); + } + + n_kc->set_data_length(count*SIM_KC_LENGTH); + n_sres->set_data_length(count*SIM_SRES_LENGTH); + + status = get_am_partner()->complete_SIM_kc_sres( + copy_of_n_rands, + n_kc, + n_sres); + + delete copy_of_n_rands; + + if (status == eap_status_ok) + { + status = eap_status_completed_request; + } + + return status; +} + +//-------------------------------------------------- + +// +eap_status_e eap_am_type_gsmsim_simulator_c::cancel_SIM_kc_sres_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::generate_encryption_IV( + eap_variable_data_c * const encryption_IV, + const u32_t IV_length) +{ + encryption_IV->init(IV_length); + encryption_IV->set_is_valid(); + encryption_IV->set_data_length(IV_length); + + m_am_tools->get_crypto()->add_rand_seed_hw_ticks(); + + eap_status_e status = m_am_tools->get_crypto()->get_rand_bytes( + encryption_IV->get_data(encryption_IV->get_data_length()), + encryption_IV->get_data_length()); + + return status; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_imsi_from_username( + const eap_boolean_e must_be_synchronous, + const u8_t next_eap_identifier, + const eap_am_network_id_c * const /* network_id */, + const eap_variable_data_c * const /* username */, + eap_variable_data_c * const imsi, + eap_type_gsmsim_identity_type * const type) +{ + EAP_UNREFERENCED_PARAMETER(must_be_synchronous); + EAP_UNREFERENCED_PARAMETER(next_eap_identifier); + EAP_UNREFERENCED_PARAMETER(type); + + // Note this is syncronous call. + + imsi->init(SIM_IMSI_LENGTH); + imsi->set_is_valid(); + u32_t imsi_length = 0u; + query_SIM_imsi( + imsi->get_data(imsi->get_data_length()), + SIM_IMSI_LENGTH, + &imsi_length); + EAP_ASSERT_ALWAYS(imsi_length == SIM_IMSI_LENGTH); + imsi->set_data_length(imsi_length); + return eap_status_ok; + +} + +//-------------------------------------------------- + +// +eap_status_e eap_am_type_gsmsim_simulator_c::cancel_imsi_from_username_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::generate_reauthentication_id( + const eap_am_network_id_c * const network_id, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const reauthentication_identity, + const u32_t maximum_reauthentication_identity_length) +{ + // This is an example. + + return generate_pseudonym_id( + network_id, + imsi, + reauthentication_identity, + maximum_reauthentication_identity_length); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::generate_pseudonym_id( + const eap_am_network_id_c * const /* network_id */, + const eap_variable_data_c * const imsi, + eap_variable_data_c * const pseudonym, + const u32_t maximum_pseudonym_length) +{ + // This is an example. Pseudonym is mostly same length as IMSI. + eap_variable_data_c tmp_pseudonym(m_am_tools); + tmp_pseudonym.init(imsi->get_data_length()); + tmp_pseudonym.set_is_valid(); + tmp_pseudonym.set_data_length(imsi->get_data_length()); + + m_am_tools->get_crypto()->add_rand_seed_hw_ticks(); + + eap_status_e status = m_am_tools->get_crypto()->get_rand_bytes( + tmp_pseudonym.get_data(tmp_pseudonym.get_data_length()), + tmp_pseudonym.get_data_length()); + + + pseudonym->init(tmp_pseudonym.get_data_length()*2u); + pseudonym->set_is_valid(); + pseudonym->set_data_length(imsi->get_data_length()*2u); + + u32_t pseudonym_length = pseudonym->get_data_length(); + m_am_tools->convert_bytes_to_hex_ascii( + tmp_pseudonym.get_data_offset(0u, tmp_pseudonym.get_data_length()), + tmp_pseudonym.get_data_length(), + pseudonym->get_data_offset(0u, pseudonym->get_data_length()), + &pseudonym_length); + + if (pseudonym_length > maximum_pseudonym_length) + { + pseudonym_length = maximum_pseudonym_length; + } + pseudonym->set_data_length(pseudonym_length); + + return status; +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_type_gsmsim_simulator_c::set_is_valid() +{ + m_is_valid = eap_boolean_true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_boolean_e eap_am_type_gsmsim_simulator_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const eap_status_e eap_am_type_gsmsim_simulator_c::type_configure_read( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data) +{ + // Here configuration data must be read from type spesific database. + + // NOTE: This is really just for simulation. + // Read is routed to partner object. + eap_status_e status = m_partner->read_configure( + field, + field_length, + data); + return status; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT const eap_status_e eap_am_type_gsmsim_simulator_c::type_configure_write( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data) +{ + // Here configuration data must be read from type spesific database. + + // NOTE: This is really just for simulation. + // Write is routed to partner object. + eap_status_e status = m_partner->write_configure( + field, + field_length, + data); + return status; +} + +//-------------------------------------------------- + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/101f8e49.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/101f8e49.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Localization strings for project EAPOL +* +*/ + + + +// LOCALISATION STRINGS: + +// b: 50 +// e: 300 +// f: EDialogLabelFont +// d: This name for the EAP-SIM EAP type is displayed in the EAP type list in IAP UI and in EAP-PEAP +// d: encapsulated EAP type selection. +#define ESPL_GE_NAME "EAP-SIM" + + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/EapSim.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/EapSim.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,171 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPSIM_H_ +#define _EAPSIM_H_ + +// INCLUDES +#include +#include "eap_header.h" + +// FORWARD DECLARATIONS +class eap_am_network_id_c; + +// CLASS DECLARATION +/** +* Class that implements the generic EAP type interface. Implements EAP SIM protocol. +*/ +class CEapSim : public CEapType +{ +public: + + /** + * Construction function. Called by ECom after the EAP SIM plugin has been loaded. + * @param aIapInfo Pointer to the class that contains information about bearer type and unique index. + * @return Pointer to the instance. + */ + static CEapSim* NewL(const SIapInfo* aIapInfo); + + /** + * Destructor does nothing. + */ + virtual ~CEapSim(); + +#ifdef USE_EAP_SIMPLE_CONFIG + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @param eap_config_if Pointer used for call back to creater of stack (eapol_am_wlan_authentication_symbian_c class). + * @return Pointer to the implementation. + */ + virtual eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if); + +#else + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @return Pointer to the implementation. + */ + eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG + + /** + * Invokes the configuration UI. + **/ + TInt InvokeUiL(); + + /** + * Gets information about EAP type. + * @return Pointer to a class that contains the EAP type information. Also pushed to cleanup stack. + */ + CEapTypeInfo* GetInfoLC(); + + /** + * Deletes EAP type configuration + */ + void DeleteConfigurationL(); + + /** + * Returns the version of the interface that the EAP type implements. + * The client-side of the interface must always check the version with this function + * and not call the functions that are not implemented. New functions must be + * added to the end of the interface so that the order of the old functions + * does not change. + * @return Integer indicating the version. + */ + TUint GetInterfaceVersion(); + + /** + * Sets the tunneling type. This is used to indicate that this type is run inside another + * EAP type. + * @param aTunnelingType Type number for the tunneling type + */ + void SetTunnelingType(const TInt aTunnelingType); + + /** + * Changes the index of the saved parameters. + * @param aIndexType Indicates the bearer used for this connection. + * @param aIndex Index for the connection. aIndexType and aIndex uniquely specify the connection. + */ + void SetIndexL( + const TIndexType aIndexType, + const TInt aIndex); + + /** + * Sets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void SetConfigurationL(const EAPSettings& aSettings); + + /** + * Gets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void GetConfigurationL(EAPSettings& aSettings); + + /** + * Copies the EAP types configuration + * @param aDestinationIndex ID to where copy the settings. + */ + void CopySettingsL(const TIndexType aDestinationIndexType, const TInt aDestinationIndex); + + + +protected: + + /** + * Constructor initialises member variables. + */ + CEapSim(const TIndexType aIndexType, const TInt aIndex); + +private: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // Tunneling type + eap_type_value_e iTunnelingType; +}; + +#endif // _EAPSIM_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/EapSimDbDefaults.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/EapSimDbDefaults.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPSIMDBDEFAULTS_H_) +#define _EAPSIMDBDEFAULTS_H_ + +enum TGSMSIMUsePseudonymId +{ + EGSMSIMUsePseudonymIdNo, // False. Don't use pseudonym id. + EGSMSIMUsePseudonymIdYes, // True. Use pseudonym id. + EGSMSIMUsePseudonymIdNotValid // This indicates that the value is not configured. +}; + +enum TGSMSIMUseManualRealm +{ + EGSMSIMUseManualRealmNo, // False. Don't use Manual Realm. + EGSMSIMUseManualRealmYes, // True. Use Manual Realm. +}; + +enum TGSMSIMUseManualUsername +{ + EGSMSIMUseManualUsernameNo, // False. Don't use Manual Username. + EGSMSIMUseManualUsernameYes, // True. Use Manual Username. +}; + +// LOCAL CONSTANTS +const TInt default_EAP_GSMSIM_use_manual_realm = EGSMSIMUseManualRealmNo; +_LIT(default_EAP_GSMSIM_manual_realm, ""); + +const TInt default_EAP_GSMSIM_use_manual_username = EGSMSIMUseManualUsernameNo; +_LIT(default_EAP_GSMSIM_manual_username, ""); + +const TInt default_EAP_GSMSIM_use_pseudonym_identity = EGSMSIMUsePseudonymIdYes; // Default is, use pseudonym identity. + +const TInt64 default_MaxSessionTime = 0; // 0 means read from configuration file. +const TInt64 default_FullAuthTime = 0; + +const TUint KMaxPseudonymIdLengthInDB = 1020; // This is the max possible length of an EAP packet. +const TUint KMaxReauthIdLengthInDB = 1020; // Hope pseudonym id or reauth id can't be more than that. + +const TUint KMaxManualUsernameLengthInDB = 255; +const TUint KMaxManualRealmLengthInDB = 255; + +const TUint KMaxIMSILengthInDB = 15; + +const TUint KMaxXKeyLengthInDB = 20; +const TUint KMaxK_autLengthInDB = 16; +const TUint KMaxK_encrLengthInDB = 16; + +#endif // _EAPSIMDBDEFAULTS_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/EapSimDbParameterNames.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/EapSimDbParameterNames.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_EAPSIMDBPARAMETERNAMES_H_) +#define _EAPSIMDBPARAMETERNAMES_H_ + +#include "eap_type_gsmsim_types.h" + +// LOCAL CONSTANTS + +_LIT(KServiceType, "ServiceType"); +_LIT(KServiceIndex, "ServiceIndex"); +_LIT(KTunnelingType, "TunnelingType"); +_LIT(KPseudonymId, "PseudonymId"); +_LIT(KXKey, "XKEY"); +_LIT(KK_aut, "K_aut"); +_LIT(KK_encr, "K_encr"); +_LIT(KReauthCounter, "ReauthCounter"); +_LIT(KReauthId, "ReauthId"); +_LIT(KPreviousIMSI, "PreviousIMSI"); + +_LIT(KGSMSIMLastFullAuthTime, "EAP_GSMSIM_reauthentication_time"); + +#endif // _EAPSIMDBPARAMETERNAMES_H_ + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/EapSimDbUtils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/EapSimDbUtils.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,104 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPSIMDBUTILS_H_ +#define _EAPSIMDBUTILS_H_ + +// INCLUDES +#include +#include +#include "eap_header.h" + +// LOCAL CONSTANTS + +#ifdef SYMBIAN_SECURE_DBMS +// For EAP SIM secure database. +// Full path is not needed. The database eapsim.dat will be saved in the +// data cage path for DBMS. So it will be in "\private\100012a5\eapsim.dat" in C: drive. +// The maximum length of database name is 0x40 (KDbMaxName) , which is defined in d32dbms.h. + +_LIT(KDatabaseName, "c:eapsim.dat"); + +_LIT(KSecureUIDFormat, "SECURE[102072e9]"); // For the security policy. + +#else + +_LIT(KDatabaseName, "c:\\system\\data\\eapsim.dat"); + +#endif //#ifdef SYMBIAN_SECURE_DBMS + +_LIT(KSimTableName, "eapsim"); + + +// CLASS DECLARATION +class EapSimDbUtils +{ +public: + + static void OpenDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + /** + * Changes the settings' index + */ + static void SetIndexL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const TIndexType aNewIndexType, + const TInt aNewIndex, + const eap_type_value_e aNewTunnelingType); + + static void SetConfigurationL( + RDbNamedDatabase& aDatabase, + const EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + static void GetConfigurationL( + RDbNamedDatabase& aDatabase, + EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + static void CopySettingsL( + RDbNamedDatabase& aDatabase, + const TIndexType aSrcIndexType, + const TInt aSrcIndex, + const eap_type_value_e aSrcTunnelingType, + const TIndexType aDestIndexType, + const TInt aDestIndex, + const eap_type_value_e aDestTunnelingType); + + static void DeleteConfigurationL( + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + +}; + +#endif // _EAPSIMDBUTILS_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/EapSimGlobal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/EapSimGlobal.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPSIMGLOBAL_H_ +#define _EAPSIMGLOBAL_H_ + +// LOCAL CONSTANTS + +// Release date must be of format YYYYMMDD:. Will be localised automatically. +// Note that days and months start from 0. +_LIT(KReleaseDate, "20040829:"); +_LIT(KEapTypeVersion, "1.0"); +_LIT(KManufacturer, "Nokia"); +_LIT(KNokiaSignature, ""); // Not used +_LIT(KExtraInfo1, ""); // Not used +_LIT(KExtraInfo2, ""); // Not used + +#endif // _EAPSIMGLOBAL_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/eap-sim.hlp.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/eap-sim.hlp.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource headers for project EAPOL +* +*/ + + +// +// eap-sim.hlp.hrh +// + +// +// File generated on 15:30:14 18/6/2004 +// by cshlpcmp Version 010 +// + +#ifndef __EAP_SIM_HLP_HRH__ +#define __EAP_SIM_HLP_HRH__ + + +_LIT(KESPL_HLP_DIAL_CONFIGURATION,"ESPL_HLP_DIAL_CONFIGURATION"); + +#endif diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/eapsim.hlp.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/inc/eapsim.hlp.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource headers for project EAPOL +* +*/ + + +// +// eapsim.hlp.hrh +// + +// +// File generated on 10:42:26 28/7/2004 +// by cshlpcmp Version 010 +// + +#ifndef __EAPSIM_HLP_HRH__ +#define __EAPSIM_HLP_HRH__ + + +_LIT(KESPL_HLP_DIAL_CONFIGURATION,"ESPL_HLP_DIAL_CONFIGURATION"); + +#endif diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/inc/EapSimSimulatorConfig.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/inc/EapSimSimulatorConfig.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/inc/EapSimSimulatorPlugin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/inc/EapSimSimulatorPlugin.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPSIMPLUGIN_H_ +#define _EAPSIMPLUGIN_H_ + +#include "EapPluginInterface.h" +#include + +const TUint KVersion = 1; + +class CEapSimSimulatorConfiguration; +class eap_type_gsmsim_c; +class eap_am_type_gsmsim_simulator_c; + + +class CEapSimSimulatorPlugin : public CEapPluginInterface +{ +public: + CEapSimSimulatorPlugin(); + static CEapSimSimulatorPlugin* NewL(); + virtual ~CEapSimSimulatorPlugin(); + CEapConfigInterface* CreateConfigIfL(const TIndexType aIndexType, const TInt aIndex); + eap_base_type_c* CreateTypeIfL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const TIndexType aIndexType, + const TInt aIndex); + TUint GetVersion(void) { return KVersion; }; +private: + CEapSimSimulatorConfiguration* iConfig; + eap_type_gsmsim_c* iEapType; + eap_am_type_gsmsim_simulator_c* iAmEapType; +}; + +const TImplementationProxy ImplementationTable[] = +{ + {{0x2666666b}, CEapSimSimulatorPlugin::NewL} +}; + +#endif // _EAPSIMPLUGIN_H_ + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/src/26666669.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/src/26666669.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2666 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource definitions for project EAPOL +* +*/ + + + +#include +RESOURCE REGISTRY_INFO theInfo +{ +dll_uid = 0x26666669; +interfaces = + { + INTERFACE_INFO + { + interface_uid = 0x1666666a; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = 0x2666666b; + version_no = 1; + display_name = "EAP/SIM Simulator"; + default_data = "18"; + opaque_data = "some extra data"; + } + }; + } + }; +} diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/src/EapSimSimulatorConfig.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/src/EapSimSimulatorConfig.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 199 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "EapSimSimulatorConfig.h" + + +// ================= MEMBER FUNCTIONS ======================= + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/src/EapSimSimulatorPlugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/src/EapSimSimulatorPlugin.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 201 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "EapSimSimulatorPlugin.h" +#include "EapSimSimulatorConfig.h" +#include "eap_base_type.h" +#include "eap_am_type_gsmsim_symbian_simulator.h" +#include "eap_type_gsmsim.h" + + + +// ================= MEMBER FUNCTIONS ======================= + + +CEapSimSimulatorPlugin::CEapSimSimulatorPlugin() + : iAmEapType(NULL), + iEapType(NULL), + iConfig(NULL) +{ +} + +// ---------------------------------------------------------- + +CEapSimSimulatorPlugin* CEapSimSimulatorPlugin::NewL() +{ + return new (ELeave) CEapSimSimulatorPlugin; +} + +// ---------------------------------------------------------- + +CEapSimSimulatorPlugin::~CEapSimSimulatorPlugin() +{ + delete iAmEapType; +} + +// ---------------------------------------------------------- + +CEapConfigInterface* CEapSimSimulatorPlugin::CreateConfigIfL(const TIndexType aIndexType, + const TInt aIndex) +{ + EAP_UNREFERENCED_PARAMETER(aIndexType); + EAP_UNREFERENCED_PARAMETER(aIndex); + return NULL; +} + +// ---------------------------------------------------------- + +eap_base_type_c* CEapSimSimulatorPlugin::CreateTypeIfL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const TIndexType aIndexType, + const TInt aIndex) +{ + iAmEapType = new (ELeave) eap_am_type_gsmsim_simulator_c(aTools, aPartner, aIndexType, aIndex); + iEapType = new (ELeave) eap_type_gsmsim_c(aTools, aPartner, iAmEapType, false /* free_am */, is_client_when_true); + return iEapType; +} +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/src/EapSimSimulatorProxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/simulator/src/EapSimSimulatorProxy.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 203 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "EapSimSimulatorPlugin.h" + +// ================= OTHER EXPORTED FUNCTIONS ============== + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) +{ + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + + return ImplementationTable; +} + + +GLDEF_C TInt E32Dll(TDllReason /*aReason*/) +{ + + return(KErrNone); +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/101f8e49.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/101f8e49.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource definitions for project EAPOL +* +*/ + + + +// INCLUDES +#include +#include "101f8e49.loc" +#include "EapolUID.h" + +// RESOURCE DEFINITIONS +// --------------------------------------------------------- +// +// theInfo +// Contains the ECom registration information for EAP SIM +// +// --------------------------------------------------------- +// +RESOURCE REGISTRY_INFO theInfo +{ +dll_uid = EAP_SIM_DLL_UID; +interfaces = + { + INTERFACE_INFO + { + interface_uid = PLUGIN_INTERFACE_UID; + implementations = + { + + BINARY_IMPLEMENTATION_INFO + { + implementation_uid = EAP_SIM_IMPLEMENTATION_UID; + version_no = 1; + display_name = ESPL_GE_NAME; + default_data = {0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12}; // SIM + opaque_data = {0x0}; + } + }; + } + }; +} +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSim.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSim.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,330 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 207 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "EapSim.h" +#include "eap_base_type.h" +#include "eap_am_type_gsmsim_symbian.h" +#include "eap_type_gsmsim.h" +#include "EapSimGlobal.h" +#include +#include "EapSimDbUtils.h" + +#include +#include "EapSimUi.h" + +#include "eap_am_tools_symbian.h" + +// LOCAL CONSTANTS + +// The version number of this interface. +const TUint KInterfaceVersion = 1; + + +// ================= MEMBER FUNCTIONS ======================= + + +CEapSim::CEapSim(const TIndexType aIndexType, + const TInt aIndex) +: iIndexType(aIndexType) +, iIndex(aIndex) +, iTunnelingType(eap_type_none) +{ +} + +// ---------------------------------------------------------- + +CEapSim* CEapSim::NewL(const SIapInfo *aIapInfo) +{ + return new (ELeave) CEapSim(aIapInfo->indexType, aIapInfo->index); +} + +// ---------------------------------------------------------- + +CEapSim::~CEapSim() +{ +} + +// ---------------------------------------------------------- + +#ifdef USE_EAP_SIMPLE_CONFIG + +eap_base_type_c* CEapSim::GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const /*configuration_if*/) + +#else + +eap_base_type_c* CEapSim::GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG +{ + // Create AM + eap_am_type_gsmsim_symbian_c* amEapType = eap_am_type_gsmsim_symbian_c::NewL( + aTools, + aPartner, + iIndexType, + iIndex, + iTunnelingType, + is_client_when_true, + receive_network_id); + + if (amEapType->get_is_valid() == false) + { + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrGeneral); + } + + eap_base_type_c* type = 0; + + type = new eap_type_gsmsim_c( + aTools, + aPartner, + amEapType, + true /* free_am */, + is_client_when_true, + receive_network_id); + + if (type == 0) + { + // Out of memory + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrNoMemory); + } + else if (type->get_is_valid() == false) + { + type->shutdown(); + // amEapType is freed by eap_type_gsmsim_c + delete type; + User::Leave(KErrGeneral); + } + return type; +} + +// ---------------------------------------------------------- +TInt CEapSim::InvokeUiL() +{ + TInt buttonId(0); + +#ifdef USE_EAP_EXPANDED_TYPES + + CEapSimUiConnection uiConn(iIndexType, iIndex, iTunnelingType.get_vendor_type()); + +#else + + CEapSimUiConnection uiConn(iIndexType, iIndex, iTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + CEapSimUi* ui = CEapSimUi::NewL(&uiConn); + CleanupStack::PushL(ui); + buttonId = ui->InvokeUiL(); + CleanupStack::PopAndDestroy(ui); + return buttonId; +} +// ---------------------------------------------------------- +CEapTypeInfo* CEapSim::GetInfoLC() +{ + CEapTypeInfo* info = new(ELeave) CEapTypeInfo( + (TDesC&)KReleaseDate, + (TDesC&)KEapTypeVersion, + (TDesC&)KManufacturer); + + CleanupStack::PushL(info); + return info; +} + +// ---------------------------------------------------------- + +void CEapSim::DeleteConfigurationL() +{ + EapSimDbUtils::DeleteConfigurationL(iIndexType, iIndex, iTunnelingType); +} + +// ---------------------------------------------------------- + +TUint CEapSim::GetInterfaceVersion() +{ + return KInterfaceVersion; +} + +// ---------------------------------------------------------- + +void CEapSim::SetTunnelingType(const TInt aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + // Vendor id is eap_type_vendor_id_ietf always in this plugin. + iTunnelingType.set_eap_type_values(eap_type_vendor_id_ietf, aTunnelingType); + +#else + + iTunnelingType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES +} + + +// ---------------------------------------------------------- +void CEapSim::SetIndexL( + const TIndexType aIndexType, + const TInt aIndex) +{ + // First delete the target configuration + TIndexType tmpIndexType = iIndexType; + TInt tmpIndex = iIndex; + + iIndexType = aIndexType; + iIndex = aIndex; + + TInt err(KErrNone); + TRAP(err, DeleteConfigurationL()); + // Ignore error on purpose + + // Return the indices + iIndexType = tmpIndexType; + iIndex = tmpIndex; + + RDbNamedDatabase db; + + RDbs session; + + EapSimDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapSimDbUtils::SetIndexL( + db, + iIndexType, + iIndex, + iTunnelingType, + aIndexType, + aIndex, + iTunnelingType); + + iIndexType = aIndexType; + iIndex = aIndex; + + CleanupStack::PopAndDestroy(2); // db +} + +void CEapSim::SetConfigurationL(const EAPSettings& aSettings) +{ + RDbNamedDatabase db; + + RDbs session; + + // This also creates the IAP entry if it doesn't exist + EapSimDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapSimDbUtils::SetConfigurationL( + db, + aSettings, + iIndexType, + iIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db, session +} + +void CEapSim::GetConfigurationL(EAPSettings& aSettings) +{ + RDbNamedDatabase db; + + RDbs session; + + // This also creates the IAP entry if it doesn't exist + EapSimDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapSimDbUtils::GetConfigurationL( + db, + aSettings, + iIndexType, + iIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db, session +} + +void CEapSim::CopySettingsL( + const TIndexType aDestinationIndexType, + const TInt aDestinationIndex) +{ + // First delete the target configuration + TIndexType tmpIndexType = iIndexType; + TInt tmpIndex = iIndex; + + iIndexType = aDestinationIndexType; + iIndex = aDestinationIndex; + + TInt err(KErrNone); + TRAP(err, DeleteConfigurationL()); + // Ignore error on purpose + + // Return the indices + iIndexType = tmpIndexType; + iIndex = tmpIndex; + + RDbNamedDatabase db; + + RDbs session; + + EapSimDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapSimDbUtils::CopySettingsL( + db, + iIndexType, + iIndex, + iTunnelingType, + aDestinationIndexType, + aDestinationIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db + +} + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSimDbUtils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSimDbUtils.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,802 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 209 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDES +#include "EapSimDbUtils.h" +#include "EapSimDbDefaults.h" +#include "EapSimDbParameterNames.h" + +#include "eap_am_trace_symbian.h" + +const TInt KMaxSqlQueryLength = 2048; +const TInt KMicroSecsInAMinute = 60000000; // 60000000 micro seconds is 1 minute. + +// ================= MEMBER FUNCTIONS ======================= + +void EapSimDbUtils::OpenDatabaseL(RDbNamedDatabase& aDatabase, RDbs& aSession, const TIndexType aIndexType, + const TInt aIndex, const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapSimDbUtils::OpenDatabaseL -Start- aIndexType=%d, aIndex=%d, aTunnelingVendorType=%d \n"), + aIndexType,aIndex,aTunnelingVendorType) ); + + // 1. Open/create a database + + // Connect to the DBMS server. + User::LeaveIfError(aSession.Connect()); + CleanupClosePushL(aSession); + // aSession and aDatabase are pushed to the cleanup stack even though they may be member + // variables of the calling class and would be closed in the destructor anyway. This ensures + // that if they are not member variables they will be closed. Closing the handle twice + // does no harm. + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = aDatabase.Create(aSession, KDatabaseName, KSecureUIDFormat); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapSimDbUtils::OpenDatabaseL - Created Secure DB for eapsim.dat. err=%d\n"), err)); + + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(aSession, KDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(aDatabase); + +#else + // Non secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = aDatabase.Create(fsSession, KDatabaseName); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapSimDbUtils::OpenDatabaseL - Created Non-Secure DB for eapsim.dat. err=%d\n"), err)); + + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + CleanupStack::PopAndDestroy( &fsSession ); // close fsSession + + User::LeaveIfError(aDatabase.Open(aSession, KDatabaseName)); + CleanupClosePushL(aDatabase); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + // 2. Create the eapsim table to database (ignore error if exists) + +// Table columns: +//// NAME ///////////////////////////////////////////////// TYPE ////////////// Constant ///////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| EAP_GSMSIM_use_manual_realm | UNSIGNED INTEGER | cf_str_EAP_GSMSIM_use_manual_realm_literal |// +//| EAP_GSMSIM_manual_realm | VARCHAR(255) | cf_str_EAP_GSMSIM_manual_realm_literal |// +//| EAP_GSMSIM_use_manual_username | UNSIGNED INTEGER | cf_str_EAP_GSMSIM_use_manual_username_literal|// +//| EAP_GSMSIM_manual_username | VARCHAR(255) | cf_str_EAP_GSMSIM_manual_username_literal |// +//| PseudonymId | LONG VARBINARY | KPseudonymId |// +//| XKEY | BINARY(20) | KXKey |// +//| K_aut | BINARY(16) | KK_aut |// +//| K_encr | BINARY(16) | KK_encr |// +//| ReauthCounter | UNSIGNED INTEGER | KReauthCounter |// +//| ReauthId | LONG VARBINARY | KReauthId |// +//| PreviousIMSI | VARBINARY(15) | KPreviousIMSI |// +//| EAP_GSMSIM_use_pseudonym_identity | UNSIGNED INTEGER | cf_str_EAP_GSMSIM_use_pseudonym_identity_literal |// +//| EAP_GSMSIM_max_session_validity_time | BIGINT | cf_str_EAP_GSMSIM_max_session_validity_time_literal |// +//| EAP_GSMSIM_last_full_authentication_time | BIGINT | KGSMSIMLastFullAuthTime |// +////////////////////////////////////////////////////////////////////////////////////////////////// + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLCreateTable, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S LONG VARBINARY, \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S UNSIGNED INTEGER, \ + %S LONG VARBINARY, \ + %S VARBINARY(%d), \ + %S UNSIGNED INTEGER, \ + %S BIGINT, \ + %S BIGINT)"); + + sqlStatement.Format(KSQLCreateTable, &KSimTableName, &KServiceType, + &KServiceIndex, + &KTunnelingType, + &cf_str_EAP_GSMSIM_use_manual_realm_literal, + &cf_str_EAP_GSMSIM_manual_realm_literal, KMaxManualRealmLengthInDB, + &cf_str_EAP_GSMSIM_use_manual_username_literal, + &cf_str_EAP_GSMSIM_manual_username_literal, KMaxManualUsernameLengthInDB, + &KPseudonymId, + &KXKey, KMaxXKeyLengthInDB, + &KK_aut, KMaxK_autLengthInDB, + &KK_encr, KMaxK_encrLengthInDB, + &KReauthCounter, + &KReauthId, + &KPreviousIMSI, KMaxIMSILengthInDB, + &cf_str_EAP_GSMSIM_use_pseudonym_identity_literal, + &cf_str_EAP_GSMSIM_max_session_validity_time_literal, + &KGSMSIMLastFullAuthTime); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // 4. Check if database table contains a row for this service type and id + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQueryRow, &cf_str_EAP_GSMSIM_manual_realm_literal, &KSimTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // 5. If row is not found then add it + + TInt rows = view.CountL(); + CleanupStack::PopAndDestroy( &view ); // Close view. + if (rows == 0) + { + _LIT(KSQLInsert, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert, &KSimTableName); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly)); + CleanupClosePushL(view); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_use_manual_realm_literal), default_EAP_GSMSIM_use_manual_realm); + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_manual_realm_literal), default_EAP_GSMSIM_manual_realm); + + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_use_manual_username_literal), default_EAP_GSMSIM_use_manual_username); + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_manual_username_literal), default_EAP_GSMSIM_manual_username); + + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_use_pseudonym_identity_literal), default_EAP_GSMSIM_use_pseudonym_identity); + + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_max_session_validity_time_literal), default_MaxSessionTime); + + view.SetColL(colSet->ColNo(KGSMSIMLastFullAuthTime), default_FullAuthTime); + + view.PutL(); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + CleanupStack::PopAndDestroy( &view ); // Close view. + } + + CleanupStack::PopAndDestroy( buf ); // Delete buf + CleanupStack::Pop( &aDatabase ); + CleanupStack::Pop( &aSession ); + + aDatabase.Compact(); +} + +void EapSimDbUtils::SetIndexL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const TIndexType aNewIndexType, + const TInt aNewIndex, + const eap_type_value_e aNewTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aNewTunnelingVendorType = aNewTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aNewTunnelingVendorType = static_cast(aNewTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &KSimTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + TInt rows = view.CountL(); + + if (rows == 0) + { + User::Leave(KErrNotFound); + } + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + view.UpdateL(); + + view.SetColL(colSet->ColNo(KServiceType), static_cast(aNewIndexType)); + + view.SetColL(colSet->ColNo(KServiceIndex), aNewIndex); + + view.SetColL(colSet->ColNo(KTunnelingType), aNewTunnelingVendorType); + + view.PutL(); + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapSimDbUtils::SetConfigurationL( + RDbNamedDatabase& aDatabase, + const EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapSimDbUtils::SetConfigurationL -Start- aIndexType=%d, aIndex=%d, aTunnelingVendorType=%d\n"), + aIndexType,aIndex, aTunnelingVendorType)); + + EAP_TRACE_DEBUG_SYMBIAN((_L("*************************** SetConfigurationL - Set the below values: ***************************\n")) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - Set these values for EAPType=%d"),aSettings.iEAPType) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Username=%S"),aSettings.iUsernamePresent, &(aSettings.iUsername)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Password=%S"),aSettings.iPasswordPresent, &(aSettings.iPassword)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Realm=%S"),aSettings.iRealmPresent, &(aSettings.iRealm)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, UsePseudonyms=%d"),aSettings.iUsePseudonymsPresent, aSettings.iUsePseudonyms) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, VerifyServerRealm=%d"), + aSettings.iVerifyServerRealmPresent, aSettings.iVerifyServerRealm) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, RequireClientAuthentication=%d"), + aSettings.iRequireClientAuthenticationPresent, aSettings.iRequireClientAuthentication) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, SessionValidityTime=%d minutes"), + aSettings.iSessionValidityTimePresent, aSettings.iSessionValidityTime) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, CipherSuites Count=%d"), + aSettings.iCipherSuitesPresent, aSettings.iCipherSuites.Count()) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, PEAPv0Allowed=%d, PEAPv1Allowed=%d, PEAPv2Allowed=%d"), + aSettings.iPEAPVersionsPresent, aSettings.iPEAPv0Allowed,aSettings.iPEAPv1Allowed, aSettings.iPEAPv2Allowed ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Certificates Count=%d"), + aSettings.iCertificatesPresent, aSettings.iCertificates.Count()) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - Certificate details below: \n")) ); + + for( TInt n=0; n < aSettings.iCertificates.Count(); n++ ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - Certificate type:%d \n"), aSettings.iCertificates[n].iCertType) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - present=%d, SubjectName=%S"), + aSettings.iCertificates[n].iSubjectNamePresent, &(aSettings.iCertificates[n].iSubjectName) ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - present=%d, IssuerName=%S"), + aSettings.iCertificates[n].iIssuerNamePresent, &(aSettings.iCertificates[n].iIssuerName) ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - present=%d, SerialNumber=%S"), + aSettings.iCertificates[n].iSerialNumberPresent, &(aSettings.iCertificates[n].iSerialNumber) ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - SubjectKeyID present=%d"), + aSettings.iCertificates[n].iSubjectKeyIDPresent ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "SubjectKeyID:", aSettings.iCertificates[n].iSubjectKeyID.Ptr(), + aSettings.iCertificates[n].iSubjectKeyID.Size() ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - present=%d, Thumbprint=%S"), + aSettings.iCertificates[n].iThumbprintPresent, &(aSettings.iCertificates[n].iThumbprint) ) ); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, EncapsulatedEAPTypes Count=%d"), + aSettings.iEncapsulatedEAPTypesPresent, aSettings.iEncapsulatedEAPTypes.Count()) ); + for( TInt m=0; m < aSettings.iEncapsulatedEAPTypes.Count(); m++ ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - EncapsulatedEAPTypes=%d"), + aSettings.iEncapsulatedEAPTypes[m]) ); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("*************************** SetConfigurationL - Set the above values: ***************************\n")) ); + + // Check if the settings are for the correct type + if (aSettings.iEAPType != EAPSettings::EEapSim) + { + User::Leave(KErrNotSupported); + } + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + RDbView view; + + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KSimTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + view.FirstL(); + + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Manual username + //if (aSettings.iUsernamePresent) // no need to check as there may be empty usernames with the present status is EFlase. + { + // Check if length of username is less than the max length. + if(aSettings.iUsername.Length() > KMaxManualUsernameLengthInDB) + { + // Username too long. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapSimDbUtils::SetConfigurationL: Too long Username. Length=%d \n"), + aSettings.iUsername.Length())); + + User::Leave(KErrArgument); + } + + // Length is ok. Set the value in DB. Value could be empty. It doesn't matter. + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_manual_username_literal), aSettings.iUsername); + + // This is to set the automatic or manual status. + TUint useManualUsernameStatus; + + if (aSettings.iUsernamePresent) + { + useManualUsernameStatus = EGSMSIMUseManualUsernameYes; + } + else + { + useManualUsernameStatus = EGSMSIMUseManualUsernameNo; + } + + // Set the value. + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_use_manual_username_literal), useManualUsernameStatus); + } + + // Manual realm + //if (aSettings.iRealmPresent) // no need to check as there may be empty realms with the present status is EFlase. + { + // Check if length of realm is less than the max length. + if(aSettings.iRealm.Length() > KMaxManualRealmLengthInDB) + { + // Realm too long. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapSimDbUtils::SetConfigurationL: Too long Realm. Length=%d \n"), + aSettings.iRealm.Length())); + + User::Leave(KErrArgument); + } + + // Length is ok. Set the value in DB. Value could be empty. It doesn't matter. + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_manual_realm_literal), aSettings.iRealm); + + // This is to set the automatic or manual status. + TUint useManualRealmStatus; + + if (aSettings.iRealmPresent) + { + useManualRealmStatus = EGSMSIMUseManualRealmYes; + } + else + { + useManualRealmStatus = EGSMSIMUseManualRealmNo; + } + + // Set the value. + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_use_manual_realm_literal), useManualRealmStatus); + } + + // UsePseudonym + if (aSettings.iUsePseudonymsPresent) + { + if (aSettings.iUsePseudonyms) + { + // Use pseudonym. + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_use_pseudonym_identity_literal), EGSMSIMUsePseudonymIdYes); + } + else + { + // Don't use pseudonym. + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_use_pseudonym_identity_literal), EGSMSIMUsePseudonymIdNo); + } + } + else + { + // Value is not configured. Value is read from config file if needed. + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_use_pseudonym_identity_literal), EGSMSIMUsePseudonymIdNotValid); + } + + // Session validity time + if (aSettings.iSessionValidityTimePresent) + { + // User or device management wants to store the session validity time. + // Convert the time to micro seconds and save. + + TInt64 validityInMicro = (aSettings.iSessionValidityTime) * KMicroSecsInAMinute; + + view.SetColL(colSet->ColNo(cf_str_EAP_GSMSIM_max_session_validity_time_literal), validityInMicro); + } + + if (aIndexType != EVpn) // This allows current VPN IF to use reauthentication. VPN does not zero last full authentication time. + { + // Last full authentication time should be made zero when EAP configurations are modified. + // This makes sure that the next authentication with this EAP would be full authentication + // instead of reauthentication even if the session is still valid. + + view.SetColL(colSet->ColNo(KGSMSIMLastFullAuthTime), default_FullAuthTime); + + EAP_TRACE_DEBUG_SYMBIAN((_L("Session Validity: EAP-Type=%d, Resetting Full Auth Time since settings are modified\n"), + aSettings.iEAPType )); + } + + view.PutL(); + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapSimDbUtils::GetConfigurationL( + RDbNamedDatabase& aDatabase, + EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + RDbView view; + + // Form the query + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KSimTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + aSettings.iEAPType = EAPSettings::EEapSim; + + // Username + TPtrC username = view.ColDes(colSet->ColNo(cf_str_EAP_GSMSIM_manual_username_literal)); + aSettings.iUsername.Copy(username); + + // For manual or automatic status. + TUint useUsername = view.ColUint(colSet->ColNo(cf_str_EAP_GSMSIM_use_manual_username_literal)); + if(useUsername == EGSMSIMUseManualUsernameNo) + { + aSettings.iUsernamePresent = EFalse; + } + else + { + aSettings.iUsernamePresent = ETrue; + } + + // Realm + TPtrC realm = view.ColDes(colSet->ColNo(cf_str_EAP_GSMSIM_manual_realm_literal)); + aSettings.iRealm.Copy(realm); + + // For manual or automatic status. + TUint useRealm = view.ColUint(colSet->ColNo(cf_str_EAP_GSMSIM_use_manual_realm_literal)); + if(useRealm == EGSMSIMUseManualRealmNo) + { + aSettings.iRealmPresent = EFalse; + } + else + { + aSettings.iRealmPresent = ETrue; + } + + TInt usePseudonym = view.ColUint(colSet->ColNo(cf_str_EAP_GSMSIM_use_pseudonym_identity_literal)); + + if (usePseudonym == EGSMSIMUsePseudonymIdNotValid) + { + aSettings.iUsePseudonymsPresent = EFalse; + } + else + { + if (usePseudonym == EGSMSIMUsePseudonymIdNo) + { + aSettings.iUsePseudonyms = EFalse; + } + else + { + aSettings.iUsePseudonyms = ETrue; + } + + aSettings.iUsePseudonymsPresent = ETrue; + } + + // Session validity time + TInt64 maxSessionTimeMicro = view.ColInt64(colSet->ColNo(cf_str_EAP_GSMSIM_max_session_validity_time_literal)); + + // Convert the time to minutes. + TInt64 maxSessionTimeMin = maxSessionTimeMicro / KMicroSecsInAMinute; + + aSettings.iSessionValidityTime = static_cast(maxSessionTimeMin); + aSettings.iSessionValidityTimePresent = ETrue; + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapSimDbUtils::CopySettingsL( + RDbNamedDatabase& aDatabase, + const TIndexType aSrcIndexType, + const TInt aSrcIndex, + const eap_type_value_e aSrcTunnelingType, + const TIndexType aDestIndexType, + const TInt aDestIndex, + const eap_type_value_e aDestTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aSrcTunnelingVendorType = aSrcTunnelingType.get_vendor_type(); + TUint aDestTunnelingVendorType = aDestTunnelingType.get_vendor_type(); + +#else + + TUint aSrcTunnelingVendorType = static_cast(aSrcTunnelingType); + TUint aDestTunnelingVendorType = static_cast(aDestTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &KSimTableName, + &KServiceType, aSrcIndexType, &KServiceIndex, aSrcIndex, &KTunnelingType, aSrcTunnelingVendorType); + + RDbView view; + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + TInt rows = view.CountL(); + + if (rows == 0) + { + User::Leave(KErrNotFound); + } + + // Get the first (and only) row + view.FirstL(); + + view.GetL(); + + view.InsertCopyL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + + CleanupStack::PushL(colSet); + + view.SetColL(colSet->ColNo(KServiceType), static_cast(aDestIndexType)); + + view.SetColL(colSet->ColNo(KServiceIndex), aDestIndex); + + view.SetColL(colSet->ColNo(KTunnelingType), aDestTunnelingVendorType); + + view.PutL(); + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapSimDbUtils::DeleteConfigurationL( + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + RDbs session; + RDbNamedDatabase database; + // Connect to the DBMS server. + User::LeaveIfError(session.Connect()); + CleanupClosePushL(session); + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = database.Create(session, KDatabaseName, KSecureUIDFormat); + + if(err == KErrNone) + { + // Database was created so it was empty. No need for further actions. + database.Destroy(); + CleanupStack::PopAndDestroy(); + return; + + } + else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + // Database existed, open it. + User::LeaveIfError(database.Open(session, KDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(database); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = database.Create(fsSession, KDatabaseName); + + if(err == KErrNone) + { + // Database was created so it was empty. No need for further actions. + database.Destroy(); + CleanupStack::PopAndDestroy(2); // fsSession, database session + return; + + } + else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + CleanupStack::PopAndDestroy(); // close fsSession + + User::LeaveIfError(database.Open(session, KDatabaseName)); + CleanupClosePushL(database); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Main settings table + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQL, &KSimTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Delete rows + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + // Close database + CleanupStack::PopAndDestroy(4); // view, buf, database, session +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSimProxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSimProxy.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 211 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include "EapSim.h" +#include +#include +#include "EapolUID.h" + +const TImplementationProxy ImplementationTable[] = +{ + {{EAP_SIM_IMPLEMENTATION_UID}, reinterpret_cast (CEapSim::NewL)} +}; + +// ================= OTHER EXPORTED FUNCTIONS ============== + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) +{ + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + + return ImplementationTable; +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSimUiConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSimUiConnection.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 213 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include "EapSimDbUtils.h" +#include +#include + +CEapSimUiConnection::CEapSimUiConnection( + const TIndexType aIndexType, + const TInt aIndex, + const TInt aTunnelingType) + : iIndexType(aIndexType) + , iIndex(aIndex) + , iTunnelingType(aTunnelingType) + , iIsConnected(EFalse) + , iDataConn(NULL) +{ +} + + +CEapSimUiConnection::~CEapSimUiConnection() +{ +} + + +TInt CEapSimUiConnection::Connect() +{ +#ifdef USE_EAP_EXPANDED_TYPES + + eap_type_value_e tunnelingType(static_cast(iTunnelingType)); + +#else + + eap_type_value_e tunnelingType = static_cast(iTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + TRAPD(err, EapSimDbUtils::OpenDatabaseL( + iDbNamedDatabase, + iDbs, + iIndexType, + iIndex, + tunnelingType)); + if (err == KErrNone) + { + iIsConnected = ETrue; + } + + return err; +} + + +TInt CEapSimUiConnection::Close() +{ + if (iIsConnected) + { + iDbNamedDatabase.Close(); + iDbs.Close(); + } + iIsConnected = EFalse; + + return KErrNone; +} + + +CEapSimUiDataConnection * CEapSimUiConnection::GetDataConnection() +{ + if (!iDataConn) + { + iDataConn = new CEapSimUiDataConnection(this); + } + + return iDataConn; +} + +TInt CEapSimUiConnection::GetDatabase(RDbNamedDatabase & aDatabase) +{ + if (iIsConnected == EFalse) + { + return KErrSessionClosed; + } + + aDatabase = iDbNamedDatabase; + return KErrNone; +} + + +TIndexType CEapSimUiConnection::GetIndexType() +{ + return iIndexType; +} + + +TInt CEapSimUiConnection::GetIndex() +{ + return iIndex; +} + + +TInt CEapSimUiConnection::GetTunnelingType() +{ + return iTunnelingType; +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSimUiDataConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSimUiDataConnection.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,274 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 215 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include +#include "EapSimDbUtils.h" +#include "EapSimDbParameterNames.h" +#include "EapSimDbDefaults.h" +#include +#include +#include +#include "eap_am_trace_symbian.h" + +const TUint KMaxSqlQueryLength = 256; + +CEapSimUiDataConnection::CEapSimUiDataConnection(CEapSimUiConnection * aUiConn) +: iIsOpened(EFalse) +, iUiConn(aUiConn) +, iColSet(NULL) +, iDataPtr(NULL) +{ +} + + +CEapSimUiDataConnection::~CEapSimUiDataConnection() +{ + if (iUiConn) + { + Close(); + iUiConn = NULL; + } +} + + +TInt CEapSimUiDataConnection::Open() +{ + if (iIsOpened) + { + return KErrAlreadyExists; + } + + TInt err = iUiConn->GetDatabase(iDatabase); + if (err != KErrNone) + { + return err; + } + + iIsOpened = ETrue; + return KErrNone; +} + + +TInt CEapSimUiDataConnection::GetData(CEapSimUiSimData ** aDataPtr) +{ + if (aDataPtr == NULL) + { + return KErrArgument; + } + if (iIsOpened == EFalse) + { + return KErrSessionClosed; + } + iDataPtr = new CEapSimUiSimData(); + if (!iDataPtr) + { + return KErrNoMemory; + } + + TRAPD(err, FetchDataL()); + if (err != KErrNone) + { + delete iDataPtr; + iDataPtr = NULL; + + delete iColSet; + iColSet = NULL; + + iView.Close(); + + return err; + } + + *aDataPtr = iDataPtr; + + return KErrNone; +} + + +TInt CEapSimUiDataConnection::Update() +{ + TRAPD(err, iView.UpdateL()); + if (err != KErrNone) + { + return err; + } + + // Check if length of username and realm are less than the max length possible in DB. + if(iDataPtr->GetManualUsername().Length() > KMaxManualUsernameLengthInDB + || iDataPtr->GetManualRealm().Length() > KMaxManualRealmLengthInDB) + { + // Username or realm too long. Can not be stored in DB. + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapSimUiDataConnection::Update: Too long username or realm. Length: UN=%d, Realm=%d\n"), + iDataPtr->GetManualUsername().Length(), + iDataPtr->GetManualRealm().Length())); + + return KErrArgument; + } + + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_GSMSIM_manual_username_literal), iDataPtr->GetManualUsername())); + if (err != KErrNone) + { + return err; + } + + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_GSMSIM_manual_realm_literal), iDataPtr->GetManualRealm())); + if (err != KErrNone) + { + return err; + } + + if (*(iDataPtr->GetUseManualUsername())) + { + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_GSMSIM_use_manual_username_literal), EGSMSIMUseManualUsernameYes)); + if (err != KErrNone) + { + return err; + } + } + else + { + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_GSMSIM_use_manual_username_literal), EGSMSIMUseManualUsernameNo)); + if (err != KErrNone) + { + return err; + } + } + + if (*(iDataPtr->GetUseManualRealm())) + { + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_GSMSIM_use_manual_realm_literal), EGSMSIMUseManualRealmYes)); + if (err != KErrNone) + { + return err; + } + } + else + { + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_GSMSIM_use_manual_realm_literal), EGSMSIMUseManualRealmNo)); + if (err != KErrNone) + { + return err; + } + } + + // Last full authentication time should be made zero when EAP configurations are modified. + // This makes sure that the next authentication with this EAP would be full authentication + // instead of reauthentication even if the session is still valid. + + TRAP(err, iView.SetColL(iColSet->ColNo(KGSMSIMLastFullAuthTime), default_FullAuthTime)); + if (err != KErrNone) + { + return err; + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("Session Validity: Resetting Full Auth Time since EAP-SIM settings are modified\n"))); + + TRAP(err, iView.PutL()); + + return err; +} + + +TInt CEapSimUiDataConnection::Close() +{ + if (iIsOpened == EFalse) + { + return KErrNone; + } + + delete iDataPtr; + iDataPtr = NULL; + + delete iColSet; + iColSet = NULL; + + iView.Close(); + + iUiConn = NULL; + return KErrNone; +} + + +void CEapSimUiDataConnection::FetchDataL() +{ + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Form the query. Query everything. + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, + &KSimTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + // Evaluate view + User::LeaveIfError(iView.Prepare(iDatabase, TDbQuery(sqlStatement))); + User::LeaveIfError(iView.EvaluateAll()); + // Get the first (and only) row + iView.FirstL(); + iView.GetL(); + // Get column set so we get the correct column numbers + delete iColSet; + iColSet = NULL; + iColSet = iView.ColSetL(); + + // Start fetching the values + + // use manual username + TUint intValue = iView.ColUint(iColSet->ColNo(cf_str_EAP_GSMSIM_use_manual_username_literal)); + if (intValue == 0) + { + *(iDataPtr->GetUseManualUsername()) = EFalse; + } + else + { + *(iDataPtr->GetUseManualUsername()) = ETrue; + } + + // use manual realm + intValue = iView.ColUint(iColSet->ColNo(cf_str_EAP_GSMSIM_use_manual_realm_literal)); + if (intValue == 0) + { + *(iDataPtr->GetUseManualRealm()) = EFalse; + } + else + { + *(iDataPtr->GetUseManualRealm()) = ETrue; + } + + // manual username + iDataPtr->GetManualUsername().Copy(iView.ColDes16(iColSet->ColNo(cf_str_EAP_GSMSIM_manual_username_literal))); + + // manual realm + iDataPtr->GetManualRealm().Copy(iView.ColDes16(iColSet->ColNo(cf_str_EAP_GSMSIM_manual_realm_literal))); + + CleanupStack::PopAndDestroy(buf); +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSimUiSimData.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/plugin/src/EapSimUiSimData.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 217 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include + + +CEapSimUiSimData::CEapSimUiSimData() +{ +} + + +CEapSimUiSimData::~CEapSimUiSimData() +{ +} + + +TDes& CEapSimUiSimData::GetManualUsername() +{ + return iManualUsername; +} + + +TDes& CEapSimUiSimData::GetManualRealm() +{ + return iManualRealm; +} + + +TBool * CEapSimUiSimData::GetUseManualUsername() +{ + return &iUseManualUsername; +} + + +TBool * CEapSimUiSimData::GetUseManualRealm() +{ + return &iUseManualRealm; +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/eap_am_type_mschapv2_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/eap_am_type_mschapv2_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1417 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 264 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include +#include +#include +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_type_mschapv2_symbian.h" +#include "EapMsChapV2DbParameterNames.h" +#include "EapMsChapV2DbDefaults.h" +#include "EapMsChapV2DbUtils.h" +#include "EapMsChapV2NotifierUids.h" +#include "eap_state_notification.h" + +#include "eap_am_trace_symbian.h" + +const TUint KMaxSqlQueryLength = 256; +const TUint KMaxDBFieldNameLength = 255; +const char EAP_MSCHAPV2_CREDENTIAL_HANDLE_KEY[] = "eap_type_mschapv2_c credential_store"; +const TInt KDefaultColumnInView_One = 1; // For DB view. +const TInt KMicroSecsInASecond = 1000000; // 1000000 micro seconds is 1 second. + +// ================= MEMBER FUNCTIONS ======================= + +EAP_FUNC_EXPORT eap_am_type_mschapv2_symbian_c::~eap_am_type_mschapv2_symbian_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::~eap_am_type_mschapv2_symbian_c(): this = 0x%08x\n"), + this)); + + EAP_ASSERT(m_shutdown_was_called == true); + + m_database.Close(); + m_session.Close(); + + delete m_username_password_io_ptr; + delete m_username_password_io_pckg_ptr; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_mschapv2_symbian_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::shutdown(): this = 0x%08x\n"), + this)); + + if( IsActive() ) + { + Cancel(); // Cancel only if active. + } + else + { + if( m_is_notifier_connected ) + { + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::shutdown - calling m_notifier.CancelNotifier(..)\n"))); + + TInt error = KErrNone; + EAP_UNREFERENCED_PARAMETER(error); + error = m_notifier.CancelNotifier(KEapMsChapV2UsernamePasswordUid); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::shutdown - calling m_notifier.Close(), prev error=%d\n"), + error)); + + m_notifier.Close(); // Call close only if it is connected. + + m_is_notifier_connected = false; + } + } + + m_shutdown_was_called = true; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::shutdown(): this = 0x%08x returns\n"), + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +eap_am_type_mschapv2_symbian_c::eap_am_type_mschapv2_symbian_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id) +: CActive(CActive::EPriorityStandard) +, eap_am_type_mschapv2_c(tools /*, partner */) +, m_am_tools(static_cast (tools)) +, m_partner(partner) +, m_state(EHandlingUsernamePasswordQuery) +, m_username_utf8(0) +, m_password_utf8(0) +, m_old_password_utf8(0) +, m_password_prompt_enabled(0) +, m_is_identity_query(false) +, m_username_password_io_ptr(0) +, m_username_password_io_pckg_ptr(0) +, m_receive_network_id(tools) +, m_index_type(aIndexType) +, m_index(aIndex) +, m_tunneling_type(aTunnelingType) +, m_is_client(aIsClient) +, m_is_valid(false) +, m_shutdown_was_called(false) +, m_is_notifier_connected(false) +, m_max_session_time(0) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#ifdef USE_EAP_EXPANDED_TYPES + + m_tunneling_vendor_type = m_tunneling_type.get_vendor_type(); + +#else + + m_tunneling_vendor_type = static_cast(m_tunneling_type); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + if (receive_network_id != 0 + && receive_network_id->get_is_valid_data() == true) + { + eap_status_e status = m_receive_network_id.set_copy_of_network_id( + receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +eap_am_type_mschapv2_symbian_c * eap_am_type_mschapv2_symbian_c::NewL( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id) +{ + eap_am_type_mschapv2_symbian_c * self; + + self = new(ELeave) eap_am_type_mschapv2_symbian_c( + aTools, + aPartner, + aIndexType, + aIndex, + aTunnelingType, + aIsClient, + receive_network_id); + + CleanupStack::PushL(self); + + if (self->get_is_valid() != true) + { + User::Leave(KErrGeneral); + } + + self->ConstructL(); + + CleanupStack::Pop(); + + return self; +} + +void eap_am_type_mschapv2_symbian_c::ConstructL() +{ + // NOTE: Do not use m_partner here without null check + + // Open/create the database + EapMsChapV2DbUtils::OpenDatabaseL(m_database, m_session, m_index_type, m_index, m_tunneling_type); + + m_username_password_io_ptr = new(ELeave) TEapMsChapV2UsernamePasswordInfo; + m_username_password_io_pckg_ptr = new(ELeave) TPckg (*m_username_password_io_ptr); + + CActiveScheduler::Add(this); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_type_mschapv2_symbian_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_am_type_mschapv2_symbian_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +void eap_am_type_mschapv2_symbian_c::send_error_notification(const eap_status_e error) +{ + eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error); + + if (error == eap_status_user_cancel_authentication) + { + general_state_variable = eap_general_state_authentication_cancelled; + } + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + // Notifies the lower level of an authentication error. + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, + eap_type_mschapv2, + eap_state_none, + general_state_variable, + 0, + false); + + notification.set_authentication_error(error); + + m_partner->state_notification(¬ification); +} + +//-------------------------------------------------- + +void eap_am_type_mschapv2_symbian_c::RunL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::RunL - start") + EAPL("m_state, iStatus.Int()=%d\n"), + m_state, iStatus.Int())); + + if (iStatus.Int() == KErrCancel) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::RunL - User seems to have cancelled the prompt. Stop Immediately.\n"))); + + // User cancelled the password prompt. Stop everything. + // Appropriate error notification is sent from finish_unsuccessful_authentication. + get_am_partner()->finish_unsuccessful_authentication(true); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (iStatus.Int() != KErrNone) + { + // Something is very wrong... + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP - MS-Chap-V2 notifier or dialog, iStatus.Int()=%d\n"), iStatus.Int())); + + send_error_notification(eap_status_authentication_failure); + + get_am_partner()->finish_unsuccessful_authentication(false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + eap_status_e status(eap_status_ok); + + switch (m_state) + { + case EHandlingUsernamePasswordQuery: + { + if (m_username_password_io_ptr->iPasswordPromptEnabled) + { + *m_password_prompt_enabled = true; + } + else + { + *m_password_prompt_enabled = false; + } + + { + eap_variable_data_c tmp_username_unicode( + m_am_tools); + + status = tmp_username_unicode.set_buffer( + m_username_password_io_ptr->iUsername.Ptr(), + m_username_password_io_ptr->iUsername.Size(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + eap_variable_data_c tmp_username_utf8(m_am_tools); + status = m_am_tools->convert_unicode_to_utf8(tmp_username_utf8, tmp_username_unicode); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + status = m_username_utf8->set_copy_of_buffer(&tmp_username_utf8); + if (status != eap_status_ok) + { + get_am_partner()->finish_unsuccessful_authentication(false); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + } + + { + eap_variable_data_c tmp_password_unicode( + m_am_tools); + + status = tmp_password_unicode.set_buffer( + m_username_password_io_ptr->iPassword.Ptr(), + m_username_password_io_ptr->iPassword.Size(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + eap_variable_data_c tmp_password_utf8(m_am_tools); + status = m_am_tools->convert_unicode_to_utf8(tmp_password_utf8, tmp_password_unicode); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + status = m_password_utf8->set_copy_of_buffer(&tmp_password_utf8); + if (status != eap_status_ok) + { + get_am_partner()->finish_unsuccessful_authentication(false); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + } + + // Store username and/or password if "Prompt for username" is enabled + status = update_username_password(); + if (status != eap_status_ok) + { + get_am_partner()->finish_unsuccessful_authentication(false); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (m_is_identity_query) + { + status = get_am_partner()->complete_eap_identity_query(); + } + else + { + status = get_am_partner()->complete_failure_retry_response(); + } + } + break; + + case EHandlingChangePasswordQuery: + { + { + eap_variable_data_c tmp_password_unicode( + m_am_tools); + + status = tmp_password_unicode.set_buffer( + m_username_password_io_ptr->iPassword.Ptr(), + m_username_password_io_ptr->iPassword.Size(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + eap_variable_data_c tmp_password_utf8(m_am_tools); + status = m_am_tools->convert_unicode_to_utf8(tmp_password_utf8, tmp_password_unicode); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + eap_status_e status = m_password_utf8->set_copy_of_buffer(&tmp_password_utf8); + if (status != eap_status_ok) + { + get_am_partner()->finish_unsuccessful_authentication(false); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + + { + eap_variable_data_c tmp_old_password_unicode( + m_am_tools); + + status = tmp_old_password_unicode.set_buffer( + m_username_password_io_ptr->iOldPassword.Ptr(), + m_username_password_io_ptr->iOldPassword.Size(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + eap_variable_data_c tmp_old_password_utf8(m_am_tools); + status = m_am_tools->convert_unicode_to_utf8(tmp_old_password_utf8, tmp_old_password_unicode); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + status = m_old_password_utf8->set_copy_of_buffer(&tmp_old_password_utf8); + if (status != eap_status_ok) + { + get_am_partner()->finish_unsuccessful_authentication(false); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + + status = get_am_partner()->complete_change_password_query(); + } + break; + + default: + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAP - MS-Chap-V2 illegal state in RunL.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void eap_am_type_mschapv2_symbian_c::DoCancel() +{ + if( m_is_notifier_connected ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::DoCancel - calling m_notifier.CancelNotifier(..)\n"))); + + TInt error = KErrNone; + EAP_UNREFERENCED_PARAMETER(error); + error = m_notifier.CancelNotifier(KEapMsChapV2UsernamePasswordUid); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::DoCancel - calling m_notifier.Close(), prev error=%d\n"), + error)); + + m_notifier.Close(); // Call close only if it is connected. + + m_is_notifier_connected = false; + } +} + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e eap_am_type_mschapv2_symbian_c::type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT(data != 0); + // Trap must be set here because the OS independent portion of EAP MSCHAPV2 + // that calls this function does not know anything about Symbian. + eap_status_e status(eap_status_ok); + TRAPD(err, type_configure_readL( + field->get_field(), + field->get_field_length(), + data)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + + // Read is routed to partner object. + status = m_partner->read_configure( + field, + data); + } + + m_am_tools->trace_configuration( + status, + field, + data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_mschapv2_symbian_c::type_configure_readL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(field_length); + + // Create a buffer for the ascii strings - initialised with the argument + HBufC16* unicodeBuf = HBufC16::NewLC(KMaxDBFieldNameLength); + TPtr16 unicodeString = unicodeBuf->Des(); + + TPtrC8 fieldPtr(reinterpret_cast (field), field_length); + + unicodeString.Copy(fieldPtr); + + // Now do the database query + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQueryRow, + &unicodeString, + &KMsChapV2TableName, + &KServiceType, + m_index_type, + &KServiceIndex, + m_index, + &KTunnelingType, + m_tunneling_vendor_type); + + RDbView view; + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + if (view.FirstL()) + { + eap_status_e status = eap_status_ok; + view.GetL(); + + switch (view.ColType(KDefaultColumnInView_One)) + { + case EDbColText: + { + if (view.ColLength(KDefaultColumnInView_One) > 0) + { + TPtrC16 value = view.ColDes16(KDefaultColumnInView_One); + + eap_variable_data_c string_unicode(m_am_tools); + + status = string_unicode.set_copy_of_buffer(value.Ptr(), value.Size()); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + + status = m_am_tools->convert_unicode_to_utf8( + *data, + string_unicode); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + } + else + { + data->reset(); + status = data->set_copy_of_buffer("", 0); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + } + } + break; + + case EDbColUint32: + { + TUint value = view.ColUint32(KDefaultColumnInView_One); + status = data->set_copy_of_buffer(reinterpret_cast (&value), sizeof(value)); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + } + break; + + default: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Unexpected column type.\n"))); + User::Leave(KErrGeneral); + break; + } + } + else + { + // Could not find parameter + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Could not find configuration parameter.\n"))); + User::Leave(KErrArgument); + } + + CleanupStack::PopAndDestroy(3); // Close view, 2 x buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +EAP_FUNC_EXPORT eap_status_e eap_am_type_mschapv2_symbian_c::type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + // Write is routed to partner object. + eap_status_e status = m_partner->write_configure( + field, + data); + return status; +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_mschapv2_symbian_c::update_username_password() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_ok); + TRAPD(err, type_configure_updateL()); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + } + + // User entered username/password and pressed OK. + // Treat this as a full authentication and update the Last Auth Time. + status = store_authentication_time(); + if (status != eap_status_ok) + { + // Storing failed. Don't care. + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_mschapv2_symbian_c:Storing Last Full Authentication time failed, status=%d, but continuing\n"), + status)); + + status = eap_status_ok; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_mschapv2_symbian_c::type_configure_updateL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Now do the database update + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLUpdate, "SELECT %S,%S,%S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLUpdate, + &cf_str_EAP_MSCHAPV2_username_literal, + &cf_str_EAP_MSCHAPV2_password_prompt_literal, + &cf_str_EAP_MSCHAPV2_password_literal, + &KMsChapV2TableName, + &KServiceType, + m_index_type, + &KServiceIndex, + m_index, + &KTunnelingType, + m_tunneling_vendor_type); + + RDbView view; + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), RDbView::EUpdatable)); + CleanupClosePushL(view); + + view.FirstL(); + view.GetL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + EAP_ASSERT(m_username_utf8 != 0); + + eap_status_e status(eap_status_ok); + + { + eap_variable_data_c tmp_username_unicode(m_am_tools); + + status = m_am_tools->convert_utf8_to_unicode(tmp_username_unicode, *m_username_utf8); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + TPtr8 username( + static_cast ( + tmp_username_unicode.get_data()), + tmp_username_unicode.get_data_length(), + tmp_username_unicode.get_data_length()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("type_configure_updateL - username"), + username.Ptr(), + username.Size())); + + // Validate length. + if(username.Length() > KMaxUsernameLengthInDB) + { + // Username too long. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("eap_am_type_mschapv2_symbian_c::type_configure_updateL: Too long Username. Length=%d \n"), + username.Length())); + + User::Leave(KErrArgument); + } + + // Length is ok. Set the value in DB. + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPV2_username_literal), username); + } + + if (*m_password_prompt_enabled) + { + // Username and password prompt flag is stored, password is cleared + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPV2_password_prompt_literal), EMSCHAPV2PasswordPromptOn); + view.SetColNullL(colSet->ColNo(cf_str_EAP_MSCHAPV2_password_literal)); + } + else + { + eap_variable_data_c tmp_password_unicode(m_am_tools); + + status = m_am_tools->convert_utf8_to_unicode(tmp_password_unicode, *m_password_utf8); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void) EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + TPtr8 password( + static_cast ( + tmp_password_unicode.get_data()), + tmp_password_unicode.get_data_length(), + tmp_password_unicode.get_data_length()); + + // Validate length. + if(password.Length() > KMaxPasswordLengthInDB) + { + // Password too long. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("eap_am_type_mschapv2_symbian_c::type_configure_updateL: Too long Password. Length=%d \n"), + password.Length())); + + User::Leave(KErrArgument); + } + + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPV2_password_prompt_literal), EMSCHAPV2PasswordPromptOff); + + // Length is ok. Set the value in DB. + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPV2_password_literal), password); + } + + view.PutL(); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + CleanupStack::PopAndDestroy(2); // view, buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_mschapv2_symbian_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + { + // Read Maximum Session Validity Time from the config file + eap_variable_data_c sessionTimeFromFile(m_am_tools); + + eap_status_e status = m_partner->read_configure( + cf_str_EAP_MSCHAPv2_max_session_validity_time.get_field(), + &sessionTimeFromFile); + + if (status == eap_status_ok + && sessionTimeFromFile.get_is_valid_data() == true + && sessionTimeFromFile.get_data_length() == sizeof(u32_t)) + { + u32_t *session = reinterpret_cast(sessionTimeFromFile.get_data()); + if (session != 0) + { + // Update the max session time (in micro seconds). + // configuration file saves the time in seconds. We have to convert it to micro seconds. + m_max_session_time = static_cast(*session) * static_cast(KMicroSecsInASecond); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_mschapv2_symbian_c::reset() +{ + return eap_status_ok; +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_mschapv2_symbian_c::show_username_password_dialog( + eap_variable_data_c & username_utf8, + eap_variable_data_c & password_utf8, + bool & password_prompt_enabled, + bool is_identity_query) +{ + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::show_username_password_dialog - start, password_prompt_enabled=%d,is_identity_query=%d\n"), + password_prompt_enabled, is_identity_query)); + + m_username_utf8 = &username_utf8; + m_password_utf8 = &password_utf8; + m_password_prompt_enabled = &password_prompt_enabled; + m_is_identity_query = is_identity_query; + + if (!IsActive()) + { + if (*m_password_prompt_enabled == true) + { + m_username_password_io_ptr->iPasswordPromptEnabled = ETrue; + } + else + { + m_username_password_io_ptr->iPasswordPromptEnabled = EFalse; + } + + if (m_is_identity_query == true) + { + m_username_password_io_ptr->iIsIdentityQuery = ETrue; + } + else + { + m_username_password_io_ptr->iIsIdentityQuery = EFalse; + } + + + { + eap_variable_data_c tmp_username_unicode(m_am_tools); + eap_status_e status = m_am_tools->convert_utf8_to_unicode(tmp_username_unicode, *m_username_utf8); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_username_password_io_ptr->iUsername.Copy( + reinterpret_cast ( + tmp_username_unicode.get_data(tmp_username_unicode.get_data_length())), + tmp_username_unicode.get_data_length() / 2); // 8bit -> 16bit + } + + + m_state = EHandlingUsernamePasswordQuery; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" eap_am_type_mschapv2_symbian_c::show_username_password_dialog - before m_notifier.Connect(), m_is_notifier_connected=%d\n"), + m_is_notifier_connected)); + + if( !m_is_notifier_connected ) + { + TInt error = m_notifier.Connect(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" eap_am_type_mschapv2_symbian_c::show_username_password_dialog - m_notifier.Connect() returned error=%d\n"), + error)); + + if( error != KErrNone) + { + // Can not connect to notifier. + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(error)); + } + + m_is_notifier_connected = true; // Got connectted to notifier. + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" eap_am_type_mschapv2_symbian_c::show_username_password_dialog - before m_notifier.StartNotifierAndGetResponse()\n"))); + + m_notifier.StartNotifierAndGetResponse( + iStatus, + KEapMsChapV2UsernamePasswordUid, + *m_username_password_io_pckg_ptr, + *m_username_password_io_pckg_ptr); + + SetActive(); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_mschapv2_symbian_c: Already active when tried to show username/password dialog.\n"))); + return eap_status_process_general_error; + } + + return eap_status_pending_request; +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_mschapv2_symbian_c::show_change_password_dialog( + eap_variable_data_c & /* username */, + eap_variable_data_c & /* old_password */, + eap_variable_data_c & /* password */, + bool & /* password_prompt_enabled */) +{ + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" eap_am_type_mschapv2_symbian_c::show_change_password_dialog - THIS IS NOT SUPPORTED - return eap_status_not_supported \n"))); + +#if !defined (EAP_MSCHAPV2_ENABLE_PASSWORD_CHANGE) + + send_error_notification(eap_status_password_expired); + + // This is not supported. + return eap_status_not_supported; + +#else + + // Don't remove this. May be needed in future. + + m_username_utf8 = &username; + m_password_utf8 = &password; + m_old_password_utf8 = &old_password; + m_password_prompt_enabled = &password_prompt_enabled; + + if (!IsActive()) + { + { + eap_variable_data_c tmp_username_unicode(m_am_tools); + eap_status_e status = m_am_tools->convert_utf8_to_unicode(tmp_username_unicode, *m_username_utf8); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + m_username_password_io_ptr->iUsername.Copy( + reinterpret_cast ( + tmp_username_unicode.get_data(tmp_username_unicode.get_data_length())), + tmp_username_unicode.get_data_length() / 2); // 8bit -> 16bit + } + + m_state = EHandlingChangePasswordQuery; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" eap_am_type_mschapv2_symbian_c::show_change_password_dialog - before m_notifier.Connect(), m_is_notifier_connected=%d\n"), + m_is_notifier_connected)); + + if( !m_is_notifier_connected ) + { + TInt error = m_notifier.Connect(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" eap_am_type_mschapv2_symbian_c::show_change_password_dialog - m_notifier.Connect() returned error=%d\n"), + error)); + + if( error != KErrNone) + { + // Can not connect to notifier. + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(error)); + } + + m_is_notifier_connected = true; // Got connectted to notifier. + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL(" eap_am_type_mschapv2_symbian_c::show_change_password_dialog - before m_notifier.StartNotifierAndGetResponse()\n"))); + + m_notifier.StartNotifierAndGetResponse( + iStatus, + KEapMsChapV2ChangePasswordUid, + *m_username_password_io_pckg_ptr, + *m_username_password_io_pckg_ptr); + + SetActive(); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_mschapv2_symbian_c: Already active when tried to show change password dialog.\n"))); + return eap_status_process_general_error; + } + + return eap_status_pending_request; + +#endif +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_mschapv2_symbian_c::read_auth_failure_string(eap_mschapv2_error_e error_code, eap_variable_data_c &string) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(error_code); + EAP_UNREFERENCED_PARAMETER(string); + + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_mschapv2_symbian_c::get_memory_store_key( + eap_variable_data_c * const memory_store_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = memory_store_key->set_copy_of_buffer( + EAP_MSCHAPV2_CREDENTIAL_HANDLE_KEY, + sizeof(EAP_MSCHAPV2_CREDENTIAL_HANDLE_KEY)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t fill = ':'; + + status = memory_store_key->add_data( + &m_index_type, + sizeof(m_index_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = memory_store_key->add_data( + &fill, + sizeof(fill)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = memory_store_key->add_data( + &m_index, + sizeof(m_index)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = memory_store_key->add_data( + &fill, + sizeof(fill)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = memory_store_key->add_data( + &m_tunneling_vendor_type, + sizeof(m_tunneling_vendor_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +bool eap_am_type_mschapv2_symbian_c::is_session_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + bool sessionValidity(false); + + TRAPD(err, sessionValidity = is_session_validL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_mschapv2_symbian_c::is_session_valid - LEAVE - error=%d, Assuming session is invalid \n"), + err)); + + sessionValidity = false; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return sessionValidity; +} + +//-------------------------------------------------- + +bool eap_am_type_mschapv2_symbian_c::is_session_validL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_mschapv2_symbian_c::is_session_valid - start \n"))); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT(KSQLQuery, "SELECT %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &cf_str_EAP_MSCHAPv2_max_session_validity_time_literal, + &KMSCHAPv2LastFullAuthTime, &KMsChapV2TableName, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + TInt64 maxSessionTime = view.ColInt64(colSet->ColNo(cf_str_EAP_MSCHAPv2_max_session_validity_time_literal)); + TInt64 fullAuthTime = view.ColInt64(colSet->ColNo(KMSCHAPv2LastFullAuthTime)); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + CleanupStack::PopAndDestroy(&view); // Close view. + CleanupStack::PopAndDestroy(buf); // Delete buf. + + // If the max session time from DB is zero then we use the + // one read from configuration file. + + if( maxSessionTime == 0) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("Session Validity - Using max session validity time from config file\n"))); + + maxSessionTime = m_max_session_time; // value from configuration file. + } + + // Get the current time. + TTime currentTime; + currentTime.UniversalTime(); + + TTime lastFullAuthTime(fullAuthTime); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + TDateTime fullAuthDateTime = lastFullAuthTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("Session Validity - Current Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1, currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("Session Validity - Last Full Auth Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + fullAuthDateTime.Day()+1, fullAuthDateTime.Month()+1, fullAuthDateTime.Year(), fullAuthDateTime.Hour(), + fullAuthDateTime.Minute(), fullAuthDateTime.Second(), fullAuthDateTime.MicroSecond())); + +#endif + + TTimeIntervalMicroSeconds interval = currentTime.MicroSecondsFrom(lastFullAuthTime); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_mschapv2_symbian_c::is_session_valid:interval in microseconds:"), + &(interval.Int64()), + sizeof(interval.Int64()) ) ); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_mschapv2_symbian_c::is_session_valid:max session time in microseconds:"), + &(maxSessionTime), + sizeof(maxSessionTime) ) ); + + +#if defined(_DEBUG) || defined(DEBUG) + + TTimeIntervalMinutes intervalMins; + TInt error = currentTime.MinutesFrom(lastFullAuthTime, intervalMins); + + if(error == KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::is_session_validL()") + EAPL("interval in Minutes =%d\n"), + intervalMins.Int())); + } + +#endif + + + if( maxSessionTime >= interval.Int64() ) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_mschapv2_symbian_c::is_session_valid - Session Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return true; + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_mschapv2_symbian_c::is_session_valid - Session NOT Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return false; + } +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_mschapv2_symbian_c::store_authentication_time() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + TRAPD(err, store_authentication_timeL()); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_mschapv2_symbian_c::store_authentication_timeL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_mschapv2_symbian_c::store_authentication_timeL - start \n"))); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT(KSQLQuery, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KMSCHAPv2LastFullAuthTime, &KMsChapV2TableName, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row for updation. + view.FirstL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the current universal time. + TTime currentTime; + currentTime.UniversalTime(); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_mschapv2_symbian_c::store_authentication_time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1,currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + +#endif + + TInt64 fullAuthTime = currentTime.Int64(); + + view.SetColL(colSet->ColNo(KMSCHAPv2LastFullAuthTime), fullAuthTime); + + view.PutL(); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + CleanupStack::PopAndDestroy(&view); // Close view. + CleanupStack::PopAndDestroy(buf); // Delete buf. + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- +// End of Files diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/101F8E66.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/101F8E66.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Localization strings for project EAPOL +* +*/ + + + +// LOCALISATION STRINGS: + +// b: 50 +// e: 300 +// f: EDialogLabelFont +// d: This name for the EAP-MSCHAPv2 EAP type is displayed in the EAP type list in IAP UI and in EAP-PEAP +// d: encapsulated EAP type selection. +#define EMPL_GE_NAME "EAP-MSCHAPv2" + + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/EapMsChapV2.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/EapMsChapV2.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,180 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPMSCHAPV2_H_ +#define _EAPMSCHAPV2_H_ + +// INCLUDES +#include +#include "eap_header.h" + +// LOCAL CONSTANTS + +// CLASS DECLARATION +/** +* Class that implements the generic EAP type interface. Implements EAP MSCHAPv2 and +* plain MSCHAPv2 protocol. +*/ +class CEapMsChapV2 : public CEapType +{ +public: + /** + * Construction function. Called by ECom after the EAP MSCHAPv2 plugin has been loaded. + * @param aIapInfo Pointer to the class that contains information about bearer type and unique index. + * @return Pointer to the instance. + */ + static CEapMsChapV2* NewL(SIapInfo *aIapInfo); + + /** + * Construction function. Called by ECom after the plain MSCHAPv2 plugin has been loaded. + * @param aIapInfo Pointer to the class that contains information about bearer type and unique index. + * @return Pointer to the instance. + */ + static CEapMsChapV2* NewPlainMSCHAPv2L(SIapInfo *aIapInfo); + + /** + * Destructor does nothing. + */ + virtual ~CEapMsChapV2(); + +#ifdef USE_EAP_SIMPLE_CONFIG + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @param eap_config_if Pointer used for call back to creater of stack (eapol_am_wlan_authentication_symbian_c class). + * @return Pointer to the implementation. + */ + virtual eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if); + +#else + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @return Pointer to the implementation. + */ + eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG + + /** + * Invokes the configuration UI. + **/ + TInt InvokeUiL(); + + /** + * Gets information about EAP type. + * @return Pointer to a class that contains the EAP type information. Also pushed to cleanup stack. + */ + CEapTypeInfo* GetInfoLC(); + + /** + * Deletes EAP type configuration + */ + void DeleteConfigurationL(); + + /** + * Returns the version of the interface that the EAP type implements. + * The client-side of the interface must always check the version with this function + * and not call the functions that are not implemented. New functions must be + * added to the end of the interface so that the order of the old functions + * does not change. + * @return Integer indicating the version. + */ + TUint GetInterfaceVersion(); + + /** + * Sets the tunneling type. This is used to indicate that this type is run inside another + * EAP type. + * @param aTunnelingType Type number for the tunneling type + */ + void SetTunnelingType(const TInt aTunnelingType); + + /** + * Changes the index of the saved parameters. + * @param aIndexType Indicates the bearer used for this connection. + * @param aIndex Index for the connection. aIndexType and aIndex uniquely specify the connection. + */ + void SetIndexL( + const TIndexType aIndexType, + const TInt aIndex); + + /** + * Sets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void SetConfigurationL(const EAPSettings& aSettings); + + /** + * Gets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void GetConfigurationL(EAPSettings& aSettings); + + /** + * Copies the EAP types configuration + * @param aDestinationIndex ID to where copy the settings. + */ + void CopySettingsL(const TIndexType aDestinationIndexType, const TInt aDestinationIndex); + +protected: + + /** + * Constructor initialises member variables. + */ + CEapMsChapV2(const TIndexType aIndexType, const TInt aIndex, + const eap_type_value_e aEapType = eap_type_mschapv2 ); + +private: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // Tunneling type + eap_type_value_e iTunnelingType; + + // Eap type (EAP-MSCHAPv2 or plain MSCHAPv2) + eap_type_value_e iEapType; + +}; + +#endif // _EAPMSCHAPV2_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/EapMsChapV2DbDefaults.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/EapMsChapV2DbDefaults.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#ifndef _EAPMSCHAPV2DBDEFAULTS_H_ +#define _EAPMSCHAPV2DBDEFAULTS_H_ + +enum TMSCHAPV2PasswordPrompt +{ + EMSCHAPV2PasswordPromptOff, // False. Don't show password prompt. + EMSCHAPV2PasswordPromptOn, // True. Show password prompt. +}; + +// LOCAL CONSTANTS + +const TUint default_EAP_MSCHAPV2_password_prompt = EMSCHAPV2PasswordPromptOff; + +_LIT(default_EAP_MSCHAPV2_username, ""); +_LIT(default_EAP_MSCHAPV2_password, ""); + +const TInt64 default_MaxSessionTime = 0; // 0 means read from configuration file. +const TInt64 default_FullAuthTime = 0; + +const TUint KMaxUsernameLengthInDB = 255; +const TUint KMaxPasswordLengthInDB = 255; + +#endif // _EAPMSCHAPV2DBDEFAULTS_H_ diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/EapMsChapV2DbParameterNames.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/EapMsChapV2DbParameterNames.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPMSCHAPV2DBPARAMETERNAMES_H +#define EAPMSCHAPV2DBPARAMETERNAMES_H + +#include "eap_type_mschapv2_types.h" + +// LOCAL CONSTANTS + +_LIT(KServiceType, "ServiceType"); +_LIT(KServiceIndex, "ServiceIndex"); +_LIT(KTunnelingType, "TunnelingType"); + +_LIT(KMSCHAPv2LastFullAuthTime, "EAP_MSCHAPv2_last_full_authentication_time"); + +#endif // _EAPMSCHAPV2DBPARAMETERNAMES_H_ + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/EapMsChapV2DbUtils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/EapMsChapV2DbUtils.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,104 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPMSCHAPV2DBUTILS_H_ +#define _EAPMSCHAPV2DBUTILS_H_ + +// INCLUDES +#include +#include +#include "eap_header.h" + + +// LOCAL CONSTANTS + +#ifdef SYMBIAN_SECURE_DBMS +// For EAP MSCHAPV2 secure database. +// Full path is not needed. The database eapmsmhapv2.dat will be saved in the +// data cage path for DBMS. So it will be in "\private\100012a5\eapmsmhapv2.dat" in C: drive. +// The maximum length of database name is 0x40 (KDbMaxName) , which is defined in d32dbms.h. + +_LIT(KDatabaseName, "c:eapmschapv2.dat"); + +_LIT(KSecureUIDFormat, "SECURE[102072e9]"); // For the security policy. + +#else + +_LIT(KDatabaseName, "c:\\system\\data\\eapmschapv2.dat"); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + +_LIT(KMsChapV2TableName, "eapmschapv2"); + +// CLASS DECLARATION +class EapMsChapV2DbUtils +{ +public: + + static void OpenDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + /** + * Changes the settings' index + */ + static void SetIndexL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const TIndexType aNewIndexType, + const TInt aNewIndex, + const eap_type_value_e aNewTunnelingType); + + static void SetConfigurationL( + RDbNamedDatabase& aDatabase, + const EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + static void GetConfigurationL( + RDbNamedDatabase& aDatabase, + EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + static void CopySettingsL( + RDbNamedDatabase& aDatabase, + const TIndexType aSrcIndexType, + const TInt aSrcIndex, + const eap_type_value_e aSrcTunnelingType, + const TIndexType aDestIndexType, + const TInt aDestIndex, + const eap_type_value_e aDestTunnelingType); + + static void DeleteConfigurationL( + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + +}; + +#endif // _EAPMSCHAPV2DBUTILS_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/EapMsChapV2Global.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/EapMsChapV2Global.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPMSCHAPV2GLOBAL_H_ +#define _EAPMSCHAPV2GLOBAL_H_ + +// LOCAL CONSTANTS + +_LIT(KReleaseDate, "20040829:"); // Must be in format YYYYMMDD: (dates and months start from 0) +_LIT(KEapTypeVersion, "1.0"); +_LIT(KManufacturer, "Nokia"); +_LIT(KNokiaSignature, ""); +_LIT(KExtraInfo1, ""); +_LIT(KExtraInfo2, ""); + +#endif // _EAPMSCHAPV2GLOBAL_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/eapmschap.hlp.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/inc/eapmschap.hlp.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource headers for project EAPOL +* +*/ + + +// +// eapmschap.hlp.hrh +// + +// +// File generated on 10:42:14 28/7/2004 +// by cshlpcmp Version 010 +// + +#ifndef __EAPMSCHAP_HLP_HRH__ +#define __EAPMSCHAP_HLP_HRH__ + + +_LIT(KEMPL_HLP_DIAL_SETTINGS,"EMPL_HLP_DIAL_SETTINGS"); +_LIT(KEMPD_HLP_DIAL_USER_PASSWORD,"EMPD_HLP_DIAL_USER_PASSWORD"); +_LIT(KEMPD_HLP_DIAL_CHANGE_PASSWORD,"EMPD_HLP_DIAL_CHANGE_PASSWORD"); + +#endif diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/101F8E66.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/101F8E66.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource definitions for project EAPOL +* +*/ + + + +// INCLUDES +#include +#include "101F8E66.loc" +#include "EapolUID.h" + + +// RESOURCE DEFINITIONS +// --------------------------------------------------------- +// +// theInfo +// Contains the ECom registration information for EAP MSCHAPv2 +// +// --------------------------------------------------------- +// +RESOURCE REGISTRY_INFO theInfo +{ +dll_uid = EAP_MSCHAPV2_DLL_UID; +interfaces = + { + INTERFACE_INFO + { + interface_uid = PLUGIN_INTERFACE_UID; + implementations = + { + + BINARY_IMPLEMENTATION_INFO + { + implementation_uid = MSCHAPV2_IMPLEMENTATION_UID; + version_no = 1; + display_name = "MSCHAPv2"; + default_data = {0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x63}; // plain MSCHAPv2 allowed only inside TTLS. + opaque_data = {0x4E}; //"NOT_OUTSIDE|NOT_OUTSIDE_PEAP|NOT_INSIDE_PEAP|NOT_INSIDE_FAST" + }, // NOT_OUTSIDE is the only needed instead of NOT_OUTSIDE_PEAP, + // but for historical reasons we are using NOT_OUTSIDE_PEAP + // to indicate that the EAP is allowed only as encapsulated EAP. + BINARY_IMPLEMENTATION_INFO + { + implementation_uid = EAP_MSCHAPV2_IMPLEMENTATION_UID; + version_no = 1; + display_name = EMPL_GE_NAME; + default_data = {0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A}; // EAP-MSCHAPv2 + opaque_data = {0x0A}; //"NOT_OUTSIDE|NOT_OUTSIDE_PEAP" + } + }; + } + }; +} +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,345 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 292 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "EapMsChapV2.h" +#include "eap_am_type_mschapv2_symbian.h" +#include "eap_type_mschapv2.h" +#include "EapMsChapV2Global.h" +#include +#include "EapMsChapV2DbUtils.h" + +#include +#include "EapMschapv2Ui.h" + +// LOCAL CONSTANTS + +// The version number of this interface. +const TUint KInterfaceVersion = 1; + + +// ================= MEMBER FUNCTIONS ======================= + + +CEapMsChapV2::CEapMsChapV2(const TIndexType aIndexType, + const TInt aIndex, const eap_type_value_e aEapType /* =eap_type_mschapv2 */) +: iIndexType(aIndexType) +, iIndex(aIndex) +, iTunnelingType(eap_type_none) +, iEapType(aEapType) +{ +} + +// ---------------------------------------------------------- + +CEapMsChapV2* CEapMsChapV2::NewL(SIapInfo *aIapInfo) +{ + return new (ELeave) CEapMsChapV2(aIapInfo->indexType, aIapInfo->index); +} + +// ---------------------------------------------------------- + +CEapMsChapV2* CEapMsChapV2::NewPlainMSCHAPv2L(SIapInfo *aIapInfo) +{ + return new (ELeave) CEapMsChapV2( + aIapInfo->indexType, + aIapInfo->index, +#if defined(USE_EAP_EXPANDED_TYPES) + eap_expanded_type_ttls_plain_mschapv2.get_type() +#else + eap_type_plain_mschapv2 +#endif //#if defined(USE_EAP_EXPANDED_TYPES) + ); +} + + +// ---------------------------------------------------------- + +CEapMsChapV2::~CEapMsChapV2() +{ +} + +// ---------------------------------------------------------- + +#ifdef USE_EAP_SIMPLE_CONFIG + +eap_base_type_c* CEapMsChapV2::GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const /*configuration_if*/) + +#else + +eap_base_type_c* CEapMsChapV2::GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG +{ + // Create AM + eap_am_type_mschapv2_symbian_c* amEapType = eap_am_type_mschapv2_symbian_c::NewL( + aTools, + aPartner, + iIndexType, + iIndex, + iTunnelingType, + is_client_when_true, + receive_network_id); + if (amEapType->get_is_valid() == false) + { + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrGeneral); + } + eap_base_type_c* type = 0; + + type = new eap_type_mschapv2_c( + aTools, + aPartner, + amEapType, + true /* free_am */, + is_client_when_true, + receive_network_id); + + if (type == 0) + { + // Out of memory + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrNoMemory); + } + else if (type->get_is_valid() == false) + { + type->shutdown(); + // amEapType is freed by eap_type_mschapv2_c + delete type; + User::Leave(KErrGeneral); + } + return type; + +} + +// ---------------------------------------------------------- + +TUint CEapMsChapV2::GetInterfaceVersion() +{ + return KInterfaceVersion; +} + + +// ---------------------------------------------------------- +TInt CEapMsChapV2::InvokeUiL() +{ + TInt buttonId(0); + +#ifdef USE_EAP_EXPANDED_TYPES + + CEapMsChapV2UiConnection uiConn(iIndexType, iIndex, + iTunnelingType.get_vendor_type(), iEapType.get_vendor_type()); + +#else + + CEapMsChapV2UiConnection uiConn(iIndexType, iIndex, iTunnelingType, (TInt)iEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + CEapMsChapV2Ui* ui = CEapMsChapV2Ui::NewL(&uiConn); + CleanupStack::PushL(ui); + buttonId = ui->InvokeUiL(); + CleanupStack::PopAndDestroy(ui); + return buttonId; +} + + +// ---------------------------------------------------------- +CEapTypeInfo* CEapMsChapV2::GetInfoLC() +{ + CEapTypeInfo* info = new(ELeave) CEapTypeInfo( + (TDesC&)KReleaseDate, + (TDesC&)KEapTypeVersion, + (TDesC&)KManufacturer); + + CleanupStack::PushL(info); + return info; +} + +// ---------------------------------------------------------- + +void CEapMsChapV2::DeleteConfigurationL() +{ + EapMsChapV2DbUtils::DeleteConfigurationL(iIndexType, iIndex, iTunnelingType); +} + +// ---------------------------------------------------------- + +void CEapMsChapV2::SetTunnelingType(const TInt aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + // Vendor id is eap_type_vendor_id_ietf always in this plugin. + iTunnelingType.set_eap_type_values(eap_type_vendor_id_ietf, aTunnelingType); + +#else + + iTunnelingType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES +} + +// ---------------------------------------------------------- +void CEapMsChapV2::SetIndexL( + const TIndexType aIndexType, + const TInt aIndex) +{ + // First delete the target configuration + TIndexType tmpIndexType = iIndexType; + TInt tmpIndex = iIndex; + + iIndexType = aIndexType; + iIndex = aIndex; + + TInt err(KErrNone); + TRAP(err, DeleteConfigurationL()); + // Ignore error on purpose + + // Return the indices + iIndexType = tmpIndexType; + iIndex = tmpIndex; + + RDbNamedDatabase db; + + RDbs session; + + EapMsChapV2DbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapMsChapV2DbUtils::SetIndexL( + db, + iIndexType, + iIndex, + iTunnelingType, + aIndexType, + aIndex, + iTunnelingType); + + iIndexType = aIndexType; + iIndex = aIndex; + + CleanupStack::PopAndDestroy(2); // db +} + +void CEapMsChapV2::SetConfigurationL(const EAPSettings& aSettings) +{ + RDbNamedDatabase db; + + RDbs session; + + // This also creates the IAP entry if it doesn't exist + EapMsChapV2DbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapMsChapV2DbUtils::SetConfigurationL( + db, + aSettings, + iIndexType, + iIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db, session +} + +void CEapMsChapV2::GetConfigurationL(EAPSettings& aSettings) +{ + RDbNamedDatabase db; + + RDbs session; + + // This also creates the IAP entry if it doesn't exist + EapMsChapV2DbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapMsChapV2DbUtils::GetConfigurationL( + db, + aSettings, + iIndexType, + iIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db, session +} + +void CEapMsChapV2::CopySettingsL( + const TIndexType aDestinationIndexType, + const TInt aDestinationIndex) +{ + // First delete the target configuration + TIndexType tmpIndexType = iIndexType; + TInt tmpIndex = iIndex; + + iIndexType = aDestinationIndexType; + iIndex = aDestinationIndex; + + TInt err(KErrNone); + TRAP(err, DeleteConfigurationL()); + // Ignore error on purpose + + // Return the indices + iIndexType = tmpIndexType; + iIndex = tmpIndex; + + RDbNamedDatabase db; + + RDbs session; + + EapMsChapV2DbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapMsChapV2DbUtils::CopySettingsL( + db, + iIndexType, + iIndex, + iTunnelingType, + aDestinationIndexType, + aDestinationIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db + +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2DbUtils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2DbUtils.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,642 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 294 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "EapMsChapV2DbUtils.h" +#include "EapMsChapV2DbDefaults.h" +#include "EapMsChapV2DbParameterNames.h" + +#include "eap_am_trace_symbian.h" + +const TUint KMaxSqlQueryLength = 512; +const TInt KMicroSecsInAMinute = 60000000; // 60000000 micro seconds is 1 minute. + +// ================= MEMBER FUNCTIONS ======================= + +void EapMsChapV2DbUtils::OpenDatabaseL(RDbNamedDatabase& aDatabase, RDbs& aSession, const TIndexType aIndexType, + const TInt aIndex, const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapMsChapV2DbUtils::OpenDatabaseL -Start- aIndexType=%d, aIndex=%d, aTunnelingVendorType=%d \n"), + aIndexType,aIndex,aTunnelingVendorType) ); + + // 1. Open/create a database + + // Connect to the DBMS server. + User::LeaveIfError(aSession.Connect()); + CleanupClosePushL(aSession); + // aSession and aDatabase are pushed to the cleanup stack even though they may be member + // variables of the calling class and would be closed in the destructor anyway. This ensures + // that if they are not member variables they will be closed. Closing the handle twice + // does no harm. + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = aDatabase.Create(aSession, KDatabaseName, KSecureUIDFormat); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapMsChapV2DbUtils::OpenDatabaseL - Created Secure DB for eapmsmhapv2.dat. err=%d\n"), err)); + + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(aSession, KDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(aDatabase); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = aDatabase.Create(fsSession, KDatabaseName); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapMsChapV2DbUtils::OpenDatabaseL - Created Non-Secure DB for eapmsmhapv2.dat. err=%d\n"), err)); + + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + CleanupStack::PopAndDestroy(); // close fsSession + + User::LeaveIfError(aDatabase.Open(aSession, KDatabaseName)); + CleanupClosePushL(aDatabase); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + +// 2. Create the MSCHAPv2 table to database (ignore error if database exists) +// Table columns: +//// NAME ///////////////////////////////////////////////// TYPE ////////////// Constant ///////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| EAP_MSCHAPV2_password_prompt | UNSIGNED INTEGER | cf_str_EAP_MSCHAPV2_password_prompt_literal |// +//| EAP_MSCHAPV2_username | VARCHAR(255) | cf_str_EAP_MSCHAPV2_username_literal |// +//| EAP_MSCHAPV2_password | VARCHAR(255) | cf_str_EAP_MSCHAPV2_password_literal |// +//| EAP_MSCHAPv2_max_session_validity_time | BIGINT | cf_str_EAP_MSCHAPv2_max_session_validity_time_literal |// +//| EAP_MSCHAPv2_last_full_authentication_time | BIGINT | KMSCHAPv2LastFullAuthTime |// +////////////////////////////////////////////////////////////////////////////////////////////////// + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLCreateTable1, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(255), \ + %S VARCHAR(255), \ + %S BIGINT, \ + %S BIGINT)"); + + sqlStatement.Format(KSQLCreateTable1, + &KMsChapV2TableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &cf_str_EAP_MSCHAPV2_password_prompt_literal, + &cf_str_EAP_MSCHAPV2_username_literal, + &cf_str_EAP_MSCHAPV2_password_literal, + &cf_str_EAP_MSCHAPv2_max_session_validity_time_literal, + &KMSCHAPv2LastFullAuthTime); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // 4. Check if database table contains a row for this service type and id + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQueryRow, + &cf_str_EAP_MSCHAPV2_username_literal, + &KMsChapV2TableName, + &KServiceType, + aIndexType, + &KServiceIndex, + aIndex, + &KTunnelingType, + aTunnelingVendorType); + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + // View must be closed when no longer needed + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // 5. If row is not found then add it + + TInt rows = view.CountL(); + CleanupStack::PopAndDestroy(); // view + if (rows == 0) + { + _LIT(KSQLInsert, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert, &KMsChapV2TableName); + + view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly); + CleanupClosePushL(view); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast (aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPV2_password_prompt_literal), default_EAP_MSCHAPV2_password_prompt); + + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPV2_username_literal), default_EAP_MSCHAPV2_username); + + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPV2_password_literal), default_EAP_MSCHAPV2_password); + + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPv2_max_session_validity_time_literal), default_MaxSessionTime); + + view.SetColL(colSet->ColNo(KMSCHAPv2LastFullAuthTime), default_FullAuthTime); + + view.PutL(); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + CleanupStack::PopAndDestroy( &view ); // Close view. + } + + CleanupStack::PopAndDestroy( buf ); // Delete buf + CleanupStack::Pop( &aDatabase ); + CleanupStack::Pop( &aSession ); + + aDatabase.Compact(); +} + + +void EapMsChapV2DbUtils::SetIndexL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const TIndexType aNewIndexType, + const TInt aNewIndex, + const eap_type_value_e aNewTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aNewTunnelingVendorType = aNewTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aNewTunnelingVendorType = static_cast(aNewTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &KMsChapV2TableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + TInt rows = view.CountL(); + + if (rows == 0) + { + User::Leave(KErrNotFound); + } + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + + CleanupStack::PushL(colSet); + + view.UpdateL(); + + view.SetColL(colSet->ColNo(KServiceType), static_cast(aNewIndexType)); + + view.SetColL(colSet->ColNo(KServiceIndex), aNewIndex); + + view.SetColL(colSet->ColNo(KTunnelingType), aNewTunnelingVendorType); + + view.PutL(); + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapMsChapV2DbUtils::SetConfigurationL( + RDbNamedDatabase& aDatabase, + const EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + // Check if the settings are for the correct type + if (aSettings.iEAPType != EAPSettings::EEapMschapv2 && + aSettings.iEAPType != EAPSettings::EPlainMschapv2) + { + User::Leave(KErrNotSupported); + } + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + RDbView view; + + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KMsChapV2TableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + view.FirstL(); + + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Username + if (aSettings.iUsernamePresent) + { + // Validate length. + if(aSettings.iUsername.Length() > KMaxUsernameLengthInDB) + { + // Username too long. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapMsChapV2DbUtils::SetConfigurationL: Too long Username. Length=%d \n"), + aSettings.iUsername.Length())); + + User::Leave(KErrArgument); + } + + // Length is ok. Set the value in DB. + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPV2_username_literal), aSettings.iUsername); + } + + // Password + if (aSettings.iPasswordPresent) + { + // Validate length. + if(aSettings.iPassword.Length() > KMaxPasswordLengthInDB) + { + // Password too long. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapMsChapV2DbUtils::SetConfigurationL: Too long Password. Length=%d \n"), + aSettings.iPassword.Length())); + + User::Leave(KErrArgument); + } + + // Length is ok. Set the value in DB. + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPV2_password_literal), aSettings.iPassword); + + // If password was supplied set password prompting off + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPV2_password_prompt_literal), EMSCHAPV2PasswordPromptOff); + } + + // Session validity time + if (aSettings.iSessionValidityTimePresent) + { + // User or device management wants to store the session validity time. + // Convert the time to micro seconds and save. + + TInt64 validityInMicro = (aSettings.iSessionValidityTime) * KMicroSecsInAMinute; + + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPv2_max_session_validity_time_literal), validityInMicro); + + // If max session validity time is supplied and non-zero, set password prompting ON. + // It doesn't matter even if the password is supplied. If max session validity is supplied, + // it means user needs to provide a password hence prompt should appear. + + if( validityInMicro != 0) + { + view.SetColL(colSet->ColNo(cf_str_EAP_MSCHAPV2_password_prompt_literal), EMSCHAPV2PasswordPromptOn); + } + } + + // Last full authentication time should be made zero when EAP configurations are modified. + // This makes sure that the next authentication with this EAP would be full authentication + // instead of reauthentication even if the session is still valid. + + view.SetColL(colSet->ColNo(KMSCHAPv2LastFullAuthTime), default_FullAuthTime); + + EAP_TRACE_DEBUG_SYMBIAN((_L("Session Validity: EAP-Type=%d, Resetting Full Auth Time since settings are modified\n"), + aSettings.iEAPType )); + + view.PutL(); + CleanupStack::PopAndDestroy(3); // view, colset, buf + +} + +void EapMsChapV2DbUtils::GetConfigurationL( + RDbNamedDatabase& aDatabase, + EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + RDbView view; + + // Form the query + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KMsChapV2TableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + aSettings.iEAPType = EAPSettings::EEapMschapv2; + + // Username + TPtrC username = view.ColDes(colSet->ColNo(cf_str_EAP_MSCHAPV2_username_literal)); + aSettings.iUsername.Copy(username); + aSettings.iUsernamePresent = ETrue; + + // Password + TPtrC password = view.ColDes(colSet->ColNo(cf_str_EAP_MSCHAPV2_password_literal)); + aSettings.iPassword.Copy(password); + aSettings.iPasswordPresent = ETrue; + + // Session validity time + TInt64 maxSessionTimeMicro = view.ColInt64(colSet->ColNo(cf_str_EAP_MSCHAPv2_max_session_validity_time_literal)); + + // Convert the time to minutes. + TInt64 maxSessionTimeMin = maxSessionTimeMicro / KMicroSecsInAMinute; + + aSettings.iSessionValidityTime = static_cast(maxSessionTimeMin); + aSettings.iSessionValidityTimePresent = ETrue; + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapMsChapV2DbUtils::CopySettingsL( + RDbNamedDatabase& aDatabase, + const TIndexType aSrcIndexType, + const TInt aSrcIndex, + const eap_type_value_e aSrcTunnelingType, + const TIndexType aDestIndexType, + const TInt aDestIndex, + const eap_type_value_e aDestTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aSrcTunnelingVendorType = aSrcTunnelingType.get_vendor_type(); + TUint aDestTunnelingVendorType = aDestTunnelingType.get_vendor_type(); + +#else + + TUint aSrcTunnelingVendorType = static_cast(aSrcTunnelingType); + TUint aDestTunnelingVendorType = static_cast(aDestTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &KMsChapV2TableName, + &KServiceType, aSrcIndexType, &KServiceIndex, aSrcIndex, &KTunnelingType, aSrcTunnelingVendorType); + + RDbView view; + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + TInt rows = view.CountL(); + + if (rows == 0) + { + User::Leave(KErrNotFound); + } + + // Get the first (and only) row + view.FirstL(); + + view.GetL(); + + view.InsertCopyL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + + CleanupStack::PushL(colSet); + + view.SetColL(colSet->ColNo(KServiceType), static_cast(aDestIndexType)); + + view.SetColL(colSet->ColNo(KServiceIndex), aDestIndex); + + view.SetColL(colSet->ColNo(KTunnelingType), aDestTunnelingVendorType); + + view.PutL(); + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapMsChapV2DbUtils::DeleteConfigurationL( + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + RDbs session; + RDbNamedDatabase database; + // Connect to the DBMS server. + User::LeaveIfError(session.Connect()); + CleanupClosePushL(session); + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = database.Create(session, KDatabaseName, KSecureUIDFormat); + + if(err == KErrNone) + { + // Database was created so it was empty. No need for further actions. + database.Destroy(); + CleanupStack::PopAndDestroy(); + return; + + } + else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + // Database existed, open it. + User::LeaveIfError(database.Open(session, KDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(database); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = database.Create(fsSession, KDatabaseName); + + if(err == KErrNone) + { + // Database was created so it was empty. No need for further actions. + database.Destroy(); + CleanupStack::PopAndDestroy(2); // fsSession, database session + return; + + } + else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + CleanupStack::PopAndDestroy(); // close fsSession + + User::LeaveIfError(database.Open(session, KDatabaseName)); + CleanupClosePushL(database); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Main settings table + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQL, &KMsChapV2TableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Delete rows + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + // Close database + CleanupStack::PopAndDestroy(4); // view, buf, database, session +} + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2Proxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2Proxy.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 296 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include "EapMsChapV2.h" +#include +#include + +#include "EapolUID.h" + +const TImplementationProxy ImplementationTable[] = +{ + {{EAP_MSCHAPV2_IMPLEMENTATION_UID}, reinterpret_cast (CEapMsChapV2::NewL)}, + {{MSCHAPV2_IMPLEMENTATION_UID}, reinterpret_cast (CEapMsChapV2::NewPlainMSCHAPv2L)} +}; + +// ================= OTHER EXPORTED FUNCTIONS ============== + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) +{ + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + + return ImplementationTable; +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2UiConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2UiConnection.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,137 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 298 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include "EapMsChapV2DbUtils.h" +#include +#include + +CEapMsChapV2UiConnection::CEapMsChapV2UiConnection( + const TIndexType aIndexType, + const TInt aIndex, + const TInt aTunnelingType, + const TInt aEAPType) + : iIndexType(aIndexType) + , iIndex(aIndex) + , iTunnelingType(aTunnelingType) + , iIsConnected(EFalse) + , iDataConn(NULL) + , iEAPType(aEAPType) +{ +} + + +CEapMsChapV2UiConnection::~CEapMsChapV2UiConnection() +{ +} + + +TInt CEapMsChapV2UiConnection::Connect() +{ +#ifdef USE_EAP_EXPANDED_TYPES + + eap_type_value_e tunnelingType(static_cast(iTunnelingType)); + +#else + + eap_type_value_e tunnelingType = static_cast(iTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + TRAPD(err, EapMsChapV2DbUtils::OpenDatabaseL( + iDbNamedDatabase, + iDbs, + iIndexType, + iIndex, + tunnelingType)); + if (err == KErrNone) + { + iIsConnected = ETrue; + } + + return err; +} + + +TInt CEapMsChapV2UiConnection::Close() +{ + if (iIsConnected) + { + iDbNamedDatabase.Close(); + iDbs.Close(); + } + iIsConnected = EFalse; + + return KErrNone; +} + + +CEapMsChapV2UiDataConnection * CEapMsChapV2UiConnection::GetDataConnection() +{ + if (!iDataConn) + { + iDataConn = new CEapMsChapV2UiDataConnection(this); + } + + return iDataConn; +} + +TInt CEapMsChapV2UiConnection::GetDatabase(RDbNamedDatabase & aDatabase) +{ + if (iIsConnected == EFalse) + { + return KErrSessionClosed; + } + + aDatabase = iDbNamedDatabase; + return KErrNone; +} + + +TIndexType CEapMsChapV2UiConnection::GetIndexType() +{ + return iIndexType; +} + + +TInt CEapMsChapV2UiConnection::GetIndex() +{ + return iIndex; +} + + +TInt CEapMsChapV2UiConnection::GetTunnelingType() +{ + return iTunnelingType; +} + +TInt CEapMsChapV2UiConnection::GetBearerEAPType() +{ + return iEAPType; +} + +// End of file + + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2UiDataConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2UiDataConnection.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,250 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 300 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include +#include "EapMsChapV2DbUtils.h" +#include "EapMsChapV2DbParameterNames.h" +#include "EapMsChapV2DbDefaults.h" +#include +#include +#include +#include "eap_am_trace_symbian.h" + +const TUint KMaxSqlQueryLength = 256; + + +CEapMsChapV2UiDataConnection::CEapMsChapV2UiDataConnection(CEapMsChapV2UiConnection * aUiConn) +: iIsOpened(EFalse) +, iUiConn(aUiConn) +, iColSet(NULL) +, iDataPtr(NULL) +{ +} + + +CEapMsChapV2UiDataConnection::~CEapMsChapV2UiDataConnection() +{ + if (iUiConn) + { + Close(); + iUiConn = NULL; + } +} + + +TInt CEapMsChapV2UiDataConnection::Open() +{ + if (iIsOpened) + { + return KErrAlreadyExists; + } + + TInt err = iUiConn->GetDatabase(iDatabase); + if (err != KErrNone) + { + return err; + } + + iIsOpened = ETrue; + return KErrNone; +} + + +TInt CEapMsChapV2UiDataConnection::GetData(CEapMsChapV2UiMsChapV2Data ** aDataPtr) +{ + if (aDataPtr == NULL) + { + return KErrArgument; + } + if (iIsOpened == EFalse) + { + return KErrSessionClosed; + } + iDataPtr = new CEapMsChapV2UiMsChapV2Data(); + if (!iDataPtr) + { + return KErrNoMemory; + } + + TRAPD(err, FetchDataL()); + if (err != KErrNone) + { + delete iDataPtr; + iDataPtr = NULL; + + delete iColSet; + iColSet = NULL; + + iView.Close(); + + return err; + } + + *aDataPtr = iDataPtr; + + return KErrNone; +} + + +TInt CEapMsChapV2UiDataConnection::Update() +{ + TRAPD(err, iView.UpdateL()); + if (err != KErrNone) + { + return err; + } + + // Validate the length of username and password. + if(iDataPtr->GetUsername().Length() > KMaxUsernameLengthInDB + || iDataPtr->GetPassword().Length() > KMaxPasswordLengthInDB) + { + // Username or password too long. Can not be stored in DB. + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapMsChapV2UiDataConnection::Update: Too long username or password. Length: UN=%d, PW=%d\n"), + iDataPtr->GetUsername().Length(), + iDataPtr->GetPassword().Length())); + + return KErrArgument; + } + + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_MSCHAPV2_username_literal), iDataPtr->GetUsername())); + if (err != KErrNone) + { + return err; + } + + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_MSCHAPV2_password_literal), iDataPtr->GetPassword())); + if (err != KErrNone) + { + return err; + } + + if (*(iDataPtr->GetPasswordPrompt())) + { + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_MSCHAPV2_password_prompt_literal), EMSCHAPV2PasswordPromptOn)); + if (err != KErrNone) + { + return err; + } + } + else + { + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_MSCHAPV2_password_prompt_literal), EMSCHAPV2PasswordPromptOff)); + if (err != KErrNone) + { + return err; + } + } + + // Last full authentication time should be made zero when EAP configurations are modified. + // This makes sure that the next authentication with this EAP would be full authentication + // instead of reauthentication even if the session is still valid. + + TRAP(err, iView.SetColL(iColSet->ColNo(KMSCHAPv2LastFullAuthTime), default_FullAuthTime)); + if (err != KErrNone) + { + return err; + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("Session Validity: EAP-Type=MSCHAPv2 (or plain), Resetting Full Auth Time since settings are modified\n"))); + + TRAP(err, iView.PutL()); + + return err; +} + + +TInt CEapMsChapV2UiDataConnection::Close() +{ + if (iIsOpened == EFalse) + { + return KErrNone; + } + + delete iDataPtr; + iDataPtr = NULL; + + delete iColSet; + iColSet = NULL; + + iView.Close(); + + iUiConn = NULL; + + return KErrNone; +} + + +void CEapMsChapV2UiDataConnection::FetchDataL() +{ + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Form the query. Query everything. + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, + &KMsChapV2TableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + // Evaluate view + User::LeaveIfError(iView.Prepare(iDatabase, TDbQuery(sqlStatement))); + User::LeaveIfError(iView.EvaluateAll()); + + // Get the first (and only) row + iView.FirstL(); + iView.GetL(); + + // Get column set so we get the correct column numbers + delete iColSet; + iColSet = NULL; + iColSet = iView.ColSetL(); + + // Start fetching the values + + // Prompt password + TUint intValue = iView.ColUint(iColSet->ColNo(cf_str_EAP_MSCHAPV2_password_prompt_literal)); + if (intValue == 0) + { + *(iDataPtr->GetPasswordPrompt()) = EFalse; + } + else + { + *(iDataPtr->GetPasswordPrompt()) = ETrue; + } + + // username + iDataPtr->GetUsername().Copy(iView.ColDes16(iColSet->ColNo(cf_str_EAP_MSCHAPV2_username_literal))); + + // password + iDataPtr->GetPassword().Copy(iView.ColDes16(iColSet->ColNo(cf_str_EAP_MSCHAPV2_password_literal))); + + CleanupStack::PopAndDestroy(buf); +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2UiMsChapV2Data.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/mschapv2/symbian/plugin/src/EapMsChapV2UiMsChapV2Data.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 302 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include + + +CEapMsChapV2UiMsChapV2Data::CEapMsChapV2UiMsChapV2Data() +{ +} + + +CEapMsChapV2UiMsChapV2Data::~CEapMsChapV2UiMsChapV2Data() +{ +} + + +TDes& CEapMsChapV2UiMsChapV2Data::GetUsername() +{ + return iUsername; +} + + +TDes& CEapMsChapV2UiMsChapV2Data::GetPassword() +{ + return iPassword; +} + + +TBool * CEapMsChapV2UiMsChapV2Data::GetPasswordPrompt() +{ + return &iPasswordPrompt; +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/protected_setup/EapProtectedSetupInterface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/protected_setup/EapProtectedSetupInterface.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,290 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 174 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +// INCLUDE FILES +#include "EapProtectedSetupInterface.h" +#include "eap_am_type_protected_setup_symbian.h" + +#include +#include + +// ================= MEMBER FUNCTIONS ======================= + +CEapProtectedSetupInterface::CEapProtectedSetupInterface(abs_eap_am_tools_c* const aTools, eap_am_type_protected_setup_symbian_c* const aParent) +: CActive(CActive::EPriorityStandard) +, iParent(aParent) +, m_am_tools(aTools) +, iQueryId(EQueryNone) +, iMMETELConnectionStatus(EFalse) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +CEapProtectedSetupInterface* CEapProtectedSetupInterface::NewL(abs_eap_am_tools_c* const aTools, + eap_am_type_protected_setup_symbian_c* const aParent) +{ + CEapProtectedSetupInterface* self = new(ELeave) CEapProtectedSetupInterface(aTools, aParent); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; +} + +//-------------------------------------------------- + +void CEapProtectedSetupInterface::ConstructL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + CActiveScheduler::Add(this); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +CEapProtectedSetupInterface::~CEapProtectedSetupInterface() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if(IsActive()) + { + Cancel(); + } + + DisconnectMMETel(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapProtectedSetupInterface::QueryDeviceParametersL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ProtectedSetup interface: Querying Device Parametes.\n"))); + + iQueryId = EQueryDeviceParams; + + // Create MMETEl connection. + User::LeaveIfError( CreateMMETelConnectionL() ); + + iPhone.GetPhoneId( iStatus, iDeviceId ); + + if( !IsActive() ) + { + SetActive(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapProtectedSetupInterface::DoCancel() +{ + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapProtectedSetupInterface::DoCancel() - Cancelling MMETEL query.\n") ) ); + + if(iQueryId == EQueryDeviceParams) + { + // Cancel the request for device id. + iPhone.CancelAsyncRequest(EMobilePhoneGetPhoneId); + } + else + { + // This should not happen. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: CEapProtectedSetupInterface::DoCancel(): SOME BIG PROBLEM \n"))); + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapProtectedSetupInterface::DoCancel(): CANCELLED the REQUEST \n"))); +} + +//-------------------------------------------------- + +void CEapProtectedSetupInterface::RunL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapProtectedSetupInterface::RunL(). iStatus.Int() =%d \n"), iStatus.Int() )); + + TInt error = KErrNone; + eap_status_e completion_status(eap_status_ok); + + if (iStatus.Int() == KErrNone) + { + switch( iQueryId ) + { + case EQueryDeviceParams: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapProtectedSetupInterface::RunL():: Got Device ID reply.\n"))); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Manufacturer"), + iDeviceId.iManufacturer.Ptr(), + iDeviceId.iManufacturer.Size())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Model"), + iDeviceId.iModel.Ptr(), + iDeviceId.iModel.Size())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Revision"), + iDeviceId.iRevision.Ptr(), + iDeviceId.iRevision.Size())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("SerialNumber"), + iDeviceId.iSerialNumber .Ptr(), + iDeviceId.iSerialNumber .Size())); + + // Complete. This happens only if completion_status is eap_status_ok so far. + TRAP(error, iParent->complete_protected_setup_device_paramsL(iDeviceId, completion_status)); + + break; + + default: + + // Some problem + // This should not happen. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: CEapProtectedSetupInterface::RunL(): Unknown query completed.\n"))); + break; + } + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: CEapProtectedSetupInterface::RunL(): Got error reply.\n"))); + + switch( iQueryId ) + { + case EQueryDeviceParams: + + // Error with Device id request. Complete the request with error. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: CEapProtectedSetupInterface::RunL(): Error in device parameters query.\n"))); + + TRAP(error, iParent->complete_protected_setup_device_paramsL( + iDeviceId, + m_am_tools->convert_am_error_to_eapol_error(iStatus.Int()))); + break; + + default: + + // Some problem + // This should not happen. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: CEapProtectedSetupInterface::RunL(): Unknown query failed.\n"))); + + break; + + } + } + + DisconnectMMETel(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +TInt CEapProtectedSetupInterface::CreateMMETelConnectionL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Creating MMETel connection.\n"))); + + TInt errorCode = KErrNone; + + // MMETel need to be connected only once. + if( !iMMETELConnectionStatus ) + { + RTelServer::TPhoneInfo phoneInfo; + TInt phoneCount = 0; + + // Connect to ETel server + User::LeaveIfError( iServer.Connect() ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Connected to ETel server.\n"))); + + // This function loads an ETel TSY module, mmtsy. + errorCode = iServer.LoadPhoneModule( KMmTsyModuleName ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Loaded phone module.\n"))); + + if ( errorCode != KErrNone && errorCode != KErrAlreadyExists ) + { + User::Leave( errorCode ); + } + + iServer.SetExtendedErrorGranularity( RTelServer::EErrorExtended ); + + // This function retrieves the total number of phones supported by all + // the currently loaded ETel (TSY) modules. + User::LeaveIfError( iServer.EnumeratePhones( phoneCount ) ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Number of phones supported by the loaded ETel = %d.\n"), phoneCount)); + + // This function retrieves information associated with the specified phone + while ( ( phoneCount-- ) && ( phoneInfo.iName != KMmTsyPhoneName ) ) + { + User::LeaveIfError( iServer.GetPhoneInfo( phoneCount, phoneInfo ) ); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got phone info.\n"))); + } + + // This function opens a phone subsession by name. ("DefaultPhone"). + User::LeaveIfError( iPhone.Open( iServer, phoneInfo.iName ) ); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Opened phone subsession.\n"))); + + // MMETel connected and the phone module loaded fine. + iMMETELConnectionStatus = ETrue; + } + else + { + // MMETel already connected. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("MMETel connected once already.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return errorCode; +} + +//-------------------------------------------------- + +void CEapProtectedSetupInterface::DisconnectMMETel() +{ + if( iMMETELConnectionStatus ) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Closing RMobilePhone and MMETEL.\n"))); + + iPhone.Close(); + iServer.Close(); // Phone module is unloaded automatically when RTelServer session is closed + + iMMETELConnectionStatus = EFalse; + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("RMobilePhone and MMETEL already closed.\n"))); + } +} + +//-------------------------------------------------- + +// End of file. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/protected_setup/eap_am_type_protected_setup_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/protected_setup/eap_am_type_protected_setup_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1644 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 175 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +// INCLUDE FILES + +#include "eap_am_type_protected_setup_symbian.h" + +#include "eap_am_tools.h" +#include "eap_state_notification.h" +#include "eap_config.h" +#include + +#include "eap_type_simple_config_types.h" +#include "eap_tlv_message_data.h" +#include "abs_simple_config_am_services.h" +#include "simple_config_credential.h" +#include "abs_eap_configuration_if.h" + +#include "eap_am_trace_symbian.h" +#include + +static const char EAP_AM_TYPE_SIMPLE_CONFIG_MEMORY_STORE_KEY[] = "eap_am_type_simple_config_simulator_c credential_store"; + +// ================= MEMBER FUNCTIONS ======================= + + +// +EAP_FUNC_EXPORT eap_am_type_protected_setup_symbian_c::eap_am_type_protected_setup_symbian_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if) +: m_partner(partner) +, m_index(aIndex) +, m_am_tools(tools) +, m_am_partner(0) +, m_simple_config_am_partner(0) +, m_configuration_if(configuration_if) +, m_device_parameters_valid(false) +, m_network_and_device_parameters(tools) +, m_UUID_E(tools) +, m_Device_Password_ID(simple_config_Device_Password_ID_Default_PIN) +, m_receive_network_id(tools) +, m_eap_identifier(0) +, m_eap_type(eap_type) +, m_simple_config_state(simple_config_state_none) +, m_is_valid(false) +, m_is_client(is_client_when_true) +, m_shutdown_was_called(false) +, m_manual_username(tools) +, m_manual_realm(tools) +, m_use_manual_username(false) +, m_use_manual_realm(false) +, m_configured(false) +, m_prot_setup_if(0) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: eap_am_type_protected_setup_symbian_c(): this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + if (receive_network_id == 0 + || receive_network_id->get_is_valid_data() == false) + { + // No need to delete anything here because it is done in destructor. + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + eap_status_e status = m_receive_network_id.set_copy_of_network_id( + receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void eap_am_type_protected_setup_symbian_c::ConstructL() +{ + if (m_is_client == true) + { + m_prot_setup_if = CEapProtectedSetupInterface::NewL(m_am_tools, this); + if(m_prot_setup_if == NULL) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAP-WSC No interface to MMETEL\n"))); + User::Leave(KErrNoMemory); + } + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAP-WSC server does not work at the moment\n"))); + User::Leave(KErrNotSupported); + } +} + +//-------------------------------------------------- + +eap_am_type_protected_setup_symbian_c* eap_am_type_protected_setup_symbian_c::NewL( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e eap_type, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if) +{ + eap_am_type_protected_setup_symbian_c* self = new (ELeave) eap_am_type_protected_setup_symbian_c( + tools, + partner, + aIndexType, + aIndex, + aTunnelingType, + eap_type, + is_client_when_true, + receive_network_id, + configuration_if); + + CleanupStack::PushL(self); + + self->ConstructL(); + + if (self->get_is_valid() != true) + { + User::Leave(KErrGeneral); + } + + CleanupStack::Pop(); + return self; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_type_protected_setup_symbian_c::~eap_am_type_protected_setup_symbian_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: ~eap_am_type_protected_setup_symbian_c(): this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_ASSERT(m_shutdown_was_called == true); + + if (m_is_client == true) + { + delete m_prot_setup_if; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +abs_simple_config_am_services_c * eap_am_type_protected_setup_symbian_c::get_simple_config_am_partner() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT_ALWAYS(m_simple_config_am_partner != 0); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_simple_config_am_partner; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_type_protected_setup_symbian_c::set_simple_config_am_partner(abs_simple_config_am_services_c * const simple_config_am_partner) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_simple_config_am_partner = simple_config_am_partner; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_type_protected_setup_symbian_c::set_am_partner(abs_eap_am_type_simple_config_c * const partner) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_am_partner = partner; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::configure() +{ + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: eap_am_type_protected_setup_symbian_c::configure()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_configured == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: eap_am_type_protected_setup_symbian_c::configure(): Already configured.\n"), + (m_is_client == true ? "client": "server"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_manual_username(m_am_tools); + + eap_status_e status = m_partner->read_configure( + cf_str_EAP_SIMPLE_CONFIG_use_manual_username.get_field(), + &use_manual_username); + if (status == eap_status_ok + && use_manual_username.get_is_valid_data() == true) + { + u32_t *use_manual_username_flag = reinterpret_cast( + use_manual_username.get_data(sizeof(u32_t))); + if (use_manual_username_flag != 0 + && *use_manual_username_flag != 0) + { + m_use_manual_username = true; + } + } + } + + //---------------------------------------------------------- + + if (m_use_manual_username == true) + { + eap_status_e status = m_partner->read_configure( + cf_str_EAP_SIMPLE_CONFIG_manual_username.get_field(), + &m_manual_username); + if (status == eap_status_ok + && m_manual_username.get_is_valid_data() == true) + { + // This is optional value. + } + else + { + // No username defined. + m_use_manual_username = false; + } + } + + //---------------------------------------------------------- + + // create UUID using create_uuid_v5_from_mac_address, mac address from receive_nw_id. + // Copy the UUID to m_UUID_E + { + eap_status_e status = m_am_tools->create_uuid_v5_from_mac_address( + m_receive_network_id.get_destination(), + m_receive_network_id.get_destination_length(), + &m_UUID_E); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP_type_SIMPLE_CONFIG: function: configure(): cannot get UUID-E from MAC address\n"))); + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: UUID-E from MAC address"), + m_UUID_E.get_data(), + m_UUID_E.get_data_length())); + } + + } + + m_configured = true; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::reset() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + m_device_parameters_valid = false; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: eap_am_type_protected_setup_symbian_c::shutdown(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + if (m_shutdown_was_called == true) + { + // Shutdown function was called already. + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + m_shutdown_was_called = true; + + { + eap_variable_data_c key(m_am_tools); + + eap_status_e status = key.set_copy_of_buffer( + EAP_AM_TYPE_SIMPLE_CONFIG_MEMORY_STORE_KEY, + sizeof(EAP_AM_TYPE_SIMPLE_CONFIG_MEMORY_STORE_KEY)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = key.add_data(&m_is_client, sizeof(m_is_client)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = key.add_data(&m_eap_type, sizeof(m_eap_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + (void) m_am_tools->memory_store_remove_data(&key); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: eap_am_type_protected_setup_symbian_c::shutdown():") + EAPL("credentials removed from eapol\n"))); + + eap_tlv_message_data_c tlv_data(m_am_tools); + + + status = m_am_tools->memory_store_add_data( + &key, + &tlv_data, + eap_type_default_credential_timeout); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_SIMPLE_CONFIG: function: shutdown(): cannot store credentials\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + } + + reset(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +void eap_am_type_protected_setup_symbian_c::send_error_notification(const eap_status_e error) +{ + { + eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error); + + if (error == eap_status_user_cancel_authentication) + { + general_state_variable = eap_general_state_authentication_cancelled; + } + + // Notifies the lower level of an authentication error. + eap_state_notification_c notification( + m_am_tools, + &m_receive_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, + m_eap_type, + eap_state_none, + general_state_variable, + 0, + false); + + notification.set_authentication_error(error); + + m_partner->state_notification(¬ification); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::authentication_finished( + const bool true_when_successfull, + const bool true_when_session_resumed) +{ + EAP_UNREFERENCED_PARAMETER(true_when_successfull); // for release + EAP_UNREFERENCED_PARAMETER(true_when_session_resumed); // for release + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: authentication_finished()\n"), + (m_is_client == true ? "client": "server"))); + + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::query_eap_identity( + const eap_am_network_id_c * const receive_network_id, + const u8_t eap_identifier, + bool * const use_manual_username, + eap_variable_data_c * const manual_username, + bool *const use_manual_realm, + eap_variable_data_c * const manual_realm + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: query_eap_identity()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_process_general_error); + + if (m_use_manual_username == true + && m_manual_username.get_is_valid_data() == true) + { + status = manual_username->set_copy_of_buffer(&m_manual_username); + } + + m_eap_identifier = eap_identifier; + + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: direct_complete_function: complete_eap_identity_query()\n"), + (m_is_client == true ? "client": "server"))); + + status = get_am_partner()->complete_eap_identity_query( + &m_receive_network_id, + m_eap_identifier, + status, + m_use_manual_username, + &m_manual_username, + m_use_manual_realm, + &m_manual_realm); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else //if (status == eap_status_ok) + { + status = eap_status_completed_request; + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::cancel_identity_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: function: cancel_identity_query()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_is_client == true) + { + m_prot_setup_if->Cancel(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_type_protected_setup_symbian_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_type_protected_setup_symbian_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + // Here configuration data must be read from type spesific database (CommsDat). + + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT(data != NULL); + + // Trap must be set here because the OS independent portion of EAP protected setup + // that calls this function does not know anything about Symbian. + + eap_status_e status(eap_status_ok); + + eap_variable_data_c wanted_field(m_am_tools); + eap_variable_data_c type_field(m_am_tools); + + status = wanted_field.set_buffer( + field->get_field(), + field->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = type_field.set_buffer( + cf_str_EAP_SIMPLE_CONFIG_device_password.get_field()->get_field(), + cf_str_EAP_SIMPLE_CONFIG_device_password.get_field()->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (!wanted_field.compare(&type_field)) + { + // We have to get the device password here. It is nothing but the PIN code in PIN based protected setup. + + TRAPD(err, read_device_passwordL( + field->get_field(), + field->get_field_length(), + data)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + } + + m_am_tools->trace_configuration( + status, + field, + data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + + } // if (!wanted_field.compare(&type_field)) + + + // NOTE: This is for simulation. + // Read is routed to partner object. + status = m_partner->read_configure( + field, + data); + + m_am_tools->trace_configuration( + status, + field, + data); + + return status; +} + +//-------------------------------------------------- + +// +void eap_am_type_protected_setup_symbian_c::read_device_passwordL( + eap_config_string /*field*/, + const u32_t /*field_length*/, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Get the things from commsdat here. + + // We need PSK (PIN code for protected setup) from the CommsDat. + // CommDbIf is used to get the PSK. + + CWLanSettings* wlan_settings = new(ELeave) CWLanSettings; + CleanupStack::PushL(wlan_settings); + SWLANSettings wlanSettings; + TInt error(KErrNone); + + // Connect to CommsDat using CommDbIf + error = wlan_settings->Connect(); + if (error != KErrNone) + { + // Could not connect to CommsDat + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("ERROR: eap_am_type_protected_setup_symbian_c::read_device_passwordL() Connecting to CommsDat failed!\n"))); + + User::Leave(KErrCouldNotConnect); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_protected_setup_symbian_c::read_device_passwordL() Connected to CommDbIf.\n"))); + + error = wlan_settings->GetWlanSettingsForService(m_index, wlanSettings); + if ( error != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("ERROR: eap_am_type_protected_setup_symbian_c::read_device_passwordL() GetWlanSettingsForService failed, error=%d\n"), + error)); + + wlan_settings->Disconnect(); + + User::Leave(error); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Protected Setup: Got WLAN settings: wlanSettings.EnableWpaPsk=%d\n"), + wlanSettings.EnableWpaPsk)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WPA-PSK or PIN"), + wlanSettings.WPAPreSharedKey.Ptr(), + wlanSettings.WPAPreSharedKey.Size())); + + if(wlanSettings.WPAPreSharedKey.Size() != 0) + { + // Copy the PSK (PIN for us here) to the data + eap_status_e status = data->set_copy_of_buffer( + wlanSettings.WPAPreSharedKey.Ptr(), + wlanSettings.WPAPreSharedKey.Size()); + + if (status != eap_status_ok) + { + wlan_settings->Disconnect(); + + User::Leave(KErrNoMemory); + } + } + else + { + // NO PIN -> means this is for the PUSH-BUTTON. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("WARNING: ############ NO PIN (WPA-PSK) FOR PROTECTED SETUP -> PUSH-BUTTON ############\n"))); + + m_Device_Password_ID = simple_config_Device_Password_ID_PushButton; + + // This ("00000000") is a temporary password. This is not used since we will try push-button. + // Some value has to be set for this password so that that calling function doesn't return error. + // If nothing is set for the password the calling function takes it as wrong password and + // stops the authentication. + TBuf8<16> asciiString(_L8("00000000")); + eap_status_e status = data->set_copy_of_buffer(asciiString.Ptr(), asciiString.Size()); + if (status != eap_status_ok) + { + wlan_settings->Disconnect(); + + User::Leave(KErrNoMemory); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("WARNING: ############ WE WILL TRY PUSH-BUTTON ############\n"))); + } + + wlan_settings->Disconnect(); + CleanupStack::PopAndDestroy(wlan_settings); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + // Here configuration data must be read from type spesific database. + + // NOTE: This is for simulation. + // Write is routed to partner object. + eap_status_e status = m_partner->write_configure( + field, + data); + return status; +} + +//-------------------------------------------------- + +abs_eap_am_type_simple_config_c * eap_am_type_protected_setup_symbian_c::get_am_partner() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_partner; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::query_network_and_device_parameters( + const simple_config_state_e state) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: eap_am_type_protected_setup_symbian_c::query_network_and_device_parameters()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eap_status_process_general_error; + + m_simple_config_state = state; + + // check if we already have done the query + if( m_device_parameters_valid == true ) + { + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_protected_setup_symbian_c::query_network_and_device_parameters: Parameters exist, completing query immediately."))); + + // pass the parameters + status = get_simple_config_am_partner()->complete_query_network_and_device_parameters( + m_simple_config_state, + &m_network_and_device_parameters, + eap_status_ok); + + if (status == eap_status_ok || + status == eap_status_pending_request) + { + // we completed the request successfully + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + m_network_and_device_parameters.reset(); + + if (m_simple_config_state == simple_config_state_process_simple_config_start) + { + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_UUID_E, + true, + m_UUID_E.get_data(), + m_UUID_E.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + u16_t Authentication_Type( + simple_config_Authentication_Type_Open + | simple_config_Authentication_Type_WPAPSK + | simple_config_Authentication_Type_Shared + | simple_config_Authentication_Type_WPA2PSK); + + u16_t network_order_Authentication_Type(eap_htons(Authentication_Type)); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Authentication_Type_Flags, + true, + &network_order_Authentication_Type, + sizeof(network_order_Authentication_Type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + u16_t Encryption_Type( + simple_config_Encryption_Type_None + | simple_config_Encryption_Type_WEP + | simple_config_Encryption_Type_TKIP + | simple_config_Encryption_Type_AES); + + u16_t network_order_Encryption_Type(eap_htons(Encryption_Type)); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Encryption_Type_Flags, + true, + &network_order_Encryption_Type, + sizeof(network_order_Encryption_Type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + // We support ESS only. + simple_config_Connection_Type_e Connection_Type(simple_config_Connection_Type_ESS); + + u8_t network_order_Encryption_Type(static_cast(Connection_Type)); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Connection_Type_Flags, + true, + &network_order_Encryption_Type, + sizeof(network_order_Encryption_Type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_protected_setup_symbian_c::query_network_and_device_parameters() m_Device_Password_ID=%d\n"), + m_Device_Password_ID)); + + { + // This may be changed in future if more methods need to be supported. + simple_config_Config_Methods_e Config_Methods(simple_config_Config_Methods_Display); + + // At the moment only PIN and PUSH-BUTTON. Default method is PIN. + if(m_Device_Password_ID == simple_config_Device_Password_ID_PushButton) + { + Config_Methods = simple_config_Config_Methods_PushButton; + } + + u16_t network_order_Config_Methods(eap_htons(static_cast(Config_Methods))); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Config_Methods, + true, + &network_order_Config_Methods, + sizeof(network_order_Config_Methods)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + simple_config_State_e State(simple_config_State_Not_Configured); + + u8_t network_order_State(static_cast(State)); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Simple_Config_State, + true, + &network_order_State, + sizeof(network_order_State)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + // See WPS spec for this. + u8_t Primary_Device_Type[] + = { 0x00, 0x0a, + 0x00, 0x50, 0xf2, 0x04, + 0x00, 0x02 }; + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Primary_Device_Type, + true, + Primary_Device_Type, + sizeof(Primary_Device_Type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + // 2.4 GHz band support only. + u8_t RF_Band(simple_config_RF_Bands_2_4_GHz); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_RF_Band, + true, + &RF_Band, + sizeof(RF_Band)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + simple_config_Association_State_e Association_State(simple_config_Association_State_Not_Associated); + + u16_t network_order_Association_State(eap_htons(static_cast(Association_State))); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Association_State, + true, + &network_order_Association_State, + sizeof(network_order_Association_State)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + // This is for authentication based on PIN method or PUSH-BUTTON method. + u16_t network_order_Device_Password_ID(eap_htons(static_cast(m_Device_Password_ID))); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Device_Password_ID, + true, + &network_order_Device_Password_ID, + sizeof(network_order_Device_Password_ID)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + // No need for anything specific here. + u8_t OS_Version[] + = { 0xf0, 0x00, 0x00, 0x01 }; + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_OS_Version, + true, + OS_Version, + sizeof(OS_Version)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Query the device details from the MMETEL connection. + TRAPD(error, m_prot_setup_if->QueryDeviceParametersL()); + if (error != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(error); + if (status == eap_status_process_general_error) + { + status = eap_status_credential_query_failed; + } + + send_error_notification(status); + + // Query failed. + get_simple_config_am_partner()->complete_query_network_and_device_parameters( + m_simple_config_state, + &m_network_and_device_parameters, + status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); // Request is always pending here. +} + +//-------------------------------------------------- + +// This is always synchronous call. +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::save_simple_config_session( + const simple_config_state_e state, + EAP_TEMPLATE_CONST eap_array_c * const credential_array, + const eap_variable_data_c * const new_password, + const simple_config_Device_Password_ID_e Device_Password_ID, + const simple_config_payloads_c * const other_configuration) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: save_simple_config_session()\n"), + (m_is_client == true ? "client": "server"))); + + for (u32_t ind = 0ul; ind < credential_array->get_object_count(); ind++) + { + simple_config_credential_c * const credential = credential_array->get_object(ind); + + if (credential != 0 + && credential->get_is_valid() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: network_index=%d\n"), + credential->get_network_index())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: SSID"), + credential->get_SSID()->get_data(), + credential->get_SSID()->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: Authentication_Type=%d\n"), + credential->get_Authentication_Type())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: Encryption_Type=%d\n"), + credential->get_Encryption_Type())); + + for (u32_t ind = 0ul; ind < credential->get_network_keys()->get_object_count(); ++ind) + { + network_key_and_index_c * const key = credential->get_network_keys()->get_object(ind); + if (key != 0) + { + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: network_key_index=%d\n"), + key->get_network_key_index())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: Key"), + key->get_network_key()->get_data(), + key->get_network_key()->get_data_length())); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: MAC_address"), + credential->get_MAC_address()->get_data(), + credential->get_MAC_address()->get_data_length())); + } + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: new_password"), + new_password->get_data(), + new_password->get_data_length())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: Device_Password_ID=%d\n"), + Device_Password_ID)); + + eap_status_e status = m_configuration_if->save_simple_config_session( + state, + credential_array, + new_password, + Device_Password_ID, + other_configuration); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::received_registrar_information( + EAP_TEMPLATE_CONST eap_array_c * const M2D_payloads) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: received_registrar_information()\n"), + (m_is_client == true ? "client": "server"))); + + eap_simple_config_trace_string_c debug_string; + + for (u32_t ind = 0ul; ind < M2D_payloads->get_object_count(); ind++) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("---------------------------------------------------------------\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("M2D %d\n"), + ind)); + + simple_config_payloads_c * const payloads = M2D_payloads->get_object(ind); + if (payloads == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + const u32_t attribute_count(payloads->get_attribute_count()); + u32_t attribute_index(0ul); + + while (attribute_index < attribute_count) + { + simple_config_variable_data_c * attribute = payloads->get_attribute(attribute_index); + if (attribute == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("%s (0x%08x): TLV type 0x%08x=%s, data length 0x%04x.\n"), + "M2D", (attribute)->get_data((attribute)->get_data_length()), + (attribute)->get_attribute_type(), + debug_string.get_attribute_type_string((attribute)->get_attribute_type()), + (attribute)->get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, + (EAPL("M2D"), (attribute)->get_data((attribute)->get_data_length()), + (attribute)->get_data_length())); + + ++attribute_index; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::cancel_query_network_and_device_parameters() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("SIMPLE_CONFIG: %s: message_function: cancel_query_dh_parameters()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_is_client == true) + { + m_prot_setup_if->Cancel(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::load_module( + const eap_type_value_e eap_type, + const eap_type_value_e tunneling_type, + abs_eap_base_type_c * const partner, + eap_base_type_c ** const eap_type_if, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_protected_setup_symbian_c::load_module(0x%08x)\n"), + convert_eap_type_to_u32_t(eap_type))); + + eap_status_e status = m_partner->load_module( + eap_type, + tunneling_type, + partner, + eap_type_if, + is_client_when_true, + receive_network_id); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::check_is_valid_eap_type(const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_protected_setup_symbian_c::check_is_valid_eap_type(0x%08x)\n"), + convert_eap_type_to_u32_t(eap_type))); + + eap_status_e status = m_partner->check_is_valid_eap_type( + eap_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = m_partner->get_eap_type_list(eap_type_list); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::unload_module(const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_protected_setup_symbian_c::unload_module(0x%08x)\n"), + convert_eap_type_to_u32_t(eap_type))); + + eap_status_e status = m_partner->unload_module( + eap_type); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_protected_setup_symbian_c::complete_protected_setup_device_paramsL( + const RMobilePhone::TMobilePhoneIdentityV1 &phone_identity, + const eap_status_e completion_status ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_process_general_error); + + if (completion_status != eap_status_ok) + { + // Query failed + status = get_simple_config_am_partner()->complete_query_network_and_device_parameters( + m_simple_config_state, + &m_network_and_device_parameters, + completion_status); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + if(phone_identity.iManufacturer.Size() == 0 + || phone_identity.iModel.Size() == 0 + || phone_identity.iRevision.Size() == 0 + || phone_identity.iSerialNumber.Size() == 0 ) + { + // Some identies are missing. + status = get_simple_config_am_partner()->complete_query_network_and_device_parameters( + m_simple_config_state, + &m_network_and_device_parameters, + eap_status_process_general_error); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + // Copy device details to m_network_and_device_parameters + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + HBufC8* attribute_data = HBufC8::NewLC(phone_identity.iManufacturer.Size()); + + TPtr8 attribute_data_Ptr = attribute_data->Des(); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("Attribute data to convert:", + phone_identity.iManufacturer.Ptr(), + phone_identity.iManufacturer.Size())); + + ConvertUnicodeToAsciiL(phone_identity.iManufacturer, attribute_data_Ptr); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Manufacturer, + true, + attribute_data_Ptr.Ptr(), + attribute_data_Ptr.Size()); + + CleanupStack::PopAndDestroy(attribute_data); + + if (status != eap_status_ok) + { + status = get_simple_config_am_partner()->complete_query_network_and_device_parameters( + m_simple_config_state, + &m_network_and_device_parameters, + eap_status_process_general_error); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + HBufC8* attribute_data = HBufC8::NewLC(phone_identity.iModel.Size()); + + TPtr8 attribute_data_Ptr = attribute_data->Des(); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("Attribute data to convert:", + phone_identity.iModel.Ptr(), + phone_identity.iModel.Size())); + + ConvertUnicodeToAsciiL(phone_identity.iModel, attribute_data_Ptr); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Model_Name, + true, + attribute_data_Ptr.Ptr(), + attribute_data_Ptr.Size()); + + if (status != eap_status_ok) + { + CleanupStack::PopAndDestroy(attribute_data); + + status = get_simple_config_am_partner()->complete_query_network_and_device_parameters( + m_simple_config_state, + &m_network_and_device_parameters, + eap_status_process_general_error); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Use model as the device name as well + // since there is nothing better for the purpose. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_protected_setup_symbian_c::complete_protected_setup_device_paramsL: Uses model as device name."))); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Device_Name, + true, + attribute_data_Ptr.Ptr(), + attribute_data_Ptr.Size()); + + CleanupStack::PopAndDestroy(attribute_data); + + if (status != eap_status_ok) + { + status = get_simple_config_am_partner()->complete_query_network_and_device_parameters( + m_simple_config_state, + &m_network_and_device_parameters, + eap_status_process_general_error); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + HBufC8* attribute_data = HBufC8::NewLC(phone_identity.iRevision.Size()); + + TPtr8 attribute_data_Ptr = attribute_data->Des(); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("Attribute data to convert:", + phone_identity.iRevision.Ptr(), + phone_identity.iRevision.Size())); + + ConvertUnicodeToAsciiL(phone_identity.iRevision, attribute_data_Ptr); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Model_Number, + true, + attribute_data_Ptr.Ptr(), + attribute_data_Ptr.Size()); + + CleanupStack::PopAndDestroy(attribute_data); + + if (status != eap_status_ok) + { + status = get_simple_config_am_partner()->complete_query_network_and_device_parameters( + m_simple_config_state, + &m_network_and_device_parameters, + eap_status_process_general_error); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + { + HBufC8* attribute_data = HBufC8::NewLC(phone_identity.iSerialNumber.Size()); + + TPtr8 attribute_data_Ptr = attribute_data->Des(); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("Attribute data to convert:", + phone_identity.iSerialNumber.Ptr(), + phone_identity.iSerialNumber.Size())); + + ConvertUnicodeToAsciiL(phone_identity.iSerialNumber, attribute_data_Ptr); + + status = m_network_and_device_parameters.copy_attribute_data( + simple_config_Attribute_Type_Serial_Number, + true, + attribute_data_Ptr.Ptr(), + attribute_data_Ptr.Size()); + + CleanupStack::PopAndDestroy(attribute_data); + + if (status != eap_status_ok) + { + status = get_simple_config_am_partner()->complete_query_network_and_device_parameters( + m_simple_config_state, + &m_network_and_device_parameters, + eap_status_process_general_error); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Ok So far. Complete the request succesfully. + + status = get_simple_config_am_partner()->complete_query_network_and_device_parameters( + m_simple_config_state, + &m_network_and_device_parameters, + completion_status); + + if( status == eap_status_ok ) + { + // save the state + // no need to fetch the parameters again + m_device_parameters_valid = true; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; +} + +//-------------------------------------------------- + +void eap_am_type_protected_setup_symbian_c::ConvertUnicodeToAsciiL(const TDesC16& aFromUnicode, TDes8& aToAscii) +{ + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_protected_setup_symbian_c::ConvertUnicodeToAsciiL:From TEXT", + aFromUnicode.Ptr(), + aFromUnicode.Size())); + + if(aFromUnicode.Length() <= 0) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_protected_setup_symbian_c::ConvertUnicodeToAsciiL: Return: NOTHING TO CONVERT"))); + + return; + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_protected_setup_symbian_c::ConvertUnicodeToAsciiL, aFromUnicode.Length=%d, aFromUnicode.Size=%d"), + aFromUnicode.Length(), aFromUnicode.Size())); + + // Convert from Unicode to ascii. + HBufC8* aFromUnicodeBuf8 = HBufC8::NewLC(aFromUnicode.Length()); // Half times size of source (or length) is enough here. + TPtr8 aFromUnicodePtr8 = aFromUnicodeBuf8->Des(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_protected_setup_symbian_c::ConvertUnicodeToAsciiL, aFromUnicodePtr8.Length=%d, aFromUnicodePtr8.Size=%d, aFromUnicodePtr8.MaxLength=%d, aFromUnicodePtr8.MaxSize=%d"), + aFromUnicodePtr8.Length(), aFromUnicodePtr8.Size(), aFromUnicodePtr8.MaxLength(), aFromUnicodePtr8.MaxSize())); + + aFromUnicodePtr8.Copy(aFromUnicode); // Unicode -> ascii. + + aToAscii = aFromUnicodePtr8; + + CleanupStack::PopAndDestroy(aFromUnicodeBuf8); // Delete aFromUnicodeBuf8. + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_protected_setup_symbian_c::ConvertUnicodeToAsciiL:To ASCII", + aToAscii.Ptr(), + aToAscii.Size())); +} + +//-------------------------------------------------- + +// End of file. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/protected_setup/symbian/plugin/inc/EapProtectedSetup.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/protected_setup/symbian/plugin/inc/EapProtectedSetup.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,148 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPPROTECTEDSETUP_H_ +#define _EAPPROTECTEDSETUP_H_ + +// INCLUDES +#include +#include "eap_header.h" + +// CLASS DECLARATION +/** +* Class that implements the generic EAP type interface for EAP protected setup (EAP-WSC). +*/ +class CEapProtectedSetup : public CEapType +{ +public: + + /** + * Construction function for EAP Protected setup. Called by ECom after the DLL has been loaded. + * @param aIapInfo Pointer to the class that contains information about bearer type and unique index. + * @return Pointer to the instance. + */ + static CEapProtectedSetup* NewL(SIapInfo *aIapInfo); + + /** + * Destructor does nothing. + */ + virtual ~CEapProtectedSetup(); + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @param eap_config_if Pointer used for call back to creater of stack (eapol_am_wlan_authentication_symbian_c class). + * @return Pointer to the implementation. + */ + virtual eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if); + + /** + * Invokes the configuration UI. This doesn't do anything. + **/ + TInt InvokeUiL(); + + /** + * Gets information about EAP type. + * @return Pointer to a class that contains the EAP type information. Also pushed to cleanup stack. + */ + CEapTypeInfo* GetInfoLC(); + + /** + * Deletes EAP type configuration + */ + void DeleteConfigurationL(); + + /** + * Returns the version of the interface that the EAP type implements. + * The client-side of the interface must always check the version with this function + * and not call the functions that are not implemented. New functions must be + * added to the end of the interface so that the order of the old functions + * does not change. + * @return Integer indicating the version. + */ + TUint GetInterfaceVersion(); + + /** + * Sets the tunneling type. This is used to indicate that this type is run inside another + * EAP type. + * @param aTunnelingType Type number for the tunneling type + */ + void SetTunnelingType(const TInt aTunnelingType); + + /** + * Changes the index of the saved parameters. + * @param aIndexType Indicates the bearer used for this connection. + * @param aIndex Index for the connection. aIndexType and aIndex uniquely specify the connection. + */ + void SetIndexL( + const TIndexType aIndexType, + const TInt aIndex); + + /** + * Sets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void SetConfigurationL(const EAPSettings& aSettings); + + /** + * Gets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void GetConfigurationL(EAPSettings& aSettings); + + /** + * Copies the EAP types configuration + * @param aDestinationIndex ID to where copy the settings. + */ + void CopySettingsL(const TIndexType aDestinationIndexType, const TInt aDestinationIndex); + +protected: + + /** + * Constructor initialises member variables. + */ + CEapProtectedSetup(const TIndexType aIndexType, const TInt aIndex); + +private: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // Tunneling type + eap_type_value_e iTunnelingType; + + // EAP array for deleting and changing index + RImplInfoPtrArray iEapArray; +}; + +#endif // _EAPPROTECTEDSETUP_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/protected_setup/symbian/plugin/inc/EapProtectedSetupGlobal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/protected_setup/symbian/plugin/inc/EapProtectedSetupGlobal.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPPROTECTEDSETUPGLOBAL_H_ +#define _EAPPROTECTEDSETUPGLOBAL_H_ + +// LOCAL CONSTANTS + +// Release date must be of format YYYYMMDD:. Will be localised automatically. +// Note that days and months start from 0. +_LIT(KReleaseDate, "20070528:"); +_LIT(KEapTypeVersion, "1.0"); +_LIT(KManufacturer, "Nokia"); +_LIT(KNokiaSignature, ""); // Not used +_LIT(KExtraInfo1, ""); // Not used +_LIT(KExtraInfo2, ""); // Not used + +#endif // _EAPPROTECTEDSETUPGLOBAL_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/protected_setup/symbian/plugin/src/2000b003.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/protected_setup/symbian/plugin/src/2000b003.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2000 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource definitions for Protected Setup plugin +* +*/ + + + +// INCLUDES +#include +#include "EapolUID.h" + +// RESOURCE DEFINITIONS +// --------------------------------------------------------- +// +// theInfo +// Contains the ECom registration information for EAP SIM +// +// --------------------------------------------------------- +// +RESOURCE REGISTRY_INFO theInfo +{ +dll_uid = EAP_PROTECTED_SETUP_DLL_UID; +interfaces = + { + INTERFACE_INFO + { + interface_uid = PLUGIN_INTERFACE_UID; + implementations = + { + + BINARY_IMPLEMENTATION_INFO + { + implementation_uid = EAP_PROTECTED_SETUP_IMPLEMENTATION_UID; + version_no = 1; + display_name = "Protected Setup"; + default_data = {0xFE, 0x00, 0x37, 0x2A, 0x00, 0x00, 0x00, 0x01}; // WSC (Protected Setup) + opaque_data = {0x5F}; // Should NOT be shown any where. "NOT_INSIDE|NOT_INSIDE_PEAP|NOT_INSIDE_TTLS|NOT_INSIDE_FAST|NOT_OUTSIDE_PEAP|NOT_OUTSIDE" + } + }; + } + }; +} +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/protected_setup/symbian/plugin/src/EapProtectedSetup.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/protected_setup/symbian/plugin/src/EapProtectedSetup.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,269 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 176 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "EapProtectedSetup.h" +#include "eap_base_type.h" +#include "simple_config_types.h" +#include "eap_type_simple_config.h" +#include "simple_config_record.h" +#include "abs_eap_configuration_if.h" + +#include +#include "eap_am_type_protected_setup_symbian.h" +#include "EapProtectedSetupGlobal.h" +#include "eap_am_trace_symbian.h" + +//#include "EapAkaDbUtils.h" + +#include "eap_am_tools_symbian.h" + +// LOCAL CONSTANTS + +// The version number of this interface. +const TUint KInterfaceVersion = 1; + + +// ================= MEMBER FUNCTIONS ======================= + + +CEapProtectedSetup::CEapProtectedSetup(const TIndexType aIndexType, + const TInt aIndex) +: iIndexType(aIndexType) +, iIndex(aIndex) +, iTunnelingType(eap_type_none) +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapProtectedSetup::CEapProtectedSetup index type=%d, index=%d, tunneling type=%d"), + iIndexType, iIndex, iTunnelingType.get_vendor_type())); + +} + +// ---------------------------------------------------------- + +CEapProtectedSetup* CEapProtectedSetup::NewL(SIapInfo *aIapInfo) +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapProtectedSetup::NewL index type=%d, index=%d"), + aIapInfo->indexType, aIapInfo->index)); + + return new (ELeave) CEapProtectedSetup(aIapInfo->indexType, aIapInfo->index); +} + +// ---------------------------------------------------------- + +CEapProtectedSetup::~CEapProtectedSetup() +{ +} + +// ---------------------------------------------------------- + +eap_base_type_c* CEapProtectedSetup::GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if) +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapProtectedSetup::GetStackInterfaceL - Start"))); + + // Create AM + eap_am_type_protected_setup_symbian_c* amEapType = eap_am_type_protected_setup_symbian_c::NewL( + aTools, + aPartner, + iIndexType, + iIndex, + iTunnelingType, + eap_expanded_type_simple_config.get_type(), + is_client_when_true, + receive_network_id, + configuration_if); + + if (amEapType == 0 || amEapType->get_is_valid() == false) + { + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("ERROR: GetStackInterfaceL : eap_am_type_protected_setup_symbian_c(): failed."))); + + delete amEapType; + User::Leave(KErrNoMemory); + } + + simple_config_record_c* simple_config_record = new simple_config_record_c( + aTools, + amEapType, + false /* NO Free */, + is_client_when_true, + receive_network_id); + + if (simple_config_record == 0 + || simple_config_record->get_is_valid() == false) + { + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("ERROR: GetStackInterfaceL : simple_config_record_c(): failed."))); + + EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT); + + delete simple_config_record; + User::Leave(KErrNoMemory); + } + + eap_base_type_c* type = 0; + + type = new eap_type_simple_config_c( + aTools, + aPartner, + amEapType, + true, /* Free AM */ + simple_config_record, + true, /*Free record*/ + is_client_when_true, + eap_expanded_type_simple_config.get_type(), // This gets the EAP type (Protected Setup) . + receive_network_id); + + if (type == 0) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("ERROR: GetStackInterfaceL : eap_type_simple_config_c(): failed."))); + + // Out of memory + amEapType->shutdown(); + delete amEapType; + + simple_config_record->shutdown(); + delete simple_config_record; + + User::Leave(KErrNoMemory); + } + else if (type->get_is_valid() == false) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("ERROR: GetStackInterfaceL : type->get_is_valid(): not valid."))); + + type->shutdown(); + // amEapType is freed by eap_type_simple_config_c + delete type; + + User::Leave(KErrGeneral); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapProtectedSetup::GetStackInterfaceL - End"))); + + return type; +} + +// ---------------------------------------------------------- +TInt CEapProtectedSetup::InvokeUiL() +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("ERROR: CEapProtectedSetup::InvokeUiL - THIS IS NOT SUPPORTED"))); + + TInt buttonId(0); + + // This is a dummy function. + + return buttonId; +} + +// ---------------------------------------------------------- +CEapTypeInfo* CEapProtectedSetup::GetInfoLC() +{ + CEapTypeInfo* info = new(ELeave) CEapTypeInfo( + (TDesC&)KReleaseDate, + (TDesC&)KEapTypeVersion, + (TDesC&)KManufacturer); + + CleanupStack::PushL(info); + return info; +} + +// ---------------------------------------------------------- +void CEapProtectedSetup::DeleteConfigurationL() +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("ERROR: CEapProtectedSetup::DeleteConfigurationL - THIS IS NOT SUPPORTED"))); +} + +// ---------------------------------------------------------- + +TUint CEapProtectedSetup::GetInterfaceVersion() +{ + return KInterfaceVersion; +} + +// ---------------------------------------------------------- + +void CEapProtectedSetup::SetTunnelingType(const TInt aTunnelingType) +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapProtectedSetup::SetTunnelingType - tunneling type=%d"), + aTunnelingType)); + + // Vendor id is eap_type_vendor_id_ietf always in this plugin. + iTunnelingType.set_eap_type_values(eap_type_vendor_id_ietf, aTunnelingType); +} + + +// ---------------------------------------------------------- +void CEapProtectedSetup::SetIndexL( + const TIndexType /*aIndexType*/, + const TInt /*aIndex*/ ) +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("ERROR: CEapProtectedSetup::SetIndexL - THIS IS NOT SUPPORTED"))); +} + +// ---------------------------------------------------------- + +void CEapProtectedSetup::SetConfigurationL(const EAPSettings& /*aSettings*/) +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("ERROR: CEapProtectedSetup::SetConfigurationL - THIS IS NOT SUPPORTED"))); +} + +// ---------------------------------------------------------- + +void CEapProtectedSetup::GetConfigurationL(EAPSettings& /*aSettings*/) +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("ERROR: CEapProtectedSetup::GetConfigurationL - THIS IS NOT SUPPORTED"))); +} + +// ---------------------------------------------------------- + +void CEapProtectedSetup::CopySettingsL( + const TIndexType /*aDestinationIndexType*/, + const TInt /*aDestinationIndex*/) +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("ERROR: CEapProtectedSetup::CopySettingsL - THIS IS NOT SUPPORTED"))); +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/protected_setup/symbian/plugin/src/EapProtectedSetupProxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/protected_setup/symbian/plugin/src/EapProtectedSetupProxy.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 178 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include "EapProtectedSetup.h" +#include +#include +#include "EapolUID.h" + +const TImplementationProxy ImplementationTable[] = +{ + {{EAP_PROTECTED_SETUP_IMPLEMENTATION_UID}, reinterpret_cast (CEapProtectedSetup::NewL)} +}; + +// ================= OTHER EXPORTED FUNCTIONS ============== + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) +{ + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + + return ImplementationTable; +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/eap_am_type_securid_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/eap_am_type_securid_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1326 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 311 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include +#include +#include + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_type_securid_symbian.h" +#include "EapSecurIDDbParameterNames.h" +#include "EapSecurIDDbUtils.h" +#include "EapSecurIDNotifierStructs.h" +#include "EapGtcDbParameterNames.h" +#include "EapGtcDbUtils.h" +#include "EapSecurIDNotifierUids.h" +#include "eap_configuration_field.h" +#include "eap_state_notification.h" + +#include "eap_am_trace_symbian.h" + +const TUint KMaxSqlQueryLength = 256; +const TUint KMaxDBFieldNameLength = 255; +const char EAP_GTC_USERNAME_HANDLE_KEY[] = "eap_type_securid_c GTC username"; +const TInt KDefaultColumnInView_One = 1; // For DB view. +const TInt KMicroSecsInASecond = 1000000; // 1000000 micro seconds is 1 second. + +// ================= MEMBER FUNCTIONS ======================= + +EAP_FUNC_EXPORT eap_am_type_securid_symbian_c::~eap_am_type_securid_symbian_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_securid_symbian_c::~eap_am_type_securid_symbian_c(): this = 0x%08x\n"), + this)); + + EAP_ASSERT(m_shutdown_was_called == true); + + m_database.Close(); + m_session.Close(); + + delete m_dialog_data_ptr; + delete m_dialog_data_pckg_ptr; + delete m_message_buf; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_securid_symbian_c::shutdown() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_securid_symbian_c::shutdown(): this = 0x%08x\n"), + this)); + + if( IsActive() ) + { + Cancel(); // Cancel only if active. + } + else + { + if( m_is_notifier_connected ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::shutdown - calling m_notifier.CancelNotifier(..)\n"))); + + TInt error = m_notifier.CancelNotifier(KEapSecurIDIdentityQueryUid); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::shutdown - CancelNotifier(KEapSecurIDIdentityQueryUid) error=%d\n"), error)); + + + error = m_notifier.CancelNotifier(KEapSecurIDPasscodeQueryUid); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::shutdown - CancelNotifier(KEapSecurIDPasscodeQueryUid) error=%d\n"), error)); + + + error = m_notifier.CancelNotifier(KEapSecurIDPincodeQueryUid); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::shutdown - CancelNotifier(KEapSecurIDPincodeQueryUid) error=%d\n"), error)); + + + error = m_notifier.CancelNotifier(KEapGtcIdentityQueryUid); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::shutdown - CancelNotifier(KEapGtcIdentityQueryUid) error=%d\n"), error)); + + + error = m_notifier.CancelNotifier(KEapGtcUserInputQueryUid); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::shutdown - CancelNotifier(KEapGtcUserInputQueryUid) error=%d\n"), error)); + + + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::shutdown - calling m_notifier.Close(), prev error=%d\n"), error)); + + m_notifier.Close(); // Call close only if it is connected. + + m_is_notifier_connected = false; + } + } + + m_shutdown_was_called = true; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_securid_symbian_c::shutdown(): this = 0x%08x returns\n"), + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +eap_am_type_securid_symbian_c::eap_am_type_securid_symbian_c( + abs_eap_am_tools_c * const tools, + abs_eap_base_type_c * const partner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id) + : CActive(CActive::EPriorityStandard) + , eap_am_type_securid_c(tools /*, partner */) + , m_state(EHandlingIdentityQuery) + , m_am_tools(tools) + , m_partner(partner) + , m_receive_network_id(tools) + , m_index_type(aIndexType) + , m_index(aIndex) + , m_tunneling_type(aTunnelingType) + , m_is_client(aIsClient) + , m_is_valid(false) + , m_shutdown_was_called(false) + , m_eap_type(aEapType) + , m_is_notifier_connected(false) + , m_max_session_time(0) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#ifdef USE_EAP_EXPANDED_TYPES + + m_tunneling_vendor_type = m_tunneling_type.get_vendor_type(); + m_eap_vendor_type = m_eap_type.get_vendor_type(); + +#else + + m_tunneling_vendor_type = static_cast(m_tunneling_type); + m_eap_vendor_type = static_cast(m_eap_type); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + if (receive_network_id != 0 + && receive_network_id->get_is_valid_data() == true) + { + eap_status_e status = m_receive_network_id.set_copy_of_network_id( + receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +eap_am_type_securid_symbian_c* eap_am_type_securid_symbian_c::NewL( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id) +{ + eap_am_type_securid_symbian_c * self = new(ELeave) eap_am_type_securid_symbian_c( + aTools, + aPartner, + aIndexType, + aIndex, + aTunnelingType, + aEapType, + aIsClient, + receive_network_id); + + CleanupStack::PushL(self); + + if (self->get_is_valid() != true) + { + User::Leave(KErrGeneral); + } + + self->ConstructL(); + + CleanupStack::Pop(); + + return self; +} + +//-------------------------------------------------- + +void eap_am_type_securid_symbian_c::ConstructL() +{ + // Open/create database + if (m_eap_type == eap_type_generic_token_card) + { + EapGtcDbUtils::OpenDatabaseL(m_database, m_session, m_index_type, m_index, m_tunneling_type); + } + else + { + EapSecurIDDbUtils::OpenDatabaseL(m_database, m_session, m_index_type, m_index, m_tunneling_type); + } + + m_dialog_data_ptr = new(ELeave) TEapSecurIDStruct; + m_dialog_data_pckg_ptr = new(ELeave) TPckg (*m_dialog_data_ptr); + + CActiveScheduler::Add(this); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_type_securid_symbian_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_am_type_securid_symbian_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +void eap_am_type_securid_symbian_c::send_error_notification(const eap_status_e error) +{ + eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error); + + if (error == eap_status_user_cancel_authentication) + { + general_state_variable = eap_general_state_authentication_cancelled; + } + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + // Notifies the lower level of an authentication error. + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, + m_eap_type, + eap_state_none, + general_state_variable, + 0, + false); + + notification.set_authentication_error(error); + + m_partner->state_notification(¬ification); +} + +//-------------------------------------------------- + +void eap_am_type_securid_symbian_c::RunL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_securid_symbian_c::RunL - start") + EAPL("m_state, iStatus.Int()=%d\n"), + m_state, iStatus.Int())); + + if (iStatus.Int() == KErrCancel) + { + delete m_message_buf; + m_message_buf = NULL; + get_am_partner()->finish_unsuccessful_authentication(true); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (iStatus.Int() != KErrNone) + { + delete m_message_buf; + m_message_buf = NULL; + // Something is very wrong... + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP - SecurID notifier or dialog\n"))); + + send_error_notification(eap_status_authentication_failure); + + get_am_partner()->finish_unsuccessful_authentication(false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + switch (m_state) + { + case EHandlingIdentityQuery: + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_securid_symbian_c::RunL(): EHandlingIdentityQuery\n"))); + + eap_variable_data_c identity(m_am_tools); + + eap_status_e status = identity.set_copy_of_buffer( + m_dialog_data_ptr->iIdentity.Ptr(), + m_dialog_data_ptr->iIdentity.Size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + eap_variable_data_c identity_utf8(m_am_tools); + status = m_am_tools->convert_unicode_to_utf8(identity_utf8, identity); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + status = get_am_partner()->complete_eap_identity_query(&identity_utf8); + } + break; + + case EHandlingPasscodeQuery: + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_securid_symbian_c::RunL(): EHandlingPasscodeQuery\n"))); + + eap_variable_data_c passcode(m_am_tools); + + eap_status_e status = passcode.set_copy_of_buffer( + m_dialog_data_ptr->iPasscode.Ptr(), + m_dialog_data_ptr->iPasscode.Size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + eap_variable_data_c passcode_utf8(m_am_tools); + status = m_am_tools->convert_unicode_to_utf8(passcode_utf8, passcode); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + status = get_am_partner()->client_securid_complete_passcode_query(&passcode_utf8); + } + break; + + case EHandlingPincodeQuery: + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_securid_symbian_c::RunL(): EHandlingPincodeQuery\n"))); + + eap_variable_data_c pincode(m_am_tools); + + eap_status_e status = pincode.set_copy_of_buffer( + m_dialog_data_ptr->iPincode.Ptr(), + m_dialog_data_ptr->iPincode.Size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + eap_variable_data_c passcode(m_am_tools); + + status = passcode.set_copy_of_buffer( + m_dialog_data_ptr->iPasscode.Ptr(), + m_dialog_data_ptr->iPasscode.Size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + + eap_variable_data_c pincode_utf8(m_am_tools); + status = m_am_tools->convert_unicode_to_utf8(pincode_utf8, pincode); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + eap_variable_data_c passcode_utf8(m_am_tools); + status = m_am_tools->convert_unicode_to_utf8(passcode_utf8, passcode); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + status = get_am_partner()->client_securid_complete_pincode_query(&passcode_utf8, &passcode_utf8); + } + break; + + case EHandlingGTCQuery: + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_securid_symbian_c::RunL(): EHandlingGTCQuery\n"))); + + delete m_message_buf; + m_message_buf = NULL; + + eap_variable_data_c passcode(m_am_tools); + + eap_status_e status = passcode.set_copy_of_buffer( + m_dialog_data_ptr->iPasscode.Ptr(), + m_dialog_data_ptr->iPasscode.Size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + eap_variable_data_c passcode_utf8(m_am_tools); + status = m_am_tools->convert_unicode_to_utf8(passcode_utf8, passcode); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, status); + return; + } + + // User must have entered some password and pressed OK. + // Treat this as a full authentication and update the Last Auth Time. + status = store_authentication_time(); + if (status != eap_status_ok) + { + // Storing failed. Don't care. + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_securid_symbian_c:Storing Last Full Authentication time failed, status=%d, but continuing\n"), + status)); + + status = eap_status_ok; + } + + status = get_am_partner()->client_gtc_complete_user_input_query(&passcode_utf8); + } + break; + + default: + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP - SecurID illegal state in RunL.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void eap_am_type_securid_symbian_c::DoCancel() +{ + if( m_is_notifier_connected ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::DoCancel - calling m_notifier.CancelNotifier(..)\n"))); + + TInt error = m_notifier.CancelNotifier(KEapSecurIDIdentityQueryUid); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::DoCancel - CancelNotifier(KEapSecurIDIdentityQueryUid) error=%d\n"), error)); + + error = m_notifier.CancelNotifier(KEapSecurIDPasscodeQueryUid); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::DoCancel - CancelNotifier(KEapSecurIDPasscodeQueryUid) error=%d\n"), error)); + + error = m_notifier.CancelNotifier(KEapSecurIDPincodeQueryUid); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::DoCancel - CancelNotifier(KEapSecurIDPincodeQueryUid) error=%d\n"), error)); + + error = m_notifier.CancelNotifier(KEapGtcIdentityQueryUid); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::DoCancel - CancelNotifier(KEapGtcIdentityQueryUid) error=%d\n"), error)); + + error = m_notifier.CancelNotifier(KEapGtcUserInputQueryUid); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::DoCancel - CancelNotifier(KEapGtcUserInputQueryUid) error=%d\n"), error)); + + m_notifier.Close(); // Call close only if it is connected. + + m_is_notifier_connected = false; + } +} + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e eap_am_type_securid_symbian_c::type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT(data != 0); + // Trap must be set here because the OS independent portion of EAP SecurID + // that calls this function does not know anything about Symbian. + eap_status_e status(eap_status_ok); + TRAPD(err, type_configure_readL( + field->get_field(), + field->get_field_length(), + data)); + if (err != KErrNone) + { + // Read is routed to partner object, for reading from configuration file. + status = m_partner->read_configure( + field, + data); + } + + m_am_tools->trace_configuration( + status, + field, + data); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_securid_symbian_c::type_configure_readL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(field_length); + + // Create a buffer for the ascii strings - initialised with the argument + HBufC16* unicodeBuf = HBufC16::NewLC(KMaxDBFieldNameLength); + TPtr16 unicodeString = unicodeBuf->Des(); + + TPtrC8 fieldPtr(reinterpret_cast (field), field_length); + + unicodeString.Copy(fieldPtr); + + // Now do the database query + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + if (m_eap_type == eap_type_securid) + { + sqlStatement.Format(KSQLQueryRow, &unicodeString, &KSecurIDTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + } + else + { + sqlStatement.Format(KSQLQueryRow, &unicodeString, &KGtcTableName, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + } + RDbView view; + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + if (view.FirstL()) + { + eap_status_e status = eap_status_ok; + view.GetL(); + + switch (view.ColType(KDefaultColumnInView_One)) + { + case EDbColText: + { + if (view.ColLength(KDefaultColumnInView_One) > 0) + { + TPtrC16 value = view.ColDes16(KDefaultColumnInView_One); + + eap_variable_data_c string_unicode(m_am_tools); + + status = string_unicode.set_copy_of_buffer(value.Ptr(), value.Size()); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + + status = m_am_tools->convert_unicode_to_utf8( + *data, + string_unicode); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + } + else + { + data->reset(); + status = data->set_copy_of_buffer("", 0); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + } + } + break; + + case EDbColUint32: + { + TUint value = view.ColUint32(KDefaultColumnInView_One); + status = data->set_copy_of_buffer(reinterpret_cast (&value), sizeof(value)); + if (status != eap_status_ok) + { + User::Leave( + m_am_tools->convert_eapol_error_to_am_error( + EAP_STATUS_RETURN(m_am_tools, status))); + } + } + break; + + default: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Unexpected column type.\n"))); + User::Leave(KErrGeneral); + break; + } + } + else + { + // Could not find parameter + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Could not find configuration parameter.\n"))); + User::Leave(KErrArgument); + } + + CleanupStack::PopAndDestroy(3); // Close view, 2 x buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_securid_symbian_c::type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + // NOTE: At the moment this is not called anywhere. + // NOTE: This is really just for simulation. + // Write is routed to partner object. + eap_status_e status = m_partner->write_configure( + field, + data); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_securid_symbian_c::configure() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + { + // Read Maximum Session Validity Time from the config file + eap_variable_data_c sessionTimeFromFile(m_am_tools); + + eap_status_e status = m_partner->read_configure( + cf_str_EAP_GTC_max_session_validity_time.get_field(), + &sessionTimeFromFile); + + if (status == eap_status_ok + && sessionTimeFromFile.get_is_valid_data() == true + && sessionTimeFromFile.get_data_length() == sizeof(u32_t)) + { + u32_t *session = reinterpret_cast(sessionTimeFromFile.get_data()); + if (session != 0) + { + // Update the max session time (in micro seconds). + // configuration file saves the time in seconds. We have to convert it to micro seconds. + m_max_session_time = static_cast(*session) * static_cast(KMicroSecsInASecond); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return eap_status_ok; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_securid_symbian_c::reset() +{ + return eap_status_ok; +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_securid_symbian_c::show_identity_query_dialog( + eap_type_value_e eap_type, + eap_variable_data_c * const identity) +{ + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_securid_symbian_c::show_identity_query_dialog()\n"))); + + EAP_UNREFERENCED_PARAMETER(eap_type); + EAP_UNREFERENCED_PARAMETER(identity); + + // This function gets called only if the identity (username) is missing from the + // user configuration. Probably user/device management hasn't configured it. + + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP - SecurID - No Identity (username) \n"))); + + send_error_notification(eap_status_identity_query_failed); + + return eap_status_identity_query_failed; +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_securid_symbian_c::show_passcode_query_dialog( + eap_variable_data_c * const /*passcode*/, + bool is_first_query) +{ + if (!IsActive()) + { + m_state = EHandlingPasscodeQuery; + + if (is_first_query == true) + { + m_dialog_data_ptr->iIsFirstQuery = ETrue; + } + else + { + m_dialog_data_ptr->iIsFirstQuery = EFalse; + } + + if( !m_is_notifier_connected ) + { + TInt error = m_notifier.Connect(); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::show_passcode_query_dialog - m_notifier.Connect() returned error=%d\n"), error)); + + if( error != KErrNone) + { + // Can not connect to notifier. + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(error)); + } + + m_is_notifier_connected = true; // Got connectted to notifier. + } + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::show_passcode_query_dialog - StartNotifierAndGetResponse - KEapSecurIDPasscodeQueryUid \n"))); + + m_notifier.StartNotifierAndGetResponse( + iStatus, + KEapSecurIDPasscodeQueryUid, + *m_dialog_data_pckg_ptr, + *m_dialog_data_pckg_ptr); + + SetActive(); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_securid_symbian_c: Already active when tried to show passcode query dialog.\n"))); + return eap_status_process_general_error; + } + + return eap_status_pending_request; +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_securid_symbian_c::show_gtc_query_dialog( + eap_variable_data_c * const /*passcode*/, + const u8_t * const message, + u32_t message_length, + bool is_first_query) +{ + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_securid_symbian_c::show_gtc_query_dialog: message"), + message, + message_length)); + + if (!IsActive()) + { + m_state = EHandlingGTCQuery; + + eap_variable_data_c message_utf8(m_am_tools); + eap_status_e status = message_utf8.set_buffer(message, message_length, false, false); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c message_unicode(m_am_tools); + status = m_am_tools->convert_utf8_to_unicode(message_unicode, message_utf8); + if (status != eap_status_ok) + { + return EAP_STATUS_RETURN(m_am_tools, status); + } + + TRAPD(err, m_message_buf = HBufC8::NewL(message_unicode.get_data_length())); + if (err != KErrNone) + { + return eap_status_allocation_error; + } + TPtr8 messageBufPtr = m_message_buf->Des(); + messageBufPtr.Copy(message_unicode.get_data(), message_unicode.get_data_length()); + + if (is_first_query == true) + { + m_dialog_data_ptr->iIsFirstQuery = ETrue; + } + else + { + m_dialog_data_ptr->iIsFirstQuery = EFalse; + } + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::show_gtc_query_dialog - before m_notifier.Connect(), m_is_notifier_connected=%d\n"), m_is_notifier_connected)); + + if( !m_is_notifier_connected ) + { + TInt error = m_notifier.Connect(); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::show_gtc_query_dialog - m_notifier.Connect() returned error=%d\n"), error)); + + if( error != KErrNone) + { + // Can not connect to notifier. + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(error)); + } + + m_is_notifier_connected = true; // Got connectted to notifier. + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_securid_symbian_c::show_gtc_query_dialog: m_message_buf"), + m_message_buf->Ptr(), + m_message_buf->Size())); + + m_notifier.StartNotifierAndGetResponse( + iStatus, + KEapGtcUserInputQueryUid, + *m_message_buf, + *m_dialog_data_pckg_ptr); + + SetActive(); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_securid_symbian_c: Already active when tried to show GTC query dialog.\n"))); + return eap_status_process_general_error; + } + + return eap_status_pending_request; +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_securid_symbian_c::show_pincode_query_dialog( + eap_variable_data_c * const /*passcode*/, + eap_variable_data_c * const /*pincode*/, + bool is_first_query) +{ + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::_pincode_query_dialog - start - is_first_query=%d\n"), is_first_query)); + + if (!IsActive()) + { + m_state = EHandlingPincodeQuery; + + if (is_first_query == true) + { + m_dialog_data_ptr->iIsFirstQuery = ETrue; + } + else + { + m_dialog_data_ptr->iIsFirstQuery = EFalse; + } + + if( !m_is_notifier_connected ) + { + TInt error = m_notifier.Connect(); + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::show_pincode_query_dialog - m_notifier.Connect() returned error=%d\n"), error)); + + if( error != KErrNone) + { + // Can not connect to notifier. + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(error)); + } + + m_is_notifier_connected = true; // Got connectted to notifier. + } + + EAP_TRACE_DEBUG_SYMBIAN((_L(" eap_am_type_securid_symbian_c::show_pincode_query_dialog - StartNotifierAndGetResponse - KEapSecurIDPincodeQueryUid \n"))); + + m_notifier.StartNotifierAndGetResponse( + iStatus, + KEapSecurIDPincodeQueryUid, + *m_dialog_data_pckg_ptr, + *m_dialog_data_pckg_ptr); + + SetActive(); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_securid_symbian_c: Already active when tried to show identity query dialog.\n"))); + return eap_status_process_general_error; + } + + return eap_status_pending_request; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_securid_symbian_c::read_auth_failure_string( + eap_variable_data_c * const string) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(string); + + eap_status_e status=eap_status_ok; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_securid_symbian_c::get_memory_store_key( + eap_variable_data_c * const memory_store_key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status = memory_store_key->set_copy_of_buffer( + EAP_GTC_USERNAME_HANDLE_KEY, + sizeof(EAP_GTC_USERNAME_HANDLE_KEY)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + u8_t fill = ':'; + + status = memory_store_key->add_data( + &m_index_type, + sizeof(m_index_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = memory_store_key->add_data( + &fill, + sizeof(fill)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = memory_store_key->add_data( + &m_index, + sizeof(m_index)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + status = memory_store_key->add_data( + &fill, + sizeof(fill)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = memory_store_key->add_data( + &m_tunneling_vendor_type, + sizeof(m_tunneling_vendor_type)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +bool eap_am_type_securid_symbian_c::is_session_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + bool sessionValidity(false); + + TRAPD(err, sessionValidity = is_session_validL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_securid_symbian_c::is_session_valid - LEAVE - error=%d, Assuming session is invalid \n"), + err)); + + sessionValidity = false; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return sessionValidity; +} + +//-------------------------------------------------- + +bool eap_am_type_securid_symbian_c::is_session_validL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_securid_symbian_c::is_session_valid: EAP vendor type=%d\n"), + m_eap_vendor_type)); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT(KSQLQuery, "SELECT %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + if (m_eap_type == eap_type_generic_token_card) + { + sqlStatement.Format(KSQLQuery, &cf_str_EAP_GTC_max_session_validity_time_literal, + &KGTCLastFullAuthTime, &KGtcTableName, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + } + else + { + // Secure ID is not supported at the moment. + // Treat this as session invalid. + + CleanupStack::PopAndDestroy(buf); // Delete buf. + return false; + } + + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + TInt64 maxSessionTime = view.ColInt64(colSet->ColNo(cf_str_EAP_GTC_max_session_validity_time_literal)); + TInt64 fullAuthTime = view.ColInt64(colSet->ColNo(KGTCLastFullAuthTime)); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + CleanupStack::PopAndDestroy(&view); // Close view. + CleanupStack::PopAndDestroy(buf); // Delete buf. + + // If the max session time from DB is zero then we use the + // one read from configuration file. + + if( maxSessionTime == 0) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("Session Validity - Using max session validity time from config file\n"))); + + maxSessionTime = m_max_session_time; // value from configuration file. + } + + // Get the current time. + TTime currentTime; + currentTime.UniversalTime(); + + TTime lastFullAuthTime(fullAuthTime); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + TDateTime fullAuthDateTime = lastFullAuthTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("Session Validity - Current Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1, currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("Session Validity - Last Full Auth Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + fullAuthDateTime.Day()+1, fullAuthDateTime.Month()+1, fullAuthDateTime.Year(), fullAuthDateTime.Hour(), + fullAuthDateTime.Minute(), fullAuthDateTime.Second(), fullAuthDateTime.MicroSecond())); + +#endif + + TTimeIntervalMicroSeconds interval = currentTime.MicroSecondsFrom(lastFullAuthTime); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_securid_symbian_c::is_session_valid:interval in microseconds:"), + &(interval.Int64()), + sizeof(interval.Int64()) ) ); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_securid_symbian_c::is_session_valid:max session time in microseconds:"), + &(maxSessionTime), + sizeof(maxSessionTime) ) ); + + +#if defined(_DEBUG) || defined(DEBUG) + + TTimeIntervalMinutes intervalMins; + TInt error = currentTime.MinutesFrom(lastFullAuthTime, intervalMins); + + if(error == KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_securid_symbian_c::is_session_validL()") + EAPL("interval in Minutes =%d\n"), + intervalMins.Int())); + } + +#endif + + + if( maxSessionTime >= interval.Int64() ) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_securid_symbian_c::is_session_valid - Session Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return true; + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_securid_symbian_c::is_session_valid - Session NOT Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return false; + } +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_securid_symbian_c::store_authentication_time() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + TRAPD(err, store_authentication_timeL()); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_securid_symbian_c::store_authentication_timeL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_securid_symbian_c::store_authentication_timeL: EAP Vendor Type=%d\n"), + m_eap_vendor_type)); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT(KSQLQuery, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + if (m_eap_type == eap_type_generic_token_card) + { + sqlStatement.Format(KSQLQuery, &KGTCLastFullAuthTime, &KGtcTableName, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + } + else + { + // Secure ID is not supported at the moment. + // Leave with error. + + CleanupStack::PopAndDestroy(buf); // Delete buf. + User::Leave(KErrNotSupported); + } + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row for updation. + view.FirstL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the current universal time. + TTime currentTime; + currentTime.UniversalTime(); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_securid_symbian_c::store_authentication_time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1,currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + +#endif + + TInt64 fullAuthTime = currentTime.Int64(); + + view.SetColL(colSet->ColNo(KGTCLastFullAuthTime), fullAuthTime); + + view.PutL(); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + CleanupStack::PopAndDestroy(&view); // Close view. + CleanupStack::PopAndDestroy(buf); // Delete buf. + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/101F8E74.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/101F8E74.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Localization strings for project EAPOL +* +*/ + + + +// LOCALISATION STRINGS: + +// b: 50 +// e: 300 +// f: EDialogLabelFont +// d: This name for the EAP-SecurID EAP type is displayed in the EAP type list in IAP UI and in EAP-PEAP +// d: encapsulated EAP type selection. +#define ESIP_GE_NAME "EAP-SecurID" + +// b: 50 +// e: 300 +// f: EDialogLabelFont +// d: This name for the EAP-GTC EAP type is displayed in the EAP type list in IAP UI and in EAP-PEAP +// d: encapsulated EAP type selection. +#define EGTP_GE_NAME "EAP-GTC" + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapGtcDbDefaults.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapGtcDbDefaults.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPGTCDBDEFAULTS_H +#define EAPGTCDBDEFAULTS_H + +// LOCAL CONSTANTS + +_LIT(default_EAP_GTC_identity, ""); + +const TInt64 default_MaxSessionTime = 0; // 0 means read from configuration file. +const TInt64 default_FullAuthTime = 0; + +const TUint KMaxIdentityLengthInDB = 255; + +#endif // EAPGTCDBDEFAULTS_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapGtcDbParameterNames.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapGtcDbParameterNames.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPGTCDBPARAMETERNAMES_H +#define EAPGTCDBPARAMETERNAMES_H + +#include "eap_type_securid_types.h" + +// LOCAL CONSTANTS + +_LIT(KGTCLastFullAuthTime, "EAP_GTC_last_full_authentication_time"); + +#endif // EAPGTCDBPARAMETERNAMES_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapGtcDbUtils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapGtcDbUtils.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPGTCDBUTILS_H +#define EAPGTCDBUTILS_H + +// INCLUDES +#include +#include +#include "eap_header.h" + +// LOCAL CONSTANTS + +#ifdef SYMBIAN_SECURE_DBMS +// For EAP GTC secure database. +// Full path is not needed. The database eapgtc.dat will be saved in the +// data cage path for DBMS. So it will be in "\private\100012a5\eapgtc.dat" in C: drive. +// The maximum length of database name is 0x40 (KDbMaxName) , which is defined in d32dbms.h. + +_LIT(KGtcDatabaseName, "c:eapgtc.dat"); + +_LIT(KGtcSecureUIDFormat, "SECURE[102072e9]"); // For the security policy. + +#else + +_LIT(KGtcDatabaseName, "c:\\system\\data\\eapgtc.dat"); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + +_LIT(KGtcTableName, "eapgtc"); + +// CLASS DECLARATION +class EapGtcDbUtils +{ +public: + + /** + * Opens database + * @param aDatabase Handle to database + * @param aSession Handle to session + * @param aIndexType Bearer type + * @param aIndex Index + */ + static void OpenDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + /** + * Changes the settings' index + */ + static void SetIndexL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const TIndexType aNewIndexType, + const TInt aNewIndex, + const eap_type_value_e aNewTunnelingType); + + static void SetConfigurationL( + RDbNamedDatabase& aDatabase, + const EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + static void GetConfigurationL( + RDbNamedDatabase& aDatabase, + EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + static void CopySettingsL( + RDbNamedDatabase& aDatabase, + const TIndexType aSrcIndexType, + const TInt aSrcIndex, + const eap_type_value_e aSrcTunnelingType, + const TIndexType aDestIndexType, + const TInt aDestIndex, + const eap_type_value_e aDestTunnelingType); + + static void DeleteConfigurationL( + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + +}; + +#endif // EAPGTCBUTILS_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapSecurID.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapSecurID.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,179 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPSECURID_H +#define EAPSECURID_H + +// INCLUDES +#include +#include "eap_header.h" + +// LOCAL CONSTANTS + +// CLASS DECLARATION +/** +* Class that implements the generic EAP type interface. Implements EAP SecurID protocol. +*/ +class CEapSecurID : public CEapType +{ +public: + /** + * Construction function. Called by ECom after the EAP SecurID plugin has been loaded. + * @param aIapInfo Pointer to the class that contains information about bearer type and unique index. + * @return Pointer to the instance. + */ + static CEapSecurID* NewSecurIdL(SIapInfo *aIapInfo); + + /** + * Construction function. Called by ECom after the EAP SecurID plugin has been loaded. + * @param aIapInfo Pointer to the class that contains information about bearer type and unique index. + * @return Pointer to the instance. + */ + static CEapSecurID* NewGtcL(SIapInfo *aIapInfo); + + /** + * Destructor does nothing. + */ + virtual ~CEapSecurID(); + +#ifdef USE_EAP_SIMPLE_CONFIG + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @param eap_config_if Pointer used for call back to creater of stack (eapol_am_wlan_authentication_symbian_c class). + * @return Pointer to the implementation. + */ + virtual eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if); + +#else + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @return Pointer to the implementation. + */ + eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG + + /** + * Invokes the configuration UI. + **/ + TInt InvokeUiL(); + + /** + * Gets information about EAP type. + * @return Pointer to a class that contains the EAP type information. Also pushed to cleanup stack. + */ + CEapTypeInfo* GetInfoLC(); + + /** + * Deletes EAP type configuration + */ + void DeleteConfigurationL(); + + /** + * Returns the version of the interface that the EAP type implements. + * The client-side of the interface must always check the version with this function + * and not call the functions that are not implemented. New functions must be + * added to the end of the interface so that the order of the old functions + * does not change. + * @return Integer indicating the version. + */ + TUint GetInterfaceVersion(); + + /** + * Sets the tunneling type. This is used to indicate that this type is run inside another + * EAP type. + * @param aTunnelingType Type number for the tunneling type + */ + void SetTunnelingType(const TInt aTunnelingType); + + /** + * Changes the index of the saved parameters. + * @param aIndexType Indicates the bearer used for this connection. + * @param aIndex Index for the connection. aIndexType and aIndex uniquely specify the connection. + * @return Pointer to the implementation. + */ + void SetIndexL( + const TIndexType aIndexType, + const TInt aIndex); + + /** + * Sets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void SetConfigurationL(const EAPSettings& aSettings); + + /** + * Gets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void GetConfigurationL(EAPSettings& aSettings); + + /** + * Copies the EAP types configuration + * @param aDestinationIndex ID to where copy the settings. + */ + void CopySettingsL(const TIndexType aDestinationIndexType, const TInt aDestinationIndex); + + +protected: + + /** + * Constructor initialises member variables. + */ + CEapSecurID(const TIndexType aIndexType, const TInt aIndex, const eap_type_value_e aEapType); + +private: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // Eap type (GTC or SecurID) + eap_type_value_e iEapType; + + // Tunneling type + eap_type_value_e iTunnelingType; +}; + +#endif // EAPSECURID_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapSecurIDDbDefaults.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapSecurIDDbDefaults.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPSECURIDDBDEFAULTS_H +#define EAPSECURIDDBDEFAULTS_H + +// LOCAL CONSTANTS + +_LIT(default_EAP_SECURID_identity, ""); +_LIT(default_EAP_GTC_identity, ""); + +#endif // EAPSECURIDDBDEFAULTS_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapSecurIDDbParameterNames.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapSecurIDDbParameterNames.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPSECURIDDBPARAMETERNAMES_H +#define EAPSECURIDDBPARAMETERNAMES_H + +#include "eap_type_securid_types.h" + +// LOCAL CONSTANTS + +_LIT(KServiceType, "ServiceType"); +_LIT(KServiceIndex, "ServiceIndex"); +_LIT(KTunnelingType, "TunnelingType"); + +#endif // EAPSECURIDDBPARAMETERNAMES_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapSecurIDDbUtils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapSecurIDDbUtils.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPSECURIDDBUTILS_H +#define EAPSECURIDDBUTILS_H + +// INCLUDES +#include +#include +#include "eap_header.h" + +// LOCAL CONSTANTS + +#ifdef SYMBIAN_SECURE_DBMS +// For EAP SecureID secure database. +// Full path is not needed. The database eapsecurid.dat will be saved in the +// data cage path for DBMS. So it will be in "\private\100012a5\eapsecurid.dat" in C: drive. +// The maximum length of database name is 0x40 (KDbMaxName) , which is defined in d32dbms.h. + +_LIT(KDatabaseName, "c:eapsecurid.dat"); + +_LIT(KSecureUIDFormat, "SECURE[102072e9]"); // For the security policy. + +#else + +_LIT(KDatabaseName, "c:\\system\\data\\eapsecurid.dat"); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + +_LIT(KSecurIDTableName, "eapsecurid"); + +// CLASS DECLARATION +class EapSecurIDDbUtils +{ +public: + + /** + * Opens database + * @param aDatabase Handle to database + * @param aSession Handle to session + * @param aIndexType Bearer type + * @param aIndex Index + */ + static void OpenDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); +}; + +#endif // EAPSECURIDDBUTILS_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapSecurIDGlobal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/EapSecurIDGlobal.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef EAPSECURIDGLOBAL_H +#define EAPSECURIDGLOBAL_H + +// LOCAL CONSTANTS + +_LIT(KReleaseDate, "20040829:"); // Must be in format YYYYMMDD: (dates and months start from 0) +_LIT(KEapTypeVersion, "1.0"); +_LIT(KManufacturer, "Nokia"); +_LIT(KNokiaSignature, ""); +_LIT(KExtraInfo1, ""); +_LIT(KExtraInfo2, ""); + +#endif // EAPSECURIDGLOBAL_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/eapgtc.hlp.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/inc/eapgtc.hlp.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource headers for project EAPOL +* +*/ + + +// +// eapgtc.hlp.hrh +// + +// +// File generated on 10:41:53 28/7/2004 +// by cshlpcmp Version 010 +// + +#ifndef __EAPGTC_HLP_HRH__ +#define __EAPGTC_HLP_HRH__ + + +_LIT(KESPD_HLP_DIAL_GTC_USERNAME,"ESPD_HLP_DIAL_GTC_USERNAME"); +_LIT(KESPD_HLP_DIAL_USER_INPUT,"ESPD_HLP_DIAL_USER_INPUT"); +_LIT(KEGTP_HLP_DIAL_SETTINGS,"EGTP_HLP_DIAL_SETTINGS"); + +#endif diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/101F8E74.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/101F8E74.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource definitions for project EAPOL +* +*/ + + + +// INCLUDES +#include +#include "101F8E74.loc" +#include "EapolUID.h" + +// RESOURCE DEFINITIONS +// --------------------------------------------------------- +// +// theInfo +// Contains the ECom registration information for EAP SecurID and EAP GTC +// +// --------------------------------------------------------- +// +RESOURCE REGISTRY_INFO theInfo +{ +dll_uid = EAP_SECURID_DLL_UID; +interfaces = + { + INTERFACE_INFO + { + interface_uid = PLUGIN_INTERFACE_UID; + implementations = + { + + BINARY_IMPLEMENTATION_INFO + { + implementation_uid = EAP_GTC_IMPLEMENTATION_UID; + version_no = 1; + display_name = EGTP_GE_NAME; + default_data = {0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06}; // GTC + opaque_data = {0x0A}; // "NOT_OUTSIDE|NOT_OUTSIDE_PEAP" + } // NOT_OUTSIDE is the only needed, but for historical reasons we are + // using NOT_OUTSIDE_PEAP to indicate that the EAP is allowed only as encapsulated EAP. + }; + } + }; +} diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapGtcDbUtils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapGtcDbUtils.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,593 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 337 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "EapGtcDbUtils.h" +#include "EapGtcDbDefaults.h" +#include "EapGtcDbParameterNames.h" +#include "EapSecurIDDbParameterNames.h" + +#include "eap_am_trace_symbian.h" + +const TUint KMaxSqlQueryLength = 512; +const TInt KMicroSecsInAMinute = 60000000; // 60000000 micro seconds is 1 minute. + +// ================= MEMBER FUNCTIONS ======================= + +void EapGtcDbUtils::OpenDatabaseL(RDbNamedDatabase& aDatabase, RDbs& aSession, const TIndexType aIndexType, + const TInt aIndex, const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapGtcDbUtils::OpenDatabaseL -Start- aIndexType=%d, aIndex=%d, aTunnelingVendorType=%d \n"), + aIndexType,aIndex,aTunnelingVendorType) ); + + // 1. Open/create a database + + // Connect to the DBMS server. + User::LeaveIfError(aSession.Connect()); + CleanupClosePushL(aSession); + // aSession and aDatabase are pushed to the cleanup stack even though they may be member + // variables of the calling class and would be closed in the destructor anyway. This ensures + // that if they are not member variables they will be closed. Closing the handle twice + // does no harm. + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = aDatabase.Create(aSession, KGtcDatabaseName, KGtcSecureUIDFormat); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapGtcDbUtils::OpenDatabaseL - Created Secure DB for eapgtc.dat. err=%d\n"), err)); + + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(aSession, KGtcDatabaseName, KGtcSecureUIDFormat)); + CleanupClosePushL(aDatabase); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = aDatabase.Create(fsSession, KGtcDatabaseName); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapGtcDbUtils::OpenDatabaseL - Created Non-Secure DB for eapgtc.dat. err=%d\n"), err)); + + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + CleanupStack::PopAndDestroy(); // close fsSession + + User::LeaveIfError(aDatabase.Open(aSession, KGtcDatabaseName)); + CleanupClosePushL(aDatabase); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + // 2. Create the eap-securid table to database (ignore error if exists) + +// Table columns: +//// NAME ///////////////////////////////////////////////// TYPE ////////////// Constant ///////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| EAP_GTC_identity | VARCHAR(255) | cf_str_EAP_GTC_identity_literal |// +//| EAP_GTC_max_session_validity_time | BIGINT | cf_str_EAP_GTC_max_session_validity_time_literal |// +//| EAP_GTC_last_full_authentication_time | BIGINT | KGTCLastFullAuthTime |// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLCreateTable1, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(255), \ + %S BIGINT, \ + %S BIGINT)"); + + sqlStatement.Format(KSQLCreateTable1, + &KGtcTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &cf_str_EAP_GTC_identity_literal, + &cf_str_EAP_GTC_max_session_validity_time_literal, + &KGTCLastFullAuthTime); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // 4. Check if database table contains a row for this service type and id + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQueryRow, &cf_str_EAP_GTC_identity_literal, &KGtcTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + // View must be closed when no longer needed + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // 5. If row is not found then add it + + TInt rows = view.CountL(); + CleanupStack::PopAndDestroy(); // view + if (rows == 0) + { + _LIT(KSQLInsert, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert, &KGtcTableName); + + view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly); + CleanupClosePushL(view); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast (aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + view.SetColL(colSet->ColNo(cf_str_EAP_GTC_identity_literal), default_EAP_GTC_identity); + + view.SetColL(colSet->ColNo(cf_str_EAP_GTC_max_session_validity_time_literal), default_MaxSessionTime); + + view.SetColL(colSet->ColNo(KGTCLastFullAuthTime), default_FullAuthTime); + + view.PutL(); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + CleanupStack::PopAndDestroy( &view ); // Close view. + + } + + CleanupStack::PopAndDestroy( buf ); // Delete buf + CleanupStack::Pop( &aDatabase ); + CleanupStack::Pop( &aSession ); + + aDatabase.Compact(); +} + + +void EapGtcDbUtils::SetIndexL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const TIndexType aNewIndexType, + const TInt aNewIndex, + const eap_type_value_e aNewTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aNewTunnelingVendorType = aNewTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aNewTunnelingVendorType = static_cast(aNewTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &KGtcTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + TInt rows = view.CountL(); + + if (rows == 0) + { + User::Leave(KErrNotFound); + } + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + + CleanupStack::PushL(colSet); + + + view.UpdateL(); + + view.SetColL(colSet->ColNo(KServiceType), static_cast(aNewIndexType)); + + view.SetColL(colSet->ColNo(KServiceIndex), aNewIndex); + + view.SetColL(colSet->ColNo(KTunnelingType), aNewTunnelingVendorType); + + view.PutL(); + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapGtcDbUtils::SetConfigurationL( + RDbNamedDatabase& aDatabase, + const EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + // Check if the settings are for the correct type + if (aSettings.iEAPType != EAPSettings::EEapGtc) + { + User::Leave(KErrNotSupported); + } + + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + RDbView view; + + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KGtcTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + view.FirstL(); + + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Username + if (aSettings.iUsernamePresent) + { + // Validate length. + if(aSettings.iUsername.Length() > KMaxIdentityLengthInDB) + { + // Username too long. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapGtcDbUtils::SetConfigurationL: Too long Username. Length=%d \n"), + aSettings.iUsername.Length())); + + User::Leave(KErrArgument); + } + + // Length is ok. Set the value in DB. + view.SetColL(colSet->ColNo(cf_str_EAP_GTC_identity_literal), aSettings.iUsername); + } + + // Session validity time + if (aSettings.iSessionValidityTimePresent) + { + // User or device management wants to store the session validity time. + // Convert the time to micro seconds and save. + + TInt64 validityInMicro = (aSettings.iSessionValidityTime) * KMicroSecsInAMinute; + + view.SetColL(colSet->ColNo(cf_str_EAP_GTC_max_session_validity_time_literal), validityInMicro); + } + + // Last full authentication time should be made zero when EAP configurations are modified. + // This makes sure that the next authentication with this EAP would be full authentication + // instead of reauthentication even if the session is still valid. + + view.SetColL(colSet->ColNo(KGTCLastFullAuthTime), default_FullAuthTime); + + EAP_TRACE_DEBUG_SYMBIAN((_L("Session Validity: EAP-Type=%d, Resetting Full Auth Time since settings are modified\n"), + aSettings.iEAPType )); + + view.PutL(); + CleanupStack::PopAndDestroy(3); // view, colset, buf + +} + +void EapGtcDbUtils::GetConfigurationL( + RDbNamedDatabase& aDatabase, + EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + RDbView view; + + // Form the query + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &KGtcTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + aSettings.iEAPType = EAPSettings::EEapGtc; + + // Username + TPtrC username = view.ColDes(colSet->ColNo(cf_str_EAP_GTC_identity_literal)); + aSettings.iUsername.Copy(username); + aSettings.iUsernamePresent = ETrue; + + // Session validity time + TInt64 maxSessionTimeMicro = view.ColInt64(colSet->ColNo(cf_str_EAP_GTC_max_session_validity_time_literal)); + + // Convert the time to minutes. + TInt64 maxSessionTimeMin = maxSessionTimeMicro / KMicroSecsInAMinute; + + aSettings.iSessionValidityTime = static_cast(maxSessionTimeMin); + aSettings.iSessionValidityTimePresent = ETrue; + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapGtcDbUtils::CopySettingsL( + RDbNamedDatabase& aDatabase, + const TIndexType aSrcIndexType, + const TInt aSrcIndex, + const eap_type_value_e aSrcTunnelingType, + const TIndexType aDestIndexType, + const TInt aDestIndex, + const eap_type_value_e aDestTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aSrcTunnelingVendorType = aSrcTunnelingType.get_vendor_type(); + TUint aDestTunnelingVendorType = aDestTunnelingType.get_vendor_type(); + +#else + + TUint aSrcTunnelingVendorType = static_cast(aSrcTunnelingType); + TUint aDestTunnelingVendorType = static_cast(aDestTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &KGtcTableName, + &KServiceType, aSrcIndexType, &KServiceIndex, aSrcIndex, &KTunnelingType, aSrcTunnelingVendorType); + + RDbView view; + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + TInt rows = view.CountL(); + + if (rows == 0) + { + User::Leave(KErrNotFound); + } + + // Get the first (and only) row + view.FirstL(); + + view.GetL(); + + view.InsertCopyL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + + CleanupStack::PushL(colSet); + + view.SetColL(colSet->ColNo(KServiceType), static_cast(aDestIndexType)); + + view.SetColL(colSet->ColNo(KServiceIndex), aDestIndex); + + view.SetColL(colSet->ColNo(KTunnelingType), aDestTunnelingVendorType); + + view.PutL(); + + CleanupStack::PopAndDestroy(3); // view, colset, buf +} + +void EapGtcDbUtils::DeleteConfigurationL( + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + RDbs session; + RDbNamedDatabase database; + // Connect to the DBMS server. + User::LeaveIfError(session.Connect()); + CleanupClosePushL(session); + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = database.Create(session, KGtcDatabaseName, KGtcSecureUIDFormat); + + if(err == KErrNone) + { + // Database was created so it was empty. No need for further actions. + database.Destroy(); + CleanupStack::PopAndDestroy(); + return; + + } + else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + // Database existed, open it. + User::LeaveIfError(database.Open(session, KGtcDatabaseName, KGtcSecureUIDFormat)); + CleanupClosePushL(database); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = database.Create(fsSession, KGtcDatabaseName); + + if(err == KErrNone) + { + // Database was created so it was empty. No need for further actions. + database.Destroy(); + CleanupStack::PopAndDestroy(2); // fsSession, database session + return; + + } + else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + CleanupStack::PopAndDestroy(); // close fsSession + + User::LeaveIfError(database.Open(session, KGtcDatabaseName)); + CleanupClosePushL(database); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Main settings table + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQL, &KGtcTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Delete rows + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + // Close database + CleanupStack::PopAndDestroy(4); // view, buf, database, session +} + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapGtcUiConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapGtcUiConnection.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 339 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include "EapGtcDbUtils.h" +#include +#include + +CEapGtcUiConnection::CEapGtcUiConnection( + const TIndexType aIndexType, + const TInt aIndex, + const TInt aTunnelingType) + : iIndexType(aIndexType) + , iIndex(aIndex) + , iTunnelingType(aTunnelingType) + , iIsConnected(EFalse) + , iDataConn(NULL) +{ +} + + +CEapGtcUiConnection::~CEapGtcUiConnection() +{ +} + + +TInt CEapGtcUiConnection::Connect() +{ +#ifdef USE_EAP_EXPANDED_TYPES + + eap_type_value_e tunnelingType(static_cast(iTunnelingType)); + +#else + + eap_type_value_e tunnelingType = static_cast(iTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + TRAPD(err, EapGtcDbUtils::OpenDatabaseL( + iDbNamedDatabase, + iDbs, + iIndexType, + iIndex, + tunnelingType)); + if (err == KErrNone) + { + iIsConnected = ETrue; + } + + return err; +} + + +TInt CEapGtcUiConnection::Close() +{ + if (iIsConnected) + { + iDbNamedDatabase.Close(); + iDbs.Close(); + } + iIsConnected = EFalse; + + return KErrNone; +} + + +CEapGtcUiDataConnection * CEapGtcUiConnection::GetDataConnection() +{ + if (!iDataConn) + { + iDataConn = new CEapGtcUiDataConnection(this); + } + + return iDataConn; +} + +TInt CEapGtcUiConnection::GetDatabase(RDbNamedDatabase & aDatabase) +{ + if (iIsConnected == EFalse) + { + return KErrSessionClosed; + } + + aDatabase = iDbNamedDatabase; + return KErrNone; +} + + +TIndexType CEapGtcUiConnection::GetIndexType() +{ + return iIndexType; +} + + +TInt CEapGtcUiConnection::GetIndex() +{ + return iIndex; +} + + +TInt CEapGtcUiConnection::GetTunnelingType() +{ + return iTunnelingType; +} + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapGtcUiDataConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapGtcUiDataConnection.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,214 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 341 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include +#include "EapGtcDbUtils.h" +#include "EapSecurIDDbParameterNames.h" +#include "EapGtcDbParameterNames.h" +#include "EapGtcDbDefaults.h" +#include +#include +#include +#include "eap_am_trace_symbian.h" + +const TUint KMaxSqlQueryLength = 256; + + +CEapGtcUiDataConnection::CEapGtcUiDataConnection(CEapGtcUiConnection * aUiConn) +: iIsOpened(EFalse) +, iUiConn(aUiConn) +, iColSet(NULL) +, iDataPtr(NULL) +{ +} + + +CEapGtcUiDataConnection::~CEapGtcUiDataConnection() +{ + if (iUiConn) + { + Close(); + iUiConn = NULL; + } +} + + +TInt CEapGtcUiDataConnection::Open() +{ + if (iIsOpened) + { + return KErrAlreadyExists; + } + + TInt err = iUiConn->GetDatabase(iDatabase); + if (err != KErrNone) + { + return err; + } + + iIsOpened = ETrue; + return KErrNone; +} + + +TInt CEapGtcUiDataConnection::GetData(CEapGtcUiGtcData ** aDataPtr) +{ + if (aDataPtr == NULL) + { + return KErrArgument; + } + if (iIsOpened == EFalse) + { + return KErrSessionClosed; + } + iDataPtr = new CEapGtcUiGtcData(); + if (!iDataPtr) + { + return KErrNoMemory; + } + + TRAPD(err, FetchDataL()); + if (err != KErrNone) + { + delete iDataPtr; + iDataPtr = NULL; + + delete iColSet; + iColSet = NULL; + + iView.Close(); + + return err; + } + + *aDataPtr = iDataPtr; + + return KErrNone; +} + + +TInt CEapGtcUiDataConnection::Update() +{ + TRAPD(err, iView.UpdateL()); + if (err != KErrNone) + { + return err; + } + + // Validate the length of username/identity. + if(iDataPtr->GetIdentity().Length() > KMaxIdentityLengthInDB) + { + // Username or identity too long. Can not be stored in DB. + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapGtcUiDataConnection::Update: Too long username/identity. length =%d\n"), + iDataPtr->GetIdentity().Length())); + + return KErrArgument; + } + + TRAP(err, iView.SetColL(iColSet->ColNo(cf_str_EAP_GTC_identity_literal), iDataPtr->GetIdentity())); + if (err != KErrNone) + { + return err; + } + + // Last full authentication time should be made zero when EAP configurations are modified. + // This makes sure that the next authentication with this EAP would be full authentication + // instead of reauthentication even if the session is still valid. + + TRAP(err, iView.SetColL(iColSet->ColNo(KGTCLastFullAuthTime), default_FullAuthTime)); + if (err != KErrNone) + { + return err; + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("Session Validity: Resetting Full Auth Time since EAP-GTC settings are modified\n"))); + + TRAP(err, iView.PutL()); + + return err; +} + + +TInt CEapGtcUiDataConnection::Close() +{ + if (iIsOpened == EFalse) + { + return KErrNone; + } + + delete iDataPtr; + iDataPtr = NULL; + + delete iColSet; + iColSet = NULL; + + iView.Close(); + + iUiConn = NULL; + + return KErrNone; +} + + +void CEapGtcUiDataConnection::FetchDataL() +{ + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Form the query. Query everything. + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, + &KGtcTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + + // Evaluate view + User::LeaveIfError(iView.Prepare(iDatabase, TDbQuery(sqlStatement))); + + User::LeaveIfError(iView.EvaluateAll()); + + // Get the first (and only) row + iView.FirstL(); + iView.GetL(); + + // Get column set so we get the correct column numbers + delete iColSet; + iColSet = NULL; + iColSet = iView.ColSetL(); + + // Start fetching the values + + // identity + iDataPtr->GetIdentity().Copy(iView.ColDes16(iColSet->ColNo(cf_str_EAP_GTC_identity_literal))); + + CleanupStack::PopAndDestroy(buf); +} + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapGtcUiGtcData.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapGtcUiGtcData.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 343 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include + + +CEapGtcUiGtcData::CEapGtcUiGtcData() +{ +} + + +CEapGtcUiGtcData::~CEapGtcUiGtcData() +{ +} + + +TDes& CEapGtcUiGtcData::GetIdentity() +{ + return iIdentity; +} + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapSecurID.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapSecurID.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,340 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 347 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "EapSecurID.h" +#include "eap_am_type_securid_symbian.h" +#include "eap_type_securid.h" +#include "EapSecurIDGlobal.h" +#include +#include "EapGtcDbUtils.h" + +#include +#include "EapGtcUi.h" + +#include "eap_am_tools_symbian.h" + +// LOCAL CONSTANTS + +// The version number of this interface. +const TUint KInterfaceVersion = 1; + +// ================= MEMBER FUNCTIONS ======================= + +CEapSecurID::CEapSecurID( + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aEapType) + : iIndexType(aIndexType) + , iIndex(aIndex) + , iEapType(aEapType) + , iTunnelingType(eap_type_none) +{ +} + +// ---------------------------------------------------------- + +CEapSecurID* CEapSecurID::NewSecurIdL(SIapInfo *aIapInfo) +{ + return new(ELeave) CEapSecurID(aIapInfo->indexType, aIapInfo->index, eap_type_securid); +} + +// ---------------------------------------------------------- + +CEapSecurID* CEapSecurID::NewGtcL(SIapInfo *aIapInfo) +{ + return new(ELeave) CEapSecurID(aIapInfo->indexType, aIapInfo->index, eap_type_generic_token_card); +} + +// ---------------------------------------------------------- + +CEapSecurID::~CEapSecurID() +{ +} + +// ---------------------------------------------------------- + +#ifdef USE_EAP_SIMPLE_CONFIG + +eap_base_type_c* CEapSecurID::GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const /*configuration_if*/) + +#else + +eap_base_type_c* CEapSecurID::GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG +{ + // Create AM + eap_am_type_securid_symbian_c* amEapType = eap_am_type_securid_symbian_c::NewL( + aTools, + aPartner, + iIndexType, + iIndex, + iTunnelingType, + iEapType, + is_client_when_true, + receive_network_id); + if (amEapType->get_is_valid() == false) + { + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrGeneral); + } + eap_base_type_c* type = 0; + + type = new eap_type_securid_c( + aTools, + aPartner, + amEapType, + true /* free_am */, + iEapType, + is_client_when_true, + receive_network_id); + + if (type == 0) + { + // Out of memory + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrNoMemory); + } + else if (type->get_is_valid() == false) + { + type->shutdown(); + // amEapType is freed by eap_type_securid_c + delete type; + User::Leave(KErrGeneral); + } + return type; +} + +// ---------------------------------------------------------- + +TUint CEapSecurID::GetInterfaceVersion() +{ + return KInterfaceVersion; +} + +// ---------------------------------------------------------- + +TInt CEapSecurID::InvokeUiL() +{ + TInt buttonId(0); + +#ifdef USE_EAP_EXPANDED_TYPES + + CEapGtcUiConnection uiConn(iIndexType, iIndex, iTunnelingType.get_vendor_type()); + +#else + + CEapGtcUiConnection uiConn(iIndexType, iIndex, iTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + CEapGtcUi* ui = CEapGtcUi::NewL(&uiConn); + CleanupStack::PushL(ui); + buttonId = ui->InvokeUiL(); + CleanupStack::PopAndDestroy(ui); + return buttonId; +} + +// ---------------------------------------------------------- + +CEapTypeInfo* CEapSecurID::GetInfoLC() +{ + CEapTypeInfo* info = new(ELeave) CEapTypeInfo( + (TDesC&) KReleaseDate, + (TDesC&) KEapTypeVersion, + (TDesC&) KManufacturer); + CleanupStack::PushL(info); + return info; +} + +// ---------------------------------------------------------- + +void CEapSecurID::DeleteConfigurationL() +{ + EapGtcDbUtils::DeleteConfigurationL(iIndexType, iIndex, iTunnelingType); +} + +// ---------------------------------------------------------- + +void CEapSecurID::SetTunnelingType(const TInt aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + // Vendor id is eap_type_vendor_id_ietf always in this plugin. + iTunnelingType.set_eap_type_values(eap_type_vendor_id_ietf, aTunnelingType); + +#else + + iTunnelingType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES +} + +// ---------------------------------------------------------- +void CEapSecurID::SetIndexL( + const TIndexType aIndexType, + const TInt aIndex) +{ + // First delete the target configuration + TIndexType tmpIndexType = iIndexType; + TInt tmpIndex = iIndex; + + iIndexType = aIndexType; + iIndex = aIndex; + + TInt err(KErrNone); + TRAP(err, DeleteConfigurationL()); + // Ignore error on purpose + + // Return the indices + iIndexType = tmpIndexType; + iIndex = tmpIndex; + + RDbNamedDatabase db; + + RDbs session; + + EapGtcDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapGtcDbUtils::SetIndexL( + db, + iIndexType, + iIndex, + iTunnelingType, + aIndexType, + aIndex, + iTunnelingType); + + iIndexType = aIndexType; + iIndex = aIndex; + + CleanupStack::PopAndDestroy(2); // db + + +} + +void CEapSecurID::SetConfigurationL(const EAPSettings& aSettings) +{ + RDbNamedDatabase db; + + RDbs session; + + // This also creates the IAP entry if it doesn't exist + EapGtcDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapGtcDbUtils::SetConfigurationL( + db, + aSettings, + iIndexType, + iIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db, session +} + +void CEapSecurID::GetConfigurationL(EAPSettings& aSettings) +{ + RDbNamedDatabase db; + + RDbs session; + + // This also creates the IAP entry if it doesn't exist + EapGtcDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapGtcDbUtils::GetConfigurationL( + db, + aSettings, + iIndexType, + iIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db, session +} + +void CEapSecurID::CopySettingsL( + const TIndexType aDestinationIndexType, + const TInt aDestinationIndex) +{ + // First delete the target configuration + TIndexType tmpIndexType = iIndexType; + TInt tmpIndex = iIndex; + + iIndexType = aDestinationIndexType; + iIndex = aDestinationIndex; + + TInt err(KErrNone); + TRAP(err, DeleteConfigurationL()); + // Ignore error on purpose + + // Return the indices + iIndexType = tmpIndexType; + iIndex = tmpIndex; + + RDbNamedDatabase db; + + RDbs session; + + EapGtcDbUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapGtcDbUtils::CopySettingsL( + db, + iIndexType, + iIndex, + iTunnelingType, + aDestinationIndexType, + aDestinationIndex, + iTunnelingType); + + CleanupStack::PopAndDestroy(2); // db + +} + + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapSecurIDDbUtils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapSecurIDDbUtils.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,176 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 349 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "EapSecurIDDbUtils.h" +#include "EapSecurIDDbDefaults.h" +#include "EapSecurIDDbParameterNames.h" + +#include "eap_am_trace_symbian.h" + +const TUint KMaxSqlQueryLength = 512; + +// ================= MEMBER FUNCTIONS ======================= + +void EapSecurIDDbUtils::OpenDatabaseL(RDbNamedDatabase& aDatabase, RDbs& aSession, const TIndexType aIndexType, + const TInt aIndex, const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + // 1. Open/create a database + + // Connect to the DBMS server. + User::LeaveIfError(aSession.Connect()); + CleanupClosePushL(aSession); + // aSession and aDatabase are pushed to the cleanup stack even though they may be member + // variables of the calling class and would be closed in the destructor anyway. This ensures + // that if they are not member variables they will be closed. Closing the handle twice + // does no harm. + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = aDatabase.Create(aSession, KDatabaseName, KSecureUIDFormat); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapSecurIDDbUtils::OpenDatabaseL - Created Secure DB for eapsecurid.dat. err=%d\n"), err)); + + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(aSession, KDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(aDatabase); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = aDatabase.Create(fsSession, KDatabaseName); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapSecurIDDbUtils::OpenDatabaseL - Created Non-Secure DB for eapsecurid.dat. err=%d\n"), err)); + + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + CleanupStack::PopAndDestroy(); // close fsSession + + User::LeaveIfError(aDatabase.Open(aSession, KDatabaseName)); + CleanupClosePushL(aDatabase); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + // 2. Create the eap-securid table to database (ignore error if exists) + // Table columns: + //// NAME ///////////////////////////////////////////////// TYPE ////////////// Constant ///////// + //| ServiceType | UNSIGNED INTEGER | KServiceType |// + //| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// + //| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// + //| EAP_SECURID_identity | VARCHAR(255) | cf_str_EAP_SECURID_identity_literal |// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLCreateTable1, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(255))"); + sqlStatement.Format(KSQLCreateTable1, &KSecurIDTableName, &KServiceType, &KServiceIndex, &KTunnelingType, &cf_str_EAP_SECURID_identity_literal); + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // 4. Check if database table contains a row for this service type and id + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQueryRow, &cf_str_EAP_SECURID_identity_literal, &KSecurIDTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + // View must be closed when no longer needed + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + // 5. If row is not found then add it + TInt rows = view.CountL(); + CleanupStack::PopAndDestroy(); // view + if (rows == 0) + { + _LIT(KSQLInsert, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert, &KSecurIDTableName); + + view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly); + CleanupClosePushL(view); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast (aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + view.SetColL(colSet->ColNo(cf_str_EAP_SECURID_identity_literal), default_EAP_SECURID_identity); + view.PutL(); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + CleanupStack::PopAndDestroy( &view ); // Close view. + } + + CleanupStack::PopAndDestroy(); // sqlStatement + CleanupStack::Pop(2); // database, session + aDatabase.Compact(); +} + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapSecurIDProxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/securid/symbian/plugin/src/EapSecurIDProxy.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 351 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "EapSecurID.h" +#include +#include +#include "EapolUID.h" + +const TImplementationProxy ImplementationTable[] = +{ + {{EAP_GTC_IMPLEMENTATION_UID}, reinterpret_cast (CEapSecurID::NewGtcL)} +}; + +// ================= OTHER EXPORTED FUNCTIONS ============== + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) +{ + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + + return ImplementationTable; +} + +//-------------------------------------------------- + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/sim/symbian/eap_am_type_sim_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/sim/symbian/eap_am_type_sim_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,222 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 352 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_type_sim_symbian.h" +#include "abs_eap_am_crypto.h" +#include "abs_eap_am_mutex.h" + +const u32_t SIM_IMSI_LENGTH = 8u; + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_type_sim_simulator_c::~eap_am_type_sim_simulator_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_am_type_sim_simulator_c::eap_am_type_sim_simulator_c( + abs_eap_am_tools_c * const tools, abs_eap_am_type_sim_c * const partner) +: eap_am_type_sim_c(tools, partner) +, m_am_tools(tools) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_sim_simulator_c::query_SIM_imsi( + u8_t * const imsi, const u32_t max_length, u32_t * const imsi_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + u32_t ind = 0u; + for (ind = 0u; ind < max_length; ind++) + { + imsi[ind] = static_cast(~ind; + } + *imsi_length = ind; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_process_general_error; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_sim_simulator_c::query_SIM_kc_and_sres( + const u8_t * const imsi, const u32_t imsi_length, + const u8_t * const rand, const u32_t /*rand_length*/, + u8_t * const kc, u32_t * const kc_length, + u8_t * const sres, u32_t * const sres_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (imsi == 0 + || rand == 0 + || kc == 0 + || sres == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + EAP_ASSERT_ALWAYS(*kc_length >= 8u); + EAP_ASSERT_ALWAYS(*sres_length >= 4u); + + eap_variable_data_c aes_context(m_am_tools); + eap_variable_data_c encryption_IV(m_am_tools); + eap_variable_data_c imsi_tmp(m_am_tools); + u8_t tmp_buffer[16u]; + + eap_status_e status = imsi_tmp.add_data(imsi, imsi_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = imsi_tmp.add_data(imsi, imsi_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = m_am_tools->get_crypto()->cbc_aes_set_encryption_key( + &aes_context, + //&encryption_IV, + imsi_tmp.get_data(imsi_tmp.get_data_length()), + imsi_tmp.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = encryption_IV.init(m_am_tools->get_crypto()->aes_key_length()); + if (status != eap_status_ok) + { + return status; + } + encryption_IV.set_is_valid(); + + encryption_IV.set_data_length(m_am_tools->get_crypto()->aes_key_length()); + m_am_tools->memset( + encryption_IV.get_data(encryption_IV.get_data_length()), + 0, + encryption_IV.get_data_length()); + + status = m_am_tools->get_crypto()->cbc_aes_encrypt_data( + &aes_context, + &encryption_IV, + rand, + tmp_buffer, + sizeof(tmp_buffer)); + + m_am_tools->memmove(kc, tmp_buffer, *kc_length); + + + eap_variable_data_c kc_tmp(m_am_tools); + u8_t sres_tmp[16u]; + + status = kc_tmp.add_data(kc, *kc_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = kc_tmp.add_data(kc, *kc_length); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = m_am_tools->get_crypto()->cbc_aes_set_encryption_key( + &aes_context, + //&encryption_IV, + kc_tmp.get_data(kc_tmp.get_data_length()), + kc_tmp.get_data_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return status; + } + + status = encryption_IV.init(m_am_tools->get_crypto()->aes_key_length()); + if (status != eap_status_ok) + { + return status; + } + encryption_IV.set_is_valid(); + + encryption_IV.set_data_length(m_am_tools->get_crypto()->aes_key_length()); + m_am_tools->memset( + encryption_IV.get_data(encryption_IV.get_data_length()), + 0, + encryption_IV.get_data_length()); + + status = m_am_tools->get_crypto()->cbc_aes_encrypt_data( + &aes_context, + &encryption_IV, + rand, + sres_tmp, + sizeof(sres_tmp)); + + m_am_tools->memmove(sres, sres_tmp, *sres_length); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_sim_simulator_c::query_SIM_triplets( + //const eap_state_selector_c * const p_state_selector, + const eap_variable_data_c * const p_imsi, + eap_type_sim_triplet_array_c * const triplets) +{ + // NOTE if user needs to use imsi after return from query_SIM_triplets() + // function that parameter MUST be copied using copy() member function of each parameter. + // For example: saved_imsi = imsi->copy() + + eap_status_e status = eap_status_process_general_error; + + const u32_t triplet_count = 2u; + + + +// End. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/symbian/plugin/common/EapTypeInfo.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/symbian/plugin/common/EapTypeInfo.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,90 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 363 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include + +// ================= MEMBER FUNCTIONS ======================= +CEapTypeInfo::CEapTypeInfo() +{ +} + +CEapTypeInfo::CEapTypeInfo(const TDesC& aReleaseDate, const TDesC& aVersion, + const TDesC& aManufacturer) +: iVersion(aVersion), +iManufacturer(aManufacturer) +{ + // Format the release date according to locale + TTime date(aReleaseDate); + _LIT(KDateFormat, "%/0%1%/1%2%/2%3%/3"); + TRAPD(err, date.FormatL(iReleaseDate, KDateFormat)); + if (err != KErrNone) + { + // Something went wrong. Clear release date. + iReleaseDate.SetLength(0); + } +} + +// ---------------------------------------------------------- + +CEapTypeInfo::~CEapTypeInfo() +{ +} + +// ---------------------------------------------------------- + +void CEapTypeInfo::Set(const TDesC& aReleaseDate, const TDesC& aVersion, + const TDesC& aManufacturer) +{ + iReleaseDate = aReleaseDate; + iVersion = aVersion; + iManufacturer = aManufacturer; +} + +// ---------------------------------------------------------- + +const TDesC& CEapTypeInfo::ReleaseDate() const +{ + return iReleaseDate; +} + +// ---------------------------------------------------------- + +const TDesC& CEapTypeInfo::Version() const +{ + return iVersion; +} + +// ---------------------------------------------------------- + +const TDesC& CEapTypeInfo::Manufacturer() const +{ + return iManufacturer; +} + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/EapTlsPeapCertInterface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/EapTlsPeapCertInterface.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2459 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 390 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include "EapTlsPeapCertInterface.h" +#include "EapTlsPeapUtils.h" +#include +#include +#include "eap_tlv_message_data.h" +#include "eap_am_trace_symbian.h" + +const TText8 KKeyStoreHandlePrefix[] = "EapTlsPeapKeyStoreHandler"; +const TText8 KKeyStoreHandleKey[] = "CEapTlsPeapCertInterface KeyStore handle"; + +enum TAlgorithmAndSignedType +{ + ERSASign = 1, + EDSASign, + ERSASignWithFixedDH, + EDSASignWithFixedDH, + ERSASignWithEphemeralDH, + EDSASignWithEphemeralDH +}; + +enum eap_type_tlspeap_stored_e +{ + eap_type_tlspeap_stored_keystore_handle = 1 +}; + +// ================= MEMBER FUNCTIONS ======================= + +// Completition functions should be moved to abstract IF + +CEapTlsPeapCertInterface* CEapTlsPeapCertInterface::NewL(abs_eap_am_tools_c* const aTools, + eap_am_type_tls_peap_symbian_c* const aParent) +{ + CEapTlsPeapCertInterface* self = new(ELeave) CEapTlsPeapCertInterface(aTools, aParent); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; +} + +//-------------------------------------------------- + +CEapTlsPeapCertInterface::CEapTlsPeapCertInterface(abs_eap_am_tools_c* const aTools, eap_am_type_tls_peap_symbian_c* const aParent) +: CActive(CActive::EPriorityStandard) +,iParent(aParent) +,m_am_tools(aTools) +,iAllowedUserCerts(1) +,iEncodedCertificate(0) +,iCertPtr(0,0) +,iMatchingUserCertInfos(1) +,iCAIndex(0) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapTlsPeapCertInterface::ConstructL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + User::LeaveIfError(iFs.Connect()); + + CActiveScheduler::Add(this); + + iValidationResult = CPKIXValidationResult::NewL(); + + iEncodedCertificate = HBufC8::NewL(0); + iCertPtr.Set(iEncodedCertificate->Des()); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +CEapTlsPeapCertInterface::~CEapTlsPeapCertInterface() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + iMatchingUserCerts.ResetAndDestroy(); + + iMatchingUserCertInfos.Reset(); + + iAllowedUserCerts.Reset(); + + iRootCerts.ResetAndDestroy(); + iUserCertChain.ResetAndDestroy(); + + iCertAuthorities.ResetAndDestroy(); + + TInt i(0); + for (i = 0; i < iCertInfos.Count(); i++) + { + iCertInfos[i]->Release(); + } + iCertInfos.Reset(); + + for (i = 0; i < iKeyInfos.Count(); i++) + { + iKeyInfos[i]->Release(); + } + iKeyInfos.Reset(); + + delete iCertFilter; + delete iCertStore; + delete iCertChain; + delete iValidationResult; + delete iInputCertChain; + delete iEncodedCertificate; + delete iDataIn; + delete iDataOut; + delete iSignature; + delete iPtrOut; + delete iSignaturePtr; + + iFs.Close(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::~CEapTlsPeapCertInterface(): returns\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapTlsPeapCertInterface::GetMatchingCertificatesL( + const RArray& aAllowedUserCerts, + const TBool aUseCertAuthoritiesFilter, + EAP_TEMPLATE_CONST eap_array_c * const aCertAuthorities, + const TBool aUseCertTypesFilter, + EAP_TEMPLATE_CONST eap_array_c * const aCertTypes, + const TBool aUseAllowedCipherSuitesFilter, + const RArray& aAllowedCipherSuites) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + iUseCertAuthoritiesFilter = aUseCertAuthoritiesFilter; + + iUseCertTypesFilter = aUseCertTypesFilter; + + iUseAllowedCipherSuitesFilter = aUseAllowedCipherSuitesFilter; + + iAllowedUserCerts.Reset(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::GetMatchingCertificatesL: Total allowed user certs=%d\n"), + aAllowedUserCerts.Count())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::GetMatchingCertificatesL:UseCertAuthoritiesFilter=%d, UseCertTypesFilter=%d, UseAllowedCipherSuitesFilter=%d\n"), + iUseCertAuthoritiesFilter,iUseCertTypesFilter,iUseAllowedCipherSuitesFilter)); + + for (TInt j = 0; j < aAllowedUserCerts.Count(); j++) + { + iAllowedUserCerts.AppendL(aAllowedUserCerts[j]); + +#if defined(_DEBUG) || defined(DEBUG) + + // This is just for the debug prints. + TCertLabel tempLabel = iAllowedUserCerts[j].iLabel; + TKeyIdentifier tempSubjectKeyId = iAllowedUserCerts[j].iSubjectKeyId; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::GetMatchingCertificatesL: details of allowed user certs,Label=%S\n"), + &tempLabel)); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "GetMatchingCertificatesL : Subject Key Id:", + tempSubjectKeyId.Ptr(), tempSubjectKeyId.Size() ) ); +#endif + } + + if (iCertAuthorities.Count() > 0) + { + iCertAuthorities.ResetAndDestroy(); + } + if (aUseCertAuthoritiesFilter) + { + for (TUint i = 0; i < aCertAuthorities->get_object_count(); i++) + { + HBufC8* buf = HBufC8::NewLC((aCertAuthorities->get_object(i))->get_data_length()); + TPtr8 ptr = buf->Des(); + ptr.Copy((aCertAuthorities->get_object(i))->get_data((aCertAuthorities->get_object(i))->get_data_length()), + (aCertAuthorities->get_object(i))->get_data_length()); + + // Try to form distiguished name + CX500DistinguishedName* tmp = 0; + TRAPD(err, tmp = CX500DistinguishedName::NewL(ptr)); + if (err == KErrNone) + { + CleanupStack::PushL(tmp); + // Distinguished name was found -> add it to array. + User::LeaveIfError(iCertAuthorities.Append(tmp)); + CleanupStack::Pop(tmp); + } + CleanupStack::PopAndDestroy(buf); + } + } + + if (aUseCertTypesFilter) + { + iCertTypes = aCertTypes; + } + + if (aUseAllowedCipherSuitesFilter) + { + iRSACertsAllowed = EFalse; + iDSACertsAllowed = EFalse; + + for (TInt i = 0; i < aAllowedCipherSuites.Count(); i++) + { + if (EapTlsPeapUtils::CipherSuiteUseRSAKeys(static_cast(aAllowedCipherSuites[i]))) + { + iRSACertsAllowed = ETrue; + } + else if (EapTlsPeapUtils::CipherSuiteUseDSAKeys(static_cast(aAllowedCipherSuites[i]))) + { + iDSACertsAllowed = ETrue; + } + } + } + + iState = EGetMatchingCertsInitStore; + + if (iCertStore == 0) + { + iCertStore = CUnifiedCertStore::NewL(iFs, false); + iCertStore->Initialize(iStatus); + } + else + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + SetActive(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapTlsPeapCertInterface::ReadCertificateL(SCertEntry& aCertInfo, const TBool aRetrieveChain) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + iCertInfo = aCertInfo; + iRetrieveChain = aRetrieveChain; + iState = EReadCertInitStore; + + if (iCertStore == 0) + { + iCertStore = CUnifiedCertStore::NewL(iFs, false); + iCertStore->Initialize(iStatus); + } + else + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + SetActive(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapTlsPeapCertInterface::ReadCACertificateL(SCertEntry& aCertInfo) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapTlsPeapCertInterface::ReadCACertificateL.\n"))); + + iCertInfo = aCertInfo; + iState = EReadCACertInitStore; + + if (iCertStore == 0) + { + iCertStore = CUnifiedCertStore::NewL(iFs, false); + iCertStore->Initialize(iStatus); + } + else + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + SetActive(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + + +//-------------------------------------------------- + +void CEapTlsPeapCertInterface::ValidateChainL(TDesC8& aCertChain, RArray& aAllowedCACerts) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + iCAIndex = 0; + iAllowedCACerts = aAllowedCACerts; + delete iInputCertChain; + + iInputCertChain = 0; + iInputCertChain = aCertChain.AllocL(); + iState = EValidateChainInitStore; + if (iCertStore == 0) + { + iCertStore = CUnifiedCertStore::NewL(iFs, false); + iCertStore->Initialize(iStatus); + } + else + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + SetActive(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapTlsPeapCertInterface::DoCancel() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::DoCancel()\n"))); + + if (iCertStore != 0 && iCertStore->IsActive()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::DoCancel(): calls iCertStore->CancelInitialize and other cancels()\n"))); + + iCertStore->CancelInitialize(); + iCertStore->CancelList(); + iCertStore->CancelGetCert(); + iCertStore->CancelRetrieve(); + } + + // We have to cancel singing if it is ongoing. Both for RSA and DSA. + if(iRSASigner != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::DoCancel(): calls iRSASigner->CancelSign()\n"))); + + iRSASigner->CancelSign(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::DoCancel(): calls iRSASigner->Release()\n"))); + + iRSASigner->Release(); // This seems to be needed. + } + + if(iDSASigner != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::DoCancel(): calls iDSASigner->CancelSign()\n"))); + + iDSASigner->CancelSign(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::DoCancel(): calls iDSASigner->Release()\n"))); + + iDSASigner->Release(); // This seems to be needed. + } + + // We have to cancel decrypting if it is ongoing. + if(iDecryptor != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::DoCancel(): calls iDecryptor->CancelDecrypt()\n"))); + + iDecryptor->CancelDecrypt(); + } + + if (iKeyStore != 0 && iKeyStore->IsActive()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::DoCancel(): calls iKeyStore->CancelOpen()\n"))); + + iKeyStore->CancelOpen(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::DoCancel(): calls iKeyStore->Cancel()\n"))); + + iKeyStore->Cancel(); + } + + if (iCertChain != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::DoCancel(): calls iCertChain->CancelValidate()\n"))); + + iCertChain->CancelValidate(); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::DoCancel(): returns\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapTlsPeapCertInterface::SignL( + TKeyIdentifier& aKeyId, + const TDesC8& aHashIn, + const TUint aSignatureLength) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + iKeyIdentifier = aKeyId; + if (aHashIn.Size() > KMaxHashLength) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Illegal hash size to SignL.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + iHashIn.Copy(aHashIn); + + delete iSignature; + iSignature = 0; + + // Allocate space for the signature + iSignature = HBufC8::NewL(aSignatureLength); + + delete iSignaturePtr; + iSignaturePtr = 0; + + iSignaturePtr = new(ELeave) TPtr8(iSignature->Des()); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("SignL: aKeyId"), + aKeyId.Ptr(), + aKeyId.Length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("SignL: aHashIn"), + aHashIn.Ptr(), + aHashIn.Length())); + + + if (iKeyStore == 0) + { + // Try to get the keystore class pointer from memory store + eap_variable_data_c key(m_am_tools); + eap_status_e status = key.set_copy_of_buffer(KKeyStoreHandlePrefix, sizeof(KKeyStoreHandlePrefix)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + status = key.add_data(KKeyStoreHandleKey, sizeof(KKeyStoreHandleKey)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + + eap_tlv_message_data_c tlv_data(m_am_tools); + + status = m_am_tools->memory_store_get_data(&key, &tlv_data); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLSPEAP: cannot get previous keystore handle.\n"))); + + + // At this point we can set the passphrase timeout because it the passphrase + // cache in the FS token server is still empty. Passphrase timeout setting clears + // the cache. + iState = ESignInitStore; + + iKeyStore = CUnifiedKeyStore::NewL(iFs); + iKeyStore->Initialize(iStatus); + + status = tlv_data.add_message_data( + eap_type_tlspeap_stored_keystore_handle, + sizeof(iKeyStore), + &iKeyStore); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + + status = m_am_tools->memory_store_add_data( + &key, + &tlv_data, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + } + else + { + + status = m_am_tools->memory_store_get_data(&key, &tlv_data); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLSPEAP: Found previous keystore handle.\n"))); + + // Parse read data. + eap_array_c tlv_blocks(m_am_tools); + + status = tlv_data.parse_message_data(&tlv_blocks); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + + if (tlv_blocks.get_object_count() > 0) + { + eap_tlv_header_c * const tlv = tlv_blocks.get_object(0); + if (tlv != 0) + { + if (tlv->get_type() == eap_type_tlspeap_stored_keystore_handle) + { + iKeyStore = *(reinterpret_cast(tlv->get_value(tlv->get_value_length()))); + + // Skip passphrase setting because it clears the passphrase cache + iState = ESetPassphraseTimeout; + + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + } + } + else + { + // Skip passphrase setting because it clears the passphrase cache + iState = ESetPassphraseTimeout; + + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + SetActive(); + + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapTlsPeapCertInterface::DecryptL( + TKeyIdentifier& aKeyId, + const TDesC8& aDataIn) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + iKeyIdentifier = aKeyId; + + delete iDataIn; + iDataIn = 0; + delete iDataOut; + iDataOut = 0; + + iDataIn = HBufC8::NewL(aDataIn.Length()); + iDataOut = HBufC8::NewL(aDataIn.Length()); + + delete iPtrOut; + iPtrOut = 0; + + iPtrOut = new(ELeave) TPtr8(iDataOut->Des()); + TPtr8 ptrIn = iDataIn->Des(); + + ptrIn.Copy(aDataIn); + + iState = EDecryptInitStore; + + // Try to get the keystore handler class from memory store + if (iKeyStore == 0) + { + // Try to get the keystore class pointer from memory store + eap_variable_data_c key(m_am_tools); + eap_status_e status = key.set_copy_of_buffer(KKeyStoreHandlePrefix, sizeof(KKeyStoreHandlePrefix)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + status = key.add_data(KKeyStoreHandleKey, sizeof(KKeyStoreHandleKey)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + + eap_tlv_message_data_c tlv_data(m_am_tools); + + status = m_am_tools->memory_store_get_data(&key, &tlv_data); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLSPEAP: cannot get previous keystore handle.\n"))); + + iKeyStore = CUnifiedKeyStore::NewL(iFs); + iKeyStore->Initialize(iStatus); + + status = tlv_data.add_message_data( + eap_type_tlspeap_stored_keystore_handle, + sizeof(iKeyStore), + &iKeyStore); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + + status = m_am_tools->memory_store_add_data( + &key, + &tlv_data, + 0); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP_type_TLSPEAP: Found previous keystore handle.\n"))); + + // Parse read data. + eap_array_c tlv_blocks(m_am_tools); + + status = tlv_data.parse_message_data(&tlv_blocks); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + + if (tlv_blocks.get_object_count() > 0) + { + eap_tlv_header_c * const tlv = tlv_blocks.get_object(0); + if (tlv != 0) + { + if (tlv->get_type() == eap_type_tlspeap_stored_keystore_handle) + { + iKeyStore = *(reinterpret_cast(tlv->get_value(tlv->get_value_length()))); + + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrGeneral); + } + } + } + else + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + + SetActive(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void CEapTlsPeapCertInterface::RunL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapCertInterface::RunL(): TEMP iStatus=%d, iState=%d"), + iStatus.Int(), iState)); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): iStatus %d\n"), + iStatus.Int())); + + if (!(iStatus.Int() == KErrNone)) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS certificate interface failed: %d.\n"), + iStatus.Int())); + iParent->SendErrorNotification(eap_status_user_cancel_authentication); + + if(iState == ESignOpenKeyStore) + { + // User probably cancelled the keystore password query. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapCertInterface::RunL(): ESignOpenKeyStore Failed"))); + + if(iRSASigner != NULL) + { + iRSASigner->Release(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapCertInterface::RunL(): iRSASigner->Release() OK"))); + + } + + if(iDSASigner != NULL) + { + iDSASigner->Release(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapCertInterface::RunL(): iDSASigner->Release() OK"))); + } + } + + return; + } + + switch (iState) + { + + case EGetMatchingCertsInitStore: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EGetMatchingCertsInitStore\n"))); + + // Set up filter + delete iCertFilter; + iCertFilter = 0; + + for (TInt i = 0; i < iCertInfos.Count(); i++) + { + iCertInfos[i]->Release(); + } + iCertInfos.Reset(); + + TRAPD(err, iCertFilter = CCertAttributeFilter::NewL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + CArrayFixFlat tmp(sizeof(SCertEntry)); + + m_am_tools->enter_global_mutex(); + + iParent->complete_get_matching_certificates(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + break; + } + + iCertFilter->SetFormat(EX509Certificate); + iCertFilter->SetOwnerType(EUserCertificate); + + iState = EGetMatchingCertsInitialize; + iCertStore->List( + iCertInfos, + *iCertFilter, + iStatus); + SetActive(); + + } + break; + + case EGetMatchingCertsInitialize: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EGetMatchingCertsInitialize, Total Certs: iCertInfos.Count()=%d\n"), + iCertInfos.Count())); + + iMatchingUserCertInfos.Reset(); + + // Remove non-allowed + TInt i(0); + TInt j(0); + for (i = 0; i < iCertInfos.Count(); i++) + { + for (j = 0; j < iAllowedUserCerts.Count(); j++) + { + if ( (iCertInfos[i]->Label().Compare(iAllowedUserCerts[j].iLabel) == 0 + || iCertInfos[i]->Label().Length() == 0 + || iAllowedUserCerts[j].iLabel.Length() == 0) + && iCertInfos[i]->SubjectKeyId() == iAllowedUserCerts[j].iSubjectKeyId) + { + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RunL(): EGetMatchingCertsInitialize, Found a Matching USER cert\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RunL(): EGetMatchingCertsInitialize,Label of matching cert=%S\n"), + &(iCertInfos[i]->Label()))); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("RunL(): EGetMatchingCertsInitialize,SubjectkeyID of matching cert", + iCertInfos[i]->SubjectKeyId().Ptr(), iCertInfos[i]->SubjectKeyId().Size())); + + break; + } + } + if (j == iAllowedUserCerts.Count()) + { + // Not allowed -> remove + iCertInfos.Remove(i); + i--; + } + } + if (iCertInfos.Count() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EGetMatchingCertsInitialize - No matching Certificates.\n"))); + + // No matching certs + + CArrayFixFlat* tmp = NULL; + + TRAPD(err, tmp = new (ELeave) CArrayFixFlat(1) ); + if (tmp == 0 || err != KErrNone) + { + // Timeout handles error situation + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + } + + m_am_tools->enter_global_mutex(); + + iParent->complete_get_matching_certificates(*tmp, eap_status_illegal_certificate); //Failure + + m_am_tools->leave_global_mutex(); + + delete tmp; + break; + } + + // Get the first certificate + iUserCertIndex = 0; + + iMatchingUserCerts.ResetAndDestroy(); + + iState = EGetMatchingCertsLoop; + + iEncodedCertificate->Des().SetLength(0); + + TRAPD(err, iEncodedCertificate = iEncodedCertificate->ReAllocL(iCertInfos[iUserCertIndex]->Size())); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + CArrayFixFlat tmp(sizeof(SCertEntry)); + + m_am_tools->enter_global_mutex(); + + iParent->complete_get_matching_certificates(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + iCertPtr.Set(iEncodedCertificate->Des()); + + iCertStore->Retrieve( + *(iCertInfos[iUserCertIndex]), + iCertPtr, + iStatus); + + SetActive(); + } + break; + + case EGetMatchingCertsLoop: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EGetMatchingCertsLoop\n"))); + + CX509Certificate* cert = 0; + TRAPD(err, cert = CX509Certificate::NewL(iEncodedCertificate->Des())); + if (err != KErrNone || cert == 0) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + CArrayFixFlat tmp(sizeof(SCertEntry)); + + m_am_tools->enter_global_mutex(); + + iParent->complete_get_matching_certificates(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + if (iMatchingUserCerts.Append(cert) != KErrNone) + { + delete cert; + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + CArrayFixFlat tmp(sizeof(SCertEntry)); + + m_am_tools->enter_global_mutex(); + + iParent->complete_get_matching_certificates(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + // No need to validate iCertInfos here as the execution doesn't come to this case if iCertInfos + // is empty, check is done in the above case. + + SCertEntry entry; + entry.iLabel.Copy(iCertInfos[iUserCertIndex]->Label()); + entry.iSubjectKeyId = iCertInfos[iUserCertIndex]->SubjectKeyId(); + + TRAP(err, iMatchingUserCertInfos.AppendL(entry)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + CArrayFixFlat tmp(sizeof(SCertEntry)); + + m_am_tools->enter_global_mutex(); + + iParent->complete_get_matching_certificates(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + iUserCertIndex++; + + if (iUserCertIndex >= static_cast(iCertInfos.Count())) + { + // Check each item in iMatchingUserCerts against filters + TInt i(0); + + // CA filter + if (iUseCertAuthoritiesFilter) + { + for (i = 0; i < iMatchingUserCerts.Count(); i++) + { + const CX500DistinguishedName& dn = iMatchingUserCerts[i]->IssuerName(); + + TInt j(0); + + for (j = 0; j < iCertAuthorities.Count(); j++) + { + if (dn.ExactMatchL(*iCertAuthorities[j])) + { + // Matches + break; + } + } + if (j == iCertAuthorities.Count()) + { + // No match. Remove + delete iMatchingUserCerts[i]; + iMatchingUserCerts.Remove(i); + iMatchingUserCertInfos.Delete(i); + i--; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RunL(): EGetMatchingCertsLoop Using CertAuthoritiesFilter - no distinguished name matching - Matching cert removed\n"))); + } + } + } + // Check Certificate types + if (iUseCertTypesFilter) + { + for (i = 0; i < (TInt) iMatchingUserCerts.Count(); i++) + { + // Get the public key algorithm + const CSubjectPublicKeyInfo& public_key = iMatchingUserCerts[i]->PublicKey(); + TAlgorithmId algorithm = public_key.AlgorithmId(); + + TUint j(0); + for (j = 0; j < iCertTypes->get_object_count(); j++) + { + u8_t* val = iCertTypes->get_object(j); + if (algorithm == ERSA + && (*val == ERSASign + || *val == ERSASignWithFixedDH + || *val == ERSASignWithEphemeralDH)) + { + break; + } + if (algorithm == EDSA + && (*val == EDSASign + || *val == EDSASignWithFixedDH + || *val == EDSASignWithEphemeralDH)) + { + break; + } + } + if (j == iCertTypes->get_object_count()) + { + // No match. Remove + delete iMatchingUserCerts[i]; + iMatchingUserCerts.Remove(i); + iMatchingUserCertInfos.Delete(i); + i--; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RunL(): EGetMatchingCertsLoop Using CertTypesFilter - Public key algorithm(%d) or Signing methods NOT matching - Matching cert removed\n"), + algorithm)); + } + + } + } + // Check cipher suites + if (iUseAllowedCipherSuitesFilter) + { + for (i = 0; i < static_cast (iMatchingUserCerts.Count()); i++) + { + // Get the public key algorithm + const CSubjectPublicKeyInfo& public_key = iMatchingUserCerts[i]->PublicKey(); + TAlgorithmId algorithm = public_key.AlgorithmId(); + + // IF it is RSA certificate that is not allowed + if (algorithm == ERSA && iRSACertsAllowed == EFalse + // OR it is DSA certificate that is not allowed + || (algorithm == EDSA && iDSACertsAllowed == EFalse) + // OR it is some other type + || (algorithm != ERSA && algorithm != EDSA)) + { + // No match. Remove + delete iMatchingUserCerts[i]; + iMatchingUserCerts.Remove(i); + iMatchingUserCertInfos.Delete(i); + i--; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("RunL(): EGetMatchingCertsLoop Using AllowedCipherSuitesFilter - Cert is NOT allowed (RSACertsAllowed=%d,DSACertsAllowed=%d) for this Public key algorithm(%d) - Matching cert removed\n"), + iRSACertsAllowed, iDSACertsAllowed, algorithm)); + } + } + } + // Return the certificates. + m_am_tools->enter_global_mutex(); + + iParent->complete_get_matching_certificates(iMatchingUserCertInfos, eap_status_ok); + + m_am_tools->leave_global_mutex(); + } + else + { + + iState = EGetMatchingCertsLoop; + + iEncodedCertificate->Des().SetLength(0); + + TRAPD(err, iEncodedCertificate = iEncodedCertificate->ReAllocL(iCertInfos[iUserCertIndex]->Size())); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + CArrayFixFlat tmp(sizeof(SCertEntry)); + + m_am_tools->enter_global_mutex(); + + iParent->complete_get_matching_certificates(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + iCertPtr.Set(iEncodedCertificate->Des()); + + iCertStore->Retrieve( + *(iCertInfos[iUserCertIndex]), + iCertPtr, + iStatus); + + SetActive(); + } + } + break; + + case EReadCertInitStore: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EReadCertInitStore\n"))); + + // Set up filter + delete iCertFilter; + iCertFilter = 0; + + for (TInt i = 0; i < iCertInfos.Count(); i++) + { + iCertInfos[i]->Release(); + } + iCertInfos.Reset(); + + TRAPD(err, iCertFilter = CCertAttributeFilter::NewL()); + if (err != KErrNone || iCertFilter == 0) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + iCertFilter->SetFormat(EX509Certificate); + iCertFilter->SetOwnerType(EUserCertificate); + iCertFilter->SetSubjectKeyId(iCertInfo.iSubjectKeyId); + if (iCertInfo.iLabel.Size()>0) + iCertFilter->SetLabel(iCertInfo.iLabel); // We can not use Label in the filter as certificates saved + // by using SetConfigurationL (OMA DM etc uses it) will not have Label. + + iState = EReadCertList; + iCertStore->List( + iCertInfos, + *iCertFilter, + iStatus); + SetActive(); + + } + break; + + case EReadCertList: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EReadCertList\n"))); + + // Now we should have all the cert infos in iCertInfos. + if (iCertInfos.Count() == 0) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EReadCertList iCertInfos.Count = 0.\n"))); + + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_illegal_certificate); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + // Just take the first found certificate + CCTCertInfo* info; + info = iCertInfos[0]; + + iState = EReadCert; + + iEncodedCertificate->Des().SetLength(0); + + TRAPD(err, iEncodedCertificate = iEncodedCertificate->ReAllocL(info->Size())); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + iCertPtr.Set(iEncodedCertificate->Des()); + + iCertStore->Retrieve( + *info, + iCertPtr, + iStatus); + + SetActive(); + } + break; + case EReadCert: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EReadCert\n"))); + + CX509Certificate* cert = 0; + TRAPD(err, cert = CX509Certificate::NewL(iEncodedCertificate->Des())); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + iUserCertChain.ResetAndDestroy(); + if (iUserCertChain.Append(cert) != KErrNone) + { + delete cert; + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL()-EReadCert: iRetrieveChain=%d\n"), + iRetrieveChain)); + if (iRetrieveChain) + { + // Init Symbian store for cert fetching + iState = ERetrieveChainInitStore; + if (iCertStore == 0) + { + iCertStore = CUnifiedCertStore::NewL(iFs, false); + iCertStore->Initialize(iStatus); + } + else + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + SetActive(); + break; + } + + // Note that parent handles cert deletion from now on. + iParent->complete_read_own_certificate(iUserCertChain, eap_status_ok); + } + break; + + case ERetrieveChainInitStore: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): ERetrieveChainInitStore\n"))); + + // List all certificates + delete iCertFilter; + iCertFilter = 0; + + for (TInt i = 0; i < iCertInfos.Count(); i++) + { + iCertInfos[i]->Release(); + } + iCertInfos.Reset(); + + TRAPD(err, iCertFilter = CCertAttributeFilter::NewL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + iCertFilter->SetFormat(EX509Certificate); + iCertFilter->SetOwnerType(ECACertificate); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): For chain init store, we need CA certificates only\n"))); + + iState = EGetAllCerts; + iCertStore->List( + iCertInfos, + *iCertFilter, + iStatus); + SetActive(); + } + break; + + case EGetAllCerts: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EGetAllCerts\n"))); + + // Now we should have all the cert infos in iCertInfos. + + iRootCerts.ResetAndDestroy(); + + // Validate iCertInfos before using it. + if (iCertInfos.Count() == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EGetAllCerts - No matching Certificates.\n"))); + + // No matching certs. The authentication should fail now. So complete the request with an + // empty chain. + + iUserCertChain.ResetAndDestroy(); + + m_am_tools->enter_global_mutex(); + + // Note that parent handles cert deletion from now on. + iParent->complete_read_own_certificate(iUserCertChain, eap_status_illegal_certificate); + + m_am_tools->leave_global_mutex(); + + break; + } + + CCTCertInfo* info; + info = iCertInfos[0]; + iCAIndex = 0; + + iState = ECreateCertChain; + + iEncodedCertificate->Des().SetLength(0); + TRAPD(err, iEncodedCertificate = iEncodedCertificate->ReAllocL(info->Size())); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + iCertPtr.Set(iEncodedCertificate->Des()); + + iCertStore->Retrieve( + *info, + iCertPtr, + iStatus); + + SetActive(); + } + break; + + case ECreateCertChain: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): ECreateCertChain\n"))); + + CX509Certificate* cert = 0; + TRAPD(err, cert = CX509Certificate::NewL(iEncodedCertificate->Des())); + if (err != KErrNone || cert == 0) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + +#if defined(_DEBUG) || defined(DEBUG) + + // No need to validate iCertInfos in here as it is done in case: EGetAllCerts + CCTCertInfo* tempInfo; + tempInfo = iCertInfos[iCAIndex]; + + // These are for the trace debug. + TCertLabel label = tempInfo->Label(); + TKeyIdentifier KeyIdentifier = tempInfo->SubjectKeyId(); + TKeyIdentifier IssuerId = tempInfo->IssuerKeyId(); + TCertificateFormat format = tempInfo->CertificateFormat(); + TCertificateOwnerType ownerType = tempInfo->CertificateOwnerType(); + + EAP_TRACE_DEBUG_SYMBIAN((_L("\n CEapTlsPeapCertInterface::RunL() : About to retrieve Cert with details, Label = %S"), &label)); + EAP_TRACE_DEBUG_SYMBIAN((_L("Other detials- Format=%d, Owner type=%d, IsDeletable=%d, Type UID=%d"), + format, ownerType, tempInfo->IsDeletable(), tempInfo->Type())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Subject key Id is"), + KeyIdentifier.Ptr(), + KeyIdentifier.Size())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Issuer Id is"), + IssuerId.Ptr(), + IssuerId.Size())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL()- NEW subject key id stuff\n"))); + + if( cert != NULL ) + { + const CX509CertExtension* certExt = cert->Extension(KSubjectKeyId); + + if (certExt) + { + const CX509SubjectKeyIdExt* subKeyExt = CX509SubjectKeyIdExt::NewLC(certExt->Data()); + EAP_UNREFERENCED_PARAMETER(subKeyExt); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("NEW Subject key Id is:"), + subKeyExt->KeyId().Ptr(), + subKeyExt->KeyId().Size())); + + CleanupStack::PopAndDestroy(); // subKeyIdExt + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("WARNING: No extension for this certificate\n"))); + } + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: No Certs here!\n"))); + } + +#endif + + + // Signal completition + if (iRootCerts.Append(cert) != KErrNone) + { + delete cert; + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL()-ECreateCertChain: iCAIndex=%d, iRootCerts.Count()=%d, iUserCertChain.Count()= %d, iCertInfos-count=%d\n"), + iCAIndex, iRootCerts.Count(), iUserCertChain.Count(), iCertInfos.Count())); + + iCAIndex++; + if (iCAIndex >= static_cast(iCertInfos.Count())) + { + if(iUserCertChain.Count() == 0) + { + iParent->complete_read_own_certificate(iUserCertChain, eap_status_ca_certificate_unknown); + break; + } + + // We got all. Validate. + TInt i(0); + for (i = 0; i < iRootCerts.Count(); i++) + { + if (iUserCertChain[iUserCertChain.Count()-1]->IsSelfSignedL()) + { + // The last cert in chain is self-signed. Our chain is ready. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL()-ECreateCertChain: The last cert in chain is self-signed\n"))); + + break; + } + if (iUserCertChain[iUserCertChain.Count()-1]->IssuerName().ExactMatchL(iRootCerts[i]->SubjectName())) + { + // DNs match. Check signature. + if (iUserCertChain[iUserCertChain.Count()-1]->PublicKey().AlgorithmId() != iRootCerts[i]->PublicKey().AlgorithmId()) + { + // The algorithms differ. + continue; + } + CDSAParameters* dsaParams = 0; + CSigningKeyParameters* signParams = 0; + + if (iUserCertChain[iUserCertChain.Count()-1]->PublicKey().AlgorithmId() == EDSA) + { + // DSA signing + const CSubjectPublicKeyInfo& key = iRootCerts[i]->PublicKey(); + const TPtrC8 params = key.EncodedParams(); + + TRAPD(err, dsaParams = CX509DSAPublicKey::DSAParametersL(params)); + if (err != KErrNone) + { + + RPointerArray tmp; + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + return; + } + + TRAP(err, signParams = CSigningKeyParameters::NewL()); + if (err != KErrNone) + { + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + delete dsaParams; + return; + } + TRAP(err, signParams->SetDSAParamsL(*dsaParams)); + if (err != KErrNone) + { + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + delete dsaParams; + delete signParams; + return; + } + + TRAP(err, iUserCertChain[iUserCertChain.Count()-1]->SetParametersL(*signParams)); + if (err != KErrNone) + { + RPointerArray tmp; + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + delete dsaParams; + delete signParams; + return; + } + } + + if (iUserCertChain[iUserCertChain.Count()-1]->VerifySignatureL(iRootCerts[i]->PublicKey().KeyData())) + { + // This is the next item in the chain. + if (iUserCertChain.Append(iRootCerts[i]) != KErrNone) + { + delete dsaParams; + delete signParams; + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_own_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + return; + } + // Remove the copied pointer from original list + iRootCerts.Remove(i); + i--; + } + // delete all + delete dsaParams; + delete signParams; + } + } + + iRootCerts.ResetAndDestroy(); + + // The chain is complete + m_am_tools->enter_global_mutex(); + + // Note that parent handles cert deletion from now on. + iParent->complete_read_own_certificate(iUserCertChain, eap_status_ok); + + m_am_tools->leave_global_mutex(); + + } + else // if (iCAIndex >= static_cast(iCertInfos.Count())) + { + CCTCertInfo* info; + info = iCertInfos[iCAIndex]; // No need to vvalidate iCertInfos, as execution comes + // here only if iCertInfos has more items than iCAIndex + + iState = ECreateCertChain; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL()- ECreateCertChain - Before Retrieve(): iCAIndex=%d, size=%d\n"), + iCAIndex, info->Size())); + + + + iEncodedCertificate->Des().SetLength(0); + TRAPD(err, iEncodedCertificate = iEncodedCertificate->ReAllocL(info->Size())); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_ca_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + + break; + } + + iCertPtr.Set(iEncodedCertificate->Des()); + + iCertStore->Retrieve( + *info, + iCertPtr, + iStatus); + + SetActive(); + } + } + break; + + case EReadCACertInitStore: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EReadCACertInitStore\n"))); + + // Set up filter + delete iCertFilter; + iCertFilter = 0; + + for (TInt i = 0; i < iCertInfos.Count(); i++) + { + iCertInfos[i]->Release(); + } + iCertInfos.Reset(); + + TRAPD(err, iCertFilter = CCertAttributeFilter::NewL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_ca_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + break; + } + + iCertFilter->SetFormat(EX509Certificate); + iCertFilter->SetOwnerType(ECACertificate); + iCertFilter->SetSubjectKeyId(iCertInfo.iSubjectKeyId); + if (iCertInfo.iLabel.Size()>0) + iCertFilter->SetLabel(iCertInfo.iLabel);// We can not use Label in the filter as certificates saved + // by using SetConfigurationL (OMA DM etc uses it) will not have Label. + + iState = EReadCACertList; + iCertStore->List( + iCertInfos, + *iCertFilter, + iStatus); + SetActive(); + + } + break; + + case EReadCACertList: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EReadCACertList\n"))); + + // Now we should have all the cert infos in iCertInfos. + if (iCertInfos.Count() == 0) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EReadCACertList iCertInfos.Count = 0.\n"))); + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_ca_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + break; + } + + // Just take the first found certificate + CCTCertInfo* info; + info = iCertInfos[0]; + + iState = EReadCACert; + + iEncodedCertificate->Des().SetLength(0); + + TRAPD(err, iEncodedCertificate = iEncodedCertificate->ReAllocL(info->Size())); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_ca_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + break; + } + + iCertPtr.Set(iEncodedCertificate->Des()); + + iCertStore->Retrieve( + *info, + iCertPtr, + iStatus); + + SetActive(); + } + break; + + case EReadCACert: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EReadCACert\n"))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL():EncodedCertificate string size=%d\n"), + iEncodedCertificate->Size())); + + CX509Certificate* cert = 0; + TRAPD(err, cert = CX509Certificate::NewL(iEncodedCertificate->Des())); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_ca_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + break; + } + + // Use iUserCertChain on purpose for this anyway even though this is CA cert. + iUserCertChain.ResetAndDestroy(); + if (iUserCertChain.Append(cert) != KErrNone) + { + delete cert; + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + RPointerArray tmp; + + m_am_tools->enter_global_mutex(); + + iParent->complete_read_ca_certificate(tmp, eap_status_allocation_error); //Failure + + m_am_tools->leave_global_mutex(); + break; + } + + // Note that parent handles cert deletion from now on. + iParent->complete_read_ca_certificate(iUserCertChain, eap_status_ok); + } + break; + + case EValidateChainInitStore: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EValidateChainInitStore\n"))); + + delete iCertFilter; + iCertFilter = 0; + + for (TInt i = 0; i < iCertInfos.Count(); i++) + { + iCertInfos[i]->Release(); + } + iCertInfos.Reset(); + + TRAPD(err, iCertFilter = CCertAttributeFilter::NewL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + CPKIXValidationResult* tmp = 0; + + m_am_tools->enter_global_mutex(); + + iParent->complete_validate_chain(*tmp, eap_status_ca_certificate_unknown); //Failure. + + m_am_tools->leave_global_mutex(); + break; + } + iCertFilter->SetOwnerType(ECACertificate); + iCertFilter->SetFormat(EX509Certificate); + + iState = EValidateChainGetCACertList; + iCertStore->List( + iCertInfos, + *iCertFilter, + iStatus); + SetActive(); + } + break; + + case EValidateChainGetCACertList: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EValidateChainGetCACertList\n"))); + + int index; + TIdentityRelation comparator(&EapTlsPeapUtils::CompareSCertEntries); + // Remove disallowed CA certs from the array + for (TInt i = 0; i < iCertInfos.Count(); i++) + { + SCertEntry certEntry; + certEntry.iLabel.Copy(iCertInfos[i]->Label()); + certEntry.iSubjectKeyId.Copy(iCertInfos[i]->SubjectKeyId()); + index = iAllowedCACerts.Find(certEntry, comparator); + + if (index == KErrNotFound) + { + // Remove + iCertInfos[i]->Release(); + iCertInfos.Remove(i); + i--; + } + } + if (iCertInfos.Count() == 0) + { + // Create new validation result for this failure case. + // CPKIXValidationResult does include a Reset-member function + // but it is not in x500.lib as the documentation says. + CPKIXValidationResult* validationResult = 0; + TRAPD(err, validationResult = CPKIXValidationResult::NewL()); + if (err != KErrNone) + { + // Do nothing. Session timeout takes care of cleanup... + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + } + m_am_tools->enter_global_mutex(); + + iParent->complete_validate_chain(*validationResult, eap_status_ca_certificate_unknown); //Failure. + + m_am_tools->leave_global_mutex(); + delete validationResult; + break; + } + + CCTCertInfo* info; + info = iCertInfos[0]; + iCAIndex = 0; + + iState = EValidateChainGetCACert; + + iEncodedCertificate->Des().SetLength(0); + TRAPD(err, iEncodedCertificate = iEncodedCertificate->ReAllocL(info->Size())); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + + CPKIXValidationResult* tmp = 0; + + m_am_tools->enter_global_mutex(); + + iParent->complete_validate_chain(*tmp, eap_status_ca_certificate_unknown); //Failure. + + m_am_tools->leave_global_mutex(); + break; + } + + iCertPtr.Set(iEncodedCertificate->Des()); + + iCertStore->Retrieve( + *info, + iCertPtr, + iStatus); + + SetActive(); + } + break; + + case EValidateChainGetCACert: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EValidateChainGetCACert\n"))); + + CX509Certificate* cert = 0; + TRAPD(err, cert = CX509Certificate::NewL(iEncodedCertificate->Des())); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + CPKIXValidationResult* tmp = 0; + + m_am_tools->enter_global_mutex(); + + iParent->complete_validate_chain(*tmp, eap_status_ca_certificate_unknown); //Failure. + + m_am_tools->leave_global_mutex(); + break; + } + + // Signal completition + if (iRootCerts.Append(cert) != KErrNone) + { + delete cert; + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + CPKIXValidationResult* tmp = 0; + + m_am_tools->enter_global_mutex(); + + iParent->complete_validate_chain(*tmp, eap_status_ca_certificate_unknown); //Failure. + + m_am_tools->leave_global_mutex(); + break; + } + + iCAIndex++; + if (iCAIndex >= static_cast(iCertInfos.Count())) + { + delete iCertChain; + iCertChain = 0; + + TRAPD(err, iCertChain = CPKIXCertChain::NewL(iFs, *iInputCertChain, iRootCerts)); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAP-TLS error %d.\n"), err)); + CPKIXValidationResult* tmp = 0; + + m_am_tools->enter_global_mutex(); + + iParent->complete_validate_chain(*tmp, eap_status_ca_certificate_unknown); //Failure. + + m_am_tools->leave_global_mutex(); + break; + } + // Set the current time + iTime.UniversalTime(); + iState = EValidateChainEnd; + TRAP(err, iCertChain->ValidateL(*iValidationResult, iTime, iStatus)); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Error in certificate validation in EAP-TLS.\n"))); + CPKIXValidationResult* tmp = 0; + + m_am_tools->enter_global_mutex(); + + iParent->complete_validate_chain(*tmp, eap_status_ca_certificate_unknown); //Failure. + + m_am_tools->leave_global_mutex(); + break; + } + SetActive(); // Validate. + } + else + { + CCTCertInfo* info; + info = iCertInfos[iCAIndex]; + + iState = EValidateChainGetCACert; + + iEncodedCertificate->Des().SetLength(0); + TRAPD(err, iEncodedCertificate = iEncodedCertificate->ReAllocL(info->Size())); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + CPKIXValidationResult* tmp = 0; + + m_am_tools->enter_global_mutex(); + + iParent->complete_validate_chain(*tmp, eap_status_ca_certificate_unknown); //Failure. + + m_am_tools->leave_global_mutex(); + break; + } + + iCertPtr.Set(iEncodedCertificate->Des()); + + iCertStore->Retrieve( + *info, + iCertPtr, + iStatus); + + SetActive(); + } + } + break; + + case EValidateChainEnd: + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EValidateChainEnd\n"))); + + m_am_tools->enter_global_mutex(); + + iParent->complete_validate_chain(*iValidationResult, eap_status_ok); + + m_am_tools->leave_global_mutex(); + // Ignore error because there is nothing that can be done. + break; + + case ESignInitStore: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): ESignInitStore\n"))); + + iState = ESetPassphraseTimeout; + iKeyStore->SetPassphraseTimeout(-1 , iStatus); + SetActive(); + } + break; + + case ESetPassphraseTimeout: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): ESetPassphraseTimeout\n"))); + + // Set up filter + delete iKeyFilter; + iKeyFilter = 0; + + TRAPD(err, iKeyFilter = new (ELeave) TCTKeyAttributeFilter); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + RInteger tmp; + iParent->complete_sign(tmp, tmp, eap_status_key_error); + break; + } + + iKeyFilter->iKeyId = iKeyIdentifier; + iKeyFilter->iPolicyFilter = TCTKeyAttributeFilter::EUsableKeys; + + iState = ESignList; + iKeyStore->List( + iKeyInfos, + *iKeyFilter, + iStatus); + SetActive(); + } + break; + + case ESignList: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): ESignList, iKeyInfos.Count=%d\n"), + iKeyInfos.Count())); + + if(iKeyInfos.Count() <= 0) + { + RInteger tmp; + iParent->complete_sign(tmp, tmp, eap_status_key_error); + break; + } + + iState = ESignOpenKeyStore; + + CKeyInfoBase::EKeyAlgorithm rsa(static_cast (1)); + + if (iKeyInfos[0]->Algorithm() == rsa) + { + // Note to the CodeScanner users. This function does not return any value. + (void)iKeyStore->Open( + iKeyInfos[0]->Handle(), + iRSASigner, + iStatus); + } + else + { + // Note to the CodeScanner users. This function does not return any value. + (void)iKeyStore->Open( + iKeyInfos[0]->Handle(), + iDSASigner, + iStatus); + } + SetActive(); + } + break; + + case ESignOpenKeyStore: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): ESignOpenKeyStore, iKeyInfos.Count=%d\n"), + iKeyInfos.Count())); + + if(iKeyInfos.Count() <= 0) + { + RInteger tmp; + iParent->complete_sign(tmp, tmp, eap_status_key_error); + break; + } + + iState = ESign; + + CKeyInfoBase::EKeyAlgorithm rsa(static_cast (1)); + + if (iKeyInfos[0]->Algorithm() == rsa) + { + iRSASigner->Sign( + iHashIn, + iRSASignature, + iStatus); + } + else + { + iDSASigner->Sign( + iHashIn, + iDSASignature, + iStatus); + } + + SetActive(); + } + break; + + case ESign: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): ESign, iKeyInfos.Count=%d\n"), + iKeyInfos.Count())); + + if(iKeyInfos.Count() <= 0) + { + RInteger tmp; + iParent->complete_sign(tmp, tmp, eap_status_key_error); + break; + } + + CKeyInfoBase::EKeyAlgorithm rsa(static_cast (1)); + + if (iKeyInfos[0]->Algorithm() == rsa) + { + // This is just dummy integer. It is ignored in RSA case. + RInteger R = RInteger::NewL(); + + CleanupStack::PushL(R); + + iParent->complete_sign(R, reinterpret_cast(iRSASignature->S()), eap_status_ok); + + CleanupStack::PopAndDestroy(); + + iRSASigner->Release(); // This seems to be needed. + } + else + { + iParent->complete_sign(reinterpret_cast(iDSASignature->R()), + reinterpret_cast(iDSASignature->S()), eap_status_ok); + + iDSASigner->Release(); // This seems to be needed. + } + } + break; + + case EDecryptInitStore: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EDecryptInitStore\n"))); + + // Set up filter + delete iKeyFilter; + iKeyFilter = 0; + + TRAPD(err, iKeyFilter = new (ELeave) TCTKeyAttributeFilter); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Out of memory in EAP-TLS.\n"))); + TBuf8<1> tmp; + iParent->complete_decrypt(tmp, eap_status_key_error); + break; + } + + iKeyFilter->iKeyId = iKeyIdentifier; + iKeyFilter->iPolicyFilter = TCTKeyAttributeFilter::EUsableKeys; + + iState = EDecryptList; + iKeyStore->List( + iKeyInfos, + *iKeyFilter, + iStatus); + SetActive(); + } + break; + + case EDecryptList: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EDecryptList, iKeyInfos.Count=%d\n"), + iKeyInfos.Count())); + + if(iKeyInfos.Count() <= 0) + { + TBuf8<1> tmp; + iParent->complete_decrypt(tmp, eap_status_key_error); + break; + } + + iState = EDecryptOpenKeyStore; + + // Note to the CodeScanner users. This function does not return any value. + (void)iKeyStore->Open( + iKeyInfos[0]->Handle(), + iDecryptor, + iStatus); + + SetActive(); + } + break; + + case EDecryptOpenKeyStore: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EDecryptOpenKeyStore\n"))); + + iState = EDecrypt; + + iDecryptor->Decrypt( + *iDataIn, + *iPtrOut, + iStatus); + + SetActive(); + } + break; + + case EDecrypt: + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): EDecrypt\n"))); + + iParent->complete_decrypt(*iPtrOut, eap_status_ok); + } + break; + + default: + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::RunL(): unknown %d\n"), + iState)); + break; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; +} + +void CEapTlsPeapCertInterface::CancelSignWithPrivateKey() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::CancelSignWithPrivateKey():Cancelling Signing - iState=%d (13=ESign)\n"), + iState)); + + if(IsActive()) + { + + // We have to cancel singing if it is ongoing. Both for RSA and DSA. + if(iRSASigner != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::CancelSignWithPrivateKey(): calls iRSASigner->CancelSign()\n"))); + + iRSASigner->CancelSign(); + } + + if(iDSASigner != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("CEapTlsPeapCertInterface::CancelSignWithPrivateKey(): calls iDSASigner->CancelSign()\n"))); + + iDSASigner->CancelSign(); + } + } +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/eap_am_type_tls_peap_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/eap_am_type_tls_peap_symbian.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,11374 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 388 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_tools.h" +#include "eap_am_type_tls_peap_symbian.h" +#include "abs_eap_am_crypto.h" +#include "abs_eap_am_mutex.h" +#include "eap_crypto_api.h" +#include "abs_eap_base_type.h" +#include "eap_type_tls_peap_types.h" +#include "eap_am_tools_symbian.h" +#include "abs_tls_am_services.h" +#include "eap_base_type.h" +#include "eap_array_algorithms.h" + +#include "EapTlsPeapUtils.h" +#include "EapTlsPeapDbDefaults.h" +#include "EapTlsPeapDbParameterNames.h" +#include "EapTlsPeapCertInterface.h" + +#include +#include +#include "eap_am_dh_primes.h" +#include +#include +#include "EapTlsPeapTimerValues.h" +#include "eap_state_notification.h" +#include "eap_am_trace_symbian.h" +#include "eap_automatic_variable.h" + +#if defined(USE_FAST_EAP_TYPE) +#include "abs_tls_am_application_eap_fast.h" +#include "eap_fast_strings.h" +#include "eap_fast_tlv_payloads.h" +//#include "eap_am_async_wait_symbian.h" +#include "EapFastActive.h" +#include "eap_tlv_header.h" +#include "eap_tlv_message_data.h" +#endif + +#include "eap_ttls_pap_active.h" + +#ifdef USE_PAC_STORE +#include "pac_store_db_symbian.h" +#include +#endif + +#ifdef USE_EAP_EXPANDED_TYPES +#include "eap_header_string.h" +#endif //#ifdef USE_EAP_EXPANDED_TYPES + +#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) +#include "eap_config.h" +#include "eap_file_config.h" +#include "eap_am_file_input_symbian.h" +#endif + +const TUint KMaxSqlQueryLength = 512; +const TUint KMaxDBFieldNameLength = 255; +const TUint KDSASignatureLength = 40; +const TInt KDefaultColumnInView_One = 1; // For DB view. +const TInt KMicroSecsInASecond = 1000000; // 1000000 micro seconds is 1 second. + +/** + * Length of the MAC address + */ +#ifdef USE_FAST_EAP_TYPE + const TUint8 KMacAddressLength = 6; +#endif +//-------------------------------------------------- + +eap_am_type_tls_peap_symbian_c::eap_am_type_tls_peap_symbian_c( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id) + : CActive(CActive::EPriorityStandard) + , m_index_type(aIndexType) + , m_index(aIndex) + , m_tunneling_type(aTunnelingType) + , m_partner(aPartner) + , m_am_tools(static_cast (aTools)) + , m_tls_am_partner(0) +#if defined(USE_FAST_EAP_TYPE) + , m_tls_application(0) + //, iWaitNoteCancelled( EFalse ) + , iEapFastActiveWaitNote( NULL ) + , iEapFastActiveNotes( NULL ) +#endif //#if defined(USE_FAST_EAP_TYPE) + , m_is_valid(false) + , m_is_client(aIsClient) + , m_current_eap_type(aEapType) + , m_max_count_of_session_resumes(0ul) + , m_cipher_suite(tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA) + , m_ca_certificate(0) + , m_own_certificate(0) + , m_peer_certificate(0) + , m_cert_if(0) + , m_receive_network_id(aTools) + , m_eap_identifier(0u) + , m_subject_key_id(0) + , m_allowed_user_certs(1) + , m_allowed_server_certs(1) + , m_peer_public_key(aTools) + , m_param_p(aTools) + , m_param_q(aTools) + , m_param_g(aTools) + , m_shutdown_was_called(false) + , m_identity_info(0) + , m_tunneled_type(eap_type_none) + , m_verify_certificate_realm(true) + , m_allow_subdomain_matching(false) + , m_latest_alert_description(tls_alert_description_none) + , m_use_manual_username(false) + , m_manual_username(aTools) + , m_use_manual_realm(false) + , m_manual_realm(aTools) + , m_tls_peap_server_authenticates_client_policy_flag(true) + , m_configured(false) + , m_max_session_time(0) +#if defined(USE_EAP_TLS_SESSION_TICKET) + , m_use_session_ticket(false) +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + +#if defined(USE_FAST_EAP_TYPE) + , m_received_tunnel_pac_in_session_ticket(0) + , m_received_user_authorization_pac_in_session_ticket(0) + , m_saved_pac_type(eap_fast_pac_type_none) + , m_completion_operation(eap_fast_completion_operation_none) + //, m_new_pac_tlv(aTools) + , m_verification_status(eap_status_process_general_error) + , m_pac_type(eap_fast_pac_type_none) + , m_PAC_store_password(aTools) + //, m_PAC_store_device_seed(aTools) + , m_imported_PAC_data_password(aTools) + , m_PAC_store_path(aTools) + , m_EAP_FAST_IAP_reference(aTools) + , m_EAP_FAST_Group_reference(aTools) + , m_EAP_FAST_import_path(aTools) + , m_eap_fast_completion_status(eap_status_process_general_error) + , m_eap_fast_pac_store_pending_operation(eap_fast_pac_store_pending_operation_none) + , m_references_and_data_blocks(aTools) + , m_new_references_and_data_blocks(aTools) + , m_ready_references_and_data_blocks(aTools) + , m_serv_unauth_prov_mode(false) + , m_serv_auth_prov_mode(false) + , m_is_notifier_connected(false) + , m_notifier_data_to_user(NULL) + , m_notifier_data_pckg_to_user(NULL) + , m_notifier_data_from_user(NULL) + , m_notifier_data_pckg_from_user(NULL) + , m_completed_with_zero(false) + , m_verificationStatus(false) + , m_data_reference(m_am_tools) + , m_notifier_complete(false) + , m_userResponse(m_am_tools) + , m_both_completed(0) + , m_both_asked(0) +#endif //#if defined(USE_FAST_EAP_TYPE) + +#ifdef USE_PAC_STORE + ,iPacStoreDb(NULL) +#endif + +#ifdef USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS +, m_skip_user_interactions(false) +, m_fileconfig(0) +#endif + + + + , iEapTtlsPapMaxSessionConfigTime( 0 ) + , iEapTtlsPapActive( NULL ) + +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + +#ifdef USE_EAP_EXPANDED_TYPES + + m_tunneling_vendor_type = m_tunneling_type.get_vendor_type(); + m_current_eap_vendor_type = m_current_eap_type.get_vendor_type(); + +#else + + m_tunneling_vendor_type = static_cast(m_tunneling_type); + m_current_eap_vendor_type = static_cast(m_current_eap_type); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + // Set the database table name based on the type + switch (m_current_eap_vendor_type) + { + case eap_type_tls: + m_db_table_name = KTlsDatabaseTableName; + m_db_user_cert_table_name = KTlsAllowedUserCertsDatabaseTableName; + m_db_ca_cert_table_name = KTlsAllowedCACertsDatabaseTableName; + m_db_cipher_suite_table_name = KTlsAllowedCipherSuitesDatabaseTableName; + m_db_name = KTlsDatabaseName; + break; + + case eap_type_peap: + m_db_table_name = KPeapDatabaseTableName; + m_db_user_cert_table_name = KPeapAllowedUserCertsDatabaseTableName; + m_db_ca_cert_table_name = KPeapAllowedCACertsDatabaseTableName; + m_db_cipher_suite_table_name = KPeapAllowedCipherSuitesDatabaseTableName; + m_db_name = KPeapDatabaseName; + break; + + case eap_type_ttls_plain_pap: + // use the same case as for eap_type_ttls; + // break is not needed + + case eap_type_ttls: + m_db_table_name = KTtlsDatabaseTableName; + m_db_user_cert_table_name = KTtlsAllowedUserCertsDatabaseTableName; + m_db_ca_cert_table_name = KTtlsAllowedCACertsDatabaseTableName; + m_db_cipher_suite_table_name = KTtlsAllowedCipherSuitesDatabaseTableName; + m_db_name = KTtlsDatabaseName; + break; + +#if defined (USE_FAST_EAP_TYPE) + case eap_type_fast: + m_db_table_name = KFastGeneralSettingsDBTableName; // General settings + m_db_fast_special_table_name = KFastSpecialSettingsDBTableName; // Special settings for only FAST + m_db_user_cert_table_name = KFastAllowedUserCertsDatabaseTableName; + m_db_ca_cert_table_name = KFastAllowedCACertsDatabaseTableName; + m_db_cipher_suite_table_name = KFastAllowedCipherSuitesDatabaseTableName; + m_db_name = KFastDatabaseName; + break; +#endif // #if defined (USE_FAST_EAP_TYPE) + default: + { + // Unsupported type + // Should never happen + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("Unsupported EAP type, m_current_eap_vendor_type=%d \n"), + m_current_eap_vendor_type)); + + return; + } + } + + if (receive_network_id != 0 + && receive_network_id->get_is_valid_data() == true) + { + eap_status_e status = m_receive_network_id.set_copy_of_network_id( + receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + return; + } + } + + set_is_valid(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +eap_am_type_tls_peap_symbian_c* eap_am_type_tls_peap_symbian_c::NewL( + abs_eap_am_tools_c * const aTools, + abs_eap_base_type_c * const aPartner, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const bool aIsClient, + const eap_am_network_id_c * const receive_network_id) +{ + if (aEapType != eap_type_tls + && aEapType != eap_type_peap +#if defined(USE_TTLS_EAP_TYPE) + && aEapType != eap_type_ttls +#endif // #if defined(USE_TTLS_EAP_TYPE) + + && aEapType != eap_type_ttls_plain_pap + +#if defined (USE_FAST_EAP_TYPE) + && aEapType != eap_type_fast +#endif // #if defined (USE_FAST_EAP_TYPE) + ) + { + User::Leave(KErrNotSupported); + } + + eap_am_type_tls_peap_symbian_c* self = new(ELeave) eap_am_type_tls_peap_symbian_c( + aTools, + aPartner, + aIndexType, + aIndex, + aTunnelingType, + aEapType, + aIsClient, + receive_network_id); + + CleanupStack::PushL(self); + + if (self->get_is_valid() != true) + { + User::Leave(KErrGeneral); + } + + self->ConstructL(); + + CleanupStack::Pop(); + return self; +} + +//-------------------------------------------------- + +// +void eap_am_type_tls_peap_symbian_c::ConstructL() +{ + // Open/create database + EapTlsPeapUtils::OpenDatabaseL(m_database, m_session, m_index_type, m_index, m_tunneling_type, m_current_eap_type); + + m_cert_if = CEapTlsPeapCertInterface::NewL(m_am_tools, this); + + CActiveScheduler::Add(this); + + // Create and open PAC store (only for EAP-FAST at the moment) +#ifdef USE_PAC_STORE +#ifdef USE_FAST_EAP_TYPE + + if(m_current_eap_type == eap_type_fast && iPacStoreDb == NULL) + { + iPacStoreDb = CPacStoreDatabase::NewL( this ); + User::LeaveIfNull(iPacStoreDb); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ConstructL Created PAC store"))); + + iPacStoreDb->OpenPacStoreL(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ConstructL Opened PAC store"))); + } + m_info_array.Reset(); + +#endif // End: #ifdef USE_FAST_EAP_TYPE +#endif // End: #ifdef USE_PAC_STORE + +#ifdef USE_FAST_EAP_TYPE + + if(m_current_eap_type == eap_type_fast) + { + m_notifier_data_to_user = new(ELeave) TEapFastNotifierStruct; + m_notifier_data_pckg_to_user = new(ELeave) TPckg (*m_notifier_data_to_user); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::ConstructL m_notifier_data_pckg_to_user"), + m_notifier_data_pckg_to_user->Ptr(), + m_notifier_data_pckg_to_user->Size())); + + m_notifier_data_from_user = new(ELeave) TEapFastNotifierStruct; + m_notifier_data_pckg_from_user = new(ELeave) TPckg (*m_notifier_data_from_user); + } +#endif // End: #ifdef USE_FAST_EAP_TYPE + + +} + +//-------------------------------------------------- + +// + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::shutdown() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: function: eap_am_type_tls_peap_symbian_c::shutdown()\n"), + (m_is_client == true ? "client": "server"))); + + if(IsActive()) + { + RDebug::Print( _L("eap_am_type_tls_peap_symbian_c::shutdown() cancelling active object") ); + Cancel(); + } + + else + { + if(m_cert_if->IsActive()) + { + m_cert_if->Cancel(); + } + } + + if ( iEapTtlsPapActive ) + { + if ( iEapTtlsPapActive->IsActive() ) + { + EAP_TRACE_DEBUG_SYMBIAN( + ( _L( " eap_am_type_tls_peap_symbian_c::shutdown() \ + Cancelling iEapTtlsPapActive." ) ) ); + iEapTtlsPapActive->Cancel(); + } + EAP_TRACE_DEBUG_SYMBIAN( + ( _L( " eap_am_type_tls_peap_symbian_c::shutdown() \ + Deleting iEapTtlsPapActive." ) ) ); + delete iEapTtlsPapActive; + iEapTtlsPapActive = NULL; + } + +#if defined(USE_FAST_EAP_TYPE) + if( m_is_notifier_connected ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L(" eap_am_type_tls_peap_symbian_c::shutdown - calling m_notifier.CancelNotifier"))); + if(IsActive()) + { + TInt error = m_notifier.CancelNotifier(KEapFastNotifierUid); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::shutdown - CancelNotifier=%d"), error)); + } + EAP_TRACE_DEBUG_SYMBIAN( + (_L(" eap_am_type_securid_symbian_c::shutdown - calling m_notifier.Close()"))); + + m_notifier.Close(); // Call close only if it is connected. + + m_is_notifier_connected = false; + + } // End: if( m_is_notifier_connected ) + + if (m_partner != NULL) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L(" eap_am_type_tls_peap_symbian_c::shutdown - Cancel timers ..."))); + + m_partner->cancel_timer( + this, + KRemoveIAPReferenceTimerID); + + m_partner->cancel_timer( + this, + KImportFileTimerID); + + m_partner->cancel_timer( + this, + KCompleteReadPacstoreTimerID); + + m_partner->cancel_timer( + this, + KHandleReadPacstoreTimerID); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L(" eap_am_type_tls_peap_symbian_c::shutdown - Timers canceled"))); + } + + if ( iEapFastActiveWaitNote ) + { + if ( iEapFastActiveWaitNote->IsActive() ) + { + iEapFastActiveWaitNote->Cancel(); + } + delete iEapFastActiveWaitNote; + iEapFastActiveWaitNote = NULL; + } + + if ( iEapFastActiveNotes ) + { + if ( iEapFastActiveNotes->IsActive() ) + { + iEapFastActiveNotes->Cancel(); + } + delete iEapFastActiveNotes; + iEapFastActiveNotes = NULL; + } +#endif // #if defined(USE_FAST_EAP_TYPE) + + + m_allowed_server_certs.Reset(); + m_allowed_ca_certs.Close(); + m_allowed_cipher_suites.Close(); + m_allowed_user_certs.Reset(); + +#ifdef USE_PAC_STORE +#ifdef USE_FAST_EAP_TYPE + + if(m_current_eap_type == eap_type_fast && iPacStoreDb != NULL) + { + iPacStoreDb->Close(); + } + + TInt count=0; + while (count < m_info_array.Count()) + { + delete m_info_array[count].iData; + delete m_info_array[count].iReference; + } + m_info_array.Reset(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L(" eap_am_type_tls_peap_symbian_c::shutdown - Arrays cleared"))); + +#endif // End: #ifdef USE_FAST_EAP_TYPE +#endif // End: #ifdef USE_PAC_STORE + + m_shutdown_was_called = true; + +#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) + delete m_fileconfig; + m_fileconfig = 0; +#endif + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: function: eap_am_type_tls_peap_symbian_c::shutdown() returns\n"), + (m_is_client == true ? "client": "server"))); + + return eap_status_ok; +} + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_type_tls_peap_symbian_c::~eap_am_type_tls_peap_symbian_c() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_am_type_tls_peap_symbian_c::~eap_am_type_tls_peap_symbian_c()"); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: function: eap_am_type_tls_peap_symbian_c::~eap_am_type_tls_peap_symbian_c()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_ASSERT(m_shutdown_was_called == true); + + m_database.Close(); + m_session.Close(); + +#ifdef USE_FAST_EAP_TYPE + + if(m_current_eap_type == eap_type_fast) + { + delete m_notifier_data_to_user; + delete m_notifier_data_pckg_to_user; + + delete m_notifier_data_from_user; + delete m_notifier_data_pckg_from_user; + } +#endif // End: #ifdef USE_FAST_EAP_TYPE + + delete m_cert_if; + + delete m_ca_certificate; + delete m_own_certificate; + delete m_peer_certificate; + delete m_identity_info; + +#ifdef USE_EAP_EXPANDED_TYPES + + m_enabled_tunneling_exp_eap_array.ResetAndDestroy(); + m_disabled_tunneling_exp_eap_array.ResetAndDestroy(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::~eap_am_type_tls_peap_symbian_c() tunneling done.\n"))); + +#else + + m_iap_eap_array.ResetAndDestroy(); + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + +#ifdef USE_PAC_STORE + + delete iPacStoreDb; + +#endif // End: #ifdef USE_PAC_STORE + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} +//-------------------------------------------------- + +// + +void eap_am_type_tls_peap_symbian_c::RunL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::RunL - iStatus.Int()=%d, m_state=%d "), + iStatus.Int() , m_state)); + +#ifdef USE_FAST_EAP_TYPE + eap_status_e status(eap_status_ok); + + if (m_notifier_complete) + { + + TRAPD(err, CompleteNotifierL());// Only for the notifiers. + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::RunL LEAVE from CompleteNotifierL, Error =%d \n"), + err)); + } + + m_notifier_complete = EFalse; + } + + if ( m_state == EPasswordCancel || + m_state == EMasterkeyQuery || + m_state == EPasswordQuery || + m_state == EWrongPassword || + m_state == EFilePasswordQuery ) + { + m_eap_fast_completion_status = m_partner->set_timer( + this, + KHandleReadPacstoreTimerID, + &status, + 0); + return; + } + if (m_state == ENone) + { + return; + } + +#endif // #ifdef USE_FAST_EAP_TYPE + + if (iStatus.Int() != KErrNone) + { + // Notifier was cancelled or something went wrong + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: Certificate selection notifier was cancelled or failed, error=%d, m_state=%d.\n"), + iStatus.Int(), + m_state)); + + switch (m_state) + { + case EHandlingIdentityQuery: + case EHandlingManualIdentityQuery: + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: Cannot read user certificate.\n"))); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_process_general_error, + false, + 0, + false, + 0); + return; + + case EHandlingChainQuery: + // Notifier was cancelled or something went wrong + get_tls_am_partner()->complete_query_certificate_chain( + 0, + eap_status_process_general_error); + return; + default: + return; + } + } + + if (m_state == EHandlingIdentityQuery + || m_state == EHandlingChainQuery) + { + TUint index(0); + if (m_selector_output.Length() > 0) + { + TPckg data(index); + data.Copy(m_selector_output); + } + else + { + // There is only one certificate. Use that. + index = 0; + } + + if(m_allowed_user_certs.Count() > 0) + { + m_own_certificate_info = m_allowed_user_certs[index]; + } + + TBool retrieve_chain; + + if (m_state == EHandlingChainQuery) + { + retrieve_chain = true; + } + else + { + retrieve_chain = false; + } + + TInt allowed_user_cert_count = m_allowed_user_certs.Count(); + TInt err(KErrNone); + + if(allowed_user_cert_count > 0) + { + TRAP(err, m_cert_if->ReadCertificateL(m_allowed_user_certs[index], retrieve_chain)); + } + if (err != KErrNone || allowed_user_cert_count <= 0) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Certificate reading failed or no user cert, user cert count=%d\n"), + allowed_user_cert_count)); + + switch (m_state) + { + case EHandlingIdentityQuery: + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: EHandlingIdentityQuery: Cannot read user certificate.\n"))); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_process_general_error, + false, + 0, + false, + 0); + return; + + case EHandlingChainQuery: + // Notifier was cancelled or something went wrong + get_tls_am_partner()->complete_query_certificate_chain( + 0, + eap_status_process_general_error); + return; + default: + return; + } + } + } + else if (m_state == EHandlingManualIdentityQuery) + { + // Convert to 8-bit text + TBuf8 buf; + buf.Copy(m_identity_info->iUsername); + + eap_status_e status = m_manual_username.set_copy_of_buffer( + buf.Ptr(), + buf.Size()); + + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: EHandlingIdentityQuery: Cannot read manual username.\n"))); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + status, + false, + 0, + false, + 0); + } + + buf.Copy(m_identity_info->iRealm); + status = m_manual_realm.set_copy_of_buffer( + buf.Ptr(), + buf.Size()); + + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: EHandlingIdentityQuery: Cannot read manual realm.\n"))); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + status, + false, + 0, + false, + 0); + } + + // This must be true + m_use_manual_realm = true; + + if (m_identity_info->iUseManualUsername) + { + m_use_manual_username = true; + } + else + { + m_use_manual_username = false; + } + + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_ok, + m_use_manual_username, + &m_manual_username, + m_use_manual_realm, + &m_manual_realm); + + TRAPD(err, SaveManualIdentityL( + m_identity_info->iUseManualUsername, + m_identity_info->iUsername, + ETrue, + m_identity_info->iRealm)); + + (void)EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(err)); + + // Ignore return value on purpose. It's not fatal if saving fails. + + delete m_identity_info; + m_identity_info = 0; + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// + + +void eap_am_type_tls_peap_symbian_c::DoCancel() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + RDebug::Print( _L("eap_am_type_tls_peap_symbian_c::DoCancel()\n") ); + + if(m_cert_if->IsActive()) + { + m_cert_if->Cancel(); + } + + if ( iEapTtlsPapActive ) + { + if ( iEapTtlsPapActive->IsActive() ) + { + EAP_TRACE_DEBUG_SYMBIAN( + ( _L( " eap_am_type_tls_peap_symbian_c::DoCancel() \ + Cancelling iEapTtlsPapActive." ) ) ); + iEapTtlsPapActive->Cancel(); + } + } + +#if defined(USE_FAST_EAP_TYPE) + + m_partner->cancel_timer( + this, + KRemoveIAPReferenceTimerID); + + m_partner->cancel_timer( + this, + KImportFileTimerID); + + m_partner->cancel_timer( + this, + KCompleteReadPacstoreTimerID); + + m_partner->cancel_timer( + this, + KHandleReadPacstoreTimerID); + + if( m_is_notifier_connected ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L(" eap_am_type_tls_peap_symbian_c::DoCancel - calling m_notifier.CancelNotifier"))); + if(IsActive()) + { + TInt error = m_notifier.CancelNotifier(KEapFastNotifierUid); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::DoCancel:CancelNotifier=%d"), + error)); + } + + m_notifier.Close(); // Call close only if it is connected. + + m_is_notifier_connected = false; + + } // End: if( m_is_notifier_connected ) + +#endif // #if defined(USE_FAST_EAP_TYPE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// + +eap_status_e eap_am_type_tls_peap_symbian_c::SaveManualIdentityL( + const TBool use_manual_username, + TDesC& manual_username, + const TBool use_manual_realm, + TDesC& manual_realm) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Validate length. + if(manual_username.Length() > KMaxManualUsernameLengthInDB + || manual_realm.Length() > KMaxManualRealmLengthInDB) + { + // Username or realm too long. Can not be stored in DB. + EAP_TRACE_DEBUG_SYMBIAN((_L("eap_am_type_tls_peap_symbian_c::SaveManualIdentityL: Too long username or realm. Length: UN=%d, Realm=%d\n"), + manual_username.Length(), manual_realm.Length())); + + User::Leave(KErrArgument); + } + + HBufC* sqlbuf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = sqlbuf->Des(); + + RDbView view; + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &m_db_table_name, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + view.FirstL(); + + view.UpdateL(); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_realm_literal), static_cast(use_manual_realm) ); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_realm_literal), manual_realm); // realm + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_username_literal), static_cast(use_manual_username) ); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_username_literal), manual_username); + + view.PutL(); + + CleanupStack::PopAndDestroy(3); // colset, view, session + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + + +//-------------------------------------------------- + +abs_eap_am_type_tls_peap_c * eap_am_type_tls_peap_symbian_c::get_am_partner() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_am_partner; +} + +//-------------------------------------------------- + +void eap_am_type_tls_peap_symbian_c::set_am_partner(abs_eap_am_type_tls_peap_c * const partner) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + m_am_partner = partner; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT abs_tls_am_services_c * eap_am_type_tls_peap_symbian_c::get_tls_am_partner() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT_ALWAYS(m_tls_am_partner != 0); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return m_tls_am_partner; +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_type_tls_peap_symbian_c::set_tls_am_partner(abs_tls_am_services_c * const tls_am_partner) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_tls_am_partner = tls_am_partner; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +// --------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::SendErrorNotification() +// --------------------------------------------------------- +// +void eap_am_type_tls_peap_symbian_c::SendErrorNotification( + const eap_status_e aError ) + { + send_error_notification( aError ); + } +//-------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + +EAP_FUNC_EXPORT void eap_am_type_tls_peap_symbian_c::set_tls_application( + abs_tls_am_application_eap_fast_c * const tls_application) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_tls_application = tls_application; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + + + + +// --------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::IsProvisioningMode() +// --------------------------------------------------------- +// +TBool eap_am_type_tls_peap_symbian_c::IsProvisioningMode() + { + return ( m_provisioning_mode == + eap_fast_completion_operation_server_authenticated_provisioning_mode ) ? ETrue : EFalse; + } + + +// --------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::CompleteQueryUserPermissionForAid() +// --------------------------------------------------------- +// +eap_status_e +eap_am_type_tls_peap_symbian_c::CompleteQueryUserPermissionForAid( + EEapFastNotifierUserAction aUserAction ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::CompleteQueryUserPermissionForAid"))); + if ( aUserAction == EEapFastNotifierUserActionOk ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::CompleteQueryUserPermissionForAid eap_status_ok"))); + m_eap_fast_completion_status = m_tls_application-> + complete_query_user_permission_for_A_ID( + eap_status_ok, + m_pending_operation ); + } + else //if (userAction == EEapFastNotifierUserActionCancel) + { + EAP_TRACE_DEBUG_SYMBIAN( + _L("eap_am_type_tls_peap_symbian_c::CompleteQueryUserPermissionForAid eap_status_user_cancel_authentication")); + + // comlete query + m_eap_fast_completion_status = m_tls_application-> + complete_query_user_permission_for_A_ID( + eap_status_user_cancel_authentication, + m_pending_operation ); + } + return m_eap_fast_completion_status; + } + + +#endif //#if defined(USE_FAST_EAP_TYPE) + +//-------------------------------------------------- + +// +void eap_am_type_tls_peap_symbian_c::notify_configuration_error( + const eap_status_e configuration_status) +{ + if (m_is_client == true) + { + EAP_UNREFERENCED_PARAMETER(configuration_status); // in release + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAP-TLS: Configuration error notification, %d.\n"), + configuration_status)); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + // Send a notification that configuration is incorrect. + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, // This must be used with eap_general_state_configuration_error. + m_current_eap_type, + eap_state_none, + eap_general_state_configuration_error, + 0, + false); + + notification.set_authentication_error(configuration_status); + + m_partner->state_notification(¬ification); + } +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::configure() +{ + eap_status_e status(eap_status_ok); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: function: eap_am_type_tls_peap_symbian_c::configure()\n"), + (m_is_client == true ? "client": "server"))); + + + + if (m_configured == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: function: eap_am_type_tls_peap_symbian_c::configure(): Already configured.\n"), + (m_is_client == true ? "client": "server"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + + //---------------------------------------------------------- + + { + TRAPD(err, EapTlsPeapUtils::ReadCertRowsToArrayL( + m_database, + m_am_tools, + m_db_user_cert_table_name, + m_index_type, + m_index, + m_tunneling_type, + m_allowed_user_certs)); + + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::configure - ReadCertRowsToArrayL, User cert, Error =%d \n"), + err)); + + // Convert the leave error code to EAPOL stack error code. + status = m_am_tools->convert_am_error_to_eapol_error(err); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::configure, EapTlsPeapUtils::ReadCertRowsToArrayL success, m_allowed_user_certs count=%d"), + m_allowed_user_certs.Count())); + } + + TRAP(err, EapTlsPeapUtils::ReadCertRowsToArrayL( + m_database, + m_am_tools, + m_db_ca_cert_table_name, + m_index_type, + m_index, + m_tunneling_type, + m_allowed_ca_certs)); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::configure - ReadCertRowsToArrayL, CA cert, Error =%d \n"), + err)); + + // Convert the leave error code to EAPOL stack error code. + status = m_am_tools->convert_am_error_to_eapol_error(err); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::configure, EapTlsPeapUtils::ReadCertRowsToArrayL success, m_allowed_ca_certs count=%d"), + m_allowed_ca_certs.Count())); + } + + TRAP(err, EapTlsPeapUtils::ReadUintRowsToArrayL( + m_database, + m_am_tools, + m_db_cipher_suite_table_name, + KCipherSuite, + m_index_type, + m_index, + m_tunneling_type, + m_allowed_cipher_suites)); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::configure - ReadUintRowsToArrayL, CipherSuit, Error =%d \n"), + err)); + + // Convert the leave error code to EAPOL stack error code. + status = m_am_tools->convert_am_error_to_eapol_error(err); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + //---------------------------------------------------------- + + if (m_current_eap_type == eap_type_peap +#if defined(USE_TTLS_EAP_TYPE) + || m_current_eap_type == eap_type_ttls +#endif + +#if defined(USE_FAST_EAP_TYPE) + || m_current_eap_type == eap_type_fast +#endif + + + ) + { +#ifdef USE_EAP_EXPANDED_TYPES + + TRAPD(err, EapTlsPeapUtils::GetTunnelingExpandedEapDataL( + m_database, + m_am_tools, + m_enabled_tunneling_exp_eap_array, + m_disabled_tunneling_exp_eap_array, + m_index_type, + m_index, + m_tunneling_type, + m_current_eap_type)); + +#else + TRAPD(err, EapTlsPeapUtils::GetEapDataL( + m_database, + m_am_tools, + m_iap_eap_array, + m_index_type, + m_index, + m_tunneling_type, + m_current_eap_type)); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::configure - GetEapDataL or GetTunnelingExpandedEapDataL, Error =%d \n"), + err)); + + // Convert the leave error code to EAPOL stack error code. + status = m_am_tools->convert_am_error_to_eapol_error(err); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c verify_certificate_realm(m_am_tools); + + eap_status_e status = type_configure_read( + cf_str_EAP_TLS_PEAP_verify_certificate_realm.get_field(), + &verify_certificate_realm); + if (status == eap_status_ok + && verify_certificate_realm.get_is_valid_data() == true + && verify_certificate_realm.get_data_length() == sizeof(u32_t) + && verify_certificate_realm.get_data(sizeof(u32_t)) != 0) + { + // OK + // This is optional value. + if (*(reinterpret_cast( + verify_certificate_realm.get_data(sizeof(u32_t)))) == 1) + { + m_verify_certificate_realm = true; + } + else + { + m_verify_certificate_realm = false; + } + } + } + + //---------------------------------------------------------- + + { + eap_variable_data_c allow_subdomain_matching(m_am_tools); + + eap_status_e status = type_configure_read( + cf_str_EAP_TLS_PEAP_allow_subdomain_matching.get_field(), + &allow_subdomain_matching); + if (status == eap_status_ok + && allow_subdomain_matching.get_is_valid_data() == true + && allow_subdomain_matching.get_data_length() == sizeof(u32_t) + && allow_subdomain_matching.get_data(sizeof(u32_t)) != 0) + { + // OK + // This is optional value. + if (*(reinterpret_cast( + allow_subdomain_matching.get_data(sizeof(u32_t)))) == 1) + { + m_allow_subdomain_matching = true; + } + else + { + m_allow_subdomain_matching = false; + } + } + } + + //---------------------------------------------------------- + + // This is only for server + { + eap_variable_data_c cipher_suite(m_am_tools); + + eap_status_e status = type_configure_read( + cf_str_EAP_TLS_PEAP_cipher_suite.get_field(), + &cipher_suite); + if (status == eap_status_ok + && cipher_suite.get_is_valid_data() == true + && cipher_suite.get_data_length() == sizeof(u32_t) + && cipher_suite.get_data(sizeof(u32_t)) != 0) + { + // OK + // This is optional value. + m_cipher_suite = (tls_cipher_suites_e)*reinterpret_cast( + cipher_suite.get_data(sizeof(u32_t))); + } + } + + //---------------------------------------------------------- + +#ifndef USE_EAP_EXPANDED_TYPES // This is not needed it seems. Still keeping it for normal EAP types. + // Intention of this is to get tunneled EAP types, but m_tunneled_type is not used + // anywhere other than this place. + + if (m_current_eap_type == eap_type_peap +#if defined(USE_TTLS_EAP_TYPE) + || m_current_eap_type == eap_type_ttls +#endif // #if defined(USE_TTLS_EAP_TYPE) + +#if defined(USE_FAST_EAP_TYPE) + || m_current_eap_type == eap_type_fast +#endif + + + ) + { + eap_variable_data_c tunneled_type(m_am_tools); + + eap_status_e status = type_configure_read( + cf_str_PEAP_tunneled_eap_type_hex_data.get_field(), + &tunneled_type); + if (status == eap_status_illegal_configure_type) + { + status = m_partner->read_configure( + cf_str_PEAP_tunneled_eap_type_u32_t.get_field(), + &tunneled_type); + } + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else if (tunneled_type.get_is_valid_data() == true + && tunneled_type.get_data_length() == sizeof(u32_t) + && tunneled_type.get_data(sizeof(u32_t)) != 0) + { + m_tunneled_type = static_cast( + *reinterpret_cast(tunneled_type.get_data(sizeof(u32_t)))); + } + else if (tunneled_type.get_data_length() + == eap_expanded_type_c::get_eap_expanded_type_size() + && tunneled_type.get_data(tunneled_type.get_data_length()) != 0) + { + eap_expanded_type_c eap_type(eap_type_none); + + status = eap_type.set_expanded_type_data( + m_am_tools, + &tunneled_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = eap_type.get_type_data( + m_am_tools, + &m_tunneled_type); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + +#endif //#ifndef USE_EAP_EXPANDED_TYPES + + //---------------------------------------------------------- + + { + eap_variable_data_c use_manual_username(m_am_tools); + + eap_status_e status = type_configure_read( + cf_str_EAP_TLS_PEAP_use_manual_username.get_field(), + &use_manual_username); + if (status == eap_status_ok + && use_manual_username.get_is_valid_data() == true + && use_manual_username.get_data_length() == sizeof(u32_t) + && use_manual_username.get_data(sizeof(u32_t)) != 0) + { + // OK + // This is optional value. + if (*(reinterpret_cast(use_manual_username.get_data(sizeof(u32_t)))) == 1) + { + m_use_manual_username = true; + } + else + { + m_use_manual_username = false; + } + } + } + + //---------------------------------------------------------- + + { + (void) type_configure_read( + cf_str_EAP_TLS_PEAP_manual_username.get_field(), + &m_manual_username); + // return value ignored on purpose (optional parameter) + } + + //---------------------------------------------------------- + + { + eap_variable_data_c use_manual_realm(m_am_tools); + + eap_status_e status = type_configure_read( + cf_str_EAP_TLS_PEAP_use_manual_realm.get_field(), + &use_manual_realm); + if (status == eap_status_ok + && use_manual_realm.get_is_valid_data() == true + && use_manual_realm.get_data_length() == sizeof(u32_t) + && use_manual_realm.get_data(sizeof(u32_t)) != 0) + { + // OK + // This is optional value. + if (*(reinterpret_cast( + use_manual_realm.get_data(sizeof(u32_t)))) == 1) + { + m_use_manual_realm = true; + } + else + { + m_use_manual_realm = false; + } + } + } + + //---------------------------------------------------------- + + { + (void) type_configure_read( + cf_str_EAP_TLS_PEAP_manual_realm.get_field(), + &m_manual_realm); + // return value ignored on purpose (optional parameter) + } + + //---------------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + { + eap_variable_data_c use_session_ticket(m_am_tools); + + eap_status_e status = m_partner->read_configure( + cf_str_EAP_TLS_PEAP_use_session_ticket.get_field(), + &use_session_ticket); + if (status == eap_status_ok + && use_session_ticket.get_is_valid_data() == true) + { + u32_t *use_manual_realm_flag = reinterpret_cast( + use_session_ticket.get_data(sizeof(u32_t))); + if (use_manual_realm_flag != 0 + && *use_manual_realm_flag != 0) + { + m_use_session_ticket = true; + } + } + } +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + + //---------------------------------------------------------- + + if (m_current_eap_type == eap_type_peap +#if defined(USE_TTLS_EAP_TYPE) + || m_current_eap_type == eap_type_ttls +#endif // #if defined(USE_TTLS_EAP_TYPE) + +#if defined(USE_FAST_EAP_TYPE) + || m_current_eap_type == eap_type_fast +#endif + + ) + { + m_tls_peap_server_authenticates_client_policy_flag = false; + } + + //---------------------------------------------------------- + + { + eap_variable_data_c server_authenticates_client(m_am_tools); + + status = type_configure_read( + cf_str_TLS_server_authenticates_client_policy_in_client.get_field(), + &server_authenticates_client); + if (status == eap_status_ok + && server_authenticates_client.get_is_valid_data() == true + && server_authenticates_client.get_data_length() == sizeof(u32_t) + && server_authenticates_client.get_data(sizeof(u32_t)) != 0) + { + // This is optional value. + u32_t *flag = reinterpret_cast( + server_authenticates_client.get_data(sizeof(u32_t))); + if (flag != 0) + { + if (*flag == 0) + { + m_tls_peap_server_authenticates_client_policy_flag = false; + } + else + { + m_tls_peap_server_authenticates_client_policy_flag = true; + } + } + } + } + + //---------------------------------------------------------- + + { + // Read Maximum Session Validity Time from the config file + eap_variable_data_c sessionTimeFromFile(m_am_tools); + + eap_status_e status(eap_status_ok); + + switch (m_current_eap_vendor_type) + { + case eap_type_tls: + { + status = m_partner->read_configure( + cf_str_EAP_TLS_max_session_validity_time.get_field(), + &sessionTimeFromFile); + } + break; + + case eap_type_peap: + { + status = m_partner->read_configure( + cf_str_EAP_PEAP_max_session_validity_time.get_field(), + &sessionTimeFromFile); + } + break; + + case eap_type_ttls: + { + status = m_partner->read_configure( + cf_str_EAP_TTLS_max_session_validity_time.get_field(), + &sessionTimeFromFile); + } + break; + + case eap_type_ttls_plain_pap: + { + // read PAP session time + status = m_partner->read_configure( + cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time.get_field(), + &sessionTimeFromFile ); + } + break; + +#if defined(USE_FAST_EAP_TYPE) + case eap_type_fast: + { + status = m_partner->read_configure( + cf_str_EAP_FAST_max_session_validity_time.get_field(), + &sessionTimeFromFile); + } + break; +#endif + + default: + { + // Should never happen + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::configure - Unsupported EAP type, m_current_eap_vendor_type=%d \n"), + m_current_eap_vendor_type)); + } + } + + // set m_max_session_time + if (status == eap_status_ok + && sessionTimeFromFile.get_is_valid_data() == true + && sessionTimeFromFile.get_data_length() == sizeof(u32_t)) + { + u32_t *session = reinterpret_cast(sessionTimeFromFile.get_data()); + if (session != 0) + { + // Update the max session time (in micro seconds). + // configuration file saves the time in seconds. We have to convert it to micro seconds. + m_max_session_time = static_cast(*session) * static_cast(KMicroSecsInASecond); + } + } + // set max session time for protocol in tunnel; + // currently for PAP + if ( status == eap_status_ok && + sessionTimeFromFile.get_is_valid_data() == true && + sessionTimeFromFile.get_data_length() == sizeof( u32_t ) ) + + { + u32_t* session = reinterpret_cast( sessionTimeFromFile.get_data() ); + if ( session != 0 ) + { + // Update the max session time (in micro seconds). + // configuration file saves the time in seconds. + // We have to convert it to micro seconds. + iEapTtlsPapMaxSessionConfigTime = static_cast + ( *session ) * static_cast( KMicroSecsInASecond ); + } + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(USE_FAST_EAP_TYPE) + + // Read UnAuthenticated provisioning mode from database. + // We need this only for EAP-FAST + + if(m_current_eap_type == eap_type_fast) + { + //---------------------------------------------------------- + { + eap_variable_data_c allow_serv_unauth_prov_mode(m_am_tools); + + eap_status_e status = type_configure_read( + cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP.get_field(), + &allow_serv_unauth_prov_mode); + if (status == eap_status_ok + && allow_serv_unauth_prov_mode.get_is_valid_data() == true + && allow_serv_unauth_prov_mode.get_data_length() == sizeof(u32_t) + && allow_serv_unauth_prov_mode.get_data(sizeof(u32_t)) != 0) + { + // OK + if (*(reinterpret_cast( + allow_serv_unauth_prov_mode.get_data(sizeof(u32_t)))) == 1) + { + m_serv_unauth_prov_mode = true; + } + else + { + m_serv_unauth_prov_mode = false; + } + } + } + //---------------------------------------------------------- + { + eap_variable_data_c allow_serv_auth_prov_mode(m_am_tools); + + eap_status_e status = type_configure_read( + cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode.get_field(), + &allow_serv_auth_prov_mode); + if (status == eap_status_ok + && allow_serv_auth_prov_mode.get_is_valid_data() == true + && allow_serv_auth_prov_mode.get_data_length() == sizeof(u32_t) + && allow_serv_auth_prov_mode.get_data(sizeof(u32_t)) != 0) + { + // OK + if (*(reinterpret_cast( + allow_serv_auth_prov_mode.get_data(sizeof(u32_t)))) == 1) + { + m_serv_auth_prov_mode = true; + } + else + { + m_serv_auth_prov_mode = false; + } + } + } + //---------------------------------------------------------- + + } // End: if(m_current_eap_type == eap_type_fast) + +#endif // #if defined(USE_FAST_EAP_TYPE) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = eap_status_ok; + + if (m_allowed_ca_certs.Count() == 0) + { + // needed because of nonworking wrong settings +#if defined(USE_FAST_EAP_TYPE) + if(m_current_eap_type == eap_type_fast && + m_serv_auth_prov_mode != true) + { + // In the case of EAP-FAST, CA cert is must if m_serv_auth_prov_mode is TRUE. + status = eap_status_ok; + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::configure - No CA certificate but exception for EAP-FAST as m_serv_auth_prov_mode is FALSE and for all m_serv_unauth_prov_mode \n"))); + } + else +#endif // #if defined(USE_FAST_EAP_TYPE) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::configure - Error - No CA certificate\n"))); + + // No root certificate selected. Cannot continue. + status = eap_status_ca_certificate_unknown; + send_error_notification(status); + } + } + + if(m_allowed_user_certs.Count() == 0) + { +#if defined(USE_FAST_EAP_TYPE) + if(m_current_eap_type == eap_type_fast) + { + m_use_manual_realm = true; + + if (m_use_manual_username == false) + { + TRAPD(err, status=ConfigureL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::configure LEAVE from ConfigureL, Error =%d \n"), + err)); + } + } + } +#endif // #if defined(USE_FAST_EAP_TYPE) + } + if (m_tls_peap_server_authenticates_client_policy_flag == true + && m_allowed_user_certs.Count() == 0) + { +#if defined(USE_FAST_EAP_TYPE) + if (m_current_eap_type == eap_type_fast) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::configure - No USER certificate, but in eap_fast it's not mandatory\n"))); + + } + else +#endif // #if defined(USE_FAST_EAP_TYPE) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::configure - Error - No USER certificate\n"))); + + // No user certificate selected. Cannot continue. + status = eap_status_user_certificate_unknown; + send_error_notification(status); + } + } + + if (m_allowed_cipher_suites.Count() == 0) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::configure - Error - No cipher suit\n"))); + + // No sipher suites selected. Cannot continue. + status = eap_status_illegal_cipher_suite; + send_error_notification(status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + if (status != eap_status_ok) + { + notify_configuration_error(status); + } + + m_configured = true; + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::configure - END \n"))); + + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- +#if defined(USE_FAST_EAP_TYPE) + +eap_status_e eap_am_type_tls_peap_symbian_c::ConfigureL() + { + + eap_status_e status(eap_status_ok); + + _LIT(KTempUserName, "EAP-FAST-"); + TBuf8<10> TempUserName; + + TempUserName.Copy(KTempUserName); + + HBufC8* buf = HBufC8::NewLC(KIdentityFieldLength); + TPtr8 bufPtr = buf->Des(); + + HBufC8* tempUserBuf8 = HBufC8::NewLC(KMacAddressLength); + TPtr8 tempUserBufPtr8 = tempUserBuf8->Des(); + + HBufC8* ConvertedtempUserBuf8 = HBufC8::NewLC(KMacAddressLength*2); + TPtr8 ConvertedtempUserBufPtr8 = ConvertedtempUserBuf8->Des(); + + if (m_receive_network_id.get_destination_length()>0) + { + tempUserBufPtr8.Copy(m_receive_network_id.get_destination(), m_receive_network_id.get_destination_length()); + + u32_t toBinaryPtr8SizeForTools = static_cast(KMacAddressLength*2); + u32_t fromTextPtr8SizeForTools = static_cast(tempUserBufPtr8.Size()); + + u8_t * toBinaryPtr8ForTools = const_cast(ConvertedtempUserBuf8->Ptr()); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::configure,Call convert_bytes_to_hex_ascii, toBinaryPtr8SizeForTools=%d"), + toBinaryPtr8SizeForTools)); + + // Convert hex to ascii string. + status = m_am_tools->convert_bytes_to_hex_ascii( + tempUserBufPtr8.Ptr(), + fromTextPtr8SizeForTools, + toBinaryPtr8ForTools, + &toBinaryPtr8SizeForTools); + + if(status != eap_status_ok) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::configure, Error in convert_hex_ascii_to_bytes. status=%d"), + status)); + + User::Leave(m_am_tools->convert_eapol_error_to_am_error(status)); + } + + ConvertedtempUserBufPtr8.SetLength(KMacAddressLength*2); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("MAC"), + ConvertedtempUserBuf8->Ptr(), + ConvertedtempUserBuf8->Size())); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::config: user size = %d, MAC size= %d \n"), + TempUserName.Size(), ConvertedtempUserBuf8->Size())); + + bufPtr.Append(TempUserName.Ptr(), TempUserName.Size()); + bufPtr.Append(ConvertedtempUserBuf8->Ptr(),ConvertedtempUserBuf8->Size()); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("UserName"), + bufPtr.Ptr(), + bufPtr.Size())); + + status = m_manual_username.set_copy_of_buffer( + bufPtr.Ptr(), + bufPtr.Size()); + } + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::config: UserName = %s \n"), + bufPtr.Ptr(), bufPtr.Size())); + + CleanupStack::PopAndDestroy(ConvertedtempUserBuf8); + CleanupStack::PopAndDestroy(tempUserBuf8); + CleanupStack::PopAndDestroy(buf); + + m_use_manual_username = true; + + return status; + } + +#endif // #if defined(USE_FAST_EAP_TYPE) + +//-------------------------------------------------- + +eap_status_e eap_am_type_tls_peap_symbian_c::reset() +{ + + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +// + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::authentication_finished( + const bool true_when_successful, + const tls_session_type_e tls_session_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_ok); + + TRAPD(err, authentication_finishedL(true_when_successful, tls_session_type)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::authentication_finished, TRAP ERROR=%d\n"), + err)); + + status = m_am_tools->convert_am_error_to_eapol_error(err); + send_error_notification(status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_type_tls_peap_symbian_c::authentication_finishedL( + const bool true_when_successful, + const tls_session_type_e tls_session_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_is_client == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + // In EAP-FAST this could be called when provisioning is successfull. + // If there was provisioning, We have to toggle + // cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal + +#if defined(USE_FAST_EAP_TYPE) + + if(m_current_eap_type == eap_type_fast && + m_serv_unauth_prov_mode == true) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::authentication_finishedL EAP-FAST Provisioning!"))); + + eap_variable_data_c unauthProvMode(m_am_tools); + unauthProvMode.set_copy_of_buffer( + &default_EAP_FAST_Unauth_Prov_Mode_Allowed, + sizeof(default_EAP_FAST_Unauth_Prov_Mode_Allowed)); + + EapTlsPeapUtils::SetEapSettingsDataL( + m_database, + m_index_type, + m_index, + m_tunneling_type, + m_current_eap_type, + cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal, + &unauthProvMode); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::authentication_finishedL Unauth Prov mode set to default (NO)!"))); + } +#endif + + // Store the authentication time if the full authentication is successful + if (true_when_successful == true + && tls_session_type == tls_session_type_full_authentication) + { + store_authentication_timeL(); + } + + if (m_latest_alert_description == tls_alert_description_certificate_expired) + { + send_error_notification(eap_status_certificate_expired); + } + else if (m_latest_alert_description == tls_alert_description_bad_certificate) + { + send_error_notification(eap_status_bad_certificate); + } + else if (m_latest_alert_description == tls_alert_description_unsupported_certificate) + { + send_error_notification(eap_status_unsupported_certificate); + } + else if (m_latest_alert_description == tls_alert_description_certificate_revoked) + { + send_error_notification(eap_status_certificate_revoked); + } + else if (m_latest_alert_description == tls_alert_description_certificate_unknown) + { + send_error_notification(eap_status_user_certificate_unknown); + } + else if(m_latest_alert_description != tls_alert_description_none) + { + // Send error notification any alert other than tls_alert_description_none. + send_error_notification(eap_status_process_general_error); + } + + if (true_when_successful == false) + { + ResetSessionIdL(); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::query_eap_identity( + eap_variable_data_c * const /*identity*/, + const eap_am_network_id_c * const /* receive_network_id */, + const u8_t eap_identifier, + bool * const /*use_manual_username*/, + eap_variable_data_c * const /*manual_username*/, + bool *const /*use_manual_realm*/, + eap_variable_data_c * const /*manual_realm*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_pending_request); + + // Store parameters + m_eap_identifier = eap_identifier; + m_state = EHandlingIdentityQuery; + + // Get the own certificate only if it has already been retrieved + if (m_own_certificate == 0) + { + TRAPD(err, m_cert_if->GetMatchingCertificatesL( + m_allowed_user_certs, + EFalse, + 0, + EFalse, + 0, + ETrue, + m_allowed_cipher_suites)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + } + else + { + status = eap_status_pending_request; + } + } + else + { + RPointerArray tmp; + if (tmp.Append(m_own_certificate) != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(eap_status_allocation_error); + } + else + { + status = complete_read_own_certificate(tmp, eap_status_ok); + } + tmp.Reset(); + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +eap_status_e eap_am_type_tls_peap_symbian_c::complete_read_own_certificate( + const RPointerArray& aCertChain, eap_status_e aStatus) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_process_general_error; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::complete_read_own_certificate -start- cert chain count = %d, aStatus=%d\n"), + aCertChain.Count(), aStatus)); + + if (aStatus != eap_status_ok) + { + switch (m_state) + { + case EHandlingIdentityQuery: + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: EHandlingIdentityQuery: Cannot read own certificate.\n"))); + + status = get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + aStatus, + false, + 0, + false, + 0); + break; + + case EHandlingChainQuery: + status = get_tls_am_partner()->complete_query_certificate_chain(0, aStatus); + break; + + default: + // This should never happen + User::Panic(_L("EAPOL"), 1); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Handle errors - if certificate is 0 then an error has occurred. + if (aCertChain.Count() == 0) + { + switch (m_state) + { + case EHandlingIdentityQuery: + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Could not read own certificate.\n"))); + + status = get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_illegal_eap_identity, + false, + 0, + false, + 0); + break; + + case EHandlingChainQuery: + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Could not read own certificate.\n"))); + status = get_tls_am_partner()->complete_query_certificate_chain(0, eap_status_illegal_certificate); + break; + + default: + // This should never happen + User::Panic(_L("EAPOL"), 1); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + TBool aEqual = EFalse; + if (m_own_certificate != 0) + { + TRAPD(err1, aEqual = m_own_certificate->IsEqualL(*aCertChain[0])); + if (err1 != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + // Store certificate + if (m_own_certificate == 0 + || aEqual == EFalse) + { + delete m_own_certificate; + + // Create a copy of the certificate + TRAPD(err, m_own_certificate = CX509Certificate::NewL(*aCertChain[0])); + if (err != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + switch (m_state) + { + case EHandlingIdentityQuery: + { + eap_variable_data_c subjectIdentity(m_am_tools); + eap_variable_data_c IssuerIdentity(m_am_tools); + + TRAPD(err, get_identity_from_alternative_nameL(m_own_certificate, &subjectIdentity)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Could not find identity in SubjectAltName field.\n"))); + + TRAPD(err, get_identities_from_distinguished_namesL(m_own_certificate, &subjectIdentity, &IssuerIdentity)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Could not find subject identity from certificate.\n"))); + + status = get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_illegal_eap_identity, + false, + 0, + false, + 0); + break; + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Found subject identity from certificate.\n"))); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Found identity in SubjectAltName field.\n"))); + } + + // The completition function return a status value but there is no need to check them. + status = get_am_partner()->complete_eap_identity_query( + &subjectIdentity, + &m_receive_network_id, + m_eap_identifier, + eap_status_ok, + m_use_manual_username, + &m_manual_username, + m_use_manual_realm, + &m_manual_realm); + if (status == eap_status_ok + || status == eap_status_pending_request) + { + status = eap_status_completed_request; + } + } + break; + case EHandlingChainQuery: + { + eap_array_c chain(m_am_tools); + + // Check if the certificate cipher suite is correct + const CSubjectPublicKeyInfo& pubkey = m_own_certificate->PublicKey(); + TAlgorithmId algorithm = pubkey.AlgorithmId(); + + if (EapTlsPeapUtils::CipherSuiteUseRSAKeys(m_cipher_suite) + && algorithm != ERSA) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Tried to use DSA certificate with RSA cipher suite.\n"))); + + send_error_notification(eap_status_illegal_cipher_suite); + + status = get_tls_am_partner()->complete_query_certificate_chain(0, eap_status_illegal_cipher_suite); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (EapTlsPeapUtils::CipherSuiteUseDSAKeys(m_cipher_suite) + && algorithm != EDSA) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Tried to use RSA certificate with DSS cipher suite.\n"))); + + send_error_notification(eap_status_illegal_cipher_suite); + + status = get_tls_am_partner()->complete_query_certificate_chain(0, eap_status_illegal_cipher_suite); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Add the chain certificates to eap_array_c + TInt i(0); + for (i = 0; i < aCertChain.Count(); i++) + { + eap_variable_data_c * cert = new eap_variable_data_c(m_am_tools); + if (cert == 0) + { + status = get_tls_am_partner()->complete_query_certificate_chain(0, eap_status_allocation_error); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = cert->set_buffer( + aCertChain[i]->Encoding().Ptr(), + aCertChain[i]->Encoding().Size(), + false, + false); + if (status != eap_status_ok) + { + delete cert; + status = get_tls_am_partner()->complete_query_certificate_chain(0, eap_status_process_general_error); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + status = chain.add_object(cert, true); + if (status != eap_status_ok) + { + status = get_tls_am_partner()->complete_query_certificate_chain(0, eap_status_allocation_error); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + // Complete query + status = get_tls_am_partner()->complete_query_certificate_chain(&chain, eap_status_ok); + } + break; + + default: + // This should never happen + User::Panic(_L("EAPOL"), 1); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +eap_status_e eap_am_type_tls_peap_symbian_c::complete_read_ca_certificate( + const RPointerArray& aCertChain, eap_status_e aStatus) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::complete_read_ca_certificate. Cert Chain count=%d, aStatus=%d\n"), + aCertChain.Count(), aStatus)); + + if (aStatus != eap_status_ok) + { + switch (m_state) + { + case EHandlingIdentityQuery: + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Could not CA certificate.\n"))); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + aStatus, + false, + 0, + false, + 0); + + break; + + case EHandlingCipherSuiteQuery: + get_tls_am_partner()->complete_query_certificate_chain(0, aStatus); + break; + + default: + // This should never happen + User::Panic(_L("EAPOL"), 1); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Check the error case first + if (aCertChain.Count() == 0) + { + switch (m_state) + { + case EHandlingIdentityQuery: + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Could not read ca certificate.\n"))); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_illegal_eap_identity, + false, + 0, + false, + 0); + + break; + + case EHandlingCipherSuiteQuery: + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Could not read own certificate.\n"))); + get_tls_am_partner()->complete_query_certificate_chain(0, eap_status_illegal_certificate); + break; + + default: + // This should never happen + User::Panic(_L("EAPOL"), 1); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Store certificate + TBool aEqual = EFalse; + if (m_ca_certificate != 0) + { + TRAPD(err1, aEqual = m_ca_certificate->IsEqualL(*aCertChain[0])); + if (err1 != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + if (m_ca_certificate == 0 + || aEqual == EFalse) + { + delete m_ca_certificate; + + // Create a copy of the certificate + TRAPD(err, m_ca_certificate = CX509Certificate::NewL(*aCertChain[0])); + if (err != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + } + + + switch (m_state) + { + case EHandlingIdentityQuery: + { + + // Get the realm from the CA certificate + eap_variable_data_c tmp(m_am_tools); + + eap_status_e status = get_realms_from_certificate( + m_ca_certificate, + &m_manual_realm, + &tmp); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Could not read realms from ca certificate.\n"))); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_illegal_eap_identity, + false, + 0, + false, + 0); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Got realm from CA certificate"), + m_manual_realm.get_data(m_manual_realm.get_data_length()), + m_manual_realm.get_data_length())); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because certificate query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_ok, + m_use_manual_username, + &m_manual_username, + true, + &m_manual_realm); + } + break; + + case EHandlingCipherSuiteQuery: + { + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Got CA certificate. Resume cipher suite selection.\n"))); + + query_cipher_suites_and_previous_session(); + } + break; + + default: + // This should never happen + User::Panic(_L("EAPOL"), 1); + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +void eap_am_type_tls_peap_symbian_c::get_identities_from_distinguished_namesL( + const CX509Certificate * const aCertificate, + eap_variable_data_c * const aSubjectIdentity, + eap_variable_data_c * const aIssuerIdentity) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (aSubjectIdentity == 0 + || aIssuerIdentity == 0 + || aCertificate == 0) + { + User::Leave(KErrArgument); + } + + TInt i(0); + HBufC *value = 0; + // Loop the distinguished name field and try to find common name + const CX500DistinguishedName& dn = aCertificate->SubjectName(); + + for (i = 0; i < dn.Count(); i++) + { + const CX520AttributeTypeAndValue& attribute = dn.Element(i); + + if (attribute.Type() == KX520CommonName) + { + value = attribute.ValueL(); + CleanupStack::PushL(value); + + // Convert to 8-bit text + HBufC8* tmp = HBufC8::NewLC(value->Length()); + + if (NULL == tmp) + { + User::Leave(KErrNoMemory); + } + + TPtr8 tmpptr = tmp->Des(); + tmpptr.Copy(*value); + + eap_status_e status = aSubjectIdentity->set_copy_of_buffer( + tmpptr.Ptr(), + tmpptr.Size()); + + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::get_identities_from_distinguished_namesL:SubjectIdentity:"), + tmpptr.Ptr(), + tmpptr.Size())); + + CleanupStack::PopAndDestroy(tmp); + CleanupStack::PopAndDestroy(value); + } + } + const CX500DistinguishedName& dn2 = aCertificate->IssuerName(); + + for (i = 0; i < dn2.Count(); i++) + { + const CX520AttributeTypeAndValue& attribute = dn2.Element(i); + + if (attribute.Type() == KX520CommonName) + { + value = attribute.ValueL(); + CleanupStack::PushL(value); + // Convert to 8-bit text + HBufC8* tmp = HBufC8::NewLC(value->Length()); + + if (NULL == tmp) + { + User::Leave(KErrNoMemory); + } + + TPtr8 tmpptr = tmp->Des(); + tmpptr.Copy(*value); + + eap_status_e status = aIssuerIdentity->set_copy_of_buffer( + tmpptr.Ptr(), + tmpptr.Size()); + + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::get_identities_from_distinguished_namesL:IssuerIdentity:"), + tmpptr.Ptr(), + tmpptr.Size())); + + CleanupStack::PopAndDestroy(tmp); + CleanupStack::PopAndDestroy(value); + } + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +void eap_am_type_tls_peap_symbian_c::get_identity_from_alternative_nameL( + const CX509Certificate * const aCertificate, + eap_variable_data_c * const aIdentity) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + /******************************************************************** + SubjectAltName ::= GeneralNames + + GeneralNames ::= SEQUENCE OF GeneralName + + GeneralName ::= CHOICE { + otherName [0] AnotherName, + rfc822Name [1] IA5String, + dNSName [2] IA5String, + x400Address [3] ANY, --ORAddress, + directoryName [4] Name, + ediPartyName [5] EDIPartyName, + uniformResourceIdentifier [6] IA5String, + iPAddress [7] OCTET STRING, + registeredID [8] OBJECT IDENTIFIER } + + -- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as + -- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax + + AnotherName ::= SEQUENCE { + type OBJECT IDENTIFIER, + value [0] EXPLICIT ANY } --DEFINED BY type-id } + **********************************************************************/ + + const CX509CertExtension* ext = aCertificate->Extension(KSubjectAltName); + // Check if there is alternative name extension (Windows provided certificates usually do) + if (ext != 0) + { + // Start parsing the alt. name + TPtrC8 name = ext->Data(); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::get_identity_from_alternative_nameL: Alt Name from Cert extn:"), + name.Ptr(), + name.Size())); + + if(0 == name.Size()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR:get_identity_from_alternative_nameL:No Alternative Name in cert extension\n"))); + + User::Leave(KErrNotFound); + } + + // Extension is inside an octet string + TASN1DecOctetString octetstring; + TInt pos(0); + HBufC8* pOct = octetstring.DecodeDERL(name, pos); + + if(NULL == pOct) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR:get_identity_from_alternative_nameL:No ASN1DecOctetString or DecodeDER failed\n"))); + + User::Leave(KErrNotFound); + } + + CleanupStack::PushL(pOct); + + // Then there is SEQUENCE + TASN1DecSequence seq; + pos = 0; + CArrayPtrFlat* pSeq = seq.DecodeDERLC(pOct->Des(), pos); + + if(0 == pSeq->Count()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR:get_identity_from_alternative_nameL:No ASN1DecSequence or DecodeDER failed\n"))); + + User::Leave(KErrNotFound); + } + + // Get the first item in the sequence (ignore other possible items) + TASN1DecGeneric* gen; + gen = pSeq->At(0); + if (gen == 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR:get_identity_from_alternative_nameL:No ASN1DecGeneric\n"))); + + User::Leave(KErrNotFound); + } + if (gen->Tag() != 0) // Only parse otherName in the CHOICE at the moment. + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR:get_identity_from_alternative_nameL:Some Tag in ASN1DecGeneric\n"))); + + User::Leave(KErrNotSupported); + } + + TPtrC8 pOtherName = gen->GetContentDER(); + + TASN1DecObjectIdentifier objid; + + pos = 0; + HBufC* objId = objid.DecodeDERL(pOtherName, pos); + + if(NULL == objId) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR:get_identity_from_alternative_name_L:No ASN1DecObjectIdentifier or DecodeDER failed\n"))); + + User::Leave(KErrNotFound); + } + + CleanupStack::PushL(objId); + + // http://asn1.elibel.tm.fr/oid/ + _LIT(KMSObjectId, "1.3.6.1.4.1.311.20.2.3"); + if (objId->Compare(KMSObjectId) != 0) + { + // Not supported object type + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR:get_identity_from_alternative_nameL:Not supported object type\n"))); + + User::Leave(KErrNotSupported); + } + + pos += 2; // Skip over explicit tag + + TASN1DecUTF8String utf8; + HBufC* utf8name = utf8.DecodeDERL(pOtherName, pos); + + if(NULL == utf8name) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR:get_identity_from_alternative_nameL:No ASN1DecUTF8String or DecodeDER failed\n"))); + + User::Leave(KErrNotFound); + } + + CleanupStack::PushL(utf8name); + + HBufC8* buf= HBufC8::NewLC(128); + if (NULL == buf) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + + TPtr8 nname = buf->Des(); + + nname.Copy(utf8name->Des()); + + eap_status_e status = aIdentity->set_copy_of_buffer( + nname.Ptr(), + nname.Size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::get_identity_from_alternative_nameL: Identity from Alt Name:"), + nname.Ptr(), + nname.Size())); + + CleanupStack::PopAndDestroy(5); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("get_identity_from_alternative_nameL:No X509 Cert Extension\n"))); + + User::Leave(KErrNotFound); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::timer_expired( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(id); // in release + EAP_UNREFERENCED_PARAMETER(data); // in release + + eap_status_e status = eap_status_ok; + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: [0x%08x]->eap_am_type_tls_peap_symbian_c::timer_expired(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + +#if defined(USE_FAST_EAP_TYPE) + + if(id == KHandleCompletePacstoreNokTimerID) + { + m_eap_fast_completion_status = eap_status_file_does_not_exist; + m_tls_application->complete_initialize_PAC_store( iCompletionOperation, iCompletion ); + return eap_status_ok; + } + if(id == KHandleCompletePacstoreOkTimerID) + { + m_eap_fast_completion_status = eap_status_ok; + m_tls_application->complete_initialize_PAC_store( iCompletionOperation, iCompletion ); + return eap_status_ok; + } + if (id == KRemoveIAPReferenceTimerID) + { + status = RemoveIAPReference(); + + } + if (id == KImportFileTimerID) + { + TRAPD(err, status = ImportFilesL()); + if (err != KErrNone) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - Leave From ImportFilesL %d\n"),err)); + } + } + + if (id == KCompleteReadPacstoreTimerID) + { + TRAPD(err, FinalCompleteReadPACStoreDataL(m_eap_fast_completion_status)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - Leave From FinalCompleteReadPACStoreDataL %d\n"),err)); + } + } + + if (id == KHandleReadPacstoreTimerID) + { + if (m_state == EPasswordCancel) + { + m_eap_fast_completion_status = eap_status_user_cancel_authentication; + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - PW query Cancel\n"))); + + + status = m_partner->set_timer( + this, + KCompleteReadPacstoreTimerID, + 0, + 0); + return eap_status_ok; + } + if (m_state == EMasterkeyQuery && m_verificationStatus == EFalse) + { + if (m_userResponse.get_data_length()>0) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - Masterkey Create\n"))); + m_verificationStatus = ETrue; + TRAPD(err, m_eap_fast_completion_status=CreateMasterkeyL()); + if (err != KErrNone) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - Leave From CreateMasterkeyL %d\n"),err)); + } + } + else + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - Masterkey, no data -> final complete for PW\n"))); + m_state = EWrongPassword; + m_verificationStatus = EFalse; + + status = m_partner->set_timer( + this, + KCompleteReadPacstoreTimerID, + 0, + 0); + + return status; + } + } + + if (m_state == EPasswordQuery || m_state == EWrongPassword || m_state == EMasterkeyQuery) + { + if (m_verificationStatus == EFalse) + { + TRAPD(err, status = PasswordQueryL()); + m_eap_fast_completion_status = m_am_tools->convert_am_error_to_eapol_error(status); + if (err != KErrNone) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - Leave From PasswordQueryL %d\n"),err)); + } + + if (m_eap_fast_completion_status != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - PW query NOK, final complete for PW\n"))); + + status = m_partner->set_timer( + this, + KCompleteReadPacstoreTimerID, + 0, + 0); + } + } + if (m_verificationStatus != EFalse) + { + TRAPD(err, CompletePasswordQueryL()); + if (err != KErrNone) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - Leave From CompletePasswordQueryL %d\n"),err)); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - Complete_password_query, m_both_completed=%d, m_both_asked=%d status=%d.\n"), + m_both_completed, + m_both_asked, + m_eap_fast_completion_status)); + if (m_both_completed == m_both_asked) + { + m_both_completed = 0; + m_both_asked = 0; + m_verificationStatus = EFalse; + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - All OK, final complete for PW\n"))); + status = m_partner->set_timer( + this, + KCompleteReadPacstoreTimerID, + 0, + 0); + return status; + } + } + } + + if (m_state == EFilePasswordQuery) + { + TRAPD( err, status = CompleteFilePasswordQueryL()); + if (err != KErrNone) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - Leave From CompleteFilePasswordQueryL %d\n"),err)); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - Complete_file_password_query, m_both_completed=%d, m_both_asked=%d status=%d.\n"), + m_both_completed, + m_both_asked, + status)); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - PW query NOK, final complete for PW\n"))); + status = m_partner->set_timer( + this, + KCompleteReadPacstoreTimerID, + &status, + 0); + return status; + } + if (m_both_completed == m_both_asked) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::timer_expired - All ok, final complete for PW\n"))); + m_both_completed = 0; + m_both_asked = 0; + status = m_partner->set_timer( + this, + KCompleteReadPacstoreTimerID, + &status, + 0); + } + return status; + } + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT void eap_am_type_tls_peap_symbian_c::set_is_valid() +{ + m_is_valid = true; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT bool eap_am_type_tls_peap_symbian_c::get_is_valid() +{ + return m_is_valid; +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::timer_delete_data( + const u32_t id, void *data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(id); // in release + EAP_UNREFERENCED_PARAMETER(data); // in release + + eap_status_e status = eap_status_ok; + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: [0x%08x]->eap_am_type_tls_peap_symbian_c::timer_delete_data(id 0x%02x, data 0x%08x).\n"), + this, id, data)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::type_configure_read( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_ASSERT(data != NULL); + // Trap must be set here because the OS independent portion of EAP TLS + // that calls this function does not know anything about Symbian. + eap_status_e status(eap_status_ok); + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::type_configure_read - Start\n"))); + + if (m_current_eap_type == eap_type_peap +#if defined(USE_TTLS_EAP_TYPE) + || m_current_eap_type == eap_type_ttls +#endif // #if defined(USE_TTLS_EAP_TYPE) +#if defined(USE_FAST_EAP_TYPE) + || m_current_eap_type == eap_type_fast +#endif + + || m_current_eap_type == eap_type_ttls_plain_pap + + ) + { + // Check if the wanted parameter is default type + eap_variable_data_c wanted_field(m_am_tools); + eap_variable_data_c type_field(m_am_tools); + eap_variable_data_c type_field_server(m_am_tools); + + status = wanted_field.set_buffer( + field->get_field(), + field->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = type_field.set_buffer( + cf_str_PEAP_tunneled_eap_type_hex_data.get_field()->get_field(), + cf_str_PEAP_tunneled_eap_type_hex_data.get_field()->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = type_field_server.set_buffer( + cf_str_PEAP_server_tunneled_eap_type_hex_data.get_field()->get_field(), + cf_str_PEAP_server_tunneled_eap_type_hex_data.get_field()->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (!wanted_field.compare(&type_field_server)) + { + // Change the name of the parameter because Symbian AM does not have separate config + // for the server + status = wanted_field.set_buffer( + cf_str_PEAP_tunneled_eap_type_hex_data.get_field()->get_field(), + cf_str_PEAP_tunneled_eap_type_hex_data.get_field()->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + if (!wanted_field.compare(&type_field)) + { + // We are asked to return cf_str_PEAP_tunneled_eap_type_hex_data + +#ifdef USE_EAP_EXPANDED_TYPES + + // We need to return here the next ENABLED tunneled EAP type we should try. + + if (0 == m_enabled_tunneling_exp_eap_array.Count()) + { + // No EAP types are ENABLED as tunneling type. + if (m_is_client) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: No ENABLED encapsulated EAP types.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + else + { + // Get the first enabled EAP type (tunneling). + + TBuf8 tmpExpEAP(m_enabled_tunneling_exp_eap_array[0]->iExpandedEAPType); //first item. + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("type_configure_read:Enabled expanded tunneling EAP type:"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + + status = data->set_copy_of_buffer(tmpExpEAP.Ptr(), KExpandedEAPTypeSize); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-PEAP or EAP-TTLS: Trying encapsulated EAP type:"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + } + +#else // For normal EAP types. + + // We need to return here the next tunneled EAP type we should try. + TInt i; + + for (i = 0; i < m_iap_eap_array.Count(); i++) + { + // Find the first enabled EAP type (highest priority) + TEap *eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + // Convert the string to integer + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + status = data->set_copy_of_buffer(reinterpret_cast(&val), sizeof(TUint)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAP-PEAP: Trying encapsulated EAP type: %d.\n"), val)); + break; + } + } + if (i == m_iap_eap_array.Count()) + { + // Not found + if (m_is_client) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: No configured encapsulated EAP types.\n"))); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + + } // End of if (!wanted_field.compare(&type_field)) + +#if !defined(USE_EAP_EXPANDED_TYPES) + + // cf_str_PEAP_accepted_tunneled_client_types_hex_data is available only for expaned EAP types. + // cf_str_PEAP_accepted_tunneled_client_types_u32array should be used otherwise. + // So for cf_str_PEAP_accepted_tunneled_client_types_hex_data and eap_configure_type_hex_data + // we should return eap_status_illegal_configure_field. + // This is needed only if USE_EAP_EXPANDED_TYPES is not defined. Otherwise the field + // cf_str_PEAP_accepted_tunneled_client_types_hex_data can be read from the database using + // type_configure_readL (let it fall through). + + eap_variable_data_c tunneled_type_field(m_am_tools); + + status = tunneled_type_field.set_buffer( + cf_str_PEAP_accepted_tunneled_client_types_hex_data.get_field()->get_field(), + cf_str_PEAP_accepted_tunneled_client_types_hex_data.get_field()->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (!wanted_field.compare(&tunneled_type_field)) + { + // Check if the type is eap_configure_type_hex_data. + + if( eap_configure_type_hex_data == field->get_type() ) + { + // This field is used only for exapanded EAP types. + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_type); + } + } + +#else // For expanded EAP type. + + // cf_str_PEAP_accepted_tunneled_client_types_u32array is available only for normal EAP types. + // So for cf_str_PEAP_accepted_tunneled_client_types_u32array and eap_configure_type_u32array + // we should return eap_status_illegal_configure_field. + + eap_variable_data_c tunneled_type_field(m_am_tools); + + status = tunneled_type_field.set_buffer( + cf_str_PEAP_accepted_tunneled_client_types_u32array.get_field()->get_field(), + cf_str_PEAP_accepted_tunneled_client_types_u32array.get_field()->get_field_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + if (!wanted_field.compare(&tunneled_type_field)) + { + // Check if the type is eap_configure_type_u32array. + + if( eap_configure_type_u32array == field->get_type() ) + { + // This field is used only for Normal EAP types. This is illegal here. + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_type); + } + } + +#endif // End of #if !defined(USE_EAP_EXPANDED_TYPES) + + } // End of if (m_current_eap_type == eap_type_peap + + TRAPD(err, type_configure_readL( + field->get_field(), + field->get_field_length(), + data)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + } + + m_am_tools->trace_configuration( + status, + field, + data); + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::type_configure_read - End\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- +void eap_am_type_tls_peap_symbian_c::type_configure_readL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(field_length); + + // Create a buffer for the ascii strings - initialised with the argument + HBufC8* asciibuf = HBufC8::NewLC(KMaxDBFieldNameLength); + TPtr8 asciiString = asciibuf->Des(); + asciiString.Copy(reinterpret_cast(field)); + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::type_configure_readL: Reading field:"), + asciiString.Ptr(), + asciiString.Size())); + + // Buffer for unicode parameter + HBufC* unicodebuf = HBufC::NewLC(KMaxDBFieldNameLength); + TPtr unicodeString = unicodebuf->Des(); + + // Convert to unicode + unicodeString.Copy(asciiString); + + // Now do the database query + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + +#if defined(USE_FAST_EAP_TYPE) + + // Unlike other EAP types, EAP-FAST has some settings in special settings table + // (m_db_fast_special_table_name) + + if(m_current_eap_type == eap_type_fast + && ((unicodeString.Compare(cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal) == 0) + || (unicodeString.Compare(cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal) == 0) + || (unicodeString.Compare(cf_str_EAP_FAST_warn_ADHP_no_PAC_literal) == 0) + || (unicodeString.Compare(cf_str_EAP_FAST_warn_ADHP_no_matching_PAC_literal) == 0) + || (unicodeString.Compare(cf_str_EAP_FAST_warn_ADHP_not_default_server_literal) == 0) + || (unicodeString.Compare(KFASTPACGroupImportReferenceCollection) == 0) + || (unicodeString.Compare(KFASTPACGroupDBReferenceCollection) == 0))) + { + if (unicodeString.Compare(cf_str_EAP_FAST_warn_ADHP_no_matching_PAC_literal) == 0) + { + unicodeString.Copy(KFASTWarnADHPNoMatchingPAC); + } + if (unicodeString.Compare(cf_str_EAP_FAST_warn_ADHP_no_PAC_literal) == 0) + { + unicodeString.Copy(KFASTWarnADHPNoPAC); + } + if (unicodeString.Compare(cf_str_EAP_FAST_warn_ADHP_not_default_server_literal) == 0) + { + unicodeString.Copy(KFASTWarnNotDefaultServer); + } + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::type_configure_readL This field will be read from EAP-FAST's special table\n"))); + + sqlStatement.Format(KSQLQueryRow, &unicodeString, &m_db_fast_special_table_name, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + } + else + { + sqlStatement.Format(KSQLQueryRow, &unicodeString, &m_db_table_name, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + } + +#else + + sqlStatement.Format(KSQLQueryRow, &unicodeString, &m_db_table_name, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + +#endif // End: #if defined(USE_FAST_EAP_TYPE) + + RDbView view; + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + if (view.FirstL()) + { + eap_status_e status; + view.GetL(); + switch (view.ColType(KDefaultColumnInView_One)) + { + case EDbColText: + { + unicodeString = view.ColDes(KDefaultColumnInView_One); + // Convert to 8-bit + asciiString.Copy(unicodeString); + if (asciiString.Size() > 0) + { + status = data->set_copy_of_buffer(asciiString.Ptr(), asciiString.Size()); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + else + { + status = data->init(0); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + data->set_is_valid(); + break; + } + } + break; + case EDbColUint32: + { + TUint value; + value = view.ColUint32(KDefaultColumnInView_One); + status = data->set_copy_of_buffer(&value, sizeof(value)); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + break; + + case EDbColBinary: + { + TPtrC8 value = view.ColDes8(KDefaultColumnInView_One); + status = data->set_copy_of_buffer(value.Ptr(), value.Length()); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + } + break; + default: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Unexpected column type.\n"))); + User::Leave(KErrGeneral); + break; + } + } + else + { + // Could not find parameter + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Could not find configuration parameter.\n"))); + User::Leave(KErrArgument); + } + + // Close database + CleanupStack::PopAndDestroy(4); // view + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} +//-------------------------------------------------- + +// + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::type_configure_write( + const eap_configuration_field_c * const field, + eap_variable_data_c * const data) +{ + // Here configuration data must be read from type spesific database. + + // NOTE: This is really just for simulation. + // Write is routed to partner object. + eap_status_e status = m_partner->write_configure( + field, + data); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +// + +void eap_am_type_tls_peap_symbian_c::WriteBinaryParamL( + eap_config_string field, + const u32_t field_length, + const eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + // Form the insertion command + TPtrC8 p(reinterpret_cast(field), field_length); + + HBufC* fieldbuf = HBufC::NewLC(KMaxDBFieldNameLength); + TPtr field_name = fieldbuf->Des(); + + field_name.Copy(p); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %s FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, field_name.PtrZ(), &m_db_table_name, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + // Update the columns in the database + view.FirstL(); + + view.UpdateL(); + + if (data->get_is_valid_data() == true) + { + TPtrC8 data_ptr(data->get_data(data->get_data_length()), data->get_data_length()); + view.SetColL(KDefaultColumnInView_One, data_ptr); + } + else + { + view.SetColNullL(KDefaultColumnInView_One); + } + view.PutL(); + + // Close database + CleanupStack::PopAndDestroy(3); // view, 2 strings + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +void eap_am_type_tls_peap_symbian_c::WriteIntParamL( + eap_config_string field, + const u32_t field_length, + eap_variable_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + TPtrC8 p(reinterpret_cast(field), field_length); + + HBufC* fieldbuf = HBufC::NewLC(KMaxDBFieldNameLength); + TPtr field_name = fieldbuf->Des(); + + field_name.Copy(p); + + // Form the insertion command + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %s FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, field_name.PtrZ(), &m_db_table_name, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Create pointers to the data + TPtrC8 data_ptr(data->get_data(data->get_data_length()), data->get_data_length()); + + // Convert the string to integer + const TInt val = *( reinterpret_cast(data_ptr.Ptr()) ); + + // Update the columns in the database + view.FirstL(); + + view.UpdateL(); + + view.SetColL(KDefaultColumnInView_One, val); + view.PutL(); + + // Close database + CleanupStack::PopAndDestroy(3); // view, buf, 2nd buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +void eap_am_type_tls_peap_symbian_c::WriteIntParamL( + eap_config_string field, + const u32_t field_length, + const u32_t value) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + TPtrC8 p(reinterpret_cast(field), field_length); + + HBufC* fieldbuf = HBufC::NewLC(KMaxDBFieldNameLength); + TPtr field_name = fieldbuf->Des(); + + field_name.Copy(p); + + // Form the insertion command + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLInsert, "SELECT %s FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLInsert, field_name.PtrZ(), &m_db_table_name, + &KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Update the columns in the database + view.FirstL(); + + view.UpdateL(); + + view.SetColL(KDefaultColumnInView_One, value); + view.PutL(); + + // Close database + CleanupStack::PopAndDestroy(3); // view, buf, 2nd buf + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +void eap_am_type_tls_peap_symbian_c::ResetSessionIdL() +{ + eap_variable_data_c count_of_session_resumes(m_am_tools); + eap_variable_data_c session_id(m_am_tools); + eap_variable_data_c master_secret(m_am_tools); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("ResetSessionIdL - clearing session resume info.\n"))); + + { + session_id.reset(); + WriteBinaryParamL( + cf_str_EAP_TLS_PEAP_saved_session_id.get_field()->get_field(), + cf_str_EAP_TLS_PEAP_saved_session_id.get_field()->get_field_length(), + &session_id); + } + + { + master_secret.reset(); + WriteBinaryParamL( + cf_str_EAP_TLS_PEAP_saved_master_secret.get_field()->get_field(), + cf_str_EAP_TLS_PEAP_saved_master_secret.get_field()->get_field_length(), + &master_secret); + } + + { + WriteIntParamL( + cf_str_EAP_TLS_PEAP_saved_cipher_suite.get_field()->get_field(), + cf_str_EAP_TLS_PEAP_saved_cipher_suite.get_field()->get_field_length(), + tls_cipher_suites_TLS_NULL_WITH_NULL_NULL); + } +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::alert_received( + const tls_alert_level_e alert_level, + const tls_alert_description_e alert_description) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_UNREFERENCED_PARAMETER(alert_description); // in release + EAP_UNREFERENCED_PARAMETER(alert_level); // in release + + eap_tls_trace_string_c tls_trace; + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: %s: message_function: alert_received(), level %d=%s, description %d=%s\n"), + (m_is_client == true ? "client": "server"), + alert_level, + tls_trace.get_alert_level_string(alert_level), + alert_description, + tls_trace.get_alert_description_string(alert_description))); + + // Store alert description so that it is possible to disallow certificates based + // on that information. + m_latest_alert_description = alert_description; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::query_cipher_suites_and_previous_session() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: function: query_cipher_suites_and_previous_session()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_ASSERT_ALWAYS(m_is_client == true); + + eap_status_e status(eap_status_process_general_error); + + TAlgorithmId certAlgorithm(ERSA); + + bool select_all_cipher_suites = false; + + eap_variable_data_c session_id(m_am_tools); + eap_variable_data_c master_secret(m_am_tools); + tls_cipher_suites_e used_cipher_suite(tls_cipher_suites_TLS_NULL_WITH_NULL_NULL); + tls_session_type_e tls_session_type(tls_session_type_full_authentication); + + eap_array_c cipher_suites(m_am_tools); + +#if defined(USE_FAST_EAP_TYPE) + + if(m_current_eap_type == eap_type_fast && + m_serv_unauth_prov_mode == true) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::query_cipher_suites_and_previous_session-Exception for EAP-FAST as m_serv_unauth_prov_mode is true \n"))); + + tls_session_type = tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP; + + // This is the only cipher suite needed in this case. + { + u16_t *tmp_object = new u16_t; + if (tmp_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *tmp_object = eap_htons(tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA); + + status = cipher_suites.add_object(tmp_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + } + else +#endif // #if defined(USE_FAST_EAP_TYPE) + + { + // This is the normal case for all EAP types (for EAP-FAST with m_serv_unauth_prov_mode = false). + + if (m_own_certificate == 0 + && m_ca_certificate == 0) + { + // Since there is no user certificate and CA cert has not been read yet + // we need to read the CA cert. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("query_cipher_suites_and_previous_session(): No user or CA certificate. Read CA certificate.\n"))); + + if (m_allowed_ca_certs.Count() != 0) + { +#if defined(USE_FAST_EAP_TYPE) + + if(m_current_eap_type == eap_type_fast) + { + // Exception for EAP-FAST + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::query_cipher_suites_and_previous_session - No CA certificate but exception for EAP-FAST\n"))); + } + else +#endif // #if defined(USE_FAST_EAP_TYPE) + { + m_state = EHandlingCipherSuiteQuery; + + TRAPD(err, m_cert_if->ReadCACertificateL(m_allowed_ca_certs[0])); + if (err != KErrNone) + { + // Error occurred. Just select all cipher suites. + select_all_cipher_suites = true; + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); + } + } + } // End: if (m_allowed_ca_certs.Count() != 0) + } + else if (m_own_certificate != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Selecting cipher suites based on user certificate algorithm.\n"))); + + select_all_cipher_suites = false; + + const CSubjectPublicKeyInfo& public_key = m_own_certificate->PublicKey(); + + certAlgorithm = public_key.AlgorithmId(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Selecting cipher suites based on CA certificate algorithm.\n"))); + + select_all_cipher_suites = false; + + const CSubjectPublicKeyInfo& public_key = m_ca_certificate->PublicKey(); + + certAlgorithm = public_key.AlgorithmId(); + } + + // IF cipher suite is allowed + if (m_allowed_cipher_suites.Find(tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA) != KErrNotFound + // AND the algorithm matches the certificates algorithm + && (select_all_cipher_suites == true + || certAlgorithm == ERSA)) + // THEN add it to list. + { + u16_t *tmp_object = new u16_t; + if (tmp_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *tmp_object = eap_htons(tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA); + + status = cipher_suites.add_object(tmp_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + if (m_allowed_cipher_suites.Find(tls_cipher_suites_TLS_RSA_WITH_AES_128_CBC_SHA) != KErrNotFound + // AND the algorithm matches the certificates algorithm + && (select_all_cipher_suites == true + || certAlgorithm == ERSA)) + // THEN add it to list. + { + u16_t *tmp_object = new u16_t; + if (tmp_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *tmp_object = eap_htons(tls_cipher_suites_TLS_RSA_WITH_AES_128_CBC_SHA); + + status = cipher_suites.add_object(tmp_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + if (m_allowed_cipher_suites.Find(tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA) != KErrNotFound + // AND the algorithm matches the certificates algorithm + && (select_all_cipher_suites == true + || certAlgorithm == EDSA)) + // THEN add it to list. + { + u16_t *tmp_object = new u16_t; + if (tmp_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *tmp_object = eap_htons(tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA); + + status = cipher_suites.add_object(tmp_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + if (m_allowed_cipher_suites.Find(tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA) != KErrNotFound + // AND the algorithm matches the certificates algorithm + && (select_all_cipher_suites == true + || certAlgorithm == EDSA)) + // THEN add it to list. + { + u16_t *tmp_object = new u16_t; + if (tmp_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *tmp_object = eap_htons(tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA); + + status = cipher_suites.add_object(tmp_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + if (m_allowed_cipher_suites.Find(tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) != KErrNotFound + // AND the algorithm matches the certificates algorithm + && (select_all_cipher_suites == true + || certAlgorithm == ERSA)) + // THEN add it to list. + { + u16_t *tmp_object = new u16_t; + if (tmp_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *tmp_object = eap_htons(tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA); + + status = cipher_suites.add_object(tmp_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + if (m_allowed_cipher_suites.Find(tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA) != KErrNotFound + // AND the algorithm matches the certificates algorithm + && (select_all_cipher_suites == true + || certAlgorithm == ERSA)) + // THEN add it to list. + { + u16_t *tmp_object = new u16_t; + if (tmp_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *tmp_object = eap_htons(tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA); + + status = cipher_suites.add_object(tmp_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + if (m_allowed_cipher_suites.Find(tls_cipher_suites_TLS_RSA_WITH_RC4_128_MD5) != KErrNotFound + // AND the algorithm matches the certificates algorithm + && (select_all_cipher_suites == true + || certAlgorithm == ERSA)) + // THEN add it to list. + { + u16_t *tmp_object = new u16_t; + if (tmp_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *tmp_object = eap_htons(tls_cipher_suites_TLS_RSA_WITH_RC4_128_MD5); + + status = cipher_suites.add_object(tmp_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + if (m_allowed_cipher_suites.Find(tls_cipher_suites_TLS_RSA_WITH_RC4_128_SHA) != KErrNotFound + // AND the algorithm matches the certificates algorithm + && (select_all_cipher_suites == true + || certAlgorithm == ERSA)) + // THEN add it to list.) + { + u16_t *tmp_object = new u16_t; + if (tmp_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *tmp_object = eap_htons(tls_cipher_suites_TLS_RSA_WITH_RC4_128_SHA); + + status = cipher_suites.add_object(tmp_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (is_session_valid()) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Trying to resume previous session as previous session is still valid\n"))); + + // OK, previous session will be restored. + + // Read database fields. + { + eap_status_e status = type_configure_read( + cf_str_EAP_TLS_PEAP_saved_session_id.get_field(), + &session_id); + if (status != eap_status_ok + || session_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + { + eap_status_e status = type_configure_read( + cf_str_EAP_TLS_PEAP_saved_master_secret.get_field(), + &master_secret); + if (status != eap_status_ok + || master_secret.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + { + eap_variable_data_c saved_cipher_suite(m_am_tools); + + eap_status_e status = type_configure_read( + cf_str_EAP_TLS_PEAP_saved_cipher_suite.get_field(), + &saved_cipher_suite); + if (status == eap_status_ok + && saved_cipher_suite.get_is_valid_data() == true + && saved_cipher_suite.get_data_length() == sizeof(u32_t) + && saved_cipher_suite.get_data(sizeof(u32_t)) != 0) + { + // OK + used_cipher_suite = static_cast(*(reinterpret_cast(saved_cipher_suite.get_data(sizeof(u32_t))))); + + u16_t tmp_object = eap_htons(static_cast (used_cipher_suite)); + + tls_session_type = tls_session_type_original_session_resumption; + + if( 0 > find_simple( &cipher_suites, + &tmp_object, + m_am_tools ) ) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: cipher suite of the resumed session is NOT included in the cipher_suites list.\n"), + (m_is_client == true ? "client": "server"))); + + used_cipher_suite = tls_cipher_suites_TLS_NULL_WITH_NULL_NULL; + + master_secret.reset(); + + session_id.reset(); + } + } + } + } + + if(used_cipher_suite == tls_cipher_suites_TLS_NULL_WITH_NULL_NULL) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: query_cipher_suites_and_previous_session(): creates new session.\n"), + (m_is_client == true ? "client": "server"))); + + TRAPD(err, ResetSessionIdL()); + if (err != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + tls_session_type = tls_session_type_full_authentication; + } + + } // End : if(m_current_eap_type == eap_type_fast && + // m_serv_unauth_prov_mode == true) + + + // Compression methods. TLS supports only null compression at the moment. + eap_array_c compression_methods(m_am_tools); + { + u8_t *tmp_object = new u8_t; + if (tmp_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + *tmp_object = tls_compression_method_null; + status = compression_methods.add_object(tmp_object, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + status = get_tls_am_partner()->complete_query_cipher_suites_and_previous_session( + tls_session_type, + &cipher_suites, + &compression_methods, +#if defined(USE_EAP_TLS_SESSION_TICKET) + 0, +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + &session_id, + &master_secret, + used_cipher_suite, + eap_status_ok); + if (status == eap_status_ok || + status == eap_status_pending_request) + { + status = eap_status_completed_request; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_TLS_SESSION_TICKET) + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::query_new_session_ticket() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: %s: message_function: query_new_session_ticket()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_ASSERT_ALWAYS(m_is_client == false); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::select_cipher_suite_and_check_session_id( + EAP_TEMPLATE_CONST eap_array_c * const cipher_suite_proposal, + const eap_variable_data_c * const session_id +#if defined(USE_EAP_TLS_SESSION_TICKET) + , const tls_extension_c * const /* session_ticket */ +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: function: select_cipher_suite_and_check_session_id()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_ASSERT_ALWAYS(m_is_client == false); + + eap_status_e status = eap_status_illegal_payload; + u16_t *tmp_object = 0; + + tls_session_type_e tls_session_type(tls_session_type_full_authentication); + + for (u32_t ind = 0; ind < cipher_suite_proposal->get_object_count(); ind++) + { + tmp_object = cipher_suite_proposal->get_object(ind); + if (tmp_object == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + if (m_allowed_cipher_suites.Find(*tmp_object) != KErrNotFound) + { + // Read stored session id + eap_variable_data_c stored_session_id(m_am_tools); + eap_variable_data_c stored_master_secret(m_am_tools); + tls_cipher_suites_e stored_cipher_suite(tls_cipher_suites_TLS_NULL_WITH_NULL_NULL); + + eap_variable_data_c count_of_session_resumes(m_am_tools); + + { + status = type_configure_read( + cf_str_EAP_TLS_PEAP_saved_session_id.get_field(), + &stored_session_id); + if (status != eap_status_ok + || stored_session_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + if (session_id != 0 + && session_id->get_is_valid_data() == true + && session_id->compare(&stored_session_id) == 0 + && is_session_valid()) + { + // OK, previous session will be restored. + + // Read database fields. + { + eap_status_e status = type_configure_read( + cf_str_EAP_TLS_PEAP_saved_session_id.get_field(), + &stored_session_id); + if (status != eap_status_ok + || stored_session_id.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + { + eap_status_e status = type_configure_read( + cf_str_EAP_TLS_PEAP_saved_master_secret.get_field(), + &stored_master_secret); + if (status != eap_status_ok + || stored_master_secret.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + { + eap_variable_data_c saved_cipher_suite(m_am_tools); + + eap_status_e status = type_configure_read( + cf_str_EAP_TLS_PEAP_saved_cipher_suite.get_field(), + &saved_cipher_suite); + if (status == eap_status_ok + && saved_cipher_suite.get_is_valid_data() == true + && saved_cipher_suite.get_data_length() == sizeof(u32_t) + && saved_cipher_suite.get_data(sizeof(u32_t)) != 0) + { + // OK + + stored_cipher_suite = static_cast(*(reinterpret_cast(saved_cipher_suite.get_data(sizeof(u32_t))))); + } + else + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); + } + } + + tls_session_type = tls_session_type_original_session_resumption; + + } + else + { + { + stored_session_id.reset(); + + TRAPD(err, WriteBinaryParamL( + cf_str_EAP_TLS_PEAP_saved_session_id.get_field()->get_field(), + cf_str_EAP_TLS_PEAP_saved_session_id.get_field()->get_field_length(), + &stored_session_id)); + if (err != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + + { + stored_master_secret.reset(); + + TRAPD(err, WriteBinaryParamL( + cf_str_EAP_TLS_PEAP_saved_master_secret.get_field()->get_field(), + cf_str_EAP_TLS_PEAP_saved_master_secret.get_field()->get_field_length(), + &stored_master_secret)); + if (err != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + + { + TRAPD(err, WriteIntParamL( + cf_str_EAP_TLS_PEAP_saved_cipher_suite.get_field()->get_field(), + cf_str_EAP_TLS_PEAP_saved_cipher_suite.get_field()->get_field_length(), + tls_cipher_suites_TLS_NULL_WITH_NULL_NULL)); + if (err != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + } + } + + if (stored_cipher_suite != tls_cipher_suites_TLS_NULL_WITH_NULL_NULL) + { + // We got saved cipher suite from previous session + m_cipher_suite = stored_cipher_suite; + } + else + { + // Use the first cipher suite the client offered + m_cipher_suite = static_cast(*tmp_object); + } + + status = get_tls_am_partner()->complete_select_cipher_suite_and_check_session_id( + tls_session_type, + static_cast(m_cipher_suite), + &stored_session_id, + &stored_master_secret, +#if defined(USE_EAP_TLS_SESSION_TICKET) + 0, +#endif // #if defined(USE_EAP_TLS_SESSION_TICKET) + eap_status_ok); + + break; + } + } // for() + + if (status == eap_status_ok || + status == eap_status_pending_request) + { + status = eap_status_completed_request; + } + + if (status != eap_status_completed_request) + { + // Could not find matching cipher suite + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Server: Could not find matching cipher suite in client's proposal.\n"))); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::verify_certificate_chain( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain, + const tls_cipher_suites_e required_cipher_suite) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: message_function: verify_certificate_chain_and_query_public_key()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_ASSERT_ALWAYS(certificate_chain->get_object_count() > 0); + + eap_status_e status(eap_status_ok); + + TRAPD(err, verify_certificate_chainL(certificate_chain, required_cipher_suite)); + if (err != KErrNone) + { + if (err == KErrArgument) + { + status = eap_status_illegal_certificate; + } + else + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_type_tls_peap_symbian_c::verify_certificate_chainL( + EAP_TEMPLATE_CONST eap_array_c * const certificate_chain, + const tls_cipher_suites_e required_cipher_suite) +{ + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::verify_certificate_chainL: Number of certificates in chain=%d\n"), + certificate_chain->get_object_count())); + + eap_status_e status(eap_status_process_general_error); + if (m_is_client) + { + m_cipher_suite = required_cipher_suite; + } + + // Verify that server certificate's realm matches with our identity realm + // If server does not verify client then we don't necessarily have a certificate + // and thus we cannot verify server here. + if (m_is_client + && m_verify_certificate_realm == true + && (m_own_certificate != 0 + || (m_use_manual_realm == true + && m_manual_realm.get_is_valid_data() == true))) + { + eap_variable_data_c client_subject_realm(m_am_tools); + eap_variable_data_c manual_client_subject_realm(m_am_tools); + eap_variable_data_c client_issuer_realm(m_am_tools); + + if (m_own_certificate != 0) + { + status = get_realms_from_certificate( + m_own_certificate, + &client_subject_realm, + &client_issuer_realm); + if (status != eap_status_ok) + { + // Could not find realms... Give up. + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAP-TLS: Could not find realm from client certificate.\n"))); + User::Leave(KErrArgument); + } + } + else + { + status = client_subject_realm.init(0); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + client_subject_realm.set_is_valid(); + + status = client_issuer_realm.init(0); + if (status != eap_status_ok) + { + User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status))); + } + + client_issuer_realm.set_is_valid(); + } + + if (m_use_manual_realm == true + && m_manual_realm.get_is_valid_data() == true) + { + status = manual_client_subject_realm.set_copy_of_buffer(&m_manual_realm); + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + } + + eap_variable_data_c server_subject_realm(m_am_tools); + eap_variable_data_c server_issuer_realm(m_am_tools); + + eap_variable_data_c* cert; + cert = certificate_chain->get_object(0); + + if( cert == NULL ) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: No certs in certificate_chain\n"))); + + User::Leave(KErrArgument); + } + + TPtr8 ptr( + cert->get_data(cert->get_data_length()), + cert->get_data_length(), + cert->get_data_length()); + CX509Certificate* server_certificate = CX509Certificate::NewL(ptr); + + if( server_certificate == NULL ) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: No memory for server_certificate\n"))); + + User::Leave(KErrNoMemory); + } + + CleanupStack::PushL(server_certificate); + + status = get_realms_from_certificate( + server_certificate, + &server_subject_realm, + &server_issuer_realm); + if (status != eap_status_ok + || server_subject_realm.get_is_valid_data() == false + || server_issuer_realm.get_is_valid_data() == false) + { + // Could not find realms... Give up. + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAP-TLS: Could not find realm from server certificate.\n"))); + User::Leave(KErrArgument); + } + CleanupStack::PopAndDestroy(server_certificate); + + if (client_subject_realm.get_is_valid_data() == true) + { + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, (EAPL("Client subject realm:"), + client_subject_realm.get_data(client_subject_realm.get_data_length()), + client_subject_realm.get_data_length())); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Client subject realm is empty.\n"))); + } + + if (manual_client_subject_realm.get_is_valid_data() == true) + { + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, (EAPL("Client manual realm:"), + manual_client_subject_realm.get_data(manual_client_subject_realm.get_data_length()), + manual_client_subject_realm.get_data_length())); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Client manual realm is empty.\n"))); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, (EAPL("Server subject realm:"), + server_subject_realm.get_data(server_subject_realm.get_data_length()), + server_subject_realm.get_data_length())); + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, (EAPL("Server issuer realm:"), + server_issuer_realm.get_data(server_issuer_realm.get_data_length()), + server_issuer_realm.get_data_length())); + + // First check exact match with client subject realm and server subject and issuer realms + if (client_subject_realm.get_is_valid_data() == false + || (client_subject_realm.get_is_valid_data() == true + && client_subject_realm.compare(&server_subject_realm) != 0 + && client_subject_realm.compare(&server_issuer_realm) != 0)) + { + // Check if manual realm matches + if (manual_client_subject_realm.get_is_valid_data() == false + || (manual_client_subject_realm.get_is_valid_data() == true + && manual_client_subject_realm.compare(&server_subject_realm) != 0 + && manual_client_subject_realm.compare(&server_issuer_realm) != 0)) + { + // Realms did not match! Are we allowed to do relaxed subdomain checking? + if (m_allow_subdomain_matching == true) + { + + TPtr8 client_subject_ptr( + client_subject_realm.get_data(client_subject_realm.get_data_length()), + client_subject_realm.get_data_length(), + client_subject_realm.get_data_length()); + + TPtr8 server_subject_ptr( + server_subject_realm.get_data(server_subject_realm.get_data_length()), + server_subject_realm.get_data_length(), + server_subject_realm.get_data_length()); + + TPtr8 server_issuer_ptr( + server_issuer_realm.get_data(server_issuer_realm.get_data_length()), + server_issuer_realm.get_data_length(), + server_issuer_realm.get_data_length()); + + if (client_subject_ptr.Length() == 0 + || (server_subject_ptr.Find(client_subject_ptr) == KErrNotFound + && server_issuer_ptr.Find(client_subject_ptr) == KErrNotFound)) + { + // still not ok + + // One more test: subdomain matching with manual realm + if (manual_client_subject_realm.get_is_valid_data() == true) + { + TPtr8 manual_client_subject_ptr( + manual_client_subject_realm.get_data(manual_client_subject_realm.get_data_length()), + manual_client_subject_realm.get_data_length(), + manual_client_subject_realm.get_data_length()); + + if (manual_client_subject_ptr.Length() == 0 + || (server_subject_ptr.Find(manual_client_subject_ptr) == KErrNotFound + && server_issuer_ptr.Find(manual_client_subject_ptr) == KErrNotFound)) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: Client and server realms do not match.\n"))); + + send_error_notification(eap_status_realm_check_failed); + + User::Leave(KErrArgument); + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: Client and server realms do not match.\n"))); + + send_error_notification(eap_status_realm_check_failed); + + User::Leave(KErrArgument); + } + } + } + else + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: Client and server realms do not match.\n"))); + + send_error_notification(eap_status_realm_check_failed); + + User::Leave(KErrArgument); + } + } + } + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Server certificate realm verification OK.\n"))); + } + + HBufC8* chain = HBufC8::NewL(0); + HBufC8* temp; + eap_variable_data_c* cert; + + for (u32_t i = 0; i < certificate_chain->get_object_count(); i++) + { + cert = certificate_chain->get_object(i); + + if( cert == NULL ) + { + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: Problem in certificate_chain\n"))); + + User::Leave(KErrArgument); + } + +#if defined(_DEBUG) || defined(DEBUG) + + TPtr8 certPtr( + cert->get_data(cert->get_data_length()), + cert->get_data_length(), + cert->get_data_length()); + CX509Certificate* x509Cert = CX509Certificate::NewL(certPtr); + + if( x509Cert != NULL ) + { + CleanupStack::PushL(x509Cert); + + TKeyIdentifier KeyIdentifier = x509Cert->KeyIdentifierL(); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Key identifier is"), + KeyIdentifier.Ptr(), + KeyIdentifier.Size())); + + // This is for subject key id. + const CX509CertExtension* certExt = x509Cert->Extension(KSubjectKeyId); + + if (certExt) + { + const CX509SubjectKeyIdExt* subKeyExt = CX509SubjectKeyIdExt::NewLC(certExt->Data()); + EAP_UNREFERENCED_PARAMETER(subKeyExt); + + EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("The Subject key Id is:"), + subKeyExt->KeyId().Ptr(), + subKeyExt->KeyId().Size())); + + CleanupStack::PopAndDestroy(); // subKeyExt + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: verify_certificate_chainL - No extension for this certificate\n"))); + } + + CleanupStack::PopAndDestroy(x509Cert); + } + +#endif + + CleanupStack::PushL(chain); + temp = chain->ReAllocL(chain->Length() + cert->get_data_length()); + chain = temp; + TPtr8 ptr = chain->Des(); + ptr.Append(cert->get_data(cert->get_data_length()), cert->get_data_length()); + if (i == 0) + { + // This is the peer certificate. Save it. + if (m_peer_certificate != 0) + { + delete m_peer_certificate; + } + m_peer_certificate = CX509Certificate::NewL(ptr); + } + CleanupStack::Pop(); + } + CleanupStack::PushL(chain); + TPtr8 certChain = chain->Des(); + m_cert_if->ValidateChainL(certChain, m_allowed_ca_certs); + + CleanupStack::PopAndDestroy(); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + // This returns eap_status_pending_request + User::Leave(KErrCompletion); + +} + + +void eap_am_type_tls_peap_symbian_c::complete_validate_chain( + CPKIXValidationResult& aValidationResult, eap_status_e aStatus) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if(aStatus != eap_status_ok) + { + get_tls_am_partner()->complete_verify_certificate_chain(aStatus); + return; + } + + eap_status_e result; + if (aValidationResult.Error().iReason == EValidatedOK) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("Certificate chain validation OK. Reason: %d\n"), + aValidationResult.Error().iReason)); + result = eap_status_ok; + } + else + { + if (aValidationResult.Error().iReason == EDateOutOfRange) + { + send_error_notification(eap_status_certificate_expired); + // Ignore error on purpose + } + else + { + send_error_notification(eap_status_illegal_certificate); + // Ignore error on purpose + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Certificate chain validation FAILED. Reason: %d\n"), + aValidationResult.Error().iReason)); + + result = eap_status_illegal_certificate; + } + + // Copy the public key + const CSubjectPublicKeyInfo& publicKey = m_peer_certificate->PublicKey(); + TPtrC8 ptr = publicKey.KeyData(); + m_peer_public_key.reset(); + eap_status_e status = m_peer_public_key.set_copy_of_buffer(ptr.Ptr(), ptr.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: complete_validate_chain: could not allocate memory."))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + get_tls_am_partner()->complete_verify_certificate_chain(result); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +#if defined(USE_FAST_EAP_TYPE) +#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) +eap_status_e eap_am_type_tls_peap_symbian_c::ReadFileConfig() + { + eap_status_e status = eap_status_ok; + + eap_am_file_input_symbian_c * const fileio = new eap_am_file_input_symbian_c(m_am_tools); + + eap_automatic_variable_c automatic_fileio(m_am_tools, fileio); + + if (fileio != 0 + && fileio->get_is_valid() == true) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Initialize file configuration.\n"))); + + eap_variable_data_c file_name_c_data(m_am_tools); + + { + #if defined(EAPOL_SYMBIAN_VERSION_7_0_s) + eap_const_string const FILECONFIG_FILENAME_C + = "c:\\system\\data\\eap.conf"; + #else + eap_const_string const FILECONFIG_FILENAME_C + = "c:\\private\\101F8EC5\\eap.conf"; + #endif + + status = file_name_c_data.set_copy_of_buffer( + FILECONFIG_FILENAME_C, + m_am_tools->strlen(FILECONFIG_FILENAME_C)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = file_name_c_data.add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + eap_variable_data_c file_name_z_data(m_am_tools); + + { + #if defined(EAPOL_SYMBIAN_VERSION_7_0_s) + eap_const_string const FILECONFIG_FILENAME_Z + = "z:\\system\\data\\eap.conf"; + #else + eap_const_string const FILECONFIG_FILENAME_Z + = "z:\\private\\101F8EC5\\eap.conf"; + #endif + + status = file_name_z_data.set_copy_of_buffer( + FILECONFIG_FILENAME_Z, + m_am_tools->strlen(FILECONFIG_FILENAME_Z)); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = file_name_z_data.add_end_null(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + + if (status == eap_status_ok) + { + // First try open from C: disk. + status = fileio->file_open( + &file_name_c_data, + eap_file_io_direction_read); + if (status == eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Opens configure file %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + else if (status != eap_status_ok) + { + // Second try open from Z: disk. + status = fileio->file_open( + &file_name_z_data, + eap_file_io_direction_read); + if (status == eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Opens configure file %s\n"), + file_name_z_data.get_data(file_name_z_data.get_data_length()))); + } + } + + if (status == eap_status_ok) + { + // Some of the files were opened. + + m_fileconfig = new eap_file_config_c(m_am_tools); + if (m_fileconfig != 0 + && m_fileconfig->get_is_valid() == true) + { + status = m_fileconfig->configure(fileio); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Configure read from %s failed.\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Configure read from %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + } + else + { + // No file configuration. + delete m_fileconfig; + m_fileconfig = 0; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Cannot create configure object for file %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()))); + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Cannot open configure file neither %s nor %s\n"), + file_name_c_data.get_data(file_name_c_data.get_data_length()), + file_name_z_data.get_data(file_name_z_data.get_data_length()))); + } + } + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Skips file configuration.\n"))); + } + + eap_variable_data_c skip_user_interactions(m_am_tools); + + if (m_fileconfig != 0 + && m_fileconfig->get_is_valid() == true) + { + // Here we could try the final configuration option. + status = m_fileconfig->read_configure( + cf_str_EAP_skip_user_interactions_for_testing_purposes.get_field(), + &skip_user_interactions); + } + + if (status == eap_status_ok + && skip_user_interactions.get_is_valid_data() == true) + { + u32_t *skip_user_interactions_flag = reinterpret_cast( + skip_user_interactions.get_data(sizeof(u32_t))); + if (skip_user_interactions_flag != 0) + { + if (*skip_user_interactions_flag != 0) + { + m_skip_user_interactions = true; + } + else + { + m_skip_user_interactions = false; + } + } + } + + iPacStoreDb->SkipUserActions (m_skip_user_interactions); + + return status; + } +#endif //#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS) +#endif + + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::query_certificate_chain( + EAP_TEMPLATE_CONST eap_array_c * const certificate_authorities, + EAP_TEMPLATE_CONST eap_array_c * const certificate_types, + const tls_cipher_suites_e required_cipher_suite) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (m_is_client) + { + m_cipher_suite = required_cipher_suite; + } + + eap_status_e status(eap_status_pending_request); + m_state = EHandlingChainQuery; + TInt err(KErrNone); + + if (m_is_client) + { + // Get the matching certificates + TRAPD(err, m_cert_if->GetMatchingCertificatesL( + m_allowed_user_certs, + ETrue, + certificate_authorities, + ETrue, + certificate_types, + ETrue, + m_allowed_cipher_suites)); + + (void)EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(err)); + } + else + { + // server + TRAPD(err, m_cert_if->GetMatchingCertificatesL( + m_allowed_user_certs, + EFalse, + 0, + EFalse, + 0, + ETrue, + m_allowed_cipher_suites)); + + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + } + } + + if (err == KErrNone) + { + status = eap_status_pending_request; + } + else + { + // Convert the leave error code to EAPOL stack error code. + status = m_am_tools->convert_am_error_to_eapol_error(err); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + +} + +void eap_am_type_tls_peap_symbian_c::complete_get_matching_certificates( + CArrayFixFlat& aMatchingCerts, + eap_status_e aStatus) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_UNREFERENCED_PARAMETER(aStatus); + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::complete_get_matching_certificates-Matching cert count after possible cert removal=%d, m_state=%d, aStatus=%d\n"), + aMatchingCerts.Count(), m_state, aStatus)); + + if (m_state == EHandlingIdentityQuery) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::complete_get_matching_certificates(): EHandlingIdentityQuery\n"))); + + // Add found certs to allowed certificate list. + // This list is updated here because there might be certificates that have been removed. + m_allowed_user_certs.Reset(); + for (TInt i = 0; i < aMatchingCerts.Count(); i++) + { + TRAPD(err, m_allowed_user_certs.AppendL(aMatchingCerts[i])); + if (err != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: eap_am_type_tls_peap_symbian_c::complete_get_matching_certificates -EHandlingIdentityQuery- Error=%d\n"), + err)); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_allocation_error, + false, + 0, + false, + 0); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + + if (m_allowed_user_certs.Count() == 0) + { + // No allowed user certificates. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAP-TLS: No allowed user certificates configured.\n"))); + + if (m_tls_peap_server_authenticates_client_policy_flag == true) + { + // Certificate is really required + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: Could not find proper user certificate.\n"))); + + send_error_notification(eap_status_user_certificate_unknown); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_illegal_certificate, + false, + 0, + false, + 0); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (m_use_manual_realm == false) + { + // Since there is no user certificate or manual realm configured + // the realm needs to be dig out from the CA certificate. + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c: no manual realm - no user cert. Get realm from CA certificate.\n"))); + + TInt allowed_ca_cert_count = m_allowed_ca_certs.Count(); + TInt err(KErrNone); + + if(allowed_ca_cert_count > 0) + { + TRAP(err, m_cert_if->ReadCACertificateL(m_allowed_ca_certs[0])); + } + if (err != KErrNone || allowed_ca_cert_count <= 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: EAP-TLS: Cannot read user certificate or No CA cert configured, CA cert count=%d.\n"), + allowed_ca_cert_count)); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because identity query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_illegal_certificate, + false, + 0, + false, + 0); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-TLS: Uses manual realm.\n"))); + + get_am_partner()->complete_eap_identity_query( + 0, // 0 because certificate query failed + &m_receive_network_id, + m_eap_identifier, + eap_status_ok, + m_use_manual_username, + &m_manual_username, + m_use_manual_realm, + &m_manual_realm); + + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + // Just complete (this selects the first certificate in the array) + m_selector_output.SetLength(0); + TRequestStatus* reqStatus = &iStatus; + User::RequestComplete(reqStatus, KErrNone); + SetActive(); + } + else if (m_state == EHandlingChainQuery) + { + + if (aMatchingCerts.Count() > 0) + { + m_allowed_user_certs.Reset(); + + for (TInt i = 0; i < aMatchingCerts.Count(); i++) + { + TRAPD(err, m_allowed_user_certs.AppendL(aMatchingCerts[i])); + if (err != KErrNone) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_tls_peap_symbian_c::complete_get_matching_certificates -EHandlingChainQuery- Error=%d\n"), + err)); + + get_tls_am_partner()->complete_query_certificate_chain(0, eap_status_allocation_error); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + } + } + + if (m_allowed_user_certs.Count() == 0) + { + // No matching or allowed certs and no pre-loaded cert. + // Could not find matching certificate + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAP-TLS: Could not find proper user certificate.\n"))); + + if (m_tls_peap_server_authenticates_client_policy_flag == true) + { + send_error_notification(eap_status_user_certificate_unknown); + } + + get_tls_am_partner()->complete_query_certificate_chain(0, eap_status_illegal_certificate); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + // We got at least one allowed user cert. + // Just use the first allowed certificate + // Don't ask user. Just complete (this selects the first certificate in the array) + m_selector_output.SetLength(0); + TRequestStatus* reqStatus = &iStatus; + User::RequestComplete(reqStatus, KErrNone); + SetActive(); + + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAP-TLS: Illegal state in complete_get_matching_certs.\n"))); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; +} + + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::query_certificate_authorities_and_types() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: message_function: query_certificate_authorities_and_types()\n"), + (m_is_client == true ? "client": "server"))); + + EAP_ASSERT_ALWAYS(!m_is_client); + + eap_status_e status; + eap_array_c certificate_authorities(m_am_tools); + eap_variable_data_c ca_dn(m_am_tools); + + // TEST CODE: This is not a proper CA DN. + _LIT8(KTestCA, "ca.eapsim.foo"); + status = ca_dn.add_data(KTestCA().Ptr(), KTestCA().Size()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = certificate_authorities.add_object(&ca_dn, false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + eap_array_c certificate_types(m_am_tools); + + { + u8_t * const dummy_certificate_type = new u8_t; + if (dummy_certificate_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *dummy_certificate_type = tls_certificate_type_rsa_sign; + + status = certificate_types.add_object(dummy_certificate_type, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + { + u8_t * const dummy_certificate_type = new u8_t; + if (dummy_certificate_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + *dummy_certificate_type = tls_certificate_type_dss_sign; + + status = certificate_types.add_object(dummy_certificate_type, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + + status = get_tls_am_partner()->complete_query_certificate_authorities_and_types( + &certificate_authorities, + &certificate_types, + eap_status_ok); + if (status == eap_status_ok || + status == eap_status_pending_request) + { + status = eap_status_completed_request; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::query_dh_parameters( + EAP_TEMPLATE_CONST eap_array_c * const /*certificate_chain*/, + const tls_cipher_suites_e required_cipher_suite) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: message_function: query_dh_parameters()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status = eap_status_process_general_error; + + if (required_cipher_suite != m_cipher_suite) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); + } + + if (EapTlsPeapUtils::CipherSuiteIsEphemeralDHKeyExchange(m_cipher_suite)) + { + eap_variable_data_c dhe_prime(m_am_tools); + status = dhe_prime.set_copy_of_buffer(SAE_GROUP_PRIME, SAE_GROUP_PRIME_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c dhe_group_generator(m_am_tools); + + status = dhe_group_generator.set_copy_of_buffer(SAE_GROUP_GENERATOR, SAE_GROUP_GENERATOR_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = get_tls_am_partner()->complete_query_dh_parameters( + &dhe_prime, + &dhe_group_generator, + eap_status_ok); + } + else + { + status = eap_status_not_supported; + } + + if (status == eap_status_ok || + status == eap_status_pending_request) + { + status = eap_status_completed_request; + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::query_realm( + EAP_TEMPLATE_CONST eap_array_c * const /*certificate_chain*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_tls_peap_symbian_c::get_realms_from_certificate( + CX509Certificate* certificate, + eap_variable_data_c * const subject_realm, + eap_variable_data_c * const issuer_realm) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status(eap_status_process_general_error); + _LIT8(KAt, "@"); + eap_variable_data_c subject_identity(m_am_tools); + eap_variable_data_c issuer_identity(m_am_tools); + + TInt offset = KErrNotFound; + + // SUBJECT + // Try alternative name first + TRAPD(err, get_identity_from_alternative_nameL(certificate, &subject_identity)); + if (err == KErrNone) + { + // Parse realm from identity + TPtr8 ptr( + subject_identity.get_data(subject_identity.get_data_length()), + subject_identity.get_data_length(), + subject_identity.get_data_length()); + + offset = ptr.Find(KAt); + } + + if (offset == KErrNotFound) + { + // Check DN + TRAPD(err, get_identities_from_distinguished_namesL(certificate, &subject_identity, &issuer_identity)); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAP-TLS: Could not find realm from certificate.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_certificate); + } + + // Parse realm from identity + TPtr8 ptr( + subject_identity.get_data(subject_identity.get_data_length()), + subject_identity.get_data_length(), + subject_identity.get_data_length()); + offset = ptr.Find(KAt); + // Don't worry if @ is not found. Then just use the whole CN as realm. + // It probably is the realm in CA certificates. + } + + TPtr8 ptr( + subject_identity.get_data(subject_identity.get_data_length()), + subject_identity.get_data_length(), + subject_identity.get_data_length()); + + status = subject_realm->set_copy_of_buffer((ptr.Mid(offset + 1)).Ptr(), ptr.Length() - offset - 1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // ISSUER + // Check DN + TRAP(err, get_identities_from_distinguished_namesL(certificate, &subject_identity, &issuer_identity)); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAP-TLS: Could not find realm from certificate.\n"))); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_certificate); + } + + // Parse realm from identity + TPtr8 ptr2( + issuer_identity.get_data(issuer_identity.get_data_length()), + issuer_identity.get_data_length(), + issuer_identity.get_data_length()); + + offset = ptr2.Find(KAt); + + status = issuer_realm->set_copy_of_buffer((ptr2.Mid(offset + 1)).Ptr(), ptr2.Length() - offset - 1); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::save_tls_session( + const eap_variable_data_c * const session_id, + const eap_variable_data_c * const master_secret, + const tls_cipher_suites_e used_cipher_suite +#if defined(USE_EAP_TLS_SESSION_TICKET) + , const tls_extension_c * const new_session_ticket +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + eap_status_e status = eap_status_ok; + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: save_tls_session()\n"), + (m_is_client == true ? "client": "server"))); + + // Save current session. + if (session_id != 0 + && session_id->get_is_valid_data() == true + && master_secret != 0 + && master_secret->get_is_valid_data() == true) + { + // Send error if any of the parameters are too long. + if(session_id->get_data_length() > KMaxSessionIdLengthInDB + || master_secret->get_data_length() > KMaxMasterSecretLengthInDB) + { + // Some of the parameters are too long. Can't store them in DB. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::save_tls_session: ") + EAPL("Too long parameters. Length: session_id=%d, master_secret=%d \n"), + session_id->get_data_length(), master_secret->get_data_length())); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + { + TRAPD(err, WriteBinaryParamL( + cf_str_EAP_TLS_PEAP_saved_session_id.get_field()->get_field(), + cf_str_EAP_TLS_PEAP_saved_session_id.get_field()->get_field_length(), + session_id)); + if (err != KErrNone) + { + // Convert the leave error code to EAPOL stack error code. + status = m_am_tools->convert_am_error_to_eapol_error(err); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + { + TRAPD(err, WriteBinaryParamL( + cf_str_EAP_TLS_PEAP_saved_master_secret.get_field()->get_field(), + cf_str_EAP_TLS_PEAP_saved_master_secret.get_field()->get_field_length(), + master_secret)); + if (err != KErrNone) + { + // Convert the leave error code to EAPOL stack error code. + status = m_am_tools->convert_am_error_to_eapol_error(err); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + { + TRAPD(err, WriteIntParamL( + cf_str_EAP_TLS_PEAP_saved_cipher_suite.get_field()->get_field(), + cf_str_EAP_TLS_PEAP_saved_cipher_suite.get_field()->get_field_length(), + used_cipher_suite)); + if (err != KErrNone) + { + // Convert the leave error code to EAPOL stack error code. + status = m_am_tools->convert_am_error_to_eapol_error(err); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } + +#if defined(USE_EAP_TLS_SESSION_TICKET) + if (m_use_session_ticket == true + && new_session_ticket != 0) + { + // Save new session ticket. + } +#endif //#if defined(USE_EAP_TLS_SESSION_TICKET) + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} +//-------------------------------------------------- +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::rsa_encrypt_with_public_key( + const eap_variable_data_c * const premaster_secret) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: message_function: rsa_encrypt_with_public_key()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_peer_public_key.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DATA_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, (EAPL("TLS: rsa_encrypt_with_public_key() m_peer_public_key"), + m_peer_public_key.get_data(m_peer_public_key.get_data_length()), + m_peer_public_key.get_data_length())); + + + crypto_rsa_c rsa(m_am_tools); + + eap_variable_data_c encrypted_premaster_secret(m_am_tools); + + eap_status_e status = rsa.encrypt_with_public_key( + &m_peer_public_key, + premaster_secret, + &encrypted_premaster_secret); + + status = get_tls_am_partner()->complete_rsa_encrypt_with_public_key( + &encrypted_premaster_secret, + eap_status_ok); + if (status == eap_status_ok + || status == eap_status_pending_request) + { + status = eap_status_completed_request; + } + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::rsa_decrypt_with_private_key( + const eap_variable_data_c * const encrypted_premaster_secret) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: message_function: rsa_decrypt_with_private_key()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_pending_request); + if (m_own_certificate == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + HBufC8* data = 0; + + TRAPD(err, data = HBufC8::NewL(encrypted_premaster_secret->get_data_length())); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + TPtr8 ptr = data->Des(); + + ptr.Copy(encrypted_premaster_secret->get_data(encrypted_premaster_secret->get_data_length()), + encrypted_premaster_secret->get_data_length()); + + TRAP(err, m_cert_if->DecryptL(m_own_certificate_info.iSubjectKeyId, *data)); + + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + } + else + { + status = eap_status_pending_request; + } + + delete data; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +void eap_am_type_tls_peap_symbian_c::complete_decrypt(TDes8& aData, eap_status_e aStatus) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (aStatus != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: eap_am_type_tls_peap_symbian_c::complete_decrypt, aStatus=%d\n"), + aStatus)); + + get_tls_am_partner()->complete_rsa_decrypt_with_private_key(0, aStatus); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + if (aData.Length() == 0) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Decrypt with private key failed.\n"))); + get_tls_am_partner()->complete_rsa_decrypt_with_private_key(0, eap_status_decryption_failure); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + eap_variable_data_c decrypted_data(m_am_tools); + eap_status_e status = decrypted_data.set_copy_of_buffer(aData.Ptr(), aData.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: rsa_decrypt_with_private_key() decrypted data"), + decrypted_data.get_data(decrypted_data.get_data_length()), + decrypted_data.get_data_length())); + + status = get_tls_am_partner()->complete_rsa_decrypt_with_private_key(&decrypted_data, eap_status_ok); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::sign_with_private_key( + const eap_variable_data_c * const message_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: message_function: sign_with_private_key()\n"), + (m_is_client == true ? "client": "server"))); + + eap_status_e status(eap_status_pending_request); + if (m_own_certificate == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: sign_with_private_key() message_hash"), + message_hash->get_data(message_hash->get_data_length()), + message_hash->get_data_length())); + + + HBufC8* buf = 0; + TRAPD(err, buf = HBufC8::NewL(message_hash->get_data_length())) + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + TPtr8 hash = buf->Des(); + + hash.Copy(message_hash->get_data(message_hash->get_data_length()), message_hash->get_data_length()); + + + // Calculate the signature length based on algorithm and public key lenght + TUint signature_length(0); + + const CSubjectPublicKeyInfo& public_key = m_own_certificate->PublicKey(); + + if (public_key.AlgorithmId() == EDSA) + { + // DSA signatures are always 40 bytes (320 bits) + signature_length = KDSASignatureLength; + } + else + { + // RSA signature is the same length as public key. + TPtrC8 public_key_data = public_key.KeyData(); + + // public_key_data actually has the asn.1 header so it is a few bytes longer + // than the actual signature. + signature_length = public_key_data.Size(); + } + + TRAP(err, m_cert_if->SignL(m_own_certificate_info.iSubjectKeyId, hash, signature_length)); + if (err != KErrNone) + { + status = m_am_tools->convert_am_error_to_eapol_error(err); + } + else + { + status = eap_status_pending_request; + } + + delete buf; + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + +} +//-------------------------------------------------- +void eap_am_type_tls_peap_symbian_c::complete_sign( + const RInteger& aR, const RInteger& aS, eap_status_e aStatus) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if(aStatus != eap_status_ok) + { + get_tls_am_partner()->complete_sign_with_private_key(0, aStatus); + return; + } + + TRAPD(err, complete_signL(aR, aS, eap_status_ok)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: complete_signL leaved.\n"))); + get_tls_am_partner()->complete_sign_with_private_key(0, m_am_tools->convert_am_error_to_eapol_error(err)); + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +void eap_am_type_tls_peap_symbian_c::complete_signL( + const RInteger& aR, const RInteger& aS, eap_status_e aStatus) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if(aStatus != eap_status_ok) + { + get_tls_am_partner()->complete_sign_with_private_key(0, aStatus); + return; + } + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AM: Signing completed.\n"))); + + eap_variable_data_c signed_message_hash(m_am_tools); + eap_status_e status(eap_status_process_general_error); + + if (EapTlsPeapUtils::CipherSuiteUseDSAKeys(m_cipher_suite)) + { + CASN1EncSequence* sequence = CASN1EncSequence::NewLC(); + CASN1EncBigInt* enc_r = CASN1EncBigInt::NewLC(aR); + CASN1EncBigInt* enc_s = CASN1EncBigInt::NewLC(aS); + sequence->AddChildL(enc_r); + sequence->AddChildL(enc_s); + + HBufC8* buf = HBufC8::NewLC(sequence->LengthDER()); + TPtr8 tmp = buf->Des(); + + tmp.SetLength(sequence->LengthDER()); + TInt pos = 0; + sequence->WriteDERL(tmp, (TUint&) pos); + + status = signed_message_hash.set_copy_of_buffer(tmp.Ptr(), tmp.Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; + } + + CleanupStack::PopAndDestroy(); // buf + CleanupStack::Pop(2); // BigInts are deleted by the sequence + CleanupStack::PopAndDestroy(1); // Sequence + } + else if (EapTlsPeapUtils::CipherSuiteUseRSAKeys(m_cipher_suite)) + { + HBufC8* buf = aS.BufferLC(); + + // RSA signing. Just use the data as it is. + eap_status_e status = signed_message_hash.set_copy_of_buffer(buf->Ptr(), buf->Length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNoMemory); + } + CleanupStack::PopAndDestroy(); // buf + } + else + { + EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Unsupported cipher suite.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrNotSupported); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: sign_with_private_key() signed_message_hash"), + signed_message_hash.get_data(signed_message_hash.get_data_length()), + signed_message_hash.get_data_length())); + + status = get_tls_am_partner()->complete_sign_with_private_key( + &signed_message_hash, + eap_status_ok); + + // Ignore return value on purpose + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::verify_with_public_key( + const eap_variable_data_c * const message_hash, + const eap_variable_data_c * const signed_message_hash) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: %s: message_function: verify_with_public_key()\n"), + (m_is_client == true ? "client": "server"))); + + if (m_peer_public_key.get_is_valid_data() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: verify_with_public_key() m_peer_public_key"), + m_peer_public_key.get_data(m_peer_public_key.get_data_length()), + m_peer_public_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: verify_with_public_key() message_hash"), + message_hash->get_data(message_hash->get_data_length()), + message_hash->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("TLS: verify_with_public_key() signed_message_hash"), + signed_message_hash->get_data(signed_message_hash->get_data_length()), + signed_message_hash->get_data_length())); + + eap_status_e status = eap_status_process_general_error; + + if (EapTlsPeapUtils::CipherSuiteUseDSAKeys(m_cipher_suite)) + { + TRAPD(err, read_dsa_parametersL()); + if (err != KErrNone) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_am_tools->convert_am_error_to_eapol_error(err)); + } + crypto_dsa_c dsa(m_am_tools); + + status = dsa.init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = dsa.verify( + &m_peer_public_key, + &m_param_p, + &m_param_q, + &m_param_g, + message_hash, + signed_message_hash); + } + else if (EapTlsPeapUtils::CipherSuiteUseRSAKeys(m_cipher_suite)) + { + crypto_rsa_c rsa(m_am_tools); + + status = rsa.init(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rsa.verify( + &m_peer_public_key, + message_hash, + signed_message_hash); + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Signing with private key failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); + } + + status = get_tls_am_partner()->complete_verify_with_public_key(status); + + if (status == eap_status_ok + || status == eap_status_pending_request) + { + status = eap_status_completed_request; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +void eap_am_type_tls_peap_symbian_c::read_dsa_parametersL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + if (m_peer_certificate == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + User::Leave(KErrArgument); + } + // Peer cert is the first one + const CSubjectPublicKeyInfo& key = m_peer_certificate->PublicKey(); + const TPtrC8 params = key.EncodedParams(); + + CDSAParameters* dsaParams = CX509DSAPublicKey::DSAParametersL(params); + + CleanupStack::PushL(dsaParams); + + RInteger P = RInteger::NewL(dsaParams->P()); + CleanupStack::PushL(P); + RInteger Q = RInteger::NewL(dsaParams->Q()); + CleanupStack::PushL(Q); + RInteger G = RInteger::NewL(dsaParams->G()); + CleanupStack::PushL(G); + + HBufC8* buf = P.BufferLC(); + + // Copy the shared key + m_param_p.reset(); + eap_status_e status = m_param_p.set_copy_of_buffer(buf->Des().Ptr(), buf->Length()); + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + + buf = Q.BufferLC(); + m_param_q.reset(); + status = m_param_q.set_copy_of_buffer(buf->Des().Ptr(), buf->Length()); + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + + buf = G.BufferLC(); + m_param_g.reset(); + status = m_param_g.set_copy_of_buffer(buf->Des().Ptr(), buf->Length()); + if (status != eap_status_ok) + { + User::Leave(KErrNoMemory); + } + + CleanupStack::PopAndDestroy(7); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- +// MODULE HANDLING FUNCTIONS +//-------------------------------------------------- +eap_status_e eap_am_type_tls_peap_symbian_c::load_module( + const eap_type_value_e /*type*/, + const eap_type_value_e /* tunneling_type */, + abs_eap_base_type_c * const /*partner*/, + eap_base_type_c ** const /*eap_type_if*/, + const bool /*is_client_when_true*/, + const eap_am_network_id_c * const /*receive_network_id*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_tls_peap_symbian_c::check_is_valid_eap_type(const eap_type_value_e eap_type) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + eap_status_e status(eap_status_illegal_eap_type); + +#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::check_is_valid_eap_type:Given EAP vendor ID=%x, type=%x\n"), + eap_type.get_vendor_id(), eap_type.get_vendor_type())); + + for (TInt i = 0; i < m_enabled_tunneling_exp_eap_array.Count(); i++) + { + eap_expanded_type_c expEAPTmp; + + // This will read the expanded EAP from enabledEAPTypes[i]->iExpandedEAPType to expEAPTmp. + // This makes easy to get the vendor type. + eap_expanded_type_c::read_type( m_am_tools, + 0, + m_enabled_tunneling_exp_eap_array[i]->iExpandedEAPType.Ptr(), + KExpandedEAPTypeSize, + &expEAPTmp); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("check_is_valid_eap_type:Checking with EAP type:"), + m_enabled_tunneling_exp_eap_array[i]->iExpandedEAPType.Ptr(), + m_enabled_tunneling_exp_eap_array[i]->iExpandedEAPType.Size())); + + if (eap_type == expEAPTmp) + { + // This EAp type is one among the enabled ones. Hence a valid EAP type. + status = eap_status_ok; + break; + } + } + +#else // For normal EAP types. + + TEap *eapType = 0; + + TInt i(0); + + for (i = 0; i < m_iap_eap_array.Count(); i++) + { + // Try next EAP type + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + // Convert the string to integer + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + if (val == eap_type) + { + // Allowed + status = eap_status_ok; + break; + } + } + } + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::get_eap_type_list( + eap_array_c * const eap_type_list) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::get_eap_type_list - Start\n"))); + + eap_status_e status(eap_status_illegal_eap_type); + +#ifdef USE_EAP_EXPANDED_TYPES + + // We need to return only the EAP types available as enabled types. + // It means only the ones available in m_enabled_tunneling_exp_eap_array. + + for (TInt i = 0; i < m_enabled_tunneling_exp_eap_array.Count(); i++) + { + TBuf8 tmpExpEAP(m_enabled_tunneling_exp_eap_array[i]->iExpandedEAPType); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::get_eap_type_list:Enabled expanded EAP type at index=%d\n"), + i)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Enabled expanded EAP type:"), + tmpExpEAP.Ptr(), + tmpExpEAP.Size())); + + // This is for one expanded EAP type (for the above one). + eap_type_value_e * expandedEAPType = new eap_type_value_e(); + + // Read the expanded EAP type details from an item in m_enabled_tunneling_exp_eap_array. + status = eap_type_value_e::read_type(m_am_tools, + 0, + &tmpExpEAP, + tmpExpEAP.Length(), + expandedEAPType); + if (status != eap_status_ok) + { + delete expandedEAPType; + expandedEAPType = 0; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Add EAP-type to list. + status = eap_type_list->add_object(expandedEAPType, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_header_string_c eap_string; + EAP_UNREFERENCED_PARAMETER(eap_string); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("get_eap_type_list():added EAP-type=0x%08x=%s\n"), + expandedEAPType->get_vendor_type(), + eap_string.get_eap_type_string(*expandedEAPType))); + + }// for() + +#else // for normal EAP types. + + TEap *eapType = 0; + + status = eap_type_list->reset(); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + + for (TInt i = 0; i < m_iap_eap_array.Count(); i++) + { + // Check if type is enabled + eapType = m_iap_eap_array[i]; + if (eapType->Enabled == 1) + { + TLex8 tmp(eapType->UID); + TInt val(0); + tmp.Val(val); + + eap_type_value_e * const eap_type = new eap_type_value_e(static_cast(val)); + if (eap_type == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = eap_type_list->add_object(eap_type, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } // for() + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +eap_status_e eap_am_type_tls_peap_symbian_c::unload_module(const eap_type_value_e /*type*/) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + + +void eap_am_type_tls_peap_symbian_c::send_error_notification(const eap_status_e error) +{ + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::send_error_notification, error=%d\n"), + error)); + + eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error); + + if (error == eap_status_user_cancel_authentication) + { + general_state_variable = eap_general_state_authentication_cancelled; + } + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + m_receive_network_id.get_destination_id(), + m_receive_network_id.get_source_id(), + m_receive_network_id.get_type()); + + // Notifies the lower level of an authentication error. + eap_state_notification_c notification( + m_am_tools, + &send_network_id, + m_is_client, + eap_state_notification_eap, + eap_protocol_layer_general, + m_current_eap_type, + eap_state_none, + general_state_variable, + 0, + false); + + notification.set_authentication_error(error); + + m_partner->state_notification(¬ification); +} + +eap_status_e eap_am_type_tls_peap_symbian_c::show_certificate_selection_dialog() +{ + return eap_status_ok; +} + +eap_status_e eap_am_type_tls_peap_symbian_c::show_manual_identity_dialog() +{ + return eap_status_ok; +} + +//-------------------------------------------------- +// CANCELLATION FUNCTIONS +//-------------------------------------------------- +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_identity_query() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_identity_query()\n"))); + + m_cert_if->Cancel(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return eap_status_ok; +} + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_query_cipher_suites_and_previous_session() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_query_cipher_suites_and_previous_session()\n"))); + + // This is synchronous + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_select_cipher_suite_and_check_session_id() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_select_cipher_suite_and_check_session_id()\n"))); + + // This is synchronous + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_verify_certificate_chain() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_verify_certificate_chain()\n"))); + + m_cert_if->Cancel(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_query_certificate_chain() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_query_certificate_chain()\n"))); + + m_cert_if->Cancel(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_query_certificate_authorities_and_types() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_query_certificate_authorities_and_types()\n"))); + + // This is synchronous + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_query_dh_parameters() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_query_dh_parameters()\n"))); + + // This is synchronous + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_query_dsa_parameters() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_query_dsa_parameters()\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_query_realm() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_query_realm()\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_rsa_encrypt_with_public_key() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_rsa_encrypt_with_public_key()\n"))); + + // This is synchronous + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_rsa_decrypt_with_private_key() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_rsa_decrypt_with_private_key()\n"))); + + m_cert_if->Cancel(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_sign_with_private_key() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_sign_with_private_key()\n"))); + + m_cert_if->CancelSignWithPrivateKey(); // Lets see if separate cancelling works. + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_sign_with_private_key() returns\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_verify_with_public_key() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::cancel_verify_with_public_key()\n"))); + + // This is synchronous + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + +bool eap_am_type_tls_peap_symbian_c::is_session_valid() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + bool sessionValidity(false); + + TRAPD(err, sessionValidity = is_session_validL()); + if (err != KErrNone) + { + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::is_session_valid - LEAVE - error=%d, Assuming session is invalid \n"), + err)); + + sessionValidity = false; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return sessionValidity; +} + +//-------------------------------------------------- + +bool eap_am_type_tls_peap_symbian_c::is_session_validL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("eap_am_type_tls_peap_symbian_c::is_session_valid - m_current_eap_vendor_type=%d \n"), + m_current_eap_vendor_type)); + + TPtrC maxSessionTimeString; + TPtrC lastFullAuthTimeString; + + switch (m_current_eap_vendor_type) + { + case eap_type_tls: + { + maxSessionTimeString.Set(cf_str_EAP_TLS_max_session_validity_time_literal); + lastFullAuthTimeString.Set(KTLSLastFullAuthTime); + } + break; + + case eap_type_peap: + { + maxSessionTimeString.Set(cf_str_EAP_PEAP_max_session_validity_time_literal); + lastFullAuthTimeString.Set(KPEAPLastFullAuthTime); + } + break; + + case eap_type_ttls: + { + maxSessionTimeString.Set(cf_str_EAP_TTLS_max_session_validity_time_literal); + lastFullAuthTimeString.Set(KTTLSLastFullAuthTime); + } + break; + +#if defined(USE_FAST_EAP_TYPE) + case eap_type_fast: + { + maxSessionTimeString.Set(cf_str_EAP_FAST_max_session_validity_time_literal); + lastFullAuthTimeString.Set(KFASTLastFullAuthTime); + } + break; +#endif + + case eap_type_ttls_plain_pap: + { + // we should not come here, ttls pap has its own + // method for checking session validity + EAP_TRACE_ERROR( m_am_tools, TRACE_FLAGS_DEFAULT, ( + EAPL( "ERROR: wrong eap type.\n" ) ) ); + return false; + } + + default: + { + // Should never happen + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("Unsupported EAP type, m_current_eap_vendor_type=%d \n"), + m_current_eap_vendor_type)); + + return false; // Treat this as Session invalid. + } + } + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT(KSQLQuery, "SELECT %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &maxSessionTimeString, &lastFullAuthTimeString, &m_db_table_name, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + TInt64 maxSessionTime = view.ColInt64(colSet->ColNo(maxSessionTimeString)); + TInt64 fullAuthTime = view.ColInt64(colSet->ColNo(lastFullAuthTimeString)); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + CleanupStack::PopAndDestroy(&view); // Close view. + CleanupStack::PopAndDestroy(buf); // Delete buf. + + // If the max session time from DB is zero then we use the + // one read from configuration file. + + if( maxSessionTime == 0) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("Session Validity - Using max session validity time from config file\n"))); + + maxSessionTime = m_max_session_time; // value from configuration file. + } + + // Get the current time. + TTime currentTime; + currentTime.UniversalTime(); + + TTime lastFullAuthTime(fullAuthTime); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + TDateTime fullAuthDateTime = lastFullAuthTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("Session Validity - Current Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1, currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("Session Validity - Last Full Auth Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + fullAuthDateTime.Day()+1, fullAuthDateTime.Month()+1, fullAuthDateTime.Year(), fullAuthDateTime.Hour(), + fullAuthDateTime.Minute(), fullAuthDateTime.Second(), fullAuthDateTime.MicroSecond())); + +#endif + + TTimeIntervalMicroSeconds interval = currentTime.MicroSecondsFrom(lastFullAuthTime); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_tls_peap_symbian_c::is_session_valid:interval in microseconds:"), + &(interval.Int64()), + sizeof(interval.Int64()) ) ); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_tls_peap_symbian_c::is_session_valid:max session time in microseconds:"), + &(maxSessionTime), + sizeof(maxSessionTime) ) ); + +#if defined(_DEBUG) || defined(DEBUG) + + TTimeIntervalMinutes intervalMins; + TInt error = currentTime.MinutesFrom(lastFullAuthTime, intervalMins); + + if(error == KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::is_session_validL()") + EAPL("interval in Minutes =%d\n"), + intervalMins.Int())); + } + +#endif + + if( maxSessionTime >= interval.Int64() ) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_tls_peap_symbian_c::is_session_valid - Session Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return true; + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_tls_peap_symbian_c::is_session_valid - Session NOT Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + return false; + } +} + +//-------------------------------------------------- + +void eap_am_type_tls_peap_symbian_c::store_authentication_timeL() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::store_authentication_timeL, index type=%d, index=%d, tunneling type=%d, current eap type=%d\n"), + m_index_type, m_index, m_tunneling_vendor_type, m_current_eap_vendor_type)); + + TPtrC lastFullAuthTimeString; + + switch (m_current_eap_vendor_type) + { + case eap_type_tls: + { + lastFullAuthTimeString.Set(KTLSLastFullAuthTime); + } + break; + + case eap_type_peap: + { + lastFullAuthTimeString.Set(KPEAPLastFullAuthTime); + } + break; + + case eap_type_ttls: + { + lastFullAuthTimeString.Set(KTTLSLastFullAuthTime); + } + break; + + case eap_type_ttls_plain_pap: + { + lastFullAuthTimeString.Set( KTTLSPAPLastFullAuthTime ); + } + break; + +#if defined(USE_FAST_EAP_TYPE) + case eap_type_fast: + { + lastFullAuthTimeString.Set(KFASTLastFullAuthTime); + } + break; +#endif + + default: + { + // Should never happen + EAP_TRACE_ERROR(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("Unsupported EAP type, m_current_eap_vendor_type=%d \n"), + m_current_eap_vendor_type)); + + User::Leave(KErrNotSupported); + } + } + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT(KSQLQuery, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + sqlStatement.Format(KSQLQuery, &lastFullAuthTimeString, &m_db_table_name, + &KServiceType, m_index_type, + &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type); + + RDbView view; + // Evaluate view + User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row for updation. + view.FirstL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the current universal time. + TTime currentTime; + currentTime.UniversalTime(); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::store_authentication_time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1,currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + +#endif + + TInt64 fullAuthTime = currentTime.Int64(); + + view.SetColL(colSet->ColNo(lastFullAuthTimeString), fullAuthTime); + + view.PutL(); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + CleanupStack::PopAndDestroy(&view); // Close view. + CleanupStack::PopAndDestroy(buf); // Delete buf. + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_tls_peap_symbian_c::store_authentication_timeL - End \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_type_tls_peap_symbian_c::set_peap_version( + const peap_version_e /* peap_version */, + const bool /* use_tppd_tls_peap */, + const bool /* use_tppd_peapv1_acknowledge_hack */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +#if defined(USE_FAST_EAP_TYPE) + +//-------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::read_authority_identity(eap_variable_data_c * const /* authority_identity */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: %s: crypto_function: eap_am_type_tls_peap_symbian_c::read_authority_identity(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// This is commented in tls_am_application_eap_fast_c::query_pac_of_type(). +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::query_pac_of_type( + const eap_fast_pac_type_e /* pac_type */) + +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: %s: crypto_function: eap_am_type_tls_peap_symbian_c::query_pac_of_type(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +#if defined(USE_EAP_CORE_SERVER) +/** + * This function call is always asyncronous. + * It will be completed always with complete_verify_pac() function call. + * Function verifies the received PAC is valid. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::verify_pac(const eap_fast_variable_data_c * const /* tlv_pac */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: %s: crypto_function: eap_am_type_tls_peap_symbian_c::verify_pac(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +#endif //#if defined(USE_EAP_CORE_SERVER) +//-------------------------------------------------- + + +// This is commented in eap_am_fast_pac_store_services_c::query_user_permission_for_A_ID(). +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::query_user_permission_for_A_ID( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + const eap_fast_variable_data_c * const in_pac_attribute_A_ID_info, + const eap_fast_variable_data_c * const in_pac_attribute_A_ID) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: %s: eap_am_type_tls_peap_symbian_c::query_user_permission_for_A_ID(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + eap_status_e status(eap_status_ok); + + m_pending_operation = in_pending_operation; + + if (in_pac_attribute_A_ID_info->get_data_length()>0) + { + TRAPD(err, status = QueryUserPermissionForAIDL(in_pac_attribute_A_ID_info, in_pac_attribute_A_ID )); + if (err != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::read_PAC_store_data() ERROR: LEAVE from QueryUserPermissionForAIDL error=%d"), + err)); + + m_eap_fast_completion_status = m_am_tools->convert_am_error_to_eapol_error(err); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + } + } + if (status == KErrNone) + { + m_eap_fast_completion_status = eap_status_pending_request; + } + else + { + m_eap_fast_completion_status = status; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_tls_peap_symbian_c::QueryUserPermissionForAIDL( + const eap_fast_variable_data_c * const in_pac_attribute_A_ID_info, + const eap_fast_variable_data_c * const in_pac_attribute_A_ID) + { + eap_status_e status(eap_status_ok); + + HBufC8* A_ID_info8 = HBufC8::NewLC((in_pac_attribute_A_ID_info->get_data_length())); + TPtr8 A_ID_infoPtr8 = A_ID_info8->Des(); + + HBufC* A_ID_info = HBufC::NewLC((in_pac_attribute_A_ID_info->get_data_length())); + TPtr A_ID_infoPtr = A_ID_info->Des(); + + HBufC8* A_ID = HBufC8::NewLC((in_pac_attribute_A_ID->get_data_length())); + TPtr8 A_IDPtr = A_ID->Des(); + + A_ID_infoPtr8.Copy(in_pac_attribute_A_ID_info->get_data(in_pac_attribute_A_ID_info->get_data_length()),in_pac_attribute_A_ID_info->get_data_length() ); + A_ID_infoPtr.Copy(A_ID_infoPtr8); + + A_IDPtr.Copy(in_pac_attribute_A_ID->get_data(in_pac_attribute_A_ID->get_data_length()),in_pac_attribute_A_ID->get_data_length() ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_tls_peap_symbian_c::query_user_permission_for_A_ID(): in_pac_attribute_A_ID_info", + (A_ID_infoPtr.Ptr()), + (in_pac_attribute_A_ID_info->get_data_length()))); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_tls_peap_symbian_c::query_user_permission_for_A_ID(): in_pac_attribute_A_ID", + (A_IDPtr.Ptr()), + (in_pac_attribute_A_ID->get_data_length()))); + + if (A_ID_infoPtr.Size()>KMaxEapFastNotifierBufLength) + { + CleanupStack::PopAndDestroy(3); // A_ID, A_ID_info + status = m_am_tools->convert_am_error_to_eapol_error(KErrArgument); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + } + + TBool startedOk = ETrue; + + if (!iEapFastActiveNotes) + { + TRAPD( err, iEapFastActiveNotes = CEapFastActive::NewL( this ) ); + + if ( err != KErrNone ) + { + status = eap_status_allocation_error; + } + } + if ( status == KErrNone ) + { + //update buffer + iEapFastActiveNotes->UpdateInputBuf( A_ID_infoPtr ); + // start query install dialog + // asynch. call, return immediately + startedOk = iEapFastActiveNotes->Start( + CEapFastActive::EEapFastActiveInstallPacQueryDialog ); + if ( startedOk == EFalse ) + { + status = eap_status_process_general_error; + } + } + else + { + status = eap_status_process_general_error; + } + + CleanupStack::PopAndDestroy(3); // A_ID, A_ID_info + + return status; + } + + +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::read_PAC_store_data( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_eap_fast_pac_store_pending_operation = in_pending_operation; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::read_PAC_store_data()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_am_type_tls_peap_symbian_c::read_PAC_store_data()"); + + m_eap_fast_completion_status = eap_status_ok; + m_both_asked = 0; + m_both_completed = 0; + + TRAPD(error, ReadPACStoredataL(in_pending_operation, in_references)); + if(error != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::read_PAC_store_data() ERROR: LEAVE from ReadPACStoredataL error=%d"), + error)); + + m_eap_fast_completion_status = m_am_tools->convert_am_error_to_eapol_error(error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + // Proceed with normal complete case. + + if(m_eap_fast_completion_status == eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::complete_read_PAC_store_data(), m_eap_fast_completion_status=%d\n"), + (m_is_client == true ? "client": "server"), m_eap_fast_completion_status)); + + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); // m_ready_references_and_data_blocks + } + else if (m_eap_fast_completion_status == eap_status_pending_request ) + { + + m_ready_references_and_data_blocks.reset(); + m_new_references_and_data_blocks.reset(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::read_PAC_store_data() ERROR =%d"), + m_eap_fast_completion_status)); + + m_references_and_data_blocks.reset(); + + m_eap_fast_completion_status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + // ERROR. + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::read_PAC_store_data-End, m_eap_fast_completion_status=%d"), + m_eap_fast_completion_status)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); +} + +//-------------------------------------------------- + +void eap_am_type_tls_peap_symbian_c::ReadPACStoredataL( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::ReadPACStoredataL() Start \n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_am_type_tls_peap_symbian_c::ReadPACStoredataL()"); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + m_eap_fast_completion_status = eap_status_ok; + + m_eap_fast_pac_store_pending_operation = in_pending_operation; + + (void) m_references_and_data_blocks.reset(); + + + for (u32_t ind = 0ul; ind < in_references->get_object_count(); ++ind) + { + const eap_fast_pac_store_data_c * const data_reference = in_references->get_object(ind); + + if (data_reference != 0 + && data_reference->get_is_valid() == true) + { + eap_pac_store_data_type_e pacStoreDataRefType = data_reference->get_type(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ReadPACStoredataL(): data_reference type=%d=%s\n"), + pacStoreDataRefType, + eap_fast_tlv_header_string_c::get_fast_pac_store_data_string(pacStoreDataRefType))); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("ReadPACStoredataL(): data_reference reference:", + data_reference->get_reference()->get_data(data_reference->get_reference()->get_data_length()), + data_reference->get_reference()->get_data_length())); + + switch(pacStoreDataRefType) + { + case eap_pac_store_data_type_PAC_store_master_key: + { + // To read master key. + + eap_variable_data_c master_key(m_am_tools); + +#ifdef USE_PAC_STORE + // Get master key from PAC store DB. + GetPacStoreDbDataL( + pacStoreDataRefType, + &master_key); + +#endif // End: #ifdef USE_PAC_STORE + + // master_key should have the master key now. + // Doesn't matter even if there is no master key (master_key is empty). + // Proceed as normal case. + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + new_data->set_type(pacStoreDataRefType); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(data_reference->get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(&master_key); + + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_pac_store_data_type_PAC_store_master_key - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + break; + + } // End: case eap_pac_store_data_type_PAC_store_master_key: + + case eap_pac_store_data_type_reference_counter: + { + // To read reference counter. + + eap_variable_data_c reference_counter(m_am_tools); + +#ifdef USE_PAC_STORE + // Get reference counter from PAC store DB. + GetPacStoreDbDataL( + pacStoreDataRefType, + &reference_counter); + +#endif // End: #ifdef USE_PAC_STORE + + // reference_counter should have the reference counter now. + // Doesn't matter even if it is empty. Proceed as normal case. + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + new_data->set_type(pacStoreDataRefType); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(data_reference->get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(&reference_counter); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_pac_store_data_type_reference_counter - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + break; + + } // End: case eap_pac_store_data_type_reference_counter: + + case eap_pac_store_data_type_group_data: // Check the reference (the ref is data_reference->get_reference()) and provide only the value from groups table. + { + // To read a particular group data. + + eap_variable_data_c group_data(m_am_tools); + +#ifdef USE_PAC_STORE + // Get group data from PAC store DB, using the reference. + GetPacStoreDbDataL( + pacStoreDataRefType, + &group_data, + data_reference->get_reference()); + +#endif // End: #ifdef USE_PAC_STORE + + // group_data should have the value stored in PAC store now. + // Doesn't matter even if it is empty. Proceed as normal case. + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + new_data->set_type(pacStoreDataRefType); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(data_reference->get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(&group_data); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_pac_store_data_type_group_data - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + break; + + } // End: case eap_pac_store_data_type_group_data: + + case eap_pac_store_data_type_A_ID_data: // Check the reference and provide only the value from AIDs table. + { + // To read a particular AID data. + + eap_variable_data_c aid_data(m_am_tools); + +#ifdef USE_PAC_STORE + // Get AID data from PAC store DB, using the reference. + GetPacStoreDbDataL( + pacStoreDataRefType, + &aid_data, + data_reference->get_reference()); + +#endif // End: #ifdef USE_PAC_STORE + + // aid_data should have the value stored in PAC store now. + // Doesn't matter even if it is empty. Proceed as normal case. + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + new_data->set_type(pacStoreDataRefType); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(data_reference->get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(&aid_data); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_pac_store_data_type_A_ID_data - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + break; + + } // End: case eap_pac_store_data_type_A_ID_data: + + case eap_pac_store_data_type_PAC_data: // Check the reference and provide only the value from PACs table. + { + // To read a particular PAC data. + + eap_variable_data_c pac_data(m_am_tools); + +#ifdef USE_PAC_STORE + // Get PAC data from PAC store DB, using the reference. + GetPacStoreDbDataL( + pacStoreDataRefType, + &pac_data, + data_reference->get_reference()); + +#endif // End: #ifdef USE_PAC_STORE + + // pac_data should have the value stored in PAC store now. + // Doesn't matter even if it is empty. Proceed as normal case. + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + new_data->set_type(pacStoreDataRefType); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(data_reference->get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(&pac_data); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_pac_store_data_type_PAC_data - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + break; + + } // End: case eap_pac_store_data_type_PAC_data: + + case eap_pac_store_data_type_group_info:// Provide all from groups table. Create data for one entry in the groups table. + case eap_pac_store_data_type_A_ID_info: // Provide all from AIDs table. Create data for one entry in the AIDs table. + case eap_pac_store_data_type_PAC_info:// Provide all from PACs table. Create data for one entry in the PACs table. + { + /** Read the items from DB here.*/ + TBuf<64> dbTableName; + eap_pac_store_data_type_e dataType = eap_pac_store_data_type_none; + + switch(pacStoreDataRefType) + { + case eap_pac_store_data_type_group_info: + { + dbTableName = KPacStoreGroupsTableName; + dataType = eap_pac_store_data_type_group_data; + break; + } + case eap_pac_store_data_type_A_ID_info: + { + dbTableName = KPacStoreAIDsTableName; + dataType = eap_pac_store_data_type_A_ID_data; + break; + } + case eap_pac_store_data_type_PAC_info: + { + dbTableName = KPacStorePACsTableName; + dataType = eap_pac_store_data_type_PAC_data; + break; + } + } + + TInt count = 0; + + m_info_array.Reset(); + + iPacStoreDb->GetPacStoreDataL(dbTableName, m_info_array); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ReadPACStoredataL:Number of entries in table %S=%d\n"), + &dbTableName, m_info_array.Count())); + + while (count < m_info_array.Count()) + { + TPtr8 infoDataPtr = m_info_array[count].iData->Des(); + TPtr8 infoRefPtr = m_info_array[count].iReference->Des(); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_tls_peap_symbian_c::ReadPACStoredataL: BINARY value from PAC DB (reference)", + infoRefPtr.Ptr(), + infoRefPtr.Size())); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_tls_peap_symbian_c::ReadPACStoredataL: BINARY value from PAC DB (value)", + infoDataPtr.Ptr(), + infoDataPtr.Size())); + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + new_data->set_type(dataType); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(infoRefPtr.Ptr(), infoRefPtr.Size()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + delete m_info_array[count].iData; + delete m_info_array[count].iReference; + break; + } + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(infoDataPtr.Ptr(),infoDataPtr.Size() ); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + delete m_info_array[count].iData; + delete m_info_array[count].iReference; + break; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + delete m_info_array[count].iData; + delete m_info_array[count].iReference; + break; + } + + delete m_info_array[count].iData; + delete m_info_array[count].iReference; + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("For GROUP, AID, PAC INFOs - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + count++; + } // End: while + + + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + break; + } // End: case eap_pac_store_data_type_group_info: + + case eap_pac_store_data_type_PAC_store_password: + { + // To read PAC store PW. + +#ifdef USE_PAC_STORE + // Get PAC store password + + // First check if there is some PW in PAC store DB. + GetPacStoreDbDataL( + pacStoreDataRefType, + &m_PAC_store_password); + +#endif // End: #ifdef USE_PAC_STORE + + if(m_PAC_store_password.get_data_length() == 0) + { + // Nothing in the PAC store DB. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ReadPACStoredataL: NO PW in PAC store. Try Notifier"))); + + + // Show the password query notifier to get the password. + + m_ready_references_array_index = ind; + + m_verificationStatus = EFalse; + + m_state = EPasswordQuery; + + m_pacStoreDataRefType = pacStoreDataRefType; + + m_data_reference.get_writable_reference()->set_copy_of_buffer(data_reference->get_reference()); + + m_both_asked++; + + if(iPacStoreDb->IsMasterKeyPresentL()) + { + m_eap_fast_completion_status = ShowNotifierItemAndGetResponse( + EEapFastNotifierPacStorePwQuery, ETrue ); + } + else + { + m_state = EMasterkeyQuery; + m_eap_fast_completion_status = ShowNotifierItemAndGetResponse( + EEapFastNotifierCreateMasterkeyQuery, ETrue ); + } + + break; + } + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + new_data->set_type(pacStoreDataRefType); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(data_reference->get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(&m_PAC_store_password); + + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_pac_store_data_type_PAC_store_password - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + m_eap_fast_completion_status = eap_status_pending_request; + + break; + + } // End: case eap_pac_store_data_type_PAC_store_password: + + case eap_pac_store_data_type_PAC_store_device_seed: + { + // To get the device seed. + + // Create a device seed. + + eap_variable_data_c m_PAC_store_device_seed(m_am_tools); + m_eap_fast_completion_status = m_PAC_store_device_seed.set_copy_of_buffer( + iPacStoreDb->GetSeed() ); + if ( m_eap_fast_completion_status != eap_status_ok ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ReadPACStoredataL: ERROR: seed data is not valid."))); + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + // continue normally + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("Device Seed", + m_PAC_store_device_seed.get_data(m_PAC_store_device_seed.get_data_length()), + m_PAC_store_device_seed.get_data_length())); + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + new_data->set_type(pacStoreDataRefType); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(data_reference->get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(&m_PAC_store_device_seed); + + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_pac_store_data_type_PAC_store_device_seed - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + break; + } // End: case eap_pac_store_data_type_PAC_store_device_seed: + + case eap_pac_store_data_type_PAC_store_IAP_reference: + { + // To get the IAP reference. + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + new_data->set_type(pacStoreDataRefType); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(data_reference->get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + // Provide Service table id (m_index) and type (m_index_type) + // in the specified format. + + i32_t tmpIndex = static_cast(m_index); + i32_t tmpIndexType = static_cast(m_index_type); + + eap_variable_data_c tmp_EAP_FAST_IAP_reference(m_am_tools); + + // Copy the index and index type. The order of copying is important. + + m_eap_fast_completion_status = tmp_EAP_FAST_IAP_reference.set_copy_of_buffer(&tmpIndex,sizeof(i32_t)); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + m_eap_fast_completion_status = tmp_EAP_FAST_IAP_reference.add_data(&tmpIndexType,sizeof(i32_t)); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + if (tmp_EAP_FAST_IAP_reference.get_is_valid_data() == true) + { + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(&tmp_EAP_FAST_IAP_reference); + + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_pac_store_data_type_PAC_store_IAP_reference - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + break; + + } // End : case eap_pac_store_data_type_PAC_store_IAP_reference: + + case eap_pac_store_data_type_PAC_store_group_reference: + { + // To get the PAC store group reference + // It is EAP_FAST_PAC_Group_DB_Reference_Collection in PAC store DB. + + eap_variable_data_c groupDbReferenceData(m_am_tools); + + EapTlsPeapUtils::GetEapSettingsDataL( + m_database, + m_index_type, + m_index, + m_tunneling_type, + m_current_eap_type, + KFASTPACGroupDBReferenceCollection, + &groupDbReferenceData); + + // groupDbReferenceData should have the value stored in PAC store DB. + // Doesn't matter even if it is empty. Proceed as normal case. + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("PAC group ref from PAC store DB", + groupDbReferenceData.get_data(groupDbReferenceData.get_data_length()), + groupDbReferenceData.get_data_length())); + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + new_data->set_type(pacStoreDataRefType); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(&groupDbReferenceData); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + eap_variable_data_c group_data_2(m_am_tools); + +#ifdef USE_PAC_STORE + // Get group data from PAC store DB, using the reference. + GetPacStoreDbDataL( + eap_pac_store_data_type_group_data, + &group_data_2, + &groupDbReferenceData); + +#endif // End: #ifdef USE_PAC_STORE + + if ( group_data_2.get_data_length() == 0 ) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(&group_data_2); + + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_pac_store_data_type_PAC_store_group_reference - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + break; + + } // End: case eap_pac_store_data_type_PAC_store_group_reference: + + case eap_pac_store_data_type_PAC_file_password: + { + // To get the password for decrypting the PAC file. + + // Show the notifier to get the PAC file password. + + m_ready_references_array_index = ind; + + m_pacStoreDataRefType = pacStoreDataRefType; + + m_data_reference.get_writable_reference()->set_copy_of_buffer(data_reference->get_reference()); + + m_state = EFilePasswordQuery; + + m_both_asked++; + + m_eap_fast_completion_status = ShowNotifierItemAndGetResponse( + EEapFastNotifierPacFilePwQuery, ETrue ); + + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + break; + + } // End : case eap_pac_store_data_type_PAC_file_password: + + default: + { + // Unknown data query. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ReadPACStoredataL: ERROR: Unknown data type"))); + + m_eap_fast_completion_status = eap_status_not_found; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + + } // End: switch(pacStoreDataRefType) + } + } // for () + if (m_both_asked) + m_eap_fast_completion_status = eap_status_pending_request; + m_info_array.Reset(); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ReadPACStoredataL-End, m_eap_fast_completion_status=%d"), + m_eap_fast_completion_status)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return; +} + + +//-------------------------------------------------- + +// This is commented in eap_am_fast_pac_store_services_c::write_PAC_store_data(). +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::write_PAC_store_data( + const bool /* when_true_must_be_synchronous_operation */, + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references_and_data_blocks) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: %s: eap_am_type_tls_peap_symbian_c::write_PAC_store_data(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + m_eap_fast_pac_store_pending_operation = in_pending_operation; + TRAPD(error, WritePACStoreDataL(in_pending_operation, in_references_and_data_blocks)); + + if(error != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::write_PAC_store_data() ERROR: LEAVE from WritePACStoreDataL error=%d"), + error)); + + m_eap_fast_completion_status = m_am_tools->convert_am_error_to_eapol_error(error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + // Proceed with normal complete case. + + eap_status_e status(eap_status_ok); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("FAST: %s: direct_complete_function: WritePACStoreDataL(), m_eap_fast_completion_status=%d\n"), + (m_is_client == true ? "client": "server"), m_eap_fast_completion_status)); + + if (m_eap_fast_completion_status == eap_status_ok) + { + status = m_tls_application->complete_write_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation); + } + else + { + status = m_tls_application->complete_write_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation); + + // ERROR. + (void) EAP_STATUS_RETURN(m_am_tools, status); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::write_PAC_store_data-End, status=%d, m_eap_fast_completion_status=%d"), + status, m_eap_fast_completion_status)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + + +//-------------------------------------------------- + +void eap_am_type_tls_peap_symbian_c::WritePACStoreDataL( + const eap_fast_pac_store_pending_operation_e in_pending_operation, + EAP_TEMPLATE_CONST eap_array_c * const in_references_and_data_blocks) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::WritePACStoreDataL()\n"))); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_am_type_tls_peap_symbian_c::WritePACStoreDataL()"); + + // - - - - - - - - - - - - - - - - - - - - - - - - + + m_eap_fast_completion_status = eap_status_ok; + + m_eap_fast_pac_store_pending_operation = in_pending_operation; + + TBuf pacStoreDBColName; + TBool writeToPacStore = EFalse; + + // - - - - - - - - - - - - - - - - - - - - - - - - + + for (u32_t ind = 0ul; ind < in_references_and_data_blocks->get_object_count(); ++ind) + { + const eap_fast_pac_store_data_c * const data_reference = in_references_and_data_blocks->get_object(ind); + if (data_reference != 0) + { + const eap_pac_store_data_type_e aPacStoreDataType = data_reference->get_type(); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::WritePACStoreDataL(): type %d=%s\n"), + data_reference->get_type(), + eap_fast_tlv_header_string_c::get_fast_pac_store_data_string(data_reference->get_type()))); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("WritePACStoreDataL(): data_reference data(value):", + data_reference->get_data()->get_data(data_reference->get_data()->get_data_length()), + data_reference->get_data()->get_data_length())); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("WritePACStoreDataL(): data_reference reference:", + data_reference->get_reference()->get_data(data_reference->get_reference()->get_data_length()), + data_reference->get_reference()->get_data_length())); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::WritePACStoreDataL: change status=%d (0=eap_pac_store_data_change_status_none)"), + data_reference->get_change_status())); + + if (data_reference != 0 + && data_reference->get_is_valid() == true + && data_reference->get_type() != eap_pac_store_data_type_none + && data_reference->get_change_status() != eap_pac_store_data_change_status_none) + { + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + break; + } + + + /* Get the data (or value) from the input */ + HBufC8* pacStoreDBColVal8 = HBufC8::NewLC(data_reference->get_data()->get_data_length()); + TPtr8 pacStoreDBColValPtr8 = pacStoreDBColVal8->Des(); + pacStoreDBColValPtr8.Copy(data_reference->get_data()->get_data(), + data_reference->get_data()->get_data_length()); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("write_PAC_store_dataL(): 8 bit VALUE from common:", + pacStoreDBColValPtr8.Ptr(), + pacStoreDBColValPtr8.Size())); + + /* Get the reference from the input */ + HBufC8* pacStoreDBColRef8 = HBufC8::NewLC(data_reference->get_reference()->get_data_length()); + TPtr8 pacStoreDBColRefPtr8 = pacStoreDBColRef8->Des(); + pacStoreDBColRefPtr8.Copy(data_reference->get_reference()->get_data(), + data_reference->get_reference()->get_data_length()); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("write_PAC_store_dataL(): 8 bit REFERENCE from common:", + pacStoreDBColRefPtr8.Ptr(), + pacStoreDBColRefPtr8.Size())); + + writeToPacStore = EFalse; + + TBool isNewEntry(EFalse); + if(data_reference->get_change_status() == eap_pac_store_data_change_status_new) + { + isNewEntry =ETrue; + } + else + { + isNewEntry =EFalse; + } + + switch(aPacStoreDataType) + { + case eap_pac_store_data_type_PAC_store_master_key: + { + pacStoreDBColName.Copy(KPacStoreMasterKey); + writeToPacStore = ETrue; + + // This can not be a new entry. Only modification possible for this. + // Some times common side provides this as new entry. + isNewEntry = EFalse; + + break; + } + case eap_pac_store_data_type_PAC_store_password: + { + //This is not saved anywhere. + break; + } + case eap_pac_store_data_type_PAC_store_device_seed: + { + //This is not saved anywhere. + break; + } + case eap_pac_store_data_type_PAC_store_IAP_reference: + { + //This is not saved anywhere. + break; + } + case eap_pac_store_data_type_PAC_store_group_reference: + { + // This should be saved in FAST special settings table in EAP DB, not in PAC store. + + EapTlsPeapUtils::SetEapSettingsDataL( + m_database, + m_index_type, + m_index, + m_tunneling_type, + m_current_eap_type, + KFASTPACGroupDBReferenceCollection, + data_reference->get_data()); + + writeToPacStore = EFalse; + + break; + } + case eap_pac_store_data_type_reference_counter: + { + pacStoreDBColName.Copy(KPacStoreReferenceCounter); + writeToPacStore = ETrue; + + // This can not be a new entry. Only modification possible for this. + // Some times common side provides this as new entry. + isNewEntry = EFalse; + + break; + } + case eap_pac_store_data_type_PAC_file_password: + { + //This is not saved anywhere. + break; + } + case eap_pac_store_data_type_group_info: + case eap_pac_store_data_type_A_ID_info: + case eap_pac_store_data_type_PAC_info: + { + //These are not saved, as such, anywhere. + break; + } + case eap_pac_store_data_type_group_data: + { + pacStoreDBColName.Copy(KPacStoreGroupValue); + writeToPacStore = ETrue; + break; + } + case eap_pac_store_data_type_A_ID_data: + { + pacStoreDBColName.Copy(KPacStoreAIDValue); + writeToPacStore = ETrue; + break; + } + case eap_pac_store_data_type_PAC_data: + { + pacStoreDBColName.Copy(KPacStorePACValue); + writeToPacStore = ETrue; + break; + } + default: + { + // Unknown data type. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::WritePACStoreDataL: ERROR: Unknown data type"))); + + m_eap_fast_completion_status = eap_status_not_found; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + break; + } + } // End : switch(aPacStoreDataType) + + if (writeToPacStore) + { + if(data_reference->get_change_status() == eap_pac_store_data_change_status_delete) + { + // We have to delete this entry from PAC store. + + iPacStoreDb->RemovePacStoreEntryL( + pacStoreDBColName, + pacStoreDBColValPtr8, + pacStoreDBColRefPtr8); + } + else + { + // Here the entry is either modified or a new entry. isNewEntry will have the correct value. + iPacStoreDb->SetPacStoreDataL( + pacStoreDBColName, + pacStoreDBColValPtr8, + pacStoreDBColRefPtr8, + isNewEntry); + } + + m_eap_fast_completion_status = eap_status_ok; + } + + if (m_eap_fast_completion_status != eap_status_ok) + { + break; + } + + CleanupStack::PopAndDestroy(2); // pacStoreDBColVal8 (pacStoreDBColValPtr8) and + // pacStoreDBColRef8 (pacStoreDBColRefPtr8). + + } + else if (data_reference != 0 + && data_reference->get_is_valid() == true + && data_reference->get_type() == eap_pac_store_data_type_none) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: illegal reference 0x%08x: type %d\n"), + data_reference, + data_reference->get_type())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: unknown reference"), + data_reference->get_reference()->get_data(), + data_reference->get_reference()->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: unknown data"), + data_reference->get_data()->get_data(), + data_reference->get_data()->get_data_length())); + } + } + } // for () + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::WritePACStoreDataL-End, m_eap_fast_completion_status=%d"), + m_eap_fast_completion_status)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); +} + +//-------------------------------------------------- + +// This is commented in eap_am_fast_pac_store_services_c::complete_add_imported_PAC_file(). +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::complete_add_imported_PAC_file( + const eap_status_e /* in_completion_status */, + const eap_variable_data_c * const in_imported_PAC_filename, + const eap_variable_data_c * const out_used_group_reference) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: %s: eap_am_type_tls_peap_symbian_c::complete_add_imported_PAC_file(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + m_eap_fast_completion_status = eap_status_ok; + + TRAPD(err, CompleteAddImportedPACFileL(in_imported_PAC_filename, out_used_group_reference)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::read_PAC_store_data() ERROR: LEAVE from CompleteAddImportedPACFfileL error=%d"), + err)); + + m_eap_fast_completion_status = m_am_tools->convert_am_error_to_eapol_error(err); + } + + m_eap_fast_completion_status = m_partner->set_timer( + this, + KImportFileTimerID, // if nothing in db & remove_IAP_reference called already with 0 -> import + 0, + 1); + + if (m_eap_fast_completion_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); +} + +void eap_am_type_tls_peap_symbian_c::CompleteAddImportedPACFileL( + const eap_variable_data_c * const in_imported_PAC_filename, + const eap_variable_data_c * const out_used_group_reference) + { + RFs aFs; + aFs.Connect( KFileServerDefaultMessageSlots ); + + HBufC8* buf = HBufC8::NewLC(in_imported_PAC_filename->get_data_length()); + TPtr8 bufPtr = buf->Des(); + + if (in_imported_PAC_filename->get_data_length() != 0) + { + bufPtr.Copy(in_imported_PAC_filename->get_data(), in_imported_PAC_filename->get_data_length()); + } + + eap_variable_data_c someVariableData(m_am_tools); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::complete_add_imported_PAC_file: Get ImportReference from database"))); + + EapTlsPeapUtils::GetEapSettingsDataL( + m_database, + m_index_type, + m_index, + m_tunneling_type, + m_current_eap_type, + KFASTPACGroupImportReferenceCollection, + &someVariableData); + + HBufC8* ref = HBufC8::NewLC(someVariableData.get_data_length()); // must be defined to correct maxs dir length + TPtr8 refPtr = ref->Des(); + if (someVariableData.get_data_length() != 0) + { + refPtr.Copy(someVariableData.get_data(),someVariableData.get_data_length()); + + HBufC8* tempUserBuf8 = HBufC8::NewLC(someVariableData.get_data_length()); + TPtr8 tempUserBufPtr8 = tempUserBuf8->Des(); + + for (int i = 0; i< someVariableData.get_data_length();i++ ) + { + tempUserBufPtr8.Append(refPtr.Ptr()[i++]); + } + refPtr.Copy(tempUserBufPtr8); + CleanupStack::PopAndDestroy(tempUserBuf8); + + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::complete_add_imported_PAC_file: NO ImportReference !!!!"))); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::complete_add_imported_PAC_file: Set GroupDBReference to database"))); + + if (out_used_group_reference->get_data_length()>0 && someVariableData.get_data_length()>0) + { + someVariableData.set_copy_of_buffer(out_used_group_reference->get_data(), + out_used_group_reference->get_data_length()); + + EapTlsPeapUtils::SetEapSettingsDataL( + m_database, + m_index_type, + m_index, + m_tunneling_type, + m_current_eap_type, + KFASTPACGroupDBReferenceCollection, + &someVariableData); + + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::complete_add_imported_PAC_file: NO GROUP REFERENCE !!!!"))); + + } + + HBufC* FilePath = HBufC::NewLC(KMaxFileName); // must be defined to correct maxs dir length + TPtr FilePathPtr = FilePath->Des(); + HBufC8* FilePath8 = HBufC8::NewLC(KMaxFileName); // must be defined to correct maxs dir length + TPtr8 FilePathPtr8 = FilePath8->Des(); + + _LIT8(KPacStoreSourceDir, "c:\\private\\101f8ec5\\PACGroup\\"); // in dir are dirs where from files are read + FilePathPtr8.Zero(); + FilePathPtr8.Append(KPacStoreSourceDir); + FilePathPtr8.Append(refPtr); + FilePathPtr8.Append(KSeparator); + FilePathPtr8.Append(bufPtr); + + FilePathPtr.Copy(FilePathPtr8); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::complete_add_imported_PAC_file: Delete File"), + FilePathPtr.Ptr(), + FilePathPtr.Size())); + + if(aFs.Delete(FilePathPtr)!= KErrNone) + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::complete_add_imported_PAC_file: Couldn't delete file"), + FilePathPtr.Ptr(), + FilePathPtr.Size())); + + + m_eap_fast_completion_status = eap_status_file_does_not_exist; + } + + CleanupStack::PopAndDestroy(FilePath8); + CleanupStack::PopAndDestroy(FilePath); + CleanupStack::PopAndDestroy(ref); + CleanupStack::PopAndDestroy(buf); + + } + + +// --------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::ContinueInitializePacStore() +// --------------------------------------------------------- +// +void eap_am_type_tls_peap_symbian_c::ContinueInitializePacStore() + + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ContinueInitializePacStore()"))); + + TRAPD(error, CheckPasswordTimeValidityL()); + + if(error != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::ContinueInitializePacStore() ERROR: LEAVE from CheckPasswordTimeValidityL() error=%d"), + error)); + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: %s: eap_am_type_tls_peap_symbian_c::ContinueInitializePacStore(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + m_eap_fast_completion_status = eap_status_ok; + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ContinueInitializePacStore: Remove removed IAP references"))); + + m_eap_fast_completion_status = m_partner->set_timer( + this, + KRemoveIAPReferenceTimerID, + 0, + 1); + + } + +//-------------------------------------------------- + +// This is commented in eap_am_fast_pac_store_services_c::complete_remove_PAC(). +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::complete_remove_PAC( + const eap_status_e /* completion_status */, + const eap_variable_data_c * const /* out_used_group_reference */) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: %s: crypto_function: eap_am_type_tls_peap_symbian_c::complete_remove_PAC(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); +} + +//-------------------------------------------------- + +// This is commented in eap_am_fast_pac_store_services_c::complete_remove_IAP_reference(). +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::complete_remove_IAP_reference( + const eap_status_e completion_status) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: %s: crypto_function: eap_am_type_tls_peap_symbian_c::complete_remove_IAP_reference(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + eap_variable_data_c aIapReference(m_am_tools); + if (aIapReference.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c aGroupReferenceCollection(m_am_tools); + if (aGroupReferenceCollection.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // delete previously removed entry + TRAPD(error, iPacStoreDb->RemoveTheFirstCleanupReferenceEntryL()); + + if(error != KErrNone) + { + EAP_UNREFERENCED_PARAMETER(completion_status); + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::complete_remove_IAP_reference() ERROR: LEAVE from RemoveTheFirstCleanupReferenceEntryL error=%d"), + error)); + + m_eap_fast_completion_status = m_am_tools->convert_am_error_to_eapol_error(error); + } + + TRAPD(error1, iPacStoreDb->GetTheFirstCleanupReferenceEntryL( + &aIapReference, + &aGroupReferenceCollection)); + + if(error1 != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::complete_remove_IAP_reference() ERROR: LEAVE from GetTheFirstCleanupReferenceEntryL error=%d"), + error1)); + + m_eap_fast_completion_status = m_am_tools->convert_am_error_to_eapol_error(error1); + } + + if ((aIapReference.get_data_length() > 0) && !m_completed_with_zero) + { + m_eap_fast_completion_status = m_partner->set_timer( + this, + KRemoveIAPReferenceTimerID, + 0, + 1); + + if (m_eap_fast_completion_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + } + } + else if (m_completed_with_zero) + { + m_eap_fast_completion_status = m_partner->set_timer( + this, + KImportFileTimerID, // if nothing in db & remove_IAP_reference called already with 0 -> import + 0, + 1); + + if (m_eap_fast_completion_status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + } + } + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); +} + +// This is commented in eap_am_fast_pac_store_services_c::cancel_PAC_store_operations(). +EAP_FUNC_EXPORT eap_status_e eap_am_type_tls_peap_symbian_c::cancel_PAC_store_operations() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: %s: crypto_function: eap_am_type_tls_peap_symbian_c::cancel_PAC_store_operations(): ") + EAPL("this = 0x%08x\n"), + (m_is_client == true ? "client": "server"), + this)); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_am_type_tls_peap_symbian_c::cancel_PAC_store_operations()"); + + if(iPacStoreDb) + iPacStoreDb->Cancel(); + + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//-------------------------------------------------- + + +EAP_FUNC_EXPORT eap_status_e +eap_am_type_tls_peap_symbian_c::initialize_PAC_store( + const eap_fast_completion_operation_e aCompletionOperation, + const eap_fast_initialize_pac_store_completion_e aCompletion ) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::initialize_PAC_store IN\n"))); + + iCompletionOperation = aCompletionOperation; + iCompletion = aCompletion; + + TRAPD( err, FixOldTableForPacStoreInitL() ); + if ( err != KErrNone ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "ERROR: eap_am_type_tls_peap_symbian_c::initialize_PAC_store() \ + Failed to fix table.\n" ) ) ); + } + + if ( iPacStoreDb ) + { + + TBool isInitialized = EFalse; + TRAP( err, isInitialized = iPacStoreDb->IsInitializedL() ); + if ( err == KErrNone ) + { + if ( !isInitialized ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::initialize_PAC_store(): PAC store initialized, erase memorystore"))); + m_tls_application->remove_cached_pac_store_data(); + TRAP( err, iPacStoreDb->SetPacStoreInitValueL( + CPacStoreDatabase::EPacStoreInitialized ) ); + if ( err != KErrNone ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::initialize_PAC_store(): ERROR: Leave in SetPacStoreInitValueL()"))); + } + } + // asynch. call, return immediately + iPacStoreDb->CreateDeviceSeedAsynch(); + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "ERROR: eap_am_type_tls_peap_symbian_c::initialize_PAC_store(): Leave, IsInitializedL(), err=%d.\n"), + err ) ); + + return m_am_tools->convert_am_error_to_eapol_error(err); + } + } + + m_eap_fast_completion_status = eap_status_pending_request; + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::initialize_PAC_store() OUT\n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); +} + +// --------------------------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::indicates_eap_fast_provisioning_starts +// --------------------------------------------------------------------------- +// +EAP_FUNC_EXPORT +eap_status_e eap_am_type_tls_peap_symbian_c::indicates_eap_fast_provisioning_starts( + const eap_fast_completion_operation_e provisioning_mode, + const eap_fast_pac_type_e pac_type ) + { + eap_status_e status( eap_status_ok ); + m_provisioning_mode = provisioning_mode; // save provis. mode + + TInt err = KErrNone; + if ( !iEapFastActiveWaitNote ) + { + TRAP( err, iEapFastActiveWaitNote = CEapFastActive::NewL( this ) ); + } + if ( !iEapFastActiveNotes ) + { + TRAP( err, iEapFastActiveNotes = CEapFastActive::NewL( this ) ); + } + if ( err != KErrNone ) + { + status = eap_status_allocation_error; + } + /** + * The note is started in a separate active object. + * When user cancels waiting note, + * SendErrorNotification( eap_status_user_cancel_authentication ) + * will be called in iEapFastActiveWaitNote->RunL(). + * Otherwise note is stopped using iEapFastActiveWaitNote.Start() method. + */ + TBool startedOk = ETrue; + + if ( pac_type == eap_fast_pac_type_tunnel_pac + && + provisioning_mode == + eap_fast_completion_operation_server_authenticated_provisioning_mode + && + status == eap_status_ok ) + { + EAP_TRACE_DEBUG_SYMBIAN( ( _L("eap_am_type_tls_peap_symbian_c:: \ + indicates_eap_fast_provisioning_starts Authenticated provisioning!"))); + startedOk = iEapFastActiveWaitNote->Start( + CEapFastActive::EEapFastActiveStartAuthProvWaitNote ); + } + else if ( + pac_type == eap_fast_pac_type_tunnel_pac + && + provisioning_mode == + eap_fast_completion_operation_server_unauthenticated_provisioning_mode_ADHP + && + status == eap_status_ok ) + { + EAP_TRACE_DEBUG_SYMBIAN( (_L("eap_am_type_tls_peap_symbian_c:: \ + indicates_eap_fast_provisioning_starts UnAuthenticated provisioning!"))); + startedOk = iEapFastActiveWaitNote->Start( + CEapFastActive::EEapFastActiveStartUnauthProvWaitNote ); + } + if ( startedOk == EFalse ) + { + status = eap_status_process_general_error; + } + if ( status != eap_status_ok ) + { + EAP_TRACE_DEBUG_SYMBIAN( (_L("eap_am_type_tls_peap_symbian_c:: \ + indicates_eap_fast_provisioning_starts ERROR: status=%d."), status ) ); + } + return status; + } + +// --------------------------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::indicates_eap_fast_provisioning_ends +// --------------------------------------------------------------------------- +// +EAP_FUNC_EXPORT +eap_status_e eap_am_type_tls_peap_symbian_c::indicates_eap_fast_provisioning_ends( + const bool provisioning_successfull, + const eap_fast_completion_operation_e provisioning_mode, + const eap_fast_pac_type_e pac_type ) + { + EAP_TRACE_DEBUG_SYMBIAN( (_L("eap_am_type_tls_peap_symbian_c:: \ + indicates_eap_fast_provisioning_ends()"))); + + EAP_UNREFERENCED_PARAMETER(provisioning_mode); + + eap_status_e status( eap_status_ok ); + + if ( pac_type == eap_fast_pac_type_tunnel_pac ) + { + // stop wait note; + if ( iEapFastActiveWaitNote ) + { + if ( iEapFastActiveWaitNote->IsActive() ) + { + iEapFastActiveWaitNote->Cancel(); + } + delete iEapFastActiveWaitNote; + iEapFastActiveWaitNote = NULL; + } + + if ( iEapFastActiveNotes ) + { + if( provisioning_successfull ) + { + // synch. call + iEapFastActiveNotes->Start( CEapFastActive:: + EEapFastActiveShowProvSuccessNote, ETrue ); + } + else + { + // synch. call + iEapFastActiveNotes->Start( CEapFastActive:: + EapFastActiveShowProvNotSuccessNote, ETrue ); + } + } + } // if ( pac_type == eap_fast_pac_type_tunnel_pac ) + + return status; + } + +#endif //#if defined(USE_FAST_EAP_TYPE) + +#ifdef USE_PAC_STORE + +void eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL( + const eap_pac_store_data_type_e aPacStoreDataType, + eap_variable_data_c * aPacStoreData, + const eap_variable_data_c * const aPacStoreReference /*=NULL*/) +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL Start aPacStoreDataType=%d"), + aPacStoreDataType)); + + if(m_current_eap_type != eap_type_fast || iPacStoreDb == NULL) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL ERROR: Unknown EAP type or No PAC store DB!"))); + + // Can't proceed. + User::Leave(KErrNotSupported); + } + + TBuf pacStoreDBColName; + HBufC8* pacStoreDBColValBuf8(NULL); + eap_status_e status(eap_status_ok); + TInt error(KErrNone); + TBuf dbTableName; + HBufC8* aDbBinaryColumnValue(NULL); + + switch(aPacStoreDataType) + { + case eap_pac_store_data_type_PAC_store_master_key: + { + pacStoreDBColName.Copy(KPacStoreMasterKey); + pacStoreDBColValBuf8 = HBufC8::NewLC(KMaxMasterKeyLengthInDB); + break; + } + case eap_pac_store_data_type_PAC_store_password: + { + pacStoreDBColName.Copy(cf_str_EAP_FAST_PAC_store_password_literal); + pacStoreDBColValBuf8 = HBufC8::NewLC(KMaxPasswordLengthInDB); + break; + } + case eap_pac_store_data_type_PAC_store_device_seed: + { + // Not in PAC store. This should not be called. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL ERROR: This is not in PAC store DB!"))); + + return; + } + case eap_pac_store_data_type_PAC_store_IAP_reference: + { + // Not in PAC store. This should not be called. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL ERROR: This is not in PAC store DB!"))); + + return; + } + case eap_pac_store_data_type_PAC_store_group_reference: + { + // Not in PAC store. This should not be called. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL ERROR: This is not in PAC store DB!"))); + + return; + } + case eap_pac_store_data_type_reference_counter: + { + pacStoreDBColName.Copy(KPacStoreReferenceCounter); + pacStoreDBColValBuf8 = HBufC8::NewLC(KMaxRefCounterLengthInDB); + break; + } + case eap_pac_store_data_type_PAC_file_password: + { + // Not in PAC store. This should not be called. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL ERROR: This is not in PAC store DB!"))); + + return; + } + case eap_pac_store_data_type_group_info: + { + dbTableName = KPacStoreGroupsTableName; + break; + } + case eap_pac_store_data_type_A_ID_info: + { + dbTableName = KPacStoreAIDsTableName; + break; + } + case eap_pac_store_data_type_PAC_info: + { + dbTableName = KPacStorePACsTableName; + break; + } + case eap_pac_store_data_type_group_data: + { + // Memory for aDbBinaryColumnValue is allocated in CPacStoreDatabase::GetPacStoreDataL + pacStoreDBColName.Copy(KPacStoreGroupValue); + break; + } + case eap_pac_store_data_type_A_ID_data: + { + // Memory for aDbBinaryColumnValue is allocated in CPacStoreDatabase::GetPacStoreDataL + pacStoreDBColName.Copy(KPacStoreAIDValue); + break; + } + case eap_pac_store_data_type_PAC_data: + { + // Memory for aDbBinaryColumnValue is allocated in CPacStoreDatabase::GetPacStoreDataL + pacStoreDBColName.Copy(KPacStorePACValue); + break; + } + default: + { + break; + } + } // End : switch(aPacStoreDataType) + + switch(aPacStoreDataType) + { + case eap_pac_store_data_type_PAC_store_master_key: + case eap_pac_store_data_type_PAC_store_password: + case eap_pac_store_data_type_reference_counter: + { + TPtr8 pacStoreDBColValPtr8 = pacStoreDBColValBuf8->Des(); + + TRAPD( err, iPacStoreDb->GetPacStoreDataL(pacStoreDBColName, pacStoreDBColValPtr8) ); + if ( err ) + { + if(pacStoreDBColValBuf8 != NULL) + { + CleanupStack::PopAndDestroy(pacStoreDBColValBuf8); + pacStoreDBColValBuf8 = NULL; + User::Leave( err ); + } + } + + status = aPacStoreData->set_copy_of_buffer( + pacStoreDBColValPtr8.Ptr(), + pacStoreDBColValPtr8.Size()); + + error = m_am_tools->convert_eapol_error_to_am_error(status); + break; + } + case eap_pac_store_data_type_group_data: + case eap_pac_store_data_type_A_ID_data: + case eap_pac_store_data_type_PAC_data: + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL: To get GROUP, PAC or AID data"))); + + + if(aPacStoreReference == NULL )//|| aPacStoreReference->get_data_length() <= 0) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL ERROR: Empty reference"))); + + // Can't proceed. + User::Leave(KErrArgument); + } + if ( aPacStoreReference->get_data_length() <= 0 ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL reset aPacStoreData."))); + aPacStoreData->reset(); + break; + } + + + HBufC8 * reference8 = HBufC8::NewLC(aPacStoreReference->get_data_length()); + TPtr8 referencePtr8 = reference8->Des(); + + referencePtr8.Copy(aPacStoreReference->get_data(), + aPacStoreReference->get_data_length()); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL: reference to DB", + referencePtr8.Ptr(), + referencePtr8.Size())); + + TPtr8 pacStoreDBColDataValPtr8(0,0); + + TRAPD( err, iPacStoreDb->GetPacStoreDataL(pacStoreDBColName, pacStoreDBColDataValPtr8, referencePtr8, &aDbBinaryColumnValue) ); + if ( err ) + { + CleanupStack::PopAndDestroy(1); // reference8. + if(pacStoreDBColValBuf8 != NULL) + { + CleanupStack::PopAndDestroy(pacStoreDBColValBuf8); + pacStoreDBColValBuf8 = NULL; + delete (aDbBinaryColumnValue); + User::Leave( err ); + } + } + + + CleanupStack::PopAndDestroy(1); // reference8. + + if (aDbBinaryColumnValue != NULL) + { + TPtr8 aDbBinaryColumnValuePtr = aDbBinaryColumnValue->Des(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL, data size=%d"), + aDbBinaryColumnValuePtr.Size())); + + if (aDbBinaryColumnValuePtr.Size() > 0) + { + status = aPacStoreData->set_copy_of_buffer( + aDbBinaryColumnValuePtr.Ptr(), + aDbBinaryColumnValuePtr.Size()); + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::No data to fill !!"))); + + } + delete (aDbBinaryColumnValue); + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::Data NULL !!"))); + } + + error = m_am_tools->convert_eapol_error_to_am_error(status); + + delete (pacStoreDBColDataValPtr8.Ptr()); + + break; + } + case eap_pac_store_data_type_group_info: + case eap_pac_store_data_type_A_ID_info: + case eap_pac_store_data_type_PAC_info: + { + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL:ERROR: Calls for INFOs should not come here !!!"))); + + break; + } + default: + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL - UNSUPPORTED Column !!!"))); + + break; + } + }// End: switch(aPacStoreDataType) + + if(pacStoreDBColValBuf8 != NULL) + { + CleanupStack::PopAndDestroy(pacStoreDBColValBuf8); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::GetPacStoreDbDataL-End"))); + + User::LeaveIfError(error); // This could be success or error. Does't matter. +} + +#endif // End: #ifdef USE_PAC_STORE + +//-------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + +eap_status_e eap_am_type_tls_peap_symbian_c::ShowNotifierItemAndGetResponse( + EEapFastNotifierUiItem aNotifierUiItem, TBool aSetActive ) +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ShowNotifierItem aNotifierUiItem=%d, ActiveStatus=%d "), + aNotifierUiItem, IsActive())); + + if ( aSetActive && IsActive() ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("ShowNotifierItemAndGetResponse: Already active when tried to show Notifier"))); + + return eap_status_device_busy; + } + + eap_status_e status( eap_status_ok ); + + if( !m_is_notifier_connected ) + { + TInt error = m_notifier.Connect(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ShowNotifierItem - m_notifier.Connect() returned error=%d\n"), error)); + + if( error != KErrNone) + { + // Can not connect to notifier. + return m_am_tools->convert_am_error_to_eapol_error(error); + } + + m_is_notifier_connected = ETrue; // Got connectted to notifier. + } + + // Update the values needed for notifier. + m_notifier_data_to_user->iEapFastNotifierUiItem = aNotifierUiItem; + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("m_notifier_data_pckg_to_user"), + m_notifier_data_pckg_to_user->Ptr(), + m_notifier_data_pckg_to_user->Size())); + + m_notifier_data_from_user->iEapFastNotifierBuffer.Delete(0,KMaxEapFastNotifierBufLength); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ShowNotifierItem - StartNotifierAndGetResponse"))); + + m_notifier.StartNotifierAndGetResponse( + iStatus, + KEapFastNotifierUid, + *m_notifier_data_pckg_to_user, + *m_notifier_data_pckg_from_user); + + if ( aSetActive ) + { + m_notifier_complete = ETrue; + SetActive(); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ShowNotifierItem - End"))); + + return status; +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_tls_peap_symbian_c::RemoveIAPReference() + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::RemoveIAPReference - Start"))); + m_eap_fast_completion_status = eap_status_ok; + + eap_variable_data_c aIapReference(m_am_tools); + if (aIapReference.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_variable_data_c aGroupReferenceCollection(m_am_tools); + if (aGroupReferenceCollection.get_is_valid() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + TRAPD(error, iPacStoreDb->GetTheFirstCleanupReferenceEntryL( + &aIapReference, + &aGroupReferenceCollection)); + + if(error != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::RemoveIAPReference() ERROR: LEAVE from GetTheFirstCleanupReferenceEntryL error=%d"), + error)); + + m_eap_fast_completion_status = m_am_tools->convert_am_error_to_eapol_error(error); + } + + if (aIapReference.get_data_length() > 0) + { + eap_fast_pac_store_data_c * const group_reference_and_data = new eap_fast_pac_store_data_c(m_am_tools); + + + m_eap_fast_completion_status = group_reference_and_data->get_writable_data()->set_copy_of_buffer(aGroupReferenceCollection.get_data(), aGroupReferenceCollection.get_data_length()); + + if (aIapReference.get_data_length() > 0) + m_completed_with_zero = EFalse; + else + m_completed_with_zero = ETrue; + + + if (m_eap_fast_completion_status == eap_status_ok) + { + m_eap_fast_completion_status = m_tls_application->remove_IAP_reference( + &aIapReference, + group_reference_and_data); + } + } + else + { + m_eap_fast_completion_status = m_partner->set_timer( + this, + KImportFileTimerID, // if nothing in db, go right to file read + 0, + 1); + } + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::RemoveIAPReference - End"))); + + return m_eap_fast_completion_status; + } + +eap_status_e eap_am_type_tls_peap_symbian_c::ImportFilesL() + { + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL - Start"))); + + CDir* files; + + RFs aFs; + aFs.Connect( KFileServerDefaultMessageSlots ); + + m_eap_fast_completion_status = eap_status_pending_request; + + TBool aSuccess = EFalse; + + eap_variable_data_c ImportReference(m_am_tools); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: Get ImportReference from database"))); + + EapTlsPeapUtils::GetEapSettingsDataL( + m_database, + m_index_type, + m_index, + m_tunneling_type, + m_current_eap_type, + KFASTPACGroupImportReferenceCollection, + &ImportReference); + + HBufC8* group_reference8 = HBufC8::NewLC(KMaxFileName); + TPtr8 group_referencePtr8 = group_reference8->Des(); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::ImportFilesL: ImportReference"), + ImportReference.get_data(), + ImportReference.get_data_length())); + + if (ImportReference.get_data_length() != 0) + { + group_referencePtr8.Copy(ImportReference.get_data(), ImportReference.get_data_length()); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::ImportFilesL: Reference"), + group_referencePtr8.Ptr(), + group_referencePtr8.Size())); + + } + else + { + m_eap_fast_completion_status = m_partner->set_timer( + this, + KHandleCompletePacstoreOkTimerID, + &m_eap_fast_completion_status, + 1); + + CleanupStack::PopAndDestroy(group_reference8); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + } + + HBufC8* tempUserBuf8 = HBufC8::NewLC(ImportReference.get_data_length()); + TPtr8 tempUserBufPtr8 = tempUserBuf8->Des(); + for (int i = 0; i< ImportReference.get_data_length();i++ ) + { + tempUserBufPtr8.Append(group_referencePtr8.Ptr()[i++]); + } + group_referencePtr8.Copy(tempUserBufPtr8); + CleanupStack::PopAndDestroy(tempUserBuf8); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::ImportFilesL: Reformatted Reference"), + group_referencePtr8.Ptr(), + group_referencePtr8.Size())); + TInt fileCounter=0; + TBool directoryEmpty = false; + TBool directoryExists = true; + HBufC* buf2 = HBufC::NewLC(KMaxPath); + HBufC8* filename8 = HBufC8::NewLC(KMaxFileName); + TPtr FileNamePtr = buf2->Des(); + TUint filesize =0; + TPtr8 filenamePtr8 = filename8->Des(); + TBool badFile = false; + HBufC* Path = HBufC::NewLC(KMaxFileName); + TPtr PathPtr = Path->Des(); + HBufC8* Path8 = HBufC8::NewLC(KMaxFileName); + TPtr8 PathPtr8 = Path8->Des(); + HBufC8* readData = NULL; + TBool FileFound(EFalse); + + PathPtr8.Zero(); + PathPtr8.Append(KPacStoreSourceDir); + PathPtr8.Append(group_referencePtr8); + PathPtr8.Append(KSeparator); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::ImportFilesL: Path8"), + PathPtr8.Ptr(), + PathPtr8.Size())); + PathPtr.Zero(); + PathPtr.Copy(PathPtr8); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::ImportFilesL: Path"), + PathPtr.Ptr(), + PathPtr.Size())); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: Check directory availability"))); + + if (aFs.GetDir(PathPtr, KEntryAttNormal, ESortByName, files) == KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: Files %d"), + files->Count())); + + while (!FileFound && (fileCounter < files->Count())) + { + directoryExists = true; + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: Get directory contents"))); + + directoryEmpty = false; + + while( fileCounter < files->Count() || (!FileFound)) + { + if (!((*files)[fileCounter].IsDir())) + { + filesize = (*files)[fileCounter].iSize; + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: File size %d"), + filesize)); + filenamePtr8.Copy((*files)[fileCounter++].iName); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::ImportFilesL: Filename"), + filenamePtr8.Ptr(), + filenamePtr8.Size())); + FileFound = ETrue; + } + else + { + fileCounter++; + } + } + + if (!FileFound) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: DirectoryEmpty"))); + directoryEmpty = true; + } + + if (directoryEmpty == true || directoryExists == false || FileFound == EFalse) + { + if (directoryExists) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: We would remove directory"))); + + { + m_eap_fast_completion_status = m_partner->set_timer( + this, + KHandleCompletePacstoreOkTimerID, + &m_eap_fast_completion_status, + 1); + if (readData != NULL) + CleanupStack::PopAndDestroy(readData); + CleanupStack::PopAndDestroy(5); // Path, Path8, filename, buf2, group_reference8 + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + } + } + } + else if(directoryEmpty == false && directoryExists == true && FileFound != EFalse) + { + PathPtr8.Zero(); + PathPtr8.Append(KPacStoreSourceDir); + PathPtr8.Append(group_referencePtr8); + PathPtr8.Append(KSeparator); + PathPtr8.Append(filenamePtr8); + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::ImportFilesL: Path8"), + PathPtr8.Ptr(), + PathPtr8.Size())); + PathPtr.Zero(); + PathPtr.Copy(PathPtr8); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: Read file"))); + + RFile file; + if(file.Open(aFs, PathPtr, EFileRead)==KErrNone) + { + readData= HBufC8::NewLC(filesize); + TPtr8 readDataPtr = readData->Des(); + file.Read(readDataPtr); + file.Close(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: Copy data"))); + + eap_variable_data_c * const in_imported_PAC_data = new eap_variable_data_c(m_am_tools); + // eap_automatic_variable_c can be used in this block because no functions are leaving here. + eap_automatic_variable_c automatic_in_imported_PAC_data(m_am_tools, in_imported_PAC_data); + if (in_imported_PAC_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_eap_fast_completion_status = in_imported_PAC_data->set_copy_of_buffer(readDataPtr.Ptr(), readDataPtr.Size()); + + eap_fast_pac_store_data_c * const in_opt_group_reference_and_data = new eap_fast_pac_store_data_c(m_am_tools); + // eap_automatic_variable_c can be used in this block because no functions are leaving here. + eap_automatic_variable_c automatic_in_opt_group_reference_and_data(m_am_tools, in_opt_group_reference_and_data); + if (in_opt_group_reference_and_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + in_opt_group_reference_and_data->get_writable_data()->set_copy_of_buffer(readDataPtr.Ptr(), readDataPtr.Size()); + + eap_variable_data_c * const in_imported_PAC_filename = new eap_variable_data_c(m_am_tools); + // eap_automatic_variable_c can be used in this block because no functions are leaving here. + eap_automatic_variable_c automatic_in_imported_PAC_filename(m_am_tools, in_imported_PAC_filename); + if (in_imported_PAC_filename == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + m_eap_fast_completion_status = in_imported_PAC_filename->set_copy_of_buffer(filenamePtr8.Ptr(), filenamePtr8.Size()); + + + eap_variable_data_c IAP_reference(m_am_tools); + if (IAP_reference.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + u32_t reference[] = {1ul, 2ul}; + + if (IAP_reference.get_data_length() != 0) + m_eap_fast_completion_status = IAP_reference.set_copy_of_buffer(reference, sizeof(reference)); + else + m_eap_fast_completion_status = IAP_reference.set_copy_of_buffer(EAP_FAST_ZERO_REFERENCE, sizeof(EAP_FAST_ZERO_REFERENCE)); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: Complete operation"))); + + if (m_eap_fast_completion_status != eap_status_ok) + { + if (readData != NULL) + { + CleanupStack::PopAndDestroy(readData); + } + CleanupStack::PopAndDestroy(5); // filename, buf2, group_reference8, Path, path8 + delete files; + return EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + } + else + { + m_eap_fast_completion_status = m_tls_application->add_imported_PAC_file( + &IAP_reference, + in_opt_group_reference_and_data, + in_imported_PAC_data, + in_imported_PAC_filename); + aSuccess = ETrue; + } + } + } + else + { + badFile = true; + } + } + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: No Directory"))); + directoryExists = false; + } + + if (readData != NULL) + { + CleanupStack::PopAndDestroy(readData); + } + CleanupStack::PopAndDestroy(5); // Path, filename8, buf2, Path8, group_reference8 + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL: Operation failed or Complete"))); + + delete files; + + if (m_eap_fast_completion_status != eap_status_pending_request || aSuccess == EFalse) + { + if(badFile == true || directoryEmpty == true || directoryExists == false) + { + if (aSuccess == EFalse) + m_eap_fast_completion_status = eap_status_ok; + m_eap_fast_completion_status = m_partner->set_timer( + this, + KHandleCompletePacstoreNokTimerID, + &m_eap_fast_completion_status, + 1); + } + else + { + m_eap_fast_completion_status = m_partner->set_timer( + this, + KHandleCompletePacstoreOkTimerID, + &m_eap_fast_completion_status, + 1); + } + } + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ImportFilesL - End"))); + + return m_eap_fast_completion_status; + } + +// ---------------------------------------------------------------------------- +eap_status_e eap_am_type_tls_peap_symbian_c::PasswordQueryL() + { + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::PasswordQueryL"))); + + m_pacStorePWBuf8 = HBufC8::NewLC(m_userResponse.get_data_length()); + TPtr8 pacStorePWPtr8 = m_pacStorePWBuf8->Des(); + pacStorePWPtr8.Copy(m_userResponse.get_data(),m_userResponse.get_data_length() ); + m_PAC_store_password.set_copy_of_buffer(m_userResponse.get_data(), m_userResponse.get_data_length()); + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_tls_peap_symbian_c::PasswordQueryL:PW used for masterkey verification (8bits)", + pacStorePWPtr8.Ptr(), + pacStorePWPtr8.Size())); + + + if (iPacStoreDb->IsMasterKeyPresentL() && pacStorePWPtr8.Size()>0 ) + m_verificationStatus = iPacStoreDb->IsMasterKeyAndPasswordMatchingL(pacStorePWPtr8); + + if ((pacStorePWPtr8.Size()==0 && (m_state == EPasswordQuery || m_state == EMasterkeyQuery )) + || m_userAction == EEapFastNotifierUserActionCancel || m_state == EPasswordCancel) + { + m_verificationStatus = EFalse; + m_state = EPasswordCancel; + CleanupStack::PopAndDestroy(m_pacStorePWBuf8); + + m_eap_fast_completion_status = m_partner->set_timer( + this, + KHandleReadPacstoreTimerID, + &m_eap_fast_completion_status, + 0); + return m_eap_fast_completion_status; + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST:eap_am_type_tls_peap_symbian_c::PasswordQueryL:State:%d Prev_State:%d verificationstatus:%d"), + m_state, + m_prev_state, + m_verificationStatus)); + + eap_status_e m_eap_fast_completion_status(eap_status_ok); + + if (m_state == EPasswordQuery) + { + m_state = EWrongPassword; + + if(m_verificationStatus == EFalse) + { + CleanupStack::PopAndDestroy(m_pacStorePWBuf8); + + m_eap_fast_completion_status = ShowNotifierItemAndGetResponse( + EEapFastNotifierWrongPacStorePwNote, ETrue ); + return m_eap_fast_completion_status; + + } + else + { + m_eap_fast_completion_status = m_partner->set_timer( + this, + KHandleReadPacstoreTimerID, + &m_eap_fast_completion_status, + 0); + + CleanupStack::PopAndDestroy(m_pacStorePWBuf8); + return m_eap_fast_completion_status; + } + } + if (m_state == EWrongPassword) + { + m_state = EPasswordQuery; + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST:eap_am_type_tls_peap_symbian_c::PasswordQueryL (first pw ?):State:%d Prev_State:%d verificationstatus:%d"), + m_state, + m_prev_state, + m_verificationStatus)); + pacStorePWPtr8.Zero(); + if (m_verificationStatus == EFalse) + m_eap_fast_completion_status = ShowNotifierItemAndGetResponse( + EEapFastNotifierPacStorePwQuery, ETrue ); + else + m_eap_fast_completion_status = m_partner->set_timer( + this, + KHandleReadPacstoreTimerID, + &m_eap_fast_completion_status, + 0); + + CleanupStack::PopAndDestroy(m_pacStorePWBuf8); + return m_eap_fast_completion_status; + } + + if (m_PAC_store_password.get_data_length()>0 && m_state == EMasterkeyQuery) + { + + if ( m_verificationStatus != EFalse) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::PasswordQueryL - EMasterkeyQuery - OK"))); + } + else // temporary before masterkey creation is done dynamically !!! + { + m_eap_fast_completion_status = ShowNotifierItemAndGetResponse( + EEapFastNotifierCreateMasterkeyQuery, ETrue ); + + } + } + + CleanupStack::PopAndDestroy(m_pacStorePWBuf8); + + return m_eap_fast_completion_status; + } + +eap_status_e eap_am_type_tls_peap_symbian_c::CompletePasswordQueryL() + { + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::CompletePasswordQueryL"))); + + // m_PAC_store_password should have the PW now. Proceed as normal case. + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + return m_eap_fast_completion_status; + } + //eap_pac_store_data_type_PAC_store_password + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::CompletePasswordQueryL()Datatype=%d"), + m_pacStoreDataRefType)); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::CompletePasswordQueryL()Reference=%d"), + m_data_reference.get_reference()->get_data(m_data_reference.get_reference()->get_data_length()))); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::CompletePasswordQueryL()Data=%d"), + m_PAC_store_password.get_data(m_PAC_store_password.get_data_length()))); + + new_data->set_type(eap_pac_store_data_type_PAC_store_password); //m_pacStoreDataRefType + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(m_data_reference.get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + return m_eap_fast_completion_status; + } + + if(m_PAC_store_password.get_data_length() >0) + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(&m_PAC_store_password); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + return m_eap_fast_completion_status; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_new_references_and_data_blocks.add_object(new_data, true); // m_ready_references_and_data_blocks + + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("EAP-FAST: eap_am_type_tls_peap_symbian_c::CompletePasswordQueryL eap_pac_store_data_type_PAC_store_password - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + return m_eap_fast_completion_status; + } + + m_both_completed++; + + return m_eap_fast_completion_status; + } + +eap_status_e eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL(eap_status_e status) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL"))); + if (status == eap_status_ok && (m_new_references_and_data_blocks.get_object_count()>0)) + { + for (u32_t ind = 0ul; ind < m_ready_references_array_index; ++ind) + { + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + new_data->set_type(m_references_and_data_blocks.get_object(ind)->get_type()); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(m_references_and_data_blocks.get_object(ind)->get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(m_references_and_data_blocks.get_object(ind)->get_data()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_ready_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("Final_complete_read_PAC_store_data - added original data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + } + + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + new_data->set_type(m_new_references_and_data_blocks.get_object(m_ready_references_array_index)->get_type()); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(m_new_references_and_data_blocks.get_object(m_ready_references_array_index)->get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(m_new_references_and_data_blocks.get_object(m_ready_references_array_index)->get_data()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_ready_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL - added extra data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + + for (u32_t ind = m_ready_references_array_index; ind < m_references_and_data_blocks.get_object_count(); ++ind) + { + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + new_data->set_type(m_references_and_data_blocks.get_object(ind)->get_type()); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(m_references_and_data_blocks.get_object(ind)->get_reference()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(m_references_and_data_blocks.get_object(ind)->get_data()); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + automatic_new_data.do_not_free_variable(); + + m_eap_fast_completion_status = m_ready_references_and_data_blocks.add_object(new_data, true); + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + + return status; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("Final_complete_read_PAC_store_data - added original data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + } + + if (status == eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL: index=%d, original objects=%d, new=%d total=%d"), + m_ready_references_array_index, + m_references_and_data_blocks.get_object_count(), + m_new_references_and_data_blocks.get_object_count(), + m_ready_references_and_data_blocks.get_object_count())); + + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL Reset unsent data"))); + + m_references_and_data_blocks.reset(); + m_new_references_and_data_blocks.reset(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL Reset Done"))); + + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_ready_references_and_data_blocks); + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_eap_fast_completion_status = eap_status_user_cancel_authentication; + m_new_references_and_data_blocks.reset(); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + } + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL:status nok"))); + m_eap_fast_completion_status = eap_status_user_cancel_authentication; + m_new_references_and_data_blocks.reset(); + m_ready_references_and_data_blocks.reset(); + eap_status_e status = m_tls_application->complete_read_PAC_store_data( + m_eap_fast_completion_status, + m_eap_fast_pac_store_pending_operation, + &m_references_and_data_blocks); + } + + TRAPD(error, UpdatePasswordTimeL()); + + if(error != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::FinalCompleteReadPACStoreDataL ERROR: LEAVE from UpdatePasswordTimeL() error=%d"), + error)); + } + return status; +} + +//-------------------------------------------------- + +eap_status_e eap_am_type_tls_peap_symbian_c::CompleteFilePasswordQueryL() + { + eap_fast_pac_store_data_c * const new_data = new eap_fast_pac_store_data_c(m_am_tools); + + eap_automatic_variable_c automatic_new_data( + m_am_tools, new_data); + + if (new_data == 0) + { + m_eap_fast_completion_status = eap_status_allocation_error; + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + return m_eap_fast_completion_status; + } + + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::CompleteFilePasswordQueryL()Datatype=%d"), + m_pacStoreDataRefType)); + + new_data->set_type(eap_pac_store_data_type_PAC_file_password); //m_pacStoreDataRefType + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::CompleteFilePasswordQueryL()Reference=%d"), + m_data_reference.get_reference()->get_data(m_data_reference.get_reference()->get_data_length()))); + + // Set the reference. + m_eap_fast_completion_status = new_data->get_writable_reference()->set_copy_of_buffer(m_data_reference.get_reference()); + + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + return m_eap_fast_completion_status; + } + m_eap_fast_completion_status = new_data->get_writable_data()->set_copy_of_buffer(&m_userResponse); + + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + return m_eap_fast_completion_status; + } + + automatic_new_data.do_not_free_variable(); + + + m_eap_fast_completion_status = m_new_references_and_data_blocks.add_object(new_data, true); // m_ready_references_and_data_blocks + if (m_eap_fast_completion_status != eap_status_ok) + { + (void) EAP_STATUS_RETURN(m_am_tools, m_eap_fast_completion_status); + return m_eap_fast_completion_status; + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("EAP-FAST: eap_am_type_tls_peap_symbian_c::CompleteFilePasswordQueryL eap_pac_store_data_type_PAC_file_password - added data", + (new_data->get_data())->get_data((new_data->get_data())->get_data_length()), + (new_data->get_data())->get_data_length())); + + m_both_completed++; + return m_eap_fast_completion_status; + + } + +// --------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::CompleteNotifier +// --------------------------------------------------------- +// +eap_status_e eap_am_type_tls_peap_symbian_c::CompleteNotifierL() + { + eap_status_e status( eap_status_ok ); + switch ( m_state ) + { + case EPasswordCancel: + case EPasswordQuery: + case EWrongPassword: + case EFilePasswordQuery: + case EMasterkeyQuery: + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("m_notifier_data_pckg_from_user"), + m_notifier_data_pckg_from_user->Ptr(), + m_notifier_data_pckg_from_user->Size())); + if ( iStatus.Int() == KErrCancel ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::CompleteNotifierL - User cancelled the notifier item"))); + m_userAction = EEapFastNotifierUserActionCancel; + } + else if( iStatus.Int() != KErrNone ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::CompleteNotifierL - ERROR: Notifier error=%d"), + iStatus.Int())); + return m_am_tools->convert_am_error_to_eapol_error(iStatus.Int()); + } + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CompleteNotifierL - Notifier return UiItem=%d, UserAction=%d"), + m_notifier_data_from_user->iEapFastNotifierUiItem, + m_notifier_data_from_user->iEapFastNotifierUserAction)); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("CompleteNotifierL:UserInput:", + m_notifier_data_from_user->iEapFastNotifierBuffer.Ptr(), + m_notifier_data_from_user->iEapFastNotifierBuffer.Size())); + + if ( m_notifier_data_from_user->iEapFastNotifierBuffer.Size() > 0 ) + { + HBufC8* notifier_data8 = HBufC8::NewLC(m_notifier_data_from_user->iEapFastNotifierBuffer.Size()); + TPtr8 notifier_dataPtr8 = notifier_data8->Des(); + + notifier_dataPtr8.Copy(m_notifier_data_from_user->iEapFastNotifierBuffer); // Unicode -> ascii. + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::CompleteNotifierL ShowNotifierItem - Data copy done"))); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_tls_peap_symbian_c::CompleteNotifierL ShowNotifierItem:PW from UI (8bits)", + notifier_dataPtr8.Ptr(), + notifier_dataPtr8.Size())); + + status = m_userResponse.set_copy_of_buffer( + notifier_dataPtr8.Ptr(), + notifier_dataPtr8.Size()); + + CleanupStack::PopAndDestroy( notifier_data8 ); + } + break; + } + default: + { + EAP_TRACE_DEBUG_SYMBIAN( + ( _L( "eap_am_type_tls_peap_symbian_c::CompleteNotifierL() m_state = %d not supported." ), + m_state ) ); + } + } + return status; + } + +//-------------------------------------------------- + +void eap_am_type_tls_peap_symbian_c::ConvertUnicodeToAsciiL(const TDesC16& aFromUnicode, TDes8& aToAscii) + { + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_tls_peap_symbian_c::ConvertUnicodeToAsciiL:From TEXT", + aFromUnicode.Ptr(), + aFromUnicode.Size())); + + if(aFromUnicode.Length() <= 0) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ConvertUnicodeToAsciiL: Return: NOTHING TO CONVERT"))); + + return; + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ConvertUnicodeToAsciiL, aFromUnicode.Length=%d, aFromUnicode.Size=%d"), + aFromUnicode.Length(), aFromUnicode.Size())); + + // Convert from Unicode to ascii. + HBufC8* aFromUnicodeBuf8 = HBufC8::NewLC(aFromUnicode.Length()); // Half times size of source (or length) is enough here. + TPtr8 aFromUnicodePtr8 = aFromUnicodeBuf8->Des(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::ConvertUnicodeToAsciiL, aFromUnicodePtr8.Length=%d, aFromUnicodePtr8.Size=%d, aFromUnicodePtr8.MaxLength=%d, aFromUnicodePtr8.MaxSize=%d"), + aFromUnicodePtr8.Length(), aFromUnicodePtr8.Size(), aFromUnicodePtr8.MaxLength(), aFromUnicodePtr8.MaxSize())); + + aFromUnicodePtr8.Copy(aFromUnicode); // Unicode -> ascii. + + aToAscii = aFromUnicodePtr8; + + CleanupStack::PopAndDestroy(aFromUnicodeBuf8); // Delete aFromUnicodeBuf8. + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("eap_am_type_tls_peap_symbian_c::ConvertUnicodeToAsciiL:To ASCII", + aToAscii.Ptr(), + aToAscii.Size())); + } + + +// --------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL() +// --------------------------------------------------------- +// +void eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL() + { + /* Check validity of password against timelimit */ + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("CheckPasswordTimeValidityL - Start\n"))); + + TInt64 maxSessionTime = 0; + TInt64 fullAuthTime = 0; + + // get max session time + HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength ); + TPtr sqlStatement = buf->Des(); + _LIT( KSqlQuery, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d" ); + sqlStatement.Format( + KSqlQuery, + &cf_str_EAP_FAST_max_session_validity_time_literal, + &KFastGeneralSettingsDBTableName, + &KServiceType, m_index_type, + &KServiceIndex, m_index, + &KTunnelingType, m_tunneling_vendor_type ); + TRAPD( err, maxSessionTime = ReadIntDbValueL( + m_database, + cf_str_EAP_FAST_max_session_validity_time_literal, + sqlStatement ) ); + if ( err != KErrNone ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, + ( EAPL( "ERROR: Leave happened trying to read max session time, \ + error=%d.\n" ), err ) ); + } + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( + EAPL("CheckPasswordTimeValidityL - maxSessionTime=%ld\n"), + maxSessionTime ) ); + +#ifdef USE_PAC_STORE + sqlStatement.Zero(); + if ( !iPacStoreDb ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( + EAPL("CheckPasswordTimeValidityL - iPacStoreDb is NULL.\n"))); + CleanupStack::PopAndDestroy( buf ); // Delete buf. + User::Leave( KErrArgument ); + } + _LIT( KSqlQuery1, "SELECT %S FROM %S" ); + sqlStatement.Format( + KSqlQuery1, + &KFASTLastPasswordIdentityTime, + &KPacStoreGeneralSettingsTableName ); + RDbNamedDatabase& db = iPacStoreDb->GetPacStoreDb(); + TRAP( err, fullAuthTime = ReadIntDbValueL( + db, + KFASTLastPasswordIdentityTime, + sqlStatement ) ); + if ( err == KErrNotFound ) // KFASTLastPasswordIdentityTime was not found + { + TRAP( err, FixOldTablesForPwdIdentityTimeL() ); + if ( err != KErrNone ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "ERROR: eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL() \ + Leave happened trying to fix old table for pwd \ + identity time, error=%d.\n" ), err ) ); + User::Leave( err ); + } + TRAP( err, fullAuthTime = ReadIntDbValueL( + db, + KFASTLastPasswordIdentityTime, + sqlStatement ) ); + if ( err != KErrNone ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "ERROR: eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL() \ + Leave happened trying to read full auth. time, \ + error=%d.\n" ), err ) ); + User::Leave( err ); + } + } + else if ( err != KErrNone ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "ERROR: eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL() \ + Leave happened trying to read full auth. time, \ + error=%d.\n" ), err ) ); + User::Leave( err ); + } +#else + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( + EAPL("CheckPasswordTimeValidityL - PAC store is not used.\n"))); + CleanupStack::PopAndDestroy( buf ); // Delete buf. + User::Leave( KErrNotSupported ); +#endif + + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, + ( EAPL( "CheckPasswordTimeValidityL - fullAuthTime=%ld.\n" ), + fullAuthTime ) ); + + CleanupStack::PopAndDestroy( buf ); // Delete buf. + + // If the max session time from DB is zero then we use the + // one read from configuration file. + if( maxSessionTime == 0) + { + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("CheckPasswordTimeValidityL - Using max session validity time from config file\n"))); + + maxSessionTime = m_max_session_time; // value from configuration file. + } + + // Get the current time. + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("UpdatePasswordTimeL - Get time\n"))); + + TTime currentTime; + currentTime.UniversalTime(); + + TTime lastFullAuthTime(fullAuthTime); + + #if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + TDateTime fullAuthDateTime = lastFullAuthTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("CheckPasswordTimeValidityL Session Validity - Current Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1, currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("CheckPasswordTimeValidityL Session Validity - Last Full Auth Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + fullAuthDateTime.Day()+1, fullAuthDateTime.Month()+1, fullAuthDateTime.Year(), fullAuthDateTime.Hour(), + fullAuthDateTime.Minute(), fullAuthDateTime.Second(), fullAuthDateTime.MicroSecond())); + + #endif + + TTimeIntervalMicroSeconds interval = currentTime.MicroSecondsFrom(lastFullAuthTime); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL:interval in microseconds:"), + &(interval.Int64()), + sizeof(interval.Int64()) ) ); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL:max session time in microseconds:"), + &(maxSessionTime), + sizeof(maxSessionTime) ) ); + + #if defined(_DEBUG) || defined(DEBUG) + + TTimeIntervalMinutes intervalMins; + TInt error = currentTime.MinutesFrom(lastFullAuthTime, intervalMins); + + if(error == KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL") + EAPL("interval in Minutes =%d\n"), + intervalMins.Int())); + } + + #endif + + if( maxSessionTime >= interval.Int64() ) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL - Session Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + /* do nothing */ + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL - Session NOT Valid \n"))); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + + m_tls_application->remove_cached_pac_store_data(); + + TRAPD(error, UpdatePasswordTimeL()); + + if(error != KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("EAP-FAST: eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL() ERROR: LEAVE from UpdatePasswordTimeL() error=%d"), + error)); + + } + } + + } // eap_am_type_tls_peap_symbian_c::CheckPasswordTimeValidityL() + + +// --------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::AlterTableL() +// --------------------------------------------------------- +// +void eap_am_type_tls_peap_symbian_c::AlterTableL( + RDbNamedDatabase& aDb, + TAlterTableCmd aCmd, + const TDesC& aTableName, + const TDesC& aColumnName, + const TDesC& aColumnDef ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "eap_am_type_tls_peap_symbian_c::AlterTableL() IN\n" ) ) ); + + CDbColSet* colSet = aDb.ColSetL( aTableName ); + User::LeaveIfNull( colSet ); + CleanupStack::PushL( colSet ); + + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "eap_am_type_tls_peap_symbian_c::AlterTableL() \ + Number of columns in %S table is %d.\n" ), + &aTableName, colSet->Count() ) ); + + if ( aCmd == EAddColumn ) + { + // Check if there is a target column + if( colSet->ColNo( aColumnName ) != KDbNullColNo ) + { + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "eap_am_type_tls_peap_symbian_c::AlterTableL() \ + Column %S exists already in table %S.\n" ), + &aColumnName, &aTableName ) ); + CleanupStack::PopAndDestroy( colSet ); + return; + } + } + else + { + // Check if there is a target column + if( colSet->ColNo( aColumnName ) == KDbNullColNo ) + { + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "eap_am_type_tls_peap_symbian_c::AlterTableL() \ + Column %S does not exists already in table %S.\n" ), + &aColumnName, &aTableName ) ); + CleanupStack::PopAndDestroy( colSet ); + return; + } + } + + HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength ); + TPtr sqlStatement = buf->Des(); + + _LIT( KSqlAddCol, "ALTER TABLE %S ADD %S %S" ); + _LIT( KSqlRemoveCol, "ALTER TABLE %S DROP %S" ); + + if ( aCmd == EAddColumn ) + { + sqlStatement.Format( KSqlAddCol, &aTableName, + &aColumnName, &aColumnDef ); + } + else + { + sqlStatement.Format( KSqlRemoveCol, &aTableName, + &aColumnName ); + } + + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "eap_am_type_tls_peap_symbian_c::AlterTableL(): sqlStatement=%S\n"), + &sqlStatement ) ); + + User::LeaveIfError( aDb.Execute( sqlStatement ) ); + CleanupStack::PopAndDestroy( buf ); + CleanupStack::PopAndDestroy( colSet ); + + CDbColSet* alteredColSet = aDb.ColSetL( aTableName ); + User::LeaveIfNull( alteredColSet ); + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "eap_am_type_tls_peap_symbian_c::AlterTableL() \ + Number of columns in %S table is %d.\n" ), + &aTableName, alteredColSet->Count() ) ); + delete alteredColSet; + + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "eap_am_type_tls_peap_symbian_c::AlterTableL() OUT\n" ) ) ); + + } // eap_am_type_tls_peap_symbian_c::AlterTableL() + + +// --------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::FixOldTablesForPwdIdentityTimeL() +// --------------------------------------------------------- +// +void eap_am_type_tls_peap_symbian_c::FixOldTablesForPwdIdentityTimeL() + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "eap_am_type_tls_peap_symbian_c::FixOldTablesForPwdIdentityTimeL() IN" ) ) ); + + // remove password identity time from fast table + _LIT( KColumnDef, "BIGINT" ); + AlterTableL( m_database, ERemoveColumn, KFastGeneralSettingsDBTableName, + KFASTLastPasswordIdentityTime ); + + // add password identity time to PAC store table +#ifdef USE_PAC_STORE + if ( !iPacStoreDb ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "ERROR: eap_am_type_tls_peap_symbian_c::FixOldTablesForPwdIdentityTimeL() \ + iPacStoreDb is NULL.\n" ) ) ); + User::Leave( KErrArgument ); + } + RDbNamedDatabase& pacStoreDb = iPacStoreDb->GetPacStoreDb(); + AlterTableL( pacStoreDb, EAddColumn , KPacStoreGeneralSettingsTableName, + KFASTLastPasswordIdentityTime, KColumnDef ); +#else + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "ERROR: eap_am_type_tls_peap_symbian_c::FixOldTablesForPwdIdentityTimeL() \ + PAC store is not used.\n" ) ) ); + User::Leave( KErrNotSupported ); +#endif + + // update password identity time + UpdatePasswordTimeL(); + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "eap_am_type_tls_peap_symbian_c::FixOldTablesForPwdIdentityTimeL() OUT" ) ) ); + + } // eap_am_type_tls_peap_symbian_c::FixOldTablesForPwdIdentityTimeL() + + +// --------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::FixOldTableForPacStoreInitL() +// --------------------------------------------------------- +// +void eap_am_type_tls_peap_symbian_c::FixOldTableForPacStoreInitL() + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "eap_am_type_tls_peap_symbian_c::FixOldTableForPacStoreInitL() IN\n" ) ) ); + +#ifdef USE_PAC_STORE + + if ( !iPacStoreDb ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "ERROR: eap_am_type_tls_peap_symbian_c::FixOldTableForPacStoreInitL() \ + iPacStoreDb is NULL.\n" ) ) ); + User::Leave( KErrArgument ); + } + RDbNamedDatabase& pacStoreDb = iPacStoreDb->GetPacStoreDb(); + _LIT( KColumnDef, "UNSIGNED INTEGER" ); + AlterTableL( pacStoreDb, EAddColumn, KPacStoreGeneralSettingsTableName, + KPacStoreInitialized, KColumnDef ); + +#else + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "ERROR: eap_am_type_tls_peap_symbian_c::FixOldTableForPacStoreInitL() \ + PAC store is not used.\n" ) ) ); + User::Leave( KErrNotSupported ); +#endif + + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( EAPL( + "eap_am_type_tls_peap_symbian_c::FixOldTableForPacStoreInitL() OUT\n" ) ) ); + + } // eap_am_type_tls_peap_symbian_c::FixOldTableForPacStoreInitL() + + +// --------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::ReadIntDbValue() +// --------------------------------------------------------- +// +TInt64 eap_am_type_tls_peap_symbian_c::ReadIntDbValueL( + RDbNamedDatabase& aDb, + const TDesC& aColumnName, + const TDesC& aSqlStatement ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( + EAPL( "eap_am_type_tls_peap_symbian_c::ReadIntDbValueL()\n" ) ) ); + TPtrC columnName; + columnName.Set( aColumnName ); + + RDbView view; + // Evaluate view + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( + EAPL( "ReadIntDbValue() prepare view\n" ) ) ); + User::LeaveIfError( view.Prepare( aDb, TDbQuery( + aSqlStatement ) ) ); + CleanupClosePushL( view ); + + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( + EAPL("ReadIntDbValue() evaluate view\n" ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + // Get the first (and only) row + view.FirstL(); + view.GetL(); + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL( colSet ); + TInt64 retVal = view.ColInt64( colSet->ColNo( columnName ) ); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + CleanupStack::PopAndDestroy( &view ); // Close view. + + return retVal; + } // eap_am_type_tls_peap_symbian_c::ReadIntDbValueL + + +// --------------------------------------------------------- +// eap_am_type_tls_peap_symbian_c::UpdatePasswordTimeL() +// --------------------------------------------------------- +// +void eap_am_type_tls_peap_symbian_c::UpdatePasswordTimeL() + { + /* update last password time */ + TPtrC lastFullPasswordTimeString; + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("UpdatePasswordTimeL - Start\n"))); + + lastFullPasswordTimeString.Set(KFASTLastPasswordIdentityTime); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("UpdatePasswordTimeL - prepare query\n"))); + // Query all the relevant parameters + _LIT(KSQLQuery, "SELECT %S FROM %S"); + sqlStatement.Format( KSQLQuery, &lastFullPasswordTimeString, + &KPacStoreGeneralSettingsTableName ); + + RDbView view; + // Evaluate view + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("UpdatePasswordTimeL - prepare view\n"))); + +#ifdef USE_PAC_STORE + if ( !iPacStoreDb ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( + EAPL("CheckPasswordTimeValidityL - iPacStoreDb is NULL.\n"))); + CleanupStack::PopAndDestroy( buf ); // Delete buf. + User::Leave( KErrArgument ); + } + RDbNamedDatabase& db = iPacStoreDb->GetPacStoreDb(); + User::LeaveIfError( view.Prepare( db, TDbQuery( sqlStatement ), + TDbWindow::EUnlimited ) ); + CleanupClosePushL( view ); +#else + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, ( + EAPL("CheckPasswordTimeValidityL - PAC store is not used.\n"))); + CleanupStack::PopAndDestroy( buf ); // Delete buf. + User::Leave( KErrNotSupported ); +#endif + + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("UpdatePasswordTimeL - evaluate view\n"))); + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row for updation. + view.FirstL(); + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Get the current universal time. + EAP_TRACE_DEBUG(m_am_tools, + TRACE_FLAGS_DEFAULT, ( + EAPL("UpdatePasswordTimeL - Get time\n"))); + TTime currentTime; + currentTime.UniversalTime(); + + + TDateTime currentDateTime = currentTime.DateTime(); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::UpdatePasswordTimeL:store_authentication_time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1,currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + + TInt64 fullAuthTime = currentTime.Int64(); + + view.SetColL(colSet->ColNo(lastFullPasswordTimeString), fullAuthTime); + + view.PutL(); + + CleanupStack::PopAndDestroy(colSet); // Delete colSet. + CleanupStack::PopAndDestroy(&view); // Close view. + CleanupStack::PopAndDestroy(buf); // Delete buf. + + /* update end */ + + } // eap_am_type_tls_peap_symbian_c::UpdatePasswordTimeL() + + +eap_status_e eap_am_type_tls_peap_symbian_c::CreateMasterkeyL() + { + HBufC8* password = HBufC8::NewLC(m_userResponse.get_data_length()); + TPtr8 passwordPtr = password->Des(); + m_PAC_store_password.set_copy_of_buffer(&m_userResponse); + passwordPtr.Copy(m_userResponse.get_data(), m_userResponse.get_data_length()); + m_eap_fast_completion_status = m_am_tools->convert_am_error_to_eapol_error(iPacStoreDb->CreateAndSaveMasterKeyL(passwordPtr)); + CleanupStack::PopAndDestroy(password); + return m_eap_fast_completion_status; + } +#endif //#if defined(USE_FAST_EAP_TYPE) + + + +// ================= TTLS-PAP public exported ======================= + +// ------------------------------------------------------------------------ +// eap_am_type_tls_peap_symbian_c::is_ttls_pap_session_valid() +// ------------------------------------------------------------------------ +// +EAP_FUNC_EXPORT +bool eap_am_type_tls_peap_symbian_c::is_ttls_pap_session_valid() + { + DEBUG( "eap_am_type_tls_peap_symbian_c::is_ttls_pap_session_valid()" ); + + TBool isValid = EFalse; + TInt err = KErrNone; + bool retVal = false; + + TRAP( err, isValid = IsTtlsPapSessionValidL() ); + if ( err != KErrNone ) + { + DEBUG1( "eap_am_type_tls_peap_symbian_c::is_ttls_pap_session_valid() ERROR: \ + Leave, err==%d.", err ); + retVal = false; + } + else + { + retVal = ( isValid ) ? true : false; + } + return retVal; + } + +// ------------------------------------------------------------------------ +// eap_am_type_tls_peap_symbian_c::query_ttls_pap_username_and_password() +// ------------------------------------------------------------------------ +// +EAP_FUNC_EXPORT eap_status_e +eap_am_type_tls_peap_symbian_c::query_ttls_pap_username_and_password( + const eap_variable_data_c * const aInSrvChallengeUtf8 ) + { + DEBUG( "eap_am_type_tls_peap_symbian_c::query_ttls_pap_username_and_password()" ); + + eap_status_e status( eap_status_pending_request ); + + if ( !iEapTtlsPapActive ) + { + TRAPD( err, iEapTtlsPapActive = CEapTtlsPapActive::NewL( + this, m_am_tools ) ); + if ( err != KErrNone ) + { + DEBUG1( "eap_am_type_tls_peap_symbian_c::query_ttls_pap_username_and_password() \ + ERROR: CEapTtlsPapActive::NewL(), err=%d.", err ); + return ConvertAmErrorToEapolError( err ); + } + } + if ( aInSrvChallengeUtf8 != NULL ) + { + iEapTtlsPapActive->UpdateSrvChallenge( *aInSrvChallengeUtf8 ); + } + TBool startedOk = iEapTtlsPapActive->Start( + CEapTtlsPapActive::EEapTtlsPapActiveQueryUserNameAndPassword ); + if ( !startedOk ) + { + status = eap_status_process_general_error; + } + if ( status != eap_status_pending_request ) + { + DEBUG( "eap_am_type_tls_peap_symbian_c::query_ttls_pap_username_and_password() \ + ERROR: status != eap_status_pending_request" ); + } + return status; + } + +// ================= TTLS-PAP public not exported ======================= + +// ------------------------------------------------------------------------ +// eap_am_type_tls_peap_symbian_c::verify_ttls_pap_username_and_password() +// ------------------------------------------------------------------------ +// +eap_status_e +eap_am_type_tls_peap_symbian_c::verify_ttls_pap_username_and_password( + const eap_variable_data_c * const /*aUserName*/, + const eap_variable_data_c * const /*aUserPassword*/ ) + { + DEBUG( "eap_am_type_tls_peap_symbian_c::verify_ttls_pap_username_and_password()" ); + return eap_status_not_supported; + } + +// ================= TTLS-PAP public new ======================= + +// ------------------------------------------------------------------------ +// eap_am_type_tls_peap_symbian_c::CompleteQueryTtlsPapUserNameAndPassword() +// ------------------------------------------------------------------------ +// +eap_status_e +eap_am_type_tls_peap_symbian_c::CompleteQueryTtlsPapUserNameAndPassword( + eap_status_e aStatus, + const TDesC8& aUserNameUtf8, + const TDesC8& aPasswordUtf8 ) + { + DEBUG( "eap_am_type_tls_peap_symbian_c::CompleteQueryTtlsPapUserNameAndPassword()" ); + + eap_status_e retStatus = aStatus; + eap_status_e tmpStatus = eap_status_ok; + + eap_variable_data_c userNameUtf8( m_am_tools ); + eap_variable_data_c passwordUtf8( m_am_tools ); + + tmpStatus = userNameUtf8.set_copy_of_buffer( + aUserNameUtf8.Ptr(), aUserNameUtf8.Length() ); + if ( tmpStatus != eap_status_ok && retStatus == eap_status_ok ) + { + retStatus = tmpStatus; + } + tmpStatus = passwordUtf8.set_copy_of_buffer( + aPasswordUtf8.Ptr(), aPasswordUtf8.Length() ); + if ( tmpStatus != eap_status_ok && retStatus == eap_status_ok ) + { + retStatus = tmpStatus; + } + if ( m_tls_am_partner == NULL ) + { + DEBUG( "eap_am_type_tls_peap_symbian_c::CompleteQueryTtlsPapUserNameAndPassword() \ + ERROR: m_tls_am_partner is NULL." ); + return eap_status_process_general_error; + } + retStatus = m_tls_am_partner-> + complete_query_ttls_pap_username_and_password( + &userNameUtf8, &passwordUtf8, retStatus ); + return retStatus; + } // eap_am_type_tls_peap_symbian_c::CompleteQueryTtlsPapUserNameAndPassword( + + +// ------------------------------------------------------------------------ +// eap_am_type_tls_peap_symbian_c::ConvertAmErrorToEapolError() +// ------------------------------------------------------------------------ +// +eap_status_e +eap_am_type_tls_peap_symbian_c::ConvertAmErrorToEapolError( TInt aErr ) + { + DEBUG( "eap_am_type_tls_peap_symbian_c::ConvertAmErrorToEapolError()" ); + if ( m_am_tools ) + { + return m_am_tools->convert_am_error_to_eapol_error( aErr ); + } + return eap_status_process_general_error; + } + + +// ------------------------------------------------------------------------ +// eap_am_type_tls_peap_symbian_c::ReadTtlsPapDbL() +// ------------------------------------------------------------------------ +// +//| EAP_TLS_PEAP_ttls_pap_password_prompt | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal |// +//| EAP_TLS_PEAP_ttls_pap_username | VARCHAR(253) | cf_str_EAP_TLS_PEAP_ttls_pap_username_literal |// +//| EAP_TLS_PEAP_ttls_pap_password | VARCHAR(128) | cf_str_EAP_TLS_PEAP_ttls_pap_password_literal |// +//| EAP_TLS_PEAP_ttls_pap_max_session_validity_time | BIGINT | cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal |// +//| EAP_TLS_PEAP_ttls_pap_last_full_authentication_time | BIGINT | KTTLSPAPLastFullAuthTime |// +void eap_am_type_tls_peap_symbian_c::ReadTtlsPapDbL( + TTtlsPapDbInfo& aOutDbInfo ) + { + DEBUG( "eap_am_type_tls_peap_symbian_c::ReadTtlsPapDbL()" ); + + HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength ); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT( KSQLQuery, + "SELECT %S, %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d" ); + sqlStatement.Format( KSQLQuery, + &cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal, // select´ + &cf_str_EAP_TLS_PEAP_ttls_pap_username_literal, // select + &cf_str_EAP_TLS_PEAP_ttls_pap_password_literal, // select + &cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal, // select + &KTTLSPAPLastFullAuthTime, // select + &KTtlsDatabaseTableName, // from + &KServiceType, m_index_type, // where %S=%d + &KServiceIndex, m_index, // where %S=%d + &KTunnelingType, eap_type_ttls ); // where %S=%d + + RDbView view; + // Evaluate view + User::LeaveIfError( view.Prepare( m_database, TDbQuery( sqlStatement ) ) ); + CleanupClosePushL( view ); + User::LeaveIfError( view.EvaluateAll() ); + + // Get the first (and only) row + if (view.FirstL()) + { + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL( colSet ); + + // columns reading + aOutDbInfo.iUsrPwdInfo.iPasswordPromptEnabled = view.ColUint( + colSet->ColNo( cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal ) ); + + aOutDbInfo.iUsrPwdInfo.iUserName = view.ColDes( + colSet->ColNo( cf_str_EAP_TLS_PEAP_ttls_pap_username_literal ) ); + + aOutDbInfo.iUsrPwdInfo.iPassword = view.ColDes( + colSet->ColNo( cf_str_EAP_TLS_PEAP_ttls_pap_password_literal ) ); + + aOutDbInfo.iMaxSessionTime = view.ColInt64( + colSet->ColNo( cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal ) ); + + aOutDbInfo.iLastFullAuthTime = view.ColInt64( + colSet->ColNo( KTTLSPAPLastFullAuthTime ) ); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + } + CleanupStack::PopAndDestroy( &view ); // Close view. + CleanupStack::PopAndDestroy( buf ); // Delete buf. + + } // eap_am_type_tls_peap_symbian_c::ReadTtlsPapDbL() + + +// ------------------------------------------------------------------------ +// eap_am_type_tls_peap_symbian_c::WriteTtlsPapDbL() +// ------------------------------------------------------------------------ +// +//| EAP_TLS_PEAP_ttls_pap_password_prompt | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal |// +//| EAP_TLS_PEAP_ttls_pap_username | VARCHAR(253) | cf_str_EAP_TLS_PEAP_ttls_pap_username_literal |// +//| EAP_TLS_PEAP_ttls_pap_password | VARCHAR(128) | cf_str_EAP_TLS_PEAP_ttls_pap_password_literal |// +//| EAP_TLS_PEAP_ttls_pap_max_session_validity_time | BIGINT | cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal |// +//| EAP_TLS_PEAP_ttls_pap_last_full_authentication_time | BIGINT | KTTLSPAPLastFullAuthTime |// +void eap_am_type_tls_peap_symbian_c::WriteTtlsPapDbL( + const TTtlsPapDbInfo& aInDbInfo ) + { + DEBUG( "eap_am_type_tls_peap_symbian_c::WriteTtlsPapDbL()" ); + + + HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength ); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT( KSQLQuery, + "SELECT %S, %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d" ); + sqlStatement.Format( KSQLQuery, + &cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal, // select´ + &cf_str_EAP_TLS_PEAP_ttls_pap_username_literal, // select + &cf_str_EAP_TLS_PEAP_ttls_pap_password_literal, // select + &cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal, // select + &KTTLSPAPLastFullAuthTime, // select + &KTtlsDatabaseTableName, // from + &KServiceType, m_index_type, // where %S=%d + &KServiceIndex, m_index, // where %S=%d + &KTunnelingType, m_tunneling_vendor_type ); // where %S=%d + + RDbView view; + // Evaluate view + User::LeaveIfError( view.Prepare( m_database, TDbQuery( sqlStatement ) ) ); + CleanupClosePushL( view ); + User::LeaveIfError( view.EvaluateAll() ); + + // Get the first (and only) row + if (view.FirstL()) + { + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL( colSet ); + + // columns updating + view.SetColL( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal ), + aInDbInfo.iUsrPwdInfo.iPasswordPromptEnabled ); + + view.SetColL( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_username_literal ), + aInDbInfo.iUsrPwdInfo.iUserName ); + + view.SetColL( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_password_literal ), + aInDbInfo.iUsrPwdInfo.iPassword ); + + view.SetColL( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal ), + aInDbInfo.iMaxSessionTime ); + + view.SetColL( colSet->ColNo( + KTTLSPAPLastFullAuthTime ), + aInDbInfo.iLastFullAuthTime ); + + view.PutL(); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + } + + CleanupStack::PopAndDestroy( &view ); // Close view. + CleanupStack::PopAndDestroy( buf ); // Delete buf. + + } // eap_am_type_tls_peap_symbian_c::WriteTtlsPapDbL() + + +// ------------------------------------------------------------------------ +// eap_am_type_tls_peap_symbian_c::SetTtlsPapColumnToNullL +// ------------------------------------------------------------------------ +// +void eap_am_type_tls_peap_symbian_c::SetTtlsPapColumnToNullL( const TDesC& aColName ) + { + DEBUG( "eap_am_type_tls_peap_symbian_c::SetColumnNullL()" ); + + HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength ); + TPtr sqlStatement = buf->Des(); + + // Query all the relevant parameters + _LIT( KSQLQuery, + "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d" ); + sqlStatement.Format( KSQLQuery, + &aColName, // select´ + &KTtlsDatabaseTableName, // from + &KServiceType, m_index_type, // where %S=%d + &KServiceIndex, m_index, // where %S=%d + &KTunnelingType, m_tunneling_vendor_type ); // where %S=%d + + RDbView view; + // Evaluate view + User::LeaveIfError( view.Prepare( m_database, TDbQuery( sqlStatement ) ) ); + CleanupClosePushL( view ); + User::LeaveIfError( view.EvaluateAll() ); + + // Get the first (and only) row + if (view.FirstL()) + { + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL( colSet ); + + // set column to null + view.SetColNullL( colSet->ColNo( aColName ) ); + + view.PutL(); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + } + + CleanupStack::PopAndDestroy( &view ); // Close view. + CleanupStack::PopAndDestroy( buf ); // Delete buf. + + } // eap_am_type_tls_peap_symbian_c::SetTtlsPapColumnToNullL() + + +// ================= TTLS-PAP private ======================= + +// ------------------------------------------------------------------------ +// eap_am_type_tls_peap_symbian_c::IsTtlsPapSessionValidL() +// ------------------------------------------------------------------------ +// +TBool eap_am_type_tls_peap_symbian_c::IsTtlsPapSessionValidL() + { + DEBUG( "eap_am_type_tls_peap_symbian_c::IsTtlsPapSessionValidL()" ); + + TTtlsPapDbInfo dbInfo; + TInt err = KErrNone; + TBool retValue = EFalse; + + TRAP( err, ReadTtlsPapDbL( dbInfo ) ); + + if ( err != KErrNone ) + { + DEBUG1( "eap_am_type_tls_peap_symbian_c::IsTtlsPapSessionValidL() ERROR: \ + Leave happened, err=%d.", err ); + retValue = EFalse; + } + else + { + if ( dbInfo.iUsrPwdInfo.iPasswordPromptEnabled ) + { + // If the max session time from DB is zero then we use the + // one read from configuration file. + if( dbInfo.iMaxSessionTime == 0 ) + { + DEBUG( "eap_am_type_tls_peap_symbian_c::IsTtlsPapSessionValidL() \ + Using max TTLS PAP session validity time from config file." ); + + // use value from config file + dbInfo.iMaxSessionTime = iEapTtlsPapMaxSessionConfigTime; + } + + retValue = CheckTtlsPapSessionValidity( dbInfo.iMaxSessionTime, + dbInfo.iLastFullAuthTime ); + } + } + return retValue; + } // eap_am_type_tls_peap_symbian_c::IsTtlsPapSessionValidL() + + +// ------------------------------------------------------------------------ +// eap_am_type_tls_peap_symbian_c::CheckTtlsPapSessionValidity() +// ------------------------------------------------------------------------ +// +TBool eap_am_type_tls_peap_symbian_c::CheckTtlsPapSessionValidity( + const TInt64& aInMaxSessionTime, + const TInt64& aInLastFullAuthTime ) + { + DEBUG( "eap_am_type_tls_peap_symbian_c::CheckTtlsPapSessionValidity()" ); + + // Get the current time. + TTime currentTime; + currentTime.UniversalTime(); + + TTime lastFullAuthTime( aInLastFullAuthTime ); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + TDateTime fullAuthDateTime = lastFullAuthTime.DateTime(); + + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, + ( EAPL( "Session Validity - Current Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n" ), + currentDateTime.Day()+1, currentDateTime.Month()+1, currentDateTime.Year(), + currentDateTime.Hour(), currentDateTime.Minute(), currentDateTime.Second(), + currentDateTime.MicroSecond() ) ); + + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + ( EAPL( "Session Validity - Last Full Auth Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n" ), + fullAuthDateTime.Day()+1, fullAuthDateTime.Month()+1, fullAuthDateTime.Year(), fullAuthDateTime.Hour(), + fullAuthDateTime.Minute(), fullAuthDateTime.Second(), fullAuthDateTime.MicroSecond())); + +#endif + + TTimeIntervalMicroSeconds interval = currentTime.MicroSecondsFrom(lastFullAuthTime); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, + ( EAPL( "eap_am_type_tls_peap_symbian_c::CheckTtlsPapSessionValidity:interval in microseconds:"), + &( interval.Int64() ), sizeof( interval.Int64() ) ) ); + + EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, + ( EAPL( "eap_am_type_tls_peap_symbian_c::CheckTtlsPapSessionValidity:max session time in microseconds:"), + &( aInMaxSessionTime ), sizeof( aInMaxSessionTime ) ) ); + +#if defined(_DEBUG) || defined(DEBUG) + + TTimeIntervalMinutes intervalMins; + TInt error = currentTime.MinutesFrom(lastFullAuthTime, intervalMins); + + if(error == KErrNone) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::CheckTtlsPapSessionValidity()") + EAPL("interval in Minutes =%d\n"), + intervalMins.Int())); + } + +#endif + + if( aInMaxSessionTime >= interval.Int64() ) + { + EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, + ( EAPL( "eap_am_type_tls_peap_symbian_c::CheckTtlsPapSessionValidity - Session Valid \n" ) ) ); + EAP_TRACE_END( m_am_tools, TRACE_FLAGS_DEFAULT ); + + return ETrue; + } + else + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, + ( EAPL( "eap_am_type_tls_peap_symbian_c::CheckTtlsPapSessionValidity - Session NOT Valid \n" ) ) ); + EAP_TRACE_END( m_am_tools, TRACE_FLAGS_DEFAULT ); + + return EFalse; + } + } // eap_am_type_tls_peap_symbian_c::CheckTtlsPapSessionValidity + + +// End of file. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/101f8e4c.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/101f8e4c.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Localization strings for project EAPOL +* +*/ + + + +// LOCALISATION STRINGS: + +// b: 50 +// e: 300 +// f: EDialogLabelFont +// d: This name for the EAP-TLS EAP type is displayed in the EAP type list in IAP UI and in EAP-PEAP +// d: encapsulated EAP type selection. +#define TLPL_GE_NAME "EAP-TLS" + +// b: 50 +// e: 300 +// f: EDialogLabelFont +// d: This name for the EAP-PEAP EAP type is displayed in the EAP type list in IAP UI. +#define PEPL_GE_NAME "EAP-PEAP" + + +// b: 50 +// e: 300 +// f: EDialogLabelFont +// d: This name for the EAP-TTLS EAP type is displayed in the EAP type list in IAP UI. +#define TTLSPL_GE_NAME "EAP-TTLS" + +// b: 50 +// e: 300 +// f: EDialogLabelFont +// d: This name for the EAP-FAST EAP type is displayed in the EAP type list in IAP UI. +#define FASTPL_GE_NAME "EAP-FAST" + +// b: 50 +// e: 300 +// f: EDialogLabelFont +// d: This name for the TTLS-PAP type is displayed in the tunneled EAP type list inside EAP-TTLS in IAP UI. +#define TTLSPAPPL_GE_NAME "PAP" + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeap.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,218 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPTLSPEAP_H_ +#define _EAPTLSPEAP_H_ + +// INCLUDES +#include +#include "eap_header.h" + +// CLASS DECLARATION +/** +* Class that implements the generic EAP type interface. Implements EAP TLS protocol. +*/ +class CEapTlsPeap : public CEapType +{ +public: + + /** + * Construction function for TLS. Called by ECom after the DLL has been loaded. + * @param aIapInfo Pointer to the class that contains information about bearer type and unique index. + * @return Pointer to the instance. + */ + static CEapTlsPeap* NewTlsL(SIapInfo *aIapInfo); + + /** + * Construction function for PEAP. Called by ECom after the DLL has been loaded. + * @param aIapInfo Pointer to the class that contains information about bearer type and unique index. + * @return Pointer to the instance. + */ + static CEapTlsPeap* NewPeapL(SIapInfo *aIapInfo); + + /** + * Construction function for TTLS. Called by ECom after the DLL has been loaded. + * @param aIapInfo Pointer to the class that contains information about bearer type and unique index. + * @return Pointer to the instance. + */ +#if defined(USE_TTLS_EAP_TYPE) + static CEapTlsPeap* NewTtlsL(SIapInfo *aIapInfo); +#endif // #if defined(USE_TTLS_EAP_TYPE) + + /** + * Construction function for TTLS-PAP. + * + * Called by ECom after the DLL has been loaded. + * @param aIapInfo Pointer to the class that contains information + * about bearer type and unique index. + * @return Pointer to the instance. + */ + + static CEapTlsPeap* NewTtlsPapL( SIapInfo* aIapInfo ); + + /** + * Construction function for FAST. Called by ECom after the DLL has been loaded. + * @param aIapInfo Pointer to the class that contains information about bearer type and unique index. + * @return Pointer to the instance. + */ +#if defined(USE_FAST_EAP_TYPE) + static CEapTlsPeap* NewFastL(SIapInfo *aIapInfo); +#endif + + /** + * Destructor does nothing. + */ + virtual ~CEapTlsPeap(); + +#ifdef USE_EAP_SIMPLE_CONFIG + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @param eap_config_if Pointer used for call back to creater of stack (eapol_am_wlan_authentication_symbian_c class). + * @return Pointer to the implementation. + */ + virtual eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const configuration_if); + +#else + + /** + * Creates EAP protocol interface implementation. Instances an object that + * has been derived from eap_base_type_c that handles the communication + * with EAP stack. + * @param aTools Pointer to tools class. + * @param aPartner Used for callbacks to the stack. + * @param is_client_when_true Specifies whether the EAP type acts as a client or server. + * @param receive_network_id Network addresses + * @return Pointer to the implementation. + */ + eap_base_type_c* GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id); + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG + + /** + * Invokes the configuration UI. + **/ + TInt InvokeUiL(); + + /** + * Gets information about EAP type. + * @return Pointer to a class that contains the EAP type information. Also pushed to cleanup stack. + */ + CEapTypeInfo* GetInfoLC(); + + /** + * Deletes EAP type configuration + */ + void DeleteConfigurationL(); + + /** + * Returns the version of the interface that the EAP type implements. + * The client-side of the interface must always check the version with this function + * and not call the functions that are not implemented. New functions must be + * added to the end of the interface so that the order of the old functions + * does not change. + * @return Integer indicating the version. + */ + TUint GetInterfaceVersion(); + + /** + * Sets the tunneling type. This is used to indicate that this type is run inside another + * EAP type. + * @param aTunnelingType Type number for the tunneling type + */ + void SetTunnelingType(const TInt aTunnelingType); + + /** + * Changes the index of the saved parameters. + * @param aIndexType Indicates the bearer used for this connection. + * @param aIndex Index for the connection. aIndexType and aIndex uniquely specify the connection. + */ + void SetIndexL( + const TIndexType aIndexType, + const TInt aIndex); + + /** + * Sets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void SetConfigurationL(const EAPSettings& aSettings); + + /** + * Gets the EAP types configuration + * @param aSettings Structure containing the settings + */ + void GetConfigurationL(EAPSettings& aSettings); + + /** + * Copies the EAP types configuration + * @param aDestinationIndex ID to where copy the settings. + */ + void CopySettingsL(const TIndexType aDestinationIndexType, const TInt aDestinationIndex); + +protected: + + /** + * Constructor initialises member variables. + */ + CEapTlsPeap(const TIndexType aIndexType, const TInt aIndex, const eap_type_value_e aEapType); + +private: + +#ifdef USE_PAC_STORE + + void UpdatePacStoreCleanupTableL(const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + +#endif // #ifdef USE_PAC_STORE + +private: + + // Bearer type + TIndexType iIndexType; + + // Unique index + TInt iIndex; + + // Eap type (PEAP or TLS or TTLS or FAST) + eap_type_value_e iEapType; + + // Tunneling type + eap_type_value_e iTunnelingType; + + // EAP array for deleting and changing index + RImplInfoPtrArray iEapArray; +}; + +#endif // _EAPTLSPEAP_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeapCertFetcher.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeapCertFetcher.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,99 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPTLSPEAPCERTFETCHER_H_ +#define _EAPTLSPEAPCERTFETCHER_H_ + +// INCLUDES +#include +#include +#include +#include "EapTlsPeapUtils.h" + + +class CEapTlsPeapUiCertificates; + +// CLASS DECLARATION +class CEapTlsPeapCertFetcher +: public CActive +{ +public: + static CEapTlsPeapCertFetcher* NewL(CEapTlsPeapUiCertificates* const aParent); + + virtual ~CEapTlsPeapCertFetcher(); + + void GetCertificatesL(); + + // DON'T USE THESE. ONLY USED FOR EapTlsPeapUtils. + static CEapTlsPeapCertFetcher* NewL(); + void GetSymbianSubjectKeyIdL( TDes8& aSubjectKeyId, CertificateEntry aCertEntry ); + +protected: + + CEapTlsPeapCertFetcher(CEapTlsPeapUiCertificates* const aParent); + + void ConstructL(); + + void RunL(); + + void DoCancel(); + +private: + + // DON'T USE THIS. ONLY USED FOR EapTlsPeapUtils. + CEapTlsPeapCertFetcher(); + +private: + + enum TState + { + EGetCertificatesInitStore, + EGetCertificatesGetCertList, + EGetCertificatesRetrieveCert, + EGetSymbianSubjectKeyId // DON'T USE THIS. ONLY USED FOR EapTlsPeapUtils. + }; + + TState iState; + + CEapTlsPeapUiCertificates* const iParent; + + RMPointerArray iCertInfos; + + CUnifiedCertStore* iCertStore; + + RFs iFs; + + CCertAttributeFilter* iCertFilter; + + RArray iUserCerts; + + RArray iCACerts; + + // For wrapping asynchronous calls. + CActiveSchedulerWait iWait; + + HBufC8* iEncodedCertificate; + TPtr8 iCertPtr; + + +}; + +#endif // _EAPTLSPEAPCERTFETCHER_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeapDbDefaults.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeapDbDefaults.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,213 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + + +#if !defined(_EAPTLSPEAPDBDEFAULTS_H_) +#define _EAPTLSPEAPDBDEFAULTS_H_ + +enum TTLSPEAPUseManualRealm +{ + ETLSPEAPUseManualRealmNo, // False. Don't use Manual Realm. + ETLSPEAPUseManualRealmYes, // True. Use Manual Realm. +}; + +enum TTLSPEAPUseManualUsername +{ + ETLSPEAPUseManualUsernameNo, // False. Don't use Manual Username. + ETLSPEAPUseManualUsernameYes, // True. Use Manual Username. +}; + +enum TTLSPEAPVerifyCertRealm +{ + ETLSPEAPVerifyCertRealmNo, // False. Don't Verify Certificate Realm. + ETLSPEAPVerifyCertRealmYes, // True. Verify Certificate Realm. +}; + +enum TTLSPEAPServerAuthenticatesClientPolicy +{ + ETLSPEAPServerAuthenticatesClientPolicyNo, // False. + ETLSPEAPServerAuthenticatesClientPolicyYes, // True. +}; + +enum TTLSPEAPTLSPrivacy +{ + ETLSPEAPTLSPrivacyNo, // False. TLS Privacy OFF. + ETLSPEAPTLSPrivacyYes, // True. TLS Privacy ON. +}; + +#ifdef USE_FAST_EAP_TYPE + +enum TFASTAuthProvModeAllowed +{ + EFASTAuthProvModeAllowedNo, // False. Authenticated provisioning mode NOT allowed. + EFASTAuthProvModeAllowedYes, // True. Authenticated provisioning mode allowed. +}; + +enum TFASTUnauthProvModeAllowed +{ + EFASTUnauthProvModeAllowedNo, // False. Unauthenticated provisioning mode NOT allowed. + EFASTUnauthProvModeAllowedYes, // True. Unauthenticated provisioning mode allowed. +}; + +enum TFASTWarnADHPNoPAC +{ + EFASTWarnADHPNoPACNo, // False. Warnings or prompts NOT allowed. + EFASTWarnADHPNoPACYes, // True. Warnings or prompts allowed. +}; + +enum TFASTWarnADHPNoMatchingPAC +{ + EFASTWarnADHPNoMatchingPACNo, // False. Warnings or prompts NOT allowed. + EFASTWarnADHPNoMatchingPACYes, // True. Warnings or prompts allowed. +}; + +enum TFASTWarnNotDefaultServer +{ + EFASTWarnNotDefaultServerNo, // False. Warnings or prompts NOT allowed. + EFASTWarnNotDefaultServerYes, // True. Warnings or prompts allowed. +}; + +#endif //#ifdef USE_FAST_EAP_TYPE + +// LOCAL CONSTANTS +const TInt default_EAP_TLS_PEAP_use_manual_realm = ETLSPEAPUseManualRealmNo; +_LIT(default_EAP_TLS_PEAP_manual_realm, ""); + +const TInt default_EAP_TLS_PEAP_use_manual_username = ETLSPEAPUseManualUsernameNo; +_LIT(default_EAP_TLS_PEAP_manual_username, ""); + +const TInt default_EAP_TLS_PEAP_cipher_suite = tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA; + +const TInt default_EAP_TLS_PEAP_used_PEAP_version = 0; +const TInt default_EAP_TLS_PEAP_accepted_PEAP_versions[] = {0, 1, -1}; + +_LIT8(default_PEAP_tunneled_types, ""); + +const TInt default_EAP_TLS_server_authenticates_client = 1; +const TInt default_EAP_PEAP_TTLS_server_authenticates_client = 0; + +_LIT(default_CA_cert_label, "rsaca.eapsim.foo"); +_LIT(default_client_cert_label, "rsaclient@eapsim.foo"); + +const TInt default_EAP_TLS_PEAP_verify_certificate_realm = 0; + +const TUint default_EAP_TLS_PEAP_TLS_Privacy = ETLSPEAPTLSPrivacyNo; + +const TInt64 default_MaxSessionTime = 0; // 0 means read from configuration file. +const TInt64 default_FullAuthTime = 0; + +// Defaults for EAP-FAST specific items +#ifdef USE_FAST_EAP_TYPE +const TUint default_EAP_FAST_Auth_Prov_Mode_Allowed = EFASTAuthProvModeAllowedNo; // Default is NO +const TUint default_EAP_FAST_Unauth_Prov_Mode_Allowed = EFASTUnauthProvModeAllowedNo; // Default is NO +const TUint default_EAP_FAST_Warn_ADHP_No_PAC = EFASTWarnADHPNoPACNo; // Default is NO +const TUint default_EAP_FAST_Warn_ADHP_No_Matching_PAC = EFASTWarnADHPNoMatchingPACNo; // Default is NO +const TUint default_EAP_FAST_Warn_Not_Default_Server = EFASTWarnNotDefaultServerNo; // Default is NO +#endif //#ifdef USE_FAST_EAP_TYPE + +// Add here the cipher suites you want to be allowed by default. Note that the last +// element must be 0. +const TInt default_allowed_cipher_suites[] = { + tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA, + tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + tls_cipher_suites_TLS_RSA_WITH_AES_128_CBC_SHA, + tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + 0 +}; + +const TInt available_cipher_suites[] = { + tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA, + tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + tls_cipher_suites_TLS_RSA_WITH_AES_128_CBC_SHA, + tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + tls_cipher_suites_TLS_RSA_WITH_RC4_128_MD5, + tls_cipher_suites_TLS_RSA_WITH_RC4_128_SHA, + 0 +}; + +const TUint KMaxManualUsernameLengthInDB = 255; +const TUint KMaxManualRealmLengthInDB = 255; +const TUint KMaxCertLabelLengthInDB = 255; +const TUint KMaxSubjectKeyIdLengthInDB = 255; // Not using KKeyIdentifierLength (EapSettings.h) as this is + // Symbian's subjectkey id (hash of actual subjectkey id), though the lengths are same. +const TUint KMaxSessionIdLengthInDB = 32; +const TUint KMaxMasterSecretLengthInDB = 48; +const TUint KMaxPEAPVersionsStringLengthInDB = 12; +const TUint KMaxTunneledTypeStringLengthInDB = 240; // 8 bytes for an EAP type. So 30 EAP types can be stored with this size. + + +/** +* Possible values of password prompt. +*/ +enum TPapPasswordPrompt + { + /** + * False. Don't show password prompt. + */ + EPapPasswordPromptOff, + + /** + * True. Show password prompt. + */ + EPapPasswordPromptOn + }; + +/** +* Default password prompt value. +*/ +const TUint KDefaultPapPasswordPrompt = EPapPasswordPromptOn; + +/** +* Maximum length of PAP user name according to UI spec. +*/ +const TUint KMaxPapUserNameLengthInDb = 253; + +/** +* Maximum length of PAP password according to UI spec. +*/ +const TUint KMaxPapPasswordLengthInDb = 128; + +/** +* Default PAP user name. +*/ +_LIT( KDefaultPapUserName, "" ); + +/** +* Default PAP password. +*/ +_LIT( KDefaultPapPassword, "" ); + +/** +* Default max PAP session time. +* Value 0 means reading from configuration file. +*/ +const TInt64 KDefaultMaxPapSessionTime = 0; + +/** +* Default full PAP authentication time. +*/ +const TInt64 KDefaultFullPapAuthTime = 0; + +#endif // _EAPTLSPEAPDBDEFAULTS_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeapDbParameterNames.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeapDbParameterNames.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#if !defined(_EAPTLAPEAPDBPARAMETERNAMES_H_) +#define _EAPTLAPEAPDBPARAMETERNAMES_H_ + +#include "eap_type_tls_peap_types.h" + +// LOCAL CONSTANTS + +_LIT(KServiceType, "ServiceType"); +_LIT(KServiceIndex, "ServiceIndex"); +_LIT(KTunnelingType, "TunnelingType"); +_LIT(KCACertLabelOld, "CA_cert_label"); +_LIT(KClientCertLabel, "client_cert_label"); +_LIT(KCertLabel, "label"); +_LIT(KCipherSuite, "cipher_suite"); +_LIT(KSerialNumber, "SerialNumber"); +_LIT(KIssuerName, "IssuerName"); +_LIT(KSubjectName, "SubjectName"); +_LIT(KSubjectKeyIdentifier, "SubjectKeyId"); // This stores the Symbian's subjectkey id (hash of actual subjectkey id). + // This is the subjectkey id used in authentications. + +_LIT(KTLSLastFullAuthTime, "EAP_TLS_last_full_authentication_time"); +_LIT(KPEAPLastFullAuthTime, "EAP_PEAP_last_full_authentication_time"); +_LIT(KTTLSLastFullAuthTime, "EAP_TTLS_last_full_authentication_time"); +_LIT(KFASTLastFullAuthTime, "EAP_FAST_last_full_authentication_time"); +_LIT(KFASTLastPasswordIdentityTime, "EAP_FAST_last_password_identity_time"); +_LIT( KTTLSPAPLastFullAuthTime, "EAP_TTLS_PAP_last_full_authentication_time" ); + +// This is the subject key id present in the certificate itself, which OMA provisioning (Device Management) +// sets through EAPSettings. KSubjectKeyIdentifier -> stores the Symbian's subjectkey id (hash of actual subjectkey id). +// This is used only to provide GetConfigurationL the value set by SetConfigurationL +// No other use of this value, at the moment. +_LIT(KActualSubjectKeyIdentifier, "ActualSubjectKeyId"); +_LIT(KThumbprint, "Thumbprint"); + +#ifdef USE_FAST_EAP_TYPE +_LIT(KFASTPACGroupDBReferenceCollection, "EAP_FAST_PAC_Group_DB_Reference_Collection"); +_LIT(KFASTPACGroupImportReferenceCollection, "EAP_FAST_PAC_Group_Import_Reference_Collection"); +_LIT(KFASTWarnADHPNoPAC, "EAP_FAST_Warn_ADHP_No_PAC"); +_LIT(KFASTWarnADHPNoMatchingPAC, "EAP_FAST_Warn_ADHP_No_Matching_PAC"); +_LIT(KFASTWarnNotDefaultServer, "EAP_FAST_Warn_Not_Default_Server"); + +// For PAC store. +_LIT(KPACStoreReferenceCounter, "EAP_PAC_Store_Referance_Counter"); +_LIT(KPACStoreMasterKey, "EAP_PAC_Store_Master_Key"); +_LIT(KPACStoreGroupReference, "EAP_PAC_Store_Group_Reference"); +_LIT(KPACStoreGroupValue, "EAP_FAST_Group_Value"); +_LIT(KPACStoreAIDReference, "EAP_PAC_Store_AID_Reference"); +_LIT(KPACStoreAIDValue, "EAP_PAC_Store_AID_Value"); +_LIT(KPACStorePACReference, "EAP_PAC_Store_PAC_Reference"); +_LIT(KPACStorePACValue, "EAP_PAC_Store_PAC_Value"); + +#endif //#ifdef USE_FAST_EAP_TYPE + +#ifndef USE_EAP_TLS_IDENTITY_PRIVACY +_LIT(cf_str_EAP_TLS_PEAP_use_identity_privacy_literal, "EAP_TLS_PEAP_use_identity_privacy"); +#endif + +#endif // _EAPTLAPEAPDBPARAMETERNAMES_H_ + + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeapGlobal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeapGlobal.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +#ifndef _EAPTLSPEAPGLOBAL_H_ +#define _EAPTLSPEAPGLOBAL_H_ + +#include +#include + +// LOCAL CONSTANTS + +_LIT(KReleaseDate, "20040829:"); +_LIT(KEapTypeVersion, "1.0"); +_LIT(KManufacturer, "Nokia"); +_LIT(KNokiaSignature, ""); +_LIT(KExtraInfo1, ""); +_LIT(KExtraInfo2, ""); + +#endif // _EAPTLSPEAPGLOBAL_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeapUtils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/EapTlsPeapUtils.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,316 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _EAPTLSPEAPUTILS_H_ +#define _EAPTLSPEAPUTILS_H_ + +// INCLUDES +#include +#include +#include "eap_am_tools_symbian.h" +#include + +#include +#include + +#ifndef USE_EAP_EXPANDED_TYPES +// This dependencay is needed only for non-expanded EAP types. +#include +#endif //#ifndef USE_EAP_EXPANDED_TYPES + +#include "eap_type_tls_peap_types.h" +#include "eap_header.h" + +// LOCAL CONSTANTS + +#ifdef USE_EAP_EXPANDED_TYPES + +// Size of Expanded EAP Type +const TUint8 KExpandedEAPTypeSize = 8; + +struct SExpandedEAPType +{ + // Unique ID for an expanded EAp type. + // This includes, Type (1 byte), Vendor-Id (3bytes) and Vendor-Type (4bytes). + TBuf8 iExpandedEAPType; +}; + +typedef RPointerArray RExpandedEapTypePtrArray; + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + +#ifdef SYMBIAN_SECURE_DBMS +// For EAP TLS, PEAP, TTLS, FAST secure databases. +// Full path is not needed. The database eaptls.dat will be saved in the +// data cage path for DBMS. So it will be in "\private\100012a5\eaptls.dat" in C: drive. +// The maximum length of database name is 0x40 (KDbMaxName) , which is defined in d32dbms.h. + +_LIT(KTlsDatabaseName, "c:eaptls.dat"); +_LIT(KPeapDatabaseName, "c:eappeap.dat"); +_LIT(KTtlsDatabaseName, "c:eapttls.dat"); +_LIT(KFastDatabaseName, "c:eapfast.dat"); + +_LIT(KSecureUIDFormat, "SECURE[102072e9]"); // For the security policy. + +#else + +_LIT(KTlsDatabaseName, "c:\\system\\data\\eaptls.dat"); +_LIT(KPeapDatabaseName, "c:\\system\\data\\eappeap.dat"); +_LIT(KTtlsDatabaseName, "c:\\system\\data\\eapttls.dat"); +_LIT(KFastDatabaseName, "c:\\system\\data\\eapfast.dat"); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + +// For TLS. +_LIT(KTlsDatabaseTableName, "eaptls"); +_LIT(KTlsAllowedUserCertsDatabaseTableName, "eaptls_usercerts"); +_LIT(KTlsAllowedCACertsDatabaseTableName, "eaptls_cacerts"); +_LIT(KTlsAllowedCipherSuitesDatabaseTableName, "eaptls_ciphersuites"); + +// For PEAP. +_LIT(KPeapDatabaseTableName, "eappeap"); +_LIT(KPeapAllowedUserCertsDatabaseTableName, "eappeap_usercerts"); +_LIT(KPeapAllowedCACertsDatabaseTableName, "eappeap_cacerts"); +_LIT(KPeapAllowedCipherSuitesDatabaseTableName, "eappeap_ciphersuites"); + +// For TTLS. +_LIT(KTtlsDatabaseTableName, "eapttls"); +_LIT(KTtlsAllowedUserCertsDatabaseTableName, "eapttls_usercerts"); +_LIT(KTtlsAllowedCACertsDatabaseTableName, "eapttls_cacerts"); +_LIT(KTtlsAllowedCipherSuitesDatabaseTableName, "eapttls_ciphersuites"); + +// For FAST. +_LIT(KFastGeneralSettingsDBTableName, "eapfast_general_settings"); // Generic settings (similar to TTLS etc) for EAP-FAST. +_LIT(KFastSpecialSettingsDBTableName, "eapfast_special_settings"); // Only for EAP-FAST specific (PAC etc) settings. +_LIT(KFastAllowedUserCertsDatabaseTableName, "eapfast_usercerts"); +_LIT(KFastAllowedCACertsDatabaseTableName, "eapfast_cacerts"); +_LIT(KFastAllowedCipherSuitesDatabaseTableName, "eapfast_ciphersuites"); + +enum TAlterTableCmd +{ +EAddColumn, +ERemoveColumn +}; + +// CLASS DECLARATION +class EapTlsPeapUtils +{ +public: + static void OpenDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + eap_type_value_e aEapType); + + /** + * Changes the settings' index + */ + static void SetIndexL( + RDbNamedDatabase& aDatabase, + const TDesC& aTableName, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const TIndexType aNewIndexType, + const TInt aNewIndex, + const eap_type_value_e aNewTunnelingType); + + static void SetConfigurationL( + RDbNamedDatabase& aDatabase, + const EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType); + + static void GetConfigurationL( + RDbNamedDatabase& aDatabase, + EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType); + + static void CopySettingsL( + RDbNamedDatabase& aDatabase, + const TDesC& aTableName, + const TIndexType aSrcIndexType, + const TInt aSrcIndex, + const eap_type_value_e aSrcTunnelingType, + const TIndexType aDestIndexType, + const TInt aDestIndex, + const eap_type_value_e aDestTunnelingType); + + static void DeleteConfigurationL( + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType); + + static void ReadCertRowsToArrayL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const aTools, + const TDesC& aTableName, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + RArray& aArray); + + static void ReadUintRowsToArrayL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const aTools, + const TDesC& aTableName, + const TDesC& aColumnName, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + RArray& aArray); + +#ifdef USE_EAP_EXPANDED_TYPES + + // Stores the tunneled EAP type (expanded) to the database. + static void SetTunnelingExpandedEapDataL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const aTools, + RExpandedEapTypePtrArray &aEnabledEAPArrary, + RExpandedEapTypePtrArray &aDisabledEAPArrary, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType); + + // Retrieves the tunneled EAP type (expanded) from the database . + static void GetTunnelingExpandedEapDataL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const aTools, + RExpandedEapTypePtrArray &aEnabledEAPArrary, + RExpandedEapTypePtrArray &aDisabledEAPArrary, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType); + +#else // For normal EAP types. + + // This sets only the tunneling EAP types. + static void SetEapDataL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const aTools, + TEapArray &aEaps, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType); + + // This gets only the tunneling EAP types. + static void GetEapDataL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const aTools, + TEapArray &aEaps, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + static TBool CompareTCertLabels( + const TCertLabel& item1, + const TCertLabel& item2); + + static TBool CompareSCertEntries(const SCertEntry& item1, const SCertEntry& item2); + + static TBool CipherSuiteUseRSAKeys(tls_cipher_suites_e aCipherSuite); + + static TBool CipherSuiteUseDSAKeys(tls_cipher_suites_e aCipherSuite); + + static TBool CipherSuiteIsEphemeralDHKeyExchange(tls_cipher_suites_e aCipherSuite); + + static void GetEapSettingsDataL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const TDesC& aDbColumnName, + eap_variable_data_c * const aDbColumnValue); + + static void SetEapSettingsDataL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const TDesC& aDbColumnName, + const eap_variable_data_c * const aDbColumnValue); + +private: + static void OpenTlsDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + + static void OpenPeapDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + +#if defined(USE_TTLS_EAP_TYPE) + static void OpenTtlsDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); +#endif // #if defined(USE_TTLS_EAP_TYPE) + +#if defined(USE_FAST_EAP_TYPE) + + static void OpenFastDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType); + +#endif // #if defined(USE_FAST_EAP_TYPE) + + static void AddExtraCertColumnsL( + RDbNamedDatabase& aDatabase, + TDesC& aTableName); + +private: + + static void AlterTableL( + RDbNamedDatabase& aDb, + TAlterTableCmd aCmd, + const TDesC& aTableName, + const TDesC& aColumnName, + const TDesC& aColumnDef ); + +}; + +#endif // _EAPTLSPEAPUTILS_H_ + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/eappeap.hlp.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/eappeap.hlp.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource headers for project EAPOL +* +*/ + + +// +// eappeap.hlp.hrh +// + +// +// File generated on 10:42:20 28/7/2004 +// by cshlpcmp Version 010 +// + +#ifndef __EAPPEAP_HLP_HRH__ +#define __EAPPEAP_HLP_HRH__ + + +_LIT(KPEPL_HLP_DIAL_USER_CERTS,"PEPL_HLP_DIAL_USER_CERTS"); +_LIT(KPEPL_HLP_DIAL_CA_CERTS,"PEPL_HLP_DIAL_CA_CERTS"); +_LIT(KPEPL_HLP_DIAL_CIPHER_SUITES,"PEPL_HLP_DIAL_CIPHER_SUITES"); +_LIT(KPEPL_HLP_DIAL_EAP_TYPES,"PEPL_HLP_DIAL_EAP_TYPES"); +_LIT(KPEPL_HLP_DIAL_SETTINGS,"PEPL_HLP_DIAL_SETTINGS"); +_LIT(KETPN_HLP_DIAL_IDENTITY,"ETPN_HLP_DIAL_IDENTITY"); + +#endif diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/eaptls.hlp.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/inc/eaptls.hlp.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource headers for project EAPOL +* +*/ + + +// +// eaptls.hlp.hrh +// + +// +// File generated on 10:42:33 28/7/2004 +// by cshlpcmp Version 010 +// + +#ifndef __EAPTLS_HLP_HRH__ +#define __EAPTLS_HLP_HRH__ + + +_LIT(KTLPL_HLP_DIAL_USER_CERTS,"TLPL_HLP_DIAL_USER_CERTS"); +_LIT(KTLPL_HLP_DIAL_CA_CERTS,"TLPL_HLP_DIAL_CA_CERTS"); +_LIT(KTLPL_HLP_DIAL_CIPHER_SUITES,"TLPL_HLP_DIAL_CIPHER_SUITES"); +_LIT(KTLPL_HLP_DIAL_SETTINGS,"TLPL_HLP_DIAL_SETTINGS"); +_LIT(KETPN_HLP_DIAL_CERT_SELECTION,"ETPN_HLP_DIAL_CERT_SELECTION"); + +#endif diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/101f8e4c.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/101f8e4c.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource definitions for project EAPOL +* +*/ + + + +// INCLUDES +#include +#include "101f8e4c.loc" +#include "EapolUID.h" + +// RESOURCE DEFINITIONS +// --------------------------------------------------------- +// +// theInfo +// Contains the ECom registration information for EAP TLS & EAP PEAP & EAP TTLS +// +// --------------------------------------------------------- +// +RESOURCE REGISTRY_INFO theInfo +{ +dll_uid = EAP_TLS_PEAP_DLL_UID; +interfaces = + { + INTERFACE_INFO + { + interface_uid = PLUGIN_INTERFACE_UID; + implementations = + { + + BINARY_IMPLEMENTATION_INFO + { + implementation_uid = EAP_TLS_IMPLEMENTATION_UID; + version_no = 1; + display_name = TLPL_GE_NAME; + default_data = {0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D}; // TLS + opaque_data = {0x00}; + }, + BINARY_IMPLEMENTATION_INFO + { + implementation_uid = EAP_PEAP_IMPLEMENTATION_UID; + version_no = 1; + display_name = PEPL_GE_NAME; + default_data = {0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19}; // PEAP + opaque_data = {0x55}; // "NOT_INSIDE|NOT_INSIDE_PEAP|NOT_INSIDE_TTLS|NOT_INSIDE_FAST" + }, + BINARY_IMPLEMENTATION_INFO + { + implementation_uid = EAP_TTLS_IMPLEMENTATION_UID; + version_no = 1; + display_name = TTLSPL_GE_NAME; + default_data = {0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15}; // TTLS + opaque_data = {0x55}; // "NOT_INSIDE|NOT_INSIDE_PEAP|NOT_INSIDE_TTLS|NOT_INSIDE_FAST" + } + +#ifdef FF_WLAN_EXTENSIONS + , // Must + BINARY_IMPLEMENTATION_INFO + { + implementation_uid = EAP_FAST_IMPLEMENTATION_UID; + version_no = 1; + display_name = FASTPL_GE_NAME; + default_data = {0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B}; // FAST + opaque_data = {0x55}; // "NOT_INSIDE|NOT_INSIDE_PEAP|NOT_INSIDE_TTLS|NOT_INSIDE_FAST" + } +#endif // #ifdef FF_WLAN_EXTENSIONS + + , // Must + BINARY_IMPLEMENTATION_INFO + { + implementation_uid = TTLS_PAP_IMPLEMENTATION_UID; + version_no = 1; + display_name = TTLSPAPPL_GE_NAME; + default_data = {0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x62}; // PAP only allowed inside TTLS + opaque_data = {0x4E}; //"NOT_OUTSIDE|NOT_OUTSIDE_PEAP|NOT_INSIDE_PEAP|NOT_INSIDE_FAST" + } // NOT_OUTSIDE is the only needed instead of NOT_OUTSIDE_PEAP, + // but for historical reasons we are using NOT_OUTSIDE_PEAP + // to indicate that the EAP is allowed only as encapsulated EAP. + + }; + } + }; +} +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeap.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1316 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 417 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "EapTlsPeap.h" +#include "eap_base_type.h" +#include "EapTlsPeapGlobal.h" +#include + +#include +#include +#include +#if defined(USE_TTLS_EAP_TYPE) + #include +#endif + +#if defined(USE_FAST_EAP_TYPE) +#include +#include "tls_application_eap_fast.h" +#endif + +#include "eap_am_type_tls_peap_symbian.h" +#include "eap_type_tls_peap.h" +#include "tls_record.h" +#include "eap_core.h" +#include "tls_application_eap_core.h" +#include "eap_am_tools_symbian.h" +#include "eap_am_trace_symbian.h" + +#ifdef USE_PAC_STORE +#include "pac_store_db_symbian.h" +#endif + +#include + +// LOCAL CONSTANTS + +// The version number of this interface. At the moment this version number is +// common for all three plug-in interfaces. +const TUint KInterfaceVersion = 1; + + +// ================= MEMBER FUNCTIONS ======================= + + +CEapTlsPeap::CEapTlsPeap(const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aEapType) +: iIndexType(aIndexType) +, iIndex(aIndex) +, iEapType(aEapType) +, iTunnelingType(eap_type_none) +{ + +#ifdef USE_EAP_EXPANDED_TYPES + + ASSERT(iEapType.get_vendor_id() == eap_type_vendor_id_ietf); + ASSERT(iTunnelingType.get_vendor_id() == eap_type_vendor_id_ietf); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + +} + +// ---------------------------------------------------------- + +CEapTlsPeap* CEapTlsPeap::NewTlsL(SIapInfo *aIapInfo) +{ + return new (ELeave) CEapTlsPeap(aIapInfo->indexType, aIapInfo->index, eap_type_tls); +} + +// ---------------------------------------------------------- + +CEapTlsPeap* CEapTlsPeap::NewPeapL(SIapInfo *aIapInfo) +{ + return new (ELeave) CEapTlsPeap(aIapInfo->indexType, aIapInfo->index, eap_type_peap); +} + +// ---------------------------------------------------------- + +#if defined(USE_TTLS_EAP_TYPE) + +CEapTlsPeap* CEapTlsPeap::NewTtlsL(SIapInfo *aIapInfo) +{ + return new (ELeave) CEapTlsPeap(aIapInfo->indexType, aIapInfo->index, eap_type_ttls); +} + +#endif // #if defined(USE_TTLS_EAP_TYPE) + +// ---------------------------------------------------------- + + +// --------------------------------------------------------- +// CEapTtlsPapActive::NewTtlsPapL() +// --------------------------------------------------------- +// + +CEapTlsPeap* CEapTlsPeap::NewTtlsPapL( SIapInfo* aIapInfo ) + { + return new (ELeave) CEapTlsPeap( + aIapInfo->indexType, aIapInfo->index, eap_type_ttls_plain_pap ); + } + + +// ---------------------------------------------------------- + +#if defined(USE_FAST_EAP_TYPE) + +CEapTlsPeap* CEapTlsPeap::NewFastL(SIapInfo *aIapInfo) +{ + return new (ELeave) CEapTlsPeap(aIapInfo->indexType, aIapInfo->index, eap_type_fast); +} + +#endif // #if defined(USE_FAST_EAP_TYPE) + +// ---------------------------------------------------------- + +CEapTlsPeap::~CEapTlsPeap() +{ + iEapArray.ResetAndDestroy(); +} + +// ---------------------------------------------------------- + +#ifdef USE_EAP_SIMPLE_CONFIG + +eap_base_type_c* CEapTlsPeap::GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id, + abs_eap_configuration_if_c * const /*configuration_if*/) + +#else + +eap_base_type_c* CEapTlsPeap::GetStackInterfaceL(abs_eap_am_tools_c* const aTools, + abs_eap_base_type_c* const aPartner, + const bool is_client_when_true, + const eap_am_network_id_c * const receive_network_id) + +#endif // #ifdef USE_EAP_SIMPLE_CONFIG +{ +#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::GetStackInterfaceL -Start- iIndexType=%d, iIndex=%d, Tunneling vendor type=%d, Eap vendor type=%d \n"), + iIndexType,iIndex, iTunnelingType.get_vendor_type(), iEapType.get_vendor_type())); + +#else + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::GetStackInterfaceL -Start- iIndexType=%d, iIndex=%d, iTunnelingType=%d, iEapType=%d \n"), + iIndexType, iIndex, iTunnelingType, iEapType)); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + // Create adaptation layer + eap_am_type_tls_peap_symbian_c* amEapType; + eap_base_type_c* type; + tls_record_c* record; + + amEapType = eap_am_type_tls_peap_symbian_c::NewL( + aTools, + aPartner, + iIndexType, + iIndex, + iTunnelingType, + iEapType, + is_client_when_true, + receive_network_id); + if (amEapType->get_is_valid() == false) + { + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrGeneral); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::GetStackInterfaceL - created eap_am_type_tls_peap_symbian_c \n"))); + + if (iEapType == eap_type_tls) + { + // TLS + record = new tls_record_c( + aTools, + amEapType, + false, + 0, + false, + is_client_when_true, + iEapType, + receive_network_id); + if (record == 0) + { + // Out of memory + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrNoMemory); + } + else if (record->get_is_valid() == false) + { + record->shutdown(); + delete record; + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrGeneral); + } + } + else + { + // PEAP, TTLS and FAST. + + eap_core_c* eap_core = new eap_core_c( + aTools, + 0, + is_client_when_true, + receive_network_id, + true); + if (eap_core == 0) + { + // Out of memory + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrNoMemory); + } + else if (eap_core->get_is_valid() == false) + { + // Out of memory + eap_core->shutdown(); + delete eap_core; + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrGeneral); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::GetStackInterfaceL - created eap_core_c \n"))); + + tls_base_application_c* application; + +#if defined (USE_FAST_EAP_TYPE) + if(iEapType == eap_type_fast) + { + application = new tls_application_eap_fast_c( + aTools, + eap_core, + true, + is_client_when_true, + iEapType, + receive_network_id, + amEapType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::GetStackInterfaceL - created tls_application_eap_fast_c \n"))); + } + else +#endif // End: #if defined (USE_FAST_EAP_TYPE) + { + application = new tls_application_eap_core_c( + aTools, + eap_core, + true, + is_client_when_true, + iEapType, + receive_network_id); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::GetStackInterfaceL - created tls_application_eap_core_c \n"))); + } + if (application == 0) + { + // Out of memory + eap_core->shutdown(); + delete eap_core; + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrNoMemory); + } + else if (application->get_is_valid() == false) + { + // Out of memory + // application takes care of eap_core_c deletion + application->shutdown(); + delete application; + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrGeneral); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::GetStackInterfaceL - application is valid \n"))); + + record = new tls_record_c( + aTools, + amEapType, + false, + application, + true, + is_client_when_true, + iEapType, + receive_network_id); + if (record == 0) + { + // Out of memory + // application takes care of eap_core_c deletion + application->shutdown(); + delete application; + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrGeneral); + } + else if (record->get_is_valid() == false) + { + // Out of memory + // record takes care of application deletion + record->shutdown(); + delete record; + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrGeneral); + } + + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::GetStackInterfaceL - Creating the OS independent portion - eap_type_tls_peap_c \n"))); + + // Create the OS independent portion + + type = new eap_type_tls_peap_c( + aTools, + aPartner, + amEapType, + true, + record, + true, + is_client_when_true, + iEapType, + receive_network_id); + if (type == 0) + { + // Out of memory + // record takes care of application deletion + record->shutdown(); + delete record; + amEapType->shutdown(); + delete amEapType; + User::Leave(KErrNoMemory); + } + else if(type->get_is_valid() == false) + { + type->shutdown(); + // type deletes all + delete type; + User::Leave(KErrGeneral); + } + + return type; +} + +// ---------------------------------------------------------- +TInt CEapTlsPeap::InvokeUiL() +{ + TInt buttonId(0); + +#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::InvokeUiL -Start- iIndexType=%d, iIndex=%d, Tunneling vendor type=%d, Eap vendor type=%d \n"), + iIndexType,iIndex, iTunnelingType.get_vendor_type(), iEapType.get_vendor_type())); + + CEapTlsPeapUiConnection uiConn(iIndexType, iIndex, + iTunnelingType.get_vendor_type(), iEapType.get_vendor_type()); + +#else + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::InvokeUiL -Start- iIndexType=%d, iIndex=%d, iTunnelingType=%d, iEapType=%d \n"), + iIndexType, iIndex, iTunnelingType, iEapType)); + + CEapTlsPeapUiConnection uiConn(iIndexType, iIndex, iTunnelingType, iEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::InvokeUiL Created UI connection \n"))); + +#ifdef USE_EAP_EXPANDED_TYPES + + switch (iEapType.get_vendor_type()) + +#else + + switch (iEapType) + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + { + case eap_type_tls: + { + CEapTlsUi* tls_ui = CEapTlsUi::NewL(&uiConn); + CleanupStack::PushL(tls_ui); + buttonId = tls_ui->InvokeUiL(); + CleanupStack::PopAndDestroy(tls_ui); + } + break; + + case eap_type_peap: + { + CEapPeapUi* peap_ui = CEapPeapUi::NewL(&uiConn, iIndexType, iIndex); + CleanupStack::PushL(peap_ui); + buttonId = peap_ui->InvokeUiL(); + CleanupStack::PopAndDestroy(peap_ui); + } + break; + +#if defined (USE_TTLS_EAP_TYPE) + case eap_type_ttls: + { + CEapTtlsUi* ttls_ui = CEapTtlsUi::NewL(&uiConn, iIndexType, iIndex); + CleanupStack::PushL(ttls_ui); + buttonId = ttls_ui->InvokeUiL(); + CleanupStack::PopAndDestroy(ttls_ui); + } + break; +#endif + +#if defined (USE_FAST_EAP_TYPE) + case eap_type_fast: + { + CEapFastUi* fast_ui = CEapFastUi::NewL(&uiConn, iIndexType, iIndex); + CleanupStack::PushL(fast_ui); + buttonId = fast_ui->InvokeUiL(); + CleanupStack::PopAndDestroy(fast_ui); + } + break; +#endif + + case eap_type_ttls_plain_pap: + { + CPapUi* papUi = CPapUi::NewL( &uiConn ); + CleanupStack::PushL( papUi ); + buttonId = papUi->InvokeUiL(); + CleanupStack::PopAndDestroy( papUi ); + } + break; + + default: + // Should never happen + User::Leave(KErrArgument); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::InvokeUiL -End-\n"))); + + return buttonId; +} +// ---------------------------------------------------------- +CEapTypeInfo* CEapTlsPeap::GetInfoLC() +{ + CEapTypeInfo* info = new(ELeave) CEapTypeInfo((TDesC&)KReleaseDate, (TDesC&)KEapTypeVersion, + (TDesC&)KManufacturer); + CleanupStack::PushL(info); + return info; +} + +// ---------------------------------------------------------- + +void CEapTlsPeap::DeleteConfigurationL() +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = iTunnelingType.get_vendor_type(); + TUint aEapVendorType = iEapType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(iTunnelingType); + TUint aEapVendorType = static_cast(iEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeap::DeleteConfigurationL:Start:iIndexType=%d,iIndex=%d,TunnelingType=%d,EapType=%d"), + iIndexType, iIndex, aTunnelingVendorType, aEapVendorType)); + + EapTlsPeapUtils::DeleteConfigurationL(iIndexType, iIndex, iTunnelingType, iEapType); + + // For Encapsulated types + + if (iEapType == eap_type_peap + || iEapType == eap_type_ttls + +#ifdef USE_FAST_EAP_TYPE + || iEapType == eap_type_fast +#endif + + || iEapType == eap_type_ttls_plain_pap + + + ) + { + iEapArray.ResetAndDestroy(); + REComSession::ListImplementationsL(KEapTypeInterfaceUid, iEapArray); + + for (TInt i = 0; i < iEapArray.Count(); i++) + { + if ((iEapType == eap_type_peap && !CEapType::IsDisallowedInsidePEAP(*iEapArray[i])) + || (iEapType == eap_type_ttls && !CEapType::IsDisallowedInsideTTLS(*iEapArray[i])) + +#ifdef USE_FAST_EAP_TYPE + || (iEapType == eap_type_fast && !CEapType::IsDisallowedInsidePEAP(*iEapArray[i])) +#endif + + || (iEapType == eap_type_ttls_plain_pap && !CEapType::IsDisallowedInsidePEAP(*iEapArray[i])) + + + ) + { + // Deleting the encapsulated EAP type configurations possible inside PEAP, TTLS and FAST. + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeap::DeleteConfigurationL: Deleting encapsulated types for EAP type=%d"), + aEapVendorType)); + + CEapType* eapType; + +#ifdef USE_EAP_EXPANDED_TYPES + + TBuf8 expandedCue = iEapArray[i]->DataType(); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("CEapTlsPeap::DeleteConfigurationL: Expanded cue:", + expandedCue.Ptr(), expandedCue.Size())); + + eapType = CEapType::NewL(expandedCue, iIndexType, iIndex); + + if(eapType == NULL) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeap::DeleteConfigurationL: Ecom Error - No specified Expanded EAP plugin")) ); + User::Leave(KErrNotFound); + } + + eapType->SetTunnelingType(iEapType.get_vendor_type()); + +#ifdef USE_FAST_EAP_TYPE + + // This IAP is deleted. Update the PAC store cleanup table if this IAP is + // for EAP-FAST. + + if(iEapType == eap_type_fast) + { + +#ifdef USE_PAC_STORE + + TRAPD(error, UpdatePacStoreCleanupTableL(iIndexType, iIndex, iTunnelingType)); + + if(error != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::DeleteConfigurationL: WARNING: LEAVE: from UpdatePacStoreCleanupTableL, error=%d"), + error)); + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::DeleteConfigurationL: successfully done UpdatePacStoreCleanupTableL"))); + } + +#endif // #ifdef USE_PAC_STORE + + } + +#endif // #ifdef USE_FAST_EAP_TYPE +#endif // USE_EAP_EXPANDED_TYPES + + +#ifndef USE_EAP_EXPANDED_TYPES +//#else // For normal EAP types. + + TBuf8<3> cue = iEapArray[i]->DataType(); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("CEapTlsPeap::DeleteConfigurationL: cue:", + cue.Ptr(), cue.Size())); + + eapType = CEapType::NewL(cue, iIndexType, iIndex); + + if(eapType == NULL) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeap::DeleteConfigurationL: Ecom Error - No specified EAP plugin")) ); + User::Leave(KErrNotFound); + } + + eapType->SetTunnelingType(iEapType); + +#endif //#ifndef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::DeleteConfigurationL: PushL(...)"))); + + CleanupStack::PushL(eapType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::DeleteConfigurationL: DeleteConfigurationL()"))); + + eapType->DeleteConfigurationL(); + + CleanupStack::PopAndDestroy(); + } + } + } // End: if (iEapType == eap_type_peap + + +} + +// ---------------------------------------------------------- + +TUint CEapTlsPeap::GetInterfaceVersion() +{ + return KInterfaceVersion; +} + +// ---------------------------------------------------------- + +void CEapTlsPeap::SetTunnelingType(const TInt aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + // Vendor id is eap_type_vendor_id_ietf always in this plugin. + iTunnelingType.set_eap_type_values(eap_type_vendor_id_ietf, aTunnelingType); + +#else + + iTunnelingType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES +} + +// ---------------------------------------------------------- +void CEapTlsPeap::SetIndexL( + const TIndexType aIndexType, + const TInt aIndex) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = iTunnelingType.get_vendor_type(); + TUint aEapVendorType = iEapType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(iTunnelingType); + TUint aEapVendorType = static_cast(iEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeap::SetIndexL:Start: Old: iIndexType=%d,iIndex=%d,TunnelingType=%d,EapType=%d"), + iIndexType, iIndex, aTunnelingVendorType, aEapVendorType)); + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeap::SetIndexL: New: IndexType=%d,Index=%d"), + aIndexType, aIndex)); + + // First delete the target configuration + TIndexType tmpIndexType = iIndexType; + TInt tmpIndex = iIndex; + + iIndexType = aIndexType; + iIndex = aIndex; + + TInt err(KErrNone); + TRAP(err, DeleteConfigurationL()); + // Ignore error on purpose + + // Return the indices + iIndexType = tmpIndexType; + iIndex = tmpIndex; + + RDbNamedDatabase db; + + RDbs session; + + EapTlsPeapUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType, iEapType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + TPtrC settings; + TPtrC usercerts; + TPtrC cacerts; + TPtrC ciphersuites; + +#ifdef USE_FAST_EAP_TYPE + TPtrC fastSpecialSettings; +#endif + +#ifdef USE_EAP_EXPANDED_TYPES + + switch (iEapType.get_vendor_type()) + +#else + + switch (iEapType) + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + { + case eap_type_tls: + { + settings.Set(KTlsDatabaseTableName); + usercerts.Set(KTlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTlsAllowedCipherSuitesDatabaseTableName); + } + break; + + case eap_type_peap: + { + settings.Set(KPeapDatabaseTableName); + usercerts.Set(KPeapAllowedUserCertsDatabaseTableName); + cacerts.Set(KPeapAllowedCACertsDatabaseTableName); + ciphersuites.Set(KPeapAllowedCipherSuitesDatabaseTableName); + } + break; + +#if defined (USE_TTLS_EAP_TYPE) + case eap_type_ttls: + { + settings.Set(KTtlsDatabaseTableName); + usercerts.Set(KTtlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTtlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTtlsAllowedCipherSuitesDatabaseTableName); + } + break; +#endif + +#ifdef USE_FAST_EAP_TYPE + case eap_type_fast: + { + settings.Set(KFastGeneralSettingsDBTableName); // This is general settings for FAST. + fastSpecialSettings.Set(KFastSpecialSettingsDBTableName); + + usercerts.Set(KFastAllowedUserCertsDatabaseTableName); + cacerts.Set(KFastAllowedCACertsDatabaseTableName); + ciphersuites.Set(KFastAllowedCipherSuitesDatabaseTableName); + } + break; +#endif + + case eap_type_ttls_plain_pap: + { + settings.Set(KTtlsDatabaseTableName); + usercerts.Set(KTtlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTtlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTtlsAllowedCipherSuitesDatabaseTableName); + } + break; + + default: + // Should never happen + User::Leave(KErrArgument); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetIndexL - Setting indices to the tables\n"))); + + // For the settings db. For EAP-FAST this is the general settings. + EapTlsPeapUtils::SetIndexL( + db, + settings, + iIndexType, + iIndex, + iTunnelingType, + aIndexType, + aIndex, + iTunnelingType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetIndexL - Set the index to (general) settings table\n"))); + + // For the USER certificate db. + EapTlsPeapUtils::SetIndexL( + db, + usercerts, + iIndexType, + iIndex, + iTunnelingType, + aIndexType, + aIndex, + iTunnelingType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetIndexL - Set the index to USER cert table\n"))); + + // For the CA certificate db. + EapTlsPeapUtils::SetIndexL( + db, + cacerts, + iIndexType, + iIndex, + iTunnelingType, + aIndexType, + aIndex, + iTunnelingType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetIndexL - Set the index to CA cert table\n"))); + + // For the ciphersuites db. + EapTlsPeapUtils::SetIndexL( + db, + ciphersuites, + iIndexType, + iIndex, + iTunnelingType, + aIndexType, + aIndex, + iTunnelingType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetIndexL - Set the index to Cipher suite table\n"))); + +#ifdef USE_FAST_EAP_TYPE + // This special settings is only for EAP-FAST + if(iEapType == eap_type_fast) + { + EapTlsPeapUtils::SetIndexL( + db, + fastSpecialSettings, + iIndexType, + iIndex, + iTunnelingType, + aIndexType, + aIndex, + iTunnelingType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetIndexL - Set the index to EAP-FAST Special settings table\n"))); + + }// End: if(iEapType == eap_type_fast) + +#endif // End: #ifdef USE_FAST_EAP_TYPE + + db.Close(); + CleanupStack::PopAndDestroy(2); // db, session. + + //////// Encapsulated types + + if (iEapType == eap_type_peap + || iEapType == eap_type_ttls + +#ifdef USE_FAST_EAP_TYPE + || iEapType == eap_type_fast +#endif + + || iEapType == eap_type_ttls_plain_pap + + + ) + { + iEapArray.ResetAndDestroy(); + REComSession::ListImplementationsL(KEapTypeInterfaceUid, iEapArray); + + for (TInt i = 0; i < iEapArray.Count(); i++) + { + if ((iEapType == eap_type_peap && !CEapType::IsDisallowedInsidePEAP(*iEapArray[i])) + || (iEapType == eap_type_ttls && !CEapType::IsDisallowedInsideTTLS(*iEapArray[i])) + +#ifdef USE_FAST_EAP_TYPE + || (iEapType == eap_type_fast && !CEapType::IsDisallowedInsidePEAP(*iEapArray[i])) +#endif + + || (iEapType == eap_type_ttls_plain_pap && !CEapType::IsDisallowedInsidePEAP(*iEapArray[i])) + + + ) + { + // Setting the index for encapsulated EAP type configurations possible + // inside PEAP, TTLS and FAST. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetIndexL - Setting the index to encapsulated EAP types\n"))); + + CEapType* eapType; + +#ifdef USE_EAP_EXPANDED_TYPES + + TBuf8 expandedCue = iEapArray[i]->DataType(); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("CEapTlsPeap::SetIndexL: Expanded cue:", + expandedCue.Ptr(), expandedCue.Size())); + + eapType = CEapType::NewL(expandedCue, iIndexType, iIndex); + + if(eapType == NULL) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeap::SetIndexL: Ecom Error - No specified Expanded EAP plugin")) ); + User::Leave(KErrNotFound); + } + + eapType->SetTunnelingType(iEapType.get_vendor_type()); + +#else // For normal EAP types. + + TBuf8<3> cue = iEapArray[i]->DataType(); + + eapType = CEapType::NewL(cue, iIndexType, iIndex); + + eapType->SetTunnelingType(iEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + CleanupStack::PushL(eapType); + + eapType->SetIndexL(aIndexType, aIndex); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetIndexL - Set the index to encapsulated EAP types\n"))); + + CleanupStack::PopAndDestroy(); + } + } + } + iIndexType = aIndexType; + iIndex = aIndex; + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetIndexL - End\n"))); +} + +void CEapTlsPeap::SetConfigurationL(const EAPSettings& aSettings) +{ + RDbNamedDatabase db; + + RDbs session; + + // This also creates the IAP entry if it doesn't exist + EapTlsPeapUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType, iEapType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapTlsPeapUtils::SetConfigurationL( + db, + aSettings, + iIndexType, + iIndex, + iTunnelingType, + iEapType); + + CleanupStack::PopAndDestroy(2); // db, session +} + +void CEapTlsPeap::GetConfigurationL(EAPSettings& aSettings) +{ + RDbNamedDatabase db; + + RDbs session; + + // This also creates the IAP entry if it doesn't exist + EapTlsPeapUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType, iEapType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + EapTlsPeapUtils::GetConfigurationL( + db, + aSettings, + iIndexType, + iIndex, + iTunnelingType, + iEapType); + + db.Close(); + CleanupStack::PopAndDestroy(2); // db, session +} + +void CEapTlsPeap::CopySettingsL( + const TIndexType aDestinationIndexType, + const TInt aDestinationIndex) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = iTunnelingType.get_vendor_type(); + TUint aEapVendorType = iEapType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(iTunnelingType); + TUint aEapVendorType = static_cast(iEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeap::CopySettingsL:Start:iIndexType=%d,iIndex=%d,TunnelingType=%d,EapType=%d"), + iIndexType, iIndex, aTunnelingVendorType, aEapVendorType)); + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeap::CopySettingsL: DestinationIndexType=%d,DestinationIndex=%d"), + aDestinationIndexType, aDestinationIndex)); + + // First delete the target configuration + TIndexType tmpIndexType = iIndexType; + TInt tmpIndex = iIndex; + + iIndexType = aDestinationIndexType; + iIndex = aDestinationIndex; + + // Return the indices + iIndexType = tmpIndexType; + iIndex = tmpIndex; + + RDbNamedDatabase db; + + RDbs session; + + EapTlsPeapUtils::OpenDatabaseL(db, session, iIndexType, iIndex, iTunnelingType, iEapType); + + CleanupClosePushL(session); + CleanupClosePushL(db); + + TPtrC settings; + TPtrC usercerts; + TPtrC cacerts; + TPtrC ciphersuites; + +#ifdef USE_FAST_EAP_TYPE + TPtrC fastSpecialSettings; +#endif + +#ifdef USE_EAP_EXPANDED_TYPES + + switch (iEapType.get_vendor_type()) + +#else + + switch (iEapType) + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + { + case eap_type_tls: + { + settings.Set(KTlsDatabaseTableName); + usercerts.Set(KTlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTlsAllowedCipherSuitesDatabaseTableName); + } + break; + + case eap_type_peap: + { + settings.Set(KPeapDatabaseTableName); + usercerts.Set(KPeapAllowedUserCertsDatabaseTableName); + cacerts.Set(KPeapAllowedCACertsDatabaseTableName); + ciphersuites.Set(KPeapAllowedCipherSuitesDatabaseTableName); + } + break; + +#if defined (USE_TTLS_EAP_TYPE) + case eap_type_ttls: + { + settings.Set(KTtlsDatabaseTableName); + usercerts.Set(KTtlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTtlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTtlsAllowedCipherSuitesDatabaseTableName); + } + break; +#endif + + case eap_type_ttls_plain_pap: + { + settings.Set(KTtlsDatabaseTableName); + usercerts.Set(KTtlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTtlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTtlsAllowedCipherSuitesDatabaseTableName); + } + break; + +#ifdef USE_FAST_EAP_TYPE + case eap_type_fast: + { + settings.Set(KFastGeneralSettingsDBTableName); // This is general settings for FAST. + fastSpecialSettings.Set(KFastSpecialSettingsDBTableName); + + usercerts.Set(KFastAllowedUserCertsDatabaseTableName); + cacerts.Set(KFastAllowedCACertsDatabaseTableName); + ciphersuites.Set(KFastAllowedCipherSuitesDatabaseTableName); + } + break; +#endif + + default: + // Should never happen + User::Leave(KErrArgument); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::CopySettingsL - Copying the tables\n"))); + + // For the settings db. For EAP-FAST this is the general settings. + EapTlsPeapUtils::CopySettingsL( + db, + settings, + iIndexType, + iIndex, + iTunnelingType, + aDestinationIndexType, + aDestinationIndex, + iTunnelingType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::CopySettingsL - Copied the (general) settings table\n"))); + + // For the USER certificate db. + EapTlsPeapUtils::CopySettingsL( + db, + usercerts, + iIndexType, + iIndex, + iTunnelingType, + aDestinationIndexType, + aDestinationIndex, + iTunnelingType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::CopySettingsL - Copied the USER certs table\n"))); + + // For the CA certificate db. + EapTlsPeapUtils::CopySettingsL( + db, + cacerts, + iIndexType, + iIndex, + iTunnelingType, + aDestinationIndexType, + aDestinationIndex, + iTunnelingType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::CopySettingsL - Copied the CA certs table\n"))); + + // For the ciphersuites db. + EapTlsPeapUtils::CopySettingsL( + db, + ciphersuites, + iIndexType, + iIndex, + iTunnelingType, + aDestinationIndexType, + aDestinationIndex, + iTunnelingType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::CopySettingsL - Copied the Cipher suites table\n"))); + +#ifdef USE_FAST_EAP_TYPE + // This special settings is only for EAP-FAST + if(iEapType == eap_type_fast) + { + EapTlsPeapUtils::CopySettingsL( + db, + fastSpecialSettings, + iIndexType, + iIndex, + iTunnelingType, + aDestinationIndexType, + aDestinationIndex, + iTunnelingType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::CopySettingsL - Copied the EAP-FAST Special settings table\n"))); + + } // End: if(iEapType == eap_type_fast) + +#endif // End: #ifdef USE_FAST_EAP_TYPE + + db.Close(); + CleanupStack::PopAndDestroy(2); // db, session + + //////// Copy Encapsulated types + + // Operator == takes care of expanded EAP type conversion automatically. + if (iEapType == eap_type_peap + || iEapType == eap_type_ttls + +#ifdef USE_FAST_EAP_TYPE + || iEapType == eap_type_fast +#endif + + || iEapType == eap_type_ttls_plain_pap + + + ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::CopySettingsL - Copying encapsulated EAP types\n"))); + + iEapArray.ResetAndDestroy(); + REComSession::ListImplementationsL(KEapTypeInterfaceUid, iEapArray); + + for (TInt i = 0; i < iEapArray.Count(); i++) + { + if ((iEapType == eap_type_peap && !CEapType::IsDisallowedInsidePEAP(*iEapArray[i])) + || (iEapType == eap_type_ttls && !CEapType::IsDisallowedInsideTTLS(*iEapArray[i])) + +#ifdef USE_FAST_EAP_TYPE + || (iEapType == eap_type_fast && !CEapType::IsDisallowedInsidePEAP(*iEapArray[i])) +#endif + + || (iEapType == eap_type_ttls_plain_pap && !CEapType::IsDisallowedInsidePEAP(*iEapArray[i])) + + ) + { + // Copying the settings of encapsulated EAP type configurations possible inside PEAP and TTLS. + + CEapType* eapType; + +#ifdef USE_EAP_EXPANDED_TYPES + + TBuf8 expandedCue = iEapArray[i]->DataType(); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("CEapTlsPeap::CopySettingsL: Expanded cue:", + expandedCue.Ptr(), expandedCue.Size())); + + eapType = CEapType::NewL(expandedCue, iIndexType, iIndex); + + if(eapType == NULL) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeap::CopySettingsL: Ecom Error - No specified Expanded EAP plugin")) ); + User::Leave(KErrNotFound); + } + + eapType->SetTunnelingType(iEapType.get_vendor_type()); + +#else // For normal EAP types. + + TBuf8<3> cue = iEapArray[i]->DataType(); + + eapType = CEapType::NewL(cue, iIndexType, iIndex); + + eapType->SetTunnelingType(iEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + CleanupStack::PushL(eapType); + + eapType->CopySettingsL(aDestinationIndexType, aDestinationIndex); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::CopySettingsL - Copied the encapsulated settings\n"))); + + CleanupStack::PopAndDestroy(); + } + } + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::CopySettingsL - End \n"))); + +} + +#ifdef USE_PAC_STORE + +void CEapTlsPeap::UpdatePacStoreCleanupTableL(const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::UpdatePacStoreCleanupTableL: Start"))); + + CPacStoreDatabase * pacStoreDb = CPacStoreDatabase::NewL(); + User::LeaveIfNull(pacStoreDb); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::UpdatePacStoreCleanupTableL Created PAC store"))); + + pacStoreDb->OpenPacStoreL(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::UpdatePacStoreCleanupTableL Opened PAC store"))); + + pacStoreDb->AddACleanupReferenceEntryL(aIndexType, aIndex, aTunnelingType); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::UpdatePacStoreCleanupTableL: AddACleanupReferenceEntryL returns"))); + + pacStoreDb->Close(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::UpdatePacStoreCleanupTableL: pacStoreDb Closed"))); + + delete pacStoreDb; + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeap::UpdatePacStoreCleanupTableL: End"))); + User::Leave(KErrNone); +} + +#endif // #ifdef USE_PAC_STORE + +// End of file + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapCertFetcher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapCertFetcher.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,354 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 414 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES + +#include "EapTlsPeapCertFetcher.h" +#include +#include "eap_am_trace_symbian.h" + +#include +#include +#include + + +// ================= MEMBER FUNCTIONS ======================= + +CEapTlsPeapCertFetcher* CEapTlsPeapCertFetcher::NewL(CEapTlsPeapUiCertificates* const aParent) +{ + CEapTlsPeapCertFetcher* self = new(ELeave) CEapTlsPeapCertFetcher(aParent); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; +} + +//-------------------------------------------------- + +// DON'T USE THIS FUNCTION. THIS IS ONLY FOR EapTlsPeapUtils. +CEapTlsPeapCertFetcher* CEapTlsPeapCertFetcher::NewL() +{ + CEapTlsPeapCertFetcher* self = new(ELeave) CEapTlsPeapCertFetcher(); + CleanupStack::PushL(self); + + /************* THIS PART MAY NOT BE NEEDED AT ALL. NOT A GOOD IDEA TO INSTALL SCHEDULER HERE ****************/ + // Check if we are in a scheduler already. + CActiveScheduler* scheduler = NULL; + scheduler = CActiveScheduler::Current(); + + // There may not be a default scheduler if called from EapTlsPeapUtils for the first time. + // Hence need to add one. Otherwise no need to install another. + if( scheduler == NULL ) + { + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapCertFetcher::NewL -No default scheduler!!\n") ) ); + + scheduler = new (ELeave) CActiveScheduler(); + CActiveScheduler::Install(scheduler); + } + /*****************************/ + + self->ConstructL(); + CleanupStack::Pop(); + + return self; +} + +//-------------------------------------------------- + +CEapTlsPeapCertFetcher::CEapTlsPeapCertFetcher(CEapTlsPeapUiCertificates* const aParent) +: CActive(CActive::EPriorityStandard) +, iParent(aParent) +, iEncodedCertificate(0) +, iCertPtr(0,0) +{ +} + +//-------------------------------------------------- + +// DON'T USE THIS FUNCTION. THIS IS ONLY FOR EapTlsPeapUtils. +CEapTlsPeapCertFetcher::CEapTlsPeapCertFetcher() +: CActive(CActive::EPriorityStandard) +, iParent(NULL) +, iEncodedCertificate(0) +, iCertPtr(0,0) +{ +} + +//-------------------------------------------------- + +void CEapTlsPeapCertFetcher::ConstructL() +{ + User::LeaveIfError(iFs.Connect()); + + CActiveScheduler::Add(this); + + iEncodedCertificate = HBufC8::NewL(0); + iCertPtr.Set(iEncodedCertificate->Des()); + +} + +//-------------------------------------------------- + +CEapTlsPeapCertFetcher::~CEapTlsPeapCertFetcher() +{ + // Delete iCertInfos + for (TInt i = 0; i < iCertInfos.Count(); i++) + { + iCertInfos[i]->Release(); + } + iCertInfos.Reset(); + + iCACerts.Reset(); + + iUserCerts.Reset(); + + delete iCertFilter; + + delete iCertStore; + + delete iEncodedCertificate; + + iFs.Close(); + + if(IsActive()) + { + Cancel(); + } +} + +//-------------------------------------------------- + +void CEapTlsPeapCertFetcher::GetCertificatesL() +{ + iState = EGetCertificatesInitStore; + if (iCertStore == 0) + { + iCertStore = CUnifiedCertStore::NewL(iFs, false); + iCertStore->Initialize(iStatus); + } + else + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + SetActive(); +} + + +void CEapTlsPeapCertFetcher::DoCancel() +{ +} + +//-------------------------------------------------- + +void CEapTlsPeapCertFetcher::RunL() +{ + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapCertFetcher::RunL - iStatus.Int()=%d, iState=%d \n"), + iStatus.Int() , iState)); + if( iState == EGetSymbianSubjectKeyId ) + { + // Only for GetSymbianSubjectKeyIdL. + iWait.AsyncStop(); // This is needed to continue the execution after Wait.Start() + return; // No need to proceed further. + } + + if( iState == EGetCertificatesRetrieveCert) + { + // This is executed when certificate details are being retrieved. + iWait.AsyncStop(); // This is needed to continue the execution after Wait.Start() + return; // No need to proceed further. + } + + int i; + TInt err(KErrNone); + + // This causes panic if leaves + if (iStatus.Int() != KErrNone) + { +RDebug::Print(_L("CEapTlsPeapCertFetcher::RunL() -- don't leave...")); + } + + switch (iState) + { + case EGetCertificatesInitStore: + { + // Delete iCertInfos + for (TInt i = 0; i < iCertInfos.Count(); i++) + { + iCertInfos[i]->Release(); + } + iCertInfos.Reset(); + + delete iCertFilter; + iCertFilter = 0; + + TRAP(err, iCertFilter = CCertAttributeFilter::NewL()); + if (err != KErrNone) + { + // Complete with empty lists + TInt err(KErrNone); + TRAP(err, iParent->CompleteReadCertificatesL(iUserCerts, iCACerts)); + break; + } + iCertFilter->SetFormat(EX509Certificate); + + iState = EGetCertificatesGetCertList; + iCertStore->List( + iCertInfos, + *iCertFilter, + iStatus); + SetActive(); + } + break; + + case EGetCertificatesGetCertList: + { + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapCertFetcher::RunL - EGetCertificatesGetCertList - Symbian cert store found %d certs in device\n"), + iCertInfos.Count())); + + if(0 == iCertInfos.Count()) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("ERROR : CEapTlsPeapCertFetcher::RunL - SERIOUS PROBLEM - Symbian cert store couldn't find any certs in device\n"))); + } + + for (i = 0; i < iCertInfos.Count(); i++) + { + CCTCertInfo* CertInfo; + CertInfo = iCertInfos[i]; + iEncodedCertificate->Des().SetLength(0); + + TRAPD(err, iEncodedCertificate = iEncodedCertificate->ReAllocL(iCertInfos[i]->Size())); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("\nCEapTlsPeapCertFetcher::RunL() - EGetCertificatesGetCertList - leave from iEncodedCertificate->ReAllocL Error:%d\n"), err ) ); + } + iCertPtr.Set(iEncodedCertificate->Des()); + + EAP_TRACE_DEBUG_SYMBIAN((_L("\nCEapTlsPeapCertFetcher::RunL() - EGetCertificatesGetCertList - Retreiving cert %d\n"), i ) ); + + iCertStore->Retrieve( *CertInfo, iCertPtr, iStatus); + + iState = EGetCertificatesRetrieveCert; + + SetActive(); + iWait.Start(); + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapCertFetcher::RunL() - iWait.Start() returned, iStatus.Int()=%d \n"),iStatus.Int() ) ); + + CCertificate* cert = NULL; + + if ( iStatus.Int() == KErrNone ) + { + switch ( CertInfo->CertificateFormat() ) + { + case EX509Certificate: + { + TRAPD(err, cert = CX509Certificate::NewL( iCertPtr )); + if (err != KErrNone) + EAP_TRACE_DEBUG_SYMBIAN((_L("\nCEapTlsPeapCertFetcher::RunL() - EGetCertificatesGetCertList - leave from CX509Certificate::NewL Label:%S Error:%d\n"),&(CertInfo->Label()), err ) ); + break; + } + default: + { + // Only X509 type of certificates are supported at the moment. + // This won't be happening ever since we have used a filter while getting the certificate list. + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapCertFetcher::RunL() - Unsupported Certificate - Not X509\n") ) ); + + break; + } + } + } + else + { + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapCertFetcher::RunL() - Error from Certificate retrieve, iStatus.Int()=%d\n"), iStatus.Int() ) ); + } + + if( cert == NULL ) + { + // Some problem above. Skip the below and go for the next certificate. + continue; + } + + HBufC* pri = NULL; + HBufC* sec = NULL; + + CleanupStack::PushL( cert ); + + X509CertNameParser::PrimaryAndSecondaryNameL( *((CX509Certificate*)cert), pri, sec, CertInfo->Label()); + + CleanupStack::PopAndDestroy(); // cert + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapCertFetcher::RunL() - Label=%S, Pri name=%S,Length=%d, Sec name=%S,Length=%d\n"), + &(CertInfo->Label()), pri, pri->Length(), sec, sec->Length() ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "CEapTlsPeapCertFetcher::RunL() - Sub Key Id:", (CertInfo->SubjectKeyId().Ptr()), + (CertInfo->SubjectKeyId().Size()) ) ); + + SCertEntry certEntry; + + certEntry.iLabel.Copy(iCertInfos[i]->Label()); + certEntry.iSubjectKeyId.Copy(iCertInfos[i]->SubjectKeyId()); + + // Copy the new fields. Primary and secondary name. + certEntry.iPrimaryName.Copy( pri->Des().Left(KMaxNameLength ) ); + certEntry.iSecondaryName.Copy( sec->Des().Left(KMaxNameLength ) ); + + delete pri; + delete sec; + + if (iCertInfos[i]->CertificateOwnerType() == ECACertificate) + { + iCACerts.Append(certEntry); + } + else if (iCertInfos[i]->CertificateOwnerType() == EUserCertificate) + { + iUserCerts.Append(certEntry); + } + } + delete iCertFilter; + iCertFilter = 0; + + // Delete iCertInfos + for (TInt i = 0; i < iCertInfos.Count(); i++) + { + iCertInfos[i]->Release(); + } + iCertInfos.Reset(); + TRAP(err, iParent->CompleteReadCertificatesL(iUserCerts, iCACerts)); + // Ignore error on purpose. + } + break; + + default: + break; + } + return; +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapProxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapProxy.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 420 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include "EapTlsPeap.h" +#include +#include + +#include "EapolUID.h" + +const TImplementationProxy ImplementationTable[] = +{ + {{EAP_TLS_IMPLEMENTATION_UID}, reinterpret_cast (CEapTlsPeap::NewTlsL)}, + {{EAP_PEAP_IMPLEMENTATION_UID}, reinterpret_cast (CEapTlsPeap::NewPeapL)}, +#if defined(USE_TTLS_EAP_TYPE) + {{EAP_TTLS_IMPLEMENTATION_UID}, reinterpret_cast (CEapTlsPeap::NewTtlsL)} +#endif // #if defined(USE_TTLS_EAP_TYPE) +#if defined(USE_FAST_EAP_TYPE) + ,{{EAP_FAST_IMPLEMENTATION_UID}, reinterpret_cast (CEapTlsPeap::NewFastL)} +#endif // #if defined(USE_FAST_EAP_TYPE) + , + {{TTLS_PAP_IMPLEMENTATION_UID}, reinterpret_cast (CEapTlsPeap::NewTtlsPapL)} +}; + +// ================= OTHER EXPORTED FUNCTIONS ============== + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) +{ + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + + return ImplementationTable; +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiCertificates.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiCertificates.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,592 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 423 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include +#include "EapTlsPeapUtils.h" +#include "EapTlsPeapDbDefaults.h" +#include "EapTlsPeapDbParameterNames.h" +#include +#include +#include +#include "EapTlsPeapCertFetcher.h" +#include +#include "eap_am_trace_symbian.h" + +#include +#include + +const TUint KMaxSqlQueryLength = 256; +const TUint KCertArrayGranularity = 16; + +CEapTlsPeapUiCertificates::CEapTlsPeapUiCertificates( + CEapTlsPeapUiConnection * const aUiConn, + MEapTlsPeapUiCertificates * const aParent) +: iIsOpened(EFalse) +, iUiConn(aUiConn) +, iUserCerts(0) +, iCACerts(0) +, iParent(aParent) +{ +} + + +CEapTlsPeapUiCertificates::~CEapTlsPeapUiCertificates() +{ + if (iUiConn) + { + Close(); + iUiConn = NULL; + } +} + + +TInt CEapTlsPeapUiCertificates::Open() +{ + if (iIsOpened) + { + return KErrAlreadyExists; + } + + TInt err = iUiConn->GetDatabase(iDatabase); + if (err != KErrNone) + { + return err; + } + + TRAP(err, iCertFetcher = CEapTlsPeapCertFetcher::NewL(this)); + if (err != KErrNone) + { + return err; + } + + iIsOpened = ETrue; + + return KErrNone; +} + + +TInt CEapTlsPeapUiCertificates::Close() +{ + if (iIsOpened == EFalse) + { + return KErrNone; + } + + delete iUserCerts; + iUserCerts = 0; + + delete iCACerts; + iCACerts = 0; + + delete iCertFetcher; + iCertFetcher = 0; + + iUiConn = NULL; + return KErrNone; +} + +TInt CEapTlsPeapUiCertificates::GetCertificates(CArrayFixFlat ** aUserCerts, + CArrayFixFlat ** aCACerts) +{ + if (aUserCerts == NULL + || aCACerts == NULL) + { + return KErrArgument; + } + if (iIsOpened == EFalse) + { + return KErrSessionClosed; + } + if (iUserCerts == 0) + { + iUserCerts = new CArrayFixFlat(KCertArrayGranularity); + if (!iUserCerts) + { + return KErrNoMemory; + } + } + + *aUserCerts = iUserCerts; + + if (iCACerts == 0) + { + iCACerts = new CArrayFixFlat(KCertArrayGranularity); + if (!iUserCerts) + { + return KErrNoMemory; + } + } + *aCACerts = iCACerts; + + TRAPD(err, iCertFetcher->GetCertificatesL()); + + return err; +} + + +void CEapTlsPeapUiCertificates::CompleteReadCertificatesL( + const RArray& aAvailableUserCerts, + const RArray& aAvailableCACerts) +{ + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::CompleteReadCertificatesL - Available cert count in device - USER=%d, CA=%d \n"), + aAvailableUserCerts.Count(), aAvailableCACerts.Count())); + + // Now all available certificates have been read. + // Get the allowed certs from the database and set their iIsEnabled flag -> ETrue. + TInt err(KErrNone); + if (iUiConn->GetEapType() == eap_type_tls) + { + TRAP(err, FetchDataL(KTlsAllowedUserCertsDatabaseTableName, aAvailableUserCerts, iUserCerts)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::CompleteReadCertificatesL -TLS- USER cert - LEAVE from FetchDataL err=%d\n"), + err)); + + iParent->CompleteReadCertificates(err); + return; + } + TRAP(err, FetchDataL(KTlsAllowedCACertsDatabaseTableName, aAvailableCACerts, iCACerts)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::CompleteReadCertificatesL -TLS- CA cert - LEAVE from FetchDataL err=%d\n"), + err)); + + iParent->CompleteReadCertificates(err); + return; + } + + } + else if (iUiConn->GetEapType() == eap_type_peap) + { + + TRAP(err, FetchDataL(KPeapAllowedUserCertsDatabaseTableName, aAvailableUserCerts, iUserCerts)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::CompleteReadCertificatesL -PEAP- USER cert - LEAVE from FetchDataL err=%d\n"), + err)); + + iParent->CompleteReadCertificates(err); + return; + } + TRAP(err, FetchDataL(KPeapAllowedCACertsDatabaseTableName, aAvailableCACerts, iCACerts)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::CompleteReadCertificatesL -PEAP- CA cert - LEAVE from FetchDataL err=%d\n"), + err)); + + iParent->CompleteReadCertificates(err); + return; + } + } + else if (iUiConn->GetEapType() == eap_type_ttls || iUiConn->GetEapType() == eap_type_ttls_plain_pap) + { + + TRAP(err, FetchDataL(KTtlsAllowedUserCertsDatabaseTableName, aAvailableUserCerts, iUserCerts)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L( + "CEapTlsPeapUiCertificates::CompleteReadCertificatesL -TTLS- USER cert - LEAVE from FetchDataL err=%d\n"), + err)); + + iParent->CompleteReadCertificates(err); + return; + } + TRAP(err, FetchDataL(KTtlsAllowedCACertsDatabaseTableName, aAvailableCACerts, iCACerts)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L( + "CEapTlsPeapUiCertificates::CompleteReadCertificatesL -TTLS- CA cert - LEAVE from FetchDataL err=%d\n"), + err)); + + iParent->CompleteReadCertificates(err); + return; + } + } + +#ifdef USE_FAST_EAP_TYPE + else if (iUiConn->GetEapType() == eap_type_fast) + { + + TRAP(err, FetchDataL(KFastAllowedUserCertsDatabaseTableName, aAvailableUserCerts, iUserCerts)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L( + "CEapTlsPeapUiCertificates::CompleteReadCertificatesL -FAST- USER cert - LEAVE from FetchDataL err=%d\n"), + err)); + + iParent->CompleteReadCertificates(err); + return; + } + TRAP(err, FetchDataL(KFastAllowedCACertsDatabaseTableName, aAvailableCACerts, iCACerts)); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L( + "CEapTlsPeapUiCertificates::CompleteReadCertificatesL -FAST- CA cert - LEAVE from FetchDataL err=%d\n"), + err)); + + iParent->CompleteReadCertificates(err); + return; + } + } +#endif //#ifdef USE_FAST_EAP_TYPE + + else + { + iParent->CompleteReadCertificates(KErrNotSupported); + return; + } + + // Operation was successful + iParent->CompleteReadCertificates(KErrNone); +} + +void CEapTlsPeapUiCertificates::FetchDataL( + const TDesC& aTableName, + const RArray& aAvailableCerts, + CArrayFixFlat* const aArray) +{ + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::FetchDataL - Fetching & comparing cert details from table:%S\n"), + &aTableName)); + + aArray->Reset(); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Form the query. Query everything. + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQLQuery, + &aTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + TEapTlsPeapUiCertificate tmp; + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::FetchDataL - Available certs=%d\n"), + aAvailableCerts.Count())); + + // Loop through available certs + TInt i(0); + for (i = 0; i < aAvailableCerts.Count(); i++) + { + SCertEntry cert = aAvailableCerts[i]; + + tmp.iCertEntry = cert; + tmp.iIsEnabled = EFalse; + + // Try to find the cert from the database rows + if (view.FirstL()) + { + do + { + view.GetL(); + if ((view.ColDes(colSet->ColNo(KCertLabel)) == cert.iLabel + || view.IsColNull(colSet->ColNo(KCertLabel))) + && view.ColDes8(colSet->ColNo(KSubjectKeyIdentifier)) == cert.iSubjectKeyId) + { + tmp.iIsEnabled = ETrue; + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::FetchDataL - Reading certificate details from the DB - Label=%S \n"), + &(cert.iLabel) ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "Subject Key Id:", cert.iSubjectKeyId.Ptr(), + cert.iSubjectKeyId.Size() ) ); + break; + } + } while (view.NextL() != EFalse); + } + + aArray->AppendL(tmp); + } + CleanupStack::PopAndDestroy(); // colset + CleanupStack::PopAndDestroy(); // view + CleanupStack::PopAndDestroy(buf); +} + +TInt CEapTlsPeapUiCertificates::Update() +{ + TRAPD(err, UpdateL()); + + if(KErrNone != err) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::Update - UpdateL LEAVES with error =%d \n"), + err)); + } + + return err; +} + + +void CEapTlsPeapUiCertificates::UpdateL() +{ + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // USER CERTIFICATES + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + if (iUiConn->GetEapType() == eap_type_tls) + { + sqlStatement.Format( + KSQL, + &KTlsAllowedUserCertsDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + else if (iUiConn->GetEapType() == eap_type_peap) + { + sqlStatement.Format( + KSQL, + &KPeapAllowedUserCertsDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + else if (iUiConn->GetEapType() == eap_type_ttls || iUiConn->GetEapType() == eap_type_ttls_plain_pap) + { + sqlStatement.Format( + KSQL, + &KTtlsAllowedUserCertsDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + +#ifdef USE_FAST_EAP_TYPE + else if (iUiConn->GetEapType() == eap_type_fast) + { + sqlStatement.Format( + KSQL, + &KFastAllowedUserCertsDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } +#endif //#ifdef USE_FAST_EAP_TYPE + + RDbView view; + User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + CDbColSet* colSet; + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Delete old rows + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::UpdateL - About to update cert details in the DB - User cert count=%d \n"), + iUserCerts->Count())); + + TInt i(0); + for (i = 0; i < iUserCerts->Count(); i++) + { + if ((*iUserCerts)[i].iIsEnabled) + { + // Validate data lengths. + if((*iUserCerts)[i].iCertEntry.iLabel.Length() > KMaxCertLabelLengthInDB + || (*iUserCerts)[i].iCertEntry.iSubjectKeyId.Length() > KMaxSubjectKeyIdLengthInDB) + { + // Too long data. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::UpdateL: User : Too long Label or SubjectKeyId. Length: Label=%d, SubjectKeyId=%d \n"), + (*iUserCerts)[i].iCertEntry.iLabel.Length(), (*iUserCerts)[i].iCertEntry.iSubjectKeyId.Length())); + + User::Leave(KErrArgument); + } + + view.InsertL(); + // Set the default values. The other three tables (certs, ca certs & cipher suites) are empty by default. + view.SetColL(colSet->ColNo(KServiceType), static_cast(iUiConn->GetIndexType())); + view.SetColL(colSet->ColNo(KServiceIndex), static_cast(iUiConn->GetIndex())); + view.SetColL(colSet->ColNo(KTunnelingType), static_cast(iUiConn->GetTunnelingType())); + view.SetColL(colSet->ColNo(KCertLabel), (*iUserCerts)[i].iCertEntry.iLabel); + view.SetColL(colSet->ColNo(KSubjectKeyIdentifier), (*iUserCerts)[i].iCertEntry.iSubjectKeyId); + view.SetColL(colSet->ColNo(KActualSubjectKeyIdentifier), (*iUserCerts)[i].iCertEntry.iSubjectKeyId); + view.PutL(); + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::UpdateL - Wrote User cert details to the DB - Label=%S \n"), + &((*iUserCerts)[i].iCertEntry.iLabel) ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "Subject Key Id:", (*iUserCerts)[i].iCertEntry.iSubjectKeyId.Ptr(), + (*iUserCerts)[i].iCertEntry.iSubjectKeyId.Size() ) ); + } + } + + CleanupStack::PopAndDestroy(colSet); + CleanupStack::PopAndDestroy(); // view + + // CA CERTIFICATES + _LIT(KSQL2, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + if (iUiConn->GetEapType() == eap_type_tls) + { + sqlStatement.Format( + KSQL2, + &KTlsAllowedCACertsDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + else if (iUiConn->GetEapType() == eap_type_peap) + { + sqlStatement.Format( + KSQL2, + &KPeapAllowedCACertsDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + else if (iUiConn->GetEapType() == eap_type_ttls || iUiConn->GetEapType() == eap_type_ttls_plain_pap) + { + sqlStatement.Format( + KSQL2, + &KTtlsAllowedCACertsDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + +#ifdef USE_FAST_EAP_TYPE + else if (iUiConn->GetEapType() == eap_type_fast) + { + sqlStatement.Format( + KSQL2, + &KFastAllowedCACertsDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } +#endif // #ifdef USE_FAST_EAP_TYPE + + User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Delete old rows + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::UpdateL - About to update cert details in the DB - CA cert count=%d \n"), + iCACerts->Count())); + + for (i = 0; i < iCACerts->Count(); i++) + { + if ((*iCACerts)[i].iIsEnabled) + { + // Validate data lengths. + if((*iCACerts)[i].iCertEntry.iLabel.Length() > KMaxCertLabelLengthInDB + || (*iCACerts)[i].iCertEntry.iSubjectKeyId.Length() > KMaxSubjectKeyIdLengthInDB) + { + // Too long data. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::UpdateL: CA : Too long Label or SubjectKeyId. Length: Label=%d, SubjectKeyId=%d \n"), + (*iCACerts)[i].iCertEntry.iLabel.Length(), (*iCACerts)[i].iCertEntry.iSubjectKeyId.Length())); + + User::Leave(KErrArgument); + } + + view.InsertL(); + // Set the default values. The other three tables (certs, ca certs & cipher suites) are empty by default. + view.SetColL(colSet->ColNo(KServiceType), static_cast(iUiConn->GetIndexType())); + view.SetColL(colSet->ColNo(KServiceIndex), static_cast(iUiConn->GetIndex())); + view.SetColL(colSet->ColNo(KTunnelingType), static_cast(iUiConn->GetTunnelingType())); + view.SetColL(colSet->ColNo(KCertLabel), (*iCACerts)[i].iCertEntry.iLabel); + view.SetColL(colSet->ColNo(KSubjectKeyIdentifier), (*iCACerts)[i].iCertEntry.iSubjectKeyId); + view.SetColL(colSet->ColNo(KActualSubjectKeyIdentifier), (*iCACerts)[i].iCertEntry.iSubjectKeyId); + view.PutL(); + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiCertificates::UpdateL - Wrote CA cert details to the DB - Label=%S \n"), + &((*iCACerts)[i].iCertEntry.iLabel) ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "Subject Key Id:", (*iCACerts)[i].iCertEntry.iSubjectKeyId.Ptr(), + (*iCACerts)[i].iCertEntry.iSubjectKeyId.Size() ) ); + } + } + CleanupStack::PopAndDestroy(colSet); + CleanupStack::PopAndDestroy(); // view + + CleanupStack::PopAndDestroy(buf); +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiCipherSuites.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiCipherSuites.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,348 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 426 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include +#include "EapTlsPeapUtils.h" +#include "EapTlsPeapDbParameterNames.h" +#include "EapTlsPeapDbDefaults.h" +#include +#include +#include + +const TUint KMaxSqlQueryLength = 256; + +CEapTlsPeapUiCipherSuites::CEapTlsPeapUiCipherSuites(CEapTlsPeapUiConnection * const aUiConn) +: iIsOpened(EFalse) +, iUiConn(aUiConn) +, iDataPtr(NULL) +{ +} + + +CEapTlsPeapUiCipherSuites::~CEapTlsPeapUiCipherSuites() +{ + if (iUiConn) + { + Close(); + iUiConn = NULL; + } +} + + +TInt CEapTlsPeapUiCipherSuites::Open() +{ + if (iIsOpened) + { + return KErrAlreadyExists; + } + + TInt err = iUiConn->GetDatabase(iDatabase); + if (err != KErrNone) + { + return err; + } + + iIsOpened = ETrue; + + return KErrNone; +} + + +TInt CEapTlsPeapUiCipherSuites::GetCipherSuites(CArrayFixFlat ** aDataPtr) +{ + if (aDataPtr == NULL) + { + return KErrArgument; + } + if (iIsOpened == EFalse) + { + return KErrSessionClosed; + } + + if (iDataPtr != 0) + { + *aDataPtr = iDataPtr; + return KErrNone; + } + iDataPtr = new CArrayFixFlat(8); + if (!iDataPtr) + { + return KErrNoMemory; + } + + TInt i(0); + while (available_cipher_suites[i] != 0) + { + TEapTlsPeapUiCipherSuite tmp; + tmp.iCipherSuite = available_cipher_suites[i]; + tmp.iIsEnabled = EFalse; + + TRAPD(err, iDataPtr->AppendL(tmp)); + if (err != KErrNone) + { + return err; + } + + i++; + } + + + + TRAPD(err, FetchDataL()); + + if (err != KErrNone) + { + delete iDataPtr; + return err; + } + + *aDataPtr = iDataPtr; + + return KErrNone; +} + + +TInt CEapTlsPeapUiCipherSuites::Update() +{ + TRAPD(err, UpdateL()); + return err; +} + +void CEapTlsPeapUiCipherSuites::UpdateL() +{ + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Form the query. Query everything. + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + if (iUiConn->GetEapType() == eap_type_tls) + { + sqlStatement.Format(KSQLQuery, + &KTlsAllowedCipherSuitesDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + else if (iUiConn->GetEapType() == eap_type_peap) + { + sqlStatement.Format(KSQLQuery, + &KPeapAllowedCipherSuitesDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + else if (iUiConn->GetEapType() == eap_type_ttls || iUiConn->GetEapType() == eap_type_ttls_plain_pap) + { + sqlStatement.Format(KSQLQuery, + &KTtlsAllowedCipherSuitesDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + +#ifdef USE_FAST_EAP_TYPE + else if (iUiConn->GetEapType() == eap_type_fast) + { + sqlStatement.Format(KSQLQuery, + &KFastAllowedCipherSuitesDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } +#endif //#ifdef USE_FAST_EAP_TYPE + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Delete old rows + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + TInt i(0); + + for (i = 0; i < iDataPtr->Count(); i++) + { + if (iDataPtr->At(i).iIsEnabled) + { + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast(iUiConn->GetIndexType())); + view.SetColL(colSet->ColNo(KServiceIndex), static_cast(iUiConn->GetIndex())); + view.SetColL(colSet->ColNo(KTunnelingType), static_cast(iUiConn->GetTunnelingType())); + view.SetColL(colSet->ColNo(KCipherSuite), static_cast(iDataPtr->At(i).iCipherSuite)); + view.PutL(); + } + } + CleanupStack::PopAndDestroy(colSet); + CleanupStack::PopAndDestroy(); // view + CleanupStack::PopAndDestroy(buf); +} + +TInt CEapTlsPeapUiCipherSuites::Close() +{ + if (iIsOpened == EFalse) + { + return KErrNone; + } + + delete iDataPtr; + iDataPtr = 0; + + iUiConn = NULL; + return KErrNone; +} + + +void CEapTlsPeapUiCipherSuites::FetchDataL() +{ + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Form the query. Query everything. + _LIT(KSQLQuery, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + if (iUiConn->GetEapType() == eap_type_tls) + { + sqlStatement.Format(KSQLQuery, + &KCipherSuite, + &KTlsAllowedCipherSuitesDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + else if (iUiConn->GetEapType() == eap_type_peap) + { + sqlStatement.Format(KSQLQuery, + &KCipherSuite, + &KPeapAllowedCipherSuitesDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + else if (iUiConn->GetEapType() == eap_type_ttls || iUiConn->GetEapType() == eap_type_ttls_plain_pap) + { + sqlStatement.Format(KSQLQuery, + &KCipherSuite, + &KTtlsAllowedCipherSuitesDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + +#ifdef USE_FAST_EAP_TYPE + else if (iUiConn->GetEapType() == eap_type_fast) + { + sqlStatement.Format(KSQLQuery, + &KCipherSuite, + &KFastAllowedCipherSuitesDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } +#endif //#ifdef USE_FAST_EAP_TYPE + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(sqlStatement))); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + if (view.FirstL()) + { + do { + view.GetL(); + + switch (view.ColType(colSet->ColNo(KCipherSuite))) + { + case EDbColUint32: + { + // Find the corresponding cipher suite in the list + TInt j(0); + TUint id = view.ColUint(colSet->ColNo(KCipherSuite)); + for (j = 0; j < iDataPtr->Count(); j++) + { + if (iDataPtr->At(j).iCipherSuite == id) + { + iDataPtr->At(j).iIsEnabled = ETrue; + break; + } + } + } + break; + default: + User::Leave(KErrArgument); + } + } while (view.NextL() != EFalse); + } + + CleanupStack::PopAndDestroy(colSet); + + CleanupStack::PopAndDestroy(); // view + CleanupStack::PopAndDestroy(buf); +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiConnection.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,428 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 428 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include "EapTlsPeapUtils.h" +#include +#include +#include +#include +#include +#include +#include "eap_am_trace_symbian.h" + +#ifdef USE_PAC_STORE +#include "pac_store_db_symbian.h" +#endif + +CEapTlsPeapUiConnection::CEapTlsPeapUiConnection( + const TIndexType aIndexType, + const TInt aIndex, + const TInt aTunnelingType, + const TInt aEapType) + : iIndexType(aIndexType) + , iIndex(aIndex) + , iTunnelingType(aTunnelingType) + , iEapType(aEapType) + , iIsConnected(EFalse) + , iDataConn(NULL) + , iCipherSuites(NULL) + , iEapTypes(NULL) + , iCertificates(NULL) + , iPacStoreDb(NULL) +{ +} + + +CEapTlsPeapUiConnection::~CEapTlsPeapUiConnection() +{ +#ifdef USE_PAC_STORE + delete iPacStoreDb; +#endif +} + +TInt CEapTlsPeapUiConnection::Connect() +{ + if(iIsConnected) + { + // Already connected. + return KErrNone; + } + + TRAPD(err, ConnectL()); + if(err == KErrNone) + { + iIsConnected = ETrue; + } + + return err; +} + +void CEapTlsPeapUiConnection::ConnectL() +{ +#ifdef USE_EAP_EXPANDED_TYPES + + eap_type_value_e tunnelingType(static_cast(iTunnelingType)); + eap_type_value_e eapType(static_cast(iEapType)); + +#else + + eap_type_value_e tunnelingType = static_cast(iTunnelingType); + eap_type_value_e eapType = static_cast(iEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + +#ifdef USE_PAC_STORE +#ifdef USE_FAST_EAP_TYPE + + if(iEapType == eap_type_fast && iPacStoreDb == NULL) + { + iPacStoreDb = CPacStoreDatabase::NewL(); + User::LeaveIfNull(iPacStoreDb); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiConnection::Connect Created PAC store"))); + + iPacStoreDb->OpenPacStoreL(); + iPacStoreDb->CreateDeviceSeed( NULL ); + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiConnection::Connect Opened PAC store"))); + } + +#endif // End: #ifdef USE_FAST_EAP_TYPE +#endif // End: #ifdef USE_PAC_STORE + + // Open or create the databse where all the settings are stored. + EapTlsPeapUtils::OpenDatabaseL( + iDbNamedDatabase, + iDbs, + iIndexType, + iIndex, + tunnelingType, + eapType); +} + + +TInt CEapTlsPeapUiConnection::Close() +{ + if (iIsConnected) + { + +#ifdef USE_PAC_STORE + +#ifdef USE_FAST_EAP_TYPE + + if(iEapType == eap_type_fast && iPacStoreDb != NULL) + { + iPacStoreDb->Close(); + } +#endif // End: #ifdef USE_FAST_EAP_TYPE + +#endif // End: #ifdef USE_PAC_STORE + + iDbNamedDatabase.Close(); + + iDbs.Close(); // Both the Dbs are closed and server can be closed now. + } + + iIsConnected = EFalse; + + return KErrNone; +} + + +CEapTlsPeapUiDataConnection * CEapTlsPeapUiConnection::GetDataConnection() +{ + if (!iDataConn) + { + iDataConn = new CEapTlsPeapUiDataConnection(this); + } + + return iDataConn; +} + + +CEapTlsPeapUiCipherSuites * CEapTlsPeapUiConnection::GetCipherSuiteConnection() +{ + if (!iCipherSuites) + { + iCipherSuites = new CEapTlsPeapUiCipherSuites(this); + } + + return iCipherSuites; +} + + +CEapTlsPeapUiCertificates * CEapTlsPeapUiConnection::GetCertificateConnection(MEapTlsPeapUiCertificates * const aParent) +{ + if (!iCertificates) + { + iCertificates = new CEapTlsPeapUiCertificates(this, aParent); + } + + return iCertificates; +} + + +CEapTlsPeapUiEapTypes * CEapTlsPeapUiConnection::GetEapTypeConnection() +{ + if (!iEapTypes) + { + iEapTypes = new CEapTlsPeapUiEapTypes(this); + } + + return iEapTypes; +} + + +TInt CEapTlsPeapUiConnection::GetDatabase(RDbNamedDatabase & aDatabase) +{ + if (iIsConnected == EFalse) + { + return KErrSessionClosed; + } + + aDatabase = iDbNamedDatabase; + return KErrNone; +} + + +TIndexType CEapTlsPeapUiConnection::GetIndexType() +{ + return iIndexType; +} + + +TInt CEapTlsPeapUiConnection::GetIndex() +{ + return iIndex; +} + +TInt CEapTlsPeapUiConnection::GetTunnelingType() +{ + return iTunnelingType; +} + +TInt CEapTlsPeapUiConnection::GetEapType() +{ + return iEapType; +} + + +TBool CEapTlsPeapUiConnection::IsPacStoreMasterKeyPresentL() +{ + TBool status(EFalse); + +#ifdef USE_FAST_EAP_TYPE + + if(iEapType == eap_type_fast) + { + if (iIsConnected == EFalse) + { + User::Leave(KErrSessionClosed); + } + + status = iPacStoreDb->IsMasterKeyPresentL(); + + if (status) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiConnection::IsPacStoreMasterKeyPresentL Master key present! \n"))); + } + + return status; + } + else +#endif // End: #ifdef USE_FAST_EAP_TYPE + { + User::Leave(KErrNotSupported); + } + + return status; +} + +TInt CEapTlsPeapUiConnection::DestroyPacStore() +{ +#ifdef USE_FAST_EAP_TYPE + + if(iEapType == eap_type_fast) + { + if (iIsConnected == EFalse) + { + return KErrSessionClosed; + } + + TInt error = iPacStoreDb->DestroyPacStore(); + + return error; + } + else +#endif // End: #ifdef USE_FAST_EAP_TYPE + { + return KErrNotSupported; + } +} + +TBool CEapTlsPeapUiConnection::VerifyPacStorePasswordL( + const TDesC& aPacStorePw) +{ + if(aPacStorePw.Size() <= 0) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiConnection::VerifyPacStorePasswordL: PAC store PW can not be EMPTY!"))); + + User::Leave(KErrArgument); + } + + TBool status(EFalse); + +#ifdef USE_FAST_EAP_TYPE + + if(iEapType == eap_type_fast) + { + if (iIsConnected == EFalse) + { + User::Leave(KErrSessionClosed); + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("CEapTlsPeapUiConnection::VerifyPacStorePasswordL:PW from caller (16bits)", + aPacStorePw.Ptr(), + aPacStorePw.Size())); + + HBufC8* pacStorePWBuf8 = HBufC8::NewLC(aPacStorePw.Size()); + TPtr8 pacStorePWPtr8 = pacStorePWBuf8->Des(); + pacStorePWPtr8.Copy(aPacStorePw); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("CEapTlsPeapUiConnection::VerifyPacStorePasswordL:PW used for masterkey verification (8bits)", + pacStorePWPtr8.Ptr(), + pacStorePWPtr8.Size())); + + status = iPacStoreDb->IsMasterKeyAndPasswordMatchingL(pacStorePWPtr8); + + CleanupStack::PopAndDestroy(pacStorePWBuf8); + + if (status) + { + // Password and master key are matching. + // Means, This is the password used to create the master key. + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiConnection::VerifyPacStorePasswordL PAC store PW verified OK (true) \n"))); + } + } + else +#endif // End: #ifdef USE_FAST_EAP_TYPE + { + User::Leave(KErrNotSupported); + } + + return status; +} + +TInt CEapTlsPeapUiConnection::CreatePacStoreMasterKey( + const TDesC& aPacStorePw) +{ + if(aPacStorePw.Size() <= 0) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiConnection::CreatePacStoreMasterKey PAC store PW can not be EMPTY!"))); + + return KErrArgument; + } + +#ifdef USE_FAST_EAP_TYPE + + if(iEapType == eap_type_fast) + { + if (iIsConnected == EFalse) + { + return KErrSessionClosed; + } + + TInt creationStatus(KErrNone); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("CEapTlsPeapUiConnection::CreatePacStoreMasterKey:PW from caller (16bits)", + aPacStorePw.Ptr(), + aPacStorePw.Size())); + + HBufC8* pacStorePWBuf8 = NULL; + TRAPD(err, pacStorePWBuf8 = HBufC8::NewL(aPacStorePw.Size())); + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiConnection::CreatePacStoreMasterKey:Allocation failed\n"))); + return KErrNoMemory; + } + + TPtr8 pacStorePWPtr8 = pacStorePWBuf8->Des(); + pacStorePWPtr8.Copy(aPacStorePw); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("CEapTlsPeapUiConnection::CreatePacStoreMasterKey:PW used for masterkey creation (8bits)", + pacStorePWPtr8.Ptr(), + pacStorePWPtr8.Size())); + + TRAPD(err1, creationStatus = iPacStoreDb->CreateAndSaveMasterKeyL(pacStorePWPtr8)); + + delete pacStorePWBuf8; + + if(err1 != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiConnection::CreatePacStoreMasterKey:Creation failed %d\n"), err1)); + } + + if (creationStatus == KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiConnection::CreatePacStoreMasterKey Master key created OK\n"))); + } + return creationStatus; + } + else +#endif // End: #ifdef USE_FAST_EAP_TYPE + { + return KErrNotSupported; + } +} + +CPacStoreDatabase * CEapTlsPeapUiConnection::GetPacStoreDb() +{ +#ifdef USE_FAST_EAP_TYPE + + if(iEapType == eap_type_fast) + { + return iPacStoreDb; + } + else +#endif // End: #ifdef USE_FAST_EAP_TYPE + { + return NULL; + } +} + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiDataConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiDataConnection.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,828 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 430 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include +#include "EapTlsPeapUtils.h" +#include "EapTlsPeapDbParameterNames.h" +#include "EapTlsPeapDbDefaults.h" +#include +#include +#include +#include "eap_am_trace_symbian.h" + +#ifdef USE_PAC_STORE +#include "pac_store_db_symbian.h" +#endif + +const TUint KMaxSqlQueryLength = 256; + +// --------------------------------------------------------- +// CEapTlsPeapUiDataConnection::CEapTlsPeapUiDataConnection() +// --------------------------------------------------------- +// +CEapTlsPeapUiDataConnection::CEapTlsPeapUiDataConnection(CEapTlsPeapUiConnection * aUiConn) +: iIsOpened(EFalse) +, iUiConn(aUiConn) +, iColSet(NULL) +, iDataPtr(NULL) +, iFastSpecificColSet(NULL) +{ +} + + +// --------------------------------------------------------- +// CEapTlsPeapUiDataConnection::~CEapTlsPeapUiDataConnection() +// --------------------------------------------------------- +// +CEapTlsPeapUiDataConnection::~CEapTlsPeapUiDataConnection() +{ + if (iUiConn) + { + Close(); + iUiConn = NULL; + } +} + + +// --------------------------------------------------------- +// CEapTlsPeapUiDataConnection::Open() +// --------------------------------------------------------- +// +TInt CEapTlsPeapUiDataConnection::Open() +{ + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiDataConnection::Open: Start EAP-Type=%d\n"), + iUiConn->GetEapType())); + + if (iIsOpened) + { + return KErrAlreadyExists; + } + + TInt err = iUiConn->GetDatabase(iDatabase); + if (err != KErrNone) + { + return err; + } + + iIsOpened = ETrue; + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiDataConnection::Open: End\n"))); + + return KErrNone; +} + + +// --------------------------------------------------------- +// CEapTlsPeapUiDataConnection::GetData() +// --------------------------------------------------------- +// +TInt CEapTlsPeapUiDataConnection::GetData(CEapTlsPeapUiTlsPeapData ** aDataPtr) +{ + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiDataConnection::GetData: Start EAP-Type=%d\n"), + iUiConn->GetEapType())); + + if (aDataPtr == NULL) + { + return KErrArgument; + } + + if (iIsOpened == EFalse) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiDataConnection::GetData: Data Connection not opened\n"))); + + return KErrSessionClosed; + } + + if (iDataPtr != 0) + { + *aDataPtr = iDataPtr; + return KErrNone; + } + + iDataPtr = new CEapTlsPeapUiTlsPeapData(); + if (!iDataPtr) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiDataConnection::GetData: ERROR: NO MEMORY!\n"))); + + return KErrNoMemory; + } + + TRAPD(err, FetchDataL()); + if (err != KErrNone) + { + delete iDataPtr; + iDataPtr = NULL; + + delete iColSet; + iColSet = NULL; + + delete iFastSpecificColSet; + iFastSpecificColSet = NULL; + + iView.Close(); + iFastSpecificView.Close(); + + return err; + } + + *aDataPtr = iDataPtr; + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiDataConnection::GetData: End\n"))); + + return KErrNone; +} // CEapTlsPeapUiDataConnection::GetData() + + +// --------------------------------------------------------- +// CEapTlsPeapUiDataConnection::Update() +// --------------------------------------------------------- +// +TInt CEapTlsPeapUiDataConnection::Update() +{ + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiDataConnection::Update: Start EAP-Type=%d\n"), + iUiConn->GetEapType())); + + // Do the length checks first. + // Check if length of username and realm are less than the max length possible in DB. + if(iDataPtr->GetManualUsername().Length() > KMaxManualUsernameLengthInDB + || iDataPtr->GetManualRealm().Length() > KMaxManualRealmLengthInDB) + { + // Username or realm too long. Can not be stored in DB. + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiDataConnection::Update: Too long username or realm. Length: UN=%d, Realm=%d\n"), + iDataPtr->GetManualUsername().Length(), + iDataPtr->GetManualRealm().Length())); + + return KErrOverflow; + } + +#ifdef USE_FAST_EAP_TYPE + // Check the length of PAC store password. + + if(iDataPtr->GetPacStorePassword().Size() > KMaxPasswordLengthInDB) + { + // PAC store password too long. Can not be stored in DB. + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiDataConnection::Update: Too long PAC store PW. Size:%d\n"), + iDataPtr->GetPacStorePassword().Size())); + + return KErrOverflow; + } + +#endif + + TRAPD(err, UpdateDataL()); + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiDataConnection::Update: End, err=%d\n"), + err)); + + return err; +} // CEapTlsPeapUiDataConnection::Update() + + +// --------------------------------------------------------- +// CEapTlsPeapUiDataConnection::Close() +// --------------------------------------------------------- +// +TInt CEapTlsPeapUiDataConnection::Close() +{ + if (iIsOpened == EFalse) + { + return KErrNone; + } + + delete iDataPtr; + iDataPtr = NULL; + + delete iColSet; + iColSet = NULL; + + delete iFastSpecificColSet; + iFastSpecificColSet = NULL; + + iView.Close(); + + iFastSpecificView.Close(); + + iUiConn = NULL; + + return KErrNone; +} // CEapTlsPeapUiDataConnection::Close() + + +// --------------------------------------------------------- +// CEapTlsPeapUiDataConnection::FetchDataL() +// --------------------------------------------------------- +// +void CEapTlsPeapUiDataConnection::FetchDataL() +{ + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiDataConnection::FetchDataL: Start EAP-Type=%d\n"), + iUiConn->GetEapType())); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Form the general query for TLS, PEAP, TTLS and FAST. Query everything. + _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + if (iUiConn->GetEapType() == eap_type_tls) + { + sqlStatement.Format(KSQLQuery, + &KTlsDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + else if (iUiConn->GetEapType() == eap_type_peap) + { + sqlStatement.Format(KSQLQuery, + &KPeapDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + else if (iUiConn->GetEapType() == eap_type_ttls || iUiConn->GetEapType() == eap_type_ttls_plain_pap) + { + sqlStatement.Format(KSQLQuery, + &KTtlsDatabaseTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } + +#ifdef USE_FAST_EAP_TYPE + else if (iUiConn->GetEapType() == eap_type_fast) + { + // Unlike other EAP types, EAP-FAST has two settings tables. + // General settings and special settings + + // This is for the General settings. The special settings are read below. + + sqlStatement.Format(KSQLQuery, + &KFastGeneralSettingsDBTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + } +#endif + else + { + // Unknown EAP type + EAP_TRACE_DEBUG_SYMBIAN((_L("EAP-Type=%d - ERROR: Unknown EAP type!\n"), + iUiConn->GetEapType())); + + User::Leave(KErrNotSupported); + } + + // Evaluate view + User::LeaveIfError(iView.Prepare(iDatabase, TDbQuery(sqlStatement))); + User::LeaveIfError(iView.EvaluateAll()); + + // Get the first (and only) row + iView.FirstL(); + iView.GetL(); + + // Get column set so we get the correct column numbers + delete iColSet; + iColSet = NULL; + iColSet = iView.ColSetL(); + + // Start fetching the values + + + /**************** only for TTLS PAP ****************/ + + if ( iUiConn->GetEapType() == eap_type_ttls_plain_pap ) + { + // Prompt password + TUint intValue = iView.ColUint( iColSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal ) ); + if ( intValue == 0 ) + { + *( iDataPtr->GetPapPasswordPrompt() ) = EFalse; + } + else + { + *( iDataPtr->GetPapPasswordPrompt() ) = ETrue; + } + + // username + iDataPtr->GetPapUserName().Copy( iView.ColDes16( iColSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_username_literal ) ) ); + + // password + iDataPtr->GetPapPassword().Copy( iView.ColDes16( iColSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_password_literal ) ) ); + + CleanupStack::PopAndDestroy(buf); + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiDataConnection::FetchDataL: Return\n"))); + return; + } + + // Get use manual username + TUint intValue = iView.ColUint(iColSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_username_literal)); + if (intValue == 0) + { + *(iDataPtr->GetUseManualUsername()) = EFalse; + } + else + { + *(iDataPtr->GetUseManualUsername()) = ETrue; + } + + // Get use manual realm + intValue = iView.ColUint(iColSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_realm_literal)); + if (intValue == 0) + { + *(iDataPtr->GetUseManualRealm()) = EFalse; + } + else + { + *(iDataPtr->GetUseManualRealm()) = ETrue; + } + + // Get Username + iDataPtr->GetManualUsername().Copy(iView.ColDes16(iColSet->ColNo(cf_str_EAP_TLS_PEAP_manual_username_literal))); + + // Get Realm + iDataPtr->GetManualRealm().Copy(iView.ColDes16(iColSet->ColNo(cf_str_EAP_TLS_PEAP_manual_realm_literal))); + + // Get PEAP/TTLS versions + if (iUiConn->GetEapType() == eap_type_peap + || iUiConn->GetEapType() == eap_type_ttls +#ifdef USE_FAST_EAP_TYPE + || iUiConn->GetEapType() == eap_type_fast +#endif + ) + { + TPtrC8 binaryValue = iView.ColDes8(iColSet->ColNo(cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal)); + + const TInt* allowedVersions = reinterpret_cast(binaryValue.Ptr()); + + TInt i; + for (i = 0; i < static_cast(binaryValue.Length() / sizeof(TInt)); i++) + { + switch(allowedVersions[i]) + { + case 0: + *(iDataPtr->GetAllowVersion0()) = ETrue; + break; + case 1: + *(iDataPtr->GetAllowVersion1()) = ETrue; + break; + case 2: + *(iDataPtr->GetAllowVersion2()) = ETrue; + break; + } + } + } + + + intValue = iView.ColUint(iColSet->ColNo(cf_str_EAP_TLS_PEAP_use_identity_privacy_literal)); + + if (intValue == 0) + { + *(iDataPtr->GetTlsPrivacy()) = EFalse; + } + else + { + *(iDataPtr->GetTlsPrivacy()) = ETrue; + } + + +#ifdef USE_FAST_EAP_TYPE + + EAP_TRACE_DEBUG_SYMBIAN((_L("Fetching EAP-FAST specific Special settings!\n"))); + + if(iUiConn->GetEapType() == eap_type_fast) + { + // This is for the EAP-FAST specific Special settings. + + sqlStatement.Format(KSQLQuery, + &KFastSpecialSettingsDBTableName, + &KServiceType, + iUiConn->GetIndexType(), + &KServiceIndex, + iUiConn->GetIndex(), + &KTunnelingType, + iUiConn->GetTunnelingType()); + + // Evaluate view + User::LeaveIfError(iFastSpecificView.Prepare(iDatabase, TDbQuery(sqlStatement))); + User::LeaveIfError(iFastSpecificView.EvaluateAll()); + + // Get the first (and only) row + iFastSpecificView.FirstL(); + iFastSpecificView.GetL(); + + // Get column set so we get the correct column numbers + delete iFastSpecificColSet; + iFastSpecificColSet = NULL; + iFastSpecificColSet = iFastSpecificView.ColSetL(); + + // Start fetching the values + // The below uses EAP-FAST Specific settings table. So use the specific view and colset. + + // Get provisioning modes + intValue = iFastSpecificView.ColUint(iFastSpecificColSet->ColNo(cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal)); + if (intValue == 0) + { + *(iDataPtr->GetAuthProvModeAllowed()) = EFalse; + } + else + { + *(iDataPtr->GetAuthProvModeAllowed()) = ETrue; + } + + intValue = iFastSpecificView.ColUint(iFastSpecificColSet->ColNo(cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal)); + if (intValue == 0) + { + *(iDataPtr->GetUnauthProvModeAllowed()) = EFalse; + } + else + { + *(iDataPtr->GetUnauthProvModeAllowed()) = ETrue; + } + +#ifdef USE_PAC_STORE + // Get PAC store Password + // PAC store password is in a different database, pac store db. + // We can use the PacStoreDbUtils to get the PAC store password. + + TBuf8 tmpPacStorePw8; + + iUiConn->GetPacStoreDb()->GetPacStoreDataL( + cf_str_EAP_FAST_PAC_store_password_literal(), + tmpPacStorePw8); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("CEapTlsPeapUiDataConnection::FetchDataL: PW from PAC store DB(8 bits)", + tmpPacStorePw8.Ptr(), + tmpPacStorePw8.Size())); + + /***** Convert the 8 bit password to 16 bits for the UI ***************/ + + iDataPtr->GetPacStorePassword().Copy(tmpPacStorePw8); // This takes care of the conversion automatically. + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("CEapTlsPeapUiDataConnection::FetchDataL: PW to UI (16 bits)", + iDataPtr->GetPacStorePassword().Ptr(), + iDataPtr->GetPacStorePassword().Size())); + + /*****************TEST*************/ + +#endif // End: #ifdef USE_PAC_STORE + + } // End: if(iUiConn->GetEapType() == eap_type_fast) + +#endif // End: #ifdef USE_FAST_EAP_TYPE + + CleanupStack::PopAndDestroy(buf); + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiDataConnection::FetchDataL: End\n"))); + +} // CEapTlsPeapUiDataConnection::FetchDataL() + + +// --------------------------------------------------------- +// CEapTlsPeapUiDataConnection::UpdateDataL() +// --------------------------------------------------------- +// +void CEapTlsPeapUiDataConnection::UpdateDataL() +{ + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiDataConnection::UpdateDataL: Start\n"))); + + iView.UpdateL(); + + iView.SetColL( + iColSet->ColNo(cf_str_EAP_TLS_PEAP_manual_username_literal), + iDataPtr->GetManualUsername()); + + iView.SetColL( + iColSet->ColNo(cf_str_EAP_TLS_PEAP_manual_realm_literal), + iDataPtr->GetManualRealm()); + + if (*(iDataPtr->GetUseManualUsername())) + { + iView.SetColL( + iColSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_username_literal), + ETLSPEAPUseManualUsernameYes); + } + else + { + iView.SetColL( + iColSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_username_literal), + ETLSPEAPUseManualUsernameNo); + } + + if (*(iDataPtr->GetUseManualRealm())) + { + iView.SetColL( + iColSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_realm_literal), + ETLSPEAPUseManualRealmYes); + } + else + { + iView.SetColL( + iColSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_realm_literal), + ETLSPEAPUseManualRealmNo); + } + + // PEAP/TTLS versions + if (iUiConn->GetEapType() == eap_type_peap + || iUiConn->GetEapType() == eap_type_ttls +#ifdef USE_FAST_EAP_TYPE + || iUiConn->GetEapType() == eap_type_fast +#endif + ) + { + TBuf8 acceptedVersions; + + if (*(iDataPtr->GetAllowVersion0())) + { + TInt tmp(0); + acceptedVersions.Append(reinterpret_cast(&tmp), sizeof(TInt)); + } + if (*(iDataPtr->GetAllowVersion1())) + { + TInt tmp(1); + acceptedVersions.Append(reinterpret_cast(&tmp), sizeof(TInt)); + } + if (*(iDataPtr->GetAllowVersion2())) + { + TInt tmp(2); + acceptedVersions.Append(reinterpret_cast(&tmp), sizeof(TInt)); + } + + iView.SetColL( + iColSet->ColNo(cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal), + acceptedVersions); + } + + // Last full authentication time should be made zero when EAP configurations are modified. + // This makes sure that the next authentication with this EAP would be full authentication + // instead of reauthentication even if the session is still valid. + + TPtrC lastFullAuthTimeString; + + switch (iUiConn->GetEapType()) + { + case eap_type_tls: + { + lastFullAuthTimeString.Set(KTLSLastFullAuthTime); + } + break; + + case eap_type_peap: + { + lastFullAuthTimeString.Set(KPEAPLastFullAuthTime); + } + break; + + case eap_type_ttls: + { + lastFullAuthTimeString.Set(KTTLSLastFullAuthTime); + } + break; + +#ifdef USE_FAST_EAP_TYPE + case eap_type_fast: + { + lastFullAuthTimeString.Set(KFASTLastFullAuthTime); + } + break; +#endif + + case eap_type_ttls_plain_pap: + { + lastFullAuthTimeString.Set( KTTLSPAPLastFullAuthTime ); + } + break; + + default: + { + // Should never happen. Don't return error here as this is just to reset the auth time only. + EAP_TRACE_DEBUG_SYMBIAN( + (_L("Session Validity: EAP-Type=%d - ERROR: Unknown EAP type!\n"), + iUiConn->GetEapType() )); + } + } + + iView.SetColL( + iColSet->ColNo(lastFullAuthTimeString), + default_FullAuthTime); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("Session Validity: EAP-Type=%d, Resetting Full Auth Time since settings are modified\n"), + iUiConn->GetEapType() )); + + + // Update TLS Privacy + if (*(iDataPtr->GetTlsPrivacy())) + { + iView.SetColL( + iColSet->ColNo(cf_str_EAP_TLS_PEAP_use_identity_privacy_literal), + ETLSPEAPTLSPrivacyYes); + } + else + { + iView.SetColL( + iColSet->ColNo(cf_str_EAP_TLS_PEAP_use_identity_privacy_literal), + ETLSPEAPTLSPrivacyNo); + } + + + + + /************** only for TTLS PAP **************/ + + if( iUiConn->GetEapType() == eap_type_ttls_plain_pap ) + { + // PAP user name + iView.SetColL( iColSet->ColNo( cf_str_EAP_TLS_PEAP_ttls_pap_username_literal ), + iDataPtr->GetPapUserName() ); + // PAP password + iView.SetColL( iColSet->ColNo( cf_str_EAP_TLS_PEAP_ttls_pap_password_literal ), + iDataPtr->GetPapPassword() ); + // PAP password prompt + if ( *( iDataPtr->GetPapPasswordPrompt() ) ) + { + iView.SetColL( iColSet->ColNo( cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal ), + EPapPasswordPromptOn ); + } + else + { + iView.SetColL( iColSet->ColNo( cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal ), + EPapPasswordPromptOff ); + } + + } // if( iUiConn->GetEapType() == eap_type_ttls_plain_pap ) + + + + // Now put all the updated values in DB table. + iView.PutL(); + +#ifdef USE_FAST_EAP_TYPE + + if(iUiConn->GetEapType() == eap_type_fast) + { + // Make the view ready for updation. This is important! + iFastSpecificView.UpdateL(); + + // Update Authentication modes + if (*(iDataPtr->GetAuthProvModeAllowed())) + { + iFastSpecificView.SetColL( + iFastSpecificColSet->ColNo(cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal), + EFASTAuthProvModeAllowedYes); + } + else + { + iFastSpecificView.SetColL( + iFastSpecificColSet->ColNo(cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal), + EFASTAuthProvModeAllowedNo); + } + + if (*(iDataPtr->GetUnauthProvModeAllowed())) + { + iFastSpecificView.SetColL( + iFastSpecificColSet->ColNo(cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal), + EFASTUnauthProvModeAllowedYes); + } + else + { + iFastSpecificView.SetColL( + iFastSpecificColSet->ColNo(cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal), + EFASTUnauthProvModeAllowedNo); + } + + // Now put all the updated values in DB table. + iFastSpecificView.PutL(); + + +#ifdef USE_PAC_STORE + + // Update PAC store password. + // PAC store password should be stored in a different database, pac store db. + // We can use the UI connection to save the PAC store password. + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("CEapTlsPeapUiDataConnection::UpdateDataL: PW from UI(16 bits)", + iDataPtr->GetPacStorePassword().Ptr(), + iDataPtr->GetPacStorePassword().Size())); + + TBuf8 tmpSetPacStorePw8; + tmpSetPacStorePw8.Copy(iDataPtr->GetPacStorePassword()); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("CEapTlsPeapUiDataConnection::UpdateDataL: PW to PAC store DB(8 bits)", + tmpSetPacStorePw8.Ptr(), + tmpSetPacStorePw8.Size())); + + iUiConn->GetPacStoreDb()->SetPacStoreDataL( + cf_str_EAP_FAST_PAC_store_password_literal(), + tmpSetPacStorePw8); + +/*****************TEST*************/ + +#ifdef PAC_STORE_DATA_HACK + + TBuf<4> tmpSetPacStoreData1; + TBuf<4> tmpSetPacStoreData2; + TBuf<4> tmpSetPacStoreData3; + TBuf<4> tmpSetPacStoreData4; + TBuf<4> tmpSetPacStoreData5; + TBuf<4> tmpSetPacStoreData6; + RArray infoarray1; + RArray infoarray2; + + tmpSetPacStoreData1.Copy(iDataPtr->GetUsePAC_Store_Group_Reference()); + tmpSetPacStoreData2.Copy(iDataPtr->GetUsePAC_Store_Group_Value()); + tmpSetPacStoreData3.Copy(iDataPtr->GetUsePAC_Store_AID_Reference()); + tmpSetPacStoreData4.Copy(iDataPtr->GetUsePAC_Store_AID_Value()); + tmpSetPacStoreData6.Copy(iDataPtr->GetUsePAC_Store_PAC_Reference()); + tmpSetPacStoreData6.Copy(iDataPtr->GetUsePAC_Store_PAC_Value()); + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiDataConnection::UpdateDataL: tmpSetPacStoreData=%S\n"), + &tmpSetPacStorePw)); + + iUiConn->GetPacStoreDb()->SetPacStoreDataL( + KPacStoreGroupReference, + tmpSetPacStoreData1, + KPacStoreGroupReference); + iUiConn->GetPacStoreDb()->SetPacStoreDataL( + KPacStoreGroupValue, + tmpSetPacStoreData2, + KPacStoreGroupReference); + iUiConn->GetPacStoreDb()->SetPacStoreDataL( + KPacStoreAIDReference, + tmpSetPacStoreData3, + KPacStoreAIDReference); + iUiConn->GetPacStoreDb()->SetPacStoreDataL( + KPacStoreAIDValue, + tmpSetPacStoreData4, + KPacStoreAIDReference); + iUiConn->GetPacStoreDb()->SetPacStoreDataL( + KPacStorePACReference, + tmpSetPacStoreData5, + KPacStorePACValue); + iUiConn->GetPacStoreDb()->SetPacStoreDataL( + KPacStorePACValue, + tmpSetPacStoreData6, + KPacStorePACReference); + +#endif + + /*****************TEST*************/ + +#endif // End: #ifdef USE_PAC_STORE + + } // End: if(iUiConn->GetEapType() == eap_type_fast) + +#endif // End: #ifdef USE_FAST_EAP_TYPE + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiDataConnection::UpdateDataL: End\n"))); + +} // CEapTlsPeapUiDataConnection::UpdateDataL() + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiEapTypes.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiEapTypes.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,395 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 433 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include +#include "EapTlsPeapUtils.h" +#include +#include +#include +#include "eap_am_trace_symbian.h" + +const TUint KNumberOfSupportedEAPTypes = 10; //Now 10, including EAP-FAST & TTLS-PAP + +CEapTlsPeapUiEapTypes::CEapTlsPeapUiEapTypes(CEapTlsPeapUiConnection * const aUiConn) +: iIsOpened(EFalse) +, iUiConn(aUiConn) +, iDataPtr(NULL) +{ +} + + +CEapTlsPeapUiEapTypes::~CEapTlsPeapUiEapTypes() +{ + if (iUiConn) + { + Close(); + iUiConn = NULL; + } +} + + +TInt CEapTlsPeapUiEapTypes::Open() +{ + if (iIsOpened) + { + return KErrAlreadyExists; + } + + TInt err = iUiConn->GetDatabase(iDatabase); + if (err != KErrNone) + { + return err; + } + + iIsOpened = ETrue; + + return KErrNone; +} + + +TInt CEapTlsPeapUiEapTypes::GetEapTypes(CArrayFixFlat ** aDataPtr) +{ + if (aDataPtr == NULL) + { + return KErrArgument; + } + if (iIsOpened == EFalse) + { + return KErrSessionClosed; + } + if (iDataPtr != 0) + { + *aDataPtr = iDataPtr; + return KErrNone; + } + iDataPtr = new CArrayFixFlat(KNumberOfSupportedEAPTypes); + if (!iDataPtr) + { + return KErrNoMemory; + } + +#ifdef USE_EAP_EXPANDED_TYPES + + TRAPD(err, FetchExpandedDataL()); + +#else + + TRAPD(err, FetchDataL()); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + if (err != KErrNone) + { + delete iDataPtr; + return err; + } + + *aDataPtr = iDataPtr; + + return KErrNone; +} + + +TInt CEapTlsPeapUiEapTypes::Update() +{ + +#ifdef USE_EAP_EXPANDED_TYPES + + TRAPD(err, UpdateExpandedDataL()); + +#else + + TRAPD(err, UpdateL()); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + return err; +} + +#ifndef USE_EAP_EXPANDED_TYPES + +void CEapTlsPeapUiEapTypes::UpdateL() +{ + TEapArray eapTypes; + TEap* eapTmp; + + TInt i(0); + + for(i = 0; i < iDataPtr->Count(); i++) + { + eapTmp = new (ELeave) TEap; + CleanupStack::PushL(eapTmp); + eapTmp->Enabled = iDataPtr->At(i).iIsEnabled; + eapTmp->UID.Copy(iDataPtr->At(i).iEapType); + User::LeaveIfError(eapTypes.Append(eapTmp)); + CleanupStack::Pop(eapTmp); + } + + TRAPD(err, EapTlsPeapUtils::SetEapDataL( + iDatabase, + 0, + eapTypes, + iUiConn->GetIndexType(), + iUiConn->GetIndex(), + static_cast(iUiConn->GetTunnelingType()), + static_cast(iUiConn->GetEapType()))); + + eapTypes.ResetAndDestroy(); + if (err != KErrNone) + { + User::Leave(err); + } +} +#endif // #ifndef USE_EAP_EXPANDED_TYPES + + +TInt CEapTlsPeapUiEapTypes::Close() +{ + if (iIsOpened == EFalse) + { + return KErrNone; + } + + delete iDataPtr; + iDataPtr = 0; + + iUiConn = NULL; + return KErrNone; +} + +#ifndef USE_EAP_EXPANDED_TYPES + +void CEapTlsPeapUiEapTypes::FetchDataL() +{ + TEapArray eapTypes; + + TRAPD(err, EapTlsPeapUtils::GetEapDataL( + iDatabase, + 0, + eapTypes, + iUiConn->GetIndexType(), + iUiConn->GetIndex(), + static_cast(iUiConn->GetTunnelingType()), + static_cast(iUiConn->GetEapType()))); + + if (err != KErrNone) + { + eapTypes.ResetAndDestroy(); + User::Leave(err); + } + + TInt i(0); + for (i = 0; i < eapTypes.Count(); i++) + { + TEapTlsPeapUiEapType tmp; + + tmp.iIsEnabled = eapTypes[i]->Enabled; + + tmp.iEapType.Copy(eapTypes[i]->UID); + + TRAPD(err, iDataPtr->AppendL(tmp)); + if (err != KErrNone) + { + eapTypes.ResetAndDestroy(); + User::Leave(err); + } + } + eapTypes.ResetAndDestroy(); +} +#endif // #ifndef USE_EAP_EXPANDED_TYPES + +#ifdef USE_EAP_EXPANDED_TYPES + +void CEapTlsPeapUiEapTypes::FetchExpandedDataL() +{ + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiEapTypes::FetchExpandedDataL: Start\n"))); + + RExpandedEapTypePtrArray enabledEAPTypes; + RExpandedEapTypePtrArray disabledEAPTypes; + + eap_type_value_e tunnelingType(static_cast(iUiConn->GetTunnelingType())); + eap_type_value_e eapType(static_cast(iUiConn->GetEapType())); + + TRAPD(err, EapTlsPeapUtils::GetTunnelingExpandedEapDataL( + iDatabase, + 0, + enabledEAPTypes, + disabledEAPTypes, + iUiConn->GetIndexType(), + iUiConn->GetIndex(), + tunnelingType, + eapType)); + + if (err != KErrNone) + { + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiEapTypes::FetchExpandedDataL: Error from GetTunnelingExpandedEapDataL:%d\n"), + err)); + + User::Leave(err); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiEapTypes::FetchExpandedDataL: Got tunneling EAPs from DB: enabled=%d,disabled=%d\n"), + enabledEAPTypes.Count(), disabledEAPTypes.Count())); + + TInt i(0); + + // First fill the enabled EAP types. + for (i = 0; i < enabledEAPTypes.Count(); i++) + { + TEapTlsPeapUiEapType tmpEAP; + + tmpEAP.iIsEnabled = ETrue; // All EAP types here are enabled. + + tmpEAP.iEapType.Copy(enabledEAPTypes[i]->iExpandedEAPType); + + TRAPD(err, iDataPtr->AppendL(tmpEAP)); + if (err != KErrNone) + { + enabledEAPTypes.ResetAndDestroy(); + User::Leave(err); + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("CEapTlsPeapUiEapTypes::FetchExpandedDataL:Appended ENABLED EAP type:", + tmpEAP.iEapType.Ptr(), + tmpEAP.iEapType.Size() ) ); + } + + // Now fill the disabled EAP types. + for (i = 0; i < disabledEAPTypes.Count(); i++) + { + TEapTlsPeapUiEapType tmpEAP; + + tmpEAP.iIsEnabled = EFalse; // All EAP types here are disabled. + + tmpEAP.iEapType.Copy(disabledEAPTypes[i]->iExpandedEAPType); + + TRAPD(err, iDataPtr->AppendL(tmpEAP)); + if (err != KErrNone) + { + disabledEAPTypes.ResetAndDestroy(); + User::Leave(err); + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("CEapTlsPeapUiEapTypes::FetchExpandedDataL:Appended DISABLED EAP type:", + tmpEAP.iEapType.Ptr(), + tmpEAP.iEapType.Size() ) ); + } + + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiEapTypes::FetchExpandedDataL: End\n"))); +} + +void CEapTlsPeapUiEapTypes::UpdateExpandedDataL() +{ + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiEapTypes::UpdateExpandedDataL: Start\n"))); + + RExpandedEapTypePtrArray enabledEAPTypes; + RExpandedEapTypePtrArray disabledEAPTypes; + SExpandedEAPType* expandedEAPTmp; + + for(TInt i=0 ; i < iDataPtr->Count(); i++) + { + expandedEAPTmp = new (ELeave) SExpandedEAPType; + CleanupStack::PushL(expandedEAPTmp); + + expandedEAPTmp->iExpandedEAPType.Copy(iDataPtr->At(i).iEapType); + + if(iDataPtr->At(i).iIsEnabled) + { + // Enabled + TInt error = enabledEAPTypes.Append(expandedEAPTmp); + + if (error != KErrNone) + { + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + User::LeaveIfError(error); + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("CEapTlsPeapUiEapTypes::UpdateExpandedDataL:Appended ENABLED EAP type:", + expandedEAPTmp->iExpandedEAPType.Ptr(), + expandedEAPTmp->iExpandedEAPType.Size() ) ); + } + else + { + // Disabled + TInt error = disabledEAPTypes.Append(expandedEAPTmp); + + if (error != KErrNone) + { + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + User::LeaveIfError(error); + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("CEapTlsPeapUiEapTypes::UpdateExpandedDataL:Appended DISABLED EAP type:", + expandedEAPTmp->iExpandedEAPType.Ptr(), + expandedEAPTmp->iExpandedEAPType.Size() ) ); + } + + CleanupStack::Pop(expandedEAPTmp); + } + + eap_type_value_e tunnelingType(static_cast(iUiConn->GetTunnelingType())); + eap_type_value_e eapType(static_cast(iUiConn->GetEapType())); + + TRAPD(err, EapTlsPeapUtils::SetTunnelingExpandedEapDataL( + iDatabase, + 0, + enabledEAPTypes, + disabledEAPTypes, + iUiConn->GetIndexType(), + iUiConn->GetIndex(), + tunnelingType, + eapType)); + + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + + if (err != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("CEapTlsPeapUiEapTypes::UpdateExpandedDataL: Error from SetTunnelingExpandedEapDataL:%d\n"), + err)); + + User::Leave(err); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("CEapTlsPeapUiEapTypes::UpdateExpandedDataL: End\n"))); +} + +#endif // #ifdef USE_EAP_EXPANDED_TYPES + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiTlsPeapData.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUiTlsPeapData.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 435 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + +#include + + +CEapTlsPeapUiTlsPeapData::CEapTlsPeapUiTlsPeapData() +: iAllowVersion0(EFalse), +iAllowVersion1(EFalse), +iAllowVersion2(EFalse), +iPapPasswordPrompt( ETrue ) +{ +} + + +CEapTlsPeapUiTlsPeapData::~CEapTlsPeapUiTlsPeapData() +{ +} + + +TDes& CEapTlsPeapUiTlsPeapData::GetManualUsername() +{ + return iManualUsername; +} + +TBool * CEapTlsPeapUiTlsPeapData::GetUseManualUsername() +{ + return &iUseManualUsername; +} + +TDes& CEapTlsPeapUiTlsPeapData::GetManualRealm() +{ + return iManualRealm; +} + + +TBool * CEapTlsPeapUiTlsPeapData::GetUseManualRealm() +{ + return &iUseManualRealm; +} + +TBool * CEapTlsPeapUiTlsPeapData::GetAllowVersion0() +{ + return &iAllowVersion0; +} + +TBool * CEapTlsPeapUiTlsPeapData::GetAllowVersion1() +{ + return &iAllowVersion1; +} + +TBool * CEapTlsPeapUiTlsPeapData::GetAllowVersion2() +{ + return &iAllowVersion2; +} + +TBool * CEapTlsPeapUiTlsPeapData::GetTlsPrivacy() +{ + return &iTlsPrivacy; +} + +TBool * CEapTlsPeapUiTlsPeapData::GetAuthProvModeAllowed() +{ + return &iAuthProvModeAllowed; +} + +TBool * CEapTlsPeapUiTlsPeapData::GetUnauthProvModeAllowed() +{ + return &iUnauthProvModeAllowed; +} + +TDes& CEapTlsPeapUiTlsPeapData::GetPacStorePassword() +{ + return iPacStorePassword; +} + + +// --------------------------------------------------------- +// CEapTlsPeapUiTlsPeapData::GetPapUserName() +// --------------------------------------------------------- +// +TDes& CEapTlsPeapUiTlsPeapData::GetPapUserName() + { + return iPapUserName; + } + +// --------------------------------------------------------- +// CEapTlsPeapUiTlsPeapData::GetPapPassword() +// --------------------------------------------------------- +// +TDes& CEapTlsPeapUiTlsPeapData::GetPapPassword() + { + return iPapPassword; + } + +// --------------------------------------------------------- +// CEapTlsPeapUiTlsPeapData::GetPapPasswordPrompt() +// --------------------------------------------------------- +// +TBool* CEapTlsPeapUiTlsPeapData::GetPapPasswordPrompt() + { + return &iPapPasswordPrompt; + } + +// End of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUtils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/tls_peap/symbian/plugin/src/EapTlsPeapUtils.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,5828 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// This is enumeration of EAPOL source code. +#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + #undef EAP_FILE_NUMBER_ENUM + #define EAP_FILE_NUMBER_ENUM 438 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +// INCLUDE FILES +#include "EapTlsPeapUtils.h" +#include "EapTlsPeapDbDefaults.h" +#include "EapTlsPeapDbParameterNames.h" +#include +#include +#include + +#ifdef USE_FAST_EAP_TYPE +#include "pac_store_db_parameters.h" +#endif //#ifdef USE_FAST_EAP_TYPE + +#include "eap_am_trace_symbian.h" +#include "EapTlsPeapCertFetcher.h" + +const TUint KMaxSqlQueryLength = 2048; +const TInt KMicroSecsInAMinute = 60000000; // 60000000 micro seconds is 1 minute. +const TInt KDefaultColumnInView_One = 1; // For DB view. +const TInt KMaxEapDbTableNameLength = 64; +// ================= MEMBER FUNCTIONS ======================= + +void EapTlsPeapUtils::OpenDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + eap_type_value_e aEapType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenDatabaseL -Start- aIndexType=%d, aIndex=%d, Tunneling vendor type=%d, Eap vendor type=%d \n"), + aIndexType,aIndex, aTunnelingType.get_vendor_type(), aEapType.get_vendor_type())); +#else + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenDatabaseL -Start- aIndexType=%d, aIndex=%d, aTunnelingType=%d, aEapType=%d \n"), + aIndexType,aIndex, aTunnelingType, aEapType)); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + if (aEapType == eap_type_tls) + { + OpenTlsDatabaseL(aDatabase, aSession, aIndexType, aIndex, aTunnelingType); + } + else if (aEapType == eap_type_peap) + { + OpenPeapDatabaseL(aDatabase, aSession, aIndexType, aIndex, aTunnelingType); + } +#if defined(USE_TTLS_EAP_TYPE) + else if (aEapType == eap_type_ttls) + { + OpenTtlsDatabaseL(aDatabase, aSession, aIndexType, aIndex, aTunnelingType); + } +#endif // #if defined(USE_TTLS_EAP_TYPE) +#if defined(USE_FAST_EAP_TYPE) + else if (aEapType == eap_type_fast) + { + OpenFastDatabaseL(aDatabase, aSession, aIndexType, aIndex, aTunnelingType); + } +#endif // #if defined(USE_FAST_EAP_TYPE) + + else if ( aEapType == eap_type_ttls_plain_pap ) + { + OpenTtlsDatabaseL( aDatabase, aSession, aIndexType, aIndex, aTunnelingType); + } + + else + { + // Unsupported EAP type + User::Leave(KErrNotSupported); + } +} // EapTlsPeapUtils::OpenDatabaseL() + +void EapTlsPeapUtils::OpenTlsDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenTlsDatabaseL -Start- aIndexType=%d, aIndex=%d, Tunneling vendor type=%d \n"), + aIndexType,aIndex, aTunnelingVendorType)); + + // 1. Open/create a database + + // Connect to the DBMS server. + User::LeaveIfError(aSession.Connect()); + CleanupClosePushL(aSession); + // aSession and aDatabase are pushed to the cleanup stack even though they may be member + // variables of the calling class and would be closed in the destructor anyway. This ensures + // that if they are not member variables they will be closed. Closing the handle twice + // does no harm. + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = aDatabase.Create(aSession, KTlsDatabaseName, KSecureUIDFormat); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::OpenTlsDatabaseL - Created Secure DB for eaptls.dat. err=%d\n"), err) ); + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(aSession, KTlsDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(aDatabase); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = aDatabase.Create(fsSession, KTlsDatabaseName); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::OpenTlsDatabaseL - Created Non-Secure DB for eaptls.dat. err=%d\n"), err) ); + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(fsSession, KTlsDatabaseName)); + + CleanupStack::PopAndDestroy(); // close fsSession + + CleanupClosePushL(aDatabase); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + // 2. Create the eaptls table to database (ignore error if exists) + +// Table columns: +//// NAME ////////////////////////////////////////// TYPE //////////// Constant //////////////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| EAP_TLS_PEAP_use_manual_realm | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_manual_realm_literal |// +//| EAP_TLS_PEAP_manual_realm | VARCHAR(255) | cf_str_EAP_TLS_PEAP_manual_realm_literal |// +//| EAP_TLS_PEAP_use_manual_username | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_manual_username_literal |// +//| EAP_TLS_PEAP_manual_username | VARCHAR(255) | cf_str_EAP_TLS_PEAP_manual_username_literal |// +//| EAP_TLS_PEAP_cipher_suite | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_cipher_suite_literal |// +//| EAP_TLS_server_authenticates_client | UNSIGNED INTEGER | cf_str_TLS_server_authenticates_client_policy_in_client_literal |// +//| CA_cert_label | VARCHAR(255) | KCACertLabelOld |// +//| client_cert_label | VARCHAR(255) | KClientCertLabel |// +//| EAP_TLS_PEAP_saved_session_id | BINARY(32) | cf_str_EAP_TLS_PEAP_saved_session_id_literal |// +//| EAP_TLS_PEAP_saved_master_secret | BINARY(48) | cf_str_EAP_TLS_PEAP_saved_master_secret_literal |// +//| EAP_TLS_PEAP_saved_cipher_suite | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_saved_cipher_suite_literal |// +//| EAP_TLS_PEAP_verify_certificate_realm | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal |// +//| EAP_TLS_max_session_validity_time | BIGINT | cf_str_EAP_TLS_max_session_validity_time_literal |// +//| EAP_TLS_last_full_authentication_time | BIGINT | KTLSLastFullAuthTime |// +//| EAP_TLS_PEAP_use_identity_privacy | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_identity_privacy_literal|// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Table creation is divided into two parts because otherwise the SQL string would get too long + _LIT(KSQLCreateTable1, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S BIGINT, \ + %S BIGINT, \ + %S UNSIGNED INTEGER)"); + + sqlStatement.Format(KSQLCreateTable1, + &KTlsDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &cf_str_EAP_TLS_PEAP_use_manual_realm_literal, + &cf_str_EAP_TLS_PEAP_manual_realm_literal, KMaxManualRealmLengthInDB, + &cf_str_EAP_TLS_PEAP_use_manual_username_literal, + &cf_str_EAP_TLS_PEAP_manual_username_literal, KMaxManualUsernameLengthInDB, + &cf_str_EAP_TLS_PEAP_cipher_suite_literal, + &cf_str_TLS_server_authenticates_client_policy_in_client_literal, + &KCACertLabelOld, KMaxCertLabelLengthInDB, + &KClientCertLabel, KMaxCertLabelLengthInDB, + &cf_str_EAP_TLS_PEAP_saved_session_id_literal, KMaxSessionIdLengthInDB, + &cf_str_EAP_TLS_PEAP_saved_master_secret_literal, KMaxMasterSecretLengthInDB, + &cf_str_EAP_TLS_PEAP_saved_cipher_suite_literal, + &cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal, + &cf_str_EAP_TLS_max_session_validity_time_literal, + &KTLSLastFullAuthTime, + &cf_str_EAP_TLS_PEAP_use_identity_privacy_literal); + + err = aDatabase.Execute(sqlStatement); + if (err == KErrAlreadyExists) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::OpenTlsDatabaseL - Alter Table err=%d\n"), err) ); + _LIT( KColumnDef, "UNSIGNED INTEGER" ); + AlterTableL( aDatabase, EAddColumn , KTlsDatabaseTableName, + cf_str_EAP_TLS_PEAP_use_identity_privacy_literal, KColumnDef); + } + else if (err != KErrNone) + { + User::Leave(err); + } + + // Create table for _allowed_ user certificates + +//// NAME ////////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CertLabel | VARCHAR(255) | KCertLabel |// +//| SubjectKeyId | BINARY(20) | KSubjectKeyIdentifier |// This is Symbian subjectkey id +//| ActualSubjectKeyId | BINARY(20) | KActualSubjectKeyIdentifier |// This is the actual subjectkeyid present in the certificate. +//| SubjectName | VARCHAR(255) | KSubjectName |// +//| IssuerName | VARCHAR(255) | KIssuerName |// +//| SerialNumber | VARCHAR(255) | KSerialNumber |// +//| Thumbprint | BINARY(64) | KThumbprint |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable2, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BINARY(%d))"); + + sqlStatement.Format(KSQLCreateTable2, &KTlsAllowedUserCertsDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &KCertLabel, KMaxCertLabelLengthInDB, + &KSubjectKeyIdentifier, KMaxSubjectKeyIdLengthInDB, + &KActualSubjectKeyIdentifier, KKeyIdentifierLength, + &KSubjectName, KGeneralStringMaxLength, + &KIssuerName, KGeneralStringMaxLength, + &KSerialNumber, KGeneralStringMaxLength, + &KThumbprint, KThumbprintMaxLength); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // Create table for _allowed_ CA certs + +//// NAME ////////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CertLabel | VARCHAR(255) | KCACertLabel |// +//| SubjectKeyId | BINARY(255) | KSubjectKeyIdentifier |// This is Symbian subjectkey id +//| ActualSubjectKeyId | BINARY(20) | KActualSubjectKeyIdentifier |// This is the actual subjectkeyid present in the certificate. +//| SubjectName | VARCHAR(255) | KSubjectName |// +//| IssuerName | VARCHAR(255) | KIssuerName |// +//| SerialNumber | VARCHAR(255) | KSerialNumber |// +//| Thumbprint | BINARY(64) | KThumbprint |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable3, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BINARY(%d))"); + + sqlStatement.Format(KSQLCreateTable3, &KTlsAllowedCACertsDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &KCertLabel, KMaxCertLabelLengthInDB, + &KSubjectKeyIdentifier, KMaxSubjectKeyIdLengthInDB, + &KActualSubjectKeyIdentifier, KKeyIdentifierLength, + &KSubjectName, KGeneralStringMaxLength, + &KIssuerName, KGeneralStringMaxLength, + &KSerialNumber, KGeneralStringMaxLength, + &KThumbprint, KThumbprintMaxLength); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // Create table for allowed cipher suites + +//// NAME ///////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CipherSuite | UNSIGNED INTEGER | KCipherSuite |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable4, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER)"); + + sqlStatement.Format(KSQLCreateTable4, &KTlsAllowedCipherSuitesDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &KCipherSuite); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // 4. Check if database table contains a row for this service type and id + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQLQueryRow, &cf_str_EAP_TLS_PEAP_cipher_suite_literal, &KTlsDatabaseTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + // View must be closed when no longer needed + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // 5. If row is not found then add it + + TInt rows = view.CountL(); + CleanupStack::PopAndDestroy(); // view + if (rows == 0) + { + _LIT(KSQLInsert, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert, &KTlsDatabaseTableName); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly)); + CleanupClosePushL(view); + view.InsertL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Set the default values. The other three tables (certs, ca certs & cipher suites) are empty by default. + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_realm_literal), default_EAP_TLS_PEAP_use_manual_realm); + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_realm_literal), default_EAP_TLS_PEAP_manual_realm); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_username_literal), default_EAP_TLS_PEAP_use_manual_username); + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_username_literal), default_EAP_TLS_PEAP_manual_username); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_cipher_suite_literal), default_EAP_TLS_PEAP_cipher_suite); + + view.SetColL(colSet->ColNo(cf_str_TLS_server_authenticates_client_policy_in_client_literal), default_EAP_TLS_server_authenticates_client); + + view.SetColL(colSet->ColNo(KCACertLabelOld), default_CA_cert_label); + view.SetColL(colSet->ColNo(KClientCertLabel), default_client_cert_label); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal), default_EAP_TLS_PEAP_verify_certificate_realm); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_max_session_validity_time_literal), default_MaxSessionTime); + + view.SetColL(colSet->ColNo(KTLSLastFullAuthTime), default_FullAuthTime); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_identity_privacy_literal), default_EAP_TLS_PEAP_TLS_Privacy); + view.PutL(); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + CleanupStack::PopAndDestroy( &view ); // Close view. + + // Add default disabled cipher suites + _LIT(KSQLInsert2, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert2, &KTlsAllowedCipherSuitesDatabaseTableName); + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly)); + CleanupClosePushL(view); + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + TInt i(0); + while (default_allowed_cipher_suites[i] != 0) + { + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + view.SetColL(colSet->ColNo(KCipherSuite), default_allowed_cipher_suites[i]); + view.PutL(); + i++; + } + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + CleanupStack::PopAndDestroy( &view ); // Close view. + } + + // 6. Do the altering of tables here. + // Add columns to existing certificate DB tables for Serial number, Issuer name etc. + + TBufC tableName; + + // For the table _allowed_ USER certificates + tableName = KTlsAllowedUserCertsDatabaseTableName; + AddExtraCertColumnsL(aDatabase,tableName); + + // For the table _allowed_ CA certificates + tableName = KTlsAllowedCACertsDatabaseTableName; + AddExtraCertColumnsL(aDatabase,tableName); + + CleanupStack::PopAndDestroy( buf ); // Delete buf or sqlStatement + CleanupStack::Pop( &aDatabase ); + CleanupStack::Pop( &aSession ); + + aDatabase.Compact(); +} + +void EapTlsPeapUtils::OpenPeapDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenPeapDatabaseL -Start- aIndexType=%d, aIndex=%d, Tunneling vendor type=%d \n"), + aIndexType,aIndex, aTunnelingVendorType)); + + // 1. Open/create a database + + // Connect to the DBMS server. + User::LeaveIfError(aSession.Connect()); + CleanupClosePushL(aSession); + // aSession and aDatabase are pushed to the cleanup stack even though they may be member + // variables of the calling class and would be closed in the destructor anyway. This ensures + // that if they are not member variables they will be closed. Closing the handle twice + // does no harm. + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = aDatabase.Create(aSession, KPeapDatabaseName, KSecureUIDFormat); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::OpenPeapDatabaseL - Created Secure DB for eappeap.dat. err=%d\n"), err) ); + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(aSession, KPeapDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(aDatabase); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = aDatabase.Create(fsSession, KPeapDatabaseName); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::OpenPeapDatabaseL - Created Non-Secure DB for eappeap.dat. err=%d\n"), err) ); + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(fsSession, KPeapDatabaseName)); + + CleanupStack::PopAndDestroy(); // close fsSession + + CleanupClosePushL(aDatabase); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + // 2. Create the eappeap table to database (ignore error if exists) + +// Table columns: +//// NAME /////////////////////////////////////////////// TYPE ////////////// Constant /////////////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| EAP_TLS_PEAP_use_manual_realm | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_manual_realm_literal |// +//| EAP_TLS_PEAP_manual_realm | VARCHAR(255) | cf_str_EAP_TLS_PEAP_manual_realm_literal |// +//| EAP_TLS_PEAP_use_manual_username | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_manual_username_literal |// +//| EAP_TLS_PEAP_manual_username | VARCHAR(255) | cf_str_EAP_TLS_PEAP_manual_username_literal |// +//| EAP_TLS_PEAP_max_count_of_session_resumes | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_max_count_of_session_resumes_literal |// +//| EAP_TLS_PEAP_cipher_suite | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_cipher_suite_literal |// +//| EAP_TLS_PEAP_used_PEAP_version | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_used_PEAP_version_literal |// +//| EAP_TLS_PEAP_accepted_PEAP_versions | BINARY(12) | cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal|// +//| PEAP_accepted_tunneled_client_types | VARBINARY(240) | cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal |// +//| PEAP_unaccepted_tunneled_client_types | VARBINARY(240) | cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal |// +//| EAP_TLS_server_authenticates_client | UNSIGNED INTEGER | cf_str_TLS_server_authenticates_client_policy_in_client_literal|// +//| CA_cert_label | VARCHAR(255) | KCACertLabelOld |// +//| client_cert_label | VARCHAR(255) | KClientCertLabel |// +//| EAP_TLS_PEAP_saved_session_id | BINARY(32) | cf_str_EAP_TLS_PEAP_saved_session_id_literal |// +//| EAP_TLS_PEAP_saved_master_secret | BINARY(48) | cf_str_EAP_TLS_PEAP_saved_master_secret_literal |// +//| EAP_TLS_PEAP_saved_cipher_suite | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_saved_cipher_suite_literal |// +//| EAP_TLS_PEAP_verify_certificate_realm | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal |// +//| EAP_PEAP_max_session_validity_time | BIGINT | cf_str_EAP_PEAP_max_session_validity_time_literal |// +//| EAP_PEAP_last_full_authentication_time | BIGINT | KPEAPLastFullAuthTime |// +//| EAP_TLS_PEAP_use_identity_privacy | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_identity_privacy_literal|// +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // Table creation is divided into two parts because otherwise the SQL string would get too long + _LIT(KSQLCreateTable1, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S BINARY(%d), \ + %S VARBINARY(%d), \ + %S VARBINARY(%d), \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S BIGINT, \ + %S BIGINT, \ + %S UNSIGNED INTEGER)"); + sqlStatement.Format(KSQLCreateTable1, + &KPeapDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &cf_str_EAP_TLS_PEAP_use_manual_realm_literal, + &cf_str_EAP_TLS_PEAP_manual_realm_literal, KMaxManualRealmLengthInDB, + &cf_str_EAP_TLS_PEAP_use_manual_username_literal, + &cf_str_EAP_TLS_PEAP_manual_username_literal, KMaxManualUsernameLengthInDB, + &cf_str_EAP_TLS_PEAP_cipher_suite_literal, + &cf_str_EAP_TLS_PEAP_used_PEAP_version_literal, + &cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal, KMaxPEAPVersionsStringLengthInDB, + &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, KMaxTunneledTypeStringLengthInDB, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, KMaxTunneledTypeStringLengthInDB, + &cf_str_TLS_server_authenticates_client_policy_in_client_literal, + &KCACertLabelOld, KMaxCertLabelLengthInDB, + &KClientCertLabel, KMaxCertLabelLengthInDB, + &cf_str_EAP_TLS_PEAP_saved_session_id_literal, KMaxSessionIdLengthInDB, + &cf_str_EAP_TLS_PEAP_saved_master_secret_literal, KMaxMasterSecretLengthInDB, + &cf_str_EAP_TLS_PEAP_saved_cipher_suite_literal, + &cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal, + &cf_str_EAP_PEAP_max_session_validity_time_literal, + &KPEAPLastFullAuthTime, + &cf_str_EAP_TLS_PEAP_use_identity_privacy_literal); + + err = aDatabase.Execute(sqlStatement); + if (err == KErrAlreadyExists) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::OpenPeapDatabaseL - Alter Table err=%d\n"), err) ); + _LIT( KColumnDef, "UNSIGNED INTEGER" ); + AlterTableL( aDatabase, EAddColumn , KPeapDatabaseTableName, + cf_str_EAP_TLS_PEAP_use_identity_privacy_literal, KColumnDef); + } + else if (err != KErrNone) + { + User::Leave(err); + } + + // Create table for _allowed_ user certificates + +//// NAME ////////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CertLabel | VARCHAR(255) | KCACertLabel |// +//| SubjectKeyId | BINARY(20) | KSubjectKeyIdentifier |// This is Symbian subjectkey id +//| ActualSubjectKeyId | BINARY(20) | KActualSubjectKeyIdentifier |// This is the actual subjectkeyid present in the certificate. +//| SubjectName | VARCHAR(255) | KSubjectName |// +//| IssuerName | VARCHAR(255) | KIssuerName |// +//| SerialNumber | VARCHAR(255) | KSerialNumber |// +//| Thumbprint | BINARY(64) | KThumbprint |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable2, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BINARY(%d))"); + + sqlStatement.Format(KSQLCreateTable2, &KPeapAllowedUserCertsDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &KCertLabel, KMaxCertLabelLengthInDB, + &KSubjectKeyIdentifier, KMaxSubjectKeyIdLengthInDB, + &KActualSubjectKeyIdentifier, KKeyIdentifierLength, + &KSubjectName, KGeneralStringMaxLength, + &KIssuerName, KGeneralStringMaxLength, + &KSerialNumber, KGeneralStringMaxLength, + &KThumbprint, KThumbprintMaxLength); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // Create table for _allowed_ CA certs + +//// NAME ////////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CACertLabel | VARCHAR(255) | KCACertLabel |// +//| SubjectKeyId | BINARY(20) | KSubjectKeyIdentifier |// This is Symbian subjectkey id +//| ActualSubjectKeyId | BINARY(20) | KActualSubjectKeyIdentifier |// This is the actual subjectkeyid present in the certificate. +//| SubjectName | VARCHAR(255) | KSubjectName |// +//| IssuerName | VARCHAR(255) | KIssuerName |// +//| SerialNumber | VARCHAR(255) | KSerialNumber |// +//| Thumbprint | BINARY(64) | KThumbprint |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable3, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BINARY(%d))"); + + sqlStatement.Format(KSQLCreateTable3, &KPeapAllowedCACertsDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &KCertLabel, KMaxCertLabelLengthInDB, + &KSubjectKeyIdentifier, KMaxSubjectKeyIdLengthInDB, + &KActualSubjectKeyIdentifier, KKeyIdentifierLength, + &KSubjectName, KGeneralStringMaxLength, + &KIssuerName, KGeneralStringMaxLength, + &KSerialNumber, KGeneralStringMaxLength, + &KThumbprint, KThumbprintMaxLength); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // Create table for _allowed_ cipher suites + +//// NAME ///////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CipherSuite | UNSIGNED INTEGER | KCipherSuite |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable4, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER)"); + + sqlStatement.Format(KSQLCreateTable4, &KPeapAllowedCipherSuitesDatabaseTableName, + &KServiceType, &KServiceIndex, &KTunnelingType, &KCipherSuite); + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // 4. Check if database table contains a row for this service type and id + + _LIT(KSQLQueryRow, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQLQueryRow, &KPeapDatabaseTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + // View must be closed when no longer needed + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // 5. If row is not found then add it + + TInt rows = view.CountL(); + CleanupStack::PopAndDestroy(); // view + if (rows == 0) + { + _LIT(KSQLInsert, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert, &KPeapDatabaseTableName); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly)); + CleanupClosePushL(view); + view.InsertL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Set the default values. The other three tables (certs, ca certs & cipher suites) are empty by default. + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_realm_literal), default_EAP_TLS_PEAP_use_manual_realm); + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_realm_literal), default_EAP_TLS_PEAP_manual_realm); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_username_literal), default_EAP_TLS_PEAP_use_manual_username); + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_username_literal), default_EAP_TLS_PEAP_manual_username); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_cipher_suite_literal), default_EAP_TLS_PEAP_cipher_suite); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_used_PEAP_version_literal), default_EAP_TLS_PEAP_used_PEAP_version); + + TInt i(0); + + while (default_EAP_TLS_PEAP_accepted_PEAP_versions[i] != -1) + { + i++; + } + + TBuf8 tmp; + + tmp.Copy(reinterpret_cast (default_EAP_TLS_PEAP_accepted_PEAP_versions), i * sizeof(TInt)); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal), tmp); + + view.SetColL(colSet->ColNo(cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal), default_PEAP_tunneled_types); + view.SetColL(colSet->ColNo(cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal), default_PEAP_tunneled_types); + + view.SetColL(colSet->ColNo(cf_str_TLS_server_authenticates_client_policy_in_client_literal), default_EAP_PEAP_TTLS_server_authenticates_client); + view.SetColL(colSet->ColNo(KCACertLabelOld), default_CA_cert_label); + view.SetColL(colSet->ColNo(KClientCertLabel), default_client_cert_label); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal), default_EAP_TLS_PEAP_verify_certificate_realm); + + view.SetColL(colSet->ColNo(cf_str_EAP_PEAP_max_session_validity_time_literal), default_MaxSessionTime); + + view.SetColL(colSet->ColNo(KPEAPLastFullAuthTime), default_FullAuthTime); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_identity_privacy_literal), default_EAP_TLS_PEAP_TLS_Privacy); + + view.PutL(); + + CleanupStack::PopAndDestroy(colSet); + CleanupStack::PopAndDestroy( &view ); // Close view. + + // Add default disabled cipher suites + _LIT(KSQLInsert2, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert2, &KPeapAllowedCipherSuitesDatabaseTableName); + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly)); + CleanupClosePushL(view); + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + i = 0; + while (default_allowed_cipher_suites[i] != 0) + { + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + view.SetColL(colSet->ColNo(KCipherSuite), default_allowed_cipher_suites[i]); + view.PutL(); + i++; + } + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + CleanupStack::PopAndDestroy( &view ); // Close view. + } + + // 6. Do the altering of tables here. + // Add columns to existing certificate DB tables for Serial number, Issuer name etc. + + TBufC tableName; + + // For the table _allowed_ USER certificates + tableName = KPeapAllowedUserCertsDatabaseTableName; + AddExtraCertColumnsL(aDatabase,tableName); + + // For the table _allowed_ CA certificates + tableName = KPeapAllowedCACertsDatabaseTableName; + AddExtraCertColumnsL(aDatabase,tableName); + + CleanupStack::PopAndDestroy( buf ); // Delete buf or sqlStatement + CleanupStack::Pop( &aDatabase ); + CleanupStack::Pop( &aSession ); + + aDatabase.Compact(); +} + +#if defined(USE_TTLS_EAP_TYPE) + +// --------------------------------------------------------- +// EapTlsPeapUtils::OpenTtlsDatabaseL() +// --------------------------------------------------------- +// +void EapTlsPeapUtils::OpenTtlsDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenTtlsDatabaseL -Start- aIndexType=%d, aIndex=%d, Tunneling vendor type=%d \n"), + aIndexType,aIndex, aTunnelingVendorType)); + + // 1. Open/create a database + + // Connect to the DBMS server. + User::LeaveIfError(aSession.Connect()); + CleanupClosePushL(aSession); + // aSession and aDatabase are pushed to the cleanup stack even though they may be member + // variables of the calling class and would be closed in the destructor anyway. This ensures + // that if they are not member variables they will be closed. Closing the handle twice + // does no harm. + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = aDatabase.Create(aSession, KTtlsDatabaseName, KSecureUIDFormat); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::OpenTtlsDatabaseL - Created Secure DB for eapttls.dat. err=%d\n"), err) ); + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(aSession, KTtlsDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(aDatabase); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = aDatabase.Create(fsSession, KTtlsDatabaseName); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::OpenTtlsDatabaseL - Created Non-Secure DB for eapttls.dat. err=%d\n"), err) ); + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(fsSession, KTtlsDatabaseName)); + + CleanupStack::PopAndDestroy(); // close fsSession + + CleanupClosePushL(aDatabase); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + // 2. Create the eapttls table to database (ignore error if exists) + +// Table columns: +//// NAME //////////////////////////////////////////// TYPE ////////////// Constant /////////////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| EAP_TLS_PEAP_use_manual_realm | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_manual_realm_literal |// +//| EAP_TLS_PEAP_manual_realm | VARCHAR(255) | cf_str_EAP_TLS_PEAP_manual_realm_literal |// +//| EAP_TLS_PEAP_use_manual_username | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_manual_username_literal |// +//| EAP_TLS_PEAP_manual_username | VARCHAR(255) | cf_str_EAP_TLS_PEAP_manual_username_literal |// +//| EAP_TLS_PEAP_cipher_suite | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_cipher_suite_literal |// +//| EAP_TLS_PEAP_used_PEAP_version | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_used_PEAP_version_literal |// +//| EAP_TLS_PEAP_accepted_PEAP_versions | BINARY(12) | cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal|// +//| PEAP_accepted_tunneled_client_types | VARBINARY(240) | cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal |// +//| PEAP_unaccepted_tunneled_client_types | VARBINARY(240) | cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal |// +//| EAP_TLS_server_authenticates_client | UNSIGNED INTEGER | cf_str_TLS_server_authenticates_client_policy_in_client_literal|// +//| CA_cert_label | VARCHAR(255) | KCACertLabelOld |// +//| client_cert_label | VARCHAR(255) | KClientCertLabel |// +//| EAP_TLS_PEAP_saved_session_id | BINARY(32) | cf_str_EAP_TLS_PEAP_saved_session_id_literal |// +//| EAP_TLS_PEAP_saved_master_secret | BINARY(48) | cf_str_EAP_TLS_PEAP_saved_master_secret_literal |// +//| EAP_TLS_PEAP_saved_cipher_suite | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_saved_cipher_suite_literal |// +//| EAP_TLS_PEAP_verify_certificate_realm | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal |// +//| EAP_TTLS_max_session_validity_time | BIGINT | cf_str_EAP_TTLS_max_session_validity_time_literal |// +//| EAP_TTLS_last_full_authentication_time | BIGINT | KTTLSLastFullAuthTime |// +//| EAP_TLS_PEAP_use_identity_privacy | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_identity_privacy_literal |// + + +//| EAP_TLS_PEAP_ttls_pap_password_prompt | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal |// +//| EAP_TLS_PEAP_ttls_pap_username | VARCHAR(253) | cf_str_EAP_TLS_PEAP_ttls_pap_username_literal |// +//| EAP_TLS_PEAP_ttls_pap_password | VARCHAR(128) | cf_str_EAP_TLS_PEAP_ttls_pap_password_literal |// +//| EAP_TLS_PEAP_ttls_pap_max_session_validity_time | BIGINT | cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal |// +//| EAP_TLS_PEAP_ttls_pap_last_full_authentication_time | BIGINT | KTTLSPAPLastFullAuthTime |// + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + +// Table creation is divided into two parts because otherwise the SQL string would get too long + _LIT(KSQLCreateTable1, + "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S BINARY(%d), \ + %S VARBINARY(%d), \ + %S VARBINARY(%d), \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S BIGINT, \ + %S BIGINT, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BIGINT, \ + %S BIGINT)"); + + sqlStatement.Format( KSQLCreateTable1, + &KTtlsDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &cf_str_EAP_TLS_PEAP_use_manual_realm_literal, + &cf_str_EAP_TLS_PEAP_manual_realm_literal, KMaxManualRealmLengthInDB, + &cf_str_EAP_TLS_PEAP_use_manual_username_literal, + &cf_str_EAP_TLS_PEAP_manual_username_literal, KMaxManualUsernameLengthInDB, + &cf_str_EAP_TLS_PEAP_cipher_suite_literal, + &cf_str_EAP_TLS_PEAP_used_PEAP_version_literal, + &cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal, KMaxPEAPVersionsStringLengthInDB, + &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, KMaxTunneledTypeStringLengthInDB, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, KMaxTunneledTypeStringLengthInDB, + &cf_str_TLS_server_authenticates_client_policy_in_client_literal, + &KCACertLabelOld, KMaxCertLabelLengthInDB, + &KClientCertLabel, KMaxCertLabelLengthInDB, + &cf_str_EAP_TLS_PEAP_saved_session_id_literal, KMaxSessionIdLengthInDB, + &cf_str_EAP_TLS_PEAP_saved_master_secret_literal, KMaxMasterSecretLengthInDB, + &cf_str_EAP_TLS_PEAP_saved_cipher_suite_literal, + &cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal, + &cf_str_EAP_TTLS_max_session_validity_time_literal, + &KTTLSLastFullAuthTime, + &cf_str_EAP_TLS_PEAP_use_identity_privacy_literal, + &cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal, + &cf_str_EAP_TLS_PEAP_ttls_pap_username_literal, KMaxPapUserNameLengthInDb, + &cf_str_EAP_TLS_PEAP_ttls_pap_password_literal, KMaxPapPasswordLengthInDb, + &cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal, + &KTTLSPAPLastFullAuthTime ); + + + + err = aDatabase.Execute(sqlStatement); + if (err == KErrAlreadyExists) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::OpenTtlsDatabaseL - Alter Table err=%d\n"), err) ); + + _LIT( KColumnDef, "UNSIGNED INTEGER" ); + AlterTableL( aDatabase, EAddColumn , KTtlsDatabaseTableName, + cf_str_EAP_TLS_PEAP_use_identity_privacy_literal, KColumnDef); + + _LIT( KColumnDef1, "UNSIGNED INTEGER" ); + AlterTableL( aDatabase, EAddColumn , KTtlsDatabaseTableName, + cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal, KColumnDef1); + + HBufC* buf1 = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf1->Des(); + + _LIT(KSQLAlterTableForVar, "VARCHAR (%d)"); + + sqlStatement.Format(KSQLAlterTableForVar, KMaxPapUserNameLengthInDb); + + AlterTableL( aDatabase, EAddColumn , KTtlsDatabaseTableName, + cf_str_EAP_TLS_PEAP_ttls_pap_username_literal, sqlStatement); + + sqlStatement.Format(KSQLAlterTableForVar, KMaxPapPasswordLengthInDb); + + AlterTableL( aDatabase, EAddColumn , KTtlsDatabaseTableName, + cf_str_EAP_TLS_PEAP_ttls_pap_password_literal, sqlStatement); + + CleanupStack::PopAndDestroy(buf1); + + _LIT( KColumnDef4, "BIGINT" ); + AlterTableL( aDatabase, EAddColumn , KTtlsDatabaseTableName, + cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal, KColumnDef4); + + _LIT( KColumnDef5, "BIGINT" ); + AlterTableL( aDatabase, EAddColumn , KTtlsDatabaseTableName, + KTTLSPAPLastFullAuthTime, KColumnDef5); + + } + else if (err != KErrNone) + { + User::Leave(err); + } + + // Create table for _allowed_ user certificates + +//// NAME ////////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CertLabel | VARCHAR(255) | KCACertLabel |// +//| SubjectKeyId | BINARY(20) | KSubjectKeyIdentifier |// This is Symbian subjectkey id +//| ActualSubjectKeyId | BINARY(20) | KActualSubjectKeyIdentifier |// This is the actual subjectkeyid present in the certificate. +//| SubjectName | VARCHAR(255) | KSubjectName |// +//| IssuerName | VARCHAR(255) | KIssuerName |// +//| SerialNumber | VARCHAR(255) | KSerialNumber |// +//| Thumbprint | BINARY(64) | KThumbprint |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable2, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BINARY(%d))"); + + sqlStatement.Format(KSQLCreateTable2, &KTtlsAllowedUserCertsDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &KCertLabel, KMaxCertLabelLengthInDB, + &KSubjectKeyIdentifier, KMaxSubjectKeyIdLengthInDB, + &KActualSubjectKeyIdentifier, KKeyIdentifierLength, + &KSubjectName, KGeneralStringMaxLength, + &KIssuerName, KGeneralStringMaxLength, + &KSerialNumber, KGeneralStringMaxLength, + &KThumbprint, KThumbprintMaxLength); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // Create table for _allowed_ CA certs + +//// NAME ////////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CACertLabel | VARCHAR(255) | KCACertLabel |// +//| SubjectKeyId | BINARY(20) | KSubjectKeyIdentifier |// This is Symbian subjectkey id +//| ActualSubjectKeyId | BINARY(20) | KActualSubjectKeyIdentifier |// This is the actual subjectkeyid present in the certificate. +//| SubjectName | VARCHAR(255) | KSubjectName |// +//| IssuerName | VARCHAR(255) | KIssuerName |// +//| SerialNumber | VARCHAR(255) | KSerialNumber |// +//| Thumbprint | BINARY(64) | KThumbprint |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable3, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BINARY(%d))"); + + sqlStatement.Format(KSQLCreateTable3, &KTtlsAllowedCACertsDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &KCertLabel, KMaxCertLabelLengthInDB, + &KSubjectKeyIdentifier, KMaxSubjectKeyIdLengthInDB, + &KActualSubjectKeyIdentifier, KKeyIdentifierLength, + &KSubjectName, KGeneralStringMaxLength, + &KIssuerName, KGeneralStringMaxLength, + &KSerialNumber, KGeneralStringMaxLength, + &KThumbprint, KThumbprintMaxLength); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // Create table for _allowed_ cipher suites + +//// NAME ///////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CipherSuite | UNSIGNED INTEGER | KCipherSuite |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable4, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER)"); + + sqlStatement.Format(KSQLCreateTable4, &KTtlsAllowedCipherSuitesDatabaseTableName, + &KServiceType, &KServiceIndex, &KTunnelingType, &KCipherSuite); + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // 4. Check if database table contains a row for this service type and id + + _LIT(KSQLQueryRow, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQLQueryRow, &KTtlsDatabaseTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + // View must be closed when no longer needed + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // 5. If row is not found then add it + + TInt rows = view.CountL(); + CleanupStack::PopAndDestroy(); // view + if (rows == 0) + { + _LIT(KSQLInsert, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert, &KTtlsDatabaseTableName); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly)); + CleanupClosePushL(view); + view.InsertL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Set the default values. The other three tables (certs, ca certs & cipher suites) are empty by default. + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_realm_literal), default_EAP_TLS_PEAP_use_manual_realm); + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_realm_literal), default_EAP_TLS_PEAP_manual_realm); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_username_literal), default_EAP_TLS_PEAP_use_manual_username); + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_username_literal), default_EAP_TLS_PEAP_manual_username); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_cipher_suite_literal), default_EAP_TLS_PEAP_cipher_suite); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_used_PEAP_version_literal), default_EAP_TLS_PEAP_used_PEAP_version); + + TInt i(0); + + while (default_EAP_TLS_PEAP_accepted_PEAP_versions[i] != -1) + { + i++; + } + + TBuf8 tmp; + + tmp.Copy(reinterpret_cast (default_EAP_TLS_PEAP_accepted_PEAP_versions), i * sizeof(TInt)); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal), tmp); + + view.SetColL(colSet->ColNo(cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal), default_PEAP_tunneled_types); + view.SetColL(colSet->ColNo(cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal), default_PEAP_tunneled_types); + + view.SetColL(colSet->ColNo(cf_str_TLS_server_authenticates_client_policy_in_client_literal), default_EAP_PEAP_TTLS_server_authenticates_client); + view.SetColL(colSet->ColNo(KCACertLabelOld), default_CA_cert_label); + + view.SetColL(colSet->ColNo(KClientCertLabel), default_client_cert_label); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal), default_EAP_TLS_PEAP_verify_certificate_realm); + + view.SetColL(colSet->ColNo(cf_str_EAP_TTLS_max_session_validity_time_literal), default_MaxSessionTime); + + view.SetColL(colSet->ColNo(KTTLSLastFullAuthTime), default_FullAuthTime); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_identity_privacy_literal), default_EAP_TLS_PEAP_TLS_Privacy); + + + view.SetColL( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal ), + KDefaultPapPasswordPrompt ); + + view.SetColL( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_username_literal ), + KDefaultPapUserName ); + + view.SetColL( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_password_literal ), + KDefaultPapPassword ); + + view.SetColL( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal ), + KDefaultMaxPapSessionTime ); + + view.SetColL( + colSet->ColNo( KTTLSPAPLastFullAuthTime ), + KDefaultFullPapAuthTime ); + + + view.PutL(); + + CleanupStack::PopAndDestroy(colSet); + CleanupStack::PopAndDestroy( &view ); // Close view. + + // Add default disabled cipher suites + _LIT(KSQLInsert2, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert2, &KTtlsAllowedCipherSuitesDatabaseTableName); + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly)); + CleanupClosePushL(view); + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + i = 0; + while (default_allowed_cipher_suites[i] != 0) + { + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + view.SetColL(colSet->ColNo(KCipherSuite), default_allowed_cipher_suites[i]); + view.PutL(); + i++; + } + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + CleanupStack::PopAndDestroy( &view ); // Close view. + } + + // 6. Do the altering of tables here. + // Add columns to existing certificate DB tables for Serial number, Issuer name etc. + + TBufC tableName; + + // For the table _allowed_ USER certificates + tableName = KTtlsAllowedUserCertsDatabaseTableName; + AddExtraCertColumnsL(aDatabase,tableName); + + // For the table _allowed_ CA certificates + tableName = KTtlsAllowedCACertsDatabaseTableName; + AddExtraCertColumnsL(aDatabase,tableName); + + CleanupStack::PopAndDestroy( buf ); // Delete buf or sqlStatement + CleanupStack::Pop( &aDatabase ); + CleanupStack::Pop( &aSession ); + + aDatabase.Compact(); + +} // EapTlsPeapUtils::OpenTtlsDatabaseL() + +#endif // #if defined(USE_TTLS_EAP_TYPE) + +#if defined(USE_FAST_EAP_TYPE) + +// --------------------------------------------------------- +// EapTlsPeapUtils::OpenFastDatabaseL() +// --------------------------------------------------------- +// +void EapTlsPeapUtils::OpenFastDatabaseL( + RDbNamedDatabase& aDatabase, + RDbs& aSession, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType) + { +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL -Start- aIndexType=%d, aIndex=%d, Tunneling vendor type=%d \n"), + aIndexType,aIndex, aTunnelingVendorType)); + + // 1. Open/create a database + + // Connect to the DBMS server. + User::LeaveIfError(aSession.Connect()); + CleanupClosePushL(aSession); + // aSession and aDatabase are pushed to the cleanup stack even though they may be member + // variables of the calling class and would be closed in the destructor anyway. This ensures + // that if they are not member variables they will be closed. Closing the handle twice + // does no harm. + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = aDatabase.Create(aSession, KFastDatabaseName, KSecureUIDFormat); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL - Created Secure DB for eapfast.dat. err=%d (-11=DB created before)\n"), + err) ); + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(aSession, KFastDatabaseName, KSecureUIDFormat)); + CleanupClosePushL(aDatabase); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = aDatabase.Create(fsSession, KFastDatabaseName); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::OpenFastDatabaseL - Created Non-Secure DB for eapfast.dat. err=%d\n"), err) ); + + if(err == KErrNone) + { + aDatabase.Close(); + + } else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + User::LeaveIfError(aDatabase.Open(fsSession, KFastDatabaseName)); + + CleanupStack::PopAndDestroy(); // close fsSession + + CleanupClosePushL(aDatabase); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + // 2. Create the eapfast tables to database (ignore error if exists) + + // Table 1: Create table for general settings of EAP-FAST. + +// Table columns: +//// NAME //////////////////////////////////////////// TYPE ////////////// Constant /////////////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| EAP_TLS_PEAP_use_manual_realm | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_manual_realm_literal |// +//| EAP_TLS_PEAP_manual_realm | VARCHAR(255) | cf_str_EAP_TLS_PEAP_manual_realm_literal |// +//| EAP_TLS_PEAP_use_manual_username | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_manual_username_literal |// +//| EAP_TLS_PEAP_manual_username | VARCHAR(255) | cf_str_EAP_TLS_PEAP_manual_username_literal |// +//| EAP_TLS_PEAP_cipher_suite | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_cipher_suite_literal |// +//| EAP_TLS_PEAP_used_PEAP_version | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_used_PEAP_version_literal |// +//| EAP_TLS_PEAP_accepted_PEAP_versions | BINARY(12) | cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal|// +//| PEAP_accepted_tunneled_client_types | VARBINARY(240) | cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal |// +//| PEAP_unaccepted_tunneled_client_types | VARBINARY(240) | cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal |// +//| EAP_TLS_server_authenticates_client | UNSIGNED INTEGER | cf_str_TLS_server_authenticates_client_policy_in_client_literal|// +//| EAP_TLS_PEAP_saved_session_id | BINARY(32) | cf_str_EAP_TLS_PEAP_saved_session_id_literal |// +//| EAP_TLS_PEAP_saved_master_secret | BINARY(48) | cf_str_EAP_TLS_PEAP_saved_master_secret_literal |// +//| EAP_TLS_PEAP_saved_cipher_suite | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_saved_cipher_suite_literal |// +//| EAP_TLS_PEAP_verify_certificate_realm | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal |// +//| EAP_FAST_max_session_validity_time | BIGINT | cf_str_EAP_FAST_max_session_validity_time_literal |// +//| EAP_FAST_last_full_authentication_time | BIGINT | KFASTLastFullAuthTime |// +//| EAP_TLS_PEAP_use_identity_privacy | UNSIGNED INTEGER | cf_str_EAP_TLS_PEAP_use_identity_privacy_literal |// +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** moved to PAC store db, because time is the same for all IAPs **/ +//| EAP_FAST_last_password_identity_time | BIGINT | KFASTLastPasswordIdentityTime |// +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL - Creating the tables for EAP-FAST\n"))); + + _LIT(KSQLCreateTable1, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S BINARY(%d), \ + %S VARBINARY(%d), \ + %S VARBINARY(%d), \ + %S UNSIGNED INTEGER, \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S BIGINT, \ + %S BIGINT, \ + %S UNSIGNED INTEGER)"); + + sqlStatement.Format(KSQLCreateTable1, &KFastGeneralSettingsDBTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &cf_str_EAP_TLS_PEAP_use_manual_realm_literal, + &cf_str_EAP_TLS_PEAP_manual_realm_literal, KMaxManualRealmLengthInDB, + &cf_str_EAP_TLS_PEAP_use_manual_username_literal, + &cf_str_EAP_TLS_PEAP_manual_username_literal, KMaxManualUsernameLengthInDB, + &cf_str_EAP_TLS_PEAP_cipher_suite_literal, + &cf_str_EAP_TLS_PEAP_used_PEAP_version_literal, + &cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal, KMaxPEAPVersionsStringLengthInDB, + &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, KMaxTunneledTypeStringLengthInDB, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, KMaxTunneledTypeStringLengthInDB, + &cf_str_TLS_server_authenticates_client_policy_in_client_literal, + &cf_str_EAP_TLS_PEAP_saved_session_id_literal, KMaxSessionIdLengthInDB, + &cf_str_EAP_TLS_PEAP_saved_master_secret_literal, KMaxMasterSecretLengthInDB, + &cf_str_EAP_TLS_PEAP_saved_cipher_suite_literal, + &cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal, + &cf_str_EAP_FAST_max_session_validity_time_literal, + &KFASTLastFullAuthTime, + &cf_str_EAP_TLS_PEAP_use_identity_privacy_literal); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL - SQL query formated OK\n"))); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL Created General settings table\n"))); + + // Table 2: Create table for Special settings of EAP-FAST. + +// Table columns: +//// NAME //////////////////////////////////////////// TYPE ////////////// Constant /////////////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| EAP_FAST_allow_server_authenticated_provisioning_mode| UNSIGNED INTEGER | cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal |// +//| EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP| UNSIGNED INTEGER | cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal |// +//| EAP_FAST_Warn_ADHP_No_PAC | UNSIGNED INTEGER | KFASTWarnADHPNoPACP|// +//| EAP_FAST_Warn_ADHP_No_Matching_PAC | UNSIGNED INTEGER | KFASTWarnADHPNoMatchingPAC|// +//| EAP_FAST_Warn_Not_Default_Server | UNSIGNED INTEGER | KFASTWarnNotDefaultServer|// +//| EAP_FAST_PAC_Group_Import_Reference_Collection| VARCHAR(255) | KFASTPACGroupImportReferenceCollection |// +//| EAP_FAST_PAC_Group_DB_Reference_Collection | BINARY(255) | KFASTPACGroupDBReferenceCollection |// +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + _LIT(KSQLCreateTable2, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S BINARY(%d) )"); + + sqlStatement.Format(KSQLCreateTable2, &KFastSpecialSettingsDBTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal, + &cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal, + &KFASTWarnADHPNoPAC, + &KFASTWarnADHPNoMatchingPAC, + &KFASTWarnNotDefaultServer, + &KFASTPACGroupImportReferenceCollection, KMaxPACGroupRefCollectionLengthInDB, + &KFASTPACGroupDBReferenceCollection, KMaxPACGroupRefCollectionLengthInDB); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL - SQL query formated OK\n"))); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL Created Specific settings table\n"))); + + // Table 3: Create table for _allowed_ user certificates + +//// NAME ////////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CertLabel | VARCHAR(255) | KCACertLabel |// +//| SubjectKeyId | BINARY(20) | KSubjectKeyIdentifier |// This is Symbian subjectkey id +//| ActualSubjectKeyId | BINARY(20) | KActualSubjectKeyIdentifier |// This is the actual subjectkeyid present in the certificate. +//| SubjectName | VARCHAR(255) | KSubjectName |// +//| IssuerName | VARCHAR(255) | KIssuerName |// +//| SerialNumber | VARCHAR(255) | KSerialNumber |// +//| Thumbprint | BINARY(64) | KThumbprint |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable3, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BINARY(%d))"); + + sqlStatement.Format(KSQLCreateTable3, &KFastAllowedUserCertsDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &KCertLabel, KMaxCertLabelLengthInDB, + &KSubjectKeyIdentifier, KMaxSubjectKeyIdLengthInDB, + &KActualSubjectKeyIdentifier, KKeyIdentifierLength, + &KSubjectName, KGeneralStringMaxLength, + &KIssuerName, KGeneralStringMaxLength, + &KSerialNumber, KGeneralStringMaxLength, + &KThumbprint, KThumbprintMaxLength); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL - SQL query formated OK\n"))); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL Created User certificates table\n"))); + + // Table 4: Create table for _allowed_ CA certs + +//// NAME ////////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CACertLabel | VARCHAR(255) | KCACertLabel |// +//| SubjectKeyId | BINARY(20) | KSubjectKeyIdentifier |// This is Symbian subjectkey id +//| ActualSubjectKeyId | BINARY(20) | KActualSubjectKeyIdentifier |// This is the actual subjectkeyid present in the certificate. +//| SubjectName | VARCHAR(255) | KSubjectName |// +//| IssuerName | VARCHAR(255) | KIssuerName |// +//| SerialNumber | VARCHAR(255) | KSerialNumber |// +//| Thumbprint | BINARY(64) | KThumbprint |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable4, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S VARCHAR(%d), \ + %S BINARY(%d), \ + %S BINARY(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S VARCHAR(%d), \ + %S BINARY(%d))"); + + sqlStatement.Format(KSQLCreateTable4, &KFastAllowedCACertsDatabaseTableName, + &KServiceType, + &KServiceIndex, + &KTunnelingType, + &KCertLabel, KMaxCertLabelLengthInDB, + &KSubjectKeyIdentifier, KMaxSubjectKeyIdLengthInDB, + &KActualSubjectKeyIdentifier, KKeyIdentifierLength, + &KSubjectName, KGeneralStringMaxLength, + &KIssuerName, KGeneralStringMaxLength, + &KSerialNumber, KGeneralStringMaxLength, + &KThumbprint, KThumbprintMaxLength); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL - SQL query formated OK\n"))); + + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL Created CA certificates table\n"))); + + // Table 5: Create table for _allowed_ cipher suites + +//// NAME ///////////////// TYPE ////////////// Constant /////////// +//| ServiceType | UNSIGNED INTEGER | KServiceType |// +//| ServiceIndex | UNSIGNED INTEGER | KServiceIndex |// +//| TunnelingType | UNSIGNED INTEGER | KTunnelingType |// +//| CipherSuite | UNSIGNED INTEGER | KCipherSuite |// +////////////////////////////////////////////////////////////////////////////////////////////////////// + + _LIT(KSQLCreateTable5, "CREATE TABLE %S (%S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER, \ + %S UNSIGNED INTEGER)"); + + sqlStatement.Format(KSQLCreateTable5, &KFastAllowedCipherSuitesDatabaseTableName, + &KServiceType, &KServiceIndex, &KTunnelingType, &KCipherSuite); + err = aDatabase.Execute(sqlStatement); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::OpenFastDatabaseL Created Cipher suites table\n"))); + + // 4. Check if database table contains a row for this service type and id + + _LIT(KSQLQueryRow, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQLQueryRow, &KFastGeneralSettingsDBTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + // View must be closed when no longer needed + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // 5. If a row is not found then add it + + TInt rows = view.CountL(); + CleanupStack::PopAndDestroy(); // view + if (rows == 0) + { + // This is to add default values to the General settings table. + _LIT(KSQLInsert, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert, &KFastGeneralSettingsDBTableName); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly)); + CleanupClosePushL(view); + view.InsertL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Set the default values. The other three tables (certs, ca certs & cipher suites) are empty by default. + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_realm_literal), default_EAP_TLS_PEAP_use_manual_realm); + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_realm_literal), default_EAP_TLS_PEAP_manual_realm); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_username_literal), default_EAP_TLS_PEAP_use_manual_username); + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_username_literal), default_EAP_TLS_PEAP_manual_username); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_cipher_suite_literal), default_EAP_TLS_PEAP_cipher_suite); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_used_PEAP_version_literal), default_EAP_TLS_PEAP_used_PEAP_version); + + TInt i(0); + + while (default_EAP_TLS_PEAP_accepted_PEAP_versions[i] != -1) + { + i++; + } + + TBuf8 tmp; + + tmp.Copy(reinterpret_cast (default_EAP_TLS_PEAP_accepted_PEAP_versions), i * sizeof(TInt)); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal), tmp); + + view.SetColL(colSet->ColNo(cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal), default_PEAP_tunneled_types); + view.SetColL(colSet->ColNo(cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal), default_PEAP_tunneled_types); + + view.SetColL(colSet->ColNo(cf_str_TLS_server_authenticates_client_policy_in_client_literal), default_EAP_PEAP_TTLS_server_authenticates_client); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal), default_EAP_TLS_PEAP_verify_certificate_realm); + + view.SetColL(colSet->ColNo(cf_str_EAP_FAST_max_session_validity_time_literal), default_MaxSessionTime); + + view.SetColL(colSet->ColNo(KFASTLastFullAuthTime), default_FullAuthTime); + + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_identity_privacy_literal), default_EAP_TLS_PEAP_TLS_Privacy); + + view.PutL(); + + CleanupStack::PopAndDestroy(colSet); + CleanupStack::PopAndDestroy( &view ); // Close view. + + //--------------------------------------------------------// + + // This is to add default values to the Specific settings table. + // KSQLInsert is "SELECT * FROM %S" + sqlStatement.Format(KSQLInsert, &KFastSpecialSettingsDBTableName); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly)); + CleanupClosePushL(view); + view.InsertL(); + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Set the default values. + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + + view.SetColL(colSet->ColNo(cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal), + default_EAP_FAST_Auth_Prov_Mode_Allowed); + view.SetColL(colSet->ColNo(cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal), + default_EAP_FAST_Unauth_Prov_Mode_Allowed); + + view.SetColL(colSet->ColNo(KFASTWarnADHPNoPAC), + default_EAP_FAST_Warn_ADHP_No_PAC); + + view.SetColL(colSet->ColNo(KFASTWarnADHPNoMatchingPAC), + default_EAP_FAST_Warn_ADHP_No_Matching_PAC); + + view.SetColL(colSet->ColNo(KFASTWarnNotDefaultServer), + default_EAP_FAST_Warn_Not_Default_Server); + + + + view.PutL(); + + CleanupStack::PopAndDestroy(colSet); + CleanupStack::PopAndDestroy( &view ); // Close view. + + //--------------------------------------------------------// + + // Add default disabled cipher suites to cipher suites table. + _LIT(KSQLInsert2, "SELECT * FROM %S"); + sqlStatement.Format(KSQLInsert2, &KFastAllowedCipherSuitesDatabaseTableName); + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly)); + CleanupClosePushL(view); + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + i = 0; + while (default_allowed_cipher_suites[i] != 0) + { + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), aIndex); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + view.SetColL(colSet->ColNo(KCipherSuite), default_allowed_cipher_suites[i]); + view.PutL(); + i++; + } + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + CleanupStack::PopAndDestroy( &view ); // Close view. + } + + CleanupStack::PopAndDestroy( buf ); // Delete buf or sqlStatement + CleanupStack::Pop( &aDatabase ); + CleanupStack::Pop( &aSession ); + + aDatabase.Compact(); + + } // EapTlsPeapUtils::OpenFastDatabaseL() + +#endif // #if defined(USE_FAST_EAP_TYPE) + +void EapTlsPeapUtils::SetIndexL( + RDbNamedDatabase& aDatabase, + const TDesC& aTableName, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const TIndexType aNewIndexType, + const TInt aNewIndex, + const eap_type_value_e aNewTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aNewTunnelingVendorType = aNewTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aNewTunnelingVendorType = static_cast(aNewTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetIndexL -Start- aIndexType=%d, aIndex=%d, Tunneling vendor type=%d \n"), + aIndexType, aIndex, aTunnelingVendorType)); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetIndexL -Start- aNewIndexType=%d, aNewIndex=%d, New Tunneling vendor type=%d \n"), + aNewIndexType, aNewIndex, aNewTunnelingVendorType)); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + // First delete the target + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &aTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + if (view.FirstL()) + { + do { + view.GetL(); + { + view.UpdateL(); + + view.SetColL(colSet->ColNo(KServiceType), static_cast(aNewIndexType)); + + view.SetColL(colSet->ColNo(KServiceIndex), static_cast(aNewIndex)); + + view.SetColL(colSet->ColNo(KTunnelingType), aNewTunnelingVendorType); + + view.PutL(); + } + } while (view.NextL() != EFalse); + } + + CleanupStack::PopAndDestroy(3); // view, colset +} + +void EapTlsPeapUtils::ReadCertRowsToArrayL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const /*aTools*/, + const TDesC& aTableName, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + RArray& aArray) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::ReadCertRowsToArrayL -Start")) ); + + HBufC* buf = HBufC::NewLC(512); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQLQueryRow, &aTableName, &KServiceType, + aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + if (view.FirstL()) + { + do { + + view.GetL(); + + { + SCertEntry certInfo; + // Store the line + TPtrC ptr = view.ColDes(colSet->ColNo(KCertLabel)); + + certInfo.iLabel.Copy(ptr); + + TPtrC8 ptr2 = view.ColDes8(colSet->ColNo(KSubjectKeyIdentifier)); // This is for authentication and uses Symbian subjectkey id. + certInfo.iSubjectKeyId.Copy(ptr2); + + aArray.Append(certInfo); + + EAP_TRACE_DEBUG_SYMBIAN((_L("ReadCertRowsToArrayL - Appended Cert with label=%S\n"), + &(certInfo.iLabel))); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("ReadCertRowsToArrayL - Appended Cert's SubjectKeyID:", + certInfo.iSubjectKeyId.Ptr(), certInfo.iSubjectKeyId.Size())); + } + + } while (view.NextL() != EFalse); + } + + // Close database + CleanupStack::PopAndDestroy(colSet); + CleanupStack::PopAndDestroy(2); // view, buf +} + +void EapTlsPeapUtils::ReadUintRowsToArrayL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const /*aTools*/, + const TDesC& aTableName, + const TDesC& aColumnName, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + RArray& aArray) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::ReadUintRowsToArrayL -Start")) ); + + HBufC* buf = HBufC::NewLC(512); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQLQueryRow, &aColumnName, &aTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + if (view.FirstL()) + { + do { + view.GetL(); + + switch (view.ColType(KDefaultColumnInView_One)) + { + case EDbColUint32: + { + // Store the line + TUint tmp = view.ColUint(KDefaultColumnInView_One); + aArray.Append(tmp); + } + break; + default: + User::Leave(KErrArgument); + } + + } while (view.NextL() != EFalse); + } + + // Close database + CleanupStack::PopAndDestroy(2); // view, buf +} + +// Don't use this finction as Label is not saved for certificates saved by SetConfigurationL(). +// Provisioning (OMA DM etc) use SetConfigurationL() to save certificate details. + +TBool EapTlsPeapUtils::CompareTCertLabels(const TCertLabel& item1, const TCertLabel& item2) +{ + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::CompareTCertLabels-Start")) ); + + if (item1 == item2) + { + return ETrue; + } + else + { + return EFalse; + } +} + +TBool EapTlsPeapUtils::CompareSCertEntries(const SCertEntry& item1, const SCertEntry& item2) +{ + EAP_TRACE_DEBUG_SYMBIAN((_L("\nEapTlsPeapUtils::CompareSCertEntries, Label_1=%S, Label_2=%S"), + &(item1.iLabel), &(item2.iLabel))); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::CompareSCertEntries, SubjectKeyID_1:", + item1.iSubjectKeyId.Ptr(), item1.iSubjectKeyId.Size())); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::CompareSCertEntries, SubjectKeyID_2:", + item2.iSubjectKeyId.Ptr(), item2.iSubjectKeyId.Size())); + + if (item1.iLabel == item2.iLabel || + item1.iLabel.Length() == 0 || + item2.iLabel.Length() == 0 ) // Label is not saved when certs are saved using OMA DM. + { + if (item1.iSubjectKeyId == item2.iSubjectKeyId) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::CompareSCertEntries, Certs matched\n"))); + + return ETrue; + } + } + + return EFalse; +} + + +#ifndef USE_EAP_EXPANDED_TYPES +// There are separate functions (SetTunnelingExpandedEapDataL and GetTunnelingExpandedEapDataL) if USE_EAP_EXPANDED_TYPES is defined. + +/** +* Sets EAP data to a binary string record in commsdat. +* The old format (NOT USED NOW) is "+123,- 34", + means enabled, - disabled, then id, id is always 3 characters for easy parsing. +* In the new format each EAP type is saved as an unsigned integer of 32 bits ( TUint). +* There is separate binary strings for accepted (enabled) and unaccepted (disabled) tunneled EAP types. +*/ + +void EapTlsPeapUtils::SetEapDataL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const /*aTools*/, + TEapArray &aEaps, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aEapVendorType = aEapType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aEapVendorType = static_cast(aEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapDataL aIndexType=%d, aIndex=%d, Tunneling vendor type=%d, Eap vendor type=%d, No: of tunneled EAP types=%d \n"), + aIndexType,aIndex, aTunnelingVendorType, aEapVendorType, aEaps.Count()) ); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + if (aEapType == eap_type_peap) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KPeapDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#if defined(USE_TTLS_EAP_TYPE) + else if (aEapType == eap_type_ttls) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KTtlsDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#endif + + else if (aEapType == eap_type_ttls_plain_pap) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KTtlsDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } + +#if defined(USE_FAST_EAP_TYPE) + else if (aEapType == eap_type_fast) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KFastGeneralSettingsDBTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#endif + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapDataL - Unsupported EAP type =%d \n"), + aEapVendorType)); + + // Unsupported EAP type + User::Leave(KErrNotSupported); + } + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + User::LeaveIfError(view.FirstL()); + view.UpdateL(); + + TInt eapCount = aEaps.Count(); + + HBufC8 *acceptedDbText = HBufC8::NewLC( (sizeof(TUint)) * eapCount ); // 4 bytes (32 bits) for an EAP type, Need to save as TUInt (4 bytes). + HBufC8 *unacceptedDbText = HBufC8::NewLC( (sizeof(TUint)) * eapCount ); // 4 bytes (32 bits) for an EAP type, Need to save as TUInt (4 bytes). + + TPtr8 acceptedPtr(acceptedDbText->Des()); + TPtr8 unacceptedPtr(unacceptedDbText->Des()); + + TBuf8<3> UidTmp; + + for(TInt i = 0 ; i< eapCount; i++) + { + UidTmp.Copy(aEaps[i]->UID); + + TLex8 eapUidLex( UidTmp.Right(2) ); // Only last two characters determines the EAP type. + TUint eapTypeUint = 0; + + User::LeaveIfError( eapUidLex.Val(eapTypeUint, EDecimal) ); + + TPtrC8 tempEAPtype( reinterpret_cast(&eapTypeUint), sizeof(TUint) ); + + if( aEaps[i]->Enabled ) + { + // Fill in accepted tunneled type. + acceptedPtr.Append( tempEAPtype ); + } + else + { + // Fill in unaccepted tunneled type. + unacceptedPtr.Append( tempEAPtype); + } + } + + // Save the strings in the DB. + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Validate length of strings + if(acceptedPtr.Length() > KMaxTunneledTypeStringLengthInDB + || unacceptedPtr.Length() > KMaxTunneledTypeStringLengthInDB) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetEapDataL - Too long Tunneled EAP type string \n") ) ); + + User::Leave(KErrArgument); + } + + view.SetColL(colSet->ColNo(cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal), acceptedPtr); + view.SetColL(colSet->ColNo(cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal), unacceptedPtr); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + view.PutL(); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::SetEapDataL- Enabled extended EAP type data added to DB:", + acceptedPtr.Ptr(), + acceptedPtr.Size() ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::SetEapDataL- Disabled extended EAP type data added to DB:", + unacceptedPtr.Ptr(), + unacceptedPtr.Size() ) ); + + CleanupStack::PopAndDestroy(unacceptedDbText); // Delete unacceptedDbText + CleanupStack::PopAndDestroy(acceptedDbText); // Delete acceptedDbText + CleanupStack::PopAndDestroy(&view); // Close view + CleanupStack::PopAndDestroy(buf); // Delete buf +} + +/** +* Gets Eapdata from corresponding table in commdb +* see format in SetEapDAtaL +*/ +void EapTlsPeapUtils::GetEapDataL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const /*aTools*/, + TEapArray &aEaps, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aEapVendorType = aEapType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aEapVendorType = static_cast(aEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapDataL aIndexType=%d, aIndex=%d, Tunneling vendor type=%d, Eap vendor type=%d \n"), + aIndexType,aIndex, aTunnelingVendorType, aEapVendorType)); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + if (aEapType == eap_type_peap) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KPeapDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#if defined(USE_TTLS_EAP_TYPE) + else if (aEapType == eap_type_ttls) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KTtlsDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#endif + + else if (aEapType == eap_type_ttls_plain_pap) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KTtlsDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } + +#if defined(USE_FAST_EAP_TYPE) + else if (aEapType == eap_type_fast) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KFastGeneralSettingsDBTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#endif + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapDataL - Unsupported EAP type=%d \n"), + aEapVendorType)); + + // Unsupported EAP type + User::Leave(KErrNotSupported); + } + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + User::LeaveIfError(view.FirstL()); + + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + TPtrC8 acceptedEAPData = view.ColDes8(colSet->ColNo(cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal)); + TPtrC8 unacceptedEAPData = view.ColDes8(colSet->ColNo(cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal)); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::GetEapDataL- Enabled extended EAP type data from DB:", + acceptedEAPData.Ptr(), + acceptedEAPData.Size() ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::GetEapDataL- Disabled extended EAP type data from DB:", + unacceptedEAPData.Ptr(), + unacceptedEAPData.Size() ) ); + + aEaps.ResetAndDestroy(); + + TUint acceptedLength = acceptedEAPData.Length(); + TUint unacceptedLength = unacceptedEAPData.Length(); + + TEap *eapTmp; + + TUint index = 0; + + _LIT8(KUIDFormat,"%u"); + + // For accepted or enabled tunneled EAP types. + while(index < acceptedLength) + { + eapTmp = new (ELeave)TEap; + + eapTmp->Enabled=ETrue; // All EAP types in here are enabled. + + eapTmp->UID.Zero(); + + // Get the UID from data from the DB. + TPtrC8 tempEAPtype( acceptedEAPData.Mid(index, sizeof(TUint)) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::GetEapDataL- extracted EAP type:", + tempEAPtype.Ptr(), + tempEAPtype.Size() ) ); + + TUint eapTypeUint = *(tempEAPtype.Ptr()); // All EAP types are saved as TUInt. + + eapTmp->UID.Format(KUIDFormat,eapTypeUint); + + aEaps.Append(eapTmp); + + index = index + sizeof(TUint); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetEapDataL - Appended enabled-EAP type=%s \n"),eapTmp->UID.Ptr()) ); + } + + index = 0; + + // For unaccepted or disabled tunneled EAP types. + while(index < unacceptedLength) + { + eapTmp = new (ELeave)TEap; + + eapTmp->Enabled=EFalse; // All EAP types in here are disabled. + + eapTmp->UID.Zero(); + + // Get the UID from data from the DB. + TPtrC8 tempEAPtype( unacceptedEAPData.Mid(index, sizeof(TUint)) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::GetEapDataL- extracted EAP type:", + tempEAPtype.Ptr(), + tempEAPtype.Size() ) ); + + TUint eapTypeUint = *(tempEAPtype.Ptr()); // All EAP types are saved as TUint. + + eapTmp->UID.Format(KUIDFormat,eapTypeUint); + + aEaps.Append(eapTmp); + + index = index + sizeof(TUint); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetEapDataL - Appended disabled-EAP type=%s \n"),eapTmp->UID.Ptr()) ); + } + + CleanupStack::PopAndDestroy(&view); // Close view + CleanupStack::PopAndDestroy(buf); // Delete buf +} + +#endif // #ifndef USE_EAP_EXPANDED_TYPES + +//-------------------------------------------------- + +#ifdef USE_EAP_EXPANDED_TYPES + +// Stores the tunneled EAP type (expanded) to the database. +void EapTlsPeapUtils::SetTunnelingExpandedEapDataL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const /*aTools*/, + RExpandedEapTypePtrArray &aEnabledEAPArrary, + RExpandedEapTypePtrArray &aDisabledEAPArrary, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType) +{ + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aEapVendorType = aEapType.get_vendor_type(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetTunnelingExpandedEapDataL:aIndexType=%d, aIndex=%d, Tunneling vendor type=%d, Eap vendor type=%d\n"), + aIndexType,aIndex, aTunnelingVendorType, aEapVendorType)); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("Number of Tunneled EAP types: Enabled=%d, Disabled=%d\n"), + aEnabledEAPArrary.Count(), aDisabledEAPArrary.Count())); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + if (aEapType == eap_type_peap) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KPeapDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#if defined(USE_TTLS_EAP_TYPE) + else if (aEapType == eap_type_ttls) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KTtlsDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#endif +#if defined(USE_FAST_EAP_TYPE) + else if (aEapType == eap_type_fast) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KFastGeneralSettingsDBTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#endif + + else if ( aEapType == eap_type_ttls_plain_pap ) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KTtlsDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } + + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetTunnelingExpandedEapDataL - Unsupported EAP type =%d \n"), + aEapVendorType)); + + // Unsupported EAP type + User::Leave(KErrNotSupported); + } + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + User::LeaveIfError(view.FirstL()); + view.UpdateL(); + + TInt enabledEAPCount = aEnabledEAPArrary.Count(); + TInt disabledEAPCount = aDisabledEAPArrary.Count(); + + HBufC8 *acceptedDbText = HBufC8::NewLC( KExpandedEAPTypeSize * enabledEAPCount ); // 8 bytes (64 bits) for an EAP type. + HBufC8 *unacceptedDbText = HBufC8::NewLC( KExpandedEAPTypeSize * disabledEAPCount ); // 8 bytes (64 bits) for an EAP type. + + TPtr8 acceptedPtr(acceptedDbText->Des()); + TPtr8 unacceptedPtr(unacceptedDbText->Des()); + + // Fill in accepted tunneled type. + for(TInt i = 0 ; i< enabledEAPCount; i++) + { + acceptedPtr.Append(aEnabledEAPArrary[i]->iExpandedEAPType); + } + + // Fill in unaccepted tunneled type. + for(TInt i = 0 ; i< disabledEAPCount; i++) + { + unacceptedPtr.Append(aDisabledEAPArrary[i]->iExpandedEAPType); + } + + // Save the strings in the DB. + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Validate length of strings + if(acceptedPtr.Length() > KMaxTunneledTypeStringLengthInDB + || unacceptedPtr.Length() > KMaxTunneledTypeStringLengthInDB) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetTunnelingExpandedEapDataL - Too long Tunneled EAP type string \n") ) ); + + User::Leave(KErrArgument); + } + + view.SetColL(colSet->ColNo(cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal), acceptedPtr); + view.SetColL(colSet->ColNo(cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal), unacceptedPtr); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + view.PutL(); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::SetTunnelingExpandedEapDataL- Enabled extended EAP type data added to DB:", + acceptedPtr.Ptr(), + acceptedPtr.Size() ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::SetTunnelingExpandedEapDataL- Disabled extended EAP type data added to DB:", + unacceptedPtr.Ptr(), + unacceptedPtr.Size() ) ); + + CleanupStack::PopAndDestroy(unacceptedDbText); // Delete unacceptedDbText + CleanupStack::PopAndDestroy(acceptedDbText); // Delete acceptedDbText + CleanupStack::PopAndDestroy(&view); // Close view + CleanupStack::PopAndDestroy(buf); // Delete buf +} + +// Retrieves the tunneled EAP type (expanded) from the database . +void EapTlsPeapUtils::GetTunnelingExpandedEapDataL( + RDbNamedDatabase& aDatabase, + eap_am_tools_symbian_c * const /*aTools*/, + RExpandedEapTypePtrArray &aEnabledEAPArrary, + RExpandedEapTypePtrArray &aDisabledEAPArrary, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType) +{ + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aEapVendorType = aEapType.get_vendor_type(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetTunnelingExpandedEapDataL aIndexType=%d, aIndex=%d, Tunneling vendor type=%d, Eap vendor type=%d \n"), + aIndexType,aIndex, aTunnelingVendorType, aEapVendorType)); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + if (aEapType == eap_type_peap) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KPeapDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#if defined(USE_TTLS_EAP_TYPE) + else if (aEapType == eap_type_ttls) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KTtlsDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#endif +#if defined(USE_FAST_EAP_TYPE) + else if (aEapType == eap_type_fast) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KFastGeneralSettingsDBTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } +#endif + + else if (aEapType == eap_type_ttls_plain_pap ) + { + sqlStatement.Format(KSQLQueryRow, &cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal, + &cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal, + &KTtlsDatabaseTableName, &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType); + } + + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetTunnelingExpandedEapDataL - Unsupported EAP type=%d \n"), + aEapVendorType)); + + // Unsupported EAP type + User::Leave(KErrNotSupported); + } + + RDbView view; + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + User::LeaveIfError(view.FirstL()); + + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + TPtrC8 acceptedEAPData = view.ColDes8(colSet->ColNo(cf_str_PEAP_accepted_tunneled_client_types_hex_data_literal)); + TPtrC8 unacceptedEAPData = view.ColDes8(colSet->ColNo(cf_str_PEAP_unaccepted_tunneled_client_types_hex_data_literal)); + + CleanupStack::PopAndDestroy( colSet ); // Delete colSet. + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::GetTunnelingExpandedEapDataL- Enabled extended EAP type data from DB:", + acceptedEAPData.Ptr(), + acceptedEAPData.Size() ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("EapTlsPeapUtils::GetTunnelingExpandedEapDataL- Disabled extended EAP type data from DB:", + unacceptedEAPData.Ptr(), + unacceptedEAPData.Size() ) ); + + aEnabledEAPArrary.ResetAndDestroy(); + aDisabledEAPArrary.ResetAndDestroy(); + + TUint acceptedLength = acceptedEAPData.Length(); + TUint unacceptedLength = unacceptedEAPData.Length(); + + SExpandedEAPType *expandedEAPTmp = 0; + TUint index = 0; + + // For accepted or enabled tunneled EAP types. + while(index < acceptedLength) + { + expandedEAPTmp = new SExpandedEAPType; + + if (expandedEAPTmp == 0) + { + aEnabledEAPArrary.ResetAndDestroy(); + aDisabledEAPArrary.ResetAndDestroy(); + User::LeaveIfError(KErrNoMemory); + } + + expandedEAPTmp->iExpandedEAPType = acceptedEAPData.Mid(index, KExpandedEAPTypeSize); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("Extracted EAP type:", + expandedEAPTmp->iExpandedEAPType.Ptr(), + expandedEAPTmp->iExpandedEAPType.Size() ) ); + + aEnabledEAPArrary.Append(expandedEAPTmp); + + index = index + KExpandedEAPTypeSize; + } + + index = 0; + + // For unaccepted or disabled tunneled EAP types. + while(index < unacceptedLength) + { + expandedEAPTmp = new SExpandedEAPType; + + if (expandedEAPTmp == 0) + { + aEnabledEAPArrary.ResetAndDestroy(); + aDisabledEAPArrary.ResetAndDestroy(); + User::LeaveIfError(KErrNoMemory); + } + + expandedEAPTmp->iExpandedEAPType = unacceptedEAPData.Mid(index, KExpandedEAPTypeSize); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("Extracted EAP type:", + expandedEAPTmp->iExpandedEAPType.Ptr(), + expandedEAPTmp->iExpandedEAPType.Size() ) ); + + aDisabledEAPArrary.Append(expandedEAPTmp); + + index = index + KExpandedEAPTypeSize; + } + + CleanupStack::PopAndDestroy(&view); // Close view + CleanupStack::PopAndDestroy(buf); // Delete buf +} + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + +//-------------------------------------------------- + +TBool EapTlsPeapUtils::CipherSuiteUseRSAKeys(tls_cipher_suites_e aCipherSuite) +{ + if (aCipherSuite == tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA + || aCipherSuite == tls_cipher_suites_TLS_RSA_WITH_AES_128_CBC_SHA + || aCipherSuite == tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + || aCipherSuite == tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + || aCipherSuite == tls_cipher_suites_TLS_RSA_WITH_RC4_128_MD5 + || aCipherSuite == tls_cipher_suites_TLS_RSA_WITH_RC4_128_SHA) + { + return ETrue; + } + + return EFalse; + +} + +//-------------------------------------------------- + +TBool EapTlsPeapUtils::CipherSuiteUseDSAKeys(tls_cipher_suites_e aCipherSuite) +{ + if (aCipherSuite == tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA + || aCipherSuite == tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA) + { + return ETrue; + } + + return EFalse; +} + +//-------------------------------------------------- + +TBool EapTlsPeapUtils::CipherSuiteIsEphemeralDHKeyExchange(tls_cipher_suites_e aCipherSuite) +{ + if (aCipherSuite == tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA + || aCipherSuite == tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA + || aCipherSuite == tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + || aCipherSuite == tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA) + { + return ETrue; + } + + return EFalse; +} + + +// --------------------------------------------------------- +// EapTlsPeapUtils::SetConfigurationL() +// --------------------------------------------------------- +// +void EapTlsPeapUtils::SetConfigurationL( + RDbNamedDatabase& aDatabase, + const EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aEapVendorType = aEapType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aEapVendorType = static_cast(aEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + +// The current values for TTLS-PAP: +// TTLS: aEapVendorType = TTLS, aTunnelingVendorType = None +// TTLS/plain-PAP: aEapVendorType = ttls_plain_pap, aTunnelingVendorType = TTLS + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetConfigurationL -Start- aIndexType=%d, aIndex=%d, Tunneling vendor type=%d, Eap vendor type=%d \n"), + aIndexType,aIndex, aTunnelingVendorType, aEapVendorType)); + + EAP_TRACE_DEBUG_SYMBIAN((_L("*************************** SetConfigurationL - Set the below values: ***************************\n")) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - Set these values for EAPType=%d"),aSettings.iEAPType) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Username=%S"),aSettings.iUsernamePresent, &(aSettings.iUsername)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Password=%S"),aSettings.iPasswordPresent, &(aSettings.iPassword)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Realm=%S"),aSettings.iRealmPresent, &(aSettings.iRealm)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, UsePseudonyms=%d"),aSettings.iUsePseudonymsPresent, aSettings.iUsePseudonyms) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, VerifyServerRealm=%d"), + aSettings.iVerifyServerRealmPresent, aSettings.iVerifyServerRealm) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, RequireClientAuthentication=%d"), + aSettings.iRequireClientAuthenticationPresent, aSettings.iRequireClientAuthentication) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, SessionValidityTime=%d minutes"), + aSettings.iSessionValidityTimePresent, aSettings.iSessionValidityTime) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, CipherSuites Count=%d"), + aSettings.iCipherSuitesPresent, aSettings.iCipherSuites.Count()) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, PEAPv0Allowed=%d, PEAPv1Allowed=%d, PEAPv2Allowed=%d"), + aSettings.iPEAPVersionsPresent, aSettings.iPEAPv0Allowed,aSettings.iPEAPv1Allowed, aSettings.iPEAPv2Allowed ) ); + + // Validate length of inputs. + if(aSettings.iUsername.Length() > KMaxManualUsernameLengthInDB + || aSettings.iRealm.Length() > KMaxManualRealmLengthInDB ) + { + // Some inputs are too long. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetConfigurationL: Too long arguments\n"))); + + User::Leave(KErrArgument); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, Certificates Count=%d"), + aSettings.iCertificatesPresent, aSettings.iCertificates.Count()) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - Certificate details below: \n")) ); + + for( TInt n=0; n < aSettings.iCertificates.Count(); n++ ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - Certificate type:%d \n"), aSettings.iCertificates[n].iCertType) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - present=%d, SubjectName=%S"), + aSettings.iCertificates[n].iSubjectNamePresent, &(aSettings.iCertificates[n].iSubjectName) ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - present=%d, IssuerName=%S"), + aSettings.iCertificates[n].iIssuerNamePresent, &(aSettings.iCertificates[n].iIssuerName) ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - present=%d, SerialNumber=%S"), + aSettings.iCertificates[n].iSerialNumberPresent, &(aSettings.iCertificates[n].iSerialNumber) ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - SubjectKeyID present=%d"), + aSettings.iCertificates[n].iSubjectKeyIDPresent ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "SubjectKeyID:", aSettings.iCertificates[n].iSubjectKeyID.Ptr(), + aSettings.iCertificates[n].iSubjectKeyID.Size() ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - certificates - Thumbprint present=%d"), + aSettings.iCertificates[n].iThumbprintPresent ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "Thumbprint:", aSettings.iCertificates[n].iThumbprint.Ptr(), + aSettings.iCertificates[n].iThumbprint.Size() ) ); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, EncapsulatedEAPTypes Count=%d"), + aSettings.iEncapsulatedEAPTypesPresent, aSettings.iEncapsulatedEAPTypes.Count()) ); + + for( TInt m=0; m < aSettings.iEncapsulatedEAPTypes.Count(); m++ ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - EncapsulatedEAPTypes=%d"), + aSettings.iEncapsulatedEAPTypes[m]) ); + } + +#ifdef USE_FAST_EAP_TYPE + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, AuthProvModeAllowed=%d"), + aSettings.iAuthProvModeAllowedPresent, aSettings.iAuthProvModeAllowed) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, UnauthProvModeAllowed=%d"), + aSettings.iUnauthProvModeAllowedPresent, aSettings.iUnauthProvModeAllowed) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, WarnADHPNoPAC=%d"), + aSettings.iWarnADHPNoPACPresent, aSettings.iWarnADHPNoPAC) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, WarnADHPNoMatchingPAC=%d"), + aSettings.iWarnADHPNoMatchingPACPresent, aSettings.iWarnADHPNoMatchingPAC) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, WarnNotDefaultServer=%d"), + aSettings.iWarnNotDefaultServerPresent, aSettings.iWarnNotDefaultServer) ); + + // Validate length of PAC Group Ref. + if(aSettings.iPACGroupReference.Length() > KMaxPACGroupRefCollectionLengthInDB) + { + // Too long PAC Group Reference. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetConfigurationL: Too long PAC Group Ref!\n"))); + + User::Leave(KErrArgument); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - present=%d, PAC Group Ref=%S"), + aSettings.iPACGroupReferencePresent, &(aSettings.iPACGroupReference)) ); + +#endif //#ifdef USE_FAST_EAP_TYPE + + EAP_TRACE_DEBUG_SYMBIAN((_L("*************************** SetConfigurationL - Set the above values: ***************************\n")) ); + + + // Check if the settings are for the correct type + if ((aSettings.iEAPType != EAPSettings::EEapTls + && aSettings.iEAPType != EAPSettings::EEapPeap + && aSettings.iEAPType != EAPSettings::EEapTtls +#ifdef USE_FAST_EAP_TYPE + && aSettings.iEAPType != EAPSettings::EEapFast +#endif + && aSettings.iEAPType != EAPSettings::ETtlsPlainPap + ) + || static_cast(aSettings.iEAPType) != aEapVendorType) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - LEAVE - Unsupported EAP type\n")) ); + + User::Leave(KErrNotSupported); + } + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + TPtrC settings; + TPtrC usercerts; + TPtrC cacerts; + TPtrC ciphersuites; + TPtrC maxSessionTime; + TPtrC lastFullAuthTime; + +#ifdef USE_FAST_EAP_TYPE + TPtrC fastSpecialSettings; +#endif + + switch (aEapVendorType) + { + case eap_type_tls: + { + settings.Set(KTlsDatabaseTableName); + usercerts.Set(KTlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTlsAllowedCipherSuitesDatabaseTableName); + maxSessionTime.Set(cf_str_EAP_TLS_max_session_validity_time_literal); + lastFullAuthTime.Set(KTLSLastFullAuthTime); + } + break; + + case eap_type_peap: + { + settings.Set(KPeapDatabaseTableName); + usercerts.Set(KPeapAllowedUserCertsDatabaseTableName); + cacerts.Set(KPeapAllowedCACertsDatabaseTableName); + ciphersuites.Set(KPeapAllowedCipherSuitesDatabaseTableName); + maxSessionTime.Set(cf_str_EAP_PEAP_max_session_validity_time_literal); + lastFullAuthTime.Set(KPEAPLastFullAuthTime); + } + break; + + case eap_type_ttls: + { + settings.Set(KTtlsDatabaseTableName); + usercerts.Set(KTtlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTtlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTtlsAllowedCipherSuitesDatabaseTableName); + maxSessionTime.Set(cf_str_EAP_TTLS_max_session_validity_time_literal); + lastFullAuthTime.Set(KTTLSLastFullAuthTime); + } + break; + +#ifdef USE_FAST_EAP_TYPE + case eap_type_fast: + { + settings.Set(KFastGeneralSettingsDBTableName); // This is general settings for FAST. + fastSpecialSettings.Set(KFastSpecialSettingsDBTableName); + + usercerts.Set(KFastAllowedUserCertsDatabaseTableName); + cacerts.Set(KFastAllowedCACertsDatabaseTableName); + ciphersuites.Set(KFastAllowedCipherSuitesDatabaseTableName); + maxSessionTime.Set(cf_str_EAP_FAST_max_session_validity_time_literal); + lastFullAuthTime.Set(KFASTLastFullAuthTime); + } + break; +#endif + + case eap_type_ttls_plain_pap: + { + settings.Set( KTtlsDatabaseTableName ); + maxSessionTime.Set( cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal ); + lastFullAuthTime.Set( KTTLSPAPLastFullAuthTime ); + } + break; + + default: + { + EAP_TRACE_DEBUG_SYMBIAN((_L("SetConfigurationL - LEAVE - Unsupported EAP type =%d\n"), + aEapVendorType) ); + + // Should never happen + User::Leave(KErrArgument); + } + } + + RDbView view; + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + ////////////////////////////////////////// + // This is for settings for all EAP types. + // For EAP-FAST it is General settings. + ////////////////////////////////////////// + + sqlStatement.Format( KSQL, &settings, + &KServiceType, aIndexType, &KServiceIndex, aIndex, + &KTunnelingType, aTunnelingVendorType ); + + // Evaluate view + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + view.FirstL(); + + view.UpdateL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Database view is ready for setting now. Set items one by one, if needed. + + + ////////////////////////////////////////// + // This is only for plain PAP settings. // + ////////////////////////////////////////// + if ( aEapVendorType == eap_type_ttls_plain_pap ) + { + // Username + if ( aSettings.iUsernamePresent ) + { + // Validate length. + if( aSettings.iUsername.Length() > KMaxPapUserNameLengthInDb ) + { + // Username too long. Can not be stored in DB. + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "EapTlsPeapUtils::SetConfigurationL: Too long Username. Length=%d \n" ), + aSettings.iUsername.Length() ) ); + CleanupStack::PopAndDestroy( 3 ); // colset, view, buf + User::Leave( KErrArgument ); + } + + // Length is ok. Set the value in DB. + view.SetColL( colSet->ColNo( cf_str_EAP_TLS_PEAP_ttls_pap_username_literal ), + aSettings.iUsername); + } + // Password + if ( aSettings.iPasswordPresent ) + { + // Validate length. + if ( aSettings.iPassword.Length() > KMaxPapPasswordLengthInDb ) + { + // Password too long. Can not be stored in DB. + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "EapTlsPeapUtils::SetConfigurationL: Too long Password. Length=%d \n" ), + aSettings.iPassword.Length() ) ); + CleanupStack::PopAndDestroy( 3 ); // colset, view, buf + User::Leave( KErrArgument ); + } + + // Length is ok. Set the value in DB. + view.SetColL( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_password_literal ), + aSettings.iPassword ); + + // If password was supplied set password prompting off + view.SetColL( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal ), + EPapPasswordPromptOff ); + } + + // Session validity time + if ( aSettings.iSessionValidityTimePresent ) + { + // User or device management wants to store the session validity time. + // Convert the time to micro seconds and save. + TInt64 validityInMicro = + ( aSettings.iSessionValidityTime ) + * + KMicroSecsInAMinute; + view.SetColL( colSet->ColNo( maxSessionTime ), validityInMicro ); + + // If max session validity time is supplied and non-zero, set password prompting ON. + // It doesn't matter even if the password is supplied. If max session validity is supplied, + // it means user needs to provide a password hence prompt should appear. + if( validityInMicro != 0) + { + view.SetColL( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_password_prompt_literal ), + EPapPasswordPromptOn ); + } + } + + // Last full authentication time should be made zero when EAP configurations are modified. + // This makes sure that the next authentication with this EAP would be full authentication + // instead of reauthentication even if the session is still valid. + view.SetColL( colSet->ColNo( lastFullAuthTime ), default_FullAuthTime ); + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "Session Validity: EAP-Type=%d, Resetting Full Auth Time since settings are modified\n" ), + aSettings.iEAPType )); + + view.PutL(); + CleanupStack::PopAndDestroy( 3 ); // colset, view, buf + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetConfigurationL - Return \n") ) ); + return; + } // if ( aEapVendorType == eap_type_ttls_plain_pap ) + + // Manual username + { + // Set the value in DB. Value could be empty. It doesn't matter. + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_username_literal), aSettings.iUsername); + + // This is to set the automatic or manual status. + TUint useManualUsernameStatus; + + if (aSettings.iUsernamePresent) + { + useManualUsernameStatus = ETLSPEAPUseManualUsernameYes; + } + else + { + useManualUsernameStatus = ETLSPEAPUseManualUsernameNo; + } + + // Set the value. + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_username_literal), + useManualUsernameStatus); + + } + + // Manual realm + { + // Set the value in DB. Value could be empty. It doesn't matter. + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_realm_literal), aSettings.iRealm); + + // This is to set the automatic or manual status. + TUint useManualRealmStatus; + + if (aSettings.iRealmPresent) + { + useManualRealmStatus = ETLSPEAPUseManualRealmYes; + } + else + { + useManualRealmStatus = ETLSPEAPUseManualRealmNo; + } + + // Set the value. + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_realm_literal), + useManualRealmStatus); + } + + // Verify server realm + if (aSettings.iVerifyServerRealmPresent) + { + if (aSettings.iVerifyServerRealm) + { + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal), + ETLSPEAPVerifyCertRealmYes); + } + else + { + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal), + ETLSPEAPVerifyCertRealmNo); + } + } + + // Require client authentication + if (aSettings.iRequireClientAuthenticationPresent) + { + if (aSettings.iRequireClientAuthentication) + { + view.SetColL(colSet->ColNo(cf_str_TLS_server_authenticates_client_policy_in_client_literal), + ETLSPEAPServerAuthenticatesClientPolicyYes); + } + else + { + view.SetColL(colSet->ColNo(cf_str_TLS_server_authenticates_client_policy_in_client_literal), + ETLSPEAPServerAuthenticatesClientPolicyNo); + } + } + + // Session validity time + if (aSettings.iSessionValidityTimePresent) + { + // User or device management wants to store the session validity time. + // Convert the time to micro seconds and save. + + TInt64 validityInMicro = (aSettings.iSessionValidityTime) * KMicroSecsInAMinute; + + view.SetColL(colSet->ColNo(maxSessionTime), validityInMicro); + } + + // Last full authentication time should be made zero when EAP configurations are modified. + // This makes sure that the next authentication with this EAP would be full authentication + // instead of reauthentication even if the session is still valid. + + view.SetColL(colSet->ColNo(lastFullAuthTime), default_FullAuthTime); + + EAP_TRACE_DEBUG_SYMBIAN((_L("Session Validity: EAP-Type=%d, Resetting Full Auth Time since settings are modified\n"), + aSettings.iEAPType )); + + // PEAP versions + + if (aSettings.iPEAPVersionsPresent + && (aEapType == eap_type_peap + || aEapType == eap_type_ttls +#ifdef USE_FAST_EAP_TYPE + || aEapType == eap_type_fast +#endif + )) + { + TBuf8 acceptedPEAPVersions; + + if (aSettings.iPEAPv0Allowed) + { + TInt tmp(0); + acceptedPEAPVersions.Append(reinterpret_cast(&tmp), sizeof(TInt)); + } + if (aSettings.iPEAPv1Allowed) + { + TInt tmp(1); + acceptedPEAPVersions.Append(reinterpret_cast(&tmp), sizeof(TInt)); + } + if (aSettings.iPEAPv2Allowed) + { + TInt tmp(2); + acceptedPEAPVersions.Append(reinterpret_cast(&tmp), sizeof(TInt)); + } + view.SetColL(colSet->ColNo(cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal), acceptedPEAPVersions); + } + + view.PutL(); + + CleanupStack::PopAndDestroy(2); // view, colset + +#ifdef USE_FAST_EAP_TYPE + + /////////////////////////////////////////////////////// + // This is only for EAP-FAST specific, Special settings. + /////////////////////////////////////////////////////// + + if(aEapType == eap_type_fast) + { + sqlStatement.Format(KSQL, &fastSpecialSettings, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + view.FirstL(); + + view.UpdateL(); + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Database view is ready for setting now. Set items one by one, if needed. + + // For provisioning modes. + if (aSettings.iAuthProvModeAllowedPresent) + { + if (aSettings.iAuthProvModeAllowed) + { + view.SetColL(colSet->ColNo(cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal), + EFASTAuthProvModeAllowedYes); + } + else + { + view.SetColL(colSet->ColNo(cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal), + EFASTAuthProvModeAllowedNo); + } + } + + if (aSettings.iUnauthProvModeAllowedPresent) + { + if (aSettings.iUnauthProvModeAllowed) + { + view.SetColL(colSet->ColNo(cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal), + EFASTUnauthProvModeAllowedYes); + } + else + { + view.SetColL(colSet->ColNo(cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal), + EFASTUnauthProvModeAllowedNo); + } + } + + // For the warnings and prompts + if (aSettings.iWarnADHPNoPACPresent) + { + if (aSettings.iWarnADHPNoPAC) + { + view.SetColL(colSet->ColNo(KFASTWarnADHPNoPAC), + EFASTWarnADHPNoPACYes); + } + else + { + view.SetColL(colSet->ColNo(KFASTWarnADHPNoPAC), + EFASTWarnADHPNoPACNo); + } + } + + if (aSettings.iWarnADHPNoMatchingPACPresent) + { + if (aSettings.iWarnADHPNoMatchingPAC) + { + view.SetColL(colSet->ColNo(KFASTWarnADHPNoMatchingPAC), + EFASTWarnADHPNoMatchingPACYes); + } + else + { + view.SetColL(colSet->ColNo(KFASTWarnADHPNoMatchingPAC), + EFASTWarnADHPNoMatchingPACNo); + } + } + + if (aSettings.iWarnNotDefaultServerPresent) + { + if (aSettings.iWarnADHPNoMatchingPAC) + { + view.SetColL(colSet->ColNo(KFASTWarnNotDefaultServer), + EFASTWarnNotDefaultServerYes); + } + else + { + view.SetColL(colSet->ColNo(KFASTWarnNotDefaultServer), + EFASTWarnNotDefaultServerNo); + } + } + + // For PAC group reference. + if (aSettings.iPACGroupReferencePresent) + { + // The length of iPACGroupReference is already checked for max length. + // So just store it in the DB. + view.SetColL(colSet->ColNo(KFASTPACGroupImportReferenceCollection), + aSettings.iPACGroupReference); + } + + view.PutL(); + + CleanupStack::PopAndDestroy(2); // view, colset + + } // End: if(aEapType == eap_type_fast) + +#endif // #ifdef USE_FAST_EAP_TYPE + + ////////////////// + // Cipher suites + ////////////////// + + if (aSettings.iCipherSuitesPresent) + { + sqlStatement.Format(KSQL, &ciphersuites, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Delete old rows + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Database view is ready for setting now. Set items one by one, if needed. + + for (TInt i = 0; i < aSettings.iCipherSuites.Count(); i++) + { + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), static_cast(aIndex)); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + view.SetColL(colSet->ColNo(KCipherSuite), aSettings.iCipherSuites[i]); + view.PutL(); + } + + CleanupStack::PopAndDestroy(2); // view, colset + } + + ///////////////////////// + // User + CA Certificates + ///////////////////////// + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetConfigurationL - aSettings.iCertificatesPresent=%d \n"), aSettings.iCertificatesPresent ) ); + + if (aSettings.iCertificatesPresent) + { + // Needed for getting the Symbian's subject key id. + CEapTlsPeapCertFetcher* certFetcher = CEapTlsPeapCertFetcher::NewL(); + CleanupStack::PushL(certFetcher); + + TBuf8 symbianSubjectKeyID; + + // For USER certificate. + sqlStatement.Format(KSQL, &usercerts, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Delete old rows + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // Database view is ready for setting now. Set items one by one, if needed. + + TInt i(0); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetConfigurationL - aSettings.iCertificates.Count()=%d \n"), aSettings.iCertificates.Count() ) ); + + for (i = 0; i < aSettings.iCertificates.Count(); i++) + { + if (aSettings.iCertificates[i].iCertType == CertificateEntry::EUser) + { + // Validate the length and save other certificate details to the DB. + if(aSettings.iCertificates[i].iSubjectName.Length() > KKeyIdentifierLength + || aSettings.iCertificates[i].iIssuerName.Length() > KGeneralStringMaxLength + || aSettings.iCertificates[i].iSerialNumber.Length() > KGeneralStringMaxLength + || aSettings.iCertificates[i].iSubjectKeyID.Length() > KGeneralStringMaxLength + || aSettings.iCertificates[i].iThumbprint.Length() > KThumbprintMaxLength) + { + // Too long data. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetConfigurationL : Too long USER cert details.\n"))); + + User::Leave(KErrArgument); + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("THIS IS SubjectKeyID:", + aSettings.iCertificates[i].iSubjectKeyID.Ptr(), aSettings.iCertificates[i].iSubjectKeyID.Size())); + + // The cert label column is left empty + + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), static_cast(aIndex)); + view.SetColL(colSet->ColNo(KTunnelingType), aTunnelingVendorType); + + view.SetColL(colSet->ColNo(KSubjectName), aSettings.iCertificates[i].iSubjectName); + view.SetColL(colSet->ColNo(KIssuerName), aSettings.iCertificates[i].iIssuerName); + view.SetColL(colSet->ColNo(KSerialNumber), aSettings.iCertificates[i].iSerialNumber); + view.SetColL(colSet->ColNo(KActualSubjectKeyIdentifier), aSettings.iCertificates[i].iSubjectKeyID); + + // Special for thumb print (finger print). Need to convert it to 8 bits before storing in DB + TBuf8 thumbPrint8Bit; + thumbPrint8Bit.Copy(aSettings.iCertificates[i].iThumbprint); + + view.SetColL(colSet->ColNo(KThumbprint), thumbPrint8Bit); + + view.SetColL(colSet->ColNo(KSubjectKeyIdentifier), aSettings.iCertificates[i].iSubjectKeyID); + + view.PutL(); + } + } + CleanupStack::PopAndDestroy(2); // view, colset + + // Do the same for CA certificates. + sqlStatement.Format(KSQL, &cacerts, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Delete old rows + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + for (i = 0; i < aSettings.iCertificates.Count(); i++) + { + if (aSettings.iCertificates[i].iCertType == CertificateEntry::ECA) + { + // Validate the length and save other certificate details to the DB. + if(aSettings.iCertificates[i].iSubjectName.Length() > KKeyIdentifierLength + || aSettings.iCertificates[i].iIssuerName.Length() > KGeneralStringMaxLength + || aSettings.iCertificates[i].iSerialNumber.Length() > KGeneralStringMaxLength + || aSettings.iCertificates[i].iSubjectKeyID.Length() > KGeneralStringMaxLength + || aSettings.iCertificates[i].iThumbprint.Length() > KThumbprintMaxLength) + { + // Too long data. Can not be stored in DB. + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetConfigurationL:Too long CA cert details.\n"))); + + User::Leave(KErrArgument); + } + + // The cert label column is left empty + + view.InsertL(); + view.SetColL(colSet->ColNo(KServiceType), static_cast(aIndexType)); + view.SetColL(colSet->ColNo(KServiceIndex), static_cast(aIndex)); + view.SetColL(colSet->ColNo(KTunnelingType),aTunnelingVendorType); + + view.SetColL(colSet->ColNo(KSubjectName), aSettings.iCertificates[i].iSubjectName); + view.SetColL(colSet->ColNo(KIssuerName), aSettings.iCertificates[i].iIssuerName); + view.SetColL(colSet->ColNo(KSerialNumber), aSettings.iCertificates[i].iSerialNumber); + view.SetColL(colSet->ColNo(KActualSubjectKeyIdentifier), aSettings.iCertificates[i].iSubjectKeyID); + + // Special for thumb print (finger print). Need to convert it to 8 bits before storing in DB + TBuf8 thumbPrint8Bit; + thumbPrint8Bit.Copy(aSettings.iCertificates[i].iThumbprint); + + view.SetColL(colSet->ColNo(KThumbprint), thumbPrint8Bit); + + // Get the "symbian's subject key id" using symbian API. + // We use this subject key id for authentication. + + view.SetColL(colSet->ColNo(KSubjectKeyIdentifier), aSettings.iCertificates[i].iSubjectKeyID); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "EapTlsPeapUtils::SetConfigurationL - Adding CA cert to DB, Supplied (Actual) SubjectKeyID:", + aSettings.iCertificates[i].iSubjectKeyID.Ptr(), aSettings.iCertificates[i].iSubjectKeyID.Size() ) ); + + view.PutL(); + } + } + + CleanupStack::PopAndDestroy(2); // view, colset + + CleanupStack::PopAndDestroy(certFetcher); + + } // End of if (aSettings.iCertificatesPresent) + + CleanupStack::PopAndDestroy(); // buf + + ///////////////////// + // Encapsulated types + ///////////////////// + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetConfigurationL - aSettings.iEncapsulatedEAPTypesPresent=%d \n"), aSettings.iEncapsulatedEAPTypesPresent ) ); + + // Encapsulated types are only for EAP-PEAP, EAP-TTLS and EAP-FAST. Not for EAP-TLS. + // This is just to be on safe side. In case if iEncapsulatedEAPTypesPresent is set true for EAP-TLS by the caller. + if ( aEapType != eap_type_peap + && aEapType != eap_type_ttls +#ifdef USE_FAST_EAP_TYPE + && aEapType != eap_type_fast +#endif + ) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetConfigurationL - End - Since no encapsulated type for the EAPType =%d \n"), + aEapVendorType ) ); + + return; // No need to proceed. No encapsulated type for EAP-TLS.. + } + +#ifdef USE_EAP_EXPANDED_TYPES + + if (aSettings.iEncapsulatedEAPTypesPresent) + { + RExpandedEapTypePtrArray enabledEAPTypes; + // This is just for dummy. All EAP types available here are enabled as default. + RExpandedEapTypePtrArray disabledEAPTypes; + SExpandedEAPType* expandedEAPTmp = 0; + + for (TInt i = 0; i < aSettings.iEncapsulatedEAPTypes.Count(); i++) + { + expandedEAPTmp = new SExpandedEAPType; + + if (expandedEAPTmp == 0) + { + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + enabledEAPTypes.Close(); + disabledEAPTypes.Close(); + User::Leave(KErrNoMemory); + } + + // This fills the needed values for vendor id etc. + eap_expanded_type_c tmpExpEAP(static_cast (aSettings.iEncapsulatedEAPTypes[i])); + + // This is only for plain-MSCHAPv2 as long as we are using the value 99 for it. + if(aSettings.iEncapsulatedEAPTypes[i] == EAPSettings::EPlainMschapv2) + { + tmpExpEAP.set_eap_type_values( + eap_type_vendor_id_hack, + eap_type_vendor_type_plain_MSCHAPv2_hack); + } + + // And this is for TTLS-PAP as long as we are using the value 98 for it. + if(aSettings.iEncapsulatedEAPTypes[i] == EAPSettings::ETtlsPlainPap) + { + tmpExpEAP.set_eap_type_values( + eap_type_vendor_id_hack, + eap_type_vendor_type_ttls_plain_pap_hack); + } + + // Some indirect way of forming the 8 byte string of an EAP type is needed here. + TUint8 tmpExpBuffer[KExpandedEAPTypeSize]; // This is for the eap_expanded_type_c::write_type + + // This copies the 8 byte string of EAP type to tmpExpBuffer. + eap_status_e status = eap_expanded_type_c::write_type(0, + 0, // index should be zero here. + tmpExpBuffer, + KExpandedEAPTypeSize, + true, + tmpExpEAP); + + // Now copy the 8 byte string to expandedEAPTmp. + expandedEAPTmp->iExpandedEAPType.Copy(tmpExpBuffer, KExpandedEAPTypeSize); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( + ("EapTlsPeapUtils::SetConfigurationL: Expanded EAp type string", + expandedEAPTmp->iExpandedEAPType.Ptr(), + expandedEAPTmp->iExpandedEAPType.Size() ) ); + + + enabledEAPTypes.Append(expandedEAPTmp); + } + + TRAPD(error, SetTunnelingExpandedEapDataL( + aDatabase, + 0, + enabledEAPTypes, + disabledEAPTypes, + aIndexType, + aIndex, + aTunnelingType, + aEapType)); + + if( error != KErrNone ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetConfigurationL - ########### Setting Expanded Tunneling types in the DB failed ############ \n") ) ); + + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + enabledEAPTypes.Close(); + disabledEAPTypes.Close(); + + User::Leave(KErrArgument); // There could be some problem in the encapsulated EAP type argument. + } + + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + enabledEAPTypes.Close(); + disabledEAPTypes.Close(); + + } + +#else // For normal unexpanded EAP type. + + if (aSettings.iEncapsulatedEAPTypesPresent) + { + TEapArray eapArray; + + TEap *eap; + for (TInt i = 0; i < aSettings.iEncapsulatedEAPTypes.Count(); i++) + { + eap = new TEap; + if (eap == 0) + { + eapArray.ResetAndDestroy(); + eapArray.Close(); + User::Leave(KErrNoMemory); + } + + eap->UID.NumFixedWidth(aSettings.iEncapsulatedEAPTypes[i], EDecimal, 2); + eap->Enabled = ETrue; + eapArray.Append(eap); + } + + TInt err(KErrNone); + TRAP(err, SetEapDataL( + aDatabase, + 0, + eapArray, + aIndexType, + aIndex, + aTunnelingType, + aEapType)); + + if( err != KErrNone ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetConfigurationL - ########### Setting Tunneling types in the DB failed ############ \n") ) ); + + eapArray.ResetAndDestroy(); + eapArray.Close(); + + User::Leave(KErrArgument); // There could be some problem in the encapsulated EAP type argument. + } + + eapArray.ResetAndDestroy(); + eapArray.Close(); + } + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::SetConfigurationL - End \n") ) ); + +} // EapTlsPeapUtils::SetConfigurationL() + + +// --------------------------------------------------------- +// EapTlsPeapUtils::GetConfigurationL() +// --------------------------------------------------------- +// +void EapTlsPeapUtils::GetConfigurationL( + RDbNamedDatabase& aDatabase, + EAPSettings& aSettings, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aEapVendorType = aEapType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aEapVendorType = static_cast(aEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetConfigurationL aIndexType=%d, aIndex=%d, Tunneling vendor type=%d, Eap vendor type=%d \n"), + aIndexType,aIndex, aTunnelingVendorType, aEapVendorType)); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + TPtrC settings; + TPtrC usercerts; + TPtrC cacerts; + TPtrC ciphersuites; + TPtrC maxSessionTime; + +#ifdef USE_FAST_EAP_TYPE + TPtrC fastSpecialSettings; +#endif + + switch (aEapVendorType) + { + case eap_type_tls: + { + settings.Set(KTlsDatabaseTableName); + usercerts.Set(KTlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTlsAllowedCipherSuitesDatabaseTableName); + maxSessionTime.Set(cf_str_EAP_TLS_max_session_validity_time_literal); + } + break; + + case eap_type_peap: + { + settings.Set(KPeapDatabaseTableName); + usercerts.Set(KPeapAllowedUserCertsDatabaseTableName); + cacerts.Set(KPeapAllowedCACertsDatabaseTableName); + ciphersuites.Set(KPeapAllowedCipherSuitesDatabaseTableName); + maxSessionTime.Set(cf_str_EAP_PEAP_max_session_validity_time_literal); + } + break; + + case eap_type_ttls: + { + settings.Set(KTtlsDatabaseTableName); + usercerts.Set(KTtlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTtlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTtlsAllowedCipherSuitesDatabaseTableName); + maxSessionTime.Set(cf_str_EAP_TTLS_max_session_validity_time_literal); + } + break; + +#ifdef USE_FAST_EAP_TYPE + case eap_type_fast: + { + settings.Set(KFastGeneralSettingsDBTableName); // This is general settings for FAST. + fastSpecialSettings.Set(KFastSpecialSettingsDBTableName); + + usercerts.Set(KFastAllowedUserCertsDatabaseTableName); + cacerts.Set(KFastAllowedCACertsDatabaseTableName); + ciphersuites.Set(KFastAllowedCipherSuitesDatabaseTableName); + maxSessionTime.Set(cf_str_EAP_FAST_max_session_validity_time_literal); + } + break; +#endif + + + case eap_type_ttls_plain_pap: + { + settings.Set( KTtlsDatabaseTableName ); + maxSessionTime.Set( cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal ); + } + break; + + default: + // Should never happen + User::Leave(KErrArgument); + } + + RDbView view; + + // Form the query + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + ////////////////////////////////////////// + // This is for settings for all EAP types. + // For EAP-FAST it is General settings. + ////////////////////////////////////////// + + sqlStatement.Format(KSQL, &settings, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + aSettings.iEAPType = static_cast(aEapVendorType); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetConfigurationL - aSettings.iEAPType=%d \n"),aSettings.iEAPType) ); + + ////////////////////////////////////////// + // This is only for plain PAP settings. // + ////////////////////////////////////////// + if ( aEapType == eap_type_ttls_plain_pap ) + { + // Username + TPtrC username = view.ColDes( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_username_literal ) ); + aSettings.iUsername.Copy( username ); + aSettings.iUsernamePresent = ETrue; + + // Password + TPtrC password = view.ColDes( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_password_literal ) ); + aSettings.iPassword.Copy( password ); + aSettings.iPasswordPresent = ETrue; + + // Session validity time + TInt64 maxSessionTimeMicro = view.ColInt64( colSet->ColNo( + cf_str_EAP_TLS_PEAP_ttls_pap_max_session_validity_time_literal ) ); + + // Convert the time to minutes. + TInt64 maxSessionTimeMin = maxSessionTimeMicro / KMicroSecsInAMinute; + + aSettings.iSessionValidityTime = static_cast( maxSessionTimeMin ); + aSettings.iSessionValidityTimePresent = ETrue; + + CleanupStack::PopAndDestroy(3); // view, colset, buf + + return; + } + + + // Username + TPtrC username = view.ColDes(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_username_literal)); + aSettings.iUsername.Copy(username); + + // For manual or automatic status. + TUint useUsername = view.ColUint(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_username_literal)); + if(useUsername == ETLSPEAPUseManualUsernameNo) + { + aSettings.iUsernamePresent = EFalse; + } + else + { + aSettings.iUsernamePresent = ETrue; + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetConfigurationL - Settings.iUsername=%S \n"), &(aSettings.iUsername) ) ); + + // Realm + TPtrC realm = view.ColDes(colSet->ColNo(cf_str_EAP_TLS_PEAP_manual_realm_literal)); + aSettings.iRealm.Copy(realm); + + // For manual or automatic status. + TUint useRealm = view.ColUint(colSet->ColNo(cf_str_EAP_TLS_PEAP_use_manual_realm_literal)); + if(useRealm == ETLSPEAPUseManualRealmNo) + { + aSettings.iRealmPresent = EFalse; + } + else + { + aSettings.iRealmPresent = ETrue; + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetConfigurationL - aSettings.iRealm=%S \n"),&(aSettings.iRealm)) ); + + // Verify server realm + TInt verifyrealm = view.ColUint(colSet->ColNo(cf_str_EAP_TLS_PEAP_verify_certificate_realm_literal)); + if (verifyrealm == 0) + { + aSettings.iVerifyServerRealm = EFalse; + } + else + { + aSettings.iVerifyServerRealm = ETrue; + } + aSettings.iVerifyServerRealmPresent = ETrue; + + // Require client authentication + TInt requireclientauth = view.ColUint(colSet->ColNo(cf_str_TLS_server_authenticates_client_policy_in_client_literal)); + if (requireclientauth == 0) + { + aSettings.iRequireClientAuthentication = EFalse; + } + else + { + aSettings.iRequireClientAuthentication = ETrue; + } + aSettings.iRequireClientAuthenticationPresent = ETrue; + + // Session validity time + TInt64 maxSessionTimeMicro = view.ColInt64(colSet->ColNo(maxSessionTime)); + + // Convert the time to minutes. + TInt64 maxSessionTimeMin = maxSessionTimeMicro / KMicroSecsInAMinute; + + aSettings.iSessionValidityTime = static_cast(maxSessionTimeMin); + aSettings.iSessionValidityTimePresent = ETrue; + + // PEAP versions + if (aEapType == eap_type_peap + || aEapType == eap_type_ttls +#ifdef USE_FAST_EAP_TYPE + || aEapType == eap_type_fast +#endif + ) + { + TPtrC8 binaryValue = view.ColDes8(colSet->ColNo(cf_str_EAP_TLS_PEAP_accepted_PEAP_versions_literal)); + + const TInt* allowedVersions = reinterpret_cast(binaryValue.Ptr()); + + TInt i; + for (i = 0; i < static_cast(binaryValue.Length() / sizeof(TInt)); i++) + { + switch(allowedVersions[i]) + { + case 0: + aSettings.iPEAPv0Allowed = ETrue; + break; + case 1: + aSettings.iPEAPv1Allowed = ETrue; + break; + case 2: + aSettings.iPEAPv2Allowed = ETrue; + + break; + } + } + aSettings.iPEAPVersionsPresent = ETrue; + } + + CleanupStack::PopAndDestroy(2); // view, colset + +#ifdef USE_FAST_EAP_TYPE + + /////////////////////////////////////////////////////// + // This is only for EAP-FAST specific, Special settings. + /////////////////////////////////////////////////////// + + if(aEapType == eap_type_fast) + { + sqlStatement.Format(KSQL, &fastSpecialSettings, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the first (and only) row + view.FirstL(); + view.GetL(); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + // For provisioning modes. + TUint authProvMode = view.ColUint(colSet->ColNo(cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal)); + if(authProvMode == EFASTAuthProvModeAllowedNo) + { + aSettings.iAuthProvModeAllowed = EFalse; + } + else + { + aSettings.iAuthProvModeAllowed = ETrue; + } + + aSettings.iAuthProvModeAllowedPresent = ETrue; + + TUint unauthProvMode = view.ColUint(colSet->ColNo(cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal)); + if(unauthProvMode == EFASTUnauthProvModeAllowedNo) + { + aSettings.iUnauthProvModeAllowed = EFalse; + } + else + { + aSettings.iUnauthProvModeAllowed = ETrue; + } + + aSettings.iUnauthProvModeAllowedPresent = ETrue; + + // For no PAC warning + TUint warn = view.ColUint(colSet->ColNo(KFASTWarnADHPNoPAC)); + if(warn == EFASTWarnADHPNoPACNo) + { + aSettings.iWarnADHPNoPAC = EFalse; + } + else + { + aSettings.iWarnADHPNoPAC = ETrue; + } + + aSettings.iWarnADHPNoPACPresent = ETrue; + + // For no matching PAC warning + warn = view.ColUint(colSet->ColNo(KFASTWarnADHPNoMatchingPAC)); + if(warn == EFASTWarnADHPNoMatchingPACNo) + { + aSettings.iWarnADHPNoMatchingPAC = EFalse; + } + else + { + aSettings.iWarnADHPNoMatchingPAC = ETrue; + } + + aSettings.iWarnADHPNoMatchingPACPresent = ETrue; + + // For no default server warning + warn = view.ColUint(colSet->ColNo(KFASTWarnNotDefaultServer)); + if(warn == EFASTWarnNotDefaultServerNo) + { + aSettings.iWarnNotDefaultServer = EFalse; + } + else + { + aSettings.iWarnNotDefaultServer = ETrue; + } + + aSettings.iWarnNotDefaultServerPresent = ETrue; + + // For PAC group reference. + TPtrC pacGroupRef = view.ColDes(colSet->ColNo(KFASTPACGroupImportReferenceCollection)); + if(pacGroupRef.Length()) + { + aSettings.iPACGroupReference.Copy(pacGroupRef); + + aSettings.iPACGroupReferencePresent = ETrue; + } + + CleanupStack::PopAndDestroy(2); // view, colset + + } // End: if(aEapType == eap_type_fast) + +#endif //#ifdef USE_FAST_EAP_TYPE + + + ////////////////// + // Cipher suites + ////////////////// + + sqlStatement.Format(KSQL, &ciphersuites, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + if (view.FirstL()) + { + do { + view.GetL(); + { + aSettings.iCipherSuites.Append(view.ColUint(colSet->ColNo(KCipherSuite))); + } + } while (view.NextL() != EFalse); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetConfigurationL - Total cipher suites appended=%d \n"),aSettings.iCipherSuites.Count()) ); + + aSettings.iCipherSuitesPresent = ETrue; + + CleanupStack::PopAndDestroy(2); // view, colset + + ///////////////// + // User Certificates + ///////////////// + + sqlStatement.Format(KSQL, &usercerts, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + if (view.FirstL()) + { + do { + view.GetL(); + { + // This is big object. + CertificateEntry * certEntry = new (ELeave) CertificateEntry; + CleanupStack::PushL(certEntry); + + certEntry->iCertType = CertificateEntry::EUser; + + certEntry->iSubjectName.Copy(view.ColDes(colSet->ColNo(KSubjectName))); + if(certEntry->iSubjectName.Length()) + { + certEntry->iSubjectNamePresent = ETrue; + } + + certEntry->iIssuerName.Copy(view.ColDes(colSet->ColNo(KIssuerName))); + if(certEntry->iIssuerName.Length()) + { + certEntry->iIssuerNamePresent = ETrue; + } + + certEntry->iSerialNumber.Copy(view.ColDes(colSet->ColNo(KSerialNumber))); + if(certEntry->iSerialNumber.Length()) + { + certEntry->iSerialNumberPresent = ETrue; + } + + certEntry->iSubjectKeyID.Copy(view.ColDes8(colSet->ColNo(KActualSubjectKeyIdentifier))); // This is the subjectkey id we got in SetConfigurationL + if(certEntry->iSubjectKeyID.Length()) + { + certEntry->iSubjectKeyIDPresent = ETrue; + } + + certEntry->iThumbprint.Copy(view.ColDes8(colSet->ColNo(KThumbprint))); + if(certEntry->iThumbprint.Length()) + { + certEntry->iThumbprintPresent = ETrue; + } + + aSettings.iCertificates.AppendL(*certEntry); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "EapTlsPeapUtils::GetConfigurationL - Filling User cert entry, SubjectKeyID:", + certEntry->iSubjectKeyID.Ptr(), certEntry->iSubjectKeyID.Size() ) ); + + CleanupStack::PopAndDestroy(certEntry); + } + } while (view.NextL() != EFalse); + } + + CleanupStack::PopAndDestroy(2); // view, colset + + ///////////////// + // CA Certificates + ///////////////// + + sqlStatement.Format(KSQL, &cacerts, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement))); + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + if (view.FirstL()) + { + do { + view.GetL(); + { + // This is big object. + CertificateEntry * certEntry = new (ELeave) CertificateEntry; + CleanupStack::PushL(certEntry); + + certEntry->iCertType = CertificateEntry::ECA; + + certEntry->iSubjectName.Copy(view.ColDes(colSet->ColNo(KSubjectName))); + if(certEntry->iSubjectName.Length()) + { + certEntry->iSubjectNamePresent = ETrue; + } + + certEntry->iIssuerName.Copy(view.ColDes(colSet->ColNo(KIssuerName))); + if(certEntry->iIssuerName.Length()) + { + certEntry->iIssuerNamePresent = ETrue; + } + + certEntry->iSerialNumber.Copy(view.ColDes(colSet->ColNo(KSerialNumber))); + if(certEntry->iSerialNumber.Length()) + { + certEntry->iSerialNumberPresent = ETrue; + } + + certEntry->iSubjectKeyID.Copy(view.ColDes8(colSet->ColNo(KActualSubjectKeyIdentifier))); // This is the subjectkey id we got in SetConfigurationL + if(certEntry->iSubjectKeyID.Length()) + { + certEntry->iSubjectKeyIDPresent = ETrue; + } + + certEntry->iThumbprint.Copy(view.ColDes8(colSet->ColNo(KThumbprint))); + if(certEntry->iThumbprint.Length()) + { + certEntry->iThumbprintPresent = ETrue; + } + + aSettings.iCertificates.AppendL(*certEntry); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "EapTlsPeapUtils::GetConfigurationL - Filling CA cert entry, SubjectKeyID:", + certEntry->iSubjectKeyID.Ptr(), certEntry->iSubjectKeyID.Size() ) ); + + CleanupStack::PopAndDestroy(certEntry); + } + } while (view.NextL() != EFalse); + } + + CleanupStack::PopAndDestroy(3); // view, colset, buf + + aSettings.iCertificatesPresent = ETrue; + + EAP_TRACE_DEBUG_SYMBIAN((_L("**************** GetConfigurationL - Returning the below values: ***************\n")) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - Return these values for EAPType=%d"),aSettings.iEAPType) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, Username=%S"),aSettings.iUsernamePresent, &(aSettings.iUsername)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, Password=%S"),aSettings.iPasswordPresent, &(aSettings.iPassword)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, Realm=%S"),aSettings.iRealmPresent, &(aSettings.iRealm)) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, UsePseudonyms=%d"),aSettings.iUsePseudonymsPresent, aSettings.iUsePseudonyms) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, VerifyServerRealm=%d"), + aSettings.iVerifyServerRealmPresent, aSettings.iVerifyServerRealm) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, RequireClientAuthentication=%d"), + aSettings.iRequireClientAuthenticationPresent, aSettings.iRequireClientAuthentication) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, SessionValidityTime=%d minutes"), + aSettings.iSessionValidityTimePresent, aSettings.iSessionValidityTime) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, CipherSuites Count=%d"), + aSettings.iCipherSuitesPresent, aSettings.iCipherSuites.Count()) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, PEAPv0Allowed=%d, PEAPv1Allowed=%d, PEAPv2Allowed=%d"), + aSettings.iPEAPVersionsPresent, aSettings.iPEAPv0Allowed,aSettings.iPEAPv1Allowed, aSettings.iPEAPv2Allowed ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, Certificates Count=%d"), + aSettings.iCertificatesPresent, aSettings.iCertificates.Count()) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - Certificate details below: \n")) ); + for( TInt n=0; n < aSettings.iCertificates.Count(); n++ ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - Certificate type:%d \n"), aSettings.iCertificates[n].iCertType) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - certificates - present=%d, SubjectName=%S"), + aSettings.iCertificates[n].iSubjectNamePresent, &(aSettings.iCertificates[n].iSubjectName)) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - certificates - present=%d, IssuerName=%S"), + aSettings.iCertificates[n].iIssuerNamePresent, &(aSettings.iCertificates[n].iIssuerName)) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - certificates - present=%d, SerialNumber=%S"), + aSettings.iCertificates[n].iSerialNumberPresent, &(aSettings.iCertificates[n].iSerialNumber)) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - certificates - SubjectKeyID present=%d"), + aSettings.iCertificates[n].iSubjectKeyIDPresent ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "SubjectKeyID:", aSettings.iCertificates[n].iSubjectKeyID.Ptr(), + aSettings.iCertificates[n].iSubjectKeyID.Size() ) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - certificates - Thumbprint present=%d"), + aSettings.iCertificates[n].iThumbprintPresent ) ); + + EAP_TRACE_DATA_DEBUG_SYMBIAN( ( "Thumbprint:", aSettings.iCertificates[n].iThumbprint.Ptr(), + aSettings.iCertificates[n].iThumbprint.Size() ) ); + } + +#ifdef USE_FAST_EAP_TYPE + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, AuthProvModeAllowed=%d"), + aSettings.iAuthProvModeAllowedPresent, aSettings.iAuthProvModeAllowed) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, UnauthProvModeAllowed=%d"), + aSettings.iUnauthProvModeAllowedPresent, aSettings.iUnauthProvModeAllowed) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, WarnADHPNoPAC=%d"), + aSettings.iWarnADHPNoPACPresent, aSettings.iWarnADHPNoPAC) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, WarnADHPNoMatchingPAC=%d"), + aSettings.iWarnADHPNoMatchingPACPresent, aSettings.iWarnADHPNoMatchingPAC) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, WarnNotDefaultServer=%d"), + aSettings.iWarnNotDefaultServerPresent, aSettings.iWarnNotDefaultServer) ); + + EAP_TRACE_DEBUG_SYMBIAN((_L("GetConfigurationL - present=%d, PAC Group Ref=%S"), + aSettings.iPACGroupReferencePresent, &(aSettings.iPACGroupReference)) ); + +#endif //#ifdef USE_FAST_EAP_TYPE + + EAP_TRACE_DEBUG_SYMBIAN((_L("**************** GetConfigurationL - Returning the above values: ***************\n")) ); + + + ////////////////////// + // Encapsulated types + ////////////////////// + + // Encapsulated types are only for EAP-PEAP, EAP-TTLS and EAP-FAST. Not for EAP-TLS. + if ( aEapType != eap_type_peap + && aEapType != eap_type_ttls +#ifdef USE_FAST_EAP_TYPE + && aEapType != eap_type_fast +#endif + ) + { + aSettings.iEncapsulatedEAPTypesPresent = EFalse; + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetConfigurationL - End - Since no encapsulated type for the EAPType =%d \n"), + aEapVendorType)); + + return; // No need to proceed. Nothing more to provide. + } + +#ifdef USE_EAP_EXPANDED_TYPES + + RExpandedEapTypePtrArray enabledEAPTypes; + RExpandedEapTypePtrArray disabledEAPTypes; + + TRAPD(error, GetTunnelingExpandedEapDataL( + aDatabase, + 0, + enabledEAPTypes, + disabledEAPTypes, + aIndexType, + aIndex, + aTunnelingType, + aEapType)); + + if( error != KErrNone ) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetConfigurationL - ########### Getting Expanded Tunneling types from the DB failed ############ \n") ) ); + + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + enabledEAPTypes.Close(); + disabledEAPTypes.Close(); + + User::Leave(KErrGeneral); + } + + // There should be some enabled EAP types (atleast one). + if (enabledEAPTypes.Count() == 0) + { + // Nothing enabled. Some problem. + // We should get all the available EAP plugins on the device and make them enabled as default. + + RImplInfoPtrArray eapImplArray; + + TRAP(error, REComSession::ListImplementationsL(KEapTypeInterfaceUid, eapImplArray)); + if (error != KErrNone) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetConfigurationL - ########### Getting Expanded Tunneling types - Listing ECOM plugins failed ############ \n") ) ); + + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + enabledEAPTypes.Close(); + disabledEAPTypes.Close(); + + User::Leave(KErrNotFound); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("GetConfigurationL - ListImplementationsL - No: of available EAP plugin implementations=%d \n"), + eapImplArray.Count() ) ); + + SExpandedEAPType* expandedEAPTmp; + + // Add the EAP types to enabledEAPTypes array now. + + for (TInt i = 0; i < eapImplArray.Count(); i++) + { + if (aEapType == eap_type_peap) + { + // Some EAP types are not allowed inside EAP-PEAP. + if (CEapType::IsDisallowedInsidePEAP(*eapImplArray[i])) + { + continue; + } + + expandedEAPTmp = new SExpandedEAPType; + if (expandedEAPTmp == 0) + { + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + enabledEAPTypes.Close(); + disabledEAPTypes.Close(); + + eapImplArray.ResetAndDestroy(); + eapImplArray.Close(); + + User::Leave(KErrNoMemory); + } + + CleanupStack::PushL(expandedEAPTmp); + + expandedEAPTmp->iExpandedEAPType.Copy(eapImplArray[i]->DataType()); + + enabledEAPTypes.Append(expandedEAPTmp); + + CleanupStack::Pop(expandedEAPTmp); + } + + if (aEapType == eap_type_ttls) + { + // Some EAP types are not allowed inside EAP-TTLS. + if (CEapType::IsDisallowedInsideTTLS(*eapImplArray[i])) + { + continue; + } + + expandedEAPTmp = new SExpandedEAPType; + if (expandedEAPTmp == 0) + { + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + enabledEAPTypes.Close(); + disabledEAPTypes.Close(); + + eapImplArray.ResetAndDestroy(); + eapImplArray.Close(); + + User::Leave(KErrNoMemory); + } + + CleanupStack::PushL(expandedEAPTmp); + + expandedEAPTmp->iExpandedEAPType.Copy(eapImplArray[i]->DataType()); + + enabledEAPTypes.Append(expandedEAPTmp); + + CleanupStack::Pop(expandedEAPTmp); + } + +#ifdef USE_FAST_EAP_TYPE + + if (aEapType == eap_type_fast) + { + // Some EAP types are not allowed inside EAP-FAST. + if (CEapType::IsDisallowedInsidePEAP(*eapImplArray[i])) + { + continue; + } + + expandedEAPTmp = new SExpandedEAPType; + if (expandedEAPTmp == 0) + { + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + enabledEAPTypes.Close(); + disabledEAPTypes.Close(); + + eapImplArray.ResetAndDestroy(); + eapImplArray.Close(); + + User::Leave(KErrNoMemory); + } + + CleanupStack::PushL(expandedEAPTmp); + + expandedEAPTmp->iExpandedEAPType.Copy(eapImplArray[i]->DataType()); + + enabledEAPTypes.Append(expandedEAPTmp); + + CleanupStack::Pop(expandedEAPTmp); + } +#endif // #ifdef USE_FAST_EAP_TYPE + + } // End: for (TInt i = 0; i < eapImplArray.Count(); i++) + + eapImplArray.ResetAndDestroy(); + eapImplArray.Close(); + + } // End: if (enabledEAPTypes.Count() == 0) + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetConfigurationL - No: of available tunneled types for this EAP=%d \n"), + enabledEAPTypes.Count())); + + // enabledEAPTypes contains the EAP types now (expanded). + // Fill aSettings.iEncapsulatedEAPTypes here. + + for (TInt i = 0; i < enabledEAPTypes.Count(); i++) + { + eap_expanded_type_c expEAPTmp; + + // This will read the expanded EAP from enabledEAPTypes[i]->iExpandedEAPType to expEAPTmp. + // This makes easy to get the vendor type. + eap_expanded_type_c::read_type( 0, + 0, + enabledEAPTypes[i]->iExpandedEAPType.Ptr(), + KExpandedEAPTypeSize, + &expEAPTmp); + + // We need to fill only the vendor type to aSettings.iEncapsulatedEAPTypes + aSettings.iEncapsulatedEAPTypes.Append(expEAPTmp.get_vendor_type()); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetConfigurationL - Available encapsulated type for this EAP(%d)=%d\n"), + aEapVendorType, expEAPTmp.get_vendor_type())); + } + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetConfigurationL - aSettings.iEncapsulatedEAPTypes.Count()=%d \n"), + aSettings.iEncapsulatedEAPTypes.Count())); + + enabledEAPTypes.ResetAndDestroy(); + disabledEAPTypes.ResetAndDestroy(); + enabledEAPTypes.Close(); + disabledEAPTypes.Close(); + + aSettings.iEncapsulatedEAPTypesPresent = ETrue; + +#else // for Normal EAP types. + + TEapArray eapArray; + + TRAPD(err, GetEapDataL( + aDatabase, + 0, + eapArray, + aIndexType, + aIndex, + aTunnelingType, + aEapType)); + if (err != KErrNone) + { + eapArray.ResetAndDestroy(); + eapArray.Close(); + User::Leave(KErrGeneral); + } + + RImplInfoPtrArray eapImplArray; + + if (eapArray.Count() == 0) + { + // The array was empty. By default all types are enabled. + TRAP(err, REComSession::ListImplementationsL(KEapTypeInterfaceUid, eapImplArray)); + if (err != KErrNone) + { + eapArray.ResetAndDestroy(); + eapArray.Close(); + User::Leave(KErrGeneral); + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetConfigurationL - ListImplementationsL - No: of available implementations=%d \n"), eapImplArray.Count() ) ); + + TEap *eap; + for (TInt i = 0; i < eapImplArray.Count(); i++) + { + if (CEapType::IsDisallowedInsidePEAP(*eapImplArray[i])) + { + continue; + } + + eap = new TEap; + if (eap == 0) + { + eapArray.ResetAndDestroy(); + eapArray.Close(); + eapImplArray.ResetAndDestroy(); + eapImplArray.Close(); + User::Leave(KErrGeneral); + } + eap->UID.Copy(eapImplArray[i]->DataType()); + eap->Enabled = ETrue; + eapArray.Append(eap); + } + } + + TInt i(0); + + for (i = 0; i < eapArray.Count(); i++) + { + if (eapArray[i]->Enabled) + { + TLex8 tmp(eapArray[i]->UID); + TUint val(0); + tmp.Val(val); + aSettings.iEncapsulatedEAPTypes.Append(val); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetConfigurationL - Available encapsulated type for this EAP =%d \n"), val ) ); + } + } + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetConfigurationL - eapArray.Count()=%d \n"),eapArray.Count() ) ); + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetConfigurationL - aSettings.iEncapsulatedEAPTypes.Count()=%d \n"),aSettings.iEncapsulatedEAPTypes.Count() ) ); + + eapArray.ResetAndDestroy(); + eapArray.Close(); + eapImplArray.ResetAndDestroy(); + eapImplArray.Close(); + + aSettings.iEncapsulatedEAPTypesPresent = ETrue; + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::GetConfigurationL - End \n") ) ); + +} // EapTlsPeapUtils::GetConfigurationL() + + +void EapTlsPeapUtils::CopySettingsL( + RDbNamedDatabase& aDatabase, + const TDesC& aTableName, + const TIndexType aSrcIndexType, + const TInt aSrcIndex, + const eap_type_value_e aSrcTunnelingType, + const TIndexType aDestIndexType, + const TInt aDestIndex, + const eap_type_value_e aDestTunnelingType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aSrcTunnelingVendorType = aSrcTunnelingType.get_vendor_type(); + TUint aDestTunnelingVendorType = aDestTunnelingType.get_vendor_type(); + +#else + + TUint aSrcTunnelingVendorType = static_cast(aSrcTunnelingType); + TUint aDestTunnelingVendorType = static_cast(aDestTunnelingType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::CopySettingsL table=%s, aSrcIndexType=%d, aDestIndexType=%d, aSrcIndex=%d, aDestIndex=%d, SrcTunneling vendor type=%d, DestTunneling vendor type=%d \n"), + aTableName.Ptr(), aSrcIndexType, aDestIndexType, aSrcIndex, aDestIndex, aSrcTunnelingVendorType, aDestTunnelingVendorType)); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + sqlStatement.Format(KSQL, &aTableName, + &KServiceType, aDestIndexType, &KServiceIndex, aDestIndex, &KTunnelingType, aDestTunnelingVendorType); + + RDbView view; + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EUpdatable)); + + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + if (view.FirstL()) + { + do + { + view.GetL(); + if (view.ColUint(colSet->ColNo(KServiceType)) == static_cast(aDestIndexType) + && view.ColUint(colSet->ColNo(KServiceIndex)) == static_cast(aDestIndex) + && view.ColUint(colSet->ColNo(KTunnelingType)) == aDestTunnelingVendorType) + { + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::CopySettingsL - Delete old records\n") ) ); + view.DeleteL(); + } + } while (view.NextL() != EFalse); + } + + view.Close(); + CleanupStack::PopAndDestroy(2); // view, colset + + sqlStatement.Format(KSQL, &aTableName, + &KServiceType, aSrcIndexType, &KServiceIndex, aSrcIndex, &KTunnelingType, aSrcTunnelingVendorType); + + User::LeaveIfError(view.Prepare(aDatabase, TDbQuery(sqlStatement), TDbWindow::EUnlimited , RDbView::EUpdatable)); + + // View must be closed when no longer needed + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + // Get column set so we get the correct column numbers + colSet = view.ColSetL(); + CleanupStack::PushL(colSet); + + TDbBookmark bookmark; + + if (view.FirstL()) + { + do { + // Get the next line + view.GetL(); + + // Check if it was already copied + if (view.ColUint(colSet->ColNo(KServiceType)) != static_cast(aDestIndexType) + || view.ColUint(colSet->ColNo(KServiceIndex)) != static_cast(aDestIndex) + || view.ColUint(colSet->ColNo(KTunnelingType)) != aDestTunnelingVendorType) + { + bookmark = view.Bookmark(); + + view.InsertCopyL(); + + view.SetColL(colSet->ColNo(KServiceType), static_cast(aDestIndexType)); + + view.SetColL(colSet->ColNo(KServiceIndex), static_cast(aDestIndex)); + + view.SetColL(colSet->ColNo(KTunnelingType), aDestTunnelingVendorType); + + view.PutL(); + + view.GotoL(bookmark); + } + } while (view.NextL() != EFalse); + } + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::CopySettingsL - Nothing to Copy\n"))); + + } + + view.Close(); + + CleanupStack::PopAndDestroy(3); // view, colset, buf + +} // EapTlsPeapUtils::CopySettingsL() + + +// --------------------------------------------------------- +// EapTlsPeapUtils::DeleteConfigurationL() +// --------------------------------------------------------- +// +void EapTlsPeapUtils::DeleteConfigurationL( + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aEapVendorType = aEapType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aEapVendorType = static_cast(aEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::DeleteConfigurationL:Start:aIndexType=%d,aIndex=%d,aTunnelingVendorType=%d,aEapVendorType=%d"), + aIndexType, aIndex, aTunnelingVendorType, aEapVendorType)); + + TPtrC dbname; + TPtrC settings; + TPtrC usercerts; + TPtrC cacerts; + TPtrC ciphersuites; + +#ifdef USE_FAST_EAP_TYPE + TPtrC fastSpecialSettings; +#endif + + switch (aEapVendorType) + { + case eap_type_tls: + { + dbname.Set(KTlsDatabaseName); + settings.Set(KTlsDatabaseTableName); + usercerts.Set(KTlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTlsAllowedCipherSuitesDatabaseTableName); + } + break; + + case eap_type_peap: + { + dbname.Set(KPeapDatabaseName); + settings.Set(KPeapDatabaseTableName); + usercerts.Set(KPeapAllowedUserCertsDatabaseTableName); + cacerts.Set(KPeapAllowedCACertsDatabaseTableName); + ciphersuites.Set(KPeapAllowedCipherSuitesDatabaseTableName); + } + break; + + case eap_type_ttls: + { + dbname.Set(KTtlsDatabaseName); + settings.Set(KTtlsDatabaseTableName); + usercerts.Set(KTtlsAllowedUserCertsDatabaseTableName); + cacerts.Set(KTtlsAllowedCACertsDatabaseTableName); + ciphersuites.Set(KTtlsAllowedCipherSuitesDatabaseTableName); + } + break; + +#ifdef USE_FAST_EAP_TYPE + + case eap_type_fast: + { + dbname.Set(KFastDatabaseName); + settings.Set(KFastGeneralSettingsDBTableName); // This is general settings for FAST. + fastSpecialSettings.Set(KFastSpecialSettingsDBTableName); + + usercerts.Set(KFastAllowedUserCertsDatabaseTableName); + cacerts.Set(KFastAllowedCACertsDatabaseTableName); + ciphersuites.Set(KFastAllowedCipherSuitesDatabaseTableName); + } + break; +#endif + + case eap_type_ttls_plain_pap: + { + dbname.Set( KTtlsDatabaseName ); + settings.Set( KTtlsDatabaseTableName ); + } + break; + + default: + // Should never happen + User::Leave(KErrArgument); + } + + RDbs session; + RDbNamedDatabase database; + + // Connect to the DBMS server. + User::LeaveIfError(session.Connect()); + CleanupClosePushL(session); + +#ifdef SYMBIAN_SECURE_DBMS + + // Create the secure shared database with the specified secure policy. + // Database will be created in the data caging path for DBMS (C:\private\100012a5). + + TInt err = database.Create(session, dbname, KSecureUIDFormat); + + if(err == KErrNone) + { + // Database was created so it was empty. No need for further actions. + database.Destroy(); + CleanupStack::PopAndDestroy(); + return; + + } + else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + // Database existed, open it. + User::LeaveIfError(database.Open(session, dbname, KSecureUIDFormat)); + CleanupClosePushL(database); + +#else + // For non-secured database. The database will be created in the old location (c:\system\data). + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + TInt err = database.Create(fsSession, dbname); + + if(err == KErrNone) + { + // Database was created so it was empty. No need for further actions. + database.Destroy(); + CleanupStack::PopAndDestroy(2); // fsSession, database session + return; + + } + else if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + CleanupStack::PopAndDestroy(); // close fsSession + + User::LeaveIfError(database.Open(session, dbname)); + CleanupClosePushL(database); + +#endif // #ifdef SYMBIAN_SECURE_DBMS + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::DeleteConfigurationL - Deleting the tables\n"))); + + _LIT(KSQL, "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + + //--------------------- Deletion 1 ----------------------------// + + // For all EAPs delete the settings table. + // For EAP-FAST, this is delting the general settings table. + + sqlStatement.Format(KSQL, &settings, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + RDbView view; + User::LeaveIfError(view.Prepare(database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + // Delete rows + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + CleanupStack::PopAndDestroy(); // view + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::DeleteConfigurationL: Deleted %s (general) settings table"), settings.Ptr())); + + ////////////////////////////////////////// + // This is only for plain PAP settings. // + ////////////////////////////////////////// + if ( aEapVendorType == eap_type_ttls_plain_pap ) + { + CleanupStack::PopAndDestroy(3); // buf, database, session + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::DeleteConfigurationL: Return"))); + // we return here in case of pap because there is nothing to do else. + return; + } + + //--------------------- Deletion 2 ----------------------------// + + // For all EAPs delte the User cert table + +// KSQL2 is "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d" + + sqlStatement.Format(KSQL, &usercerts, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + + User::LeaveIfError(view.Prepare(database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + CleanupStack::PopAndDestroy(); // view + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::DeleteConfigurationL: Deleted USER certs table"))); + + //--------------------- Deletion 3 ----------------------------// + + // For all EAPs delete the CA cert table + +// KSQL3 is "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d" + + sqlStatement.Format(KSQL, &cacerts, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + + User::LeaveIfError(view.Prepare(database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + CleanupStack::PopAndDestroy(); // view + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::DeleteConfigurationL: Deleted CA certs table"))); + + //--------------------- Deletion 4 ----------------------------// + + // For all EAPs delete the Cipher suite table + +// KSQL4 is "SELECT * FROM %S WHERE %S=%d AND %S=%d AND %S=%d" + + sqlStatement.Format(KSQL, &ciphersuites, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + + User::LeaveIfError(view.Prepare(database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + CleanupStack::PopAndDestroy(&view); // Close view + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::DeleteConfigurationL: Deleted cipher suits table"))); + + +#ifdef USE_FAST_EAP_TYPE + + if(aEapVendorType == eap_type_fast) + { + //--------------------- Deletion 5 ----------------------------// + + // For EAP-FAST, delete the special settings table + + sqlStatement.Format(KSQL, &fastSpecialSettings, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + + // Evaluate view + + User::LeaveIfError(view.Prepare(database,TDbQuery(sqlStatement), TDbWindow::EUnlimited)); + CleanupClosePushL(view); + User::LeaveIfError(view.EvaluateAll()); + + if (view.FirstL()) + { + do { + view.DeleteL(); + } while (view.NextL() != EFalse); + } + + CleanupStack::PopAndDestroy(&view); // Close view + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::DeleteConfigurationL: Deleted EAP-FAST Special settings table"))); + + } // End: if(aEapVendorType == eap_type_fast) + +#endif // End: #ifdef USE_FAST_EAP_TYPE + + // Close database + CleanupStack::PopAndDestroy(3); // buf, database, session + +EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::DeleteConfigurationL: End"))); + +} // EapTlsPeapUtils::DeleteConfigurationL() + + +// --------------------------------------------------------- +// EapTlsPeapUtils::AddExtraCertColumnsL() +// --------------------------------------------------------- +// +void EapTlsPeapUtils::AddExtraCertColumnsL( + RDbNamedDatabase& aDatabase, + TDesC& aTableName) +{ + // Check if the EXTRA cert columns are already in the table. + + CDbColSet* colSetCertTable = aDatabase.ColSetL(aTableName); + User::LeaveIfNull(colSetCertTable); + CleanupStack::PushL(colSetCertTable); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::AddExtraCertColumnsL - Number of columns in %S table before addition=%d\n"), + &aTableName, colSetCertTable->Count())); + + // Check if there is a column for Serial Number, for example. + if(colSetCertTable->ColNo(KSerialNumber) == KDbNullColNo) + { + // The column is missing. Add all the EXTRA columns to the table. + + // EXTRA COLUMNS + //// NAME //////////////// TYPE //////////// Constant ///////////////////// + //| ActualSubjectKeyId | BINARY(20) | KActualSubjectKeyIdentifier |// + //| SubjectName | VARCHAR(255) | KSubjectName |// + //| IssuerName | VARCHAR(255) | KIssuerName |// + //| SerialNumber | VARCHAR(255) | KSerialNumber |// + //| Thumbprint | BINARY(64) | KThumbprint |// + ////////////////////////////////////////////////////////////////////////////// + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::AddExtraCertColumnsL - EXTRA cert columns missing from the table %S. Adding now.\n"), + &aTableName)); + + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLAlterTableForBin, "ALTER TABLE %S ADD %S BINARY(%d)"); + + sqlStatement.Format(KSQLAlterTableForBin, &aTableName, + &KActualSubjectKeyIdentifier, KKeyIdentifierLength); + + User::LeaveIfError( aDatabase.Execute(sqlStatement)); + + _LIT(KSQLAlterTableForVarChar, "ALTER TABLE %S ADD %S VARCHAR(%d)"); + + sqlStatement.Format(KSQLAlterTableForVarChar, &aTableName, + &KSubjectName, KGeneralStringMaxLength); + + User::LeaveIfError( aDatabase.Execute(sqlStatement)); + + sqlStatement.Format(KSQLAlterTableForVarChar, &aTableName, + &KIssuerName, KGeneralStringMaxLength); + + User::LeaveIfError( aDatabase.Execute(sqlStatement)); + + sqlStatement.Format(KSQLAlterTableForVarChar, &aTableName, + &KSerialNumber, KGeneralStringMaxLength); + + User::LeaveIfError( aDatabase.Execute(sqlStatement)); + + sqlStatement.Format(KSQLAlterTableForBin, &aTableName, + &KThumbprint, KThumbprintMaxLength); + + User::LeaveIfError( aDatabase.Execute(sqlStatement)); + + CleanupStack::PopAndDestroy( buf ); // Delete buf or sqlStatement + } + + CleanupStack::PopAndDestroy( colSetCertTable ); // Delete colSetCertTable. + + CDbColSet* colSetCertTableAfterAdd = aDatabase.ColSetL(aTableName); + User::LeaveIfNull(colSetCertTableAfterAdd); + + EAP_TRACE_DEBUG_SYMBIAN((_L("EapTlsPeapUtils::AddExtraCertColumnsL - Number of columns in %S table after addition=%d\n"), + &aTableName, colSetCertTableAfterAdd->Count())); + + delete colSetCertTableAfterAdd; +} // EapTlsPeapUtils::AddExtraCertColumnsL() + + +// --------------------------------------------------------- +// EapTlsPeapUtils::GetEapSettingsDataL() +// --------------------------------------------------------- +// +void EapTlsPeapUtils::GetEapSettingsDataL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const TDesC& aDbColumnName, + eap_variable_data_c * const aDbColumnValue) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aEapVendorType = aEapType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aEapVendorType = static_cast(aEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL-Start- aIndexType=%d, aIndex=%d, Tunneling vendor type=%d, Eap vendor type=%d \n"), + aIndexType,aIndex, aTunnelingVendorType, aEapVendorType)); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL Get Column Name:%S \n"), + &aDbColumnName)); + + TBufC generalSettingsTableName; + +#if defined (USE_FAST_EAP_TYPE) + TBufC specialSettingsTableName; +#endif + + // Set the database table name based on the type + switch (aEapVendorType) + { + case eap_type_tls: + generalSettingsTableName = KTlsDatabaseTableName; + break; + + case eap_type_peap: + generalSettingsTableName = KPeapDatabaseTableName; + break; + + case eap_type_ttls: + case eap_type_ttls_plain_pap: + generalSettingsTableName = KTtlsDatabaseTableName; + break; + +#if defined (USE_FAST_EAP_TYPE) + case eap_type_fast: + generalSettingsTableName = KFastGeneralSettingsDBTableName; // General settings + specialSettingsTableName = KFastSpecialSettingsDBTableName; // Special settings for only FAST + break; +#endif // #if defined (USE_FAST_EAP_TYPE) + + default: + { + // Unsupported EAP type + // Should never happen + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL: ERROR: Unsupported EAP type=%d"), + aEapVendorType)); + + User::Leave(KErrArgument); + } + } + + if(aDbColumnName.Size() <= 0) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL: ERROR: No Column Name!\n"))); + + User::Leave(KErrArgument); + } + + // Now do the database query + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + +#if defined(USE_FAST_EAP_TYPE) + + // Unlike other EAP types, EAP-FAST has some settings in special settings table + // (in KFastSpecialSettingsDBTableName) + + if(aEapType == eap_type_fast + && ((aDbColumnName.Compare(cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal) == 0) + || (aDbColumnName.Compare(cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal) == 0) + || (aDbColumnName.Compare(KFASTWarnADHPNoPAC) == 0) + || (aDbColumnName.Compare(KFASTWarnADHPNoMatchingPAC) == 0) + || (aDbColumnName.Compare(KFASTWarnNotDefaultServer) == 0) + || (aDbColumnName.Compare(KFASTPACGroupImportReferenceCollection) == 0) + || (aDbColumnName.Compare(KFASTPACGroupDBReferenceCollection) == 0))) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL: This field will be read from EAP-FAST's special table"))); + + sqlStatement.Format(KSQLQueryRow, &aDbColumnName, &specialSettingsTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + } + else + { + sqlStatement.Format(KSQLQueryRow, &aDbColumnName, &generalSettingsTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + } + +#else + + { + sqlStatement.Format(KSQLQueryRow, &aDbColumnName, &generalSettingsTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + } + +#endif // End: #if defined(USE_FAST_EAP_TYPE) + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL - SQL query formated OK"))); + + RDbView view; + + User::LeaveIfError(view.Prepare( + aDatabase, + TDbQuery(sqlStatement), + TDbWindow::EUnlimited, + RDbView::EReadOnly)); + + CleanupStack::PopAndDestroy(buf); // We don't need buf or sqlStatement any more. + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + eap_status_e status(eap_status_ok); + + if (view.FirstL()) + { + view.GetL(); + + switch (view.ColType(KDefaultColumnInView_One)) + { + case EDbColText: + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL: EDbColText\n"))); + if ( !view.IsColNull( KDefaultColumnInView_One ) ) + { + status = aDbColumnValue->set_copy_of_buffer( + view.ColDes(KDefaultColumnInView_One).Ptr(), + view.ColDes(KDefaultColumnInView_One).Size()); + } + else + { + aDbColumnValue->reset(); + } + } + break; + + case EDbColBinary: + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL: EDbColBinary\n"))); + if ( !view.IsColNull( KDefaultColumnInView_One ) ) + { + status = aDbColumnValue->set_copy_of_buffer( + view.ColDes8(KDefaultColumnInView_One).Ptr(), + view.ColDes8(KDefaultColumnInView_One).Size()); + } + else + { + aDbColumnValue->reset(); + } + } + break; + + case EDbColUint32: + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL: EDbColUint32\n"))); + if ( !view.IsColNull( KDefaultColumnInView_One ) ) + { + TUint value; + value = view.ColUint32(KDefaultColumnInView_One); + status = aDbColumnValue->set_copy_of_buffer(&value, sizeof(value)); + } + else + { + aDbColumnValue->reset(); + } + } + break; + + case EDbColInt64: + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL: EDbColInt64\n"))); + if ( !view.IsColNull( KDefaultColumnInView_One ) ) + { + TInt64 value; + value = view.ColInt64(KDefaultColumnInView_One); + status = aDbColumnValue->set_copy_of_buffer(&value, sizeof(value)); + } + else + { + aDbColumnValue->reset(); + } + } + break; + + case EDbColLongBinary: + { + // This needs special handling. (readstream). Not needed in this DB yet. + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL: ERROR: EDbColLongBinary not supported in this DB!\n"))); + + User::Leave(KErrNotSupported); + } + break; + + default: + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL: ERROR: Unsupported DB field! \n"))); + + User::Leave(KErrNotSupported); + break; + } + } + + CleanupStack::PopAndDestroy( &view ); // Close view. + + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL: Status=%d\n"), status)); + } + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("GetEapSettingsDataL:DbColumnValue:", + aDbColumnValue->get_data(aDbColumnValue->get_data_length()), + aDbColumnValue->get_data_length())); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::GetEapSettingsDataL: End \n"))); + +} // EapTlsPeapUtils::GetEapSettingsDataL() + + +// --------------------------------------------------------- +// EapTlsPeapUtils::SetEapSettingsDataL() +// --------------------------------------------------------- +// +void EapTlsPeapUtils::SetEapSettingsDataL( + RDbNamedDatabase& aDatabase, + const TIndexType aIndexType, + const TInt aIndex, + const eap_type_value_e aTunnelingType, + const eap_type_value_e aEapType, + const TDesC& aDbColumnName, + const eap_variable_data_c * const aDbColumnValue) +{ +#ifdef USE_EAP_EXPANDED_TYPES + + TUint aTunnelingVendorType = aTunnelingType.get_vendor_type(); + TUint aEapVendorType = aEapType.get_vendor_type(); + +#else + + TUint aTunnelingVendorType = static_cast(aTunnelingType); + TUint aEapVendorType = static_cast(aEapType); + +#endif //#ifdef USE_EAP_EXPANDED_TYPES + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapSettingsDataL-Start- aIndexType=%d, aIndex=%d, Tunneling vendor type=%d, Eap vendor type=%d \n"), + aIndexType,aIndex, aTunnelingVendorType, aEapVendorType)); + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapSettingsDataL Set Column Name:%S \n"), + &aDbColumnName)); + + EAP_TRACE_DATA_DEBUG_SYMBIAN(("SetEapSettingsDataL:DbColumnValue:", + aDbColumnValue->get_data(aDbColumnValue->get_data_length()), + aDbColumnValue->get_data_length())); + + TBufC generalSettingsTableName; + +#if defined (USE_FAST_EAP_TYPE) + TBufC specialSettingsTableName; +#endif + + // Set the database table name based on the type + switch (aEapVendorType) + { + case eap_type_tls: + generalSettingsTableName = KTlsDatabaseTableName; + break; + + case eap_type_peap: + generalSettingsTableName = KPeapDatabaseTableName; + break; + + case eap_type_ttls: + case eap_type_ttls_plain_pap: + generalSettingsTableName = KTtlsDatabaseTableName; + break; + +#if defined (USE_FAST_EAP_TYPE) + case eap_type_fast: + generalSettingsTableName = KFastGeneralSettingsDBTableName; // General settings + specialSettingsTableName = KFastSpecialSettingsDBTableName; // Special settings for only FAST + break; +#endif // #if defined (USE_FAST_EAP_TYPE) + + default: + { + // Unsupported EAP type + // Should never happen + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapSettingsDataL: ERROR: Unsupported EAP type=%d"), + aEapVendorType)); + + User::Leave(KErrArgument); + } + } + + if(aDbColumnName.Size() <= 0) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapSettingsDataL: ERROR: No Column Name!\n"))); + + User::Leave(KErrArgument); + } + + // Now do the database query + HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength); + TPtr sqlStatement = buf->Des(); + + _LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d"); + +#if defined(USE_FAST_EAP_TYPE) + + // Unlike other EAP types, EAP-FAST has some settings in special settings table + // (in KFastSpecialSettingsDBTableName) + + if(aEapType == eap_type_fast + && ((aDbColumnName.Compare(cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode_literal) == 0) + || (aDbColumnName.Compare(cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP_literal) == 0) + || (aDbColumnName.Compare(KFASTWarnADHPNoPAC) == 0) + || (aDbColumnName.Compare(KFASTWarnADHPNoMatchingPAC) == 0) + || (aDbColumnName.Compare(KFASTWarnNotDefaultServer) == 0) + || (aDbColumnName.Compare(KFASTPACGroupImportReferenceCollection) == 0) + || (aDbColumnName.Compare(KFASTPACGroupDBReferenceCollection) == 0))) + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapSettingsDataL: This field will be read from EAP-FAST's special table"))); + + sqlStatement.Format(KSQLQueryRow, &aDbColumnName, &specialSettingsTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + } + else + { + sqlStatement.Format(KSQLQueryRow, &aDbColumnName, &generalSettingsTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + } + +#else + + { + sqlStatement.Format(KSQLQueryRow, &aDbColumnName, &generalSettingsTableName, + &KServiceType, aIndexType, &KServiceIndex, aIndex, &KTunnelingType, aTunnelingVendorType); + } + +#endif // End: #if defined(USE_FAST_EAP_TYPE) + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapSettingsDataL - SQL query formated OK"))); + + RDbView view; + + User::LeaveIfError(view.Prepare( + aDatabase, + TDbQuery(sqlStatement), + TDbWindow::EUnlimited, + RDbView::EUpdatable)); + + CleanupStack::PopAndDestroy(buf); // We don't need buf or sqlStatement any more. + + CleanupClosePushL(view); + + User::LeaveIfError(view.EvaluateAll()); + + if (view.FirstL()) + { + view.UpdateL(); // Here it is update. + + if(view.ColCount() == KDefaultColumnInView_One) + { + // There should be one column (only one) with the specified column name. + + HBufC8* dbColVal8 = HBufC8::NewLC(aDbColumnValue->get_data_length()); + TPtr8 dbColValPtr8 = dbColVal8->Des(); + + dbColValPtr8.Copy( + aDbColumnValue->get_data( aDbColumnValue->get_data_length() ), + aDbColumnValue->get_data_length() ); + + switch (view.ColType(KDefaultColumnInView_One)) + { + case EDbColText: + { + TPtr dbColValPtr(0,dbColValPtr8.Size()); + dbColValPtr.Copy(dbColValPtr8); + + view.SetColL(KDefaultColumnInView_One, dbColValPtr); + } + break; + + case EDbColBinary: + { + view.SetColL(KDefaultColumnInView_One, dbColValPtr8); + } + break; + + case EDbColUint32: + { + +#if defined (USE_FAST_EAP_TYPE) + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("eap_am_type_tls_peap_symbian_c::authentication_finishedL WARNING, HACK to set Unauth Prov mode set to default (NO)!"))); + + view.SetColL(KDefaultColumnInView_One, EFASTUnauthProvModeAllowedNo); + +#endif // End: #if defined (USE_FAST_EAP_TYPE) + } + break; + + case EDbColInt64: + { + // Do some lexical analysis to get TInt64 value here and set it in DB. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapSettingsDataL: ERROR: EDbColInt64 not supported here yet!\n"))); + + User::Leave(KErrNotSupported); + } + break; + + case EDbColLongBinary: + { + // This needs special handling. (readstream). Not needed in this DB yet. + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapSettingsDataL: ERROR: EDbColLongBinary not supported in this DB!\n"))); + + User::Leave(KErrNotSupported); + } + break; + + default: + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapSettingsDataL: ERROR: Unsupported DB field! \n"))); + + User::Leave(KErrNotSupported); + break; + } + + CleanupStack::PopAndDestroy(dbColVal8); + + } // End: if(view.ColCount() == KDefaultColumnInView_One) + else + { + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapSettingsDataL: ERROR: Too many columns in DB view, count=%d \n"), + view.ColCount())); + + User::Leave(KErrNotFound); + } + } // End: if (view.FirstL()) + + // Now it should go to the DB. + view.PutL(); + + CleanupStack::PopAndDestroy( &view ); // Close view. + + EAP_TRACE_DEBUG_SYMBIAN( + (_L("EapTlsPeapUtils::SetEapSettingsDataL: End \n"))); +} + +/* + * Alter table for added column, if doesn't exist + * + */ +void EapTlsPeapUtils::AlterTableL( + RDbNamedDatabase& aDb, + TAlterTableCmd aCmd, + const TDesC& aTableName, + const TDesC& aColumnName, + const TDesC& aColumnDef ) + { + + CDbColSet* colSet = aDb.ColSetL( aTableName ); + User::LeaveIfNull( colSet ); + CleanupStack::PushL( colSet ); + + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "EapTlsPeapUtils::AlterTableL() \ + Number of columns in %S table is %d.\n" ), + &aTableName, colSet->Count() ) ); + + if ( aCmd == EAddColumn ) + { + // Check if there is a target column + if( colSet->ColNo( aColumnName ) != KDbNullColNo ) + { + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "EapTlsPeapUtils::AlterTableL() \ + Column %S exists already in table %S.\n" ), + &aColumnName, &aTableName ) ); + CleanupStack::PopAndDestroy( colSet ); + return; + } + } + else + { + // Check if there is a target column + if( colSet->ColNo( aColumnName ) == KDbNullColNo ) + { + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "EapTlsPeapUtils::AlterTableL() \ + Column %S does not exists already in table %S.\n" ), + &aColumnName, &aTableName ) ); + CleanupStack::PopAndDestroy( colSet ); + return; + } + } + + HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength ); + TPtr sqlStatement = buf->Des(); + + _LIT( KSqlAddCol, "ALTER TABLE %S ADD %S %S" ); + _LIT( KSqlRemoveCol, "ALTER TABLE %S DROP %S" ); + + if ( aCmd == EAddColumn ) + { + sqlStatement.Format( KSqlAddCol, &aTableName, + &aColumnName, &aColumnDef ); + } + else + { + sqlStatement.Format( KSqlRemoveCol, &aTableName, + &aColumnName ); + } + + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "EapTlsPeapUtils::AlterTableL(): sqlStatement=%S\n"), + &sqlStatement ) ); + + User::LeaveIfError( aDb.Execute( sqlStatement ) ); + CleanupStack::PopAndDestroy( buf ); + CleanupStack::PopAndDestroy( colSet ); + + CDbColSet* alteredColSet = aDb.ColSetL( aTableName ); + User::LeaveIfNull( alteredColSet ); + EAP_TRACE_DEBUG_SYMBIAN( ( _L( + "EapTlsPeapUtils::AlterTableL() \ + Number of columns in %S table after adding is %d.\n" ), + &aTableName, alteredColSet->Count() ) ); + delete alteredColSet; + + } // EapTlsPeapUtils::AlterTableL() + +// End of file + + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/ttls_pap/symbian/inc/eap_ttls_pap_active.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/ttls_pap/symbian/inc/eap_ttls_pap_active.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,304 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Provide synch/asynch services used by the caller to show +* EAP-TTLS-PAP related notes. +* +*/ + + +#ifndef EAPTTLSPAPACTIVE_H +#define EAPTTLSPAPACTIVE_H + + +// INCLUDES +#include +#include +#include +#include +#include "EapTtlsPapDbInfoStruct.h" +#include "eap_status.h" + +// FORWARD DECLARATIONS +class eap_am_type_tls_peap_symbian_c; +class eap_variable_data_c; +class eap_am_tools_symbian_c; + +// CLASS DECLARATION +/** +* CEapTtlsPapActive class. +* +* Class provides synch/asynch services used by the caller. +* These services includes: +* - query for TTLS-PAP user name and password. +*/ +NONSHARABLE_CLASS( CEapTtlsPapActive ) + : public CActive + { + + public: + /** + * State defines the type of service called. + */ + enum TEapTtlsPapActiveState + { + EEapTtlsPapActiveQueryUserNameAndPassword, /* 0 */ + EEapTtlsPapActiveShowAuthQueryDialog, /* 1 */ + EEapTtlsPapActiveShowPapChallengeMsgDialog, /* 2 */ + EEapTtlsPapActiveShowPapChallengeReplyQueryDialog, /* 3 */ + // ... + EEapTtlsPapActiveStatesNumber /* 4 */ // keep always as last element + }; + + public: // Constructors and destructor + + /** + * Two-phased constructor. + * + * @param aCaller Pointer AO owner. + */ + static CEapTtlsPapActive* NewL( + eap_am_type_tls_peap_symbian_c* aCaller, + eap_am_tools_symbian_c* aAmTools ); + + /** + * Destructor. + */ + ~CEapTtlsPapActive(); + + + public: // new + + /** + * Start active object. + * + * @param aState State defines the type of service requested, see TEapTtlsPapActiveState. + * @return TBool ETrue - successful start, EFalse - starting failed. + */ + TBool Start( TEapTtlsPapActiveState aState ); + + /** + * Allocate server challenge. + * + * Note, utf8->unicode conversion is needed. + * + * @param aSrvChallenge Reference to server challenge. + */ + eap_status_e UpdateSrvChallenge( const eap_variable_data_c& aSrvChallengeUtf8 ); + + protected: // from CActive + + /** + * DoCancel from CActive + */ + virtual void DoCancel(); + + /** + * RunL from CActive + */ + virtual void RunL(); + + private: // new, for AO + + /** + * Complete query-user-name-and-password request. + */ + void CompleteQueryUserNameAndPassword(); + + /** + * Complete query-user-name-and-password request + * with null server challenge. + */ + void CompleteWithSrvChallengeNull(); + + /** + * Complete query-user-name-and-password request + * with not null server challenge. + */ + void CompleteWithSrvChallengeNotNull(); + + /** + * Display authentication query dialog. + * + * Note! The call is asynchronous, i.e., return is done immediately. + */ + void StartAuthenticationQueryDialog(); + + /** + * Complete start-authentication-query-dialog request. + * + * If user accepts query, the caller is notified with EEapTtlsPapNotifierUserActionOk + * value. If user cancells the query, EEapTtlsPapNotifierUserActionCancel + * is given to the caller. + */ + void CompleteAuthenticationQueryDialog(); + + /** + * Send server challenge data size to UI side. + * + * Note! The call is asynchronous, i.e., return is done immediately. + */ + void StartSrvChallengeSize(); + + /** + * Complete start-srv-challenge-size request. + */ + void CompleteSrvChallengeSize(); + + /** + * Display PAP challenge message dialog. + * + * Note! The call is asynchronous, i.e., return is done immediately. + */ + void StartPapChallengeMsgDialog(); + + /** + * Complete start-pap-challenge-msg-dialog request. + */ + void CompletePapChallengeMsgDialog(); + + /** + * Display PAP challenge user reply query dialog. + * + * Note! The call is asynchronous, i.e., return is done immediately. + */ + void StartPapChallengeReplyQueryDialog(); + + /** + * Complete start-pap-challenge-user-reply-query-dialog request. + */ + void CompletePapChallengeReplyQueryDialog(); + + private: // new, other + + /** + * Take current time. + * + * @return Current time, number of microseconds since midnight, + * January 1st, 0 AD nominal Gregorian. + */ + TInt64 GetCurrentTime(); + + /** + * Cleans allocated memories and restores the initial object state. + */ + void Clean(); + + private: // private constructors + + /** + * C++ default constructor. + * + * @param aCaller Pointer to AO owner. + */ + CEapTtlsPapActive( + eap_am_type_tls_peap_symbian_c* aCaller, + eap_am_tools_symbian_c* aAmTools ); + + /** + * By default Symbian 2nd phase constructor is private. + */ + void ConstructL(); + + private: // data + + /** + * Object of this class implements functionality + * of platform adaptation of Symbian. + * + * Not owned. + */ + eap_am_tools_symbian_c* iAmTools; + + /** + * User / owner of this AO. + * + * Not owned. + */ + eap_am_type_tls_peap_symbian_c* iCaller ; + + /** + * State defines the type of the requested service. + */ + TEapTtlsPapActiveState iActiveState; + + /** + * Notifier. It acts as a service provider. + */ + RNotifier iNotifier; + + /** + * Data sent from AO to notifier plugin. + * + * If user name exists in database, it is sent to notifier. + * Also could be used later, if server challenge is sent to UI + * for displaying. + */ + TPapUiNotifierInfo* iNotifierDataToUser; + + /** + * Packaged data sent from AO to notifier plugin. + */ + TPckg* iNotifierDataPckgToUser; + + /** + * Data from notifier plugin to AO. + * Structure includes UI dialog id, user action value, + * notifier buffer. + */ + TPapUiNotifierInfo* iNotifierDataFromUser; + + /** + * Packaged data from notifier plugin to AO. + */ + TPckg* iNotifierDataPckgFromUser; + + /** + * Stores user action. Possible values are + * EPapNotifierUserActionOk and EPapNotifierUserActionCancel. + */ + EPapNotifierUserAction iUserAction; + + /** + * Server challenge in unicode format. + */ + HBufC16* iSrvChallengeUnicode; + + /** + * A pointer to the request status object. + */ + TRequestStatus* iRequestStatus; + + /** + * Structure contains database data for TTLS-PAP. + */ + TTtlsPapDbInfo iTtlsPapDbInfo; + + /** + * Flag is needed to read database only once. + * ETrue - initialized, EFalse - not initialized. + */ + TBool iIsTtlsPapDbInfoInitialized; + + /* + * Boolean flag to make sure that if objects are deleted in cancel, + * we don't use them anymore. + */ + TBool iCancelCalled; + + }; + + +#endif // EAPTTLSPAPACTIVE_H + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/type/ttls_pap/symbian/src/eap_ttls_pap_active.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/type/ttls_pap/symbian/src/eap_ttls_pap_active.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,770 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Provide synch/asynch services used by the caller to show +* EAP-TTLS-PAP related notes. +* +*/ + + +// INCLUDE FILES +#include "eap_tools.h" +#include "eap_ttls_pap_active.h" +#include "eap_am_type_tls_peap_symbian.h" +#include "eap_am_trace_symbian.h" +#include "eap_variable_data.h" + +// ================= public: Constructors and destructor ======================= + +// --------------------------------------------------------- +// CEapTtlsPapActive::NewL() +// --------------------------------------------------------- +// +CEapTtlsPapActive* CEapTtlsPapActive::NewL( + eap_am_type_tls_peap_symbian_c* aCaller, + eap_am_tools_symbian_c* aAmTools ) + { + DEBUG( "CEapTtlsPapActive::NewL()" ); + CEapTtlsPapActive* self = new(ELeave) CEapTtlsPapActive( + aCaller, aAmTools ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// --------------------------------------------------------- +// CEapTtlsPapActive::~CEapTtlsPapActive() +// --------------------------------------------------------- +// +CEapTtlsPapActive::~CEapTtlsPapActive() + { + DEBUG( "CEapTtlsPapActive::~CEapTtlsPapActive()" ); + if ( !iCancelCalled ) + { + Clean(); + } + } + +// ================= public: new ======================= + +// --------------------------------------------------------- +// CEapTtlsPapActive::Start() +// --------------------------------------------------------- +// +TBool CEapTtlsPapActive::Start( TEapTtlsPapActiveState aState ) + { + DEBUG1( "CEapTtlsPapActive::Start() aState=%d.", aState ); + TBool status = ETrue; + + if( IsActive() ) + { + DEBUG2( "CEapTtlsPapActive::Start() ERROR: AO is active, iActiveState=%d, aState=%d.", + iActiveState, aState ); + return EFalse; + } + if ( iCancelCalled ) + { + DEBUG( "CEapTtlsPapActive::Start() cancel was called." ); + return EFalse; + } + iActiveState = aState; + switch ( iActiveState ) + { + case EEapTtlsPapActiveQueryUserNameAndPassword: + { + // nothing to do here, we should return asap; + // the job is done in RunL() method; + // therefore we complete here + SetActive(); + iRequestStatus = &iStatus; + User::RequestComplete( iRequestStatus, KErrNone ); + break; + } + case EEapTtlsPapActiveShowAuthQueryDialog: // asynch. call + { + StartAuthenticationQueryDialog(); + SetActive(); + break; + } + case EEapTtlsPapActiveShowPapChallengeMsgDialog: + { + StartPapChallengeMsgDialog(); + SetActive(); + break; + } + case EEapTtlsPapActiveShowPapChallengeReplyQueryDialog: + { + StartPapChallengeReplyQueryDialog(); + SetActive(); + break; + } + default: + { + DEBUG1( "CEapTtlsPapActive::Start() ERROR: State is not supported, iActiveState = %d.", + iActiveState ); + status = EFalse; + break; + } + } + return status; + } // EapTtlsPapActive::Start() + + +// --------------------------------------------------------- +// CEapTtlsPapActive::UpdateSrvChallenge() +// --------------------------------------------------------- +// +eap_status_e CEapTtlsPapActive::UpdateSrvChallenge( + const eap_variable_data_c& aSrvChallengeUtf8 ) + { + DEBUG( "CEapTtlsPapActive::UpdateSrvChallenge()" ); + + eap_status_e status = eap_status_ok; + + if ( iSrvChallengeUnicode != NULL ) + { + // delete + delete iSrvChallengeUnicode ; + iSrvChallengeUnicode = NULL; + } + // convert utf8->unicode, + // aSrvChallengeUtf8 is UTF8 string, unicode max length is + // then the length of UTF8 string. + // NOTE, HBufC16 length means count of 16-bit objects. + TRAPD( err, iSrvChallengeUnicode = HBufC16::NewL( aSrvChallengeUtf8.get_data_length() ); ); + if ( err != KErrNone ) + { + status = iCaller->ConvertAmErrorToEapolError( err ); + return status; + } + TPtr16 srvChallengeUnicodePtr = iSrvChallengeUnicode->Des(); + + const TPtrC8 ptrUtf8( + aSrvChallengeUtf8.get_data( aSrvChallengeUtf8.get_data_length() ), + aSrvChallengeUtf8.get_data_length() ); // Length in bytes + + CnvUtfConverter::ConvertToUnicodeFromUtf8( + srvChallengeUnicodePtr, ptrUtf8 ); + // print data + EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( + EAPL( "iSrvChallengeUnicode" ), + iSrvChallengeUnicode->Ptr(), + iSrvChallengeUnicode->Size() ) ); + + return status; + } + + +// ================= protected: from CActive ======================= + +// --------------------------------------------------------- +// CEapTtlsPapActive::DoCancel() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::DoCancel() + { + DEBUG( "CEapTtlsPapActive::DoCancel()" ); + DEBUG( "CEapTtlsPapActive::DoCancel() iNotifier.CancelNotifier() called." ); + iNotifier.CancelNotifier( KPapNotifierUid ); + } + +// --------------------------------------------------------- +// CEapTtlsPapActive::RunL() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::RunL() + { + DEBUG1( "CEapTtlsPapActive::RunL() iStatus=%d", iStatus.Int() ); + + switch ( iActiveState ) + { + case EEapTtlsPapActiveQueryUserNameAndPassword: + { + CompleteQueryUserNameAndPassword(); + break; + } + case EEapTtlsPapActiveShowAuthQueryDialog: + { + CompleteAuthenticationQueryDialog(); + break; + } + case EEapTtlsPapActiveShowPapChallengeMsgDialog: + { + CompletePapChallengeMsgDialog(); + break; + } + case EEapTtlsPapActiveShowPapChallengeReplyQueryDialog: + { + CompletePapChallengeReplyQueryDialog(); + break; + } + default: + { + DEBUG1( "CEapTtlsPapActive::RunL() ERROR: State is not supported, iActiveState = %d.", + iActiveState); + break; + } + } + } + +// ================= private: new, for AO ======================= + +// --------------------------------------------------------- +// CEapTtlsPapActive::CompleteQueryUserNameAndPassword() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::CompleteQueryUserNameAndPassword() + { + DEBUG( "CEapTtlsPapActive::CompleteQueryUserNameAndPassword()" ); + + if ( iSrvChallengeUnicode == NULL ) + { + CompleteWithSrvChallengeNull(); + } + else + { + CompleteWithSrvChallengeNotNull(); + } + } // CEapTtlsPapActive::CompleteQueryUserNameAndPassword() + + +// --------------------------------------------------------- +// CEapTtlsPapActive::CompleteWithSrvChallengeNull() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::CompleteWithSrvChallengeNull() + { + DEBUG( "CEapTtlsPapActive::CompleteWithSrvChallengeNull()" ); + + if ( !iCaller ) + { + DEBUG( "CEapTtlsPapActive::CompleteWithSrvChallengeNull() ERROR: iCaller==NULL." ); + return; + } + + if ( !iIsTtlsPapDbInfoInitialized ) + { + // Read prompt, user name, password, and time stamps from database. + TRAPD( err, iCaller->ReadTtlsPapDbL( iTtlsPapDbInfo ) ); + if ( err != KErrNone ) + { + DEBUG1( "CEapTtlsPapActive::CompleteWithSrvChallengeNull() \ + ERROR: Leave, err==%d.", err ); + iCaller->CompleteQueryTtlsPapUserNameAndPassword( + iCaller->ConvertAmErrorToEapolError( err ), + KNullDesC8(), KNullDesC8() ); + return; + } + iIsTtlsPapDbInfoInitialized = ETrue; + } + + if ( iTtlsPapDbInfo.iUsrPwdInfo.iPasswordPromptEnabled ) + { + // set password to null value + TRAPD(err, iCaller->SetTtlsPapColumnToNullL( cf_str_EAP_TLS_PEAP_ttls_pap_password_literal )); + + if (err != KErrNone) + { + DEBUG1( "CEapTtlsPapActive::CompleteWithSrvChallengeNull() \ + ERROR: Leave, err==%d.", err ); + iCaller->CompleteQueryTtlsPapUserNameAndPassword( + iCaller->ConvertAmErrorToEapolError( err ), + KNullDesC8(), KNullDesC8() ); + return; + } + + // display query dialog + Start( EEapTtlsPapActiveShowAuthQueryDialog ); + } + else // prompt not active + { + if ( iTtlsPapDbInfo.iUsrPwdInfo.iUserName.Length() != 0 && + iTtlsPapDbInfo.iUsrPwdInfo.iPassword.Length() != 0 ) + { + // complete query with user name and password from database; + // first, convert from unicode to utf8. + TBuf8 userNameUtf8; + CnvUtfConverter::ConvertFromUnicodeToUtf8( userNameUtf8, + iTtlsPapDbInfo.iUsrPwdInfo.iUserName ); + EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( + EAPL( "userNameUtf8" ), + userNameUtf8.Ptr(), + userNameUtf8.Size() ) ); + + TBuf8 passwordUtf8; + CnvUtfConverter::ConvertFromUnicodeToUtf8( passwordUtf8, + iTtlsPapDbInfo.iUsrPwdInfo.iPassword ); + EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( + EAPL( "passwordUtf8" ), + passwordUtf8.Ptr(), + passwordUtf8.Size() ) ); + + iCaller->CompleteQueryTtlsPapUserNameAndPassword( + eap_status_ok, userNameUtf8, passwordUtf8 ); + } + else // user name or password is empty + { + // display query dialog + Start( EEapTtlsPapActiveShowAuthQueryDialog ); + } + } // if ( iPrompt ) + } // CEapTtlsPapActive::CompleteWithSrvChallengeNull() + +// --------------------------------------------------------- +// CEapTtlsPapActive::CompleteWithSrvChallengeNotNull() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::CompleteWithSrvChallengeNotNull() + { + DEBUG( "CEapTtlsPapActive::CompleteWithSrvChallengeNotNull()" ); + if ( !iCaller ) + { + DEBUG( "CEapTtlsPapActive::CompleteWithSrvChallengeNotNull() ERROR: iCaller==NULL." ); + return; + } + + if ( !iIsTtlsPapDbInfoInitialized ) + { + // Read prompt, user name, password, and time stamps from database. + TRAPD( err, iCaller->ReadTtlsPapDbL( iTtlsPapDbInfo ) ); + if ( err != KErrNone ) + { + DEBUG1( "CEapTtlsPapActive::CompleteWithSrvChallengeNotNull() \ + ERROR: Leave, err==%d.", err ); + iCaller->CompleteQueryTtlsPapUserNameAndPassword( + iCaller->ConvertAmErrorToEapolError( err ), + KNullDesC8(), KNullDesC8() ); + return; + } + iIsTtlsPapDbInfoInitialized = ETrue; + } + + // display PAP challenge message dialog + Start( EEapTtlsPapActiveShowPapChallengeMsgDialog ); + } // CEapTtlsPapActive::CompleteWithSrvChallengeNotNull() + +// --------------------------------------------------------- +// CEapTtlsPapActive::StartAuthenticationQueryDialog() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::StartAuthenticationQueryDialog() + { + DEBUG( "CEapTtlsPapActive::StartAuthenticationQueryDialog()" ); + + if ( iNotifierDataPckgToUser == NULL || + iNotifierDataPckgFromUser == NULL || + iNotifierDataToUser == NULL || + iNotifierDataFromUser == NULL ) + { + DEBUG( "CEapTtlsPapActive::StartAuthenticationQueryDialog() \ + ERROR: data pointer is NULL." ); + return; + } + + // set user name, copy data + ( *iNotifierDataPckgToUser )().iUsrPwdInfo.iUserName = iTtlsPapDbInfo.iUsrPwdInfo.iUserName; + EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( + EAPL( "iUserName" ), + iTtlsPapDbInfo.iUsrPwdInfo.iUserName.Ptr(), + iTtlsPapDbInfo.iUsrPwdInfo.iUserName.Size() ) ); + + iNotifierDataToUser->iState = TPapUiNotifierInfo:: + EPapUiNotifierAuthQueryDialog; + iNotifier.StartNotifierAndGetResponse( + iStatus, + KPapNotifierUid, + *iNotifierDataPckgToUser, + *iNotifierDataPckgFromUser ); + } // CEapTtlsPapActive::StartAuthenticationQueryDialog() + +// --------------------------------------------------------- +// CEapTtlsPapActive::CompleteAuthenticationQueryDialog() +// --------------------------------------------------------- +// +// called in RunL() +void CEapTtlsPapActive::CompleteAuthenticationQueryDialog() + { + DEBUG( "CEapTtlsPapActive::CompleteAuthenticationQueryDialog()" ); + + if ( iStatus == KErrNone ) + { + iUserAction = EPapNotifierUserActionOk; + } + else if ( iStatus == KErrCancel ) + { + iUserAction = EPapNotifierUserActionCancel; + } + else + { + DEBUG1( "CEapTtlsPapActive::CompleteAuthenticationQueryDialog() \ + ERROR: iStatus=%d", iStatus.Int() ); + return; + } + DEBUG1( "CEapTtlsPapActive::CompleteAuthenticationQueryDialog() \ + iUserAction=%d", iStatus.Int() ); + + if ( !iCaller ) + { + DEBUG( "CEapTtlsPapActive::CompleteAuthenticationQueryDialog() \ + ERROR: iCaller==NULL." ); + return; + } + if ( !iNotifierDataFromUser ) + { + DEBUG( "CEapTtlsPapActive::CompleteAuthenticationQueryDialog() \ + ERROR: iNotifierDataFromUser==NULL." ); + return; + } + if ( iUserAction == EPapNotifierUserActionOk ) + { + // just update last cache time in db + iTtlsPapDbInfo.iLastFullAuthTime = GetCurrentTime(); + + if ( !iTtlsPapDbInfo.iUsrPwdInfo.iPasswordPromptEnabled ) + { + // prompt is not active; + // update user name, and password + iTtlsPapDbInfo.iUsrPwdInfo.iUserName = iNotifierDataFromUser-> + iUsrPwdInfo.iUserName; + iTtlsPapDbInfo.iUsrPwdInfo.iPassword = iNotifierDataFromUser-> + iUsrPwdInfo.iPassword; + } + + // update database + TRAPD( err, iCaller->WriteTtlsPapDbL( iTtlsPapDbInfo ) ); + + if (err != KErrNone) + { + DEBUG1( "CEapTtlsPapActive::CompleteAuthenticationQueryDialog() \ + ERROR: Leave, err==%d.", err ); + iCaller->CompleteQueryTtlsPapUserNameAndPassword( + iCaller->ConvertAmErrorToEapolError( err ), + KNullDesC8(), KNullDesC8() ); + return; + } + + // convert from unicode to utf8 + TBuf8 userNameUtf8; + CnvUtfConverter::ConvertFromUnicodeToUtf8( userNameUtf8, + iNotifierDataFromUser->iUsrPwdInfo.iUserName ); + EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( + EAPL( "userNameUtf8" ), + userNameUtf8.Ptr(), + userNameUtf8.Size() ) ); + + TBuf8 passwordUtf8; + CnvUtfConverter::ConvertFromUnicodeToUtf8( passwordUtf8, + iNotifierDataFromUser->iUsrPwdInfo.iPassword ); + EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( + EAPL( "passwordUtf8" ), + passwordUtf8.Ptr(), + passwordUtf8.Size() ) ); + + // complete query with user name and password from UI + iCaller->CompleteQueryTtlsPapUserNameAndPassword( + eap_status_ok, userNameUtf8, passwordUtf8 ); + } + else //if (userAction == EPapNotifierUserActionCancel) + { + // user name and password are not used + iCaller->CompleteQueryTtlsPapUserNameAndPassword( + eap_status_user_cancel_authentication, + KNullDesC8(), + KNullDesC8() ); + } + } // CEapTtlsPapActive::CompleteAuthenticationQueryDialog() + + +// --------------------------------------------------------- +// CEapTtlsPapActive::StartPapChallengeMsgDialog() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::StartPapChallengeMsgDialog() + { + DEBUG( "CEapTtlsPapActive::StartPapChallengeMsgDialog()" ); + + if ( iNotifierDataPckgToUser == NULL || + iNotifierDataPckgFromUser == NULL || + iNotifierDataToUser == NULL || + iNotifierDataFromUser == NULL ) + { + DEBUG( "CEapTtlsPapActive::StartPapChallengeMsgDialog() \ + ERROR: data pointer is NULL." ); + return; + } + + TPtrC16 ptr = iSrvChallengeUnicode->Des(); + iNotifierDataToUser->iSrvChallengeSize = ptr.Size(); // number of bytes + + iNotifierDataToUser->iState = TPapUiNotifierInfo:: + EPapUiNotifierPapChallengeMsgDialog; + + // set srv challenge + iNotifierDataToUser->iPapChallenge.Copy( *iSrvChallengeUnicode); + iNotifier.StartNotifierAndGetResponse( + iStatus, + KPapNotifierUid, + *iNotifierDataPckgToUser, + *iNotifierDataPckgFromUser ); + + } // CEapTtlsPapActive::StartPapChallengeMsgDialog() + + +// --------------------------------------------------------- +// CEapTtlsPapActive::CompletePapChallengeMsgDialog() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::CompletePapChallengeMsgDialog() + { + DEBUG( "CEapTtlsPapActive::CompletePapChallengeMsgDialog()" ); + + // display query dialog + Start( EEapTtlsPapActiveShowPapChallengeReplyQueryDialog ); + + } // CEapTtlsPapActive::CompletePapChallengeMsgDialog() + + +// --------------------------------------------------------- +// CEapTtlsPapActive::StartPapChallengeReplyQueryDialog() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::StartPapChallengeReplyQueryDialog() + { + DEBUG( "CEapTtlsPapActive::StartPapChallengeReplyQueryDialog()" ); + + if ( iNotifierDataPckgToUser == NULL || + iNotifierDataPckgFromUser == NULL || + iNotifierDataToUser == NULL || + iNotifierDataFromUser == NULL ) + { + DEBUG( "CEapTtlsPapActive::StartPapChallengeMsgDialog() \ + ERROR: data pointer is NULL." ); + return; + } + + iNotifierDataToUser->iState = TPapUiNotifierInfo:: + EPapUiNotifierPapChallengeReplyQueryDialog; + + iNotifier.StartNotifierAndGetResponse( + iStatus, + KPapNotifierUid, + *iNotifierDataPckgToUser, + *iNotifierDataPckgFromUser ); + + } // CEapTtlsPapActive::StartPapChallengeReplyQueryDialog() + + +// --------------------------------------------------------- +// CEapTtlsPapActive::CompletePapChallengeMsgDialog() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::CompletePapChallengeReplyQueryDialog() + { + DEBUG( "CEapTtlsPapActive::CompletePapChallengeReplyQueryDialog()" ); + + if ( iStatus == KErrNone ) + { + iUserAction = EPapNotifierUserActionOk; + } + else if ( iStatus == KErrCancel ) + { + iUserAction = EPapNotifierUserActionCancel; + } + else + { + DEBUG1( "CEapTtlsPapActive::CompletePapChallengeReplyQueryDialog() \ + ERROR: iStatus=%d", iStatus.Int() ); + return; + } + DEBUG1( "CEapTtlsPapActive::CompletePapChallengeReplyQueryDialog() \ + iUserAction=%d", iStatus.Int() ); + + if ( !iCaller ) + { + DEBUG( "CEapTtlsPapActive::CompletePapChallengeReplyQueryDialog() \ + ERROR: iCaller==NULL." ); + return; + } + if ( !iNotifierDataFromUser ) + { + DEBUG( "CEapTtlsPapActive::CompletePapChallengeReplyQueryDialog() \ + ERROR: iNotifierDataFromUser==NULL." ); + return; + } + if ( iUserAction == EPapNotifierUserActionOk ) + { + // update password with user challenge reply + iTtlsPapDbInfo.iUsrPwdInfo.iPassword = iNotifierDataFromUser-> + iUsrPwdInfo.iPassword; + + // convert from unicode to utf8 + TBuf8 userNameUtf8; + CnvUtfConverter::ConvertFromUnicodeToUtf8( userNameUtf8, + iTtlsPapDbInfo.iUsrPwdInfo.iUserName ); + EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( + EAPL( "userNameUtf8" ), + userNameUtf8.Ptr(), + userNameUtf8.Size() ) ); + + TBuf8 passwordUtf8; + CnvUtfConverter::ConvertFromUnicodeToUtf8( passwordUtf8, + iNotifierDataFromUser->iUsrPwdInfo.iPassword ); + EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( + EAPL( "passwordUtf8" ), + passwordUtf8.Ptr(), + passwordUtf8.Size() ) ); + + // complete query with user name and password from UI + iCaller->CompleteQueryTtlsPapUserNameAndPassword( + eap_status_ok, userNameUtf8, passwordUtf8 ); + } + else //if (userAction == EPapNotifierUserActionCancel) + { + // user name and password are not used + iCaller->CompleteQueryTtlsPapUserNameAndPassword( + eap_status_user_cancel_authentication, + KNullDesC8(), + KNullDesC8() ); + } + } // CEapTtlsPapActive::CompletePapChallengeReplyQueryDialog() + + +// ================= private: new, other ======================= + + +// --------------------------------------------------------- +// CEapTtlsPapActive::GetCurrentTime() +// --------------------------------------------------------- +// +TInt64 CEapTtlsPapActive::GetCurrentTime() + { + DEBUG( "CEapTtlsPapActive::GetCurrentTime()" ); + + TTime currentTime; + currentTime.UniversalTime(); + +#if defined(_DEBUG) || defined(DEBUG) + + TDateTime currentDateTime = currentTime.DateTime(); + + EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_type_tls_peap_symbian_c::GetCurrentTime(), %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), + currentDateTime.Day()+1, currentDateTime.Month()+1,currentDateTime.Year(), currentDateTime.Hour(), + currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond())); + +#endif + + return currentTime.Int64(); + } + +// --------------------------------------------------------- +// CEapTtlsPapActive::Clean() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::Clean() + { + DEBUG( "CEapTtlsPapActive::Clean() IN" ); + + iCancelCalled = ETrue; + + DEBUG( "CEapTtlsPapActive::Clean() iActiveState set to EEapTtlsPapActiveStatesNumber" ); + iActiveState = EEapTtlsPapActiveStatesNumber; + + DEBUG( "CEapFastActive::Clean() close notifier." ); + iNotifier.Close(); + + DEBUG( "CEapTtlsPapActive::Clean() delete iNotifierDataToUser." ); + delete iNotifierDataToUser; + iNotifierDataToUser = NULL; + + DEBUG( "CEapTtlsPapActive::Clean() delete iNotifierDataPckgToUser." ); + delete iNotifierDataPckgToUser; + iNotifierDataPckgToUser = NULL; + + DEBUG( "CEapTtlsPapActive::Clean() delete iNotifierDataFromUser." ); + delete iNotifierDataFromUser; + iNotifierDataFromUser = NULL; + + DEBUG( "CEapTtlsPapActive::Clean() delete iNotifierDataFromUser." ); + delete iNotifierDataPckgFromUser; + iNotifierDataPckgFromUser = NULL; + + DEBUG( "CEapTtlsPapActive::Clean() OUT." ); + } + +// ================= private: private constructors ======================= + +// --------------------------------------------------------- +// CEapTtlsPapActive::CEapTtlsPapActive() +// --------------------------------------------------------- +// +CEapTtlsPapActive::CEapTtlsPapActive( + eap_am_type_tls_peap_symbian_c* aCaller, + eap_am_tools_symbian_c* aAmTools ) + : + CActive( CActive::EPriorityStandard ), + iAmTools( aAmTools ), + iCaller( aCaller ), + //iPartner( aPartner ), + iActiveState( EEapTtlsPapActiveStatesNumber ), + iNotifier(), + iNotifierDataToUser( NULL ), + iNotifierDataPckgToUser( NULL ), + iNotifierDataFromUser( NULL ), + iNotifierDataPckgFromUser( NULL ), + iUserAction( EPapNotifierUserActionCancel ), + iSrvChallengeUnicode( NULL ), + iRequestStatus( NULL ), + iIsTtlsPapDbInfoInitialized( EFalse ), + iCancelCalled( EFalse ) + { + DEBUG( "CEapTtlsPapActive::CEapTtlsPapActive()" ); + } + +// --------------------------------------------------------- +// CEapTtlsPapActive::ConstructL() +// --------------------------------------------------------- +// +void CEapTtlsPapActive::ConstructL() + { + DEBUG( "CEapTtlsPapActive::ConstructL()" ); + CActiveScheduler::Add( this ); + + DEBUG( "CEapTtlsPapActive::ConstructL() connecting to notifier server"); + TInt err = iNotifier.Connect(); + if ( err != KErrNone ) + { + DEBUG1( "CEapTtlsPapActive::Start() ERROR: Failed to connect to notifier server, err=%d", + err ); + return; + } + if ( !iNotifierDataToUser ) + { + iNotifierDataToUser = new(ELeave) TPapUiNotifierInfo; + } + if ( !iNotifierDataPckgToUser ) + { + iNotifierDataPckgToUser = new(ELeave) TPckg (*iNotifierDataToUser); + } + if ( !iNotifierDataFromUser ) + { + iNotifierDataFromUser = new(ELeave) TPapUiNotifierInfo; + } + if ( !iNotifierDataPckgFromUser ) + { + iNotifierDataPckgFromUser = new(ELeave) TPckg (*iNotifierDataFromUser); + } + } + +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/wlaneapolif/data/2000b05a.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/wlaneapolif/data/2000b05a.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2000 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: ECom resources for the WlanEapolIf +* +*/ + + +#include + +// --------------------------------------------------------- +// +// +// ECOM resource definitions for WlanEapolIf plugin +// +// --------------------------------------------------------- +// +RESOURCE REGISTRY_INFO theInfo + { + // UID for the DLL + dll_uid = 0x2000b05a; + + // Declare array of interface info + interfaces = + { + INTERFACE_INFO + { + // UID of interface that is implemented + interface_uid = 0x2000b05b; + implementations = + { + // Info for WlanPowerSaveImpl + IMPLEMENTATION_INFO + { + implementation_uid = 0x2000b05c; + version_no = 1; + display_name = "WlanEapolIf"; + default_data = ""; + opaque_data = ""; + } + }; + } + }; + } diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/wlaneapolif/inc/wlan_eapol_if_implementation.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/wlaneapolif/inc/wlan_eapol_if_implementation.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,132 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +#ifndef _WLAN_EAPOL_INTERFACE_IMPLEMENTATION_H_ +#define _WLAN_EAPOL_INTERFACE_IMPLEMENTATION_H_ + +// INCLUDES +#include +#include + +#include "abs_eapol_message_wlan_authentication.h" + +/** + * Implementation for MWlanEapolInterface interface. + * + * @lib wlaneapolif.dll + * @since S60 v3.2 + */ +class CWlanEapolInterfaceImplementation +: public CWlanEapolClient +, public abs_eapol_message_wlan_authentication_c +{ + +public: + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Functions from CWlanEapolClient. + + /** + * Static constructor. + * @param aPartner Pointer to callback instance. + * @return Pointer to the constructed instance. + */ + static CWlanEapolInterfaceImplementation* NewL( MWlanEapolCallbackInterface * aPartner ); + + /** + * Destructor. + */ + virtual ~CWlanEapolInterfaceImplementation(); + + /** + * Configure plugin implementation. + * + * @since S60 v3.2 + * @param aHeaderOffset Offset of EAP-header in packet_send. + * @param aMTU Maximum transfer unit (MTU). + * @param aTrailerLength Length of trailer needed by lower levels.. + * @return Return value is specified in interface specification. + */ + virtual TInt Configure( + const TInt aHeaderOffset, + const TInt aMTU, + const TInt aTrailerLength); + + /** + * Shutdown plugin implementation. + * + * @since S60 v3.2 + * @return Return value is specified in interface specification. + */ + virtual TInt Shutdown(); + + /** + * Send data to EAPOL. + * + * @since S60 v3.2 + * @param aData Pointer to the data to be sent. + * @param aLength Length of the data to be sent. + * @return Return value is specified in interface specification. + */ + virtual TInt ProcessData( + const void * const aData, + const TInt aLength ); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Functions from abs_eapol_message_wlan_authentication_c. + + /// Function sends the data message to lower layer. + /// Data is formatted to Attribute-Value Pairs. + /// Look at eap_tlv_header_c and eap_tlv_message_data_c. + virtual wlan_eap_if_send_status_e send_data(const void * const data, const u32_t length); + + +private: + + /** + * C++ default constructor. + */ + CWlanEapolInterfaceImplementation(); + + /** + * Symbian 2nd phase constructor. + */ + void ConstructL(MWlanEapolCallbackInterface * aPartner); + + /** + * The get_is_valid() function returns the status of the CWlanEapolInterfaceImplementation object. + * @return True indicates the object is initialized. + */ + bool get_is_valid(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + abs_eap_am_tools_c * m_am_tools; + + MWlanEapolCallbackInterface * m_partner; + + eapol_message_wlan_authentication_c * m_wauth; + + bool m_is_valid; + +}; + + +#endif // _WLAN_EAPOL_INTERFACE_IMPLEMENTATION_H_ + +// End of file. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/am/wlaneapolif/src/wlan_eapol_if_implementation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/am/wlaneapolif/src/wlan_eapol_if_implementation.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,226 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP and WLAN authentication protocols. +* +*/ + + +// INCLUDES +#include +#include + +#include "abs_eap_am_tools.h" + +#include "eapol_message_wlan_authentication.h" +#include "wlan_eapol_if_implementation.h" +#include "wlan_eap_if_send_status.h" + +//----------------------------------------------------------------------------------------- + +/** + * Pairs ECom implementation UIDs with a pointer to the instantiation + * method for that implementation. Required for all ECom implementation + * collections. + */ +const TImplementationProxy ImplementationTable[] = +{ + {{ KCWlanEapolClientUid }, reinterpret_cast(CWlanEapolInterfaceImplementation::NewL)} +}; + +//----------------------------------------------------------------------------------------- + +/** + * Static constructor. + * @param aPartner Pointer to callback instance. + * @return Pointer to the constructed instance. + */ +CWlanEapolInterfaceImplementation* CWlanEapolInterfaceImplementation::NewL(MWlanEapolCallbackInterface * aPartner) +{ + CWlanEapolInterfaceImplementation* self = new (ELeave) CWlanEapolInterfaceImplementation; + + CleanupStack::PushL(self); + + self->ConstructL(aPartner); + + if (self->get_is_valid() != true) + { + User::Leave(KErrGeneral); + } + + CleanupStack::Pop(self); + + return self; +} + +//----------------------------------------------------------------------------------------- + +/** + * C++ default constructor. + */ +CWlanEapolInterfaceImplementation::CWlanEapolInterfaceImplementation() +: m_am_tools(0) +, m_partner(0) +, m_wauth(0) +, m_is_valid(true) +{ +} + +//----------------------------------------------------------------------------------------- + +/** + * Destructor. + */ +CWlanEapolInterfaceImplementation::~CWlanEapolInterfaceImplementation() +{ + m_partner = 0; + + delete m_wauth; + m_wauth = 0; + m_am_tools->am_cancel_all_timers(); + abs_eap_am_tools_c::delete_abs_eap_am_tools_c(m_am_tools); + m_am_tools = 0; + +} + +//----------------------------------------------------------------------------------------- + +/** + * Configure plugin implementation. + * + * @since S60 v3.2 + * @param aHeaderOffset Offset of EAP-header in packet_send. + * @param aMTU Maximum transfer unit (MTU). + * @param aTrailerLength Length of trailer needed by lower levels.. + * @return Return value is specified in interface specification. + */ +TInt CWlanEapolInterfaceImplementation::Configure( + const TInt aHeaderOffset, + const TInt aMTU, + const TInt aTrailerLength) +{ + m_am_tools = abs_eap_am_tools_c::new_abs_eap_am_tools_c(); + + if (m_am_tools == 0) + { + return wlan_eap_if_send_status_conversion_c::convert(eap_status_allocation_error); + } + + // eapol_message_wlan_authentication_c object uses the tools object. + m_wauth = new eapol_message_wlan_authentication_c( + m_am_tools, + this); + + if (m_wauth != 0 + && m_wauth->get_is_valid() == true) + { + eap_status_e status = m_wauth->configure( + aHeaderOffset, + aMTU, + aTrailerLength); + if (status != eap_status_ok) + { + return wlan_eap_if_send_status_conversion_c::convert( + EAP_STATUS_RETURN(m_am_tools, status)); + } + } + else + { + return wlan_eap_if_send_status_conversion_c::convert( + EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error)); + } + + return wlan_eap_if_send_status_ok; +} + +//----------------------------------------------------------------------------------------- + +/** + * Shutdown plugin implementation. + * + * @since S60 v3.2 + * @return Return value is specified in interface specification. + */ +TInt CWlanEapolInterfaceImplementation::Shutdown() +{ + eap_status_e status = m_wauth->shutdown(); + + return wlan_eap_if_send_status_conversion_c::convert( + EAP_STATUS_RETURN(m_am_tools, status)); +} + +//----------------------------------------------------------------------------------------- + +/** + * Send data to EAPOL. + * + * @since S60 v3.2 + * @param aData Pointer to the data to be sent. + * @param aLength Length of the data to be sent. + * @return Return value is specified in interface specification. + */ +TInt CWlanEapolInterfaceImplementation::ProcessData( + const void * const aData, + const TInt aLength ) +{ + return m_wauth->process_data(aData, aLength); +} + +//----------------------------------------------------------------------------------------- + +/** + * Symbian 2nd phase constructor. + */ +void CWlanEapolInterfaceImplementation::ConstructL(MWlanEapolCallbackInterface * aPartner) +{ + m_partner = aPartner; +} + +//----------------------------------------------------------------------------------------- + +bool CWlanEapolInterfaceImplementation::get_is_valid() +{ + return m_is_valid; +} + +//----------------------------------------------------------------------------------------- + +/// Function sends the data message to lower layer. +/// Data is formatted to Attribute-Value Pairs. +/// Look at eap_tlv_header_c and eap_tlv_message_data_c. +wlan_eap_if_send_status_e CWlanEapolInterfaceImplementation::send_data(const void * const data, const u32_t length) +{ + return static_cast(m_partner->SendData( + data, + length)); +} + +//----------------------------------------------------------------------------------------- + +// ======== GLOBAL FUNCTIONS ======== + +// --------------------------------------------------------- +// Returns an instance of the proxy table. +// Returns: KErrNone +// --------------------------------------------------------- +// +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount ) + { + aTableCount = sizeof( ImplementationTable) / sizeof( TImplementationProxy ); + return ImplementationTable; + } + +//----------------------------------------------------------------------------------------- + +// End of file. + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/bwins/EAPOLPROTECTEDu.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/bwins/EAPOLPROTECTEDu.DEF Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1500 @@ +EXPORTS + dss_pseudo_random @ 1 NONAME + ?md5_copy_context@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@@Z @ 2 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::md5_copy_context(class eap_variable_data_c *, class eap_variable_data_c const *) + ?get_type@eap_tlv_header_c@@QBEKXZ @ 3 NONAME ; unsigned long eap_tlv_header_c::get_type(void) const + ?set_use_timer_queue@eap_am_tools_c@@QAEXXZ @ 4 NONAME ; void eap_am_tools_c::set_use_timer_queue(void) + ?copy@eap_buf_chain_wr_c@@QAEPAV1@XZ @ 5 NONAME ; class eap_buf_chain_wr_c * eap_buf_chain_wr_c::copy(void) + ?zero_key_NONCE@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@@Z @ 6 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::zero_key_NONCE(class abs_eap_am_tools_c *) + ?reset_data_buffer@eap_buf_chain_base_c@@AAEXXZ @ 7 NONAME ; void eap_buf_chain_base_c::reset_data_buffer(void) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAVnetwork_key_and_index_c@@@Z @ 8 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, class network_key_and_index_c *) + ?get_network_id@eap_am_network_id_c@@QBEPBV1@XZ @ 9 NONAME ; class eap_am_network_id_c const * eap_am_network_id_c::get_network_id(void) const + ?memory_store_get_data@eap_am_tools_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@PAVeap_tlv_message_data_c@@@Z @ 10 NONAME ; enum eap_status_e eap_am_tools_c::memory_store_get_data(class eap_variable_data_c const *, class eap_tlv_message_data_c *) + ?set_current_eap_index@eapol_wlan_authentication_c@@UAEXK@Z @ 11 NONAME ; void eapol_wlan_authentication_c::set_current_eap_index(unsigned long) + ??1eap_am_network_id_c@@UAE@XZ @ 12 NONAME ; eap_am_network_id_c::~eap_am_network_id_c(void) + ??1eapol_core_c@@UAE@XZ @ 13 NONAME ; eapol_core_c::~eapol_core_c(void) + ?set_is_invalid@eap_variable_data_c@@QAEXXZ @ 14 NONAME ; void eap_variable_data_c::set_is_invalid(void) + ?get_data_length@eap_core_retransmission_c@@QBEKXZ @ 15 NONAME ; unsigned long eap_core_retransmission_c::get_data_length(void) const + ?add_rand_seed_hw_ticks@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@XZ @ 16 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::add_rand_seed_hw_ticks(void) + ??0eap_am_crypto_sha_256_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 17 NONAME ; eap_am_crypto_sha_256_c::eap_am_crypto_sha_256_c(class abs_eap_am_tools_c *) + ??0crypto_dsa_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 18 NONAME ; crypto_dsa_c::crypto_dsa_c(class abs_eap_am_tools_c *) + ?reset@crypto_cbc_c@@AAEXXZ @ 19 NONAME ; void crypto_cbc_c::reset(void) + ?check_is_valid_eap_type@eap_session_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 20 NONAME ; enum eap_status_e eap_session_core_c::check_is_valid_eap_type(class eap_expanded_type_c) + ?get_eapol_key_state_string@eapol_key_state_string_c@@QBEPBDW4eapol_key_state_e@@@Z @ 21 NONAME ; char const * eapol_key_state_string_c::get_eapol_key_state_string(enum eapol_key_state_e) const + ?set_is_valid@eap_am_crypto_sha_256_c@@AAEXXZ @ 22 NONAME ; void eap_am_crypto_sha_256_c::set_is_valid(void) + ?add_rand_seed@crypto_random_c@@QAE?AW4eap_status_e@@PBXK@Z @ 23 NONAME ; enum eap_status_e crypto_random_c::add_rand_seed(void const *, unsigned long) + ?set_eap_type_values@eap_expanded_type_c@@QAEXW4eap_type_vendor_id_e@@K@Z @ 24 NONAME ; void eap_expanded_type_c::set_eap_type_values(enum eap_type_vendor_id_e, unsigned long) + ?get_data_length@eap_header_base_c@@QBEGXZ @ 25 NONAME ; unsigned short eap_header_base_c::get_data_length(void) const + ?configure@eapol_core_c@@UAE?AW4eap_status_e@@XZ @ 26 NONAME ; enum eap_status_e eapol_core_c::configure(void) + ?get_send_network_id@eap_state_notification_c@@UBEPBVeap_am_network_id_c@@XZ @ 27 NONAME ; class eap_am_network_id_c const * eap_state_notification_c::get_send_network_id(void) const + ?get_use_timer_queue@eap_am_tools_c@@UAE_NXZ @ 28 NONAME ; bool eap_am_tools_c::get_use_timer_queue(void) + ?get_is_valid@crypto_3des_ede_c@@UAE_NXZ @ 29 NONAME ; bool crypto_3des_ede_c::get_is_valid(void) + ?complete_WPXM_reassociation@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 30 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::complete_WPXM_reassociation(class eap_array_c const *) + ??0eap_expanded_type_c@@QAE@W4eap_type_vendor_id_e@@K@Z @ 31 NONAME ; eap_expanded_type_c::eap_expanded_type_c(enum eap_type_vendor_id_e, unsigned long) + ?cancel_all_timers@ethernet_core_c@@UAE?AW4eap_status_e@@XZ @ 32 NONAME ; enum eap_status_e ethernet_core_c::cancel_all_timers(void) + ?unload_module@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 33 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::unload_module(class eap_expanded_type_c) + ?encrypt_with_public_key@crypto_rsa_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@@Z @ 34 NONAME ; enum eap_status_e crypto_rsa_c::encrypt_with_public_key(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ?object_decrease_reference_count@eapol_key_state_c@@QAEKXZ @ 35 NONAME ; unsigned long eapol_key_state_c::object_decrease_reference_count(void) + ?init_eapol_key_pmksa_caching_timeout@eapol_core_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 36 NONAME ; enum eap_status_e eapol_core_c::init_eapol_key_pmksa_caching_timeout(class eap_am_network_id_c const *) + ?disassociation@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 37 NONAME ; enum eap_status_e eapol_wlan_authentication_c::disassociation(class eap_am_network_id_c const *) + ?set_data_length@eap_buf_chain_base_c@@QAE?AW4eap_status_e@@K@Z @ 38 NONAME ; enum eap_status_e eap_buf_chain_base_c::set_data_length(unsigned long) + ?set_is_invalid@crypto_tls_base_prf_c@@AAEXXZ @ 39 NONAME ; void crypto_tls_base_prf_c::set_is_invalid(void) + ?get_leap_password@eap_master_session_key_c@@QBEPBVeap_variable_data_c@@XZ @ 40 NONAME ; class eap_variable_data_c const * eap_master_session_key_c::get_leap_password(void) const + ?set_selector@eap_network_id_selector_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 41 NONAME ; enum eap_status_e eap_network_id_selector_c::set_selector(class eap_am_network_id_c const *) + ??0eap_core_nak_info_c@@QAE@PAVabs_eap_am_tools_c@@PBVeap_am_network_id_c@@Veap_expanded_type_c@@E@Z @ 42 NONAME ; eap_core_nak_info_c::eap_core_nak_info_c(class abs_eap_am_tools_c *, class eap_am_network_id_c const *, class eap_expanded_type_c, unsigned char) + ?get_key_information_reserved_b@eapol_RSNA_key_header_c@@QBEEXZ @ 43 NONAME ; unsigned char eapol_RSNA_key_header_c::get_key_information_reserved_b(void) const + ?set_timer@eap_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 44 NONAME ; enum eap_status_e eap_core_c::set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long) + ?get_block_size@crypto_md5_c@@UAEKXZ @ 45 NONAME ; unsigned long crypto_md5_c::get_block_size(void) + ??0crypto_random_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 46 NONAME ; crypto_random_c::crypto_random_c(class abs_eap_am_tools_c *) + ??0crypto_hmac_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_crypto_hash_algorithm_c@@_N@Z @ 47 NONAME ; crypto_hmac_c::crypto_hmac_c(class abs_eap_am_tools_c *, class abs_crypto_hash_algorithm_c *, bool) + ?get_client_send_key_reply_counter@eapol_key_state_c@@AAE_KXZ @ 48 NONAME ; unsigned long long eapol_key_state_c::get_client_send_key_reply_counter(void) + ?get_eap_header@eapol_header_rd_c@@QBEPAEXZ @ 49 NONAME ; unsigned char * eapol_header_rd_c::get_eap_header(void) const + ?rc4_decrypt@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@PAXK@Z @ 50 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rc4_decrypt(class eap_variable_data_c const *, void *, unsigned long) + ?set_key_information_key_MIC@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@_N@Z @ 51 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_information_key_MIC(bool) + ?set_length@eap_header_base_c@@QAEXG_N@Z @ 52 NONAME ; void eap_header_base_c::set_length(unsigned short, bool) + ?read_section@eap_file_config_c@@AAE?AW4eap_status_e@@PAVabs_eap_am_file_input_c@@PAV?$eap_core_map_c@Veap_config_value_c@@Vabs_eap_core_map_c@@Veap_variable_data_c@@@@@Z @ 53 NONAME ; enum eap_status_e eap_file_config_c::read_section(class abs_eap_am_file_input_c *, class eap_core_map_c *) + ?check_guard_bytes@eap_buf_chain_base_c@@ABE_NPBE@Z @ 54 NONAME ; bool eap_buf_chain_base_c::check_guard_bytes(unsigned char const *) const + ??1eap_am_crypto_rc4_c@@UAE@XZ @ 55 NONAME ; eap_am_crypto_rc4_c::~eap_am_crypto_rc4_c(void) + ?get_protocol_string@eap_state_notification_c@@UBEPBDXZ @ 56 NONAME ; char const * eap_state_notification_c::get_protocol_string(void) const + ?aes_encrypt_block@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEPAEK@Z @ 57 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::aes_encrypt_block(class eap_variable_data_c *, unsigned char const *, unsigned char *, unsigned long) + ?sha_256_init@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 58 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::sha_256_init(class eap_variable_data_c *) + ?get_is_valid@eap_type_selection_c@@QBE_NXZ @ 59 NONAME ; bool eap_type_selection_c::get_is_valid(void) const + ?cancel_retransmission@eap_core_c@@AAE?AW4eap_status_e@@XZ @ 60 NONAME ; enum eap_status_e eap_core_c::cancel_retransmission(void) + ?get_is_valid@eap_am_crypto_sha_256_c@@QAE_NXZ @ 61 NONAME ; bool eap_am_crypto_sha_256_c::get_is_valid(void) + ?update_wlan_database_reference_values@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 62 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::update_wlan_database_reference_values(class eap_array_c const *) + ?shutdown@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@XZ @ 63 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::shutdown(void) + ?copy_context@crypto_md4_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 64 NONAME ; enum eap_status_e crypto_md4_c::copy_context(class eap_variable_data_c const *) + ?cbc_copy_block@crypto_cbc_c@@AAEXPAXPBXKK@Z @ 65 NONAME ; void crypto_cbc_c::cbc_copy_block(void *, void const *, unsigned long, unsigned long) + ?load_module@eap_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@0PAVabs_eap_base_type_c@@PAPAVeap_base_type_c@@_NPBVeap_am_network_id_c@@@Z @ 66 NONAME ; enum eap_status_e eap_core_c::load_module(class eap_expanded_type_c, class eap_expanded_type_c, class abs_eap_base_type_c *, class eap_base_type_c * *, bool, class eap_am_network_id_c const *) + ?get_is_valid@crypto_tls_md5_prf_c@@QAE_NXZ @ 67 NONAME ; bool crypto_tls_md5_prf_c::get_is_valid(void) + ?cancel_all_timers@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@XZ @ 68 NONAME ; enum eap_status_e eapol_wlan_authentication_c::cancel_all_timers(void) + ?get_value@eap_tlv_header_c@@QBEPAEK@Z @ 69 NONAME ; unsigned char * eap_tlv_header_c::get_value(unsigned long) const + ?add_data@eap_buf_chain_base_c@@QAE?AW4eap_status_e@@PBXK@Z @ 70 NONAME ; enum eap_status_e eap_buf_chain_base_c::add_data(void const *, unsigned long) + ?set_key_descriptor_type@eapol_RC4_key_header_c@@QAE?AW4eap_status_e@@W4eapol_key_descriptor_type_e@@@Z @ 71 NONAME ; enum eap_status_e eapol_RC4_key_header_c::set_key_descriptor_type(enum eapol_key_descriptor_type_e) + ?convert_selected_bytes_to_ascii_armor@eap_am_tools_c@@AAEXEPAKPAE10_N@Z @ 72 NONAME ; void eap_am_tools_c::convert_selected_bytes_to_ascii_armor(unsigned char, unsigned long *, unsigned char *, unsigned char *, unsigned long *, bool) + ?shutdown@eap_session_core_c@@UAE?AW4eap_status_e@@XZ @ 73 NONAME ; enum eap_status_e eap_session_core_c::shutdown(void) + ??1crypto_hmac_c@@UAE@XZ @ 74 NONAME ; crypto_hmac_c::~crypto_hmac_c(void) + ?get_SSID@simple_config_credential_c@@QAEPAVeap_variable_data_c@@XZ @ 75 NONAME ; class eap_variable_data_c * simple_config_credential_c::get_SSID(void) + ??1crypto_aes_c@@UAE@XZ @ 76 NONAME ; crypto_aes_c::~crypto_aes_c(void) + ?set_is_valid@crypto_tls_base_prf_c@@AAEXXZ @ 77 NONAME ; void crypto_tls_base_prf_c::set_is_valid(void) + ?pulse_timer@eap_am_tools_symbian_c@@UAEKK@Z @ 78 NONAME ; unsigned long eap_am_tools_symbian_c::pulse_timer(unsigned long) + ?get_key_information_error@eapol_RSNA_key_header_c@@QBE_NXZ @ 79 NONAME ; bool eapol_RSNA_key_header_c::get_key_information_error(void) const + ?get_message_data_length@eap_tlv_message_data_c@@QBEKXZ @ 80 NONAME ; unsigned long eap_tlv_message_data_c::get_message_data_length(void) const + ?get_encrypts@crypto_aes_wrap_c@@QAE_NXZ @ 81 NONAME ; bool crypto_aes_wrap_c::get_encrypts(void) + ?hash_final@crypto_sha1_c@@UAE?AW4eap_status_e@@PAXPAK@Z @ 82 NONAME ; enum eap_status_e crypto_sha1_c::hash_final(void *, unsigned long *) + ?get_block_size@eap_am_crypto_sha1_c@@QAEKXZ @ 83 NONAME ; unsigned long eap_am_crypto_sha1_c::get_block_size(void) + ?set_type@eapol_ethernet_header_base_c@@QAEXW4eapol_ethernet_type_e@@@Z @ 84 NONAME ; void eapol_ethernet_header_base_c::set_type(enum eapol_ethernet_type_e) + ?set_mem_guard_bytes@eap_buf_chain_base_c@@AAEXXZ @ 85 NONAME ; void eap_buf_chain_base_c::set_mem_guard_bytes(void) + ?copy_context@eap_am_crypto_sha_256_c@@AAE?AW4eap_status_e@@PBVeap_variable_data_c@@_KPBK22@Z @ 86 NONAME ; enum eap_status_e eap_am_crypto_sha_256_c::copy_context(class eap_variable_data_c const *, unsigned long long, unsigned long const *, unsigned long const *, unsigned long const *) + ?get_attribute_type_string@eap_simple_config_trace_string_c@@QBEPBDW4simple_config_Attribute_Type_e@@@Z @ 87 NONAME ; char const * eap_simple_config_trace_string_c::get_attribute_type_string(enum simple_config_Attribute_Type_e) const + ?set_timer@eapol_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 88 NONAME ; enum eap_status_e eapol_core_c::set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long) + ?create_uuid_v5@eap_am_tools_c@@UAE?AW4eap_status_e@@PBXK0KPAVeap_variable_data_c@@@Z @ 89 NONAME ; enum eap_status_e eap_am_tools_c::create_uuid_v5(void const *, unsigned long, void const *, unsigned long, class eap_variable_data_c *) + ?get_key_reserved@eapol_RSNA_key_header_c@@QBEPAEXZ @ 90 NONAME ; unsigned char * eapol_RSNA_key_header_c::get_key_reserved(void) const + ?rc4_decrypt@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@PBXPAXK@Z @ 91 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rc4_decrypt(class eap_variable_data_c const *, void const *, void *, unsigned long) + ?add_message_data@eap_tlv_message_data_c@@QAE?AW4eap_status_e@@KKPBX@Z @ 92 NONAME ; enum eap_status_e eap_tlv_message_data_c::add_message_data(unsigned long, unsigned long, void const *) + ?get_is_valid@crypto_sha1_c@@UAE_NXZ @ 93 NONAME ; bool crypto_sha1_c::get_is_valid(void) + ?set_is_invalid@crypto_md5_c@@AAEXXZ @ 94 NONAME ; void crypto_md5_c::set_is_invalid(void) + ?get_is_reserved@eap_am_mutex_symbian_c@@UBE_NXZ @ 95 NONAME ; bool eap_am_mutex_symbian_c::get_is_reserved(void) const + ?get_key_RSC@eapol_RSNA_key_header_c@@QBEPAEXZ @ 96 NONAME ; unsigned char * eapol_RSNA_key_header_c::get_key_RSC(void) const + ?complete_reassociation@eapol_key_state_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@3W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@4@Z @ 97 NONAME ; enum eap_status_e eapol_key_state_c::complete_reassociation(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e) + ?get_md5_digest_length@eap_am_crypto_symbian_c@@UAEKPAVeap_variable_data_c@@@Z @ 98 NONAME ; unsigned long eap_am_crypto_symbian_c::get_md5_digest_length(class eap_variable_data_c *) + ?get_wlan_database_reference_values@eapol_message_wlan_authentication_c@@UBE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 99 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::get_wlan_database_reference_values(class eap_variable_data_c *) const + ?tkip_mic_failure@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_NW4eapol_tkip_mic_failure_type_e@eapol_RSNA_key_header_c@@@Z @ 100 NONAME ; enum eap_status_e ethernet_core_c::tkip_mic_failure(class eap_am_network_id_c const *, bool, enum eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e) + ??0crypto_rsa_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 101 NONAME ; crypto_rsa_c::crypto_rsa_c(class abs_eap_am_tools_c *) + ?get_authenticator_RSNA_IE@eapol_key_state_c@@AAEPAVeap_variable_data_c@@XZ @ 102 NONAME ; class eap_variable_data_c * eapol_key_state_c::get_authenticator_RSNA_IE(void) + ?rsa_encrypt_with_public_key@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@10@Z @ 103 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rsa_encrypt_with_public_key(class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ?get_block_size@crypto_sha_256_c@@UAEKXZ @ 104 NONAME ; unsigned long crypto_sha_256_c::get_block_size(void) + ??0eapol_header_wr_c@@QAE@PAVabs_eap_am_tools_c@@PAEK@Z @ 105 NONAME ; eapol_header_wr_c::eapol_header_wr_c(class abs_eap_am_tools_c *, unsigned char *, unsigned long) + ?send_eap_identity_request@eap_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 106 NONAME ; enum eap_status_e eap_session_core_c::send_eap_identity_request(class eap_am_network_id_c const *) + ?hash_cleanup@crypto_md4_c@@UAE?AW4eap_status_e@@XZ @ 107 NONAME ; enum eap_status_e crypto_md4_c::hash_cleanup(void) + ?get_authentication_counter@eapol_wlan_authentication_c@@QAEKXZ @ 108 NONAME ; unsigned long eapol_wlan_authentication_c::get_authentication_counter(void) + ?object_decrease_reference_count@eap_tlv_message_data_c@@QAEKXZ @ 109 NONAME ; unsigned long eap_tlv_message_data_c::object_decrease_reference_count(void) + ?init@crypto_dsa_c@@QAE?AW4eap_status_e@@XZ @ 110 NONAME ; enum eap_status_e crypto_dsa_c::init(void) + ?create_nonce@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeap_variable_data_c@@K@Z @ 111 NONAME ; enum eap_status_e eapol_key_state_c::create_nonce(class eap_variable_data_c *, unsigned long) + ?hmac_set_key@crypto_hmac_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 112 NONAME ; enum eap_status_e crypto_hmac_c::hmac_set_key(class eap_variable_data_c const *) + ?get_eap_type_list@eap_core_c@@UAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_expanded_type_c@@@@@Z @ 113 NONAME ; enum eap_status_e eap_core_c::get_eap_type_list(class eap_array_c *) + ?get_type@eapol_ethernet_header_base_c@@QBEGXZ @ 114 NONAME ; unsigned short eapol_ethernet_header_base_c::get_type(void) const + ?encrypt_block@crypto_3des_ede_c@@UAE?AW4eap_status_e@@PBXPAXK@Z @ 115 NONAME ; enum eap_status_e crypto_3des_ede_c::encrypt_block(void const *, void *, unsigned long) + ?get_length@eap_header_base_c@@QBEGXZ @ 116 NONAME ; unsigned short eap_header_base_c::get_length(void) const + ?reset@eap_session_core_c@@QAE?AW4eap_status_e@@XZ @ 117 NONAME ; enum eap_status_e eap_session_core_c::reset(void) + ?set_buffer_length@eap_variable_data_c@@QAE?AW4eap_status_e@@K@Z @ 118 NONAME ; enum eap_status_e eap_variable_data_c::set_buffer_length(unsigned long) + ?set_is_invalid@crypto_sha1_c@@AAEXXZ @ 119 NONAME ; void crypto_sha1_c::set_is_invalid(void) + ?dsa_init@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 120 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::dsa_init(class eap_variable_data_c *) + ?get_is_valid@crypto_dsa_c@@QAE_NXZ @ 121 NONAME ; bool crypto_dsa_c::get_is_valid(void) + ?get_SNonce@eapol_key_state_c@@AAEPAVeap_variable_data_c@@XZ @ 122 NONAME ; class eap_variable_data_c * eapol_key_state_c::get_SNonce(void) + ?asynchronous_init_remove_eap_session@eap_session_core_c@@QAE?AW4eap_status_e@@PBVeap_network_id_selector_c@@@Z @ 123 NONAME ; enum eap_status_e eap_session_core_c::asynchronous_init_remove_eap_session(class eap_network_id_selector_c const *) + ?unload_module@eap_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 124 NONAME ; enum eap_status_e eap_core_c::unload_module(class eap_expanded_type_c) + ?aes_decrypt_block@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEPAEK@Z @ 125 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::aes_decrypt_block(class eap_variable_data_c *, unsigned char const *, unsigned char *, unsigned long) + ?set_do_packet_retransmission@eap_buf_chain_base_c@@QAEX_N@Z @ 126 NONAME ; void eap_buf_chain_base_c::set_do_packet_retransmission(bool) + ?get_is_valid@crypto_rsa_c@@QAE_NXZ @ 127 NONAME ; bool crypto_rsa_c::get_is_valid(void) + ?initialize_4_way_handshake@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_protocol_version_e@@@Z @ 128 NONAME ; enum eap_status_e eapol_key_state_c::initialize_4_way_handshake(class eap_am_network_id_c const *, enum eapol_protocol_version_e) + ??1eapol_header_base_c@@UAE@XZ @ 129 NONAME ; eapol_header_base_c::~eapol_header_base_c(void) + ??8eap_expanded_type_c@@QBE_NW4eap_type_ietf_values_e@@@Z @ 130 NONAME ; bool eap_expanded_type_c::operator==(enum eap_type_ietf_values_e) const + ?get_type_partner@eap_base_type_c@@QAEPAVabs_eap_base_type_c@@XZ @ 131 NONAME ; class abs_eap_base_type_c * eap_base_type_c::get_type_partner(void) + ?cancel_handshake_timeout@eapol_key_state_c@@AAE?AW4eap_status_e@@XZ @ 132 NONAME ; enum eap_status_e eapol_key_state_c::cancel_handshake_timeout(void) + ?read_configure@eap_session_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 133 NONAME ; enum eap_status_e eap_session_core_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?memory_store_add_data@eap_am_tools_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@PAVeap_tlv_message_data_c@@K@Z @ 134 NONAME ; enum eap_status_e eap_am_tools_c::memory_store_add_data(class eap_variable_data_c const *, class eap_tlv_message_data_c *, unsigned long) + ?get_sha_256_digest_length@eap_am_crypto_symbian_c@@UAEKPAVeap_variable_data_c@@@Z @ 135 NONAME ; unsigned long eap_am_crypto_symbian_c::get_sha_256_digest_length(class eap_variable_data_c *) + ?get_key_information_key_ack@eapol_RSNA_key_header_c@@QBE_NXZ @ 136 NONAME ; bool eapol_RSNA_key_header_c::get_key_information_key_ack(void) const + ?check_header@eapol_RSNA_key_header_c@@UBE?AW4eap_status_e@@XZ @ 137 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::check_header(void) const + ??0eap_core_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_eap_core_c@@_NPBVeap_am_network_id_c@@2@Z @ 138 NONAME ; eap_core_c::eap_core_c(class abs_eap_am_tools_c *, class abs_eap_core_c *, bool, class eap_am_network_id_c const *, bool) + ?set_decryption_key@crypto_aes_c@@UAE?AW4eap_status_e@@PBXK@Z @ 139 NONAME ; enum eap_status_e crypto_aes_c::set_decryption_key(void const *, unsigned long) + ?get_is_manipulated@eap_buf_chain_base_c@@QAE_NXZ @ 140 NONAME ; bool eap_buf_chain_base_c::get_is_manipulated(void) + ?get_source@eap_am_network_id_c@@QBEPBEXZ @ 141 NONAME ; unsigned char const * eap_am_network_id_c::get_source(void) const + ?cancel_timer@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 142 NONAME ; enum eap_status_e eapol_wlan_authentication_c::cancel_timer(class abs_eap_base_timer_c *, unsigned long) + ??0crypto_3des_ede_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 143 NONAME ; crypto_3des_ede_c::crypto_3des_ede_c(class abs_eap_am_tools_c *) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAVeap_am_network_id_c@@@Z @ 144 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, class eap_am_network_id_c *) + ??0eap_am_memory_store_tlv_data_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 145 NONAME ; eap_am_memory_store_tlv_data_c::eap_am_memory_store_tlv_data_c(class abs_eap_am_tools_c *) + ??1crypto_md5_c@@UAE@XZ @ 146 NONAME ; crypto_md5_c::~crypto_md5_c(void) + ?set_trace_file_name@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 147 NONAME ; enum eap_status_e eap_am_tools_symbian_c::set_trace_file_name(class eap_variable_data_c const *) + ?start_WPXM_reassociation@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PAVeap_variable_data_c@@@Z @ 148 NONAME ; enum eap_status_e eapol_core_c::start_WPXM_reassociation(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c *) + ?state_notification@ethernet_core_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 149 NONAME ; void ethernet_core_c::state_notification(class abs_eap_state_notification_c const *) + ?set_is_valid@crypto_ephemeral_diffie_hellman_c@@QAEXXZ @ 150 NONAME ; void crypto_ephemeral_diffie_hellman_c::set_is_valid(void) + ?init_pmksa_caching_timeout@eapol_key_state_c@@QAE?AW4eap_status_e@@XZ @ 151 NONAME ; enum eap_status_e eapol_key_state_c::init_pmksa_caching_timeout(void) + ?disassociation@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 152 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::disassociation(class eap_am_network_id_c const *) + ??1eap_am_file_input_symbian_c@@UAE@XZ @ 153 NONAME ; eap_am_file_input_symbian_c::~eap_am_file_input_symbian_c(void) + ?get_Encryption_Type@simple_config_credential_c@@QAE?AW4simple_config_Encryption_Type_e@@XZ @ 154 NONAME ; enum simple_config_Encryption_Type_e simple_config_credential_c::get_Encryption_Type(void) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@W42@@Z @ 155 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(enum eap_status_e) + ?get_digest_length@crypto_md4_c@@UAEKXZ @ 156 NONAME ; unsigned long crypto_md4_c::get_digest_length(void) + ?eap_read_u16_t_little_endian_order@@YAGPBXK@Z @ 157 NONAME ; unsigned short eap_read_u16_t_little_endian_order(void const *, unsigned long) + ?get_EAPOL_key_IV@eapol_RSNA_key_header_c@@QBEPAEXZ @ 158 NONAME ; unsigned char * eapol_RSNA_key_header_c::get_EAPOL_key_IV(void) const + ?get_vendor_id@eap_expanded_type_c@@QBE?AW4eap_type_vendor_id_e@@XZ @ 159 NONAME ; enum eap_type_vendor_id_e eap_expanded_type_c::get_vendor_id(void) const + ?decrypt_data@crypto_rc4_c@@UAE?AW4eap_status_e@@PBXPAXK@Z @ 160 NONAME ; enum eap_status_e crypto_rc4_c::decrypt_data(void const *, void *, unsigned long) + ?write_configure@ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 161 NONAME ; enum eap_status_e ethernet_core_c::write_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?u64_struct_to_u64_t@eap_am_tools_symbian_c@@UAE_KUu64_struct@@@Z @ 162 NONAME ; unsigned long long eap_am_tools_symbian_c::u64_struct_to_u64_t(struct u64_struct) + ?get_eap_identifier@eap_core_nak_info_c@@QBEEXZ @ 163 NONAME ; unsigned char eap_core_nak_info_c::get_eap_identifier(void) const + ??0crypto_aes_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 164 NONAME ; crypto_aes_c::crypto_aes_c(class abs_eap_am_tools_c *) + ?md4_final@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PAEPAK@Z @ 165 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::md4_final(class eap_variable_data_c *, unsigned char *, unsigned long *) + ?t_prf_init@crypto_eap_fast_hmac_sha1_prf_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@00@Z @ 166 NONAME ; enum eap_status_e crypto_eap_fast_hmac_sha1_prf_c::t_prf_init(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ??0eap_am_network_id_c@@QAE@PAVabs_eap_am_tools_c@@PBVeap_variable_data_c@@1G@Z @ 167 NONAME ; eap_am_network_id_c::eap_am_network_id_c(class abs_eap_am_tools_c *, class eap_variable_data_c const *, class eap_variable_data_c const *, unsigned short) + ??1abs_crypto_block_algorithm_c@@UAE@XZ @ 168 NONAME ; abs_crypto_block_algorithm_c::~abs_crypto_block_algorithm_c(void) + ?add_data_to_offset@eap_variable_data_c@@QAE?AW4eap_status_e@@KPBXK@Z @ 169 NONAME ; enum eap_status_e eap_variable_data_c::add_data_to_offset(unsigned long, void const *, unsigned long) + ?create_uuid_v5_from_mac_address@eap_am_tools_c@@UAE?AW4eap_status_e@@PBEKPAVeap_variable_data_c@@@Z @ 170 NONAME ; enum eap_status_e eap_am_tools_c::create_uuid_v5_from_mac_address(unsigned char const *, unsigned long, class eap_variable_data_c *) + ?shutdown_operation@eap_core_c@@CA?AW4eap_status_e@@PAVeap_base_type_c@@PAVabs_eap_am_tools_c@@@Z @ 171 NONAME ; enum eap_status_e eap_core_c::shutdown_operation(class eap_base_type_c *, class abs_eap_am_tools_c *) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAVeap_expanded_type_c@@@Z @ 172 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, class eap_expanded_type_c *) + ?create_state@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@@Z @ 173 NONAME ; enum eap_status_e eapol_core_c::create_state(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e) + ?stop_timer_thread@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@XZ @ 174 NONAME ; enum eap_status_e eap_am_tools_symbian_c::stop_timer_thread(void) + ?start_WPXM_reassociation@eapol_key_state_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PAVeap_variable_data_c@@@Z @ 175 NONAME ; enum eap_status_e eapol_key_state_c::start_WPXM_reassociation(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c *) + ?get_mac_address@eap_rogue_ap_entry_c@@QBEPAEXZ @ 176 NONAME ; unsigned char * eap_rogue_ap_entry_c::get_mac_address(void) const + ?compare_length@eap_variable_data_c@@QBEJPBV1@K@Z @ 177 NONAME ; long eap_variable_data_c::compare_length(class eap_variable_data_c const *, unsigned long) const + ??0eap_am_mutex_base_c@@QAE@XZ @ 178 NONAME ; eap_am_mutex_base_c::eap_am_mutex_base_c(void) + ?cancel_all_timers@eapol_core_c@@UAE?AW4eap_status_e@@XZ @ 179 NONAME ; enum eap_status_e eapol_core_c::cancel_all_timers(void) + ?get_header_buffer_length@eap_general_header_base_c@@QBEKXZ @ 180 NONAME ; unsigned long eap_general_header_base_c::get_header_buffer_length(void) const + ?get_data_length@eap_variable_data_c@@QBEKXZ @ 181 NONAME ; unsigned long eap_variable_data_c::get_data_length(void) const + ?restart_authentication@eap_session_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N11@Z @ 182 NONAME ; enum eap_status_e eap_session_core_c::restart_authentication(class eap_am_network_id_c const *, bool, bool, bool) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PA_K@Z @ 183 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, unsigned long long *) + ?add_rand_seed@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PBEK@Z @ 184 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::add_rand_seed(unsigned char const *, unsigned long) + ??0simple_config_credential_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 185 NONAME ; simple_config_credential_c::simple_config_credential_c(class abs_eap_am_tools_c *) + ?process_4_way_handshake_message_2@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K@Z @ 186 NONAME ; enum eap_status_e eapol_key_state_c::process_4_way_handshake_message_2(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long) + ?set_type@eap_am_network_id_c@@QAEXG@Z @ 187 NONAME ; void eap_am_network_id_c::set_type(unsigned short) + ?set_is_valid@eap_variable_data_c@@QAEXXZ @ 188 NONAME ; void eap_variable_data_c::set_is_valid(void) + ?get_trace_mask@eap_am_tools_c@@UBEKXZ @ 189 NONAME ; unsigned long eap_am_tools_c::get_trace_mask(void) const + ?start_authentication@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N@Z @ 190 NONAME ; enum eap_status_e ethernet_core_c::start_authentication(class eap_am_network_id_c const *, bool) + ?get_owner_thread@eap_am_mutex_symbian_c@@QBEPBVRThread@@XZ @ 191 NONAME ; class RThread const * eap_am_mutex_symbian_c::get_owner_thread(void) const + ?copy@eap_am_crypto_sha_256_c@@QAEPAV1@XZ @ 192 NONAME ; class eap_am_crypto_sha_256_c * eap_am_crypto_sha_256_c::copy(void) + ??0crypto_md5_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 193 NONAME ; crypto_md5_c::crypto_md5_c(class abs_eap_am_tools_c *) + ??1eapol_ethernet_header_wr_c@@UAE@XZ @ 194 NONAME ; eapol_ethernet_header_wr_c::~eapol_ethernet_header_wr_c(void) + ?parse_nai@eap_am_tools_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@PAV3@1@Z @ 195 NONAME ; enum eap_status_e eap_am_tools_c::parse_nai(class eap_variable_data_c const *, class eap_variable_data_c *, class eap_variable_data_c *) + ?get_eap_type@eap_state_notification_c@@UBE?AVeap_expanded_type_c@@XZ @ 196 NONAME ; class eap_expanded_type_c eap_state_notification_c::get_eap_type(void) const + ?reset_cached_pmksa@eapol_key_state_c@@QAE?AW4eap_status_e@@XZ @ 197 NONAME ; enum eap_status_e eapol_key_state_c::reset_cached_pmksa(void) + ?get_header_offset@eap_session_core_c@@UAEKPAK0@Z @ 198 NONAME ; unsigned long eap_session_core_c::get_header_offset(unsigned long *, unsigned long *) + ?get_key_information_key_index@eapol_RSNA_key_header_c@@QBEEXZ @ 199 NONAME ; unsigned char eapol_RSNA_key_header_c::get_key_information_key_index(void) const + ?decrypt_data@crypto_cbc_c@@UAE?AW4eap_status_e@@PBXPAXK@Z @ 200 NONAME ; enum eap_status_e crypto_cbc_c::decrypt_data(void const *, void *, unsigned long) + ?hmac_128_final@crypto_hmac_c@@QAE?AW4eap_status_e@@PAXPAK@Z @ 201 NONAME ; enum eap_status_e crypto_hmac_c::hmac_128_final(void *, unsigned long *) + ?get_is_valid@crypto_rc4_c@@UAE_NXZ @ 202 NONAME ; bool crypto_rc4_c::get_is_valid(void) + ?complete_WPXM_reassociation@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@PBVeap_variable_data_c@@@Z @ 203 NONAME ; enum eap_status_e eapol_wlan_authentication_c::complete_WPXM_reassociation(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, class eap_variable_data_c const *) + ?new_eapol_wlan_authentication@eapol_wlan_authentication_c@@SAPAV1@PAVabs_eap_am_tools_c@@PAVabs_eapol_wlan_authentication_c@@_NPBVabs_eapol_wlan_database_reference_if_c@@@Z @ 204 NONAME ; class eapol_wlan_authentication_c * eapol_wlan_authentication_c::new_eapol_wlan_authentication(class abs_eap_am_tools_c *, class abs_eapol_wlan_authentication_c *, bool, class abs_eapol_wlan_database_reference_if_c const *) + ?set_is_valid@eap_session_core_c@@UAEXXZ @ 205 NONAME ; void eap_session_core_c::set_is_valid(void) + ?re_activate_timer_queue@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@XZ @ 206 NONAME ; enum eap_status_e eap_am_tools_symbian_c::re_activate_timer_queue(void) + ?eap_host_to_little_endian_long_long@@YA_K_K@Z @ 207 NONAME ; unsigned long long eap_host_to_little_endian_long_long(unsigned long long) + ?set_bits_on@eapol_RSNA_key_header_c@@QAEGGGKK@Z @ 208 NONAME ; unsigned short eapol_RSNA_key_header_c::set_bits_on(unsigned short, unsigned short, unsigned long, unsigned long) + ??1eap_buf_chain_rd_c@@UAE@XZ @ 209 NONAME ; eap_buf_chain_rd_c::~eap_buf_chain_rd_c(void) + ?set_decryption_key_3des_ede@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEK@Z @ 210 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::set_decryption_key_3des_ede(class eap_variable_data_c *, unsigned char const *, unsigned long) + ??0eap_am_mutex_symbian_c@@QAE@PBV0@@Z @ 211 NONAME ; eap_am_mutex_symbian_c::eap_am_mutex_symbian_c(class eap_am_mutex_symbian_c const *) + ?start_preauthentication@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 212 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::start_preauthentication(class eap_array_c const *) + ?eap_status_return_file_number@eap_am_tools_c@@UAE?AW4eap_status_e@@_NW42@KKJ@Z @ 213 NONAME ; enum eap_status_e eap_am_tools_c::eap_status_return_file_number(bool, enum eap_status_e, unsigned long, unsigned long, long) + ??1eap_core_c@@UAE@XZ @ 214 NONAME ; eap_core_c::~eap_core_c(void) + ?create_eapol_key_handshake_message_0@eapol_key_state_c@@AAE?AW4eap_status_e@@_NPAVeap_buf_chain_wr_c@@KPAK2_KW4eapol_protocol_version_e@@@Z @ 215 NONAME ; enum eap_status_e eapol_key_state_c::create_eapol_key_handshake_message_0(bool, class eap_buf_chain_wr_c *, unsigned long, unsigned long *, unsigned long *, unsigned long long, enum eapol_protocol_version_e) + ?copy_context@crypto_sha_256_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 216 NONAME ; enum eap_status_e crypto_sha_256_c::copy_context(class eap_variable_data_c const *) + ??0eap_header_wr_c@@QAE@PAVabs_eap_am_tools_c@@PAEK@Z @ 217 NONAME ; eap_header_wr_c::eap_header_wr_c(class abs_eap_am_tools_c *, unsigned char *, unsigned long) + ?hash_init@crypto_sha1_c@@UAE?AW4eap_status_e@@XZ @ 218 NONAME ; enum eap_status_e crypto_sha1_c::hash_init(void) + ?check_is_valid_eap_type@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 219 NONAME ; enum eap_status_e eapol_wlan_authentication_c::check_is_valid_eap_type(class eap_expanded_type_c) + ?set_copy_of_network_id@eap_am_network_id_c@@QAE?AW4eap_status_e@@PBV1@@Z @ 220 NONAME ; enum eap_status_e eap_am_network_id_c::set_copy_of_network_id(class eap_am_network_id_c const *) + ?hash@eap_variable_data_c@@QBEKK@Z @ 221 NONAME ; unsigned long eap_variable_data_c::hash(unsigned long) const + ?get_subsect@eap_file_config_c@@AAE?AW4eap_status_e@@PAVabs_eap_am_file_input_c@@PAVeap_variable_data_c@@@Z @ 222 NONAME ; enum eap_status_e eap_file_config_c::get_subsect(class abs_eap_am_file_input_c *, class eap_variable_data_c *) + ?eap_status_return@eap_am_tools_c@@UAE?AW4eap_status_e@@_NW42@PBDJ@Z @ 223 NONAME ; enum eap_status_e eap_am_tools_c::eap_status_return(bool, enum eap_status_e, char const *, long) + ?object_increase_reference_count@eap_core_c@@QAEXXZ @ 224 NONAME ; void eap_core_c::object_increase_reference_count(void) + ?send_message@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PAVeapol_handle_tlv_message_data_c@@@Z @ 225 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::send_message(class eapol_handle_tlv_message_data_c *) + ?expand_key@crypto_kd_hmac_sha256_c@@QAE?AW4eap_status_e@@PAVeap_variable_data_c@@KPBV3@1@Z @ 226 NONAME ; enum eap_status_e crypto_kd_hmac_sha256_c::expand_key(class eap_variable_data_c *, unsigned long, class eap_variable_data_c const *, class eap_variable_data_c const *) + ?set_is_invalid@crypto_tls_sha1_prf_c@@AAEXXZ @ 227 NONAME ; void crypto_tls_sha1_prf_c::set_is_invalid(void) + ?process_4_way_handshake_message_3_payloads_b@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K_N@Z @ 228 NONAME ; enum eap_status_e eapol_key_state_c::process_4_way_handshake_message_3_payloads_b(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long, bool) + ?get_is_valid@crypto_eap_fast_hmac_sha1_prf_c@@QAE_NXZ @ 229 NONAME ; bool crypto_eap_fast_hmac_sha1_prf_c::get_is_valid(void) + ?copy@eap_rogue_ap_entry_c@@QBEPAV1@XZ @ 230 NONAME ; class eap_rogue_ap_entry_c * eap_rogue_ap_entry_c::copy(void) const + ?set_is_valid@crypto_cbc_c@@UAEXXZ @ 231 NONAME ; void crypto_cbc_c::set_is_valid(void) + ?tls_prf_cleanup@crypto_tls_prf_c@@QAE?AW4eap_status_e@@XZ @ 232 NONAME ; enum eap_status_e crypto_tls_prf_c::tls_prf_cleanup(void) + ?get_packet_type@eapol_header_base_c@@QBE?AW4eapol_packet_type_e@@XZ @ 233 NONAME ; enum eapol_packet_type_e eapol_header_base_c::get_packet_type(void) const + ?copy@crypto_sha1_c@@UAEPAVabs_crypto_hash_algorithm_c@@XZ @ 234 NONAME ; class abs_crypto_hash_algorithm_c * crypto_sha1_c::copy(void) + ?add_rogue_ap@eapol_core_c@@UAE?AW4eap_status_e@@AAV?$eap_array_c@Veap_rogue_ap_entry_c@@@@@Z @ 235 NONAME ; enum eap_status_e eapol_core_c::add_rogue_ap(class eap_array_c &) + ?timer_expired@eap_core_c@@UAE?AW4eap_status_e@@KPAX@Z @ 236 NONAME ; enum eap_status_e eap_core_c::timer_expired(unsigned long, void *) + ?get_data_length@eapol_ethernet_header_base_c@@QBEKXZ @ 237 NONAME ; unsigned long eapol_ethernet_header_base_c::get_data_length(void) const + ?file_read_line@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 238 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_read_line(class eap_variable_data_c *) + ?decrypt_key_data@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeapol_RSNA_key_header_c@@@Z @ 239 NONAME ; enum eap_status_e eapol_key_state_c::decrypt_key_data(class eapol_RSNA_key_header_c *) + ?reset@eap_core_c@@QAE?AW4eap_status_e@@XZ @ 240 NONAME ; enum eap_status_e eap_core_c::reset(void) + ?state_notification@eapol_message_wlan_authentication_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 241 NONAME ; void eapol_message_wlan_authentication_c::state_notification(class abs_eap_state_notification_c const *) + ?get_received_PMKID@eapol_key_state_c@@AAEPAVeap_variable_data_c@@XZ @ 242 NONAME ; class eap_variable_data_c * eapol_key_state_c::get_received_PMKID(void) + ?eap_host_to_little_endian_short@@YAGG@Z @ 243 NONAME ; unsigned short eap_host_to_little_endian_short(unsigned short) + ?configure@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@XZ @ 244 NONAME ; enum eap_status_e eapol_wlan_authentication_c::configure(void) + ?get_key_index@eapol_session_key_c@@QBEKXZ @ 245 NONAME ; unsigned long eapol_session_key_c::get_key_index(void) const + ?get_message_type_string@eap_simple_config_trace_string_c@@QBEPBDW4simple_config_Message_Type_e@@@Z @ 246 NONAME ; char const * eap_simple_config_trace_string_c::get_message_type_string(enum simple_config_Message_Type_e) const + ??0eap_variable_data_c@@QAE@PAVabs_eap_am_tools_c@@PBXK_N2@Z @ 247 NONAME ; eap_variable_data_c::eap_variable_data_c(class abs_eap_am_tools_c *, void const *, unsigned long, bool, bool) + ?check_pmksa_cache@eapol_key_state_c@@QAE?AW4eap_status_e@@W4eapol_key_authentication_type_e@@W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@1@Z @ 248 NONAME ; enum eap_status_e eapol_key_state_c::check_pmksa_cache(enum eapol_key_authentication_type_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e) + ??1abs_crypto_stream_algorithm_c@@UAE@XZ @ 249 NONAME ; abs_crypto_stream_algorithm_c::~abs_crypto_stream_algorithm_c(void) + ??1eapol_ethernet_header_base_c@@UAE@XZ @ 250 NONAME ; eapol_ethernet_header_base_c::~eapol_ethernet_header_base_c(void) + ?eap_read_u24_t_network_order@@YAKPBXK@Z @ 251 NONAME ; unsigned long eap_read_u24_t_network_order(void const *, unsigned long) + ??0eapol_am_wlan_authentication_symbian_c@@QAE@PAVabs_eap_am_tools_c@@_NPBVabs_eapol_wlan_database_reference_if_c@@@Z @ 252 NONAME ; eapol_am_wlan_authentication_symbian_c::eapol_am_wlan_authentication_symbian_c(class abs_eap_am_tools_c *, bool, class abs_eapol_wlan_database_reference_if_c const *) + ?set_key_data_length@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@G@Z @ 253 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_data_length(unsigned short) + ?hash_init@eap_am_crypto_md4_c@@QAE?AW4eap_status_e@@XZ @ 254 NONAME ; enum eap_status_e eap_am_crypto_md4_c::hash_init(void) + ?cnf_get_string@eap_file_config_c@@AAE?AW4eap_status_e@@PBVeap_variable_data_c@@PAV3@1PAW4eap_configure_type_e@@@Z @ 255 NONAME ; enum eap_status_e eap_file_config_c::cnf_get_string(class eap_variable_data_c const *, class eap_variable_data_c *, class eap_variable_data_c *, enum eap_configure_type_e *) + ?increase_key_reply_counter@eapol_key_state_c@@AAEXXZ @ 256 NONAME ; void eapol_key_state_c::increase_key_reply_counter(void) + ?sleep@eap_am_tools_symbian_c@@UAEXK@Z @ 257 NONAME ; void eap_am_tools_symbian_c::sleep(unsigned long) + ?eap_sha1_process_data_host_order@eap_am_crypto_sha1_c@@AAE?AW4eap_status_e@@PBKK@Z @ 258 NONAME ; enum eap_status_e eap_am_crypto_sha1_c::eap_sha1_process_data_host_order(unsigned long const *, unsigned long) + ?restart_authentication@eapol_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N11@Z @ 259 NONAME ; enum eap_status_e eapol_core_c::restart_authentication(class eap_am_network_id_c const *, bool, bool, bool) + ?started_eap_authentication@eapol_key_state_c@@QAE?AW4eap_status_e@@XZ @ 260 NONAME ; enum eap_status_e eapol_key_state_c::started_eap_authentication(void) + ?get_key_flag@eapol_RC4_key_header_c@@QBE?AW4eapol_RC4_key_flags_e@@XZ @ 261 NONAME ; enum eapol_RC4_key_flags_e eapol_RC4_key_header_c::get_key_flag(void) const + ?get_data@eapol_header_base_c@@QBEPAEK@Z @ 262 NONAME ; unsigned char * eapol_header_base_c::get_data(unsigned long) const + ?get_block_size@crypto_sha1_c@@UAEKXZ @ 263 NONAME ; unsigned long crypto_sha1_c::get_block_size(void) + ?set_is_valid@crypto_tls_sha1_prf_c@@AAEXXZ @ 264 NONAME ; void crypto_tls_sha1_prf_c::set_is_valid(void) + ?get_clock_ticks@eap_am_tools_symbian_c@@UAE_KXZ @ 265 NONAME ; unsigned long long eap_am_tools_symbian_c::get_clock_ticks(void) + ?packet_process@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 266 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::packet_process(class eap_array_c const *) + ?get_data@eap_buf_chain_base_c@@QBEPAEK@Z @ 267 NONAME ; unsigned char * eap_buf_chain_base_c::get_data(unsigned long) const + ?zero_EAPOL_header_and_Key_descriptor@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@@Z @ 268 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::zero_EAPOL_header_and_Key_descriptor(class abs_eap_am_tools_c *) + ?copy@network_key_and_index_c@@QAEPAV1@XZ @ 269 NONAME ; class network_key_and_index_c * network_key_and_index_c::copy(void) + ?get_is_encryption_on@eapol_key_state_c@@QAE_NXZ @ 270 NONAME ; bool eapol_key_state_c::get_is_encryption_on(void) + ?copy@crypto_md5_c@@UAEPAVabs_crypto_hash_algorithm_c@@XZ @ 271 NONAME ; class abs_crypto_hash_algorithm_c * crypto_md5_c::copy(void) + ?get_rand_bytes@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAEK@Z @ 272 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::get_rand_bytes(unsigned char *, unsigned long) + ?get_type@eap_am_network_id_c@@QBEGXZ @ 273 NONAME ; unsigned short eap_am_network_id_c::get_type(void) const + ?get_eap_type@eap_master_session_key_c@@QBE?AVeap_expanded_type_c@@XZ @ 274 NONAME ; class eap_expanded_type_c eap_master_session_key_c::get_eap_type(void) const + ?get_key_length@crypto_cbc_c@@UAEKXZ @ 275 NONAME ; unsigned long crypto_cbc_c::get_key_length(void) + ?packet_data_session_key@eapol_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeapol_session_key_c@@@Z @ 276 NONAME ; enum eap_status_e eapol_core_c::packet_data_session_key(class eap_am_network_id_c const *, class eapol_session_key_c const *) + ?get_key_length@eapol_key_state_c@@AAE?AW4eap_status_e@@W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@PAG@Z @ 277 NONAME ; enum eap_status_e eapol_key_state_c::get_key_length(enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, unsigned short *) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@E@Z @ 278 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(unsigned char) + ?packet_process@eap_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 279 NONAME ; enum eap_status_e eap_core_c::packet_process(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long) + ?hash_init@crypto_md5_c@@UAE?AW4eap_status_e@@XZ @ 280 NONAME ; enum eap_status_e crypto_md5_c::hash_init(void) + ??0eap_session_core_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_eap_core_c@@_N@Z @ 281 NONAME ; eap_session_core_c::eap_session_core_c(class abs_eap_am_tools_c *, class abs_eap_core_c *, bool) + ?memmove@eap_am_tools_symbian_c@@UAEXPAXPBXK@Z @ 282 NONAME ; void eap_am_tools_symbian_c::memmove(void *, void const *, unsigned long) + ?set_marked_removed@eap_core_c@@QAEXXZ @ 283 NONAME ; void eap_core_c::set_marked_removed(void) + ?get_is_valid@eapol_message_wlan_authentication_c@@QAE_NXZ @ 284 NONAME ; bool eapol_message_wlan_authentication_c::get_is_valid(void) + ?set_key_type@eapol_session_key_c@@QAEXW4eapol_key_type_e@@@Z @ 285 NONAME ; void eapol_session_key_c::set_key_type(enum eapol_key_type_e) + ?eap_htonl@@YAKK@Z @ 286 NONAME ; unsigned long eap_htonl(unsigned long) + ?sha_256_update@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEK@Z @ 287 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::sha_256_update(class eap_variable_data_c *, unsigned char const *, unsigned long) + ?eap_md4_transform_host_order@eap_am_crypto_md4_c@@AAE?AW4eap_status_e@@PBKK@Z @ 288 NONAME ; enum eap_status_e eap_am_crypto_md4_c::eap_md4_transform_host_order(unsigned long const *, unsigned long) + ?add_rogue_ap@ethernet_core_c@@UAE?AW4eap_status_e@@AAV?$eap_array_c@Veap_rogue_ap_entry_c@@@@@Z @ 289 NONAME ; enum eap_status_e ethernet_core_c::add_rogue_ap(class eap_array_c &) + ??0eap_am_network_id_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 290 NONAME ; eap_am_network_id_c::eap_am_network_id_c(class abs_eap_am_tools_c *) + ?get_is_valid@eap_am_crypto_rc4_c@@QAE_NXZ @ 291 NONAME ; bool eap_am_crypto_rc4_c::get_is_valid(void) + ?get_and_increment_global_key_counter@eapol_core_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 292 NONAME ; enum eap_status_e eapol_core_c::get_and_increment_global_key_counter(class eap_variable_data_c *) + ?set_version@eapol_header_base_c@@QAEXW4eapol_protocol_version_e@@@Z @ 293 NONAME ; void eapol_header_base_c::set_version(enum eapol_protocol_version_e) + ?set_encryption_key@crypto_aes_wrap_c@@QAE?AW4eap_status_e@@PBXK@Z @ 294 NONAME ; enum eap_status_e crypto_aes_wrap_c::set_encryption_key(void const *, unsigned long) + ?start_preauthentication@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@@Z @ 295 NONAME ; enum eap_status_e eapol_core_c::start_preauthentication(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e) + ?write_configure@eap_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 296 NONAME ; enum eap_status_e eap_core_c::write_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?cleanup@crypto_rsa_c@@QAE?AW4eap_status_e@@XZ @ 297 NONAME ; enum eap_status_e crypto_rsa_c::cleanup(void) + ?object_decrease_reference_count@eap_base_type_c@@QAEKXZ @ 298 NONAME ; unsigned long eap_base_type_c::object_decrease_reference_count(void) + ?get_is_valid@crypto_md4_c@@UAE_NXZ @ 299 NONAME ; bool crypto_md4_c::get_is_valid(void) + ??1eap_header_rd_c@@UAE@XZ @ 300 NONAME ; eap_header_rd_c::~eap_header_rd_c(void) + ?allocate_message_buffer@eap_tlv_message_data_c@@QAE?AW4eap_status_e@@KKPAPAX@Z @ 301 NONAME ; enum eap_status_e eap_tlv_message_data_c::allocate_message_buffer(unsigned long, unsigned long, void * *) + ?hash_cleanup@crypto_sha1_c@@UAE?AW4eap_status_e@@XZ @ 302 NONAME ; enum eap_status_e crypto_sha1_c::hash_cleanup(void) + ?convert_hex_ascii_to_bytes@eap_am_tools_c@@UAE?AW4eap_status_e@@PBXKPAVeap_variable_data_c@@@Z @ 303 NONAME ; enum eap_status_e eap_am_tools_c::convert_hex_ascii_to_bytes(void const *, unsigned long, class eap_variable_data_c *) + ?check_pmksa_cache@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_am_network_id_c@@@@W4eapol_key_authentication_type_e@@W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@2@Z @ 304 NONAME ; enum eap_status_e eapol_wlan_authentication_c::check_pmksa_cache(class eap_array_c *, enum eapol_key_authentication_type_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e) + ?parse_generic_key_data_payload@eapol_key_state_c@@AAE?AW4eap_status_e@@W4eapol_key_descriptor_type_e@@W4eapol_RSNA_key_descriptor_type_e@@PAVeapol_rsna_key_data_header_c@@PAKPAVeapol_rsna_key_data_payloads_c@@W4eapol_key_state_e@@@Z @ 305 NONAME ; enum eap_status_e eapol_key_state_c::parse_generic_key_data_payload(enum eapol_key_descriptor_type_e, enum eapol_RSNA_key_descriptor_type_e, class eapol_rsna_key_data_header_c *, unsigned long *, class eapol_rsna_key_data_payloads_c *, enum eapol_key_state_e) + ?hash_update@eap_am_crypto_md4_c@@QAE?AW4eap_status_e@@PBXK@Z @ 306 NONAME ; enum eap_status_e eap_am_crypto_md4_c::hash_update(void const *, unsigned long) + ?set_key_information@eapol_RSNA_key_header_c@@AAE?AW4eap_status_e@@G@Z @ 307 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_information(unsigned short) + ?get_is_reserved@eap_am_mutex_base_c@@QBE_NXZ @ 308 NONAME ; bool eap_am_mutex_base_c::get_is_reserved(void) const + ?start_group_key_handshake@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_protocol_version_e@@W4eapol_key_descriptor_type_e@@@Z @ 309 NONAME ; enum eap_status_e eapol_key_state_c::start_group_key_handshake(class eap_am_network_id_c const *, enum eapol_protocol_version_e, enum eapol_key_descriptor_type_e) + ?process_RC4_key_descriptor@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 310 NONAME ; enum eap_status_e eapol_key_state_c::process_RC4_key_descriptor(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long) + ?hash_init@eap_am_crypto_sha1_c@@QAE?AW4eap_status_e@@XZ @ 311 NONAME ; enum eap_status_e eap_am_crypto_sha1_c::hash_init(void) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAV?$eap_array_c@Vsimple_config_credential_c@@@@@Z @ 312 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, class eap_array_c *) + ?get_is_valid@crypto_cbc_c@@UAE_NXZ @ 313 NONAME ; bool crypto_cbc_c::get_is_valid(void) + ?convert_bytes_to_ascii_armor@eap_am_tools_c@@UAE?AW4eap_status_e@@PBEKPAEPAK@Z @ 314 NONAME ; enum eap_status_e eap_am_tools_c::convert_bytes_to_ascii_armor(unsigned char const *, unsigned long, unsigned char *, unsigned long *) + ?copy@eap_network_id_selector_c@@QBEPAV1@XZ @ 315 NONAME ; class eap_network_id_selector_c * eap_network_id_selector_c::copy(void) const + ?get_mem_guard_length@eap_buf_chain_base_c@@QAEKXZ @ 316 NONAME ; unsigned long eap_buf_chain_base_c::get_mem_guard_length(void) + ?get_key_descriptor_type@eapol_RC4_key_header_c@@QBE?AW4eapol_key_descriptor_type_e@@XZ @ 317 NONAME ; enum eapol_key_descriptor_type_e eapol_RC4_key_header_c::get_key_descriptor_type(void) const + ?eap_write_u16_t_little_endian_order@@YA?AW4eap_status_e@@PAXKG@Z @ 318 NONAME ; enum eap_status_e eap_write_u16_t_little_endian_order(void *, unsigned long, unsigned short) + ?timer_expired@eapol_message_wlan_authentication_c@@UAE?AW4eap_status_e@@KPAX@Z @ 319 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::timer_expired(unsigned long, void *) + ??1crypto_3des_ede_c@@UAE@XZ @ 320 NONAME ; crypto_3des_ede_c::~crypto_3des_ede_c(void) + ?timer_expired@eapol_core_c@@UAE?AW4eap_status_e@@KPAX@Z @ 321 NONAME ; enum eap_status_e eapol_core_c::timer_expired(unsigned long, void *) + ?get_saved_eap_identity@eap_core_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 322 NONAME ; enum eap_status_e eap_core_c::get_saved_eap_identity(class eap_variable_data_c *) + ?convert_ascii_to_uppercase@eap_am_tools_c@@UAE?AW4eap_status_e@@PAEK@Z @ 323 NONAME ; enum eap_status_e eap_am_tools_c::convert_ascii_to_uppercase(unsigned char *, unsigned long) + ?decrypt_with_private_key@crypto_rsa_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@@Z @ 324 NONAME ; enum eap_status_e crypto_rsa_c::decrypt_with_private_key(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ?cancel_all_timers@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@XZ @ 325 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::cancel_all_timers(void) + ?tls_prf_output@crypto_tls_prf_c@@QAE?AW4eap_status_e@@PAXK@Z @ 326 NONAME ; enum eap_status_e crypto_tls_prf_c::tls_prf_output(void *, unsigned long) + ?get_is_writable@eap_variable_data_c@@QBE_NXZ @ 327 NONAME ; bool eap_variable_data_c::get_is_writable(void) const + ?convert_eap_type_to_u64_t@@YA_KVeap_expanded_type_c@@@Z @ 328 NONAME ; unsigned long long convert_eap_type_to_u64_t(class eap_expanded_type_c) + ?hash_cleanup@crypto_sha_256_c@@UAE?AW4eap_status_e@@XZ @ 329 NONAME ; enum eap_status_e crypto_sha_256_c::hash_cleanup(void) + ?get_vendor_type@eap_expanded_type_c@@QBEKXZ @ 330 NONAME ; unsigned long eap_expanded_type_c::get_vendor_type(void) const + ?get_expanded_ietf_type_offset@eap_header_base_c@@SAKXZ @ 331 NONAME ; unsigned long eap_header_base_c::get_expanded_ietf_type_offset(void) + ?get_data@eap_variable_data_c@@QBEPAEK@Z @ 332 NONAME ; unsigned char * eap_variable_data_c::get_data(unsigned long) const + ?dublicate_mutex@eap_am_mutex_symbian_c@@UAEPAVabs_eap_am_mutex_c@@XZ @ 333 NONAME ; class abs_eap_am_mutex_c * eap_am_mutex_symbian_c::dublicate_mutex(void) + ?update_non_aligned@crypto_cbc_c@@UAE?AW4eap_status_e@@PBXPAXK@Z @ 334 NONAME ; enum eap_status_e crypto_cbc_c::update_non_aligned(void const *, void *, unsigned long) + ?disassociation@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 335 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::disassociation(class eap_array_c const *) + ?cancel_authentication_session@eapol_core_c@@SA?AW4eap_status_e@@PAVeapol_key_state_c@@PAVabs_eap_am_tools_c@@@Z @ 336 NONAME ; enum eap_status_e eapol_core_c::cancel_authentication_session(class eapol_key_state_c *, class abs_eap_am_tools_c *) + ?hmac_cleanup@crypto_hmac_c@@UAE?AW4eap_status_e@@XZ @ 337 NONAME ; enum eap_status_e crypto_hmac_c::hmac_cleanup(void) + ??1eapol_rsna_variable_data_c@@UAE@XZ @ 338 NONAME ; eapol_rsna_variable_data_c::~eapol_rsna_variable_data_c(void) + ?configure@eapol_key_state_c@@QAE?AW4eap_status_e@@XZ @ 339 NONAME ; enum eap_status_e eapol_key_state_c::configure(void) + ?set_copy@eap_master_session_key_c@@QAE?AW4eap_status_e@@PBV1@@Z @ 340 NONAME ; enum eap_status_e eap_master_session_key_c::set_copy(class eap_master_session_key_c const *) + ?hash_init@eap_am_crypto_sha_256_c@@QAE?AW4eap_status_e@@XZ @ 341 NONAME ; enum eap_status_e eap_am_crypto_sha_256_c::hash_init(void) + ?get_send_network_id@eap_core_retransmission_c@@QAEPAVeap_am_network_id_c@@XZ @ 342 NONAME ; class eap_am_network_id_c * eap_core_retransmission_c::get_send_network_id(void) + ?get_eapol_packet_body_length@eapol_RSNA_key_header_c@@QBEGXZ @ 343 NONAME ; unsigned short eapol_RSNA_key_header_c::get_eapol_packet_body_length(void) const + ?get_is_valid@eapol_session_key_c@@QBE_NXZ @ 344 NONAME ; bool eapol_session_key_c::get_is_valid(void) const + ?get_ietf_type_field_length@eap_header_base_c@@SAKXZ @ 345 NONAME ; unsigned long eap_header_base_c::get_ietf_type_field_length(void) + ?rsa_encrypt_with_private_key@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@10@Z @ 346 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rsa_encrypt_with_private_key(class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ??0crypto_sha_256_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 347 NONAME ; crypto_sha_256_c::crypto_sha_256_c(class abs_eap_am_tools_c *) + ??0eap_buf_chain_base_c@@QAE@W4eap_write_buffer_e@@PAVabs_eap_am_tools_c@@K@Z @ 348 NONAME ; eap_buf_chain_base_c::eap_buf_chain_base_c(enum eap_write_buffer_e, class abs_eap_am_tools_c *, unsigned long) + ?eap_read_u64_t_little_endian_order@@YA_KPBXK@Z @ 349 NONAME ; unsigned long long eap_read_u64_t_little_endian_order(void const *, unsigned long) + ?decrypt_data@crypto_cbc_c@@UAE?AW4eap_status_e@@PAXK@Z @ 350 NONAME ; enum eap_status_e crypto_cbc_c::decrypt_data(void *, unsigned long) + ?get_is_valid@crypto_wpa_psk_password_hash_c@@QAE_NXZ @ 351 NONAME ; bool crypto_wpa_psk_password_hash_c::get_is_valid(void) + ??1ethernet_core_c@@UAE@XZ @ 352 NONAME ; ethernet_core_c::~ethernet_core_c(void) + ?eap_acknowledge@eap_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 353 NONAME ; enum eap_status_e eap_session_core_c::eap_acknowledge(class eap_am_network_id_c const *) + ?get_key_information_key_type@eapol_RSNA_key_header_c@@QBE_NXZ @ 354 NONAME ; bool eapol_RSNA_key_header_c::get_key_information_key_type(void) const + ??1crypto_aes_wrap_c@@UAE@XZ @ 355 NONAME ; crypto_aes_wrap_c::~crypto_aes_wrap_c(void) + ?get_status_string@eap_status_string_c@@SAPBDW4eap_status_e@@@Z @ 356 NONAME ; char const * eap_status_string_c::get_status_string(enum eap_status_e) + ?get_is_valid@crypto_md5_c@@UAE_NXZ @ 357 NONAME ; bool crypto_md5_c::get_is_valid(void) + ?get_timer_queue_is_empty@eap_am_tools_symbian_c@@UAE_NXZ @ 358 NONAME ; bool eap_am_tools_symbian_c::get_timer_queue_is_empty(void) + ?compare_u64@eap_am_tools_c@@UAEJ_K0@Z @ 359 NONAME ; long eap_am_tools_c::compare_u64(unsigned long long, unsigned long long) + ?enter_crypto_cs@eap_am_tools_symbian_c@@QAEXXZ @ 360 NONAME ; void eap_am_tools_symbian_c::enter_crypto_cs(void) + ??0crypto_nt_hash_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 361 NONAME ; crypto_nt_hash_c::crypto_nt_hash_c(class abs_eap_am_tools_c *) + ?md5_final@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PAEPAK@Z @ 362 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::md5_final(class eap_variable_data_c *, unsigned char *, unsigned long *) + ??0crypto_tls_md5_prf_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 363 NONAME ; crypto_tls_md5_prf_c::crypto_tls_md5_prf_c(class abs_eap_am_tools_c *) + ?object_increase_reference_count@eap_am_memory_store_tlv_data_c@@QAEXXZ @ 364 NONAME ; void eap_am_memory_store_tlv_data_c::object_increase_reference_count(void) + ?get_gmt_unix_time@eap_am_tools_symbian_c@@UAEKXZ @ 365 NONAME ; unsigned long eap_am_tools_symbian_c::get_gmt_unix_time(void) + ?cleanup@eap_am_crypto_rc4_c@@AAE?AW4eap_status_e@@XZ @ 366 NONAME ; enum eap_status_e eap_am_crypto_rc4_c::cleanup(void) + ?file_copy@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@0@Z @ 367 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_copy(class eap_variable_data_c const *, class eap_variable_data_c const *) + ??1eap_am_crypto_symbian_c@@UAE@XZ @ 368 NONAME ; eap_am_crypto_symbian_c::~eap_am_crypto_symbian_c(void) + ?cancel_retransmission@eapol_key_state_c@@AAE?AW4eap_status_e@@XZ @ 369 NONAME ; enum eap_status_e eapol_key_state_c::cancel_retransmission(void) + ?get_use_seconds_timestamp_in_traces@eap_am_tools_c@@QAE_NXZ @ 370 NONAME ; bool eap_am_tools_c::get_use_seconds_timestamp_in_traces(void) + ?get_master_key@crypto_nt_hash_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@K@Z @ 371 NONAME ; enum eap_status_e crypto_nt_hash_c::get_master_key(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *, unsigned long) + ?start_reassociation@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 372 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::start_reassociation(class eap_array_c const *) + ?packet_data_crypto_keys@eap_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeap_master_session_key_c@@@Z @ 373 NONAME ; enum eap_status_e eap_core_c::packet_data_crypto_keys(class eap_am_network_id_c const *, class eap_master_session_key_c const *) + ?get_protocol_layer_string@eap_state_notification_c@@SAPBDK@Z @ 374 NONAME ; char const * eap_state_notification_c::get_protocol_layer_string(unsigned long) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAW4eapol_tlv_message_type_function_e@@@Z @ 375 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, enum eapol_tlv_message_type_function_e *) + ?get_payload_size@eapol_handle_tlv_message_data_c@@QBEKPAVnetwork_key_and_index_c@@@Z @ 376 NONAME ; unsigned long eapol_handle_tlv_message_data_c::get_payload_size(class network_key_and_index_c *) const + ?get_MAC_address@simple_config_credential_c@@QAEPAVeap_variable_data_c@@XZ @ 377 NONAME ; class eap_variable_data_c * simple_config_credential_c::get_MAC_address(void) + ?decrypt_data@crypto_rc4_c@@UAE?AW4eap_status_e@@PAXK@Z @ 378 NONAME ; enum eap_status_e crypto_rc4_c::decrypt_data(void *, unsigned long) + ?add_rand_seed_hw_ticks@crypto_random_c@@QAE?AW4eap_status_e@@XZ @ 379 NONAME ; enum eap_status_e crypto_random_c::add_rand_seed_hw_ticks(void) + ?set_is_valid@eap_am_crypto_symbian_c@@UAEXXZ @ 380 NONAME ; void eap_am_crypto_symbian_c::set_is_valid(void) + ?set_buffer_length@eap_buf_chain_base_c@@QAE?AW4eap_status_e@@K@Z @ 381 NONAME ; enum eap_status_e eap_buf_chain_base_c::set_buffer_length(unsigned long) + ?check_header@eapol_RC4_key_header_c@@UBE?AW4eap_status_e@@XZ @ 382 NONAME ; enum eap_status_e eapol_RC4_key_header_c::check_header(void) const + ?set_is_valid@crypto_hmac_c@@UAEXXZ @ 383 NONAME ; void crypto_hmac_c::set_is_valid(void) + ?get_previous_state@eap_state_notification_c@@UBEKXZ @ 384 NONAME ; unsigned long eap_state_notification_c::get_previous_state(void) const + ?packet_send@eap_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 385 NONAME ; enum eap_status_e eap_core_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long) + ?cancel_authentication_session@eapol_key_state_c@@QAE?AW4eap_status_e@@XZ @ 386 NONAME ; enum eap_status_e eapol_key_state_c::cancel_authentication_session(void) + ?read_hex_byte@eap_file_config_c@@AAEPAEPAEPBE0@Z @ 387 NONAME ; unsigned char * eap_file_config_c::read_hex_byte(unsigned char *, unsigned char const *, unsigned char *) + ?read_configure@eap_file_config_c@@AAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@PAV?$eap_core_map_c@Veap_config_value_c@@Vabs_eap_core_map_c@@Veap_variable_data_c@@@@_N@Z @ 388 NONAME ; enum eap_status_e eap_file_config_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *, class eap_core_map_c *, bool) + ?get_md5_block_size@eap_am_crypto_symbian_c@@UAEKPAVeap_variable_data_c@@@Z @ 389 NONAME ; unsigned long eap_am_crypto_symbian_c::get_md5_block_size(class eap_variable_data_c *) + ??0eap_buf_chain_wr_c@@QAE@W4eap_write_buffer_e@@PAVabs_eap_am_tools_c@@PAEK_N3K@Z @ 390 NONAME ; eap_buf_chain_wr_c::eap_buf_chain_wr_c(enum eap_write_buffer_e, class abs_eap_am_tools_c *, unsigned char *, unsigned long, bool, bool, unsigned long) + ??1eap_core_retransmission_c@@UAE@XZ @ 391 NONAME ; eap_core_retransmission_c::~eap_core_retransmission_c(void) + ?set_session_timeout@eapol_core_c@@UAE?AW4eap_status_e@@K@Z @ 392 NONAME ; enum eap_status_e eapol_core_c::set_session_timeout(unsigned long) + ??1eap_tlv_message_data_c@@UAE@XZ @ 393 NONAME ; eap_tlv_message_data_c::~eap_tlv_message_data_c(void) + ?hash_init@crypto_md4_c@@UAE?AW4eap_status_e@@XZ @ 394 NONAME ; enum eap_status_e crypto_md4_c::hash_init(void) + ?encrypt_data@eap_am_crypto_rc4_c@@QAE?AW4eap_status_e@@PBXPAXK@Z @ 395 NONAME ; enum eap_status_e eap_am_crypto_rc4_c::encrypt_data(void const *, void *, unsigned long) + ?add_data@eap_variable_data_c@@QAE?AW4eap_status_e@@PBV1@@Z @ 396 NONAME ; enum eap_status_e eap_variable_data_c::add_data(class eap_variable_data_c const *) + ?read_configure@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 397 NONAME ; enum eap_status_e eapol_wlan_authentication_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?configure@eap_session_core_c@@UAE?AW4eap_status_e@@XZ @ 398 NONAME ; enum eap_status_e eap_session_core_c::configure(void) + ?get_destination_length@eap_am_network_id_c@@QBEKXZ @ 399 NONAME ; unsigned long eap_am_network_id_c::get_destination_length(void) const + ?tls_prf_init@crypto_tls_md5_prf_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@00@Z @ 400 NONAME ; enum eap_status_e crypto_tls_md5_prf_c::tls_prf_init(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ?get_timer_id@eap_am_memory_store_tlv_data_c@@QBEKXZ @ 401 NONAME ; unsigned long eap_am_memory_store_tlv_data_c::get_timer_id(void) const + ?get_is_valid@eapol_wlan_authentication_c@@QAE_NXZ @ 402 NONAME ; bool eapol_wlan_authentication_c::get_is_valid(void) + ??9eap_expanded_type_c@@QBE_NABV0@@Z @ 403 NONAME ; bool eap_expanded_type_c::operator!=(class eap_expanded_type_c const &) const + ?trace_eapol_key_message@eapol_key_state_c@@AAE?AW4eap_status_e@@PBDPAVeapol_RSNA_key_header_c@@@Z @ 404 NONAME ; enum eap_status_e eapol_key_state_c::trace_eapol_key_message(char const *, class eapol_RSNA_key_header_c *) + ?eap_acknowledge@eap_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 405 NONAME ; enum eap_status_e eap_core_c::eap_acknowledge(class eap_am_network_id_c const *) + ?md4_init@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 406 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::md4_init(class eap_variable_data_c *) + ?get_is_tunneled_eap@eap_core_c@@UBE_NXZ @ 407 NONAME ; bool eap_core_c::get_is_tunneled_eap(void) const + ??1crypto_tls_base_prf_c@@UAE@XZ @ 408 NONAME ; crypto_tls_base_prf_c::~crypto_tls_base_prf_c(void) + ?complete_WPXM_reassociation@ethernet_core_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@@Z @ 409 NONAME ; enum eap_status_e ethernet_core_c::complete_WPXM_reassociation(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *) + ?octet_to_ascii@eap_am_tools_c@@UAEEJ@Z @ 410 NONAME ; unsigned char eap_am_tools_c::octet_to_ascii(long) + ?get_is_valid_data@eap_buf_chain_base_c@@QBE_NXZ @ 411 NONAME ; bool eap_buf_chain_base_c::get_is_valid_data(void) const + ??0eap_buf_chain_rd_c@@QAE@W4eap_read_buffer_e@@PAVabs_eap_am_tools_c@@K@Z @ 412 NONAME ; eap_buf_chain_rd_c::eap_buf_chain_rd_c(enum eap_read_buffer_e, class abs_eap_am_tools_c *, unsigned long) + ?process_group_key_handshake_message@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K@Z @ 413 NONAME ; enum eap_status_e eapol_key_state_c::process_group_key_handshake_message(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long) + ?load_module@ethernet_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@0PAVabs_eap_base_type_c@@PAPAVeap_base_type_c@@_NPBVeap_am_network_id_c@@@Z @ 414 NONAME ; enum eap_status_e ethernet_core_c::load_module(class eap_expanded_type_c, class eap_expanded_type_c, class abs_eap_base_type_c *, class eap_base_type_c * *, bool, class eap_am_network_id_c const *) + ?get_is_valid@eap_am_crypto_md4_c@@QAE_NXZ @ 415 NONAME ; bool eap_am_crypto_md4_c::get_is_valid(void) + ?get_next_retransmission_counter@eap_core_retransmission_c@@QAEKXZ @ 416 NONAME ; unsigned long eap_core_retransmission_c::get_next_retransmission_counter(void) + ?hash_final@crypto_md5_c@@UAE?AW4eap_status_e@@PAXPAK@Z @ 417 NONAME ; enum eap_status_e crypto_md5_c::hash_final(void *, unsigned long *) + ?get_eap_type_list@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_expanded_type_c@@@@@Z @ 418 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::get_eap_type_list(class eap_array_c *) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@G@Z @ 419 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(unsigned short) + ?dh_cleanup@crypto_ephemeral_diffie_hellman_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 420 NONAME ; enum eap_status_e crypto_ephemeral_diffie_hellman_c::dh_cleanup(class eap_variable_data_c const *) + ?send_eap_failure@eap_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@E@Z @ 421 NONAME ; enum eap_status_e eap_core_c::send_eap_failure(class eap_am_network_id_c const *, unsigned char) + ?set_sequence_number@eapol_session_key_c@@QAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 422 NONAME ; enum eap_status_e eapol_session_key_c::set_sequence_number(class eap_variable_data_c *) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@_N@Z @ 423 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(bool) + ?get_send_packet_index@eap_buf_chain_base_c@@QAEKXZ @ 424 NONAME ; unsigned long eap_buf_chain_base_c::get_send_packet_index(void) + ?packet_send@eap_session_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 425 NONAME ; enum eap_status_e eap_session_core_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long) + ?set_key_information_key_descriptor_version@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@E@Z @ 426 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_information_key_descriptor_version(unsigned char) + ?reset_eap_configuration@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@XZ @ 427 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::reset_eap_configuration(void) + ?get_state_string@eap_state_notification_c@@SAPBDKK@Z @ 428 NONAME ; char const * eap_state_notification_c::get_state_string(unsigned long, unsigned long) + ?copy_context@eap_am_crypto_md4_c@@AAE?AW4eap_status_e@@PBVeap_variable_data_c@@_KPBK2@Z @ 429 NONAME ; enum eap_status_e eap_am_crypto_md4_c::copy_context(class eap_variable_data_c const *, unsigned long long, unsigned long const *, unsigned long const *) + ?get_network_index@simple_config_credential_c@@QAEEXZ @ 430 NONAME ; unsigned char simple_config_credential_c::get_network_index(void) + ?shutdown@eapol_message_wlan_authentication_c@@QAE?AW4eap_status_e@@XZ @ 431 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::shutdown(void) + ?get_is_valid@ethernet_core_c@@UAE_NXZ @ 432 NONAME ; bool ethernet_core_c::get_is_valid(void) + ?create_4_way_handshake_message_4@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeap_buf_chain_wr_c@@KPAK1_K_NW4eapol_protocol_version_e@@W4eapol_key_descriptor_type_e@@@Z @ 433 NONAME ; enum eap_status_e eapol_key_state_c::create_4_way_handshake_message_4(class eap_buf_chain_wr_c *, unsigned long, unsigned long *, unsigned long *, unsigned long long, bool, enum eapol_protocol_version_e, enum eapol_key_descriptor_type_e) + ?initialize_pad@crypto_hmac_c@@AAE?AW4eap_status_e@@PAVeap_variable_data_c@@E@Z @ 434 NONAME ; enum eap_status_e crypto_hmac_c::initialize_pad(class eap_variable_data_c *, unsigned char) + ?sha_256_cleanup@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 435 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::sha_256_cleanup(class eap_variable_data_c *) + ?aligned_data_length@crypto_cbc_c@@UAEKK@Z @ 436 NONAME ; unsigned long crypto_cbc_c::aligned_data_length(unsigned long) + ?reset_start_offset_and_data_length@eap_variable_data_c@@QAE?AW4eap_status_e@@XZ @ 437 NONAME ; enum eap_status_e eap_variable_data_c::reset_start_offset_and_data_length(void) + ?begin_db_transaction@eap_am_tools_symbian_c@@QAE?AW4eap_status_e@@AAVRDbNamedDatabase@@@Z @ 438 NONAME ; enum eap_status_e eap_am_tools_symbian_c::begin_db_transaction(class RDbNamedDatabase &) + ?eap_shift_left_64_bit@@YA_K_KK@Z @ 439 NONAME ; unsigned long long eap_shift_left_64_bit(unsigned long long, unsigned long) + ?complete_reassociation@eapol_core_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@3W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@4@Z @ 440 NONAME ; enum eap_status_e eapol_core_c::complete_reassociation(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e) + ?trace_configuration@eap_am_tools_c@@UAEXW4eap_status_e@@PBVeap_configuration_field_c@@PBVeap_variable_data_c@@@Z @ 441 NONAME ; void eap_am_tools_c::trace_configuration(enum eap_status_e, class eap_configuration_field_c const *, class eap_variable_data_c const *) + ?get_identifier@eap_header_base_c@@QBEEXZ @ 442 NONAME ; unsigned char eap_header_base_c::get_identifier(void) const + ?configure@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@XZ @ 443 NONAME ; enum eap_status_e eap_am_tools_symbian_c::configure(void) + ?copy_message_digest@eap_am_crypto_sha_256_c@@AAE?AW4eap_status_e@@PAXPAK@Z @ 444 NONAME ; enum eap_status_e eap_am_crypto_sha_256_c::copy_message_digest(void *, unsigned long *) + ?get_data_length@eapol_header_base_c@@QBEGXZ @ 445 NONAME ; unsigned short eapol_header_base_c::get_data_length(void) const + ?get_block_size@eap_am_crypto_sha_256_c@@QAEKXZ @ 446 NONAME ; unsigned long eap_am_crypto_sha_256_c::get_block_size(void) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAVsimple_config_credential_c@@@Z @ 447 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, class simple_config_credential_c *) + ?object_increase_reference_count@eap_base_type_c@@QAEXXZ @ 448 NONAME ; void eap_base_type_c::object_increase_reference_count(void) + ?file_exists@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 449 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_exists(class eap_variable_data_c const *) + ??0eap_buf_chain_base_c@@QAE@W4eap_read_buffer_e@@PAVabs_eap_am_tools_c@@PBEK_N@Z @ 450 NONAME ; eap_buf_chain_base_c::eap_buf_chain_base_c(enum eap_read_buffer_e, class abs_eap_am_tools_c *, unsigned char const *, unsigned long, bool) + ?get_do_length_checks@eap_buf_chain_base_c@@QBE_NXZ @ 451 NONAME ; bool eap_buf_chain_base_c::get_do_length_checks(void) const + ?get_key_type@eapol_session_key_c@@QBE?AW4eapol_key_type_e@@XZ @ 452 NONAME ; enum eapol_key_type_e eapol_session_key_c::get_key_type(void) const + ??1eap_file_config_c@@UAE@XZ @ 453 NONAME ; eap_file_config_c::~eap_file_config_c(void) + ?trace_data@eap_am_tools_c@@UAEXPBDPBXK@Z @ 454 NONAME ; void eap_am_tools_c::trace_data(char const *, void const *, unsigned long) + ?get_key_length@eapol_RSNA_key_header_c@@QBEGXZ @ 455 NONAME ; unsigned short eapol_RSNA_key_header_c::get_key_length(void) const + ?object_increase_reference_count@eap_tlv_message_data_c@@QAEXXZ @ 456 NONAME ; void eap_tlv_message_data_c::object_increase_reference_count(void) + ?hash_final@eap_am_crypto_sha_256_c@@QAE?AW4eap_status_e@@PAXPAK@Z @ 457 NONAME ; enum eap_status_e eap_am_crypto_sha_256_c::hash_final(void *, unsigned long *) + ?set_use_eap_milli_second_timer@eap_am_tools_symbian_c@@UAEX_N@Z @ 458 NONAME ; void eap_am_tools_symbian_c::set_use_eap_milli_second_timer(bool) + ?restart_authentication@eap_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N@Z @ 459 NONAME ; enum eap_status_e eap_core_c::restart_authentication(class eap_am_network_id_c const *, bool) + ?get_is_valid_data@eap_am_network_id_c@@QBE_NXZ @ 460 NONAME ; bool eap_am_network_id_c::get_is_valid_data(void) const + ?set_is_manipulated@eap_buf_chain_base_c@@QAEXXZ @ 461 NONAME ; void eap_buf_chain_base_c::set_is_manipulated(void) + ?get_eapol_protocol_version@eapol_RC4_key_header_c@@QBE?AW4eapol_protocol_version_e@@XZ @ 462 NONAME ; enum eapol_protocol_version_e eapol_RC4_key_header_c::get_eapol_protocol_version(void) const + ?dh_cleanup@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 463 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::dh_cleanup(class eap_variable_data_c const *) + ?get_encryption_KEK@eapol_key_state_c@@AAEPAVeap_variable_data_c@@XZ @ 464 NONAME ; class eap_variable_data_c * eapol_key_state_c::get_encryption_KEK(void) + ?process_RSNA_key_descriptor@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 465 NONAME ; enum eap_status_e eapol_key_state_c::process_RSNA_key_descriptor(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long) + ?hash_cleanup@eap_am_crypto_sha_256_c@@AAE?AW4eap_status_e@@XZ @ 466 NONAME ; enum eap_status_e eap_am_crypto_sha_256_c::hash_cleanup(void) + ?get_data@eap_variable_data_c@@QBEPAEXZ @ 467 NONAME ; unsigned char * eap_variable_data_c::get_data(void) const + ?get_key_MIC@eapol_RSNA_key_header_c@@QBEPAEXZ @ 468 NONAME ; unsigned char * eapol_RSNA_key_header_c::get_key_MIC(void) const + ?get_mac_address@eap_rogue_ap_entry_c@@QBEPAEPAE@Z @ 469 NONAME ; unsigned char * eap_rogue_ap_entry_c::get_mac_address(unsigned char *) const + ?set_is_valid@eap_core_c@@UAEXXZ @ 470 NONAME ; void eap_core_c::set_is_valid(void) + ?get_sha1_block_size@eap_am_crypto_symbian_c@@UAEKPAVeap_variable_data_c@@@Z @ 471 NONAME ; unsigned long eap_am_crypto_symbian_c::get_sha1_block_size(class eap_variable_data_c *) + ?read_configure@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 472 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?process_4_way_handshake_message_1@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K@Z @ 473 NONAME ; enum eap_status_e eapol_key_state_c::process_4_way_handshake_message_1(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long) + ?get_eapol_header@eapol_ethernet_header_rd_c@@QBEPAEXZ @ 474 NONAME ; unsigned char * eapol_ethernet_header_rd_c::get_eapol_header(void) const + ?decrypt_data@eap_am_crypto_rc4_c@@QAE?AW4eap_status_e@@PBXPAXK@Z @ 475 NONAME ; enum eap_status_e eap_am_crypto_rc4_c::decrypt_data(void const *, void *, unsigned long) + ?eap_read_u16_t_network_order@@YAGPBXK@Z @ 476 NONAME ; unsigned short eap_read_u16_t_network_order(void const *, unsigned long) + ?initialize@eapol_key_state_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@2W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@32@Z @ 477 NONAME ; enum eap_status_e eapol_key_state_c::initialize(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, class eap_variable_data_c const *) + ?send_logoff@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 478 NONAME ; enum eap_status_e ethernet_core_c::send_logoff(class eap_am_network_id_c const *) + ?rsa_sign@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@10@Z @ 479 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rsa_sign(class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ?add_padding_bytes@crypto_aes_wrap_c@@QAE?AW4eap_status_e@@PAXK@Z @ 480 NONAME ; enum eap_status_e crypto_aes_wrap_c::add_padding_bytes(void *, unsigned long) + ?check_header@eapol_header_base_c@@UBE?AW4eap_status_e@@XZ @ 481 NONAME ; enum eap_status_e eapol_header_base_c::check_header(void) const + ?send_RC4_eapol_key_messages@eapol_key_state_c@@AAE?AW4eap_status_e@@XZ @ 482 NONAME ; enum eap_status_e eapol_key_state_c::send_RC4_eapol_key_messages(void) + ?send_eap_identity_response@eap_core_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeap_variable_data_c@@E@Z @ 483 NONAME ; enum eap_status_e eap_core_c::send_eap_identity_response(class eap_am_network_id_c const *, class eap_variable_data_c const *, unsigned char) + ?copy@eapol_key_state_c@@QAEPAV1@PBVeap_am_network_id_c@@@Z @ 484 NONAME ; class eapol_key_state_c * eapol_key_state_c::copy(class eap_am_network_id_c const *) + ?association@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 485 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::association(class eap_am_network_id_c const *) + ?get_timer_resolution_ms@eap_am_tools_symbian_c@@UAEKXZ @ 486 NONAME ; unsigned long eap_am_tools_symbian_c::get_timer_resolution_ms(void) + ?set_key_reply_counter@eapol_key_state_c@@AAEX_K@Z @ 487 NONAME ; void eapol_key_state_c::set_key_reply_counter(unsigned long long) + ?set_is_invalid@crypto_tls_md5_prf_c@@AAEXXZ @ 488 NONAME ; void crypto_tls_md5_prf_c::set_is_invalid(void) + ?reassociate@eapol_message_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@@Z @ 489 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::reassociate(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *) + ?octet_to_ascii_armor@eap_am_tools_c@@AAEEE@Z @ 490 NONAME ; unsigned char eap_am_tools_c::octet_to_ascii_armor(unsigned char) + ?set_is_valid@crypto_tls_md5_prf_c@@AAEXXZ @ 491 NONAME ; void crypto_tls_md5_prf_c::set_is_valid(void) + ?get_is_valid@eap_am_mutex_symbian_c@@UBE_NXZ @ 492 NONAME ; bool eap_am_mutex_symbian_c::get_is_valid(void) const + ??0crypto_ephemeral_diffie_hellman_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 493 NONAME ; crypto_ephemeral_diffie_hellman_c::crypto_ephemeral_diffie_hellman_c(class abs_eap_am_tools_c *) + ?get_source@eapol_ethernet_header_wr_c@@QAEPAEXZ @ 494 NONAME ; unsigned char * eapol_ethernet_header_wr_c::get_source(void) + ?set_key@eap_am_crypto_rc4_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 495 NONAME ; enum eap_status_e eap_am_crypto_rc4_c::set_key(class eap_variable_data_c const *) + ?set_timer@eap_session_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 496 NONAME ; enum eap_status_e eap_session_core_c::set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long) + ??1crypto_random_c@@UAE@XZ @ 497 NONAME ; crypto_random_c::~crypto_random_c(void) + ??1eap_am_mutex_symbian_c@@UAE@XZ @ 498 NONAME ; eap_am_mutex_symbian_c::~eap_am_mutex_symbian_c(void) + ?get_header_length@eapol_RSNA_key_header_c@@SAGXZ @ 499 NONAME ; unsigned short eapol_RSNA_key_header_c::get_header_length(void) + ?read_configure@eap_file_config_c@@QAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 500 NONAME ; enum eap_status_e eap_file_config_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?delete_abs_eap_am_tools_c@abs_eap_am_tools_c@@SAXPAV1@@Z @ 501 NONAME ; void abs_eap_am_tools_c::delete_abs_eap_am_tools_c(class abs_eap_am_tools_c *) + ?get_clock_ticks_of_second@eap_am_tools_symbian_c@@UAE_KXZ @ 502 NONAME ; unsigned long long eap_am_tools_symbian_c::get_clock_ticks_of_second(void) + ??0crypto_md4_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 503 NONAME ; crypto_md4_c::crypto_md4_c(class abs_eap_am_tools_c *) + ?set_packet_type@eapol_header_base_c@@QAEXW4eapol_packet_type_e@@@Z @ 504 NONAME ; void eapol_header_base_c::set_packet_type(enum eapol_packet_type_e) + ?get_header_length@eap_header_base_c@@SAKXZ @ 505 NONAME ; unsigned long eap_header_base_c::get_header_length(void) + ?packet_process@ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 506 NONAME ; enum eap_status_e ethernet_core_c::packet_process(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long) + ?rc4_cleanup@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 507 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rc4_cleanup(class eap_variable_data_c *) + ?get_is_valid@eapol_key_state_c@@QAE_NXZ @ 508 NONAME ; bool eapol_key_state_c::get_is_valid(void) + ??0eap_am_mutex_reference_c@@QAE@XZ @ 509 NONAME ; eap_am_mutex_reference_c::eap_am_mutex_reference_c(void) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBV?$eap_array_c@Vsimple_config_credential_c@@@@@Z @ 510 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(class eap_array_c const *) + ??Ieap_expanded_type_c@@QBEPBV0@XZ @ 511 NONAME ; class eap_expanded_type_c const * eap_expanded_type_c::operator&(void) const + ?get_expanded_type_field_length@eap_header_base_c@@SAKXZ @ 512 NONAME ; unsigned long eap_header_base_c::get_expanded_type_field_length(void) + ?sha1_cleanup@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 513 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::sha1_cleanup(class eap_variable_data_c *) + ??0eapol_key_state_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_eapol_key_state_c@@PAVabs_eapol_core_c@@_NPBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@6W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@76@Z @ 514 NONAME ; eapol_key_state_c::eapol_key_state_c(class abs_eap_am_tools_c *, class abs_eapol_key_state_c *, class abs_eapol_core_c *, bool, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, class eap_variable_data_c const *) + ?dsa_sign@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@10@Z @ 515 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::dsa_sign(class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ?get_retransmission_counter@eap_core_retransmission_c@@QBEKXZ @ 516 NONAME ; unsigned long eap_core_retransmission_c::get_retransmission_counter(void) const + ?get_header_length@eapol_ethernet_header_base_c@@SAGXZ @ 517 NONAME ; unsigned short eapol_ethernet_header_base_c::get_header_length(void) + ?start_preauthentication@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 518 NONAME ; enum eap_status_e eapol_wlan_authentication_c::start_preauthentication(class eap_am_network_id_c const *) + ?get_key_information_request@eapol_RSNA_key_header_c@@QBE_NXZ @ 519 NONAME ; bool eapol_RSNA_key_header_c::get_key_information_request(void) const + ?start_reassociation@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@@Z @ 520 NONAME ; enum eap_status_e eapol_core_c::start_reassociation(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *) + ?eap_write_u64_t_little_endian_order@@YA?AW4eap_status_e@@PAXK_K@Z @ 521 NONAME ; enum eap_status_e eap_write_u64_t_little_endian_order(void *, unsigned long, unsigned long long) + ?set_eap_type@eap_master_session_key_c@@QAEXVeap_expanded_type_c@@@Z @ 522 NONAME ; void eap_master_session_key_c::set_eap_type(class eap_expanded_type_c) + ?check_guards@eap_buf_chain_base_c@@QBE_NXZ @ 523 NONAME ; bool eap_buf_chain_base_c::check_guards(void) const + ??1eap_am_tools_symbian_c@@UAE@XZ @ 524 NONAME ; eap_am_tools_symbian_c::~eap_am_tools_symbian_c(void) + ?tkip_mic_failure@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_NW4eapol_tkip_mic_failure_type_e@eapol_RSNA_key_header_c@@@Z @ 525 NONAME ; enum eap_status_e eapol_wlan_authentication_c::tkip_mic_failure(class eap_am_network_id_c const *, bool, enum eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e) + ?get_header_offset@ethernet_core_c@@UAEKPAK0@Z @ 526 NONAME ; unsigned long ethernet_core_c::get_header_offset(unsigned long *, unsigned long *) + ?set_type@eap_tlv_header_c@@QAE?AW4eap_status_e@@K@Z @ 527 NONAME ; enum eap_status_e eap_tlv_header_c::set_type(unsigned long) + ?set_Authentication_Type@simple_config_credential_c@@QAEXW4simple_config_Authentication_Type_e@@@Z @ 528 NONAME ; void simple_config_credential_c::set_Authentication_Type(enum simple_config_Authentication_Type_e) + ?increment_authentication_counter@eapol_wlan_authentication_c@@QAEXXZ @ 529 NONAME ; void eapol_wlan_authentication_c::increment_authentication_counter(void) + ?get_is_valid@crypto_tls_prf_c@@QAE_NXZ @ 530 NONAME ; bool crypto_tls_prf_c::get_is_valid(void) + ?get_unicast_cipher_suite_RSNA_IE@eapol_key_state_c@@AAEPAVeap_variable_data_c@@XZ @ 531 NONAME ; class eap_variable_data_c * eapol_key_state_c::get_unicast_cipher_suite_RSNA_IE(void) + ??0eap_rogue_ap_entry_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 532 NONAME ; eap_rogue_ap_entry_c::eap_rogue_ap_entry_c(class abs_eap_am_tools_c *) + ??0eap_tlv_message_data_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 533 NONAME ; eap_tlv_message_data_c::eap_tlv_message_data_c(class abs_eap_am_tools_c *) + ?force_inheritance@eap_buf_chain_rd_c@@EAEXXZ @ 534 NONAME ; void eap_buf_chain_rd_c::force_inheritance(void) + ?get_is_valid@eapol_core_c@@UAE_NXZ @ 535 NONAME ; bool eapol_core_c::get_is_valid(void) + ?get_ethernet_header@eap_buf_chain_rd_c@@QBEPBEXZ @ 536 NONAME ; unsigned char const * eap_buf_chain_rd_c::get_ethernet_header(void) const + ?get_destination_id@eap_am_network_id_c@@QBEPBVeap_variable_data_c@@XZ @ 537 NONAME ; class eap_variable_data_c const * eap_am_network_id_c::get_destination_id(void) const + ??0eap_am_network_id_c@@QAE@PAVabs_eap_am_tools_c@@PBV0@@Z @ 538 NONAME ; eap_am_network_id_c::eap_am_network_id_c(class abs_eap_am_tools_c *, class eap_am_network_id_c const *) + ?synchronous_remove_eap_session@eap_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 539 NONAME ; enum eap_status_e eap_session_core_c::synchronous_remove_eap_session(class eap_am_network_id_c const *) + ??1eapol_RC4_key_header_c@@UAE@XZ @ 540 NONAME ; eapol_RC4_key_header_c::~eapol_RC4_key_header_c(void) + ?eap_acknowledge@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 541 NONAME ; enum eap_status_e ethernet_core_c::eap_acknowledge(class eap_am_network_id_c const *) + ?save_simple_config_session@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@W4simple_config_state_e@@PBV?$eap_array_c@Vsimple_config_credential_c@@@@PBVeap_variable_data_c@@W4simple_config_Device_Password_ID_e@@PBVsimple_config_payloads_c@@@Z @ 542 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::save_simple_config_session(enum simple_config_state_e, class eap_array_c const *, class eap_variable_data_c const *, enum simple_config_Device_Password_ID_e, class simple_config_payloads_c const *) + ?mutex_leave@eap_am_mutex_symbian_c@@UAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@@Z @ 543 NONAME ; enum eap_status_e eap_am_mutex_symbian_c::mutex_leave(class abs_eap_am_tools_c *) + ??0crypto_cbc_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_crypto_block_algorithm_c@@_N@Z @ 544 NONAME ; crypto_cbc_c::crypto_cbc_c(class abs_eap_am_tools_c *, class abs_crypto_block_algorithm_c *, bool) + ?number_string_to_u32@eap_am_tools_c@@UAE?AW4eap_status_e@@PBEKPAK@Z @ 545 NONAME ; enum eap_status_e eap_am_tools_c::number_string_to_u32(unsigned char const *, unsigned long, unsigned long *) + ?remove_eapol_key_state@eapol_core_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 546 NONAME ; enum eap_status_e eapol_core_c::remove_eapol_key_state(class eap_am_network_id_c const *) + ?get_type_string@eapol_header_base_c@@QBEPBDXZ @ 547 NONAME ; char const * eapol_header_base_c::get_type_string(void) const + ?get_sha1_digest_length@eap_am_crypto_symbian_c@@UAEKPAVeap_variable_data_c@@@Z @ 548 NONAME ; unsigned long eap_am_crypto_symbian_c::get_sha1_digest_length(class eap_variable_data_c *) + ??1eap_buf_chain_base_c@@UAE@XZ @ 549 NONAME ; eap_buf_chain_base_c::~eap_buf_chain_base_c(void) + ??1eap_am_tools_c@@UAE@XZ @ 550 NONAME ; eap_am_tools_c::~eap_am_tools_c(void) + ?resend_packet@eap_core_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKKK@Z @ 551 NONAME ; enum eap_status_e eap_core_c::resend_packet(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long, unsigned long) + ?create_state@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@@Z @ 552 NONAME ; enum eap_status_e ethernet_core_c::create_state(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e) + ?process_message_type_error@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 553 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::process_message_type_error(class eap_array_c const *) + ?get_wlan_configuration@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 554 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::get_wlan_configuration(class eap_variable_data_c *) + ?get_digest_length@crypto_hmac_c@@UAEKXZ @ 555 NONAME ; unsigned long crypto_hmac_c::get_digest_length(void) + ??0eap_buf_chain_rd_c@@QAE@W4eap_read_buffer_e@@PAVabs_eap_am_tools_c@@PBEK_N@Z @ 556 NONAME ; eap_buf_chain_rd_c::eap_buf_chain_rd_c(enum eap_read_buffer_e, class abs_eap_am_tools_c *, unsigned char const *, unsigned long, bool) + ?unload_module@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 557 NONAME ; enum eap_status_e eapol_wlan_authentication_c::unload_module(class eap_expanded_type_c) + ?get_eap_type_list@eapol_core_c@@UAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_expanded_type_c@@@@@Z @ 558 NONAME ; enum eap_status_e eapol_core_c::get_eap_type_list(class eap_array_c *) + ?eap_sha1_dss_G_function@eap_am_crypto_sha1_c@@QAE?AW4eap_status_e@@PBXKPAXPAK@Z @ 559 NONAME ; enum eap_status_e eap_am_crypto_sha1_c::eap_sha1_dss_G_function(void const *, unsigned long, void *, unsigned long *) + ?send_eap_nak_response@eap_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@EPBV?$eap_array_c@Veap_expanded_type_c@@@@@Z @ 560 NONAME ; enum eap_status_e eap_core_c::send_eap_nak_response(class eap_am_network_id_c const *, unsigned char, class eap_array_c const *) + ?get_reference_count@eap_am_mutex_reference_c@@QAEKXZ @ 561 NONAME ; unsigned long eap_am_mutex_reference_c::get_reference_count(void) + ??0eapol_RC4_key_header_c@@QAE@PAVabs_eap_am_tools_c@@PAXK@Z @ 562 NONAME ; eapol_RC4_key_header_c::eapol_RC4_key_header_c(class abs_eap_am_tools_c *, void *, unsigned long) + ?set_key_length@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@G@Z @ 563 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_length(unsigned short) + ?complete_reassociation@ethernet_core_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@3W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@4@Z @ 564 NONAME ; enum eap_status_e ethernet_core_c::complete_reassociation(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e) + ?rsa_init@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 565 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rsa_init(class eap_variable_data_c *) + ?convert_eap_type_to_u32_t@@YAKVeap_expanded_type_c@@@Z @ 566 NONAME ; unsigned long convert_eap_type_to_u32_t(class eap_expanded_type_c) + ?set_buffer@eap_variable_data_c@@QAE?AW4eap_status_e@@PAXK_N1@Z @ 567 NONAME ; enum eap_status_e eap_variable_data_c::set_buffer(void *, unsigned long, bool, bool) + ?set_s_nonce@eapol_key_state_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 568 NONAME ; enum eap_status_e eapol_key_state_c::set_s_nonce(class eap_variable_data_c const *) + ?update_non_aligned@crypto_cbc_c@@UAE?AW4eap_status_e@@PAXK@Z @ 569 NONAME ; enum eap_status_e crypto_cbc_c::update_non_aligned(void *, unsigned long) + ??1eapol_session_key_c@@UAE@XZ @ 570 NONAME ; eapol_session_key_c::~eapol_session_key_c(void) + ?file_close@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@XZ @ 571 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_close(void) + ?tls_prf_init@crypto_tls_prf_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@00@Z @ 572 NONAME ; enum eap_status_e crypto_tls_prf_c::tls_prf_init(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ?t_prf_output@crypto_eap_fast_hmac_sha1_prf_c@@QAE?AW4eap_status_e@@PAXG@Z @ 573 NONAME ; enum eap_status_e crypto_eap_fast_hmac_sha1_prf_c::t_prf_output(void *, unsigned short) + ?set_eapol_packet_type@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@W4eapol_packet_type_e@@@Z @ 574 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_eapol_packet_type(enum eapol_packet_type_e) + ?hash_nt_password_hash@crypto_nt_hash_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@PAV3@K@Z @ 575 NONAME ; enum eap_status_e crypto_nt_hash_c::hash_nt_password_hash(class eap_variable_data_c const *, class eap_variable_data_c *, unsigned long) + ?get_key_data@eapol_RSNA_key_header_c@@QBEPAEK@Z @ 576 NONAME ; unsigned char * eapol_RSNA_key_header_c::get_key_data(unsigned long) const + ?get_encrypts@crypto_cbc_c@@UAE_NXZ @ 577 NONAME ; bool crypto_cbc_c::get_encrypts(void) + ?get_is_valid_data@network_key_and_index_c@@QAE_NXZ @ 578 NONAME ; bool network_key_and_index_c::get_is_valid_data(void) + ??1eap_type_selection_c@@UAE@XZ @ 579 NONAME ; eap_type_selection_c::~eap_type_selection_c(void) + ??0eap_am_mutex_base_c@@QAE@PBV0@@Z @ 580 NONAME ; eap_am_mutex_base_c::eap_am_mutex_base_c(class eap_am_mutex_base_c const *) + ?configure@eapol_message_wlan_authentication_c@@QAE?AW4eap_status_e@@KKK@Z @ 581 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::configure(unsigned long, unsigned long, unsigned long) + ??1eap_rogue_ap_entry_c@@UAE@XZ @ 582 NONAME ; eap_rogue_ap_entry_c::~eap_rogue_ap_entry_c(void) + ??1eapol_am_wlan_authentication_symbian_c@@UAE@XZ @ 583 NONAME ; eapol_am_wlan_authentication_symbian_c::~eapol_am_wlan_authentication_symbian_c(void) + ?get_is_valid_data@eap_variable_data_c@@QBE_NXZ @ 584 NONAME ; bool eap_variable_data_c::get_is_valid_data(void) const + ?reset_header@eapol_ethernet_header_wr_c@@QAEXW4eapol_ethernet_type_e@@G@Z @ 585 NONAME ; void eapol_ethernet_header_wr_c::reset_header(enum eapol_ethernet_type_e, unsigned short) + ??1crypto_sha1_c@@UAE@XZ @ 586 NONAME ; crypto_sha1_c::~crypto_sha1_c(void) + ?check_header@eap_header_base_c@@UBE?AW4eap_status_e@@XZ @ 587 NONAME ; enum eap_status_e eap_header_base_c::check_header(void) const + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@W4eapol_tlv_message_type_function_e@@@Z @ 588 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(enum eapol_tlv_message_type_function_e) + ?set_type@eap_header_base_c@@QAE?AW4eap_status_e@@Veap_expanded_type_c@@_N@Z @ 589 NONAME ; enum eap_status_e eap_header_base_c::set_type(class eap_expanded_type_c, bool) + ?get_is_valid@eap_buf_chain_base_c@@QBE_NXZ @ 590 NONAME ; bool eap_buf_chain_base_c::get_is_valid(void) const + ?process_4_way_handshake_message_3_payloads_a@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@KPA_N@Z @ 591 NONAME ; enum eap_status_e eapol_key_state_c::process_4_way_handshake_message_3_payloads_a(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long, bool *) + ?copy@eap_variable_data_c@@QBEPAV1@XZ @ 592 NONAME ; class eap_variable_data_c * eap_variable_data_c::copy(void) const + ?convert_bytes_to_hex_ascii@eap_am_tools_c@@UAE?AW4eap_status_e@@PBXKPAVeap_variable_data_c@@@Z @ 593 NONAME ; enum eap_status_e eap_am_tools_c::convert_bytes_to_hex_ascii(void const *, unsigned long, class eap_variable_data_c *) + ?set_is_invalid@crypto_sha_256_c@@AAEXXZ @ 594 NONAME ; void crypto_sha_256_c::set_is_invalid(void) + ?sprint@eap_am_tools_symbian_c@@AAAXAAVTDes16@@PBDZZ @ 595 NONAME ; void eap_am_tools_symbian_c::sprint(class TDes16 &, char const *, ...) + ?init_retransmission@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKW4eap_code_value_e@@EVeap_expanded_type_c@@@Z @ 596 NONAME ; enum eap_status_e eapol_key_state_c::init_retransmission(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, enum eap_code_value_e, unsigned char, class eap_expanded_type_c) + ??0eap_am_network_id_c@@QAE@PAVabs_eap_am_tools_c@@PBXK1KG_N2@Z @ 597 NONAME ; eap_am_network_id_c::eap_am_network_id_c(class abs_eap_am_tools_c *, void const *, unsigned long, void const *, unsigned long, unsigned short, bool, bool) + ??0eap_header_base_c@@QAE@PAVabs_eap_am_tools_c@@PAXK@Z @ 598 NONAME ; eap_header_base_c::eap_header_base_c(class abs_eap_am_tools_c *, void *, unsigned long) + ?config_strlen@eap_am_tools_symbian_c@@UAEKPBD@Z @ 599 NONAME ; unsigned long eap_am_tools_symbian_c::config_strlen(char const *) + ?get_authenticator_MAC_address@eapol_key_state_c@@AAEPAVeap_variable_data_c@@XZ @ 600 NONAME ; class eap_variable_data_c * eapol_key_state_c::get_authenticator_MAC_address(void) + ?asynchronous_start_authentication@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N@Z @ 601 NONAME ; enum eap_status_e eapol_core_c::asynchronous_start_authentication(class eap_am_network_id_c const *, bool) + ?encrypt_block@crypto_aes_c@@UAE?AW4eap_status_e@@PBXPAXK@Z @ 602 NONAME ; enum eap_status_e crypto_aes_c::encrypt_block(void const *, void *, unsigned long) + ?get_rand_bytes@crypto_random_c@@QAE?AW4eap_status_e@@PAXK@Z @ 603 NONAME ; enum eap_status_e crypto_random_c::get_rand_bytes(void *, unsigned long) + ?find_rvalue@eap_file_config_c@@AAE?AW4eap_status_e@@PBVeap_variable_data_c@@PA_NPAV3@2@Z @ 604 NONAME ; enum eap_status_e eap_file_config_c::find_rvalue(class eap_variable_data_c const *, bool *, class eap_variable_data_c *, class eap_variable_data_c *) + ?select_minimum@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAPBV3@1@Z @ 605 NONAME ; enum eap_status_e eapol_key_state_c::select_minimum(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const * *, class eap_variable_data_c const * *) + ?write_configure@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 606 NONAME ; enum eap_status_e eapol_wlan_authentication_c::write_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?get_key_information_key_MIC@eapol_RSNA_key_header_c@@QBE_NXZ @ 607 NONAME ; bool eapol_RSNA_key_header_c::get_key_information_key_MIC(void) const + ?add_data@eap_variable_data_c@@QAE?AW4eap_status_e@@PBXK@Z @ 608 NONAME ; enum eap_status_e eap_variable_data_c::add_data(void const *, unsigned long) + ?get_destination@eap_am_network_id_c@@QBEPBEXZ @ 609 NONAME ; unsigned char const * eap_am_network_id_c::get_destination(void) const + ?get_data_offset@eap_header_base_c@@QBEPAEKK@Z @ 610 NONAME ; unsigned char * eap_header_base_c::get_data_offset(unsigned long, unsigned long) const + ?disassociation@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 611 NONAME ; enum eap_status_e ethernet_core_c::disassociation(class eap_am_network_id_c const *) + ??0eap_state_notification_c@@QAE@PAVabs_eap_am_tools_c@@PBVeap_am_network_id_c@@_NW4eap_state_notification_generic_e@@W4eap_protocol_layer_e@@KKKE2@Z @ 612 NONAME ; eap_state_notification_c::eap_state_notification_c(class abs_eap_am_tools_c *, class eap_am_network_id_c const *, bool, enum eap_state_notification_generic_e, enum eap_protocol_layer_e, unsigned long, unsigned long, unsigned long, unsigned char, bool) + ?get_thread_stopped@eap_am_tools_c@@UAE_NXZ @ 613 NONAME ; bool eap_am_tools_c::get_thread_stopped(void) + ??1eap_tlv_header_c@@UAE@XZ @ 614 NONAME ; eap_tlv_header_c::~eap_tlv_header_c(void) + ??0eapol_key_state_string_c@@QAE@XZ @ 615 NONAME ; eapol_key_state_string_c::eapol_key_state_string_c(void) + ?getenv@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@PAV3@@Z @ 616 NONAME ; enum eap_status_e eap_am_tools_symbian_c::getenv(class eap_variable_data_c const *, class eap_variable_data_c *) + ?eap_read_u64_t_network_order@@YA_KPBXK@Z @ 617 NONAME ; unsigned long long eap_read_u64_t_network_order(void const *, unsigned long) + ?complete_association@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@PBVeap_variable_data_c@@2W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@3@Z @ 618 NONAME ; enum eap_status_e eapol_wlan_authentication_c::complete_association(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e) + ?rc4_encrypt@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@PBXPAXK@Z @ 619 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rc4_encrypt(class eap_variable_data_c const *, void const *, void *, unsigned long) + ??0eapol_key_state_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_eapol_key_state_c@@PAVabs_eapol_core_c@@_NPBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@@Z @ 620 NONAME ; eapol_key_state_c::eapol_key_state_c(class abs_eap_am_tools_c *, class abs_eapol_key_state_c *, class abs_eapol_core_c *, bool, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e) + ?aes_set_decryption_key@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEK@Z @ 621 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::aes_set_decryption_key(class eap_variable_data_c *, unsigned char const *, unsigned long) + ?timer_expired@eap_session_core_c@@UAE?AW4eap_status_e@@KPAX@Z @ 622 NONAME ; enum eap_status_e eap_session_core_c::timer_expired(unsigned long, void *) + ??0eap_buf_chain_wr_c@@QAE@W4eap_write_buffer_e@@PAVabs_eap_am_tools_c@@@Z @ 623 NONAME ; eap_buf_chain_wr_c::eap_buf_chain_wr_c(enum eap_write_buffer_e, class abs_eap_am_tools_c *) + ?get_rand_bytes@crypto_random_c@@QAE?AW4eap_status_e@@PAVeap_variable_data_c@@K@Z @ 624 NONAME ; enum eap_status_e crypto_random_c::get_rand_bytes(class eap_variable_data_c *, unsigned long) + ?get_is_valid@crypto_tls_base_prf_c@@QAE_NXZ @ 625 NONAME ; bool crypto_tls_base_prf_c::get_is_valid(void) + ?set_activate_trace_on_error@eap_am_tools_c@@UAEXXZ @ 626 NONAME ; void eap_am_tools_c::set_activate_trace_on_error(void) + ?get_eap_identifier@eap_state_notification_c@@UBEEXZ @ 627 NONAME ; unsigned char eap_state_notification_c::get_eap_identifier(void) const + ?check_is_valid_eap_type@eapol_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 628 NONAME ; enum eap_status_e eapol_core_c::check_is_valid_eap_type(class eap_expanded_type_c) + ?set_decryption_key@crypto_aes_wrap_c@@QAE?AW4eap_status_e@@PBXK@Z @ 629 NONAME ; enum eap_status_e crypto_aes_wrap_c::set_decryption_key(void const *, unsigned long) + ?association@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@2W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@32@Z @ 630 NONAME ; enum eap_status_e ethernet_core_c::association(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, class eap_variable_data_c const *) + ?copy@eap_type_selection_c@@QBEPAV1@XZ @ 631 NONAME ; class eap_type_selection_c * eap_type_selection_c::copy(void) const + ?create_upper_stack@eapol_wlan_authentication_c@@AAE?AW4eap_status_e@@XZ @ 632 NONAME ; enum eap_status_e eapol_wlan_authentication_c::create_upper_stack(void) + ??0crypto_kd_hmac_sha256_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 633 NONAME ; crypto_kd_hmac_sha256_c::crypto_kd_hmac_sha256_c(class abs_eap_am_tools_c *) + ?timer_delete_data@eapol_message_wlan_authentication_c@@UAE?AW4eap_status_e@@KPAX@Z @ 634 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::timer_delete_data(unsigned long, void *) + ?sign@crypto_rsa_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@@Z @ 635 NONAME ; enum eap_status_e crypto_rsa_c::sign(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ?get_key@eapol_session_key_c@@QBEPBVeap_variable_data_c@@XZ @ 636 NONAME ; class eap_variable_data_c const * eapol_session_key_c::get_key(void) const + ?get_eapol_packet_body_length@eapol_RC4_key_header_c@@QBEGXZ @ 637 NONAME ; unsigned short eapol_RC4_key_header_c::get_eapol_packet_body_length(void) const + ?get_header_buffer@eap_general_header_base_c@@QBEPAEK@Z @ 638 NONAME ; unsigned char * eap_general_header_base_c::get_header_buffer(unsigned long) const + ??0abs_eap_am_memory_store_data_c@@QAE@XZ @ 639 NONAME ; abs_eap_am_memory_store_data_c::abs_eap_am_memory_store_data_c(void) + ??1abs_crypto_hmac_algorithm_c@@UAE@XZ @ 640 NONAME ; abs_crypto_hmac_algorithm_c::~abs_crypto_hmac_algorithm_c(void) + ??1crypto_tls_sha1_prf_c@@UAE@XZ @ 641 NONAME ; crypto_tls_sha1_prf_c::~crypto_tls_sha1_prf_c(void) + ?get_type_string@eap_header_base_c@@QBEPBDXZ @ 642 NONAME ; char const * eap_header_base_c::get_type_string(void) const + ?get_eapol_key_handshake_type_string@eapol_key_state_string_c@@QBEPBDW4eapol_key_handshake_type_e@@@Z @ 643 NONAME ; char const * eapol_key_state_string_c::get_eapol_key_handshake_type_string(enum eapol_key_handshake_type_e) const + ?verify_key_mic@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeapol_RSNA_key_header_c@@PBVeap_variable_data_c@@@Z @ 644 NONAME ; enum eap_status_e eapol_key_state_c::verify_key_mic(class eapol_RSNA_key_header_c *, class eap_variable_data_c const *) + ?get_proposed_eap_type@eap_core_nak_info_c@@QBE?AVeap_expanded_type_c@@XZ @ 645 NONAME ; class eap_expanded_type_c eap_core_nak_info_c::get_proposed_eap_type(void) const + ?save_simple_config_session@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@W4simple_config_state_e@@PBV?$eap_array_c@Vsimple_config_credential_c@@@@PBVeap_variable_data_c@@W4simple_config_Device_Password_ID_e@@PBVsimple_config_payloads_c@@@Z @ 646 NONAME ; enum eap_status_e eapol_wlan_authentication_c::save_simple_config_session(enum simple_config_state_e, class eap_array_c const *, class eap_variable_data_c const *, enum simple_config_Device_Password_ID_e, class simple_config_payloads_c const *) + ?get_is_valid@crypto_hmac_c@@UAE_NXZ @ 647 NONAME ; bool crypto_hmac_c::get_is_valid(void) + ?get_encrypt@eap_buf_chain_base_c@@QBE_NXZ @ 648 NONAME ; bool eap_buf_chain_base_c::get_encrypt(void) const + ?is_ietf_type@eap_expanded_type_c@@SA_NV1@@Z @ 649 NONAME ; bool eap_expanded_type_c::is_ietf_type(class eap_expanded_type_c) + ?add_data_to_offset@eap_buf_chain_base_c@@QAE?AW4eap_status_e@@KPBXK@Z @ 650 NONAME ; enum eap_status_e eap_buf_chain_base_c::add_data_to_offset(unsigned long, void const *, unsigned long) + ?derive_PTK@eapol_key_state_c@@AAE?AW4eap_status_e@@XZ @ 651 NONAME ; enum eap_status_e eapol_key_state_c::derive_PTK(void) + ?timer_expired@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@KPAX@Z @ 652 NONAME ; enum eap_status_e eapol_wlan_authentication_c::timer_expired(unsigned long, void *) + ?init@crypto_rsa_c@@QAE?AW4eap_status_e@@XZ @ 653 NONAME ; enum eap_status_e crypto_rsa_c::init(void) + ?set_session_timeout@eap_core_c@@UAE?AW4eap_status_e@@K@Z @ 654 NONAME ; enum eap_status_e eap_core_c::set_session_timeout(unsigned long) + ?get_payload_size@eapol_handle_tlv_message_data_c@@QBEKPBV?$eap_array_c@Vnetwork_key_and_index_c@@@@@Z @ 655 NONAME ; unsigned long eapol_handle_tlv_message_data_c::get_payload_size(class eap_array_c const *) const + ?compare@eap_variable_data_c@@QBEJPBV1@@Z @ 656 NONAME ; long eap_variable_data_c::compare(class eap_variable_data_c const *) const + ?set_encryption_key@crypto_cbc_c@@UAE?AW4eap_status_e@@PBXK0K@Z @ 657 NONAME ; enum eap_status_e crypto_cbc_c::set_encryption_key(void const *, unsigned long, void const *, unsigned long) + ?copy_leap_password@eap_master_session_key_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 658 NONAME ; enum eap_status_e eap_master_session_key_c::copy_leap_password(class eap_variable_data_c const *) + ?zero_key_RSC@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@@Z @ 659 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::zero_key_RSC(class abs_eap_am_tools_c *) + ?verify@crypto_dsa_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@00000@Z @ 660 NONAME ; enum eap_status_e crypto_dsa_c::verify(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ?timer_sleep@eap_am_tools_symbian_c@@UAEXK@Z @ 661 NONAME ; void eap_am_tools_symbian_c::timer_sleep(unsigned long) + ?process_4_way_handshake_message_2_payloads@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K@Z @ 662 NONAME ; enum eap_status_e eapol_key_state_c::process_4_way_handshake_message_2_payloads(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long) + ??0crypto_aes_wrap_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 663 NONAME ; crypto_aes_wrap_c::crypto_aes_wrap_c(class abs_eap_am_tools_c *) + ?get_reference@eap_am_mutex_base_c@@QBEPAVeap_am_mutex_reference_c@@XZ @ 664 NONAME ; class eap_am_mutex_reference_c * eap_am_mutex_base_c::get_reference(void) const + ??1eap_buf_chain_wr_c@@UAE@XZ @ 665 NONAME ; eap_buf_chain_wr_c::~eap_buf_chain_wr_c(void) + ?get_expanded_vendor_type_offset@eap_header_base_c@@SAKXZ @ 666 NONAME ; unsigned long eap_header_base_c::get_expanded_vendor_type_offset(void) + ?unset_marked_removed@eapol_key_state_c@@QAEXXZ @ 667 NONAME ; void eapol_key_state_c::unset_marked_removed(void) + ?md5_cleanup@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 668 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::md5_cleanup(class eap_variable_data_c *) + ?add_RSN_GTK_payload@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeapol_RSNA_key_header_c@@PAVeap_variable_data_c@@PAK@Z @ 669 NONAME ; enum eap_status_e eapol_key_state_c::add_RSN_GTK_payload(class eapol_RSNA_key_header_c const *, class eap_variable_data_c *, unsigned long *) + ?encrypt_with_private_key@crypto_rsa_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@@Z @ 670 NONAME ; enum eap_status_e crypto_rsa_c::encrypt_with_private_key(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ?set_is_invalid@eap_am_crypto_md4_c@@AAEXXZ @ 671 NONAME ; void eap_am_crypto_md4_c::set_is_invalid(void) + ?get_expanded_type_data@eap_expanded_type_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@PAVeap_variable_data_c@@@Z @ 672 NONAME ; enum eap_status_e eap_expanded_type_c::get_expanded_type_data(class abs_eap_am_tools_c *, class eap_variable_data_c *) + ?get_data@eap_buf_chain_rd_c@@QBEPBEK@Z @ 673 NONAME ; unsigned char const * eap_buf_chain_rd_c::get_data(unsigned long) const + ?reset@eapol_key_state_c@@QAE?AW4eap_status_e@@XZ @ 674 NONAME ; enum eap_status_e eapol_key_state_c::reset(void) + ?get_partner@eap_session_core_c@@QAEPAVabs_eap_core_c@@XZ @ 675 NONAME ; class abs_eap_core_c * eap_session_core_c::get_partner(void) + ?get_type@eap_static_expanded_type_c@@QBEABVeap_expanded_type_c@@XZ @ 676 NONAME ; class eap_expanded_type_c const & eap_static_expanded_type_c::get_type(void) const + ?configure@eap_file_config_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_file_input_c@@@Z @ 677 NONAME ; enum eap_status_e eap_file_config_c::configure(class abs_eap_am_file_input_c *) + ?copy@eap_am_crypto_md4_c@@QAEPAV1@XZ @ 678 NONAME ; class eap_am_crypto_md4_c * eap_am_crypto_md4_c::copy(void) + ?set_rogue_reason@eap_rogue_ap_entry_c@@QAEXW4eap_rogue_ap_reason_e@@@Z @ 679 NONAME ; void eap_rogue_ap_entry_c::set_rogue_reason(enum eap_rogue_ap_reason_e) + ?get_data_length@eap_buf_chain_base_c@@QBEKXZ @ 680 NONAME ; unsigned long eap_buf_chain_base_c::get_data_length(void) const + ??1eap_header_string_c@@UAE@XZ @ 681 NONAME ; eap_header_string_c::~eap_header_string_c(void) + ?decrypt_block_3des_ede@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEPAEK@Z @ 682 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::decrypt_block_3des_ede(class eap_variable_data_c *, unsigned char const *, unsigned char *, unsigned long) + ?get_type_data@eap_expanded_type_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@PAW4eap_type_ietf_values_e@@@Z @ 683 NONAME ; enum eap_status_e eap_expanded_type_c::get_type_data(class abs_eap_am_tools_c *, enum eap_type_ietf_values_e *) + ?get_type_data@eap_expanded_type_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@PAV1@@Z @ 684 NONAME ; enum eap_status_e eap_expanded_type_c::get_type_data(class abs_eap_am_tools_c *, class eap_expanded_type_c *) + ??1crypto_nt_hash_c@@UAE@XZ @ 685 NONAME ; crypto_nt_hash_c::~crypto_nt_hash_c(void) + ?tls_prf_cleanup@crypto_tls_sha1_prf_c@@QAE?AW4eap_status_e@@XZ @ 686 NONAME ; enum eap_status_e crypto_tls_sha1_prf_c::tls_prf_cleanup(void) + ?get_data_offset@eap_buf_chain_base_c@@QBEPAEKK@Z @ 687 NONAME ; unsigned char * eap_buf_chain_base_c::get_data_offset(unsigned long, unsigned long) const + ?set_copy_of_buffer@eap_variable_data_c@@QAE?AW4eap_status_e@@PBXK@Z @ 688 NONAME ; enum eap_status_e eap_variable_data_c::set_copy_of_buffer(void const *, unsigned long) + ?get_is_WPA@eapol_key_state_c@@AAE_NXZ @ 689 NONAME ; bool eapol_key_state_c::get_is_WPA(void) + ?set_is_invalid@crypto_tls_prf_c@@AAEXXZ @ 690 NONAME ; void crypto_tls_prf_c::set_is_invalid(void) + ?check_header@eapol_ethernet_header_base_c@@UBE?AW4eap_status_e@@XZ @ 691 NONAME ; enum eap_status_e eapol_ethernet_header_base_c::check_header(void) const + ?timer_delete_data@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@KPAX@Z @ 692 NONAME ; enum eap_status_e eapol_wlan_authentication_c::timer_delete_data(unsigned long, void *) + ?restore_bytes_from_ascii_armor@eap_am_tools_c@@UAE?AW4eap_status_e@@PBEKPAEPAK@Z @ 693 NONAME ; enum eap_status_e eap_am_tools_c::restore_bytes_from_ascii_armor(unsigned char const *, unsigned long, unsigned char *, unsigned long *) + ??1eap_master_session_key_c@@UAE@XZ @ 694 NONAME ; eap_master_session_key_c::~eap_master_session_key_c(void) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 695 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(class eap_variable_data_c const *) + ?allocate_message_data_buffer@eap_tlv_message_data_c@@QAE?AW4eap_status_e@@K@Z @ 696 NONAME ; enum eap_status_e eap_tlv_message_data_c::allocate_message_data_buffer(unsigned long) + ??0eapol_ethernet_header_rd_c@@QAE@PAVabs_eap_am_tools_c@@PBEK@Z @ 697 NONAME ; eapol_ethernet_header_rd_c::eapol_ethernet_header_rd_c(class abs_eap_am_tools_c *, unsigned char const *, unsigned long) + ??0eap_network_id_selector_c@@QAE@PAVabs_eap_am_tools_c@@PBVeap_am_network_id_c@@@Z @ 698 NONAME ; eap_network_id_selector_c::eap_network_id_selector_c(class abs_eap_am_tools_c *, class eap_am_network_id_c const *) + ?load_type@ethernet_core_c@@QAEPAVeap_base_type_c@@Veap_expanded_type_c@@@Z @ 699 NONAME ; class eap_base_type_c * ethernet_core_c::load_type(class eap_expanded_type_c) + ?get_block_size@eap_am_crypto_md4_c@@QAEKXZ @ 700 NONAME ; unsigned long eap_am_crypto_md4_c::get_block_size(void) + ??0eap_am_crypto_rc4_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 701 NONAME ; eap_am_crypto_rc4_c::eap_am_crypto_rc4_c(class abs_eap_am_tools_c *) + ??0eap_buf_chain_wr_c@@QAE@W4eap_write_buffer_e@@PAVabs_eap_am_tools_c@@K@Z @ 702 NONAME ; eap_buf_chain_wr_c::eap_buf_chain_wr_c(enum eap_write_buffer_e, class abs_eap_am_tools_c *, unsigned long) + ?get_is_valid@eap_am_crypto_symbian_c@@UBE_NXZ @ 703 NONAME ; bool eap_am_crypto_symbian_c::get_is_valid(void) const + ?shutdown_operation@eapol_core_c@@SA?AW4eap_status_e@@PAVeapol_key_state_c@@PAVabs_eap_am_tools_c@@@Z @ 704 NONAME ; enum eap_status_e eapol_core_c::shutdown_operation(class eapol_key_state_c *, class abs_eap_am_tools_c *) + ?formatted_print@eap_am_tools_symbian_c@@UAAXPBDZZ @ 705 NONAME ; void eap_am_tools_symbian_c::formatted_print(char const *, ...) + ?get_is_valid@eap_am_file_input_symbian_c@@UAE_NXZ @ 706 NONAME ; bool eap_am_file_input_symbian_c::get_is_valid(void) + ?get_digest_length@crypto_md5_c@@UAEKXZ @ 707 NONAME ; unsigned long crypto_md5_c::get_digest_length(void) + ?compare_network_id@eap_am_network_id_c@@QBE_NPBV1@@Z @ 708 NONAME ; bool eap_am_network_id_c::compare_network_id(class eap_am_network_id_c const *) const + ?get_mutex@eap_am_mutex_symbian_c@@QBEPBVRMutex@@XZ @ 709 NONAME ; class RMutex const * eap_am_mutex_symbian_c::get_mutex(void) const + ?get_eapol_key_type_string@eapol_session_key_c@@SAPBDW4eapol_key_type_e@@@Z @ 710 NONAME ; char const * eapol_session_key_c::get_eapol_key_type_string(enum eapol_key_type_e) + ?trace_eap_packet@eap_core_c@@QAEXPBDPBVeap_header_wr_c@@@Z @ 711 NONAME ; void eap_core_c::trace_eap_packet(char const *, class eap_header_wr_c const *) + ?hash_init@crypto_sha_256_c@@UAE?AW4eap_status_e@@XZ @ 712 NONAME ; enum eap_status_e crypto_sha_256_c::hash_init(void) + ??1abs_eap_am_memory_store_data_c@@UAE@XZ @ 713 NONAME ; abs_eap_am_memory_store_data_c::~abs_eap_am_memory_store_data_c(void) + ?get_protocol@eap_state_notification_c@@UBEKXZ @ 714 NONAME ; unsigned long eap_state_notification_c::get_protocol(void) const + ?get_key_data_length@eapol_RSNA_key_header_c@@QBEGXZ @ 715 NONAME ; unsigned short eapol_RSNA_key_header_c::get_key_data_length(void) const + ??0eap_am_tools_symbian_c@@QAE@PBD@Z @ 716 NONAME ; eap_am_tools_symbian_c::eap_am_tools_symbian_c(char const *) + ??1abs_crypto_hash_algorithm_c@@UAE@XZ @ 717 NONAME ; abs_crypto_hash_algorithm_c::~abs_crypto_hash_algorithm_c(void) + ?asynchronous_init_remove_eapol_key_state@eapol_key_state_c@@AAE?AW4eap_status_e@@XZ @ 718 NONAME ; enum eap_status_e eapol_key_state_c::asynchronous_init_remove_eapol_key_state(void) + ?packet_process@eapol_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 719 NONAME ; enum eap_status_e eapol_core_c::packet_process(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long) + ?object_decrease_reference_count@eapol_handle_tlv_message_data_c@@QAEKXZ @ 720 NONAME ; unsigned long eapol_handle_tlv_message_data_c::object_decrease_reference_count(void) + ?restart_authentication@eap_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N@Z @ 721 NONAME ; enum eap_status_e eap_session_core_c::restart_authentication(class eap_am_network_id_c const *, bool) + ?state_notification@eapol_am_wlan_authentication_symbian_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 722 NONAME ; void eapol_am_wlan_authentication_symbian_c::state_notification(class abs_eap_state_notification_c const *) + ?get_sha_256_block_size@eap_am_crypto_symbian_c@@UAEKPAVeap_variable_data_c@@@Z @ 723 NONAME ; unsigned long eap_am_crypto_symbian_c::get_sha_256_block_size(class eap_variable_data_c *) + ?get_supplicant_RSNA_IE@eapol_key_state_c@@AAEPAVeap_variable_data_c@@XZ @ 724 NONAME ; class eap_variable_data_c * eapol_key_state_c::get_supplicant_RSNA_IE(void) + ?tkip_mic_failure@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_NW4eapol_tkip_mic_failure_type_e@eapol_RSNA_key_header_c@@@Z @ 725 NONAME ; enum eap_status_e eapol_core_c::tkip_mic_failure(class eap_am_network_id_c const *, bool, enum eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e) + ?get_block_size@crypto_cbc_c@@UAEKXZ @ 726 NONAME ; unsigned long crypto_cbc_c::get_block_size(void) + ?cnf_parse_value@eap_file_config_c@@AAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAW4eap_configure_type_e@@PAV3@_N@Z @ 727 NONAME ; enum eap_status_e eap_file_config_c::cnf_parse_value(class eap_variable_data_c const *, class eap_variable_data_c const *, enum eap_configure_type_e *, class eap_variable_data_c *, bool) + ?packet_process_type@eap_core_c@@AAE?AW4eap_status_e@@Veap_expanded_type_c@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 728 NONAME ; enum eap_status_e eap_core_c::packet_process_type(class eap_expanded_type_c, class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long) + ??0eap_master_session_key_c@@QAE@PAVabs_eap_am_tools_c@@Veap_expanded_type_c@@@Z @ 729 NONAME ; eap_master_session_key_c::eap_master_session_key_c(class abs_eap_am_tools_c *, class eap_expanded_type_c) + ?get_value_offset@eap_tlv_header_c@@QBEPAEKK@Z @ 730 NONAME ; unsigned char * eap_tlv_header_c::get_value_offset(unsigned long, unsigned long) const + ?get_source_length@eap_am_network_id_c@@QBEKXZ @ 731 NONAME ; unsigned long eap_am_network_id_c::get_source_length(void) const + ?get_source@eapol_ethernet_header_base_c@@QBEPAEXZ @ 732 NONAME ; unsigned char * eapol_ethernet_header_base_c::get_source(void) const + ?get_confirmation_KCK@eapol_key_state_c@@AAEPAVeap_variable_data_c@@XZ @ 733 NONAME ; class eap_variable_data_c * eapol_key_state_c::get_confirmation_KCK(void) + ??1eap_am_crypto_sha1_c@@UAE@XZ @ 734 NONAME ; eap_am_crypto_sha1_c::~eap_am_crypto_sha1_c(void) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@K@Z @ 735 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(unsigned long) + ?set_key_information_request@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@_N@Z @ 736 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_information_request(bool) + ??0eap_type_selection_c@@QAE@PAVabs_eap_am_tools_c@@Veap_expanded_type_c@@_N@Z @ 737 NONAME ; eap_type_selection_c::eap_type_selection_c(class abs_eap_am_tools_c *, class eap_expanded_type_c, bool) + ?set_is_valid@ethernet_core_c@@UAEXXZ @ 738 NONAME ; void ethernet_core_c::set_is_valid(void) + ?get_is_valid@crypto_aes_wrap_c@@QAE_NXZ @ 739 NONAME ; bool crypto_aes_wrap_c::get_is_valid(void) + ?read_reassociation_parameters@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@0W4eapol_key_authentication_type_e@@PAVeap_variable_data_c@@PBV5@3@Z @ 740 NONAME ; enum eap_status_e eapol_core_c::read_reassociation_parameters(class eap_am_network_id_c const *, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ?get_eap_header@eapol_header_wr_c@@QAEPAEXZ @ 741 NONAME ; unsigned char * eapol_header_wr_c::get_eap_header(void) + ?dsa_cleanup@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 742 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::dsa_cleanup(class eap_variable_data_c *) + ?get_key_tx_bit@eapol_session_key_c@@QBE_NXZ @ 743 NONAME ; bool eapol_session_key_c::get_key_tx_bit(void) const + ?get_current_state@eap_state_notification_c@@UBEKXZ @ 744 NONAME ; unsigned long eap_state_notification_c::get_current_state(void) const + ?block_size_3des_ede@eap_am_crypto_symbian_c@@UAEKXZ @ 745 NONAME ; unsigned long eap_am_crypto_symbian_c::block_size_3des_ede(void) + ?timer_expired@eapol_key_state_c@@UAE?AW4eap_status_e@@KPAX@Z @ 746 NONAME ; enum eap_status_e eapol_key_state_c::timer_expired(unsigned long, void *) + ?process_group_key_handshake_message_2@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K@Z @ 747 NONAME ; enum eap_status_e eapol_key_state_c::process_group_key_handshake_message_2(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long) + ?cancel_all_authentication_sessions@eapol_core_c@@QAE?AW4eap_status_e@@XZ @ 748 NONAME ; enum eap_status_e eapol_core_c::cancel_all_authentication_sessions(void) + ?disassociation@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 749 NONAME ; enum eap_status_e eapol_core_c::disassociation(class eap_am_network_id_c const *) + ?get_is_valid@eap_general_header_base_c@@QBE_NXZ @ 750 NONAME ; bool eap_general_header_base_c::get_is_valid(void) const + ??8eap_expanded_type_c@@QBE_NABV0@@Z @ 751 NONAME ; bool eap_expanded_type_c::operator==(class eap_expanded_type_c const &) const + ?packet_data_session_key@ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeapol_session_key_c@@@Z @ 752 NONAME ; enum eap_status_e ethernet_core_c::packet_data_session_key(class eap_am_network_id_c const *, class eapol_session_key_c const *) + ?set_expanded_type_data@eap_expanded_type_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@PBVeap_variable_data_c@@@Z @ 753 NONAME ; enum eap_status_e eap_expanded_type_c::set_expanded_type_data(class abs_eap_am_tools_c *, class eap_variable_data_c const *) + ?create_4_way_handshake_message_1@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeap_buf_chain_wr_c@@KPAK1W4eapol_protocol_version_e@@W4eapol_key_descriptor_type_e@@@Z @ 754 NONAME ; enum eap_status_e eapol_key_state_c::create_4_way_handshake_message_1(class eap_buf_chain_wr_c *, unsigned long, unsigned long *, unsigned long *, enum eapol_protocol_version_e, enum eapol_key_descriptor_type_e) + ?read_u32_t@eap_file_config_c@@AAEPAEPAEPBEPAK@Z @ 755 NONAME ; unsigned char * eap_file_config_c::read_u32_t(unsigned char *, unsigned char const *, unsigned long *) + ??0crypto_tls_prf_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 756 NONAME ; crypto_tls_prf_c::crypto_tls_prf_c(class abs_eap_am_tools_c *) + ?start_timer_thread@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@XZ @ 757 NONAME ; enum eap_status_e eap_am_tools_symbian_c::start_timer_thread(void) + ?store_configure@eap_file_config_c@@AAE?AW4eap_status_e@@PAVabs_eap_am_file_input_c@@PBVeap_variable_data_c@@PAV?$eap_core_map_c@Veap_config_value_c@@Vabs_eap_core_map_c@@Veap_variable_data_c@@@@@Z @ 758 NONAME ; enum eap_status_e eap_file_config_c::store_configure(class abs_eap_am_file_input_c *, class eap_variable_data_c const *, class eap_core_map_c *) + ?get_eap_type_list@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_expanded_type_c@@@@@Z @ 759 NONAME ; enum eap_status_e eapol_wlan_authentication_c::get_eap_type_list(class eap_array_c *) + ?packet_send@ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 760 NONAME ; enum eap_status_e ethernet_core_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long) + ?is_expanded_type@eap_expanded_type_c@@SA_NW4eap_type_ietf_values_e@@@Z @ 761 NONAME ; bool eap_expanded_type_c::is_expanded_type(enum eap_type_ietf_values_e) + ?add_RSN_IE_payload@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeapol_RSNA_key_header_c@@PAVeap_variable_data_c@@PAK@Z @ 762 NONAME ; enum eap_status_e eapol_key_state_c::add_RSN_IE_payload(class eapol_RSNA_key_header_c const *, class eap_variable_data_c *, unsigned long *) + ?leave_crypto_cs@eap_am_tools_symbian_c@@QAEXXZ @ 763 NONAME ; void eap_am_tools_symbian_c::leave_crypto_cs(void) + ??1abs_eap_am_mutex_c@@UAE@XZ @ 764 NONAME ; abs_eap_am_mutex_c::~abs_eap_am_mutex_c(void) + ?load_module@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@0PAVabs_eap_base_type_c@@PAPAVeap_base_type_c@@_NPBVeap_am_network_id_c@@@Z @ 765 NONAME ; enum eap_status_e eapol_wlan_authentication_c::load_module(class eap_expanded_type_c, class eap_expanded_type_c, class abs_eap_base_type_c *, class eap_base_type_c * *, bool, class eap_am_network_id_c const *) + ?hash_final@crypto_md4_c@@UAE?AW4eap_status_e@@PAXPAK@Z @ 766 NONAME ; enum eap_status_e crypto_md4_c::hash_final(void *, unsigned long *) + ?get_am_tools@eap_general_header_base_c@@QBEPAVabs_eap_am_tools_c@@XZ @ 767 NONAME ; class abs_eap_am_tools_c * eap_general_header_base_c::get_am_tools(void) const + ??1eap_header_wr_c@@UAE@XZ @ 768 NONAME ; eap_header_wr_c::~eap_header_wr_c(void) + ?handle_eap_identity_request@eap_core_c@@AAE?AW4eap_status_e@@Veap_expanded_type_c@@EPBVeap_am_network_id_c@@@Z @ 769 NONAME ; enum eap_status_e eap_core_c::handle_eap_identity_request(class eap_expanded_type_c, unsigned char, class eap_am_network_id_c const *) + ?md4_cleanup@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 770 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::md4_cleanup(class eap_variable_data_c *) + ?association@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@2W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@32@Z @ 771 NONAME ; enum eap_status_e eapol_core_c::association(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, class eap_variable_data_c const *) + ?load_module@eap_session_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@0PAVabs_eap_base_type_c@@PAPAVeap_base_type_c@@_NPBVeap_am_network_id_c@@@Z @ 772 NONAME ; enum eap_status_e eap_session_core_c::load_module(class eap_expanded_type_c, class eap_expanded_type_c, class abs_eap_base_type_c *, class eap_base_type_c * *, bool, class eap_am_network_id_c const *) + ?add_padding_bytes@crypto_cbc_c@@UAE?AW4eap_status_e@@PAXKE@Z @ 773 NONAME ; enum eap_status_e crypto_cbc_c::add_padding_bytes(void *, unsigned long, unsigned char) + ?get_key_length@crypto_3des_ede_c@@UAEKXZ @ 774 NONAME ; unsigned long crypto_3des_ede_c::get_key_length(void) + ?send_logoff@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 775 NONAME ; enum eap_status_e eapol_core_c::send_logoff(class eap_am_network_id_c const *) + ??0eapol_message_wlan_authentication_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_eapol_message_wlan_authentication_c@@@Z @ 776 NONAME ; eapol_message_wlan_authentication_c::eapol_message_wlan_authentication_c(class abs_eap_am_tools_c *, class abs_eapol_message_wlan_authentication_c *) + ?initialize_members@eap_variable_data_c@@AAE?AW4eap_status_e@@XZ @ 777 NONAME ; enum eap_status_e eap_variable_data_c::initialize_members(void) + ?md5_update@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEK@Z @ 778 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::md5_update(class eap_variable_data_c *, unsigned char const *, unsigned long) + ?copy_message_data@eap_am_memory_store_tlv_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_message_data_c@@K@Z @ 779 NONAME ; enum eap_status_e eap_am_memory_store_tlv_data_c::copy_message_data(class eap_tlv_message_data_c const *, unsigned long) + ?set_key_information_install@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@_N@Z @ 780 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_information_install(bool) + ?hash_update@crypto_sha_256_c@@UAE?AW4eap_status_e@@PBXK@Z @ 781 NONAME ; enum eap_status_e crypto_sha_256_c::hash_update(void const *, unsigned long) + ?get_do_packet_retransmission@eap_buf_chain_base_c@@QAE_NXZ @ 782 NONAME ; bool eap_buf_chain_base_c::get_do_packet_retransmission(void) + ?enter_global_mutex@eap_am_tools_symbian_c@@UAEXXZ @ 783 NONAME ; void eap_am_tools_symbian_c::enter_global_mutex(void) + ?add_data_to_offset@eap_variable_data_c@@QAE?AW4eap_status_e@@KPBV1@@Z @ 784 NONAME ; enum eap_status_e eap_variable_data_c::add_data_to_offset(unsigned long, class eap_variable_data_c const *) + ?encrypt_key_data@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeapol_RSNA_key_header_c@@@Z @ 785 NONAME ; enum eap_status_e eapol_key_state_c::encrypt_key_data(class eapol_RSNA_key_header_c *) + ?hash_cleanup@eap_am_crypto_md4_c@@AAE?AW4eap_status_e@@XZ @ 786 NONAME ; enum eap_status_e eap_am_crypto_md4_c::hash_cleanup(void) + ?initialize@eapol_key_state_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@@Z @ 787 NONAME ; enum eap_status_e eapol_key_state_c::initialize(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e) + ?hash_update@crypto_md5_c@@UAE?AW4eap_status_e@@PBXK@Z @ 788 NONAME ; enum eap_status_e crypto_md5_c::hash_update(void const *, unsigned long) + ?set_start_offset@eap_variable_data_c@@QAE?AW4eap_status_e@@K@Z @ 789 NONAME ; enum eap_status_e eap_variable_data_c::set_start_offset(unsigned long) + ??1eap_simple_config_trace_string_c@@UAE@XZ @ 790 NONAME ; eap_simple_config_trace_string_c::~eap_simple_config_trace_string_c(void) + ??1eapol_header_rd_c@@UAE@XZ @ 791 NONAME ; eapol_header_rd_c::~eapol_header_rd_c(void) + ?set_is_invalid@eap_am_crypto_sha_256_c@@AAEXXZ @ 792 NONAME ; void eap_am_crypto_sha_256_c::set_is_invalid(void) + ?zero_key_STA_MAC_address@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@@Z @ 793 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::zero_key_STA_MAC_address(class abs_eap_am_tools_c *) + ?u64_t_to_u64_struct@eap_am_tools_symbian_c@@UAE?AUu64_struct@@_K@Z @ 794 NONAME ; struct u64_struct eap_am_tools_symbian_c::u64_t_to_u64_struct(unsigned long long) + ?set_key_information_error@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@_N@Z @ 795 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_information_error(bool) + ?process_4_way_handshake_message_0@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K@Z @ 796 NONAME ; enum eap_status_e eapol_key_state_c::process_4_way_handshake_message_0(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long) + ?copy@crypto_sha_256_c@@UAEPAVabs_crypto_hash_algorithm_c@@XZ @ 797 NONAME ; class abs_crypto_hash_algorithm_c * crypto_sha_256_c::copy(void) + ?hash_update@eap_am_crypto_sha1_c@@QAE?AW4eap_status_e@@PBXK@Z @ 798 NONAME ; enum eap_status_e eap_am_crypto_sha1_c::hash_update(void const *, unsigned long) + ?shutdown_am_tools@eap_am_tools_c@@QAE?AW4eap_status_e@@XZ @ 799 NONAME ; enum eap_status_e eap_am_tools_c::shutdown_am_tools(void) + ?read_configure@ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 800 NONAME ; enum eap_status_e ethernet_core_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?set_message_data@eap_tlv_message_data_c@@QAE?AW4eap_status_e@@KPBX@Z @ 801 NONAME ; enum eap_status_e eap_tlv_message_data_c::set_message_data(unsigned long, void const *) + ?set_is_invalid@eap_am_crypto_rc4_c@@AAEXXZ @ 802 NONAME ; void eap_am_crypto_rc4_c::set_is_invalid(void) + ?password_hash@crypto_wpa_psk_password_hash_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@PAXP6A?AW42@2K@Z@Z @ 803 NONAME ; enum eap_status_e crypto_wpa_psk_password_hash_c::password_hash(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *, void *, enum eap_status_e (*)(void *, unsigned long)) + ?create_key_mic@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeapol_RSNA_key_header_c@@PBVeap_variable_data_c@@@Z @ 804 NONAME ; enum eap_status_e eapol_key_state_c::create_key_mic(class eapol_RSNA_key_header_c *, class eap_variable_data_c const *) + ?get_eap_type_list@eap_session_core_c@@UAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_expanded_type_c@@@@@Z @ 805 NONAME ; enum eap_status_e eap_session_core_c::get_eap_type_list(class eap_array_c *) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAV?$eap_array_c@Vnetwork_key_and_index_c@@@@@Z @ 806 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, class eap_array_c *) + ?hash_cleanup@eap_am_crypto_sha1_c@@AAE?AW4eap_status_e@@XZ @ 807 NONAME ; enum eap_status_e eap_am_crypto_sha1_c::hash_cleanup(void) + ?state_notification@eap_session_core_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 808 NONAME ; void eap_session_core_c::state_notification(class abs_eap_state_notification_c const *) + ??0eapol_header_rd_c@@QAE@PAVabs_eap_am_tools_c@@PAEK@Z @ 809 NONAME ; eapol_header_rd_c::eapol_header_rd_c(class abs_eap_am_tools_c *, unsigned char *, unsigned long) + ?process_4_way_handshake_message@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K@Z @ 810 NONAME ; enum eap_status_e eapol_key_state_c::process_4_way_handshake_message(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long) + ?get_type@eap_header_base_c@@QBE?AVeap_expanded_type_c@@XZ @ 811 NONAME ; class eap_expanded_type_c eap_header_base_c::get_type(void) const + ?shutdown@eapol_key_state_c@@QAE?AW4eap_status_e@@XZ @ 812 NONAME ; enum eap_status_e eapol_key_state_c::shutdown(void) + ?set_is_valid@crypto_dsa_c@@AAEXXZ @ 813 NONAME ; void crypto_dsa_c::set_is_valid(void) + ?aes_set_encryption_key@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEK@Z @ 814 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::aes_set_encryption_key(class eap_variable_data_c *, unsigned char const *, unsigned long) + ?set_is_valid@eapol_key_state_c@@AAEXXZ @ 815 NONAME ; void eapol_key_state_c::set_is_valid(void) + ??1crypto_cbc_c@@UAE@XZ @ 816 NONAME ; crypto_cbc_c::~crypto_cbc_c(void) + ?leave_global_mutex@eap_am_tools_symbian_c@@UAEXXZ @ 817 NONAME ; void eap_am_tools_symbian_c::leave_global_mutex(void) + ?set_key_information_key_index@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@E@Z @ 818 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_information_key_index(unsigned char) + ?set_is_valid@crypto_md4_c@@EAEXXZ @ 819 NONAME ; void crypto_md4_c::set_is_valid(void) + ?get_code@eap_header_base_c@@QBE?AW4eap_code_value_e@@XZ @ 820 NONAME ; enum eap_code_value_e eap_header_base_c::get_code(void) const + ??Ieap_expanded_type_c@@QAEPAV0@XZ @ 821 NONAME ; class eap_expanded_type_c * eap_expanded_type_c::operator&(void) + ?md4_copy_context@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@@Z @ 822 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::md4_copy_context(class eap_variable_data_c *, class eap_variable_data_c const *) + ?get_key_information_install@eapol_RSNA_key_header_c@@QBE_NXZ @ 823 NONAME ; bool eapol_RSNA_key_header_c::get_key_information_install(void) const + ?packet_send@eapol_message_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 824 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long) + ??4eap_expanded_type_c@@QAEAAV0@W4eap_type_ietf_values_e@@@Z @ 825 NONAME ; class eap_expanded_type_c & eap_expanded_type_c::operator=(enum eap_type_ietf_values_e) + ?eap_write_u16_t_network_order@@YA?AW4eap_status_e@@PAXKG@Z @ 826 NONAME ; enum eap_status_e eap_write_u16_t_network_order(void *, unsigned long, unsigned short) + ?strlen@eap_am_tools_symbian_c@@UAEKPBD@Z @ 827 NONAME ; unsigned long eap_am_tools_symbian_c::strlen(char const *) + ?get_previous_state_string@eap_state_notification_c@@UBEPBDXZ @ 828 NONAME ; char const * eap_state_notification_c::get_previous_state_string(void) const + ?get_key_reply_counter@eapol_key_state_c@@AAE_KXZ @ 829 NONAME ; unsigned long long eapol_key_state_c::get_key_reply_counter(void) + ?get_marked_removed@eapol_key_state_c@@QAE_NXZ @ 830 NONAME ; bool eapol_key_state_c::get_marked_removed(void) + ?cancel_timer@ethernet_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 831 NONAME ; enum eap_status_e ethernet_core_c::cancel_timer(class abs_eap_base_timer_c *, unsigned long) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVabs_eap_state_notification_c@@@Z @ 832 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(class abs_eap_state_notification_c const *) + ?get_block_size@crypto_3des_ede_c@@UAEKXZ @ 833 NONAME ; unsigned long crypto_3des_ede_c::get_block_size(void) + ?get_type_data_start_offset@eap_header_base_c@@SAK_N@Z @ 834 NONAME ; unsigned long eap_header_base_c::get_type_data_start_offset(bool) + ??0eap_am_crypto_sha1_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 835 NONAME ; eap_am_crypto_sha1_c::eap_am_crypto_sha1_c(class abs_eap_am_tools_c *) + ?convert_value@eap_file_config_c@@AAE?AW4eap_status_e@@PAV?$eap_core_map_c@Veap_config_value_c@@Vabs_eap_core_map_c@@Veap_variable_data_c@@@@PBVeap_variable_data_c@@W4eap_configure_type_e@@PAV4@@Z @ 836 NONAME ; enum eap_status_e eap_file_config_c::convert_value(class eap_core_map_c *, class eap_variable_data_c const *, enum eap_configure_type_e, class eap_variable_data_c *) + ?convert_hex_ascii_to_bytes@eap_am_tools_c@@UAE?AW4eap_status_e@@PBEKPAEPAK@Z @ 837 NONAME ; enum eap_status_e eap_am_tools_c::convert_hex_ascii_to_bytes(unsigned char const *, unsigned long, unsigned char *, unsigned long *) + ?set_authentication_role@eap_core_c@@UAE?AW4eap_status_e@@_N@Z @ 838 NONAME ; enum eap_status_e eap_core_c::set_authentication_role(bool) + ?start_authentication@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 839 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::start_authentication(class eap_array_c const *) + ?eap_write_u32_t_little_endian_order@@YA?AW4eap_status_e@@PAXKK@Z @ 840 NONAME ; enum eap_status_e eap_write_u32_t_little_endian_order(void *, unsigned long, unsigned long) + ?set_data_length@eapol_header_base_c@@QAEXG@Z @ 841 NONAME ; void eapol_header_base_c::set_data_length(unsigned short) + ?get_digest_length@crypto_sha_256_c@@UAEKXZ @ 842 NONAME ; unsigned long crypto_sha_256_c::get_digest_length(void) + ?reset@eap_am_network_id_c@@QAEXXZ @ 843 NONAME ; void eap_am_network_id_c::reset(void) + ??0abs_eap_am_mutex_c@@QAE@XZ @ 844 NONAME ; abs_eap_am_mutex_c::abs_eap_am_mutex_c(void) + ?configure@eap_core_c@@UAE?AW4eap_status_e@@XZ @ 845 NONAME ; enum eap_status_e eap_core_c::configure(void) + ?get_is_valid@eap_session_core_c@@UAE_NXZ @ 846 NONAME ; bool eap_session_core_c::get_is_valid(void) + ?get_rand_integer@crypto_random_c@@QAEKKK@Z @ 847 NONAME ; unsigned long crypto_random_c::get_rand_integer(unsigned long, unsigned long) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 848 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(class eap_expanded_type_c) + ?authentication_finished@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@_NVeap_expanded_type_c@@W4eapol_key_authentication_type_e@@@Z @ 849 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::authentication_finished(bool, class eap_expanded_type_c, enum eapol_key_authentication_type_e) + ?object_increase_reference_count@eapol_key_state_c@@QAEXXZ @ 850 NONAME ; void eapol_key_state_c::object_increase_reference_count(void) + ?check_activate_trace_on_error@eap_am_tools_c@@UAEXXZ @ 851 NONAME ; void eap_am_tools_c::check_activate_trace_on_error(void) + ?get_sent_packet@eap_core_retransmission_c@@QBEPAVeap_buf_chain_wr_c@@XZ @ 852 NONAME ; class eap_buf_chain_wr_c * eap_core_retransmission_c::get_sent_packet(void) const + ??0eapol_core_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_eapol_core_c@@_N@Z @ 853 NONAME ; eapol_core_c::eapol_core_c(class abs_eap_am_tools_c *, class abs_eapol_core_c *, bool) + ?asynchronous_init_remove_eap_session@eap_core_c@@AAE?AW4eap_status_e@@XZ @ 854 NONAME ; enum eap_status_e eap_core_c::asynchronous_init_remove_eap_session(void) + ?zero_key_MIC@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@@Z @ 855 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::zero_key_MIC(class abs_eap_am_tools_c *) + ?get_type_data_length@eap_header_base_c@@QBEGXZ @ 856 NONAME ; unsigned short eap_header_base_c::get_type_data_length(void) const + ??1eap_core_nak_info_c@@UAE@XZ @ 857 NONAME ; eap_core_nak_info_c::~eap_core_nak_info_c(void) + ?start_reassociation@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@@Z @ 858 NONAME ; enum eap_status_e ethernet_core_c::start_reassociation(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *) + ?get_asymmetric_start_key@crypto_nt_hash_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@PAV3@K_N2@Z @ 859 NONAME ; enum eap_status_e crypto_nt_hash_c::get_asymmetric_start_key(class eap_variable_data_c const *, class eap_variable_data_c *, unsigned long, bool, bool) + ?get_is_valid@eap_am_network_id_c@@QBE_NXZ @ 860 NONAME ; bool eap_am_network_id_c::get_is_valid(void) const + ?set_is_valid@eap_am_crypto_md4_c@@AAEXXZ @ 861 NONAME ; void eap_am_crypto_md4_c::set_is_valid(void) + ??1eap_am_mutex_reference_c@@UAE@XZ @ 862 NONAME ; eap_am_mutex_reference_c::~eap_am_mutex_reference_c(void) + ??0ethernet_core_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_ethernet_core_c@@_N@Z @ 863 NONAME ; ethernet_core_c::ethernet_core_c(class abs_eap_am_tools_c *, class abs_ethernet_core_c *, bool) + ?set_key_information_key_type@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@_N@Z @ 864 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_information_key_type(bool) + ?check_is_valid_eap_type@eap_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 865 NONAME ; enum eap_status_e eap_core_c::check_is_valid_eap_type(class eap_expanded_type_c) + ?get_is_valid@eap_tlv_message_data_c@@QAE_NXZ @ 866 NONAME ; bool eap_tlv_message_data_c::get_is_valid(void) + ?get_buffer_offset@eap_variable_data_c@@QBEPAEKK@Z @ 867 NONAME ; unsigned char * eap_variable_data_c::get_buffer_offset(unsigned long, unsigned long) const + ?get_encrypts@crypto_3des_ede_c@@UAE_NXZ @ 868 NONAME ; bool crypto_3des_ede_c::get_encrypts(void) + ?add_end_null@eap_variable_data_c@@QAE?AW4eap_status_e@@XZ @ 869 NONAME ; enum eap_status_e eap_variable_data_c::add_end_null(void) + ?shutdown@eapol_core_c@@UAE?AW4eap_status_e@@XZ @ 870 NONAME ; enum eap_status_e eapol_core_c::shutdown(void) + ?initialize_session_timeout@eap_core_c@@AAE?AW4eap_status_e@@K@Z @ 871 NONAME ; enum eap_status_e eap_core_c::initialize_session_timeout(unsigned long) + ?get_is_valid@crypto_nt_hash_c@@QAE_NXZ @ 872 NONAME ; bool crypto_nt_hash_c::get_is_valid(void) + ?get_key_length@eapol_RC4_key_header_c@@QBEGXZ @ 873 NONAME ; unsigned short eapol_RC4_key_header_c::get_key_length(void) const + ?get_use_eap_milli_second_timer@eap_am_tools_symbian_c@@UAE_NXZ @ 874 NONAME ; bool eap_am_tools_symbian_c::get_use_eap_milli_second_timer(void) + ??1crypto_eap_fast_hmac_sha1_prf_c@@UAE@XZ @ 875 NONAME ; crypto_eap_fast_hmac_sha1_prf_c::~crypto_eap_fast_hmac_sha1_prf_c(void) + ?set_mac_address@eap_rogue_ap_entry_c@@QAEXPBE@Z @ 876 NONAME ; void eap_rogue_ap_entry_c::set_mac_address(unsigned char const *) + ?copy@eap_am_network_id_c@@QBEPAV1@XZ @ 877 NONAME ; class eap_am_network_id_c * eap_am_network_id_c::copy(void) const + ?set_marked_removed@eapol_key_state_c@@QAEXXZ @ 878 NONAME ; void eapol_key_state_c::set_marked_removed(void) + ?start_preauthentication@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@@Z @ 879 NONAME ; enum eap_status_e ethernet_core_c::start_preauthentication(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e) + ?set_eapol_packet_type@eapol_RC4_key_header_c@@QAE?AW4eap_status_e@@W4eapol_packet_type_e@@@Z @ 880 NONAME ; enum eap_status_e eapol_RC4_key_header_c::set_eapol_packet_type(enum eapol_packet_type_e) + ??0eap_header_string_c@@QAE@XZ @ 881 NONAME ; eap_header_string_c::eap_header_string_c(void) + ?get_supplicant_MAC_address@eapol_key_state_c@@AAEPAVeap_variable_data_c@@XZ @ 882 NONAME ; class eap_variable_data_c * eapol_key_state_c::get_supplicant_MAC_address(void) + ?get_type_data@eap_header_base_c@@QBEPAEK@Z @ 883 NONAME ; unsigned char * eap_header_base_c::get_type_data(unsigned long) const + ?eap_write_u64_t_network_order@@YA?AW4eap_status_e@@PAXK_K@Z @ 884 NONAME ; enum eap_status_e eap_write_u64_t_network_order(void *, unsigned long, unsigned long long) + ?get_tmp_IV@crypto_cbc_c@@UAEPBVeap_variable_data_c@@XZ @ 885 NONAME ; class eap_variable_data_c const * crypto_cbc_c::get_tmp_IV(void) + ?eap_sha1_process_data_network_order@eap_am_crypto_sha1_c@@AAE?AW4eap_status_e@@PBKK@Z @ 886 NONAME ; enum eap_status_e eap_am_crypto_sha1_c::eap_sha1_process_data_network_order(unsigned long const *, unsigned long) + ?load_type@eap_core_c@@QAEPAVeap_base_type_c@@Veap_expanded_type_c@@0PBVeap_am_network_id_c@@@Z @ 887 NONAME ; class eap_base_type_c * eap_core_c::load_type(class eap_expanded_type_c, class eap_expanded_type_c, class eap_am_network_id_c const *) + ?convert_unicode_to_utf8@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@AAVeap_variable_data_c@@ABV3@@Z @ 888 NONAME ; enum eap_status_e eap_am_tools_symbian_c::convert_unicode_to_utf8(class eap_variable_data_c &, class eap_variable_data_c const &) + ?encrypt_block_3des_ede@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEPAEK@Z @ 889 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::encrypt_block_3des_ede(class eap_variable_data_c *, unsigned char const *, unsigned char *, unsigned long) + ?set_buffer@eapol_rsna_variable_data_c@@QAE?AW4eap_status_e@@PBVeapol_rsna_key_data_header_c@@PAEK_N2@Z @ 890 NONAME ; enum eap_status_e eapol_rsna_variable_data_c::set_buffer(class eapol_rsna_key_data_header_c const *, unsigned char *, unsigned long, bool, bool) + ?eapol_indication@eapol_wlan_authentication_c@@EAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_wlan_authentication_state_e@@@Z @ 891 NONAME ; enum eap_status_e eapol_wlan_authentication_c::eapol_indication(class eap_am_network_id_c const *, enum eapol_wlan_authentication_state_e) + ?send_eap_success@eap_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@E@Z @ 892 NONAME ; enum eap_status_e eap_core_c::send_eap_success(class eap_am_network_id_c const *, unsigned char) + ?sha1_final@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PAEPAK@Z @ 893 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::sha1_final(class eap_variable_data_c *, unsigned char *, unsigned long *) + ?set_pairwise_PMK@eapol_key_state_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@PBVeap_am_network_id_c@@@Z @ 894 NONAME ; enum eap_status_e eapol_key_state_c::set_pairwise_PMK(class eap_variable_data_c const *, class eap_am_network_id_c const *) + ?eap_htons@@YAGG@Z @ 895 NONAME ; unsigned short eap_htons(unsigned short) + ?reset@eap_variable_data_c@@QAE?AW4eap_status_e@@XZ @ 896 NONAME ; enum eap_status_e eap_variable_data_c::reset(void) + ?get_key_length@crypto_aes_wrap_c@@QAEKXZ @ 897 NONAME ; unsigned long crypto_aes_wrap_c::get_key_length(void) + ?get_crypto@eap_am_tools_symbian_c@@UAEPAVabs_eap_am_crypto_c@@XZ @ 898 NONAME ; class abs_eap_am_crypto_c * eap_am_tools_symbian_c::get_crypto(void) + ?eap_sha_256_process_data_network_order@eap_am_crypto_sha_256_c@@AAE?AW4eap_status_e@@PBKK@Z @ 899 NONAME ; enum eap_status_e eap_am_crypto_sha_256_c::eap_sha_256_process_data_network_order(unsigned long const *, unsigned long) + ?set_network_index@simple_config_credential_c@@QAEXE@Z @ 900 NONAME ; void simple_config_credential_c::set_network_index(unsigned char) + ?get_needs_confirmation_from_user@eap_state_notification_c@@UBE_NXZ @ 901 NONAME ; bool eap_state_notification_c::get_needs_confirmation_from_user(void) const + ?start_reassociation@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@0W4eapol_key_authentication_type_e@@@Z @ 902 NONAME ; enum eap_status_e eapol_wlan_authentication_c::start_reassociation(class eap_am_network_id_c const *, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e) + ?set_value_length@eap_tlv_header_c@@QAE?AW4eap_status_e@@K@Z @ 903 NONAME ; enum eap_status_e eap_tlv_header_c::set_value_length(unsigned long) + ?get_digest_length@eap_am_crypto_sha1_c@@QAEKXZ @ 904 NONAME ; unsigned long eap_am_crypto_sha1_c::get_digest_length(void) + ?generate_diffie_hellman_keys@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@0PBEK1K@Z @ 905 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::generate_diffie_hellman_keys(class eap_variable_data_c *, class eap_variable_data_c *, unsigned char const *, unsigned long, unsigned char const *, unsigned long) + ?get_eapol_packet_type@eapol_RC4_key_header_c@@QBE?AW4eapol_packet_type_e@@XZ @ 906 NONAME ; enum eapol_packet_type_e eapol_RC4_key_header_c::get_eapol_packet_type(void) const + ?get_is_valid@crypto_kd_hmac_sha256_c@@QAE_NXZ @ 907 NONAME ; bool crypto_kd_hmac_sha256_c::get_is_valid(void) + ?packet_send@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 908 NONAME ; enum eap_status_e eapol_key_state_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long) + ?expand_environment_variables@eap_file_config_c@@AAE?AW4eap_status_e@@PAV?$eap_core_map_c@Veap_config_value_c@@Vabs_eap_core_map_c@@Veap_variable_data_c@@@@PBVeap_variable_data_c@@PAV4@@Z @ 909 NONAME ; enum eap_status_e eap_file_config_c::expand_environment_variables(class eap_core_map_c *, class eap_variable_data_c const *, class eap_variable_data_c *) + ?hash_final@eap_am_crypto_md4_c@@QAE?AW4eap_status_e@@PAXPAK@Z @ 910 NONAME ; enum eap_status_e eap_am_crypto_md4_c::hash_final(void *, unsigned long *) + ?eap_sha_256_process_data_host_order@eap_am_crypto_sha_256_c@@AAE?AW4eap_status_e@@PBKK@Z @ 911 NONAME ; enum eap_status_e eap_am_crypto_sha_256_c::eap_sha_256_process_data_host_order(unsigned long const *, unsigned long) + ?mutex_enter@eap_am_mutex_symbian_c@@UAE?AW4eap_status_e@@XZ @ 912 NONAME ; enum eap_status_e eap_am_mutex_symbian_c::mutex_enter(void) + ?add_data@eap_buf_chain_base_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 913 NONAME ; enum eap_status_e eap_buf_chain_base_c::add_data(class eap_variable_data_c const *) + ?derive_WPXM_WPXK1_WPXK2@eapol_key_state_c@@AAE?AW4eap_status_e@@XZ @ 914 NONAME ; enum eap_status_e eapol_key_state_c::derive_WPXM_WPXK1_WPXK2(void) + ?file_read@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 915 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_read(class eap_variable_data_c *) + ?write_configure@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 916 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::write_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?eap_htonll@@YA_K_K@Z @ 917 NONAME ; unsigned long long eap_htonll(unsigned long long) + ??0eap_am_mutex_symbian_c@@QAE@XZ @ 918 NONAME ; eap_am_mutex_symbian_c::eap_am_mutex_symbian_c(void) + ?set_is_valid@crypto_eap_fast_hmac_sha1_prf_c@@AAEXXZ @ 919 NONAME ; void crypto_eap_fast_hmac_sha1_prf_c::set_is_valid(void) + ?set_WPXM_parameters@eapol_key_state_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 920 NONAME ; enum eap_status_e eapol_key_state_c::set_WPXM_parameters(class eap_am_network_id_c const *) + ?get_is_timer_thread_active@eap_am_tools_symbian_c@@UAE_NXZ @ 921 NONAME ; bool eap_am_tools_symbian_c::get_is_timer_thread_active(void) + ?object_decrease_reference_count@eap_core_c@@QAEKXZ @ 922 NONAME ; unsigned long eap_core_c::object_decrease_reference_count(void) + ?init_group_key_update_timeout@eapol_key_state_c@@AAE?AW4eap_status_e@@K@Z @ 923 NONAME ; enum eap_status_e eapol_key_state_c::init_group_key_update_timeout(unsigned long) + ?discard_stream@crypto_rc4_c@@UAE?AW4eap_status_e@@K@Z @ 924 NONAME ; enum eap_status_e crypto_rc4_c::discard_stream(unsigned long) + ?load_module@eapol_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@0PAVabs_eap_base_type_c@@PAPAVeap_base_type_c@@_NPBVeap_am_network_id_c@@@Z @ 925 NONAME ; enum eap_status_e eapol_core_c::load_module(class eap_expanded_type_c, class eap_expanded_type_c, class abs_eap_base_type_c *, class eap_base_type_c * *, bool, class eap_am_network_id_c const *) + ?zero_key_signature@eapol_RC4_key_header_c@@QAEXPAVabs_eap_am_tools_c@@@Z @ 926 NONAME ; void eapol_RC4_key_header_c::zero_key_signature(class abs_eap_am_tools_c *) + ?set_is_valid@eapol_core_c@@UAEXXZ @ 927 NONAME ; void eapol_core_c::set_is_valid(void) + ?generic_convert_unicode_to_utf8@eap_am_tools_c@@QAE?AW4eap_status_e@@AAVeap_variable_data_c@@ABV3@@Z @ 928 NONAME ; enum eap_status_e eap_am_tools_c::generic_convert_unicode_to_utf8(class eap_variable_data_c &, class eap_variable_data_c const &) + ?restore_selected_bytes_from_ascii_armor@eap_am_tools_c@@AAEXEPAKPAE0_N@Z @ 929 NONAME ; void eap_am_tools_c::restore_selected_bytes_from_ascii_armor(unsigned char, unsigned long *, unsigned char *, unsigned long *, bool) + ??1eap_expanded_type_c@@QAE@XZ @ 930 NONAME ; eap_expanded_type_c::~eap_expanded_type_c(void) + ?shutdown_operation@eap_session_core_c@@CA?AW4eap_status_e@@PAVeap_core_c@@PAVabs_eap_am_tools_c@@@Z @ 931 NONAME ; enum eap_status_e eap_session_core_c::shutdown_operation(class eap_core_c *, class abs_eap_am_tools_c *) + ?set_copy_of_am_network_id@eap_am_network_id_c@@QAE?AW4eap_status_e@@PBXK0KG@Z @ 932 NONAME ; enum eap_status_e eap_am_network_id_c::set_copy_of_am_network_id(void const *, unsigned long, void const *, unsigned long, unsigned short) + ?get_eapol_header@eapol_ethernet_header_wr_c@@QBEPAEXZ @ 933 NONAME ; unsigned char * eapol_ethernet_header_wr_c::get_eapol_header(void) const + ?memrchr@eap_am_tools_symbian_c@@UAEPAXPBXEK@Z @ 934 NONAME ; void * eap_am_tools_symbian_c::memrchr(void const *, unsigned char, unsigned long) + ?create_PMKID@eapol_key_state_c@@AAE?AW4eap_status_e@@XZ @ 935 NONAME ; enum eap_status_e eapol_key_state_c::create_PMKID(void) + ?encrypt_block@crypto_aes_wrap_c@@QAE?AW4eap_status_e@@PBXKPAXK@Z @ 936 NONAME ; enum eap_status_e crypto_aes_wrap_c::encrypt_block(void const *, unsigned long, void *, unsigned long) + ?check_one_payload@eapol_rsna_key_data_payloads_c@@QAE_NW4eapol_rsna_key_data_payload_status_e@1@PBV?$eap_array_c@Veap_variable_data_c@@@@@Z @ 937 NONAME ; bool eapol_rsna_key_data_payloads_c::check_one_payload(enum eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_e, class eap_array_c const *) + ??0eap_header_rd_c@@QAE@PAVabs_eap_am_tools_c@@PAEK@Z @ 938 NONAME ; eap_header_rd_c::eap_header_rd_c(class abs_eap_am_tools_c *, unsigned char *, unsigned long) + ?rsa_cleanup@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 939 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rsa_cleanup(class eap_variable_data_c *) + ??1eapol_key_state_string_c@@UAE@XZ @ 940 NONAME ; eapol_key_state_string_c::~eapol_key_state_string_c(void) + ?rsa_decrypt_with_public_key@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@10@Z @ 941 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rsa_decrypt_with_public_key(class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ?set_is_valid@crypto_random_c@@QAEXXZ @ 942 NONAME ; void crypto_random_c::set_is_valid(void) + ?ascii_to_octet@eap_am_tools_c@@UAEEJ@Z @ 943 NONAME ; unsigned char eap_am_tools_c::ascii_to_octet(long) + ?convert_utf8_to_unicode@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@AAVeap_variable_data_c@@ABV3@@Z @ 944 NONAME ; enum eap_status_e eap_am_tools_symbian_c::convert_utf8_to_unicode(class eap_variable_data_c &, class eap_variable_data_c const &) + ?set_is_valid@eap_am_network_id_c@@AAEXXZ @ 945 NONAME ; void eap_am_network_id_c::set_is_valid(void) + ?hash_update@crypto_sha1_c@@UAE?AW4eap_status_e@@PBXK@Z @ 946 NONAME ; enum eap_status_e crypto_sha1_c::hash_update(void const *, unsigned long) + ?verify@crypto_rsa_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@00@Z @ 947 NONAME ; enum eap_status_e crypto_rsa_c::verify(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ?get_block_size@crypto_aes_wrap_c@@QAEKXZ @ 948 NONAME ; unsigned long crypto_aes_wrap_c::get_block_size(void) + ?write_configure@eap_session_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 949 NONAME ; enum eap_status_e eap_session_core_c::write_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?unload_module@ethernet_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 950 NONAME ; enum eap_status_e ethernet_core_c::unload_module(class eap_expanded_type_c) + ?get_expanded_vendor_id_offset@eap_header_base_c@@SAKXZ @ 951 NONAME ; unsigned long eap_header_base_c::get_expanded_vendor_id_offset(void) + ?use_test_random@eap_am_crypto_symbian_c@@UAEXPBEK_N@Z @ 952 NONAME ; void eap_am_crypto_symbian_c::use_test_random(unsigned char const *, unsigned long, bool) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAE@Z @ 953 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, unsigned char *) + ?set_is_valid@crypto_rc4_c@@EAEXXZ @ 954 NONAME ; void crypto_rc4_c::set_is_valid(void) + ?memset@eap_am_tools_symbian_c@@UAEXPAXJK@Z @ 955 NONAME ; void eap_am_tools_symbian_c::memset(void *, long, unsigned long) + ?set_timer@ethernet_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 956 NONAME ; enum eap_status_e ethernet_core_c::set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long) + ?initialize_asynchronous_init_remove_eap_session@eap_core_c@@AAE?AW4eap_status_e@@K@Z @ 957 NONAME ; enum eap_status_e eap_core_c::initialize_asynchronous_init_remove_eap_session(unsigned long) + ?aes_key_length@eap_am_crypto_symbian_c@@UAEKXZ @ 958 NONAME ; unsigned long eap_am_crypto_symbian_c::aes_key_length(void) + ?get_is_valid@crypto_aes_c@@UAE_NXZ @ 959 NONAME ; bool crypto_aes_c::get_is_valid(void) + ?reset_header@eap_tlv_header_c@@QAE?AW4eap_status_e@@KK@Z @ 960 NONAME ; enum eap_status_e eap_tlv_header_c::reset_header(unsigned long, unsigned long) + ?add_data@eap_am_memory_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@PBVeap_tlv_message_data_c@@K@Z @ 961 NONAME ; enum eap_status_e eap_am_memory_store_c::add_data(class eap_variable_data_c const *, class eap_tlv_message_data_c const *, unsigned long) + ?read_configure@eapol_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 962 NONAME ; enum eap_status_e eapol_core_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?get_is_valid@eap_variable_data_c@@QBE_NXZ @ 963 NONAME ; bool eap_variable_data_c::get_is_valid(void) const + ?set_is_invalid@crypto_dsa_c@@AAEXXZ @ 964 NONAME ; void crypto_dsa_c::set_is_invalid(void) + ?read_type@eap_expanded_type_c@@SA?AW4eap_status_e@@PAVabs_eap_am_tools_c@@KPBXKPAV1@@Z @ 965 NONAME ; enum eap_status_e eap_expanded_type_c::read_type(class abs_eap_am_tools_c *, unsigned long, void const *, unsigned long, class eap_expanded_type_c *) + ??1eap_header_base_c@@UAE@XZ @ 966 NONAME ; eap_header_base_c::~eap_header_base_c(void) + ?create_group_key_handshake_message_2@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeap_buf_chain_wr_c@@KPAK1_KW4eapol_protocol_version_e@@W4eapol_key_descriptor_type_e@@@Z @ 967 NONAME ; enum eap_status_e eapol_key_state_c::create_group_key_handshake_message_2(class eap_buf_chain_wr_c *, unsigned long, unsigned long *, unsigned long *, unsigned long long, enum eapol_protocol_version_e, enum eapol_key_descriptor_type_e) + ?get_message_data_length@eap_am_memory_store_tlv_data_c@@QBEKXZ @ 968 NONAME ; unsigned long eap_am_memory_store_tlv_data_c::get_message_data_length(void) const + ?process_data@eapol_message_wlan_authentication_c@@QAE?AW4wlan_eap_if_send_status_e@@PBXK@Z @ 969 NONAME ; enum wlan_eap_if_send_status_e eapol_message_wlan_authentication_c::process_data(void const *, unsigned long) + ?load_module@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@0PAVabs_eap_base_type_c@@PAPAVeap_base_type_c@@_NPBVeap_am_network_id_c@@@Z @ 970 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::load_module(class eap_expanded_type_c, class eap_expanded_type_c, class abs_eap_base_type_c *, class eap_base_type_c * *, bool, class eap_am_network_id_c const *) + ?configure@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@XZ @ 971 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::configure(void) + ??1simple_config_credential_c@@UAE@XZ @ 972 NONAME ; simple_config_credential_c::~simple_config_credential_c(void) + ?set_timer_resolution_ms@eap_am_tools_symbian_c@@UAEXK@Z @ 973 NONAME ; void eap_am_tools_symbian_c::set_timer_resolution_ms(unsigned long) + ?get_key_information_key_descriptor_version@eapol_RSNA_key_header_c@@QBE?AW4key_descriptor_version_e@1@XZ @ 974 NONAME ; enum eapol_RSNA_key_header_c::key_descriptor_version_e eapol_RSNA_key_header_c::get_key_information_key_descriptor_version(void) const + ??1eapol_wlan_authentication_c@@UAE@XZ @ 975 NONAME ; eapol_wlan_authentication_c::~eapol_wlan_authentication_c(void) + ??0eap_file_config_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 976 NONAME ; eap_file_config_c::eap_file_config_c(class abs_eap_am_tools_c *) + ?get_header_length@eapol_header_base_c@@SAKXZ @ 977 NONAME ; unsigned long eapol_header_base_c::get_header_length(void) + ?am_cancel_all_timers@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@XZ @ 978 NONAME ; enum eap_status_e eap_am_tools_symbian_c::am_cancel_all_timers(void) + ?get_md4_block_size@eap_am_crypto_symbian_c@@UAEKPAVeap_variable_data_c@@@Z @ 979 NONAME ; unsigned long eap_am_crypto_symbian_c::get_md4_block_size(class eap_variable_data_c *) + ?set_encryption_key_3des_ede@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEK@Z @ 980 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::set_encryption_key_3des_ede(class eap_variable_data_c *, unsigned char const *, unsigned long) + ?set_stack_address@eap_buf_chain_base_c@@QAEXPBX@Z @ 981 NONAME ; void eap_buf_chain_base_c::set_stack_address(void const *) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@_K@Z @ 982 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(unsigned long long) + ?read_configure@eap_file_config_c@@AAE?AW4eap_status_e@@PAV?$eap_core_map_c@Veap_config_value_c@@Vabs_eap_core_map_c@@Veap_variable_data_c@@@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@PAW4eap_configure_type_e@@_N@Z @ 983 NONAME ; enum eap_status_e eap_file_config_c::read_configure(class eap_core_map_c *, class eap_configuration_field_c const *, class eap_variable_data_c *, enum eap_configure_type_e *, bool) + ?nt_password_hash@crypto_nt_hash_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@PAV3@K@Z @ 984 NONAME ; enum eap_status_e crypto_nt_hash_c::nt_password_hash(class eap_variable_data_c const *, class eap_variable_data_c *, unsigned long) + ?encrypt_data@crypto_cbc_c@@UAE?AW4eap_status_e@@PAXK@Z @ 985 NONAME ; enum eap_status_e crypto_cbc_c::encrypt_data(void *, unsigned long) + ?get_code_string@eap_header_base_c@@QBEPBDXZ @ 986 NONAME ; char const * eap_header_base_c::get_code_string(void) const + ?remove_reference@eap_am_mutex_reference_c@@QAEXXZ @ 987 NONAME ; void eap_am_mutex_reference_c::remove_reference(void) + ?rsa_verify@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@11@Z @ 988 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rsa_verify(class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ?eap_acknowledge@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 989 NONAME ; enum eap_status_e eapol_core_c::eap_acknowledge(class eap_am_network_id_c const *) + ?open_crypto_memory_leaks@eap_am_crypto_symbian_c@@AAEXXZ @ 990 NONAME ; void eap_am_crypto_symbian_c::open_crypto_memory_leaks(void) + ?set_is_valid@eap_am_crypto_rc4_c@@AAEXXZ @ 991 NONAME ; void eap_am_crypto_rc4_c::set_is_valid(void) + ?force_inheritance@eap_buf_chain_wr_c@@EAEXXZ @ 992 NONAME ; void eap_buf_chain_wr_c::force_inheritance(void) + ?set_is_client@eap_buf_chain_base_c@@QAEX_N@Z @ 993 NONAME ; void eap_buf_chain_base_c::set_is_client(bool) + ?check_is_valid_eap_type@ethernet_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 994 NONAME ; enum eap_status_e ethernet_core_c::check_is_valid_eap_type(class eap_expanded_type_c) + ?get_key_information@eapol_RSNA_key_header_c@@QBEGXZ @ 995 NONAME ; unsigned short eapol_RSNA_key_header_c::get_key_information(void) const + ?set_is_valid@crypto_aes_c@@UAEXXZ @ 996 NONAME ; void crypto_aes_c::set_is_valid(void) + ?set_is_invalid@crypto_eap_fast_hmac_sha1_prf_c@@AAEXXZ @ 997 NONAME ; void crypto_eap_fast_hmac_sha1_prf_c::set_is_invalid(void) + ?set_partner@eap_core_c@@QAEXPAVabs_eap_core_c@@@Z @ 998 NONAME ; void eap_core_c::set_partner(class abs_eap_core_c *) + ?get_version@eapol_header_base_c@@QBE?AW4eapol_protocol_version_e@@XZ @ 999 NONAME ; enum eapol_protocol_version_e eapol_header_base_c::get_version(void) const + ??0crypto_tls_sha1_prf_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1000 NONAME ; crypto_tls_sha1_prf_c::crypto_tls_sha1_prf_c(class abs_eap_am_tools_c *) + ?get_block_size@crypto_md4_c@@UAEKXZ @ 1001 NONAME ; unsigned long crypto_md4_c::get_block_size(void) + ?timer_thread_function@eap_am_tools_c@@UAE?AW4eap_status_e@@XZ @ 1002 NONAME ; enum eap_status_e eap_am_tools_c::timer_thread_function(void) + ?get_payload_size@eapol_handle_tlv_message_data_c@@QBEKPAVsimple_config_credential_c@@@Z @ 1003 NONAME ; unsigned long eapol_handle_tlv_message_data_c::get_payload_size(class simple_config_credential_c *) const + ?set_eapol_protocol_version@eapol_RC4_key_header_c@@QAE?AW4eap_status_e@@W4eapol_protocol_version_e@@@Z @ 1004 NONAME ; enum eap_status_e eapol_RC4_key_header_c::set_eapol_protocol_version(enum eapol_protocol_version_e) + ?packet_send@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 1005 NONAME ; enum eap_status_e eapol_wlan_authentication_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long) + ?packet_process@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 1006 NONAME ; enum eap_status_e eapol_wlan_authentication_c::packet_process(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long) + ?begin_db_update@eap_am_tools_symbian_c@@QAE?AW4eap_status_e@@AAVRDbView@@@Z @ 1007 NONAME ; enum eap_status_e eap_am_tools_symbian_c::begin_db_update(class RDbView &) + ?generic_convert_utf8_to_unicode@eap_am_tools_c@@QAE?AW4eap_status_e@@AAVeap_variable_data_c@@ABV3@@Z @ 1008 NONAME ; enum eap_status_e eap_am_tools_c::generic_convert_utf8_to_unicode(class eap_variable_data_c &, class eap_variable_data_c const &) + ?packet_data_session_key@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeapol_session_key_c@@@Z @ 1009 NONAME ; enum eap_status_e eapol_wlan_authentication_c::packet_data_session_key(class eap_am_network_id_c const *, class eapol_session_key_c const *) + ?packet_send@eapol_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 1010 NONAME ; enum eap_status_e eapol_core_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long) + ?add_rogue_ap@eap_session_core_c@@UAE?AW4eap_status_e@@AAV?$eap_array_c@Veap_rogue_ap_entry_c@@@@@Z @ 1011 NONAME ; enum eap_status_e eap_session_core_c::add_rogue_ap(class eap_array_c &) + ?get_current_eap_index@eapol_wlan_authentication_c@@UAEKXZ @ 1012 NONAME ; unsigned long eapol_wlan_authentication_c::get_current_eap_index(void) + ?set_key@crypto_rc4_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 1013 NONAME ; enum eap_status_e crypto_rc4_c::set_key(class eap_variable_data_c const *) + ?encrypt_data@crypto_rc4_c@@UAE?AW4eap_status_e@@PAXK@Z @ 1014 NONAME ; enum eap_status_e crypto_rc4_c::encrypt_data(void *, unsigned long) + ??0eapol_header_base_c@@QAE@PAVabs_eap_am_tools_c@@PAXK@Z @ 1015 NONAME ; eapol_header_base_c::eapol_header_base_c(class abs_eap_am_tools_c *, void *, unsigned long) + ?get_is_valid@crypto_ephemeral_diffie_hellman_c@@QAE_NXZ @ 1016 NONAME ; bool crypto_ephemeral_diffie_hellman_c::get_is_valid(void) + ?complete_WPXM_reassociation@eapol_core_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@@Z @ 1017 NONAME ; enum eap_status_e eapol_core_c::complete_WPXM_reassociation(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *) + ?get_is_valid@eap_core_retransmission_c@@QBE_NXZ @ 1018 NONAME ; bool eap_core_retransmission_c::get_is_valid(void) const + ?read_reassociation_parameters@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@0W4eapol_key_authentication_type_e@@PAVeap_variable_data_c@@PBV5@3@Z @ 1019 NONAME ; enum eap_status_e ethernet_core_c::read_reassociation_parameters(class eap_am_network_id_c const *, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ??1crypto_dsa_c@@UAE@XZ @ 1020 NONAME ; crypto_dsa_c::~crypto_dsa_c(void) + ?resend_packet@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 1021 NONAME ; enum eap_status_e eapol_key_state_c::resend_packet(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAVeap_variable_data_c@@@Z @ 1022 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, class eap_variable_data_c *) + ?set_is_valid@crypto_sha_256_c@@EAEXXZ @ 1023 NONAME ; void crypto_sha_256_c::set_is_valid(void) + ??1eapol_key_state_c@@UAE@XZ @ 1024 NONAME ; eapol_key_state_c::~eapol_key_state_c(void) + ??0eap_variable_data_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1025 NONAME ; eap_variable_data_c::eap_variable_data_c(class abs_eap_am_tools_c *) + ?get_trace_mutex@eap_am_tools_symbian_c@@QAEPAVabs_eap_am_mutex_c@@XZ @ 1026 NONAME ; class abs_eap_am_mutex_c * eap_am_tools_symbian_c::get_trace_mutex(void) + ?object_increase_reference_count@eapol_handle_tlv_message_data_c@@QAEXXZ @ 1027 NONAME ; void eapol_handle_tlv_message_data_c::object_increase_reference_count(void) + ?decrypt_block@crypto_aes_wrap_c@@QAE?AW4eap_status_e@@PBXKPAXK@Z @ 1028 NONAME ; enum eap_status_e crypto_aes_wrap_c::decrypt_block(void const *, unsigned long, void *, unsigned long) + ?file_delete@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 1029 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_delete(class eap_variable_data_c const *) + ?get_eap_type_string@eap_header_string_c@@SAPBDVeap_expanded_type_c@@@Z @ 1030 NONAME ; char const * eap_header_string_c::get_eap_type_string(class eap_expanded_type_c) + ??0eapol_handle_tlv_message_data_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1031 NONAME ; eapol_handle_tlv_message_data_c::eapol_handle_tlv_message_data_c(class abs_eap_am_tools_c *) + ??1eap_state_notification_c@@UAE@XZ @ 1032 NONAME ; eap_state_notification_c::~eap_state_notification_c(void) + ?hmac_final@crypto_hmac_c@@UAE?AW4eap_status_e@@PAXPAK@Z @ 1033 NONAME ; enum eap_status_e crypto_hmac_c::hmac_final(void *, unsigned long *) + ?file_read_line@eap_file_config_c@@AAE?AW4eap_status_e@@PAVabs_eap_am_file_input_c@@PAVeap_variable_data_c@@@Z @ 1034 NONAME ; enum eap_status_e eap_file_config_c::file_read_line(class abs_eap_am_file_input_c *, class eap_variable_data_c *) + ?get_is_client@eap_state_notification_c@@UBE_NXZ @ 1035 NONAME ; bool eap_state_notification_c::get_is_client(void) const + ??0crypto_wpa_psk_password_hash_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1036 NONAME ; crypto_wpa_psk_password_hash_c::crypto_wpa_psk_password_hash_c(class abs_eap_am_tools_c *) + ??0network_key_and_index_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1037 NONAME ; network_key_and_index_c::network_key_and_index_c(class abs_eap_am_tools_c *) + ?get_header_offset@eap_general_header_base_c@@QBEPAEKK@Z @ 1038 NONAME ; unsigned char * eap_general_header_base_c::get_header_offset(unsigned long, unsigned long) const + ?check_pmksa_cache@eapol_core_c@@QAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_am_network_id_c@@@@W4eapol_key_authentication_type_e@@W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@2@Z @ 1039 NONAME ; enum eap_status_e eapol_core_c::check_pmksa_cache(class eap_array_c *, enum eapol_key_authentication_type_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e) + ?get_key_STA_MAC_address@eapol_RSNA_key_header_c@@QBEPAEXZ @ 1040 NONAME ; unsigned char * eapol_RSNA_key_header_c::get_key_STA_MAC_address(void) const + ?cancel_eap_failure_timeout@eap_core_c@@AAE?AW4eap_status_e@@XZ @ 1041 NONAME ; enum eap_status_e eap_core_c::cancel_eap_failure_timeout(void) + ?get_protocol_layer@eap_state_notification_c@@UBE?AW4eap_protocol_layer_e@@XZ @ 1042 NONAME ; enum eap_protocol_layer_e eap_state_notification_c::get_protocol_layer(void) const + ?get_replay_counter@eapol_RC4_key_header_c@@QAEPAEXZ @ 1043 NONAME ; unsigned char * eapol_RC4_key_header_c::get_replay_counter(void) + ?set_do_length_checks@eap_buf_chain_base_c@@QAEX_N@Z @ 1044 NONAME ; void eap_buf_chain_base_c::set_do_length_checks(bool) + ?get_buffer_length@eap_buf_chain_base_c@@QBEKXZ @ 1045 NONAME ; unsigned long eap_buf_chain_base_c::get_buffer_length(void) const + ?set_encryption_key@crypto_3des_ede_c@@UAE?AW4eap_status_e@@PBXK@Z @ 1046 NONAME ; enum eap_status_e crypto_3des_ede_c::set_encryption_key(void const *, unsigned long) + ??0eap_general_header_base_c@@QAE@PAVabs_eap_am_tools_c@@PAXK@Z @ 1047 NONAME ; eap_general_header_base_c::eap_general_header_base_c(class abs_eap_am_tools_c *, void *, unsigned long) + ?get_state_string@eap_simple_config_trace_string_c@@QBEPBDW4simple_config_state_e@@@Z @ 1048 NONAME ; char const * eap_simple_config_trace_string_c::get_state_string(enum simple_config_state_e) const + ?start_authentication@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@W4eapol_key_authentication_type_e@@0_NPBVeap_am_network_id_c@@@Z @ 1049 NONAME ; enum eap_status_e eapol_wlan_authentication_c::start_authentication(class eap_variable_data_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, bool, class eap_am_network_id_c const *) + ?get_type_string@eapol_handle_tlv_message_data_c@@QAEPBDW4eapol_tlv_message_type_e@@@Z @ 1050 NONAME ; char const * eapol_handle_tlv_message_data_c::get_type_string(enum eapol_tlv_message_type_e) + ?parse_key_data@eapol_key_state_c@@AAE?AW4eap_status_e@@W4eapol_key_descriptor_type_e@@PBVeapol_rsna_key_data_header_c@@PAKPAVeapol_rsna_key_data_payloads_c@@W4eapol_key_state_e@@W4key_descriptor_version_e@eapol_RSNA_key_header_c@@@Z @ 1051 NONAME ; enum eap_status_e eapol_key_state_c::parse_key_data(enum eapol_key_descriptor_type_e, class eapol_rsna_key_data_header_c const *, unsigned long *, class eapol_rsna_key_data_payloads_c *, enum eapol_key_state_e, enum eapol_RSNA_key_header_c::key_descriptor_version_e) + ?get_data@eap_header_base_c@@QBEPAEK@Z @ 1052 NONAME ; unsigned char * eap_header_base_c::get_data(unsigned long) const + ?reset_header@eapol_header_wr_c@@QAEXG@Z @ 1053 NONAME ; void eapol_header_wr_c::reset_header(unsigned short) + ?get_eapol_packet_type@eapol_RSNA_key_header_c@@QBE?AW4eapol_packet_type_e@@XZ @ 1054 NONAME ; enum eapol_packet_type_e eapol_RSNA_key_header_c::get_eapol_packet_type(void) const + ?get_is_valid@eapol_handle_tlv_message_data_c@@QAE_NXZ @ 1055 NONAME ; bool eapol_handle_tlv_message_data_c::get_is_valid(void) + ?xor_u64@eap_am_tools_c@@UAE_K_K0@Z @ 1056 NONAME ; unsigned long long eap_am_tools_c::xor_u64(unsigned long long, unsigned long long) + ?swap@eap_am_crypto_rc4_c@@AAEXPAE0@Z @ 1057 NONAME ; void eap_am_crypto_rc4_c::swap(unsigned char *, unsigned char *) + ?eap_read_u32_t_network_order@@YAKPBXK@Z @ 1058 NONAME ; unsigned long eap_read_u32_t_network_order(void const *, unsigned long) + ?get_key_length@crypto_aes_c@@UAEKXZ @ 1059 NONAME ; unsigned long crypto_aes_c::get_key_length(void) + ?get_partner@eap_core_c@@QAEPAVabs_eap_core_c@@XZ @ 1060 NONAME ; class abs_eap_core_c * eap_core_c::get_partner(void) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeapol_session_key_c@@@Z @ 1061 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(class eapol_session_key_c const *) + ??1eap_am_memory_store_tlv_data_c@@UAE@XZ @ 1062 NONAME ; eap_am_memory_store_tlv_data_c::~eap_am_memory_store_tlv_data_c(void) + ?set_is_valid@crypto_rsa_c@@AAEXXZ @ 1063 NONAME ; void crypto_rsa_c::set_is_valid(void) + ?set_max_trace_file_size@eap_am_tools_symbian_c@@UAEXK@Z @ 1064 NONAME ; void eap_am_tools_symbian_c::set_max_trace_file_size(unsigned long) + ?set_is_invalid@crypto_md4_c@@AAEXXZ @ 1065 NONAME ; void crypto_md4_c::set_is_invalid(void) + ?set_wlan_parameters@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@_N0W4eapol_key_authentication_type_e@@@Z @ 1066 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::set_wlan_parameters(class eap_variable_data_c const *, bool, class eap_variable_data_c const *, enum eapol_key_authentication_type_e) + ?set_timer@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 1067 NONAME ; enum eap_status_e eapol_wlan_authentication_c::set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long) + ?enter_trace_mutex@eap_am_tools_symbian_c@@QAEXXZ @ 1068 NONAME ; void eap_am_tools_symbian_c::enter_trace_mutex(void) + ?md4_update@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEK@Z @ 1069 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::md4_update(class eap_variable_data_c *, unsigned char const *, unsigned long) + ??0eap_expanded_type_c@@QAE@W4eap_type_ietf_values_e@@@Z @ 1070 NONAME ; eap_expanded_type_c::eap_expanded_type_c(enum eap_type_ietf_values_e) + ?get_is_valid@eapol_am_wlan_authentication_symbian_c@@UAE_NXZ @ 1071 NONAME ; bool eapol_am_wlan_authentication_symbian_c::get_is_valid(void) + ?allocate_buffer@eap_variable_data_c@@AAE?AW4eap_status_e@@K@Z @ 1072 NONAME ; enum eap_status_e eap_variable_data_c::allocate_buffer(unsigned long) + ?derive_WPXM_PTK@eapol_key_state_c@@AAE?AW4eap_status_e@@K@Z @ 1073 NONAME ; enum eap_status_e eapol_key_state_c::derive_WPXM_PTK(unsigned long) + ?get_md4_digest_length@eap_am_crypto_symbian_c@@UAEKPAVeap_variable_data_c@@@Z @ 1074 NONAME ; unsigned long eap_am_crypto_symbian_c::get_md4_digest_length(class eap_variable_data_c *) + ?set_authentication_error@eap_state_notification_c@@UAEXW4eap_status_e@@@Z @ 1075 NONAME ; void eap_state_notification_c::set_authentication_error(enum eap_status_e) + ?set_client_send_key_reply_counter@eapol_key_state_c@@AAEX_K@Z @ 1076 NONAME ; void eapol_key_state_c::set_client_send_key_reply_counter(unsigned long long) + ?eap_acknowledge@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 1077 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::eap_acknowledge(class eap_array_c const *) + ?rc4_set_key@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@@Z @ 1078 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rc4_set_key(class eap_variable_data_c *, class eap_variable_data_c const *) + ?process_group_key_handshake_message_1@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K@Z @ 1079 NONAME ; enum eap_status_e eapol_key_state_c::process_group_key_handshake_message_1(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long) + ?get_header_length@eap_tlv_header_c@@SAKXZ @ 1080 NONAME ; unsigned long eap_tlv_header_c::get_header_length(void) + ?initialize@eap_buf_chain_base_c@@AAE?AW4eap_status_e@@K@Z @ 1081 NONAME ; enum eap_status_e eap_buf_chain_base_c::initialize(unsigned long) + ??0eap_expanded_type_c@@QAE@XZ @ 1082 NONAME ; eap_expanded_type_c::eap_expanded_type_c(void) + ??0eap_state_notification_c@@QAE@PAVabs_eap_am_tools_c@@PBVeap_am_network_id_c@@_NW4eap_state_notification_eap_e@@W4eap_protocol_layer_e@@Veap_expanded_type_c@@KKE2@Z @ 1083 NONAME ; eap_state_notification_c::eap_state_notification_c(class abs_eap_am_tools_c *, class eap_am_network_id_c const *, bool, enum eap_state_notification_eap_e, enum eap_protocol_layer_e, class eap_expanded_type_c, unsigned long, unsigned long, unsigned char, bool) + ?copy@eap_am_crypto_sha1_c@@QAEPAV1@XZ @ 1084 NONAME ; class eap_am_crypto_sha1_c * eap_am_crypto_sha1_c::copy(void) + ??1eap_variable_data_c@@UAE@XZ @ 1085 NONAME ; eap_variable_data_c::~eap_variable_data_c(void) + ?object_decrease_reference_count@eap_am_memory_store_tlv_data_c@@QAEKXZ @ 1086 NONAME ; unsigned long eap_am_memory_store_tlv_data_c::object_decrease_reference_count(void) + ?restart_with_new_type@eap_core_c@@AAE?AW4eap_status_e@@Veap_expanded_type_c@@PBVeap_am_network_id_c@@E@Z @ 1087 NONAME ; enum eap_status_e eap_core_c::restart_with_new_type(class eap_expanded_type_c, class eap_am_network_id_c const *, unsigned char) + ?get_payload_size@eapol_handle_tlv_message_data_c@@QBEKPBVabs_eap_state_notification_c@@@Z @ 1088 NONAME ; unsigned long eapol_handle_tlv_message_data_c::get_payload_size(class abs_eap_state_notification_c const *) const + ??0eap_core_retransmission_c@@QAE@PAVabs_eap_am_tools_c@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKKKW4eap_code_value_e@@EVeap_expanded_type_c@@@Z @ 1089 NONAME ; eap_core_retransmission_c::eap_core_retransmission_c(class abs_eap_am_tools_c *, class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long, unsigned long, enum eap_code_value_e, unsigned char, class eap_expanded_type_c) + ?init@eap_variable_data_c@@QAE?AW4eap_status_e@@K@Z @ 1090 NONAME ; enum eap_status_e eap_variable_data_c::init(unsigned long) + ?get_eap_code_string@eap_header_string_c@@SAPBDW4eap_code_value_e@@@Z @ 1091 NONAME ; char const * eap_header_string_c::get_eap_code_string(enum eap_code_value_e) + ??1network_key_and_index_c@@UAE@XZ @ 1092 NONAME ; network_key_and_index_c::~network_key_and_index_c(void) + ?copy_context@eap_am_crypto_sha1_c@@AAE?AW4eap_status_e@@PBVeap_variable_data_c@@_KPBK22@Z @ 1093 NONAME ; enum eap_status_e eap_am_crypto_sha1_c::copy_context(class eap_variable_data_c const *, unsigned long long, unsigned long const *, unsigned long const *, unsigned long const *) + ??0eap_network_id_selector_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1094 NONAME ; eap_network_id_selector_c::eap_network_id_selector_c(class abs_eap_am_tools_c *) + ?compare@eap_variable_data_c@@QBEJPBXK@Z @ 1095 NONAME ; long eap_variable_data_c::compare(void const *, unsigned long) const + ?copy@crypto_md4_c@@UAEPAVabs_crypto_hash_algorithm_c@@XZ @ 1096 NONAME ; class abs_crypto_hash_algorithm_c * crypto_md4_c::copy(void) + ?generate_g_power_to_xy@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@PBEK2K@Z @ 1097 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::generate_g_power_to_xy(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *, unsigned char const *, unsigned long, unsigned char const *, unsigned long) + ?directory_read@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PAV?$eap_array_c@Vabs_eap_file_stat_c@@@@@Z @ 1098 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::directory_read(class eap_array_c *) + ?get_is_valid@simple_config_credential_c@@QAE_NXZ @ 1099 NONAME ; bool simple_config_credential_c::get_is_valid(void) + ?set_trace_mask@eap_am_tools_c@@UAEXK@Z @ 1100 NONAME ; void eap_am_tools_c::set_trace_mask(unsigned long) + ?dsa_verify@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@11111@Z @ 1101 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::dsa_verify(class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ?file_read_word@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 1102 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_read_word(class eap_variable_data_c *) + ?set_is_valid@eap_am_memory_store_c@@AAEXXZ @ 1103 NONAME ; void eap_am_memory_store_c::set_is_valid(void) + ?process_4_way_handshake_message_4@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K@Z @ 1104 NONAME ; enum eap_status_e eapol_key_state_c::process_4_way_handshake_message_4(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long) + ?set_buffer@eap_variable_data_c@@QAE?AW4eap_status_e@@PBV1@@Z @ 1105 NONAME ; enum eap_status_e eap_variable_data_c::set_buffer(class eap_variable_data_c const *) + ?get_network_key@network_key_and_index_c@@QAEPAVeap_variable_data_c@@XZ @ 1106 NONAME ; class eap_variable_data_c * network_key_and_index_c::get_network_key(void) + ?handle_eap_identity_response@eap_core_c@@AAE?AW4eap_status_e@@PAVeap_base_type_c@@Veap_expanded_type_c@@PBVeap_am_network_id_c@@PAVeap_header_wr_c@@K@Z @ 1107 NONAME ; enum eap_status_e eap_core_c::handle_eap_identity_response(class eap_base_type_c *, class eap_expanded_type_c, class eap_am_network_id_c const *, class eap_header_wr_c *, unsigned long) + ?init_handshake_timeout@eapol_key_state_c@@AAE?AW4eap_status_e@@K@Z @ 1108 NONAME ; enum eap_status_e eapol_key_state_c::init_handshake_timeout(unsigned long) + ?set_eapol_key_state@eapol_key_state_c@@AAEXW4eapol_key_state_e@@@Z @ 1109 NONAME ; void eapol_key_state_c::set_eapol_key_state(enum eapol_key_state_e) + ?set_type_data_length@eap_header_base_c@@QAEXG_N@Z @ 1110 NONAME ; void eap_header_base_c::set_type_data_length(unsigned short, bool) + ?get_eap_expanded_type_size@eap_expanded_type_c@@SAKXZ @ 1111 NONAME ; unsigned long eap_expanded_type_c::get_eap_expanded_type_size(void) + ?init_retransmission@eap_core_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKW4eap_code_value_e@@EVeap_expanded_type_c@@@Z @ 1112 NONAME ; enum eap_status_e eap_core_c::init_retransmission(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, enum eap_code_value_e, unsigned char, class eap_expanded_type_c) + ?cancel_group_key_update_timeout@eapol_key_state_c@@AAE?AW4eap_status_e@@XZ @ 1113 NONAME ; enum eap_status_e eapol_key_state_c::cancel_group_key_update_timeout(void) + ?set_eapol_packet_body_length@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@K@Z @ 1114 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_eapol_packet_body_length(unsigned long) + ?new_eapol_am_wlan_authentication@eapol_am_wlan_authentication_c@@SAPAV1@PAVabs_eap_am_tools_c@@_NPBVabs_eapol_wlan_database_reference_if_c@@@Z @ 1115 NONAME ; class eapol_am_wlan_authentication_c * eapol_am_wlan_authentication_c::new_eapol_am_wlan_authentication(class abs_eap_am_tools_c *, bool, class abs_eapol_wlan_database_reference_if_c const *) + ?create_4_way_handshake_message_3@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeap_buf_chain_wr_c@@KPAK1W4eapol_protocol_version_e@@W4eapol_key_descriptor_type_e@@@Z @ 1116 NONAME ; enum eap_status_e eapol_key_state_c::create_4_way_handshake_message_3(class eap_buf_chain_wr_c *, unsigned long, unsigned long *, unsigned long *, enum eapol_protocol_version_e, enum eapol_key_descriptor_type_e) + ?update_header_offset@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 1117 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::update_header_offset(class eap_array_c const *) + ?asynchronous_init_remove_eap_session@eapol_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 1118 NONAME ; enum eap_status_e eapol_core_c::asynchronous_init_remove_eap_session(class eap_am_network_id_c const *) + ??1crypto_md4_c@@UAE@XZ @ 1119 NONAME ; crypto_md4_c::~crypto_md4_c(void) + ?leave_trace_mutex@eap_am_tools_symbian_c@@QAEXXZ @ 1120 NONAME ; void eap_am_tools_symbian_c::leave_trace_mutex(void) + ?get_is_valid@eap_am_memory_store_c@@QAE_NXZ @ 1121 NONAME ; bool eap_am_memory_store_c::get_is_valid(void) + ?cancel_all_timers@eap_core_c@@UAE?AW4eap_status_e@@XZ @ 1122 NONAME ; enum eap_status_e eap_core_c::cancel_all_timers(void) + ?get_digest_length@crypto_sha1_c@@UAEKXZ @ 1123 NONAME ; unsigned long crypto_sha1_c::get_digest_length(void) + ?remove_leading_spaces@eap_file_config_c@@AAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 1124 NONAME ; enum eap_status_e eap_file_config_c::remove_leading_spaces(class eap_variable_data_c *) + ?timer_delete_data@eap_core_c@@UAE?AW4eap_status_e@@KPAX@Z @ 1125 NONAME ; enum eap_status_e eap_core_c::timer_delete_data(unsigned long, void *) + ??0eap_buf_chain_base_c@@QAE@W4eap_read_buffer_e@@PAVabs_eap_am_tools_c@@K@Z @ 1126 NONAME ; eap_buf_chain_base_c::eap_buf_chain_base_c(enum eap_read_buffer_e, class abs_eap_am_tools_c *, unsigned long) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAG@Z @ 1127 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, unsigned short *) + ?set_Encryption_Type@simple_config_credential_c@@QAEXW4simple_config_Encryption_Type_e@@@Z @ 1128 NONAME ; void simple_config_credential_c::set_Encryption_Type(enum simple_config_Encryption_Type_e) + ?get_is_RSNA@eapol_key_state_c@@AAE_NXZ @ 1129 NONAME ; bool eapol_key_state_c::get_is_RSNA(void) + ??0eap_am_file_input_symbian_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1130 NONAME ; eap_am_file_input_symbian_c::eap_am_file_input_symbian_c(class abs_eap_am_tools_c *) + ?get_ethernet_header@eap_buf_chain_wr_c@@QAEPAEXZ @ 1131 NONAME ; unsigned char * eap_buf_chain_wr_c::get_ethernet_header(void) + ?tls_prf_A_value@crypto_tls_base_prf_c@@QAE?AW4eap_status_e@@PAVabs_crypto_hmac_algorithm_c@@PAVeap_variable_data_c@@11@Z @ 1132 NONAME ; enum eap_status_e crypto_tls_base_prf_c::tls_prf_A_value(class abs_crypto_hmac_algorithm_c *, class eap_variable_data_c *, class eap_variable_data_c *, class eap_variable_data_c *) + ?convert_eapol_error_to_am_error@eap_am_tools_symbian_c@@UAEJW4eap_status_e@@@Z @ 1133 NONAME ; long eap_am_tools_symbian_c::convert_eapol_error_to_am_error(enum eap_status_e) + ?get_key_descriptor_type@eapol_RSNA_key_header_c@@QBE?AW4eapol_key_descriptor_type_e@@XZ @ 1134 NONAME ; enum eapol_key_descriptor_type_e eapol_RSNA_key_header_c::get_key_descriptor_type(void) const + ?get_current_state_string@eap_state_notification_c@@UBEPBDXZ @ 1135 NONAME ; char const * eap_state_notification_c::get_current_state_string(void) const + ?get_key@eapol_RC4_key_header_c@@QBEPAEXZ @ 1136 NONAME ; unsigned char * eapol_RC4_key_header_c::get_key(void) const + ?set_data_length@eap_variable_data_c@@QAE?AW4eap_status_e@@K@Z @ 1137 NONAME ; enum eap_status_e eap_variable_data_c::set_data_length(unsigned long) + ?tkip_mic_failure@eapol_key_state_c@@QAE?AW4eap_status_e@@_NW4eapol_tkip_mic_failure_type_e@eapol_RSNA_key_header_c@@@Z @ 1138 NONAME ; enum eap_status_e eapol_key_state_c::tkip_mic_failure(bool, enum eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e) + ?set_key_tx_bit@eapol_session_key_c@@QAEX_N@Z @ 1139 NONAME ; void eapol_session_key_c::set_key_tx_bit(bool) + ?aes_cleanup@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 1140 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::aes_cleanup(class eap_variable_data_c *) + ?get_data_offset@eap_buf_chain_rd_c@@QBEPBEKK@Z @ 1141 NONAME ; unsigned char const * eap_buf_chain_rd_c::get_data_offset(unsigned long, unsigned long) const + ?cancel_timer@eap_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 1142 NONAME ; enum eap_status_e eap_core_c::cancel_timer(class abs_eap_base_timer_c *, unsigned long) + ??0eapol_ethernet_header_base_c@@QAE@PAVabs_eap_am_tools_c@@PAXK@Z @ 1143 NONAME ; eapol_ethernet_header_base_c::eapol_ethernet_header_base_c(class abs_eap_am_tools_c *, void *, unsigned long) + ?get_data_offset@eap_variable_data_c@@QBEPAEKK@Z @ 1144 NONAME ; unsigned char * eap_variable_data_c::get_data_offset(unsigned long, unsigned long) const + ?sha1_copy_context@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@@Z @ 1145 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::sha1_copy_context(class eap_variable_data_c *, class eap_variable_data_c const *) + ?cancel_timer@eapol_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 1146 NONAME ; enum eap_status_e eapol_core_c::cancel_timer(class abs_eap_base_timer_c *, unsigned long) + ?state_notification@eapol_core_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 1147 NONAME ; void eapol_core_c::state_notification(class abs_eap_state_notification_c const *) + ??0crypto_eap_fast_hmac_sha1_prf_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1148 NONAME ; crypto_eap_fast_hmac_sha1_prf_c::crypto_eap_fast_hmac_sha1_prf_c(class abs_eap_am_tools_c *) + ?tls_prf_cleanup@crypto_tls_base_prf_c@@QAE?AW4eap_status_e@@XZ @ 1149 NONAME ; enum eap_status_e crypto_tls_base_prf_c::tls_prf_cleanup(void) + ?set_key_information_secure@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@_N@Z @ 1150 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_information_secure(bool) + ?get_is_valid@network_key_and_index_c@@QAE_NXZ @ 1151 NONAME ; bool network_key_and_index_c::get_is_valid(void) + ?internal_encrypt_data@crypto_cbc_c@@AAE?AW4eap_status_e@@PBXPAXK@Z @ 1152 NONAME ; enum eap_status_e crypto_cbc_c::internal_encrypt_data(void const *, void *, unsigned long) + ??0eap_simple_config_trace_string_c@@QAE@XZ @ 1153 NONAME ; eap_simple_config_trace_string_c::eap_simple_config_trace_string_c(void) + ??1eapol_handle_tlv_message_data_c@@UAE@XZ @ 1154 NONAME ; eapol_handle_tlv_message_data_c::~eapol_handle_tlv_message_data_c(void) + ?set_encryption_key@crypto_aes_c@@UAE?AW4eap_status_e@@PBXK@Z @ 1155 NONAME ; enum eap_status_e crypto_aes_c::set_encryption_key(void const *, unsigned long) + ?save_parameters@eapol_key_state_c@@AAE?AW4eap_status_e@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@1W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@2@Z @ 1156 NONAME ; enum eap_status_e eapol_key_state_c::save_parameters(enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e) + ??1eap_am_crypto_sha_256_c@@UAE@XZ @ 1157 NONAME ; eap_am_crypto_sha_256_c::~eap_am_crypto_sha_256_c(void) + ?get_new_key_from_sha@crypto_nt_hash_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@K@Z @ 1158 NONAME ; enum eap_status_e crypto_nt_hash_c::get_new_key_from_sha(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *, unsigned long) + ?configure@ethernet_core_c@@UAE?AW4eap_status_e@@XZ @ 1159 NONAME ; enum eap_status_e ethernet_core_c::configure(void) + ?shutdown@eap_am_memory_store_c@@QAE?AW4eap_status_e@@XZ @ 1160 NONAME ; enum eap_status_e eap_am_memory_store_c::shutdown(void) + ?reset_operation@eap_core_c@@CA?AW4eap_status_e@@PAVeap_base_type_c@@PAVabs_eap_am_tools_c@@@Z @ 1161 NONAME ; enum eap_status_e eap_core_c::reset_operation(class eap_base_type_c *, class abs_eap_am_tools_c *) + ?cbc_xor_block@crypto_cbc_c@@AAEXPBXPAXKK@Z @ 1162 NONAME ; void crypto_cbc_c::cbc_xor_block(void const *, void *, unsigned long, unsigned long) + ?close_crypto_memory_leaks@eap_am_crypto_symbian_c@@AAEXXZ @ 1163 NONAME ; void eap_am_crypto_symbian_c::close_crypto_memory_leaks(void) + ?unset_marked_removed@eap_core_c@@QAEXXZ @ 1164 NONAME ; void eap_core_c::unset_marked_removed(void) + ?directory_open@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 1165 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::directory_open(class eap_variable_data_c const *) + ?memory_store_remove_data@eap_am_tools_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 1166 NONAME ; enum eap_status_e eap_am_tools_c::memory_store_remove_data(class eap_variable_data_c const *) + ?set_is_reserved@eap_am_mutex_reference_c@@QAEX_N@Z @ 1167 NONAME ; void eap_am_mutex_reference_c::set_is_reserved(bool) + ?synchronous_cancel_all_eap_sessions@eap_session_core_c@@QAE?AW4eap_status_e@@XZ @ 1168 NONAME ; enum eap_status_e eap_session_core_c::synchronous_cancel_all_eap_sessions(void) + ?associate@eapol_message_wlan_authentication_c@@UAE?AW4eap_status_e@@W4eapol_key_802_11_authentication_mode_e@@@Z @ 1169 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::associate(enum eapol_key_802_11_authentication_mode_e) + ?asynchronous_init_remove_eapol_key_state@eapol_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 1170 NONAME ; enum eap_status_e eapol_core_c::asynchronous_init_remove_eapol_key_state(class eap_am_network_id_c const *) + ?get_key_information_reserved_a@eapol_RSNA_key_header_c@@QBEEXZ @ 1171 NONAME ; unsigned char eapol_RSNA_key_header_c::get_key_information_reserved_a(void) const + ?start_4_way_handshake@eapol_key_state_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 1172 NONAME ; enum eap_status_e eapol_key_state_c::start_4_way_handshake(class eap_am_network_id_c const *) + ?hash_update@crypto_md4_c@@UAE?AW4eap_status_e@@PBXK@Z @ 1173 NONAME ; enum eap_status_e crypto_md4_c::hash_update(void const *, unsigned long) + ?rsna_prf@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_variable_data_c@@00KPAV3@@Z @ 1174 NONAME ; enum eap_status_e eapol_key_state_c::rsna_prf(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, unsigned long, class eap_variable_data_c *) + ?convert@wlan_eap_if_send_status_conversion_c@@SA?AW4eap_status_e@@W4wlan_eap_if_send_status_e@@@Z @ 1175 NONAME ; enum eap_status_e wlan_eap_if_send_status_conversion_c::convert(enum wlan_eap_if_send_status_e) + ?set_encrypt@eap_buf_chain_base_c@@QAEX_N@Z @ 1176 NONAME ; void eap_buf_chain_base_c::set_encrypt(bool) + ?set_code@eap_header_base_c@@QAEXW4eap_code_value_e@@@Z @ 1177 NONAME ; void eap_header_base_c::set_code(enum eap_code_value_e) + ?reset_header@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@EW4eapol_key_authentication_type_e@@W4eapol_RSNA_cipher_e@1@_K_N33333333W4eapol_protocol_version_e@@W4eapol_key_descriptor_type_e@@@Z @ 1178 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::reset_header(unsigned char, enum eapol_key_authentication_type_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, unsigned long long, bool, bool, bool, bool, bool, bool, bool, bool, bool, enum eapol_protocol_version_e, enum eapol_key_descriptor_type_e) + ?parse_message_data@eap_tlv_message_data_c@@QAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 1179 NONAME ; enum eap_status_e eap_tlv_message_data_c::parse_message_data(class eap_array_c *) + ?directory_close@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@XZ @ 1180 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::directory_close(void) + ??1crypto_kd_hmac_sha256_c@@UAE@XZ @ 1181 NONAME ; crypto_kd_hmac_sha256_c::~crypto_kd_hmac_sha256_c(void) + ?check_header@eap_tlv_header_c@@UBE?AW4eap_status_e@@XZ @ 1182 NONAME ; enum eap_status_e eap_tlv_header_c::check_header(void) const + ?new_abs_eap_am_tools_c@abs_eap_am_tools_c@@SAPAV1@XZ @ 1183 NONAME ; class abs_eap_am_tools_c * abs_eap_am_tools_c::new_abs_eap_am_tools_c(void) + ?eap_write_u24_t_network_order@@YA?AW4eap_status_e@@PAXKK@Z @ 1184 NONAME ; enum eap_status_e eap_write_u24_t_network_order(void *, unsigned long, unsigned long) + ?get_is_valid@crypto_sha_256_c@@UAE_NXZ @ 1185 NONAME ; bool crypto_sha_256_c::get_is_valid(void) + ?get_header_offset@eapol_core_c@@UAEKPAK0@Z @ 1186 NONAME ; unsigned long eapol_core_c::get_header_offset(unsigned long *, unsigned long *) + ??1eapol_message_wlan_authentication_c@@UAE@XZ @ 1187 NONAME ; eapol_message_wlan_authentication_c::~eapol_message_wlan_authentication_c(void) + ?check_payloads@eapol_rsna_key_data_payloads_c@@QAE_NW4eapol_rsna_key_data_payload_status_e@1@000@Z @ 1188 NONAME ; bool eapol_rsna_key_data_payloads_c::check_payloads(enum eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_e, enum eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_e, enum eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_e, enum eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_e) + ?copy_message_digest@eap_am_crypto_md4_c@@AAE?AW4eap_status_e@@PAXPAK@Z @ 1189 NONAME ; enum eap_status_e eap_am_crypto_md4_c::copy_message_digest(void *, unsigned long *) + ?timer_delete_data@eap_session_core_c@@UAE?AW4eap_status_e@@KPAX@Z @ 1190 NONAME ; enum eap_status_e eap_session_core_c::timer_delete_data(unsigned long, void *) + ?convert_am_error_to_eapol_error@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@J@Z @ 1191 NONAME ; enum eap_status_e eap_am_tools_symbian_c::convert_am_error_to_eapol_error(long) + ??1eapol_rsna_key_data_payloads_c@@UAE@XZ @ 1192 NONAME ; eapol_rsna_key_data_payloads_c::~eapol_rsna_key_data_payloads_c(void) + ?sha_256_final@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PAEPAK@Z @ 1193 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::sha_256_final(class eap_variable_data_c *, unsigned char *, unsigned long *) + ??0eapol_session_key_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1194 NONAME ; eapol_session_key_c::eapol_session_key_c(class abs_eap_am_tools_c *) + ?copy_context@crypto_md5_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 1195 NONAME ; enum eap_status_e crypto_md5_c::copy_context(class eap_variable_data_c const *) + ?get_destination_length@eapol_ethernet_header_base_c@@QBEKXZ @ 1196 NONAME ; unsigned long eapol_ethernet_header_base_c::get_destination_length(void) const + ?get_key_IV@eapol_RC4_key_header_c@@QAEPAEXZ @ 1197 NONAME ; unsigned char * eapol_RC4_key_header_c::get_key_IV(void) + ?get_key_data_offset@eapol_RSNA_key_header_c@@QBEPAEKK@Z @ 1198 NONAME ; unsigned char * eapol_RSNA_key_header_c::get_key_data_offset(unsigned long, unsigned long) const + ?eap_host_to_little_endian_long@@YAKK@Z @ 1199 NONAME ; unsigned long eap_host_to_little_endian_long(unsigned long) + ?timer_delete_data@eapol_key_state_c@@UAE?AW4eap_status_e@@KPAX@Z @ 1200 NONAME ; enum eap_status_e eapol_key_state_c::timer_delete_data(unsigned long, void *) + ?get_eapol_protocol_version@eapol_RSNA_key_header_c@@QBE?AW4eapol_protocol_version_e@@XZ @ 1201 NONAME ; enum eapol_protocol_version_e eapol_RSNA_key_header_c::get_eapol_protocol_version(void) const + ?zero_EAPOL_key_IV@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@@Z @ 1202 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::zero_EAPOL_key_IV(class abs_eap_am_tools_c *) + ?set_is_valid@crypto_tls_prf_c@@AAEXXZ @ 1203 NONAME ; void crypto_tls_prf_c::set_is_valid(void) + ?set_is_invalid@crypto_rc4_c@@AAEXXZ @ 1204 NONAME ; void crypto_rc4_c::set_is_invalid(void) + ?indicate_eapol_key_state_started_eap_authentication@eapol_core_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 1205 NONAME ; enum eap_status_e eapol_core_c::indicate_eapol_key_state_started_eap_authentication(class eap_am_network_id_c const *) + ??1eap_network_id_selector_c@@UAE@XZ @ 1206 NONAME ; eap_network_id_selector_c::~eap_network_id_selector_c(void) + ?get_allow_send_eap_success@eap_state_notification_c@@UBE_NXZ @ 1207 NONAME ; bool eap_state_notification_c::get_allow_send_eap_success(void) const + ?get_type@eap_type_selection_c@@QBE?AVeap_expanded_type_c@@XZ @ 1208 NONAME ; class eap_expanded_type_c eap_type_selection_c::get_type(void) const + ?get_authentication_error@eap_state_notification_c@@UBE?AW4eap_status_e@@XZ @ 1209 NONAME ; enum eap_status_e eap_state_notification_c::get_authentication_error(void) const + ?zero_key_reserved@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@PAVabs_eap_am_tools_c@@@Z @ 1210 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::zero_key_reserved(class abs_eap_am_tools_c *) + ?get_key_signature@eapol_RC4_key_header_c@@QBEPAEXZ @ 1211 NONAME ; unsigned char * eapol_RC4_key_header_c::get_key_signature(void) const + ?get_source_id@eap_am_network_id_c@@QBEPBVeap_variable_data_c@@XZ @ 1212 NONAME ; class eap_variable_data_c const * eap_am_network_id_c::get_source_id(void) const + ?set_key_information_encrypted_key_data@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@_N@Z @ 1213 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_information_encrypted_key_data(bool) + ?check_one_payload@eapol_rsna_key_data_payloads_c@@QAE_NW4eapol_rsna_key_data_payload_status_e@1@PBVeapol_rsna_variable_data_c@@@Z @ 1214 NONAME ; bool eapol_rsna_key_data_payloads_c::check_one_payload(enum eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payload_status_e, class eapol_rsna_variable_data_c const *) + ?get_protocol_string@eap_state_notification_c@@SAPBDKK@Z @ 1215 NONAME ; char const * eap_state_notification_c::get_protocol_string(unsigned long, unsigned long) + ?start_WPXM_reassociation@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PAVeap_variable_data_c@@@Z @ 1216 NONAME ; enum eap_status_e ethernet_core_c::start_WPXM_reassociation(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c *) + ?client_proposes_eap_types@eap_core_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@E@Z @ 1217 NONAME ; enum eap_status_e eap_core_c::client_proposes_eap_types(class eap_am_network_id_c const *, unsigned char) + ??0eapol_session_key_c@@QAE@PAVabs_eap_am_tools_c@@PAVeap_variable_data_c@@W4eapol_key_type_e@@K_NPBEK@Z @ 1218 NONAME ; eapol_session_key_c::eapol_session_key_c(class abs_eap_am_tools_c *, class eap_variable_data_c *, enum eapol_key_type_e, unsigned long, bool, unsigned char const *, unsigned long) + ?get_is_reserved@eap_am_mutex_reference_c@@QAE_NXZ @ 1219 NONAME ; bool eap_am_mutex_reference_c::get_is_reserved(void) + ?set_key@eapol_session_key_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 1220 NONAME ; enum eap_status_e eapol_session_key_c::set_key(class eap_variable_data_c const *) + ?set_is_invalid@crypto_rsa_c@@AAEXXZ @ 1221 NONAME ; void crypto_rsa_c::set_is_invalid(void) + ?complete_WPXM_reassociation@eapol_key_state_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@@Z @ 1222 NONAME ; enum eap_status_e eapol_key_state_c::complete_WPXM_reassociation(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *) + ?eap_write_u32_t_network_order@@YA?AW4eap_status_e@@PAXKK@Z @ 1223 NONAME ; enum eap_status_e eap_write_u32_t_network_order(void *, unsigned long, unsigned long) + ?get_hardware_ticks_of_second@eap_am_tools_symbian_c@@UAE_KXZ @ 1224 NONAME ; unsigned long long eap_am_tools_symbian_c::get_hardware_ticks_of_second(void) + ?get_header_offset@eapol_message_wlan_authentication_c@@UAEKPAK0@Z @ 1225 NONAME ; unsigned long eapol_message_wlan_authentication_c::get_header_offset(unsigned long *, unsigned long *) + ?get_data@eap_am_memory_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@PAVeap_tlv_message_data_c@@@Z @ 1226 NONAME ; enum eap_status_e eap_am_memory_store_c::get_data(class eap_variable_data_c const *, class eap_tlv_message_data_c *) + ?aes_block_size@eap_am_crypto_symbian_c@@UAEKXZ @ 1227 NONAME ; unsigned long eap_am_crypto_symbian_c::aes_block_size(void) + ?add_structured_parameter_header@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@W4eapol_tlv_message_type_e@@K@Z @ 1228 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_structured_parameter_header(enum eapol_tlv_message_type_e, unsigned long) + ?get_global_mutex@eap_am_tools_symbian_c@@UAEPAVabs_eap_am_mutex_c@@XZ @ 1229 NONAME ; class abs_eap_am_mutex_c * eap_am_tools_symbian_c::get_global_mutex(void) + ?check_is_aes_key_wrap_padding@eapol_key_state_c@@AAE?AW4eap_status_e@@W4eapol_RSNA_key_descriptor_type_e@@PAVeapol_rsna_key_data_header_c@@K@Z @ 1230 NONAME ; enum eap_status_e eapol_key_state_c::check_is_aes_key_wrap_padding(enum eapol_RSNA_key_descriptor_type_e, class eapol_rsna_key_data_header_c *, unsigned long) + ?get_encrypts@crypto_aes_c@@UAE_NXZ @ 1231 NONAME ; bool crypto_aes_c::get_encrypts(void) + ?get_payload_size@eapol_handle_tlv_message_data_c@@QBEKPBVeapol_session_key_c@@@Z @ 1232 NONAME ; unsigned long eapol_handle_tlv_message_data_c::get_payload_size(class eapol_session_key_c const *) const + ?check_is_valid_eap_type@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 1233 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::check_is_valid_eap_type(class eap_expanded_type_c) + ?eap_shift_right_64_bit@@YA_K_KK@Z @ 1234 NONAME ; unsigned long long eap_shift_right_64_bit(unsigned long long, unsigned long) + ?add_rogue_ap@eap_core_c@@UAE?AW4eap_status_e@@AAV?$eap_array_c@Veap_rogue_ap_entry_c@@@@@Z @ 1235 NONAME ; enum eap_status_e eap_core_c::add_rogue_ap(class eap_array_c &) + ?timer_expired@eap_am_memory_store_c@@UAE?AW4eap_status_e@@KPAX@Z @ 1236 NONAME ; enum eap_status_e eap_am_memory_store_c::timer_expired(unsigned long, void *) + ?get_eapol_key_authentication_type_string@eapol_key_state_string_c@@QBEPBDW4eapol_key_authentication_type_e@@@Z @ 1237 NONAME ; char const * eapol_key_state_string_c::get_eapol_key_authentication_type_string(enum eapol_key_authentication_type_e) const + ?add_rogue_ap@eapol_wlan_authentication_c@@UAE?AW4eap_status_e@@AAV?$eap_array_c@Veap_rogue_ap_entry_c@@@@@Z @ 1238 NONAME ; enum eap_status_e eapol_wlan_authentication_c::add_rogue_ap(class eap_array_c &) + ??9eap_expanded_type_c@@QBE_NW4eap_type_ietf_values_e@@@Z @ 1239 NONAME ; bool eap_expanded_type_c::operator!=(enum eap_type_ietf_values_e) const + ?get_sequence_number@eapol_session_key_c@@QBEPBVeap_variable_data_c@@XZ @ 1240 NONAME ; class eap_variable_data_c const * eapol_session_key_c::get_sequence_number(void) const + ?tls_prf_one_round@crypto_tls_base_prf_c@@QAE?AW4eap_status_e@@PAVabs_crypto_hmac_algorithm_c@@PBVeap_variable_data_c@@PAV4@2PAXK@Z @ 1241 NONAME ; enum eap_status_e crypto_tls_base_prf_c::tls_prf_one_round(class abs_crypto_hmac_algorithm_c *, class eap_variable_data_c const *, class eap_variable_data_c *, class eap_variable_data_c *, void *, unsigned long) + ??1crypto_rc4_c@@UAE@XZ @ 1242 NONAME ; crypto_rc4_c::~crypto_rc4_c(void) + ?memchr@eap_am_tools_symbian_c@@UAEPAXPBXEK@Z @ 1243 NONAME ; void * eap_am_tools_symbian_c::memchr(void const *, unsigned char, unsigned long) + ??1eap_status_string_c@@UAE@XZ @ 1244 NONAME ; eap_status_string_c::~eap_status_string_c(void) + ?get_buffer@eap_variable_data_c@@QBEPAEK@Z @ 1245 NONAME ; unsigned char * eap_variable_data_c::get_buffer(unsigned long) const + ?packet_data_crypto_keys@eap_session_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeap_master_session_key_c@@@Z @ 1246 NONAME ; enum eap_status_e eap_session_core_c::packet_data_crypto_keys(class eap_am_network_id_c const *, class eap_master_session_key_c const *) + ?cancel_all_timers@eap_session_core_c@@UAE?AW4eap_status_e@@XZ @ 1247 NONAME ; enum eap_status_e eap_session_core_c::cancel_all_timers(void) + ??1eapol_header_wr_c@@UAE@XZ @ 1248 NONAME ; eapol_header_wr_c::~eapol_header_wr_c(void) + ?get_is_WPXM@eapol_key_state_c@@AAE_NXZ @ 1249 NONAME ; bool eapol_key_state_c::get_is_WPXM(void) + ?send_eap_identity_request@eap_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 1250 NONAME ; enum eap_status_e eap_core_c::send_eap_identity_request(class eap_am_network_id_c const *) + ?get_key_information_encrypted_key_data@eapol_RSNA_key_header_c@@QBE_NXZ @ 1251 NONAME ; bool eapol_RSNA_key_header_c::get_key_information_encrypted_key_data(void) const + ?set_key_index@eapol_session_key_c@@QAEXK@Z @ 1252 NONAME ; void eapol_session_key_c::set_key_index(unsigned long) + ?get_next_retransmission_time@eap_core_retransmission_c@@QAEKXZ @ 1253 NONAME ; unsigned long eap_core_retransmission_c::get_next_retransmission_time(void) + ??1crypto_rsa_c@@UAE@XZ @ 1254 NONAME ; crypto_rsa_c::~crypto_rsa_c(void) + ?get_eap_type@eap_core_retransmission_c@@QBE?AVeap_expanded_type_c@@XZ @ 1255 NONAME ; class eap_expanded_type_c eap_core_retransmission_c::get_eap_type(void) const + ?get_marked_removed@eap_core_c@@QAE_NXZ @ 1256 NONAME ; bool eap_core_c::get_marked_removed(void) + ?complete_reassociation@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@PBVeap_variable_data_c@@2W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@3@Z @ 1257 NONAME ; enum eap_status_e eapol_wlan_authentication_c::complete_reassociation(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e) + ?sign@crypto_dsa_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@@Z @ 1258 NONAME ; enum eap_status_e crypto_dsa_c::sign(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ??0eap_network_id_selector_c@@QAE@PAVabs_eap_am_tools_c@@PBV0@@Z @ 1259 NONAME ; eap_network_id_selector_c::eap_network_id_selector_c(class abs_eap_am_tools_c *, class eap_network_id_selector_c const *) + ?get_buffer_length@eap_variable_data_c@@QBEKXZ @ 1260 NONAME ; unsigned long eap_variable_data_c::get_buffer_length(void) const + ?set_is_valid@crypto_sha1_c@@EAEXXZ @ 1261 NONAME ; void crypto_sha1_c::set_is_valid(void) + ?set_buffer@eap_variable_data_c@@QAE?AW4eap_status_e@@PBXK_N1@Z @ 1262 NONAME ; enum eap_status_e eap_variable_data_c::set_buffer(void const *, unsigned long, bool, bool) + ?write_type@eap_expanded_type_c@@SA?AW4eap_status_e@@PAVabs_eap_am_tools_c@@KPAXK_NV1@@Z @ 1263 NONAME ; enum eap_status_e eap_expanded_type_c::write_type(class abs_eap_am_tools_c *, unsigned long, void *, unsigned long, bool, class eap_expanded_type_c) + ?shutdown@ethernet_core_c@@UAE?AW4eap_status_e@@XZ @ 1264 NONAME ; enum eap_status_e ethernet_core_c::shutdown(void) + ?sha1_update@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBEK@Z @ 1265 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::sha1_update(class eap_variable_data_c *, unsigned char const *, unsigned long) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_buf_chain_wr_c@@@Z @ 1266 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(class eap_buf_chain_wr_c const *) + ?decrypt_block@crypto_3des_ede_c@@UAE?AW4eap_status_e@@PBXPAXK@Z @ 1267 NONAME ; enum eap_status_e crypto_3des_ede_c::decrypt_block(void const *, void *, unsigned long) + ??0eap_am_memory_store_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1268 NONAME ; eap_am_memory_store_c::eap_am_memory_store_c(class abs_eap_am_tools_c *) + ?get_is_valid@eap_core_c@@UAE_NXZ @ 1269 NONAME ; bool eap_core_c::get_is_valid(void) + ?remove_pmksa_from_cache@eapol_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 1270 NONAME ; enum eap_status_e eapol_core_c::remove_pmksa_from_cache(class eap_am_network_id_c const *) + ?get_random_error_type@eap_buf_chain_base_c@@QAE?AW4eap_random_error_type@@XZ @ 1271 NONAME ; enum eap_random_error_type eap_buf_chain_base_c::get_random_error_type(void) + ?set_timer@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 1272 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long) + ?tls_prf_output@crypto_tls_sha1_prf_c@@QAE?AW4eap_status_e@@PAXK@Z @ 1273 NONAME ; enum eap_status_e crypto_tls_sha1_prf_c::tls_prf_output(void *, unsigned long) + ??0eapol_rsna_variable_data_c@@QAE@PAVabs_eap_am_tools_c@@_N1@Z @ 1274 NONAME ; eapol_rsna_variable_data_c::eapol_rsna_variable_data_c(class abs_eap_am_tools_c *, bool, bool) + ??1eapol_ethernet_header_rd_c@@UAE@XZ @ 1275 NONAME ; eapol_ethernet_header_rd_c::~eapol_ethernet_header_rd_c(void) + ??0crypto_rc4_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1276 NONAME ; crypto_rc4_c::crypto_rc4_c(class abs_eap_am_tools_c *) + ?read_subsections@eap_file_config_c@@AAE?AW4eap_status_e@@PAVabs_eap_am_file_input_c@@PAV?$eap_core_map_c@Veap_config_value_c@@Vabs_eap_core_map_c@@Veap_variable_data_c@@@@@Z @ 1277 NONAME ; enum eap_status_e eap_file_config_c::read_subsections(class abs_eap_am_file_input_c *, class eap_core_map_c *) + ?cancel_timer@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 1278 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::cancel_timer(class abs_eap_base_timer_c *, unsigned long) + ??0eap_base_type_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_eap_base_type_c@@@Z @ 1279 NONAME ; eap_base_type_c::eap_base_type_c(class abs_eap_am_tools_c *, class abs_eap_base_type_c *) + ?get_network_keys@simple_config_credential_c@@QAEPAV?$eap_array_c@Vnetwork_key_and_index_c@@@@XZ @ 1280 NONAME ; class eap_array_c * simple_config_credential_c::get_network_keys(void) + ?add_data_to_offset@eap_buf_chain_base_c@@QAE?AW4eap_status_e@@KPBVeap_variable_data_c@@@Z @ 1281 NONAME ; enum eap_status_e eap_buf_chain_base_c::add_data_to_offset(unsigned long, class eap_variable_data_c const *) + ?state_notification@eap_core_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 1282 NONAME ; void eap_core_c::state_notification(class abs_eap_state_notification_c const *) + ?set_key_index@eapol_RC4_key_header_c@@QAE?AW4eap_status_e@@E@Z @ 1283 NONAME ; enum eap_status_e eapol_RC4_key_header_c::set_key_index(unsigned char) + ??1crypto_sha_256_c@@UAE@XZ @ 1284 NONAME ; crypto_sha_256_c::~crypto_sha_256_c(void) + ?get_original_header@eapol_rsna_variable_data_c@@QBEPBVeapol_rsna_key_data_header_c@@XZ @ 1285 NONAME ; class eapol_rsna_key_data_header_c const * eapol_rsna_variable_data_c::get_original_header(void) const + ?ignore_notifications@eap_core_c@@QAEXXZ @ 1286 NONAME ; void eap_core_c::ignore_notifications(void) + ?set_is_valid@eapol_wlan_authentication_c@@QAEXXZ @ 1287 NONAME ; void eapol_wlan_authentication_c::set_is_valid(void) + ?get_digest_length@eap_am_crypto_md4_c@@QAEKXZ @ 1288 NONAME ; unsigned long eap_am_crypto_md4_c::get_digest_length(void) + ?write_configure@eapol_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 1289 NONAME ; enum eap_status_e eapol_core_c::write_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?send_eap_notification_response@eap_core_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@E@Z @ 1290 NONAME ; enum eap_status_e eap_core_c::send_eap_notification_response(class eap_am_network_id_c const *, unsigned char) + ?get_header_offset@eap_core_retransmission_c@@QBEKXZ @ 1291 NONAME ; unsigned long eap_core_retransmission_c::get_header_offset(void) const + ?verify_field_is_zero@eapol_key_state_c@@AAE?AW4eap_status_e@@PBEK@Z @ 1292 NONAME ; enum eap_status_e eapol_key_state_c::verify_field_is_zero(unsigned char const *, unsigned long) + ?get_is_associated@eapol_key_state_c@@QAE_NXZ @ 1293 NONAME ; bool eapol_key_state_c::get_is_associated(void) + ?unload_module@eapol_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 1294 NONAME ; enum eap_status_e eapol_core_c::unload_module(class eap_expanded_type_c) + ?cancel_pmksa_caching_timeout@eapol_key_state_c@@AAE?AW4eap_status_e@@XZ @ 1295 NONAME ; enum eap_status_e eapol_key_state_c::cancel_pmksa_caching_timeout(void) + ?get_destination@eapol_ethernet_header_base_c@@QBEPAEXZ @ 1296 NONAME ; unsigned char * eapol_ethernet_header_base_c::get_destination(void) const + ?set_is_valid@crypto_3des_ede_c@@UAEXXZ @ 1297 NONAME ; void crypto_3des_ede_c::set_is_valid(void) + ?eap_md4_process_data@eap_am_crypto_md4_c@@AAE?AW4eap_status_e@@PBKK@Z @ 1298 NONAME ; enum eap_status_e eap_am_crypto_md4_c::eap_md4_process_data(unsigned long const *, unsigned long) + ?disassociate@eapol_message_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N@Z @ 1299 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::disassociate(class eap_am_network_id_c const *, bool) + ?get_message_data@eap_tlv_message_data_c@@QBEPAXXZ @ 1300 NONAME ; void * eap_tlv_message_data_c::get_message_data(void) const + ?set_eap_failure_timeout@eap_core_c@@AAE?AW4eap_status_e@@XZ @ 1301 NONAME ; enum eap_status_e eap_core_c::set_eap_failure_timeout(void) + ?snprintf@eap_am_tools_symbian_c@@UAAKPAEKPBDZZ @ 1302 NONAME ; unsigned long eap_am_tools_symbian_c::snprintf(unsigned char *, unsigned long, char const *, ...) + ?set_random_error_type@eap_buf_chain_base_c@@QAEXW4eap_random_error_type@@@Z @ 1303 NONAME ; void eap_buf_chain_base_c::set_random_error_type(enum eap_random_error_type) + ?create_new_session@eap_session_core_c@@AAEPAVeap_core_c@@PBVeap_am_network_id_c@@@Z @ 1304 NONAME ; class eap_core_c * eap_session_core_c::create_new_session(class eap_am_network_id_c const *) + ??0eapol_RSNA_key_header_c@@QAE@PAVabs_eap_am_tools_c@@_N1PAXK@Z @ 1305 NONAME ; eapol_RSNA_key_header_c::eapol_RSNA_key_header_c(class abs_eap_am_tools_c *, bool, bool, void *, unsigned long) + ?copy_context@crypto_sha1_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 1306 NONAME ; enum eap_status_e crypto_sha1_c::copy_context(class eap_variable_data_c const *) + ?cleanup@crypto_dsa_c@@QAE?AW4eap_status_e@@XZ @ 1307 NONAME ; enum eap_status_e crypto_dsa_c::cleanup(void) + ?rsa_decrypt_with_private_key@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@10@Z @ 1308 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rsa_decrypt_with_private_key(class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ?check_padding_bytes@crypto_cbc_c@@UAE?AW4eap_status_e@@PBXKE@Z @ 1309 NONAME ; enum eap_status_e crypto_cbc_c::check_padding_bytes(void const *, unsigned long, unsigned char) + ?get_key_information_secure@eapol_RSNA_key_header_c@@QBE_NXZ @ 1310 NONAME ; bool eapol_RSNA_key_header_c::get_key_information_secure(void) const + ?decrypt_block@crypto_aes_c@@UAE?AW4eap_status_e@@PBXPAXK@Z @ 1311 NONAME ; enum eap_status_e crypto_aes_c::decrypt_block(void const *, void *, unsigned long) + ?complete_association@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 1312 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::complete_association(class eap_array_c const *) + ?process_eapol_key_frame@eapol_key_state_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 1313 NONAME ; enum eap_status_e eapol_key_state_c::process_eapol_key_frame(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long) + ?remove_pmksa_from_cache@ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 1314 NONAME ; enum eap_status_e ethernet_core_c::remove_pmksa_from_cache(class eap_am_network_id_c const *) + ?tls_prf_output@crypto_tls_md5_prf_c@@QAE?AW4eap_status_e@@PAXK@Z @ 1315 NONAME ; enum eap_status_e crypto_tls_md5_prf_c::tls_prf_output(void *, unsigned long) + ?create_4_way_handshake_message_2@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeap_buf_chain_wr_c@@KPAK1_KW4eapol_protocol_version_e@@W4eapol_key_descriptor_type_e@@@Z @ 1316 NONAME ; enum eap_status_e eapol_key_state_c::create_4_way_handshake_message_2(class eap_buf_chain_wr_c *, unsigned long, unsigned long *, unsigned long *, unsigned long long, enum eapol_protocol_version_e, enum eapol_key_descriptor_type_e) + ?get_buffer_size@eap_core_retransmission_c@@QBEKXZ @ 1317 NONAME ; unsigned long eap_core_retransmission_c::get_buffer_size(void) const + ?convert@wlan_eap_if_send_status_conversion_c@@SA?AW4wlan_eap_if_send_status_e@@W4eap_status_e@@@Z @ 1318 NONAME ; enum wlan_eap_if_send_status_e wlan_eap_if_send_status_conversion_c::convert(enum eap_status_e) + ?get_type_data_offset@eap_header_base_c@@QBEPAEKK@Z @ 1319 NONAME ; unsigned char * eap_header_base_c::get_type_data_offset(unsigned long, unsigned long) const + ?get_header_offset@eap_core_c@@UAEKPAK0@Z @ 1320 NONAME ; unsigned long eap_core_c::get_header_offset(unsigned long *, unsigned long *) + ?get_is_valid@eap_am_tools_symbian_c@@UBE_NXZ @ 1321 NONAME ; bool eap_am_tools_symbian_c::get_is_valid(void) const + ?remove_spaces@eap_file_config_c@@AAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 1322 NONAME ; enum eap_status_e eap_file_config_c::remove_spaces(class eap_variable_data_c *) + ?cancel_timer@eap_session_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 1323 NONAME ; enum eap_status_e eap_session_core_c::cancel_timer(class abs_eap_base_timer_c *, unsigned long) + ?get_header_length@eapol_RC4_key_header_c@@SAGXZ @ 1324 NONAME ; unsigned short eapol_RC4_key_header_c::get_header_length(void) + ?send_error_message@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@W42@W4eapol_tlv_message_type_function_e@@@Z @ 1325 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::send_error_message(enum eap_status_e, enum eapol_tlv_message_type_function_e) + ??1eap_general_header_base_c@@UAE@XZ @ 1326 NONAME ; eap_general_header_base_c::~eap_general_header_base_c(void) + ?get_type_data_offset@eap_header_wr_c@@QBEPAEKK@Z @ 1327 NONAME ; unsigned char * eap_header_wr_c::get_type_data_offset(unsigned long, unsigned long) const + ?complete_eap_identity_query@eap_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeap_variable_data_c@@E@Z @ 1328 NONAME ; enum eap_status_e eap_core_c::complete_eap_identity_query(class eap_am_network_id_c const *, class eap_variable_data_c const *, unsigned char) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 1329 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(class eap_am_network_id_c const *) + ?set_is_invalid@eap_am_crypto_sha1_c@@AAEXXZ @ 1330 NONAME ; void eap_am_crypto_sha1_c::set_is_invalid(void) + ?encrypt_data@crypto_rc4_c@@UAE?AW4eap_status_e@@PBXPAXK@Z @ 1331 NONAME ; enum eap_status_e crypto_rc4_c::encrypt_data(void const *, void *, unsigned long) + ?synchronous_create_eap_session@eap_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 1332 NONAME ; enum eap_status_e eap_session_core_c::synchronous_create_eap_session(class eap_am_network_id_c const *) + ?set_is_valid@eap_am_crypto_sha1_c@@AAEXXZ @ 1333 NONAME ; void eap_am_crypto_sha1_c::set_is_valid(void) + ?get_selected_eap_types@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_type_selection_c@@@@@Z @ 1334 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::get_selected_eap_types(class eap_array_c *) + ?set_header_buffer@eap_general_header_base_c@@QAEXPAEK@Z @ 1335 NONAME ; void eap_general_header_base_c::set_header_buffer(unsigned char *, unsigned long) + ?configure@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@XZ @ 1336 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::configure(void) + ?am_cancel_timer@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 1337 NONAME ; enum eap_status_e eap_am_tools_symbian_c::am_cancel_timer(class abs_eap_base_timer_c *, unsigned long) + ?get_value_length@eap_tlv_header_c@@QBEKXZ @ 1338 NONAME ; unsigned long eap_tlv_header_c::get_value_length(void) const + ?get_is_valid@eap_am_crypto_sha1_c@@QAE_NXZ @ 1339 NONAME ; bool eap_am_crypto_sha1_c::get_is_valid(void) + ?set_copy_of_buffer@eap_variable_data_c@@QAE?AW4eap_status_e@@PBV1@@Z @ 1340 NONAME ; enum eap_status_e eap_variable_data_c::set_copy_of_buffer(class eap_variable_data_c const *) + ??1crypto_ephemeral_diffie_hellman_c@@UAE@XZ @ 1341 NONAME ; crypto_ephemeral_diffie_hellman_c::~crypto_ephemeral_diffie_hellman_c(void) + ?set_send_packet_index@eap_buf_chain_base_c@@QAEXK@Z @ 1342 NONAME ; void eap_buf_chain_base_c::set_send_packet_index(unsigned long) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@W4eapol_tlv_message_type_e@@K@Z @ 1343 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(enum eapol_tlv_message_type_e, unsigned long) + ?copy_message_digest@eap_am_crypto_sha1_c@@AAE?AW4eap_status_e@@PAXPAK@Z @ 1344 NONAME ; enum eap_status_e eap_am_crypto_sha1_c::copy_message_digest(void *, unsigned long *) + ?initialize_preauthentication@eapol_key_state_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@@Z @ 1345 NONAME ; enum eap_status_e eapol_key_state_c::initialize_preauthentication(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e) + ?get_network_key_index@network_key_and_index_c@@QAEEXZ @ 1346 NONAME ; unsigned char network_key_and_index_c::get_network_key_index(void) + ?reset_header@eap_header_wr_c@@QAEXG_N@Z @ 1347 NONAME ; void eap_header_wr_c::reset_header(unsigned short, bool) + ?get_ietf_type@eap_header_base_c@@QBE?AW4eap_type_ietf_values_e@@XZ @ 1348 NONAME ; enum eap_type_ietf_values_e eap_header_base_c::get_ietf_type(void) const + ?state_notification@eapol_wlan_authentication_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 1349 NONAME ; void eapol_wlan_authentication_c::state_notification(class abs_eap_state_notification_c const *) + ?cleanup_3des_ede@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 1350 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::cleanup_3des_ede(class eap_variable_data_c *) + ?get_eap_code@eap_core_retransmission_c@@QBE?AW4eap_code_value_e@@XZ @ 1351 NONAME ; enum eap_code_value_e eap_core_retransmission_c::get_eap_code(void) const + ??0eapol_wlan_authentication_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_eapol_wlan_authentication_c@@PAVeapol_am_wlan_authentication_c@@_N@Z @ 1352 NONAME ; eapol_wlan_authentication_c::eapol_wlan_authentication_c(class abs_eap_am_tools_c *, class abs_eapol_wlan_authentication_c *, class eapol_am_wlan_authentication_c *, bool) + ?finalize_non_aligned@crypto_cbc_c@@UAE?AW4eap_status_e@@XZ @ 1353 NONAME ; enum eap_status_e crypto_cbc_c::finalize_non_aligned(void) + ?set_key_descriptor_type@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@W4eapol_key_descriptor_type_e@@@Z @ 1354 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_descriptor_type(enum eapol_key_descriptor_type_e) + ?decrypt_with_public_key@crypto_rsa_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@@Z @ 1355 NONAME ; enum eap_status_e crypto_rsa_c::decrypt_with_public_key(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *) + ?get_destination@eapol_ethernet_header_wr_c@@QAEPAEXZ @ 1356 NONAME ; unsigned char * eapol_ethernet_header_wr_c::get_destination(void) + ?tls_prf_cleanup@crypto_tls_md5_prf_c@@QAE?AW4eap_status_e@@XZ @ 1357 NONAME ; enum eap_status_e crypto_tls_md5_prf_c::tls_prf_cleanup(void) + ?isspace@eap_am_tools_symbian_c@@UAE_NE@Z @ 1358 NONAME ; bool eap_am_tools_symbian_c::isspace(unsigned char) + ?set_decryption_key@crypto_cbc_c@@UAE?AW4eap_status_e@@PBXK0K@Z @ 1359 NONAME ; enum eap_status_e crypto_cbc_c::set_decryption_key(void const *, unsigned long, void const *, unsigned long) + ?add_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_general_header_base_c@@@Z @ 1360 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::add_parameter_data(class eap_general_header_base_c const *) + ?set_decryption_key@crypto_3des_ede_c@@UAE?AW4eap_status_e@@PBXK@Z @ 1361 NONAME ; enum eap_status_e crypto_3des_ede_c::set_decryption_key(void const *, unsigned long) + ?set_network_key_index@network_key_and_index_c@@QAEXE@Z @ 1362 NONAME ; void network_key_and_index_c::set_network_key_index(unsigned char) + ?start_WPXM_reassociation@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@0PAVeap_variable_data_c@@PBV4@2@Z @ 1363 NONAME ; enum eap_status_e eapol_wlan_authentication_c::start_WPXM_reassociation(class eap_am_network_id_c const *, class eap_am_network_id_c const *, class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ?set_notification_string@eap_state_notification_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@_N@Z @ 1364 NONAME ; enum eap_status_e eap_state_notification_c::set_notification_string(class eap_variable_data_c const *, bool) + ?copy_message_data@eap_tlv_message_data_c@@QAE?AW4eap_status_e@@KPBX@Z @ 1365 NONAME ; enum eap_status_e eap_tlv_message_data_c::copy_message_data(unsigned long, void const *) + ?add_reference@eap_am_mutex_reference_c@@QAEXXZ @ 1366 NONAME ; void eap_am_mutex_reference_c::add_reference(void) + ??1crypto_tls_prf_c@@UAE@XZ @ 1367 NONAME ; crypto_tls_prf_c::~crypto_tls_prf_c(void) + ?get_am_tools@eap_buf_chain_base_c@@IAEPAVabs_eap_am_tools_c@@XZ @ 1368 NONAME ; class abs_eap_am_tools_c * eap_buf_chain_base_c::get_am_tools(void) + ?get_hardware_ticks@eap_am_tools_symbian_c@@UAE_KXZ @ 1369 NONAME ; unsigned long long eap_am_tools_symbian_c::get_hardware_ticks(void) + ?get_type_data@eap_header_wr_c@@QBEPAEK@Z @ 1370 NONAME ; unsigned char * eap_header_wr_c::get_type_data(unsigned long) const + ?packet_data_session_key@eapol_message_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeapol_session_key_c@@@Z @ 1371 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::packet_data_session_key(class eap_am_network_id_c const *, class eapol_session_key_c const *) + ?process_group_key_handshake_message_0@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K@Z @ 1372 NONAME ; enum eap_status_e eapol_key_state_c::process_group_key_handshake_message_0(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long) + ?create_group_key_handshake_message_1@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeap_buf_chain_wr_c@@KPAK1W4eapol_protocol_version_e@@W4eapol_key_descriptor_type_e@@@Z @ 1373 NONAME ; enum eap_status_e eapol_key_state_c::create_group_key_handshake_message_1(class eap_buf_chain_wr_c *, unsigned long, unsigned long *, unsigned long *, enum eapol_protocol_version_e, enum eapol_key_descriptor_type_e) + ?shutdown@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@XZ @ 1374 NONAME ; enum eap_status_e eapol_wlan_authentication_c::shutdown(void) + ?get_message_data@eap_am_memory_store_tlv_data_c@@QBEPAXXZ @ 1375 NONAME ; void * eap_am_memory_store_tlv_data_c::get_message_data(void) const + ?multiply_u64@eap_am_tools_c@@UAE_K_K0@Z @ 1376 NONAME ; unsigned long long eap_am_tools_c::multiply_u64(unsigned long long, unsigned long long) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAVeapol_session_key_c@@@Z @ 1377 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, class eapol_session_key_c *) + ?hash_final@eap_am_crypto_sha1_c@@QAE?AW4eap_status_e@@PAXPAK@Z @ 1378 NONAME ; enum eap_status_e eap_am_crypto_sha1_c::hash_final(void *, unsigned long *) + ?encrypt_data@crypto_cbc_c@@UAE?AW4eap_status_e@@PBXPAXK@Z @ 1379 NONAME ; enum eap_status_e crypto_cbc_c::encrypt_data(void const *, void *, unsigned long) + ?start_WPXM_reassociation@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 1380 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::start_WPXM_reassociation(class eap_array_c const *) + ?set_is_valid@crypto_md5_c@@EAEXXZ @ 1381 NONAME ; void crypto_md5_c::set_is_valid(void) + ?get_is_client@eap_buf_chain_base_c@@QBE_NXZ @ 1382 NONAME ; bool eap_buf_chain_base_c::get_is_client(void) const + ?set_session_timeout@eap_session_core_c@@UAE?AW4eap_status_e@@K@Z @ 1383 NONAME ; enum eap_status_e eap_session_core_c::set_session_timeout(unsigned long) + ?create_tkip_mic_failure_message@eapol_key_state_c@@AAE?AW4eap_status_e@@PAVeap_buf_chain_wr_c@@KPAK1W4eapol_tkip_mic_failure_type_e@eapol_RSNA_key_header_c@@W4eapol_protocol_version_e@@@Z @ 1384 NONAME ; enum eap_status_e eapol_key_state_c::create_tkip_mic_failure_message(class eap_buf_chain_wr_c *, unsigned long, unsigned long *, unsigned long *, enum eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e, enum eapol_protocol_version_e) + ?key_length_3des_ede@eap_am_crypto_symbian_c@@UAEKXZ @ 1385 NONAME ; unsigned long eap_am_crypto_symbian_c::key_length_3des_ede(void) + ?cancel_all_authentication_sessions@ethernet_core_c@@QAE?AW4eap_status_e@@XZ @ 1386 NONAME ; enum eap_status_e ethernet_core_c::cancel_all_authentication_sessions(void) + ?read_configure@eap_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 1387 NONAME ; enum eap_status_e eap_core_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *) + ?get_header_offset@eapol_wlan_authentication_c@@UAEKPAK0@Z @ 1388 NONAME ; unsigned long eapol_wlan_authentication_c::get_header_offset(unsigned long *, unsigned long *) + ?get_notification_string@eap_state_notification_c@@UBEPBVeap_variable_data_c@@XZ @ 1389 NONAME ; class eap_variable_data_c const * eap_state_notification_c::get_notification_string(void) const + ?set_key_replay_counter@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@_K@Z @ 1390 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_replay_counter(unsigned long long) + ??1crypto_wpa_psk_password_hash_c@@UAE@XZ @ 1391 NONAME ; crypto_wpa_psk_password_hash_c::~crypto_wpa_psk_password_hash_c(void) + ?add_message_data_array@eap_tlv_message_data_c@@QAE?AW4eap_status_e@@KKPAV?$eap_array_c@Veap_variable_data_c@@@@@Z @ 1392 NONAME ; enum eap_status_e eap_tlv_message_data_c::add_message_data_array(unsigned long, unsigned long, class eap_array_c *) + ?allow_4_way_handshake@eapol_key_state_c@@QAE?AW4eap_status_e@@XZ @ 1393 NONAME ; enum eap_status_e eapol_key_state_c::allow_4_way_handshake(void) + ?get_function_string@eapol_handle_tlv_message_data_c@@QAEPBDW4eapol_tlv_message_type_function_e@@@Z @ 1394 NONAME ; char const * eapol_handle_tlv_message_data_c::get_function_string(enum eapol_tlv_message_type_function_e) + ?get_is_valid@crypto_random_c@@QAE_NXZ @ 1395 NONAME ; bool crypto_random_c::get_is_valid(void) + ?get_rogue_reason@eap_rogue_ap_entry_c@@QBE?AW4eap_rogue_ap_reason_e@@XZ @ 1396 NONAME ; enum eap_rogue_ap_reason_e eap_rogue_ap_entry_c::get_rogue_reason(void) const + ?set_is_valid@crypto_aes_wrap_c@@QAEXXZ @ 1397 NONAME ; void crypto_aes_wrap_c::set_is_valid(void) + ?process_4_way_handshake_message_3@eapol_key_state_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeapol_RSNA_key_header_c@@K@Z @ 1398 NONAME ; enum eap_status_e eapol_key_state_c::process_4_way_handshake_message_3(class eap_am_network_id_c const *, class eapol_RSNA_key_header_c *, unsigned long) + ?convert_bytes_to_hex_ascii@eap_am_tools_c@@UAE?AW4eap_status_e@@PBEKPAEPAK@Z @ 1399 NONAME ; enum eap_status_e eap_am_tools_c::convert_bytes_to_hex_ascii(unsigned char const *, unsigned long, unsigned char *, unsigned long *) + ?hash_update@eap_am_crypto_sha_256_c@@QAE?AW4eap_status_e@@PBXK@Z @ 1400 NONAME ; enum eap_status_e eap_am_crypto_sha_256_c::hash_update(void const *, unsigned long) + ?get_is_valid_data@eap_type_selection_c@@QBE_NXZ @ 1401 NONAME ; bool eap_type_selection_c::get_is_valid_data(void) const + ?read_reassociation_parameters@eapol_key_state_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PAVeap_variable_data_c@@PBV5@3@Z @ 1402 NONAME ; enum eap_status_e eapol_key_state_c::read_reassociation_parameters(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAK@Z @ 1403 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, unsigned long *) + ?timer_delete_data@eap_am_memory_store_c@@UAE?AW4eap_status_e@@KPAX@Z @ 1404 NONAME ; enum eap_status_e eap_am_memory_store_c::timer_delete_data(unsigned long, void *) + ?get_is_client@eapol_wlan_authentication_c@@UAE_NXZ @ 1405 NONAME ; bool eapol_wlan_authentication_c::get_is_client(void) + ?hmac_update@crypto_hmac_c@@UAE?AW4eap_status_e@@PBXK@Z @ 1406 NONAME ; enum eap_status_e crypto_hmac_c::hmac_update(void const *, unsigned long) + ?eap_read_u32_t_little_endian_order@@YAKPBXK@Z @ 1407 NONAME ; unsigned long eap_read_u32_t_little_endian_order(void const *, unsigned long) + ?set_key_length@eapol_RC4_key_header_c@@QAE?AW4eap_status_e@@G@Z @ 1408 NONAME ; enum eap_status_e eapol_RC4_key_header_c::set_key_length(unsigned short) + ?get_key_index@eapol_RC4_key_header_c@@QBEEXZ @ 1409 NONAME ; unsigned char eapol_RC4_key_header_c::get_key_index(void) const + ?eap_acknowledge@eapol_wlan_authentication_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 1410 NONAME ; enum eap_status_e eapol_wlan_authentication_c::eap_acknowledge(class eap_am_network_id_c const *) + ??1eap_base_type_c@@UAE@XZ @ 1411 NONAME ; eap_base_type_c::~eap_base_type_c(void) + ?get_key_replay_counter@eapol_RSNA_key_header_c@@QBE_KXZ @ 1412 NONAME ; unsigned long long eapol_RSNA_key_header_c::get_key_replay_counter(void) const + ?get_parameter_data@eapol_handle_tlv_message_data_c@@QAE?AW4eap_status_e@@PBVeap_tlv_header_c@@PAPAVeap_state_notification_c@@@Z @ 1413 NONAME ; enum eap_status_e eapol_handle_tlv_message_data_c::get_parameter_data(class eap_tlv_header_c const *, class eap_state_notification_c * *) + ?get_eap_type_list@ethernet_core_c@@UAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_expanded_type_c@@@@@Z @ 1414 NONAME ; enum eap_status_e ethernet_core_c::get_eap_type_list(class eap_array_c *) + ?unload_module@eap_session_core_c@@UAE?AW4eap_status_e@@Veap_expanded_type_c@@@Z @ 1415 NONAME ; enum eap_status_e eap_session_core_c::unload_module(class eap_expanded_type_c) + ?packet_process@eap_session_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 1416 NONAME ; enum eap_status_e eap_session_core_c::packet_process(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long) + ?begin_db_delete@eap_am_tools_symbian_c@@QAE?AW4eap_status_e@@AAVRDbView@@@Z @ 1417 NONAME ; enum eap_status_e eap_am_tools_symbian_c::begin_db_delete(class RDbView &) + ?check_pmksa_cache@ethernet_core_c@@QAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_am_network_id_c@@@@W4eapol_key_authentication_type_e@@W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@2@Z @ 1418 NONAME ; enum eap_status_e ethernet_core_c::check_pmksa_cache(class eap_array_c *, enum eapol_key_authentication_type_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e) + ?set_identifier@eap_header_base_c@@QAEXE@Z @ 1419 NONAME ; void eap_header_base_c::set_identifier(unsigned char) + ?set_am_partner@eapol_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PAVabs_eapol_am_wlan_authentication_c@@PAVabs_eap_configuration_if_c@@@Z @ 1420 NONAME ; enum eap_status_e eapol_am_wlan_authentication_symbian_c::set_am_partner(class abs_eapol_am_wlan_authentication_c *, class abs_eap_configuration_if_c *) + ?am_set_timer@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 1421 NONAME ; enum eap_status_e eap_am_tools_symbian_c::am_set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long) + ?get_eapol_packet_length@eapol_RSNA_key_header_c@@QBEGXZ @ 1422 NONAME ; unsigned short eapol_RSNA_key_header_c::get_eapol_packet_length(void) const + ?increase_client_send_key_reply_counter@eapol_key_state_c@@AAEXXZ @ 1423 NONAME ; void eapol_key_state_c::increase_client_send_key_reply_counter(void) + ?get_ANonce@eapol_key_state_c@@AAEPAVeap_variable_data_c@@XZ @ 1424 NONAME ; class eap_variable_data_c * eapol_key_state_c::get_ANonce(void) + ??1eap_am_crypto_md4_c@@UAE@XZ @ 1425 NONAME ; eap_am_crypto_md4_c::~eap_am_crypto_md4_c(void) + ?reset_or_remove_session@eap_session_core_c@@AAE?AW4eap_status_e@@PAPAVeap_core_c@@PBVeap_network_id_selector_c@@_N@Z @ 1426 NONAME ; enum eap_status_e eap_session_core_c::reset_or_remove_session(class eap_core_c * *, class eap_network_id_selector_c const *, bool) + ??1crypto_tls_md5_prf_c@@UAE@XZ @ 1427 NONAME ; crypto_tls_md5_prf_c::~crypto_tls_md5_prf_c(void) + ??4eap_expanded_type_c@@QAEAAV0@ABV0@@Z @ 1428 NONAME ; class eap_expanded_type_c & eap_expanded_type_c::operator=(class eap_expanded_type_c const &) + ?get_type_field_length@eap_header_base_c@@QBEKXZ @ 1429 NONAME ; unsigned long eap_header_base_c::get_type_field_length(void) const + ?get_eap_identifier@eap_core_retransmission_c@@QBEEXZ @ 1430 NONAME ; unsigned char eap_core_retransmission_c::get_eap_identifier(void) const + ??0crypto_sha1_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1431 NONAME ; crypto_sha1_c::crypto_sha1_c(class abs_eap_am_tools_c *) + ?sha_256_copy_context@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@@Z @ 1432 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::sha_256_copy_context(class eap_variable_data_c *, class eap_variable_data_c const *) + ??0eap_tlv_header_c@@QAE@PAVabs_eap_am_tools_c@@PAXK@Z @ 1433 NONAME ; eap_tlv_header_c::eap_tlv_header_c(class abs_eap_am_tools_c *, void *, unsigned long) + ??0eap_status_string_c@@QAE@XZ @ 1434 NONAME ; eap_status_string_c::eap_status_string_c(void) + ??1eap_session_core_c@@UAE@XZ @ 1435 NONAME ; eap_session_core_c::~eap_session_core_c(void) + ?rc4_encrypt@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@PAXK@Z @ 1436 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::rc4_encrypt(class eap_variable_data_c const *, void *, unsigned long) + ??0eap_buf_chain_base_c@@QAE@W4eap_write_buffer_e@@PAVabs_eap_am_tools_c@@PAEK_N3K@Z @ 1437 NONAME ; eap_buf_chain_base_c::eap_buf_chain_base_c(enum eap_write_buffer_e, class abs_eap_am_tools_c *, unsigned char *, unsigned long, bool, bool, unsigned long) + ?compare@eap_expanded_type_c@@QBEJPBV1@@Z @ 1438 NONAME ; long eap_expanded_type_c::compare(class eap_expanded_type_c const *) const + ?generate_g_power_to_xy@crypto_ephemeral_diffie_hellman_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@PBXK2K@Z @ 1439 NONAME ; enum eap_status_e crypto_ephemeral_diffie_hellman_c::generate_g_power_to_xy(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *, void const *, unsigned long, void const *, unsigned long) + ?tls_prf_init@crypto_tls_sha1_prf_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@00@Z @ 1440 NONAME ; enum eap_status_e crypto_tls_sha1_prf_c::tls_prf_init(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *) + ?packet_data_crypto_keys@eapol_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeap_master_session_key_c@@@Z @ 1441 NONAME ; enum eap_status_e eapol_core_c::packet_data_crypto_keys(class eap_am_network_id_c const *, class eap_master_session_key_c const *) + ??1eapol_RSNA_key_header_c@@UAE@XZ @ 1442 NONAME ; eapol_RSNA_key_header_c::~eapol_RSNA_key_header_c(void) + ?get_Authentication_Type@simple_config_credential_c@@QAE?AW4simple_config_Authentication_Type_e@@XZ @ 1443 NONAME ; enum simple_config_Authentication_Type_e simple_config_credential_c::get_Authentication_Type(void) + ?get_stack_address@eap_buf_chain_base_c@@QBEPBXXZ @ 1444 NONAME ; void const * eap_buf_chain_base_c::get_stack_address(void) const + ??0eap_am_tools_c@@QAE@XZ @ 1445 NONAME ; eap_am_tools_c::eap_am_tools_c(void) + ?get_protocol_layer_string@eap_state_notification_c@@UBEPBDXZ @ 1446 NONAME ; char const * eap_state_notification_c::get_protocol_layer_string(void) const + ?cancel_asynchronous_init_remove_eap_session@eap_core_c@@AAE?AW4eap_status_e@@XZ @ 1447 NONAME ; enum eap_status_e eap_core_c::cancel_asynchronous_init_remove_eap_session(void) + ?process_message@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PAVeapol_handle_tlv_message_data_c@@@Z @ 1448 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::process_message(class eapol_handle_tlv_message_data_c *) + ??0eap_am_crypto_symbian_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1449 NONAME ; eap_am_crypto_symbian_c::eap_am_crypto_symbian_c(class abs_eap_am_tools_c *) + ?sha1_init@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 1450 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::sha1_init(class eap_variable_data_c *) + ?get_payload_size@eapol_handle_tlv_message_data_c@@QBEKPBV?$eap_array_c@Vsimple_config_credential_c@@@@@Z @ 1451 NONAME ; unsigned long eapol_handle_tlv_message_data_c::get_payload_size(class eap_array_c const *) const + ?create_eap_identity_response@eap_core_c@@AAE?AW4eap_status_e@@PAVeap_buf_chain_wr_c@@PBVeap_variable_data_c@@E@Z @ 1452 NONAME ; enum eap_status_e eap_core_c::create_eap_identity_response(class eap_buf_chain_wr_c *, class eap_variable_data_c const *, unsigned char) + ??0crypto_tls_base_prf_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1453 NONAME ; crypto_tls_base_prf_c::crypto_tls_base_prf_c(class abs_eap_am_tools_c *) + ?file_size@eap_am_file_input_symbian_c@@UAEKXZ @ 1454 NONAME ; unsigned long eap_am_file_input_symbian_c::file_size(void) + ??1eap_am_memory_store_c@@UAE@XZ @ 1455 NONAME ; eap_am_memory_store_c::~eap_am_memory_store_c(void) + ?set_eapol_protocol_version@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@W4eapol_protocol_version_e@@@Z @ 1456 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_eapol_protocol_version(enum eapol_protocol_version_e) + ?set_key_flag@eapol_RC4_key_header_c@@QAE?AW4eap_status_e@@W4eapol_RC4_key_flags_e@@@Z @ 1457 NONAME ; enum eap_status_e eapol_RC4_key_header_c::set_key_flag(enum eapol_RC4_key_flags_e) + ?timer_delete_data@eapol_core_c@@UAE?AW4eap_status_e@@KPAX@Z @ 1458 NONAME ; enum eap_status_e eapol_core_c::timer_delete_data(unsigned long, void *) + ?md5_init@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 1459 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::md5_init(class eap_variable_data_c *) + ?get_key_NONCE@eapol_RSNA_key_header_c@@QBEPAEXZ @ 1460 NONAME ; unsigned char * eapol_RSNA_key_header_c::get_key_NONCE(void) const + ?t_prf_cleanup@crypto_eap_fast_hmac_sha1_prf_c@@QAE?AW4eap_status_e@@XZ @ 1461 NONAME ; enum eap_status_e crypto_eap_fast_hmac_sha1_prf_c::t_prf_cleanup(void) + ?complete_reassociation@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 1462 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::complete_reassociation(class eap_array_c const *) + ??0eap_state_notification_c@@QAE@PAVabs_eap_am_tools_c@@PBVeap_am_network_id_c@@_NW4eap_state_notification_eap_e@@W4eap_protocol_layer_e@@W4eap_type_ietf_values_e@@KKE2@Z @ 1463 NONAME ; eap_state_notification_c::eap_state_notification_c(class abs_eap_am_tools_c *, class eap_am_network_id_c const *, bool, enum eap_state_notification_eap_e, enum eap_protocol_layer_e, enum eap_type_ietf_values_e, unsigned long, unsigned long, unsigned char, bool) + ?add_rogue_ap@eapol_message_wlan_authentication_c@@UAE?AW4eap_status_e@@AAV?$eap_array_c@Veap_rogue_ap_entry_c@@@@@Z @ 1464 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::add_rogue_ap(class eap_array_c &) + ?check_pmksa_cache@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 1465 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::check_pmksa_cache(class eap_array_c const *) + ??1abs_crypto_cbc_block_algorithm_c@@UAE@XZ @ 1466 NONAME ; abs_crypto_cbc_block_algorithm_c::~abs_crypto_cbc_block_algorithm_c(void) + ??0eap_am_crypto_md4_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 1467 NONAME ; eap_am_crypto_md4_c::eap_am_crypto_md4_c(class abs_eap_am_tools_c *) + ?internal_decrypt_data@crypto_cbc_c@@AAE?AW4eap_status_e@@PBXPAXK@Z @ 1468 NONAME ; enum eap_status_e crypto_cbc_c::internal_decrypt_data(void const *, void *, unsigned long) + ?shutdown@eap_core_c@@UAE?AW4eap_status_e@@XZ @ 1469 NONAME ; enum eap_status_e eap_core_c::shutdown(void) + ?file_write@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 1470 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_write(class eap_variable_data_c const *) + ?compare_length@eap_variable_data_c@@QBEJPBXKK@Z @ 1471 NONAME ; long eap_variable_data_c::compare_length(void const *, unsigned long, unsigned long) const + ?save_simple_config_session@eapol_message_wlan_authentication_c@@UAE?AW4eap_status_e@@W4simple_config_state_e@@PBV?$eap_array_c@Vsimple_config_credential_c@@@@PBVeap_variable_data_c@@W4simple_config_Device_Password_ID_e@@PBVsimple_config_payloads_c@@@Z @ 1472 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::save_simple_config_session(enum simple_config_state_e, class eap_array_c const *, class eap_variable_data_c const *, enum simple_config_Device_Password_ID_e, class simple_config_payloads_c const *) + ?hash_final@crypto_sha_256_c@@UAE?AW4eap_status_e@@PAXPAK@Z @ 1473 NONAME ; enum eap_status_e crypto_sha_256_c::hash_final(void *, unsigned long *) + ?memcmp@eap_am_tools_symbian_c@@UAEJPBX0K@Z @ 1474 NONAME ; long eap_am_tools_symbian_c::memcmp(void const *, void const *, unsigned long) + ?get_block_size@crypto_aes_c@@UAEKXZ @ 1475 NONAME ; unsigned long crypto_aes_c::get_block_size(void) + ?get_data@eapol_ethernet_header_base_c@@QBEPAEK@Z @ 1476 NONAME ; unsigned char * eapol_ethernet_header_base_c::get_data(unsigned long) const + ?tkip_mic_failure@eapol_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 1477 NONAME ; enum eap_status_e eapol_message_wlan_authentication_c::tkip_mic_failure(class eap_array_c const *) + ?remove_data@eap_am_memory_store_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 1478 NONAME ; enum eap_status_e eap_am_memory_store_c::remove_data(class eap_variable_data_c const *) + ?dss_pseudo_random@eap_am_crypto_symbian_c@@UAE?AW4eap_status_e@@PAEK0K@Z @ 1479 NONAME ; enum eap_status_e eap_am_crypto_symbian_c::dss_pseudo_random(unsigned char *, unsigned long, unsigned char *, unsigned long) + ?generate_diffie_hellman_keys@crypto_ephemeral_diffie_hellman_c@@QAE?AW4eap_status_e@@PAVeap_variable_data_c@@0PBXK1K@Z @ 1480 NONAME ; enum eap_status_e crypto_ephemeral_diffie_hellman_c::generate_diffie_hellman_keys(class eap_variable_data_c *, class eap_variable_data_c *, void const *, unsigned long, void const *, unsigned long) + ?get_is_valid@eap_am_mutex_base_c@@QBE_NXZ @ 1481 NONAME ; bool eap_am_mutex_base_c::get_is_valid(void) const + ?file_open@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@W4eap_file_io_direction_e@@@Z @ 1482 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_open(class eap_variable_data_c const *, enum eap_file_io_direction_e) + ?get_source_length@eapol_ethernet_header_base_c@@QBEKXZ @ 1483 NONAME ; unsigned long eapol_ethernet_header_base_c::get_source_length(void) const + ??1eap_am_mutex_base_c@@UAE@XZ @ 1484 NONAME ; eap_am_mutex_base_c::~eap_am_mutex_base_c(void) + ?get_is_valid@crypto_tls_sha1_prf_c@@QAE_NXZ @ 1485 NONAME ; bool crypto_tls_sha1_prf_c::get_is_valid(void) + ?cancel_session_timeout@eap_core_c@@AAE?AW4eap_status_e@@XZ @ 1486 NONAME ; enum eap_status_e eap_core_c::cancel_session_timeout(void) + ?hash_cleanup@crypto_md5_c@@UAE?AW4eap_status_e@@XZ @ 1487 NONAME ; enum eap_status_e crypto_md5_c::hash_cleanup(void) + ?add_message_header@eap_tlv_message_data_c@@QAE?AW4eap_status_e@@KK@Z @ 1488 NONAME ; enum eap_status_e eap_tlv_message_data_c::add_message_header(unsigned long, unsigned long) + ??0eapol_ethernet_header_wr_c@@QAE@PAVabs_eap_am_tools_c@@PBEK@Z @ 1489 NONAME ; eapol_ethernet_header_wr_c::eapol_ethernet_header_wr_c(class abs_eap_am_tools_c *, unsigned char const *, unsigned long) + ?get_payload_size@eapol_handle_tlv_message_data_c@@QBEKPBVeap_am_network_id_c@@@Z @ 1490 NONAME ; unsigned long eapol_handle_tlv_message_data_c::get_payload_size(class eap_am_network_id_c const *) const + ?get_is_enabled@eap_type_selection_c@@QBE_NXZ @ 1491 NONAME ; bool eap_type_selection_c::get_is_enabled(void) const + ?set_eapol_packet_body_length@eapol_RC4_key_header_c@@QAE?AW4eap_status_e@@G@Z @ 1492 NONAME ; enum eap_status_e eapol_RC4_key_header_c::set_eapol_packet_body_length(unsigned short) + ?shutdown@eap_am_tools_symbian_c@@UAE?AW4eap_status_e@@XZ @ 1493 NONAME ; enum eap_status_e eap_am_tools_symbian_c::shutdown(void) + ?get_digest_length@eap_am_crypto_sha_256_c@@QAEKXZ @ 1494 NONAME ; unsigned long eap_am_crypto_sha_256_c::get_digest_length(void) + ?get_eapol_key_state@eapol_key_state_c@@ABE?AW4eapol_key_state_e@@XZ @ 1495 NONAME ; enum eapol_key_state_e eapol_key_state_c::get_eapol_key_state(void) const + ??0eapol_rsna_key_data_payloads_c@@QAE@PAVabs_eap_am_tools_c@@_N1@Z @ 1496 NONAME ; eapol_rsna_key_data_payloads_c::eapol_rsna_key_data_payloads_c(class abs_eap_am_tools_c *, bool, bool) + ?set_key_information_key_ack@eapol_RSNA_key_header_c@@QAE?AW4eap_status_e@@_N@Z @ 1497 NONAME ; enum eap_status_e eapol_RSNA_key_header_c::set_key_information_key_ack(bool) + ?octet_from_ascii_armor@eap_am_tools_c@@AAEEE@Z @ 1498 NONAME ; unsigned char eap_am_tools_c::octet_from_ascii_armor(unsigned char) + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/bwins/eapakau.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/bwins/eapakau.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &) + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/bwins/eapmschapv2u.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/bwins/eapmschapv2u.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &) + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/bwins/eapprotectedsetupu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/bwins/eapprotectedsetupu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &) + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/bwins/eapsecuridu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/bwins/eapsecuridu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &) + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/bwins/eapsimu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/bwins/eapsimu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &) + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/bwins/eaptlspeapu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/bwins/eaptlspeapu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &) + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/bwins/eapvpnifu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/bwins/eapvpnifu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &) + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/bwins/wlaneapolifu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/bwins/wlaneapolifu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &) + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/eabi/EAPOLPROTECTEDu.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/eabi/EAPOLPROTECTEDu.DEF Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2042 @@ +EXPORTS + _Z10eap_htonlly @ 1 NONAME + _Z21eap_shift_left_64_bitym @ 2 NONAME + _Z22eap_shift_right_64_bitym @ 3 NONAME + _Z25convert_eap_type_to_u32_t19eap_expanded_type_c @ 4 NONAME + _Z25convert_eap_type_to_u64_t19eap_expanded_type_c @ 5 NONAME + _Z28eap_read_u16_t_network_orderPKvm @ 6 NONAME + _Z28eap_read_u24_t_network_orderPKvm @ 7 NONAME + _Z28eap_read_u32_t_network_orderPKvm @ 8 NONAME + _Z28eap_read_u64_t_network_orderPKvm @ 9 NONAME + _Z29eap_write_u16_t_network_orderPvmt @ 10 NONAME + _Z29eap_write_u24_t_network_orderPvmm @ 11 NONAME + _Z29eap_write_u32_t_network_orderPvmm @ 12 NONAME + _Z29eap_write_u64_t_network_orderPvmy @ 13 NONAME + _Z30eap_host_to_little_endian_longm @ 14 NONAME + _Z31eap_host_to_little_endian_shortt @ 15 NONAME + _Z34eap_read_u16_t_little_endian_orderPKvm @ 16 NONAME + _Z34eap_read_u32_t_little_endian_orderPKvm @ 17 NONAME + _Z34eap_read_u64_t_little_endian_orderPKvm @ 18 NONAME + _Z35eap_host_to_little_endian_long_longy @ 19 NONAME + _Z35eap_write_u16_t_little_endian_orderPvmt @ 20 NONAME + _Z35eap_write_u32_t_little_endian_orderPvmm @ 21 NONAME + _Z35eap_write_u64_t_little_endian_orderPvmy @ 22 NONAME + _Z9eap_htonlm @ 23 NONAME + _Z9eap_htonst @ 24 NONAME + _ZN10eap_core_c11get_partnerEv @ 25 NONAME + _ZN10eap_core_c11load_moduleE19eap_expanded_type_cS0_P19abs_eap_base_type_cPP15eap_base_type_cbPK19eap_am_network_id_c @ 26 NONAME + _ZN10eap_core_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 27 NONAME + _ZN10eap_core_c11set_partnerEP14abs_eap_core_c @ 28 NONAME + _ZN10eap_core_c12add_rogue_apER11eap_array_cI20eap_rogue_ap_entry_cE @ 29 NONAME + _ZN10eap_core_c12cancel_timerEP20abs_eap_base_timer_cm @ 30 NONAME + _ZN10eap_core_c12get_is_validEv @ 31 NONAME + _ZN10eap_core_c12set_is_validEv @ 32 NONAME + _ZN10eap_core_c13resend_packetEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmmm @ 33 NONAME + _ZN10eap_core_c13timer_expiredEmPv @ 34 NONAME + _ZN10eap_core_c13unload_moduleE19eap_expanded_type_c @ 35 NONAME + _ZN10eap_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 36 NONAME + _ZN10eap_core_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 37 NONAME + _ZN10eap_core_c15eap_acknowledgeEPK19eap_am_network_id_c @ 38 NONAME + _ZN10eap_core_c15reset_operationEP15eap_base_type_cP18abs_eap_am_tools_c @ 39 NONAME + _ZN10eap_core_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 40 NONAME + _ZN10eap_core_c16send_eap_failureEPK19eap_am_network_id_ch @ 41 NONAME + _ZN10eap_core_c16send_eap_successEPK19eap_am_network_id_ch @ 42 NONAME + _ZN10eap_core_c16trace_eap_packetEPKcPK15eap_header_wr_c @ 43 NONAME + _ZN10eap_core_c17cancel_all_timersEv @ 44 NONAME + _ZN10eap_core_c17get_eap_type_listEP11eap_array_cI19eap_expanded_type_cE @ 45 NONAME + _ZN10eap_core_c17get_header_offsetEPmS0_ @ 46 NONAME + _ZN10eap_core_c17timer_delete_dataEmPv @ 47 NONAME + _ZN10eap_core_c18get_marked_removedEv @ 48 NONAME + _ZN10eap_core_c18set_marked_removedEv @ 49 NONAME + _ZN10eap_core_c18shutdown_operationEP15eap_base_type_cP18abs_eap_am_tools_c @ 50 NONAME + _ZN10eap_core_c18state_notificationEPK28abs_eap_state_notification_c @ 51 NONAME + _ZN10eap_core_c19init_retransmissionEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmm16eap_code_value_eh19eap_expanded_type_c @ 52 NONAME + _ZN10eap_core_c19packet_process_typeE19eap_expanded_type_cPK19eap_am_network_id_cP25eap_general_header_base_cm @ 53 NONAME + _ZN10eap_core_c19set_session_timeoutEm @ 54 NONAME + _ZN10eap_core_c20ignore_notificationsEv @ 55 NONAME + _ZN10eap_core_c20unset_marked_removedEv @ 56 NONAME + _ZN10eap_core_c21cancel_retransmissionEv @ 57 NONAME + _ZN10eap_core_c21restart_with_new_typeE19eap_expanded_type_cPK19eap_am_network_id_ch @ 58 NONAME + _ZN10eap_core_c21send_eap_nak_responseEPK19eap_am_network_id_chPK11eap_array_cI19eap_expanded_type_cE @ 59 NONAME + _ZN10eap_core_c22cancel_session_timeoutEv @ 60 NONAME + _ZN10eap_core_c22get_saved_eap_identityEP19eap_variable_data_c @ 61 NONAME + _ZN10eap_core_c22restart_authenticationEPK19eap_am_network_id_cb @ 62 NONAME + _ZN10eap_core_c23check_is_valid_eap_typeE19eap_expanded_type_c @ 63 NONAME + _ZN10eap_core_c23packet_data_crypto_keysEPK19eap_am_network_id_cPK24eap_master_session_key_c @ 64 NONAME + _ZN10eap_core_c23set_authentication_roleEb @ 65 NONAME + _ZN10eap_core_c23set_eap_failure_timeoutEv @ 66 NONAME + _ZN10eap_core_c25client_proposes_eap_typesEPK19eap_am_network_id_ch @ 67 NONAME + _ZN10eap_core_c25send_eap_identity_requestEPK19eap_am_network_id_c @ 68 NONAME + _ZN10eap_core_c26cancel_eap_failure_timeoutEv @ 69 NONAME + _ZN10eap_core_c26initialize_session_timeoutEm @ 70 NONAME + _ZN10eap_core_c26send_eap_identity_responseEPK19eap_am_network_id_cPK19eap_variable_data_ch @ 71 NONAME + _ZN10eap_core_c27complete_eap_identity_queryEPK19eap_am_network_id_cPK19eap_variable_data_ch @ 72 NONAME + _ZN10eap_core_c27handle_eap_identity_requestE19eap_expanded_type_chPK19eap_am_network_id_c @ 73 NONAME + _ZN10eap_core_c28create_eap_identity_responseEP18eap_buf_chain_wr_cPK19eap_variable_data_ch @ 74 NONAME + _ZN10eap_core_c28handle_eap_identity_responseEP15eap_base_type_c19eap_expanded_type_cPK19eap_am_network_id_cP15eap_header_wr_cm @ 75 NONAME + _ZN10eap_core_c30send_eap_notification_responseEPK19eap_am_network_id_ch @ 76 NONAME + _ZN10eap_core_c31object_decrease_reference_countEv @ 77 NONAME + _ZN10eap_core_c31object_increase_reference_countEv @ 78 NONAME + _ZN10eap_core_c5resetEv @ 79 NONAME + _ZN10eap_core_c8shutdownEv @ 80 NONAME + _ZN10eap_core_c9configureEv @ 81 NONAME + _ZN10eap_core_c9load_typeE19eap_expanded_type_cS0_PK19eap_am_network_id_c @ 82 NONAME + _ZN10eap_core_c9set_timerEP20abs_eap_base_timer_cmPvm @ 83 NONAME + _ZN10eap_core_cC1EP18abs_eap_am_tools_cP14abs_eap_core_cbPK19eap_am_network_id_cb @ 84 NONAME + _ZN10eap_core_cC2EP18abs_eap_am_tools_cP14abs_eap_core_cbPK19eap_am_network_id_cb @ 85 NONAME + _ZN10eap_core_cD0Ev @ 86 NONAME + _ZN10eap_core_cD1Ev @ 87 NONAME + _ZN10eap_core_cD2Ev @ 88 NONAME + _ZN12crypto_aes_c12get_encryptsEv @ 89 NONAME + _ZN12crypto_aes_c12get_is_validEv @ 90 NONAME + _ZN12crypto_aes_c12set_is_validEv @ 91 NONAME + _ZN12crypto_aes_c13decrypt_blockEPKvPvm @ 92 NONAME + _ZN12crypto_aes_c13encrypt_blockEPKvPvm @ 93 NONAME + _ZN12crypto_aes_c14get_block_sizeEv @ 94 NONAME + _ZN12crypto_aes_c14get_key_lengthEv @ 95 NONAME + _ZN12crypto_aes_c18set_decryption_keyEPKvm @ 96 NONAME + _ZN12crypto_aes_c18set_encryption_keyEPKvm @ 97 NONAME + _ZN12crypto_aes_cC1EP18abs_eap_am_tools_c @ 98 NONAME + _ZN12crypto_aes_cC2EP18abs_eap_am_tools_c @ 99 NONAME + _ZN12crypto_aes_cD0Ev @ 100 NONAME + _ZN12crypto_aes_cD1Ev @ 101 NONAME + _ZN12crypto_aes_cD2Ev @ 102 NONAME + _ZN12crypto_cbc_c10get_tmp_IVEv @ 103 NONAME + _ZN12crypto_cbc_c12decrypt_dataEPKvPvm @ 104 NONAME + _ZN12crypto_cbc_c12decrypt_dataEPvm @ 105 NONAME + _ZN12crypto_cbc_c12encrypt_dataEPKvPvm @ 106 NONAME + _ZN12crypto_cbc_c12encrypt_dataEPvm @ 107 NONAME + _ZN12crypto_cbc_c12get_encryptsEv @ 108 NONAME + _ZN12crypto_cbc_c12get_is_validEv @ 109 NONAME + _ZN12crypto_cbc_c12set_is_validEv @ 110 NONAME + _ZN12crypto_cbc_c13cbc_xor_blockEPKvPvmm @ 111 NONAME + _ZN12crypto_cbc_c14cbc_copy_blockEPvPKvmm @ 112 NONAME + _ZN12crypto_cbc_c14get_block_sizeEv @ 113 NONAME + _ZN12crypto_cbc_c14get_key_lengthEv @ 114 NONAME + _ZN12crypto_cbc_c17add_padding_bytesEPvmh @ 115 NONAME + _ZN12crypto_cbc_c18set_decryption_keyEPKvmS1_m @ 116 NONAME + _ZN12crypto_cbc_c18set_encryption_keyEPKvmS1_m @ 117 NONAME + _ZN12crypto_cbc_c18update_non_alignedEPKvPvm @ 118 NONAME + _ZN12crypto_cbc_c18update_non_alignedEPvm @ 119 NONAME + _ZN12crypto_cbc_c19aligned_data_lengthEm @ 120 NONAME + _ZN12crypto_cbc_c19check_padding_bytesEPKvmh @ 121 NONAME + _ZN12crypto_cbc_c20finalize_non_alignedEv @ 122 NONAME + _ZN12crypto_cbc_c21internal_decrypt_dataEPKvPvm @ 123 NONAME + _ZN12crypto_cbc_c21internal_encrypt_dataEPKvPvm @ 124 NONAME + _ZN12crypto_cbc_c5resetEv @ 125 NONAME + _ZN12crypto_cbc_cC1EP18abs_eap_am_tools_cP28abs_crypto_block_algorithm_cb @ 126 NONAME + _ZN12crypto_cbc_cC2EP18abs_eap_am_tools_cP28abs_crypto_block_algorithm_cb @ 127 NONAME + _ZN12crypto_cbc_cD0Ev @ 128 NONAME + _ZN12crypto_cbc_cD1Ev @ 129 NONAME + _ZN12crypto_cbc_cD2Ev @ 130 NONAME + _ZN12crypto_dsa_c12get_is_validEv @ 131 NONAME + _ZN12crypto_dsa_c12set_is_validEv @ 132 NONAME + _ZN12crypto_dsa_c14set_is_invalidEv @ 133 NONAME + _ZN12crypto_dsa_c4initEv @ 134 NONAME + _ZN12crypto_dsa_c4signEPK19eap_variable_data_cS2_PS0_ @ 135 NONAME + _ZN12crypto_dsa_c6verifyEPK19eap_variable_data_cS2_S2_S2_S2_S2_ @ 136 NONAME + _ZN12crypto_dsa_c7cleanupEv @ 137 NONAME + _ZN12crypto_dsa_cC1EP18abs_eap_am_tools_c @ 138 NONAME + _ZN12crypto_dsa_cC2EP18abs_eap_am_tools_c @ 139 NONAME + _ZN12crypto_dsa_cD0Ev @ 140 NONAME + _ZN12crypto_dsa_cD1Ev @ 141 NONAME + _ZN12crypto_dsa_cD2Ev @ 142 NONAME + _ZN12crypto_md4_c10hash_finalEPvPm @ 143 NONAME + _ZN12crypto_md4_c11hash_updateEPKvm @ 144 NONAME + _ZN12crypto_md4_c12copy_contextEPK19eap_variable_data_c @ 145 NONAME + _ZN12crypto_md4_c12get_is_validEv @ 146 NONAME + _ZN12crypto_md4_c12hash_cleanupEv @ 147 NONAME + _ZN12crypto_md4_c12set_is_validEv @ 148 NONAME + _ZN12crypto_md4_c14get_block_sizeEv @ 149 NONAME + _ZN12crypto_md4_c14set_is_invalidEv @ 150 NONAME + _ZN12crypto_md4_c17get_digest_lengthEv @ 151 NONAME + _ZN12crypto_md4_c4copyEv @ 152 NONAME + _ZN12crypto_md4_c9hash_initEv @ 153 NONAME + _ZN12crypto_md4_cC1EP18abs_eap_am_tools_c @ 154 NONAME + _ZN12crypto_md4_cC2EP18abs_eap_am_tools_c @ 155 NONAME + _ZN12crypto_md4_cD0Ev @ 156 NONAME + _ZN12crypto_md4_cD1Ev @ 157 NONAME + _ZN12crypto_md4_cD2Ev @ 158 NONAME + _ZN12crypto_md5_c10hash_finalEPvPm @ 159 NONAME + _ZN12crypto_md5_c11hash_updateEPKvm @ 160 NONAME + _ZN12crypto_md5_c12copy_contextEPK19eap_variable_data_c @ 161 NONAME + _ZN12crypto_md5_c12get_is_validEv @ 162 NONAME + _ZN12crypto_md5_c12hash_cleanupEv @ 163 NONAME + _ZN12crypto_md5_c12set_is_validEv @ 164 NONAME + _ZN12crypto_md5_c14get_block_sizeEv @ 165 NONAME + _ZN12crypto_md5_c14set_is_invalidEv @ 166 NONAME + _ZN12crypto_md5_c17get_digest_lengthEv @ 167 NONAME + _ZN12crypto_md5_c4copyEv @ 168 NONAME + _ZN12crypto_md5_c9hash_initEv @ 169 NONAME + _ZN12crypto_md5_cC1EP18abs_eap_am_tools_c @ 170 NONAME + _ZN12crypto_md5_cC2EP18abs_eap_am_tools_c @ 171 NONAME + _ZN12crypto_md5_cD0Ev @ 172 NONAME + _ZN12crypto_md5_cD1Ev @ 173 NONAME + _ZN12crypto_md5_cD2Ev @ 174 NONAME + _ZN12crypto_rc4_c12decrypt_dataEPKvPvm @ 175 NONAME + _ZN12crypto_rc4_c12decrypt_dataEPvm @ 176 NONAME + _ZN12crypto_rc4_c12encrypt_dataEPKvPvm @ 177 NONAME + _ZN12crypto_rc4_c12encrypt_dataEPvm @ 178 NONAME + _ZN12crypto_rc4_c12get_is_validEv @ 179 NONAME + _ZN12crypto_rc4_c12set_is_validEv @ 180 NONAME + _ZN12crypto_rc4_c14discard_streamEm @ 181 NONAME + _ZN12crypto_rc4_c14set_is_invalidEv @ 182 NONAME + _ZN12crypto_rc4_c7set_keyEPK19eap_variable_data_c @ 183 NONAME + _ZN12crypto_rc4_cC1EP18abs_eap_am_tools_c @ 184 NONAME + _ZN12crypto_rc4_cC2EP18abs_eap_am_tools_c @ 185 NONAME + _ZN12crypto_rc4_cD0Ev @ 186 NONAME + _ZN12crypto_rc4_cD1Ev @ 187 NONAME + _ZN12crypto_rc4_cD2Ev @ 188 NONAME + _ZN12crypto_rsa_c12get_is_validEv @ 189 NONAME + _ZN12crypto_rsa_c12set_is_validEv @ 190 NONAME + _ZN12crypto_rsa_c14set_is_invalidEv @ 191 NONAME + _ZN12crypto_rsa_c23decrypt_with_public_keyEPK19eap_variable_data_cS2_PS0_ @ 192 NONAME + _ZN12crypto_rsa_c23encrypt_with_public_keyEPK19eap_variable_data_cS2_PS0_ @ 193 NONAME + _ZN12crypto_rsa_c24decrypt_with_private_keyEPK19eap_variable_data_cS2_PS0_ @ 194 NONAME + _ZN12crypto_rsa_c24encrypt_with_private_keyEPK19eap_variable_data_cS2_PS0_ @ 195 NONAME + _ZN12crypto_rsa_c4initEv @ 196 NONAME + _ZN12crypto_rsa_c4signEPK19eap_variable_data_cS2_PS0_ @ 197 NONAME + _ZN12crypto_rsa_c6verifyEPK19eap_variable_data_cS2_S2_ @ 198 NONAME + _ZN12crypto_rsa_c7cleanupEv @ 199 NONAME + _ZN12crypto_rsa_cC1EP18abs_eap_am_tools_c @ 200 NONAME + _ZN12crypto_rsa_cC2EP18abs_eap_am_tools_c @ 201 NONAME + _ZN12crypto_rsa_cD0Ev @ 202 NONAME + _ZN12crypto_rsa_cD1Ev @ 203 NONAME + _ZN12crypto_rsa_cD2Ev @ 204 NONAME + _ZN12eapol_core_c11associationEPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_cS6_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES8_S6_ @ 205 NONAME + _ZN12eapol_core_c11load_moduleE19eap_expanded_type_cS0_P19abs_eap_base_type_cPP15eap_base_type_cbPK19eap_am_network_id_c @ 206 NONAME + _ZN12eapol_core_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 207 NONAME + _ZN12eapol_core_c11send_logoffEPK19eap_am_network_id_c @ 208 NONAME + _ZN12eapol_core_c12add_rogue_apER11eap_array_cI20eap_rogue_ap_entry_cE @ 209 NONAME + _ZN12eapol_core_c12cancel_timerEP20abs_eap_base_timer_cm @ 210 NONAME + _ZN12eapol_core_c12create_stateEPK19eap_am_network_id_c31eapol_key_authentication_type_e @ 211 NONAME + _ZN12eapol_core_c12get_is_validEv @ 212 NONAME + _ZN12eapol_core_c12set_is_validEv @ 213 NONAME + _ZN12eapol_core_c13timer_expiredEmPv @ 214 NONAME + _ZN12eapol_core_c13unload_moduleE19eap_expanded_type_c @ 215 NONAME + _ZN12eapol_core_c14disassociationEPK19eap_am_network_id_c @ 216 NONAME + _ZN12eapol_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 217 NONAME + _ZN12eapol_core_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 218 NONAME + _ZN12eapol_core_c15eap_acknowledgeEPK19eap_am_network_id_c @ 219 NONAME + _ZN12eapol_core_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 220 NONAME + _ZN12eapol_core_c16tkip_mic_failureEPK19eap_am_network_id_cbN23eapol_RSNA_key_header_c29eapol_tkip_mic_failure_type_eE @ 221 NONAME + _ZN12eapol_core_c17cancel_all_timersEv @ 222 NONAME + _ZN12eapol_core_c17check_pmksa_cacheEP11eap_array_cI19eap_am_network_id_cE31eapol_key_authentication_type_eN23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES6_ @ 223 NONAME + _ZN12eapol_core_c17get_eap_type_listEP11eap_array_cI19eap_expanded_type_cE @ 224 NONAME + _ZN12eapol_core_c17get_header_offsetEPmS0_ @ 225 NONAME + _ZN12eapol_core_c17timer_delete_dataEmPv @ 226 NONAME + _ZN12eapol_core_c18shutdown_operationEP17eapol_key_state_cP18abs_eap_am_tools_c @ 227 NONAME + _ZN12eapol_core_c18state_notificationEPK28abs_eap_state_notification_c @ 228 NONAME + _ZN12eapol_core_c19set_session_timeoutEm @ 229 NONAME + _ZN12eapol_core_c19start_reassociationEPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_c @ 230 NONAME + _ZN12eapol_core_c22remove_eapol_key_stateEPK19eap_am_network_id_c @ 231 NONAME + _ZN12eapol_core_c22restart_authenticationEPK19eap_am_network_id_cbbb @ 232 NONAME + _ZN12eapol_core_c23check_is_valid_eap_typeE19eap_expanded_type_c @ 233 NONAME + _ZN12eapol_core_c23packet_data_crypto_keysEPK19eap_am_network_id_cPK24eap_master_session_key_c @ 234 NONAME + _ZN12eapol_core_c23packet_data_session_keyEPK19eap_am_network_id_cPK19eapol_session_key_c @ 235 NONAME + _ZN12eapol_core_c23remove_pmksa_from_cacheEPK19eap_am_network_id_c @ 236 NONAME + _ZN12eapol_core_c23start_preauthenticationEPK19eap_am_network_id_c31eapol_key_authentication_type_e @ 237 NONAME + _ZN12eapol_core_c24start_WPXM_reassociationEPK19eap_am_network_id_c31eapol_key_authentication_type_eP19eap_variable_data_c @ 238 NONAME + _ZN12eapol_core_c27complete_WPXM_reassociationE33eapol_wlan_authentication_state_ePK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_c @ 239 NONAME + _ZN12eapol_core_c29cancel_authentication_sessionEP17eapol_key_state_cP18abs_eap_am_tools_c @ 240 NONAME + _ZN12eapol_core_c33asynchronous_start_authenticationEPK19eap_am_network_id_cb @ 241 NONAME + _ZN12eapol_core_c34cancel_all_authentication_sessionsEv @ 242 NONAME + _ZN12eapol_core_c36asynchronous_init_remove_eap_sessionEPK19eap_am_network_id_c @ 243 NONAME + _ZN12eapol_core_c36get_and_increment_global_key_counterEP19eap_variable_data_c @ 244 NONAME + _ZN12eapol_core_c36init_eapol_key_pmksa_caching_timeoutEPK19eap_am_network_id_c @ 245 NONAME + _ZN12eapol_core_c51indicate_eapol_key_state_started_eap_authenticationEPK19eap_am_network_id_c @ 246 NONAME + _ZN12eapol_core_c8shutdownEv @ 247 NONAME + _ZN12eapol_core_c9configureEv @ 248 NONAME + _ZN12eapol_core_c9set_timerEP20abs_eap_base_timer_cmPvm @ 249 NONAME + _ZN12eapol_core_cC1EP18abs_eap_am_tools_cP16abs_eapol_core_cb @ 250 NONAME + _ZN12eapol_core_cC2EP18abs_eap_am_tools_cP16abs_eapol_core_cb @ 251 NONAME + _ZN12eapol_core_cD0Ev @ 252 NONAME + _ZN12eapol_core_cD1Ev @ 253 NONAME + _ZN12eapol_core_cD2Ev @ 254 NONAME + _ZN13crypto_hmac_c10hmac_finalEPvPm @ 255 NONAME + _ZN13crypto_hmac_c11hmac_updateEPKvm @ 256 NONAME + _ZN13crypto_hmac_c12get_is_validEv @ 257 NONAME + _ZN13crypto_hmac_c12hmac_cleanupEv @ 258 NONAME + _ZN13crypto_hmac_c12hmac_set_keyEPK19eap_variable_data_c @ 259 NONAME + _ZN13crypto_hmac_c12set_is_validEv @ 260 NONAME + _ZN13crypto_hmac_c14hmac_128_finalEPvPm @ 261 NONAME + _ZN13crypto_hmac_c14initialize_padEP19eap_variable_data_ch @ 262 NONAME + _ZN13crypto_hmac_c17get_digest_lengthEv @ 263 NONAME + _ZN13crypto_hmac_cC1EP18abs_eap_am_tools_cP27abs_crypto_hash_algorithm_cb @ 264 NONAME + _ZN13crypto_hmac_cC2EP18abs_eap_am_tools_cP27abs_crypto_hash_algorithm_cb @ 265 NONAME + _ZN13crypto_hmac_cD0Ev @ 266 NONAME + _ZN13crypto_hmac_cD1Ev @ 267 NONAME + _ZN13crypto_hmac_cD2Ev @ 268 NONAME + _ZN13crypto_sha1_c10hash_finalEPvPm @ 269 NONAME + _ZN13crypto_sha1_c11hash_updateEPKvm @ 270 NONAME + _ZN13crypto_sha1_c12copy_contextEPK19eap_variable_data_c @ 271 NONAME + _ZN13crypto_sha1_c12get_is_validEv @ 272 NONAME + _ZN13crypto_sha1_c12hash_cleanupEv @ 273 NONAME + _ZN13crypto_sha1_c12set_is_validEv @ 274 NONAME + _ZN13crypto_sha1_c14get_block_sizeEv @ 275 NONAME + _ZN13crypto_sha1_c14set_is_invalidEv @ 276 NONAME + _ZN13crypto_sha1_c17get_digest_lengthEv @ 277 NONAME + _ZN13crypto_sha1_c4copyEv @ 278 NONAME + _ZN13crypto_sha1_c9hash_initEv @ 279 NONAME + _ZN13crypto_sha1_cC1EP18abs_eap_am_tools_c @ 280 NONAME + _ZN13crypto_sha1_cC2EP18abs_eap_am_tools_c @ 281 NONAME + _ZN13crypto_sha1_cD0Ev @ 282 NONAME + _ZN13crypto_sha1_cD1Ev @ 283 NONAME + _ZN13crypto_sha1_cD2Ev @ 284 NONAME + _ZN14eap_am_tools_c10trace_dataEPKcPKvm @ 285 NONAME + _ZN14eap_am_tools_c11compare_u64Eyy @ 286 NONAME + _ZN14eap_am_tools_c12multiply_u64Eyy @ 287 NONAME + _ZN14eap_am_tools_c14ascii_to_octetEl @ 288 NONAME + _ZN14eap_am_tools_c14create_uuid_v5EPKvmS1_mP19eap_variable_data_c @ 289 NONAME + _ZN14eap_am_tools_c14octet_to_asciiEl @ 290 NONAME + _ZN14eap_am_tools_c14set_trace_maskEm @ 291 NONAME + _ZN14eap_am_tools_c17eap_status_returnEb12eap_status_ePKcl @ 292 NONAME + _ZN14eap_am_tools_c17shutdown_am_toolsEv @ 293 NONAME + _ZN14eap_am_tools_c18get_thread_stoppedEv @ 294 NONAME + _ZN14eap_am_tools_c19get_use_timer_queueEv @ 295 NONAME + _ZN14eap_am_tools_c19set_use_timer_queueEv @ 296 NONAME + _ZN14eap_am_tools_c19trace_configurationE12eap_status_ePK25eap_configuration_field_cPK19eap_variable_data_c @ 297 NONAME + _ZN14eap_am_tools_c20number_string_to_u32EPKhmPm @ 298 NONAME + _ZN14eap_am_tools_c20octet_to_ascii_armorEh @ 299 NONAME + _ZN14eap_am_tools_c21memory_store_add_dataEPK19eap_variable_data_cP22eap_tlv_message_data_cm @ 300 NONAME + _ZN14eap_am_tools_c21memory_store_get_dataEPK19eap_variable_data_cP22eap_tlv_message_data_c @ 301 NONAME + _ZN14eap_am_tools_c21timer_thread_functionEv @ 302 NONAME + _ZN14eap_am_tools_c22octet_from_ascii_armorEh @ 303 NONAME + _ZN14eap_am_tools_c24memory_store_remove_dataEPK19eap_variable_data_c @ 304 NONAME + _ZN14eap_am_tools_c26convert_ascii_to_uppercaseEPhm @ 305 NONAME + _ZN14eap_am_tools_c26convert_bytes_to_hex_asciiEPKhmPhPm @ 306 NONAME + _ZN14eap_am_tools_c26convert_bytes_to_hex_asciiEPKvmP19eap_variable_data_c @ 307 NONAME + _ZN14eap_am_tools_c26convert_hex_ascii_to_bytesEPKhmPhPm @ 308 NONAME + _ZN14eap_am_tools_c26convert_hex_ascii_to_bytesEPKvmP19eap_variable_data_c @ 309 NONAME + _ZN14eap_am_tools_c27set_activate_trace_on_errorEv @ 310 NONAME + _ZN14eap_am_tools_c28convert_bytes_to_ascii_armorEPKhmPhPm @ 311 NONAME + _ZN14eap_am_tools_c29check_activate_trace_on_errorEv @ 312 NONAME + _ZN14eap_am_tools_c29eap_status_return_file_numberEb12eap_status_emml @ 313 NONAME + _ZN14eap_am_tools_c30restore_bytes_from_ascii_armorEPKhmPhPm @ 314 NONAME + _ZN14eap_am_tools_c31create_uuid_v5_from_mac_addressEPKhmP19eap_variable_data_c @ 315 NONAME + _ZN14eap_am_tools_c31generic_convert_unicode_to_utf8ER19eap_variable_data_cRKS0_ @ 316 NONAME + _ZN14eap_am_tools_c31generic_convert_utf8_to_unicodeER19eap_variable_data_cRKS0_ @ 317 NONAME + _ZN14eap_am_tools_c35get_use_seconds_timestamp_in_tracesEv @ 318 NONAME + _ZN14eap_am_tools_c37convert_selected_bytes_to_ascii_armorEhPmPhS1_S0_b @ 319 NONAME + _ZN14eap_am_tools_c39restore_selected_bytes_from_ascii_armorEhPmPhS0_b @ 320 NONAME + _ZN14eap_am_tools_c7xor_u64Eyy @ 321 NONAME + _ZN14eap_am_tools_c9parse_naiEPK19eap_variable_data_cPS0_S3_ @ 322 NONAME + _ZN14eap_am_tools_cC2Ev @ 323 NONAME + _ZN14eap_am_tools_cD0Ev @ 324 NONAME + _ZN14eap_am_tools_cD1Ev @ 325 NONAME + _ZN14eap_am_tools_cD2Ev @ 326 NONAME + _ZN15crypto_random_c12get_is_validEv @ 327 NONAME + _ZN15crypto_random_c12set_is_validEv @ 328 NONAME + _ZN15crypto_random_c13add_rand_seedEPKvm @ 329 NONAME + _ZN15crypto_random_c14get_rand_bytesEP19eap_variable_data_cm @ 330 NONAME + _ZN15crypto_random_c14get_rand_bytesEPvm @ 331 NONAME + _ZN15crypto_random_c16get_rand_integerEmm @ 332 NONAME + _ZN15crypto_random_c22add_rand_seed_hw_ticksEv @ 333 NONAME + _ZN15crypto_random_cC1EP18abs_eap_am_tools_c @ 334 NONAME + _ZN15crypto_random_cC2EP18abs_eap_am_tools_c @ 335 NONAME + _ZN15crypto_random_cD0Ev @ 336 NONAME + _ZN15crypto_random_cD1Ev @ 337 NONAME + _ZN15crypto_random_cD2Ev @ 338 NONAME + _ZN15eap_base_type_c16get_type_partnerEv @ 339 NONAME + _ZN15eap_base_type_c31object_decrease_reference_countEv @ 340 NONAME + _ZN15eap_base_type_c31object_increase_reference_countEv @ 341 NONAME + _ZN15eap_base_type_cC2EP18abs_eap_am_tools_cP19abs_eap_base_type_c @ 342 NONAME + _ZN15eap_base_type_cD0Ev @ 343 NONAME + _ZN15eap_base_type_cD1Ev @ 344 NONAME + _ZN15eap_base_type_cD2Ev @ 345 NONAME + _ZN15eap_header_rd_cC1EP18abs_eap_am_tools_cPhm @ 346 NONAME + _ZN15eap_header_rd_cC2EP18abs_eap_am_tools_cPhm @ 347 NONAME + _ZN15eap_header_rd_cD0Ev @ 348 NONAME + _ZN15eap_header_rd_cD1Ev @ 349 NONAME + _ZN15eap_header_rd_cD2Ev @ 350 NONAME + _ZN15eap_header_wr_c12reset_headerEtb @ 351 NONAME + _ZN15eap_header_wr_cC1EP18abs_eap_am_tools_cPhm @ 352 NONAME + _ZN15eap_header_wr_cC2EP18abs_eap_am_tools_cPhm @ 353 NONAME + _ZN15eap_header_wr_cD0Ev @ 354 NONAME + _ZN15eap_header_wr_cD1Ev @ 355 NONAME + _ZN15eap_header_wr_cD2Ev @ 356 NONAME + _ZN15ethernet_core_c11associationEPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_cS6_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES8_S6_ @ 357 NONAME + _ZN15ethernet_core_c11load_moduleE19eap_expanded_type_cS0_P19abs_eap_base_type_cPP15eap_base_type_cbPK19eap_am_network_id_c @ 358 NONAME + _ZN15ethernet_core_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 359 NONAME + _ZN15ethernet_core_c11send_logoffEPK19eap_am_network_id_c @ 360 NONAME + _ZN15ethernet_core_c12add_rogue_apER11eap_array_cI20eap_rogue_ap_entry_cE @ 361 NONAME + _ZN15ethernet_core_c12cancel_timerEP20abs_eap_base_timer_cm @ 362 NONAME + _ZN15ethernet_core_c12create_stateEPK19eap_am_network_id_c31eapol_key_authentication_type_e @ 363 NONAME + _ZN15ethernet_core_c12get_is_validEv @ 364 NONAME + _ZN15ethernet_core_c12set_is_validEv @ 365 NONAME + _ZN15ethernet_core_c13unload_moduleE19eap_expanded_type_c @ 366 NONAME + _ZN15ethernet_core_c14disassociationEPK19eap_am_network_id_c @ 367 NONAME + _ZN15ethernet_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 368 NONAME + _ZN15ethernet_core_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 369 NONAME + _ZN15ethernet_core_c15eap_acknowledgeEPK19eap_am_network_id_c @ 370 NONAME + _ZN15ethernet_core_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 371 NONAME + _ZN15ethernet_core_c16tkip_mic_failureEPK19eap_am_network_id_cbN23eapol_RSNA_key_header_c29eapol_tkip_mic_failure_type_eE @ 372 NONAME + _ZN15ethernet_core_c17cancel_all_timersEv @ 373 NONAME + _ZN15ethernet_core_c17check_pmksa_cacheEP11eap_array_cI19eap_am_network_id_cE31eapol_key_authentication_type_eN23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES6_ @ 374 NONAME + _ZN15ethernet_core_c17get_eap_type_listEP11eap_array_cI19eap_expanded_type_cE @ 375 NONAME + _ZN15ethernet_core_c17get_header_offsetEPmS0_ @ 376 NONAME + _ZN15ethernet_core_c18state_notificationEPK28abs_eap_state_notification_c @ 377 NONAME + _ZN15ethernet_core_c19start_reassociationEPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_c @ 378 NONAME + _ZN15ethernet_core_c20start_authenticationEPK19eap_am_network_id_cb @ 379 NONAME + _ZN15ethernet_core_c23check_is_valid_eap_typeE19eap_expanded_type_c @ 380 NONAME + _ZN15ethernet_core_c23packet_data_session_keyEPK19eap_am_network_id_cPK19eapol_session_key_c @ 381 NONAME + _ZN15ethernet_core_c23remove_pmksa_from_cacheEPK19eap_am_network_id_c @ 382 NONAME + _ZN15ethernet_core_c23start_preauthenticationEPK19eap_am_network_id_c31eapol_key_authentication_type_e @ 383 NONAME + _ZN15ethernet_core_c24start_WPXM_reassociationEPK19eap_am_network_id_c31eapol_key_authentication_type_eP19eap_variable_data_c @ 384 NONAME + _ZN15ethernet_core_c27complete_WPXM_reassociationE33eapol_wlan_authentication_state_ePK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_c @ 385 NONAME + _ZN15ethernet_core_c34cancel_all_authentication_sessionsEv @ 386 NONAME + _ZN15ethernet_core_c8shutdownEv @ 387 NONAME + _ZN15ethernet_core_c9configureEv @ 388 NONAME + _ZN15ethernet_core_c9load_typeE19eap_expanded_type_c @ 389 NONAME + _ZN15ethernet_core_c9set_timerEP20abs_eap_base_timer_cmPvm @ 390 NONAME + _ZN15ethernet_core_cC1EP18abs_eap_am_tools_cP19abs_ethernet_core_cb @ 391 NONAME + _ZN15ethernet_core_cC2EP18abs_eap_am_tools_cP19abs_ethernet_core_cb @ 392 NONAME + _ZN15ethernet_core_cD0Ev @ 393 NONAME + _ZN15ethernet_core_cD1Ev @ 394 NONAME + _ZN15ethernet_core_cD2Ev @ 395 NONAME + _ZN16crypto_nt_hash_c12get_is_validEv @ 396 NONAME + _ZN16crypto_nt_hash_c14get_master_keyEPK19eap_variable_data_cS2_PS0_m @ 397 NONAME + _ZN16crypto_nt_hash_c16nt_password_hashEPK19eap_variable_data_cPS0_m @ 398 NONAME + _ZN16crypto_nt_hash_c20get_new_key_from_shaEPK19eap_variable_data_cS2_PS0_m @ 399 NONAME + _ZN16crypto_nt_hash_c21hash_nt_password_hashEPK19eap_variable_data_cPS0_m @ 400 NONAME + _ZN16crypto_nt_hash_c24get_asymmetric_start_keyEPK19eap_variable_data_cPS0_mbb @ 401 NONAME + _ZN16crypto_nt_hash_cC1EP18abs_eap_am_tools_c @ 402 NONAME + _ZN16crypto_nt_hash_cC2EP18abs_eap_am_tools_c @ 403 NONAME + _ZN16crypto_nt_hash_cD0Ev @ 404 NONAME + _ZN16crypto_nt_hash_cD1Ev @ 405 NONAME + _ZN16crypto_nt_hash_cD2Ev @ 406 NONAME + _ZN16crypto_sha_256_c10hash_finalEPvPm @ 407 NONAME + _ZN16crypto_sha_256_c11hash_updateEPKvm @ 408 NONAME + _ZN16crypto_sha_256_c12copy_contextEPK19eap_variable_data_c @ 409 NONAME + _ZN16crypto_sha_256_c12get_is_validEv @ 410 NONAME + _ZN16crypto_sha_256_c12hash_cleanupEv @ 411 NONAME + _ZN16crypto_sha_256_c12set_is_validEv @ 412 NONAME + _ZN16crypto_sha_256_c14get_block_sizeEv @ 413 NONAME + _ZN16crypto_sha_256_c14set_is_invalidEv @ 414 NONAME + _ZN16crypto_sha_256_c17get_digest_lengthEv @ 415 NONAME + _ZN16crypto_sha_256_c4copyEv @ 416 NONAME + _ZN16crypto_sha_256_c9hash_initEv @ 417 NONAME + _ZN16crypto_sha_256_cC1EP18abs_eap_am_tools_c @ 418 NONAME + _ZN16crypto_sha_256_cC2EP18abs_eap_am_tools_c @ 419 NONAME + _ZN16crypto_sha_256_cD0Ev @ 420 NONAME + _ZN16crypto_sha_256_cD1Ev @ 421 NONAME + _ZN16crypto_sha_256_cD2Ev @ 422 NONAME + _ZN16crypto_tls_prf_c12get_is_validEv @ 423 NONAME + _ZN16crypto_tls_prf_c12set_is_validEv @ 424 NONAME + _ZN16crypto_tls_prf_c12tls_prf_initEPK19eap_variable_data_cS2_S2_ @ 425 NONAME + _ZN16crypto_tls_prf_c14set_is_invalidEv @ 426 NONAME + _ZN16crypto_tls_prf_c14tls_prf_outputEPvm @ 427 NONAME + _ZN16crypto_tls_prf_c15tls_prf_cleanupEv @ 428 NONAME + _ZN16crypto_tls_prf_cC1EP18abs_eap_am_tools_c @ 429 NONAME + _ZN16crypto_tls_prf_cC2EP18abs_eap_am_tools_c @ 430 NONAME + _ZN16crypto_tls_prf_cD0Ev @ 431 NONAME + _ZN16crypto_tls_prf_cD1Ev @ 432 NONAME + _ZN16crypto_tls_prf_cD2Ev @ 433 NONAME + _ZN16eap_tlv_header_c12reset_headerEmm @ 434 NONAME + _ZN16eap_tlv_header_c16set_value_lengthEm @ 435 NONAME + _ZN16eap_tlv_header_c17get_header_lengthEv @ 436 NONAME + _ZN16eap_tlv_header_c8set_typeEm @ 437 NONAME + _ZN16eap_tlv_header_cC1EP18abs_eap_am_tools_cPvm @ 438 NONAME + _ZN16eap_tlv_header_cC2EP18abs_eap_am_tools_cPvm @ 439 NONAME + _ZN16eap_tlv_header_cD0Ev @ 440 NONAME + _ZN16eap_tlv_header_cD1Ev @ 441 NONAME + _ZN16eap_tlv_header_cD2Ev @ 442 NONAME + _ZN17crypto_3des_ede_c12get_encryptsEv @ 443 NONAME + _ZN17crypto_3des_ede_c12get_is_validEv @ 444 NONAME + _ZN17crypto_3des_ede_c12set_is_validEv @ 445 NONAME + _ZN17crypto_3des_ede_c13decrypt_blockEPKvPvm @ 446 NONAME + _ZN17crypto_3des_ede_c13encrypt_blockEPKvPvm @ 447 NONAME + _ZN17crypto_3des_ede_c14get_block_sizeEv @ 448 NONAME + _ZN17crypto_3des_ede_c14get_key_lengthEv @ 449 NONAME + _ZN17crypto_3des_ede_c18set_decryption_keyEPKvm @ 450 NONAME + _ZN17crypto_3des_ede_c18set_encryption_keyEPKvm @ 451 NONAME + _ZN17crypto_3des_ede_cC1EP18abs_eap_am_tools_c @ 452 NONAME + _ZN17crypto_3des_ede_cC2EP18abs_eap_am_tools_c @ 453 NONAME + _ZN17crypto_3des_ede_cD0Ev @ 454 NONAME + _ZN17crypto_3des_ede_cD1Ev @ 455 NONAME + _ZN17crypto_3des_ede_cD2Ev @ 456 NONAME + _ZN17crypto_aes_wrap_c12get_encryptsEv @ 457 NONAME + _ZN17crypto_aes_wrap_c12get_is_validEv @ 458 NONAME + _ZN17crypto_aes_wrap_c12set_is_validEv @ 459 NONAME + _ZN17crypto_aes_wrap_c13decrypt_blockEPKvmPvm @ 460 NONAME + _ZN17crypto_aes_wrap_c13encrypt_blockEPKvmPvm @ 461 NONAME + _ZN17crypto_aes_wrap_c14get_block_sizeEv @ 462 NONAME + _ZN17crypto_aes_wrap_c14get_key_lengthEv @ 463 NONAME + _ZN17crypto_aes_wrap_c17add_padding_bytesEPvm @ 464 NONAME + _ZN17crypto_aes_wrap_c18set_decryption_keyEPKvm @ 465 NONAME + _ZN17crypto_aes_wrap_c18set_encryption_keyEPKvm @ 466 NONAME + _ZN17crypto_aes_wrap_cC1EP18abs_eap_am_tools_c @ 467 NONAME + _ZN17crypto_aes_wrap_cC2EP18abs_eap_am_tools_c @ 468 NONAME + _ZN17crypto_aes_wrap_cD0Ev @ 469 NONAME + _ZN17crypto_aes_wrap_cD1Ev @ 470 NONAME + _ZN17crypto_aes_wrap_cD2Ev @ 471 NONAME + _ZN17eap_file_config_c10read_u32_tEPhPKhPm @ 472 NONAME + _ZN17eap_file_config_c11get_subsectEP23abs_eap_am_file_input_cP19eap_variable_data_c @ 473 NONAME + _ZN17eap_file_config_c12read_sectionEP23abs_eap_am_file_input_cP14eap_core_map_cI18eap_config_value_c18abs_eap_core_map_c19eap_variable_data_cE @ 474 NONAME + _ZN17eap_file_config_c13convert_valueEP14eap_core_map_cI18eap_config_value_c18abs_eap_core_map_c19eap_variable_data_cEPKS3_20eap_configure_type_ePS3_ @ 475 NONAME + _ZN17eap_file_config_c13read_hex_byteEPhPKhS0_ @ 476 NONAME + _ZN17eap_file_config_c13remove_spacesEP19eap_variable_data_c @ 477 NONAME + _ZN17eap_file_config_c14cnf_get_stringEPK19eap_variable_data_cPS0_S3_P20eap_configure_type_e @ 478 NONAME + _ZN17eap_file_config_c14file_read_lineEP23abs_eap_am_file_input_cP19eap_variable_data_c @ 479 NONAME + _ZN17eap_file_config_c14read_configureEP14eap_core_map_cI18eap_config_value_c18abs_eap_core_map_c19eap_variable_data_cEPK25eap_configuration_field_cPS3_P20eap_configure_type_eb @ 480 NONAME + _ZN17eap_file_config_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 481 NONAME + _ZN17eap_file_config_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_cP14eap_core_map_cI18eap_config_value_c18abs_eap_core_map_cS3_Eb @ 482 NONAME + _ZN17eap_file_config_c15cnf_parse_valueEPK19eap_variable_data_cS2_P20eap_configure_type_ePS0_b @ 483 NONAME + _ZN17eap_file_config_c15store_configureEP23abs_eap_am_file_input_cPK19eap_variable_data_cP14eap_core_map_cI18eap_config_value_c18abs_eap_core_map_cS2_E @ 484 NONAME + _ZN17eap_file_config_c16read_subsectionsEP23abs_eap_am_file_input_cP14eap_core_map_cI18eap_config_value_c18abs_eap_core_map_c19eap_variable_data_cE @ 485 NONAME + _ZN17eap_file_config_c21remove_leading_spacesEP19eap_variable_data_c @ 486 NONAME + _ZN17eap_file_config_c28expand_environment_variablesEP14eap_core_map_cI18eap_config_value_c18abs_eap_core_map_c19eap_variable_data_cEPKS3_PS3_ @ 487 NONAME + _ZN17eap_file_config_c9configureEP23abs_eap_am_file_input_c @ 488 NONAME + _ZN17eap_file_config_cC1EP18abs_eap_am_tools_c @ 489 NONAME + _ZN17eap_file_config_cC2EP18abs_eap_am_tools_c @ 490 NONAME + _ZN17eap_file_config_cD0Ev @ 491 NONAME + _ZN17eap_file_config_cD1Ev @ 492 NONAME + _ZN17eap_file_config_cD2Ev @ 493 NONAME + _ZN17eap_header_base_c10set_lengthEtb @ 494 NONAME + _ZN17eap_header_base_c14set_identifierEh @ 495 NONAME + _ZN17eap_header_base_c17get_header_lengthEv @ 496 NONAME + _ZN17eap_header_base_c20set_type_data_lengthEtb @ 497 NONAME + _ZN17eap_header_base_c26get_ietf_type_field_lengthEv @ 498 NONAME + _ZN17eap_header_base_c26get_type_data_start_offsetEb @ 499 NONAME + _ZN17eap_header_base_c29get_expanded_ietf_type_offsetEv @ 500 NONAME + _ZN17eap_header_base_c29get_expanded_vendor_id_offsetEv @ 501 NONAME + _ZN17eap_header_base_c30get_expanded_type_field_lengthEv @ 502 NONAME + _ZN17eap_header_base_c31get_expanded_vendor_type_offsetEv @ 503 NONAME + _ZN17eap_header_base_c8set_codeE16eap_code_value_e @ 504 NONAME + _ZN17eap_header_base_c8set_typeE19eap_expanded_type_cb @ 505 NONAME + _ZN17eap_header_base_cC1EP18abs_eap_am_tools_cPvm @ 506 NONAME + _ZN17eap_header_base_cC2EP18abs_eap_am_tools_cPvm @ 507 NONAME + _ZN17eap_header_base_cD0Ev @ 508 NONAME + _ZN17eap_header_base_cD1Ev @ 509 NONAME + _ZN17eap_header_base_cD2Ev @ 510 NONAME + _ZN17eapol_header_rd_cC1EP18abs_eap_am_tools_cPhm @ 511 NONAME + _ZN17eapol_header_rd_cC2EP18abs_eap_am_tools_cPhm @ 512 NONAME + _ZN17eapol_header_rd_cD0Ev @ 513 NONAME + _ZN17eapol_header_rd_cD1Ev @ 514 NONAME + _ZN17eapol_header_rd_cD2Ev @ 515 NONAME + _ZN17eapol_header_wr_c12reset_headerEt @ 516 NONAME + _ZN17eapol_header_wr_c14get_eap_headerEv @ 517 NONAME + _ZN17eapol_header_wr_cC1EP18abs_eap_am_tools_cPhm @ 518 NONAME + _ZN17eapol_header_wr_cC2EP18abs_eap_am_tools_cPhm @ 519 NONAME + _ZN17eapol_header_wr_cD0Ev @ 520 NONAME + _ZN17eapol_header_wr_cD1Ev @ 521 NONAME + _ZN17eapol_header_wr_cD2Ev @ 522 NONAME + _ZN17eapol_key_state_c10get_ANonceEv @ 523 NONAME + _ZN17eapol_key_state_c10get_SNonceEv @ 524 NONAME + _ZN17eapol_key_state_c10get_is_WPAEv @ 525 NONAME + _ZN17eapol_key_state_c10initializeEPK19eap_am_network_id_c31eapol_key_authentication_type_e @ 526 NONAME + _ZN17eapol_key_state_c10initializeEPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_cS6_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES8_S6_ @ 527 NONAME + _ZN17eapol_key_state_c11get_is_RSNAEv @ 528 NONAME + _ZN17eapol_key_state_c11get_is_WPXMEv @ 529 NONAME + _ZN17eapol_key_state_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 530 NONAME + _ZN17eapol_key_state_c11set_s_nonceEPK19eap_variable_data_c @ 531 NONAME + _ZN17eapol_key_state_c12get_is_validEv @ 532 NONAME + _ZN17eapol_key_state_c12set_is_validEv @ 533 NONAME + _ZN17eapol_key_state_c13resend_packetEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 534 NONAME + _ZN17eapol_key_state_c13timer_expiredEmPv @ 535 NONAME + _ZN17eapol_key_state_c15derive_WPXM_PTKEm @ 536 NONAME + _ZN17eapol_key_state_c15save_parametersE31eapol_key_authentication_type_ePK19eap_variable_data_cS3_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES5_ @ 537 NONAME + _ZN17eapol_key_state_c16set_pairwise_PMKEPK19eap_variable_data_cPK19eap_am_network_id_c @ 538 NONAME + _ZN17eapol_key_state_c16tkip_mic_failureEbN23eapol_RSNA_key_header_c29eapol_tkip_mic_failure_type_eE @ 539 NONAME + _ZN17eapol_key_state_c17check_pmksa_cacheE31eapol_key_authentication_type_eN23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES2_ @ 540 NONAME + _ZN17eapol_key_state_c17get_is_associatedEv @ 541 NONAME + _ZN17eapol_key_state_c17timer_delete_dataEmPv @ 542 NONAME + _ZN17eapol_key_state_c18add_RSN_IE_payloadEPK23eapol_RSNA_key_header_cP19eap_variable_data_cPm @ 543 NONAME + _ZN17eapol_key_state_c18get_encryption_KEKEv @ 544 NONAME + _ZN17eapol_key_state_c18get_marked_removedEv @ 545 NONAME + _ZN17eapol_key_state_c18get_received_PMKIDEv @ 546 NONAME + _ZN17eapol_key_state_c18reset_cached_pmksaEv @ 547 NONAME + _ZN17eapol_key_state_c18set_marked_removedEv @ 548 NONAME + _ZN17eapol_key_state_c19add_RSN_GTK_payloadEPK23eapol_RSNA_key_header_cP19eap_variable_data_cPm @ 549 NONAME + _ZN17eapol_key_state_c19init_retransmissionEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmm16eap_code_value_eh19eap_expanded_type_c @ 550 NONAME + _ZN17eapol_key_state_c19set_WPXM_parametersEPK19eap_am_network_id_c @ 551 NONAME + _ZN17eapol_key_state_c19set_eapol_key_stateE17eapol_key_state_e @ 552 NONAME + _ZN17eapol_key_state_c20get_confirmation_KCKEv @ 553 NONAME + _ZN17eapol_key_state_c20get_is_encryption_onEv @ 554 NONAME + _ZN17eapol_key_state_c20unset_marked_removedEv @ 555 NONAME + _ZN17eapol_key_state_c20verify_field_is_zeroEPKhm @ 556 NONAME + _ZN17eapol_key_state_c21cancel_retransmissionEv @ 557 NONAME + _ZN17eapol_key_state_c21get_key_reply_counterEv @ 558 NONAME + _ZN17eapol_key_state_c21set_key_reply_counterEy @ 559 NONAME + _ZN17eapol_key_state_c22get_supplicant_RSNA_IEEv @ 560 NONAME + _ZN17eapol_key_state_c22init_handshake_timeoutEm @ 561 NONAME + _ZN17eapol_key_state_c23derive_WPXM_WPXK1_WPXK2Ev @ 562 NONAME + _ZN17eapol_key_state_c23process_eapol_key_frameEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 563 NONAME + _ZN17eapol_key_state_c23trace_eapol_key_messageEPKcP23eapol_RSNA_key_header_c @ 564 NONAME + _ZN17eapol_key_state_c24cancel_handshake_timeoutEv @ 565 NONAME + _ZN17eapol_key_state_c24start_WPXM_reassociationEPK19eap_am_network_id_c31eapol_key_authentication_type_eP19eap_variable_data_c @ 566 NONAME + _ZN17eapol_key_state_c25get_authenticator_RSNA_IEEv @ 567 NONAME + _ZN17eapol_key_state_c26get_supplicant_MAC_addressEv @ 568 NONAME + _ZN17eapol_key_state_c26increase_key_reply_counterEv @ 569 NONAME + _ZN17eapol_key_state_c26init_pmksa_caching_timeoutEv @ 570 NONAME + _ZN17eapol_key_state_c26started_eap_authenticationEv @ 571 NONAME + _ZN17eapol_key_state_c27complete_WPXM_reassociationE33eapol_wlan_authentication_state_ePK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_c @ 572 NONAME + _ZN17eapol_key_state_c28cancel_pmksa_caching_timeoutEv @ 573 NONAME + _ZN17eapol_key_state_c28initialize_preauthenticationEPK19eap_am_network_id_c31eapol_key_authentication_type_e @ 574 NONAME + _ZN17eapol_key_state_c29cancel_authentication_sessionEv @ 575 NONAME + _ZN17eapol_key_state_c29get_authenticator_MAC_addressEv @ 576 NONAME + _ZN17eapol_key_state_c29init_group_key_update_timeoutEm @ 577 NONAME + _ZN17eapol_key_state_c29read_reassociation_parametersEPK19eap_am_network_id_c31eapol_key_authentication_type_eP19eap_variable_data_cPKS4_S7_ @ 578 NONAME + _ZN17eapol_key_state_c31cancel_group_key_update_timeoutEv @ 579 NONAME + _ZN17eapol_key_state_c31object_decrease_reference_countEv @ 580 NONAME + _ZN17eapol_key_state_c31object_increase_reference_countEv @ 581 NONAME + _ZN17eapol_key_state_c32get_unicast_cipher_suite_RSNA_IEEv @ 582 NONAME + _ZN17eapol_key_state_c33get_client_send_key_reply_counterEv @ 583 NONAME + _ZN17eapol_key_state_c33set_client_send_key_reply_counterEy @ 584 NONAME + _ZN17eapol_key_state_c38increase_client_send_key_reply_counterEv @ 585 NONAME + _ZN17eapol_key_state_c40asynchronous_init_remove_eapol_key_stateEv @ 586 NONAME + _ZN17eapol_key_state_c4copyEPK19eap_am_network_id_c @ 587 NONAME + _ZN17eapol_key_state_c5resetEv @ 588 NONAME + _ZN17eapol_key_state_c8shutdownEv @ 589 NONAME + _ZN17eapol_key_state_c9configureEv @ 590 NONAME + _ZN17eapol_key_state_cC1EP18abs_eap_am_tools_cP21abs_eapol_key_state_cP16abs_eapol_core_cbPK19eap_am_network_id_c31eapol_key_authentication_type_e @ 591 NONAME + _ZN17eapol_key_state_cC1EP18abs_eap_am_tools_cP21abs_eapol_key_state_cP16abs_eapol_core_cbPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_cSC_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eESE_SC_ @ 592 NONAME + _ZN17eapol_key_state_cC2EP18abs_eap_am_tools_cP21abs_eapol_key_state_cP16abs_eapol_core_cbPK19eap_am_network_id_c31eapol_key_authentication_type_e @ 593 NONAME + _ZN17eapol_key_state_cC2EP18abs_eap_am_tools_cP21abs_eapol_key_state_cP16abs_eapol_core_cbPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_cSC_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eESE_SC_ @ 594 NONAME + _ZN17eapol_key_state_cD0Ev @ 595 NONAME + _ZN17eapol_key_state_cD1Ev @ 596 NONAME + _ZN17eapol_key_state_cD2Ev @ 597 NONAME + _ZN18abs_eap_am_mutex_cC2Ev @ 598 NONAME + _ZN18abs_eap_am_mutex_cD0Ev @ 599 NONAME + _ZN18abs_eap_am_mutex_cD1Ev @ 600 NONAME + _ZN18abs_eap_am_mutex_cD2Ev @ 601 NONAME + _ZN18abs_eap_am_tools_c22new_abs_eap_am_tools_cEv @ 602 NONAME + _ZN18abs_eap_am_tools_c25delete_abs_eap_am_tools_cEPS_ @ 603 NONAME + _ZN18eap_buf_chain_rd_c17force_inheritanceEv @ 604 NONAME + _ZN18eap_buf_chain_rd_cC1E17eap_read_buffer_eP18abs_eap_am_tools_cPKhmb @ 605 NONAME + _ZN18eap_buf_chain_rd_cC1E17eap_read_buffer_eP18abs_eap_am_tools_cm @ 606 NONAME + _ZN18eap_buf_chain_rd_cC2E17eap_read_buffer_eP18abs_eap_am_tools_cPKhmb @ 607 NONAME + _ZN18eap_buf_chain_rd_cC2E17eap_read_buffer_eP18abs_eap_am_tools_cm @ 608 NONAME + _ZN18eap_buf_chain_rd_cD0Ev @ 609 NONAME + _ZN18eap_buf_chain_rd_cD1Ev @ 610 NONAME + _ZN18eap_buf_chain_rd_cD2Ev @ 611 NONAME + _ZN18eap_buf_chain_wr_c17force_inheritanceEv @ 612 NONAME + _ZN18eap_buf_chain_wr_c19get_ethernet_headerEv @ 613 NONAME + _ZN18eap_buf_chain_wr_c4copyEv @ 614 NONAME + _ZN18eap_buf_chain_wr_cC1E18eap_write_buffer_eP18abs_eap_am_tools_c @ 615 NONAME + _ZN18eap_buf_chain_wr_cC1E18eap_write_buffer_eP18abs_eap_am_tools_cPhmbbm @ 616 NONAME + _ZN18eap_buf_chain_wr_cC1E18eap_write_buffer_eP18abs_eap_am_tools_cm @ 617 NONAME + _ZN18eap_buf_chain_wr_cC2E18eap_write_buffer_eP18abs_eap_am_tools_c @ 618 NONAME + _ZN18eap_buf_chain_wr_cC2E18eap_write_buffer_eP18abs_eap_am_tools_cPhmbbm @ 619 NONAME + _ZN18eap_buf_chain_wr_cC2E18eap_write_buffer_eP18abs_eap_am_tools_cm @ 620 NONAME + _ZN18eap_buf_chain_wr_cD0Ev @ 621 NONAME + _ZN18eap_buf_chain_wr_cD1Ev @ 622 NONAME + _ZN18eap_buf_chain_wr_cD2Ev @ 623 NONAME + _ZN18eap_session_core_c11get_partnerEv @ 624 NONAME + _ZN18eap_session_core_c11load_moduleE19eap_expanded_type_cS0_P19abs_eap_base_type_cPP15eap_base_type_cbPK19eap_am_network_id_c @ 625 NONAME + _ZN18eap_session_core_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 626 NONAME + _ZN18eap_session_core_c12add_rogue_apER11eap_array_cI20eap_rogue_ap_entry_cE @ 627 NONAME + _ZN18eap_session_core_c12cancel_timerEP20abs_eap_base_timer_cm @ 628 NONAME + _ZN18eap_session_core_c12get_is_validEv @ 629 NONAME + _ZN18eap_session_core_c12set_is_validEv @ 630 NONAME + _ZN18eap_session_core_c13timer_expiredEmPv @ 631 NONAME + _ZN18eap_session_core_c13unload_moduleE19eap_expanded_type_c @ 632 NONAME + _ZN18eap_session_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 633 NONAME + _ZN18eap_session_core_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 634 NONAME + _ZN18eap_session_core_c15eap_acknowledgeEPK19eap_am_network_id_c @ 635 NONAME + _ZN18eap_session_core_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 636 NONAME + _ZN18eap_session_core_c17cancel_all_timersEv @ 637 NONAME + _ZN18eap_session_core_c17get_eap_type_listEP11eap_array_cI19eap_expanded_type_cE @ 638 NONAME + _ZN18eap_session_core_c17get_header_offsetEPmS0_ @ 639 NONAME + _ZN18eap_session_core_c17timer_delete_dataEmPv @ 640 NONAME + _ZN18eap_session_core_c18create_new_sessionEPK19eap_am_network_id_c @ 641 NONAME + _ZN18eap_session_core_c18shutdown_operationEP10eap_core_cP18abs_eap_am_tools_c @ 642 NONAME + _ZN18eap_session_core_c18state_notificationEPK28abs_eap_state_notification_c @ 643 NONAME + _ZN18eap_session_core_c19set_session_timeoutEm @ 644 NONAME + _ZN18eap_session_core_c22restart_authenticationEPK19eap_am_network_id_cb @ 645 NONAME + _ZN18eap_session_core_c22restart_authenticationEPK19eap_am_network_id_cbbb @ 646 NONAME + _ZN18eap_session_core_c23check_is_valid_eap_typeE19eap_expanded_type_c @ 647 NONAME + _ZN18eap_session_core_c23packet_data_crypto_keysEPK19eap_am_network_id_cPK24eap_master_session_key_c @ 648 NONAME + _ZN18eap_session_core_c23reset_or_remove_sessionEPP10eap_core_cPK25eap_network_id_selector_cb @ 649 NONAME + _ZN18eap_session_core_c25send_eap_identity_requestEPK19eap_am_network_id_c @ 650 NONAME + _ZN18eap_session_core_c30synchronous_create_eap_sessionEPK19eap_am_network_id_c @ 651 NONAME + _ZN18eap_session_core_c30synchronous_remove_eap_sessionEPK19eap_am_network_id_c @ 652 NONAME + _ZN18eap_session_core_c35synchronous_cancel_all_eap_sessionsEv @ 653 NONAME + _ZN18eap_session_core_c5resetEv @ 654 NONAME + _ZN18eap_session_core_c8shutdownEv @ 655 NONAME + _ZN18eap_session_core_c9configureEv @ 656 NONAME + _ZN18eap_session_core_c9set_timerEP20abs_eap_base_timer_cmPvm @ 657 NONAME + _ZN18eap_session_core_cC1EP18abs_eap_am_tools_cP14abs_eap_core_cb @ 658 NONAME + _ZN18eap_session_core_cC2EP18abs_eap_am_tools_cP14abs_eap_core_cb @ 659 NONAME + _ZN18eap_session_core_cD0Ev @ 660 NONAME + _ZN18eap_session_core_cD1Ev @ 661 NONAME + _ZN18eap_session_core_cD2Ev @ 662 NONAME + _ZN19eap_am_crypto_md4_c10hash_finalEPvPm @ 663 NONAME + _ZN19eap_am_crypto_md4_c11hash_updateEPKvm @ 664 NONAME + _ZN19eap_am_crypto_md4_c12copy_contextEPK19eap_variable_data_cyPKmS4_ @ 665 NONAME + _ZN19eap_am_crypto_md4_c12get_is_validEv @ 666 NONAME + _ZN19eap_am_crypto_md4_c12hash_cleanupEv @ 667 NONAME + _ZN19eap_am_crypto_md4_c12set_is_validEv @ 668 NONAME + _ZN19eap_am_crypto_md4_c14get_block_sizeEv @ 669 NONAME + _ZN19eap_am_crypto_md4_c14set_is_invalidEv @ 670 NONAME + _ZN19eap_am_crypto_md4_c17get_digest_lengthEv @ 671 NONAME + _ZN19eap_am_crypto_md4_c19copy_message_digestEPvPm @ 672 NONAME + _ZN19eap_am_crypto_md4_c20eap_md4_process_dataEPKmm @ 673 NONAME + _ZN19eap_am_crypto_md4_c28eap_md4_transform_host_orderEPKmm @ 674 NONAME + _ZN19eap_am_crypto_md4_c4copyEv @ 675 NONAME + _ZN19eap_am_crypto_md4_c9hash_initEv @ 676 NONAME + _ZN19eap_am_crypto_md4_cC1EP18abs_eap_am_tools_c @ 677 NONAME + _ZN19eap_am_crypto_md4_cC2EP18abs_eap_am_tools_c @ 678 NONAME + _ZN19eap_am_crypto_md4_cD0Ev @ 679 NONAME + _ZN19eap_am_crypto_md4_cD1Ev @ 680 NONAME + _ZN19eap_am_crypto_md4_cD2Ev @ 681 NONAME + _ZN19eap_am_crypto_rc4_c12decrypt_dataEPKvPvm @ 682 NONAME + _ZN19eap_am_crypto_rc4_c12encrypt_dataEPKvPvm @ 683 NONAME + _ZN19eap_am_crypto_rc4_c12get_is_validEv @ 684 NONAME + _ZN19eap_am_crypto_rc4_c12set_is_validEv @ 685 NONAME + _ZN19eap_am_crypto_rc4_c14set_is_invalidEv @ 686 NONAME + _ZN19eap_am_crypto_rc4_c4swapEPhS0_ @ 687 NONAME + _ZN19eap_am_crypto_rc4_c7cleanupEv @ 688 NONAME + _ZN19eap_am_crypto_rc4_c7set_keyEPK19eap_variable_data_c @ 689 NONAME + _ZN19eap_am_crypto_rc4_cC1EP18abs_eap_am_tools_c @ 690 NONAME + _ZN19eap_am_crypto_rc4_cC2EP18abs_eap_am_tools_c @ 691 NONAME + _ZN19eap_am_crypto_rc4_cD0Ev @ 692 NONAME + _ZN19eap_am_crypto_rc4_cD1Ev @ 693 NONAME + _ZN19eap_am_crypto_rc4_cD2Ev @ 694 NONAME + _ZN19eap_am_mutex_base_cC1EPKS_ @ 695 NONAME + _ZN19eap_am_mutex_base_cC1Ev @ 696 NONAME + _ZN19eap_am_mutex_base_cC2EPKS_ @ 697 NONAME + _ZN19eap_am_mutex_base_cC2Ev @ 698 NONAME + _ZN19eap_am_mutex_base_cD0Ev @ 699 NONAME + _ZN19eap_am_mutex_base_cD1Ev @ 700 NONAME + _ZN19eap_am_mutex_base_cD2Ev @ 701 NONAME + _ZN19eap_am_network_id_c12set_is_validEv @ 702 NONAME + _ZN19eap_am_network_id_c22set_copy_of_network_idEPKS_ @ 703 NONAME + _ZN19eap_am_network_id_c25set_copy_of_am_network_idEPKvmS1_mt @ 704 NONAME + _ZN19eap_am_network_id_c5resetEv @ 705 NONAME + _ZN19eap_am_network_id_c8set_typeEt @ 706 NONAME + _ZN19eap_am_network_id_cC1EP18abs_eap_am_tools_c @ 707 NONAME + _ZN19eap_am_network_id_cC1EP18abs_eap_am_tools_cPK19eap_variable_data_cS4_t @ 708 NONAME + _ZN19eap_am_network_id_cC1EP18abs_eap_am_tools_cPKS_ @ 709 NONAME + _ZN19eap_am_network_id_cC1EP18abs_eap_am_tools_cPKvmS3_mtbb @ 710 NONAME + _ZN19eap_am_network_id_cC2EP18abs_eap_am_tools_c @ 711 NONAME + _ZN19eap_am_network_id_cC2EP18abs_eap_am_tools_cPK19eap_variable_data_cS4_t @ 712 NONAME + _ZN19eap_am_network_id_cC2EP18abs_eap_am_tools_cPKS_ @ 713 NONAME + _ZN19eap_am_network_id_cC2EP18abs_eap_am_tools_cPKvmS3_mtbb @ 714 NONAME + _ZN19eap_am_network_id_cD0Ev @ 715 NONAME + _ZN19eap_am_network_id_cD1Ev @ 716 NONAME + _ZN19eap_am_network_id_cD2Ev @ 717 NONAME + _ZN19eap_core_nak_info_cC1EP18abs_eap_am_tools_cPK19eap_am_network_id_c19eap_expanded_type_ch @ 718 NONAME + _ZN19eap_core_nak_info_cC2EP18abs_eap_am_tools_cPK19eap_am_network_id_c19eap_expanded_type_ch @ 719 NONAME + _ZN19eap_core_nak_info_cD0Ev @ 720 NONAME + _ZN19eap_core_nak_info_cD1Ev @ 721 NONAME + _ZN19eap_core_nak_info_cD2Ev @ 722 NONAME + _ZN19eap_expanded_type_c10write_typeEP18abs_eap_am_tools_cmPvmbS_ @ 723 NONAME + _ZN19eap_expanded_type_c12is_ietf_typeES_ @ 724 NONAME + _ZN19eap_expanded_type_c13get_type_dataEP18abs_eap_am_tools_cP22eap_type_ietf_values_e @ 725 NONAME + _ZN19eap_expanded_type_c13get_type_dataEP18abs_eap_am_tools_cPS_ @ 726 NONAME + _ZN19eap_expanded_type_c16is_expanded_typeE22eap_type_ietf_values_e @ 727 NONAME + _ZN19eap_expanded_type_c19set_eap_type_valuesE20eap_type_vendor_id_em @ 728 NONAME + _ZN19eap_expanded_type_c22get_expanded_type_dataEP18abs_eap_am_tools_cP19eap_variable_data_c @ 729 NONAME + _ZN19eap_expanded_type_c22set_expanded_type_dataEP18abs_eap_am_tools_cPK19eap_variable_data_c @ 730 NONAME + _ZN19eap_expanded_type_c26get_eap_expanded_type_sizeEv @ 731 NONAME + _ZN19eap_expanded_type_c9read_typeEP18abs_eap_am_tools_cmPKvmPS_ @ 732 NONAME + _ZN19eap_expanded_type_cC1E20eap_type_vendor_id_em @ 733 NONAME + _ZN19eap_expanded_type_cC1E22eap_type_ietf_values_e @ 734 NONAME + _ZN19eap_expanded_type_cC1Ev @ 735 NONAME + _ZN19eap_expanded_type_cC2E20eap_type_vendor_id_em @ 736 NONAME + _ZN19eap_expanded_type_cC2E22eap_type_ietf_values_e @ 737 NONAME + _ZN19eap_expanded_type_cC2Ev @ 738 NONAME + _ZN19eap_expanded_type_cD1Ev @ 739 NONAME + _ZN19eap_expanded_type_cD2Ev @ 740 NONAME + _ZN19eap_expanded_type_caSE22eap_type_ietf_values_e @ 741 NONAME + _ZN19eap_expanded_type_caSERKS_ @ 742 NONAME + _ZN19eap_expanded_type_cadEv @ 743 NONAME + _ZN19eap_header_string_c19get_eap_code_stringE16eap_code_value_e @ 744 NONAME + _ZN19eap_header_string_c19get_eap_type_stringE19eap_expanded_type_c @ 745 NONAME + _ZN19eap_header_string_cC1Ev @ 746 NONAME + _ZN19eap_header_string_cC2Ev @ 747 NONAME + _ZN19eap_header_string_cD0Ev @ 748 NONAME + _ZN19eap_header_string_cD1Ev @ 749 NONAME + _ZN19eap_header_string_cD2Ev @ 750 NONAME + _ZN19eap_status_string_c17get_status_stringE12eap_status_e @ 751 NONAME + _ZN19eap_status_string_cC1Ev @ 752 NONAME + _ZN19eap_status_string_cC2Ev @ 753 NONAME + _ZN19eap_status_string_cD0Ev @ 754 NONAME + _ZN19eap_status_string_cD1Ev @ 755 NONAME + _ZN19eap_status_string_cD2Ev @ 756 NONAME + _ZN19eap_variable_data_c10set_bufferEPKS_ @ 757 NONAME + _ZN19eap_variable_data_c10set_bufferEPKvmbb @ 758 NONAME + _ZN19eap_variable_data_c10set_bufferEPvmbb @ 759 NONAME + _ZN19eap_variable_data_c12add_end_nullEv @ 760 NONAME + _ZN19eap_variable_data_c12set_is_validEv @ 761 NONAME + _ZN19eap_variable_data_c14set_is_invalidEv @ 762 NONAME + _ZN19eap_variable_data_c15allocate_bufferEm @ 763 NONAME + _ZN19eap_variable_data_c15set_data_lengthEm @ 764 NONAME + _ZN19eap_variable_data_c16set_start_offsetEm @ 765 NONAME + _ZN19eap_variable_data_c17set_buffer_lengthEm @ 766 NONAME + _ZN19eap_variable_data_c18add_data_to_offsetEmPKS_ @ 767 NONAME + _ZN19eap_variable_data_c18add_data_to_offsetEmPKvm @ 768 NONAME + _ZN19eap_variable_data_c18initialize_membersEv @ 769 NONAME + _ZN19eap_variable_data_c18set_copy_of_bufferEPKS_ @ 770 NONAME + _ZN19eap_variable_data_c18set_copy_of_bufferEPKvm @ 771 NONAME + _ZN19eap_variable_data_c34reset_start_offset_and_data_lengthEv @ 772 NONAME + _ZN19eap_variable_data_c4initEm @ 773 NONAME + _ZN19eap_variable_data_c5resetEv @ 774 NONAME + _ZN19eap_variable_data_c8add_dataEPKS_ @ 775 NONAME + _ZN19eap_variable_data_c8add_dataEPKvm @ 776 NONAME + _ZN19eap_variable_data_cC1EP18abs_eap_am_tools_c @ 777 NONAME + _ZN19eap_variable_data_cC1EP18abs_eap_am_tools_cPKvmbb @ 778 NONAME + _ZN19eap_variable_data_cC2EP18abs_eap_am_tools_c @ 779 NONAME + _ZN19eap_variable_data_cC2EP18abs_eap_am_tools_cPKvmbb @ 780 NONAME + _ZN19eap_variable_data_cD0Ev @ 781 NONAME + _ZN19eap_variable_data_cD1Ev @ 782 NONAME + _ZN19eap_variable_data_cD2Ev @ 783 NONAME + _ZN19eapol_header_base_c11set_versionE24eapol_protocol_version_e @ 784 NONAME + _ZN19eapol_header_base_c15set_data_lengthEt @ 785 NONAME + _ZN19eapol_header_base_c15set_packet_typeE19eapol_packet_type_e @ 786 NONAME + _ZN19eapol_header_base_c17get_header_lengthEv @ 787 NONAME + _ZN19eapol_header_base_cC1EP18abs_eap_am_tools_cPvm @ 788 NONAME + _ZN19eapol_header_base_cC2EP18abs_eap_am_tools_cPvm @ 789 NONAME + _ZN19eapol_header_base_cD0Ev @ 790 NONAME + _ZN19eapol_header_base_cD1Ev @ 791 NONAME + _ZN19eapol_header_base_cD2Ev @ 792 NONAME + _ZN19eapol_session_key_c12set_key_typeE16eapol_key_type_e @ 793 NONAME + _ZN19eapol_session_key_c13set_key_indexEm @ 794 NONAME + _ZN19eapol_session_key_c14set_key_tx_bitEb @ 795 NONAME + _ZN19eapol_session_key_c19set_sequence_numberEP19eap_variable_data_c @ 796 NONAME + _ZN19eapol_session_key_c25get_eapol_key_type_stringE16eapol_key_type_e @ 797 NONAME + _ZN19eapol_session_key_c7set_keyEPK19eap_variable_data_c @ 798 NONAME + _ZN19eapol_session_key_cC1EP18abs_eap_am_tools_c @ 799 NONAME + _ZN19eapol_session_key_cC1EP18abs_eap_am_tools_cP19eap_variable_data_c16eapol_key_type_embPKhm @ 800 NONAME + _ZN19eapol_session_key_cC2EP18abs_eap_am_tools_c @ 801 NONAME + _ZN19eapol_session_key_cC2EP18abs_eap_am_tools_cP19eap_variable_data_c16eapol_key_type_embPKhm @ 802 NONAME + _ZN19eapol_session_key_cD0Ev @ 803 NONAME + _ZN19eapol_session_key_cD1Ev @ 804 NONAME + _ZN19eapol_session_key_cD2Ev @ 805 NONAME + _ZN20crypto_tls_md5_prf_c12get_is_validEv @ 806 NONAME + _ZN20crypto_tls_md5_prf_c12set_is_validEv @ 807 NONAME + _ZN20crypto_tls_md5_prf_c12tls_prf_initEPK19eap_variable_data_cS2_S2_ @ 808 NONAME + _ZN20crypto_tls_md5_prf_c14set_is_invalidEv @ 809 NONAME + _ZN20crypto_tls_md5_prf_c14tls_prf_outputEPvm @ 810 NONAME + _ZN20crypto_tls_md5_prf_c15tls_prf_cleanupEv @ 811 NONAME + _ZN20crypto_tls_md5_prf_cC1EP18abs_eap_am_tools_c @ 812 NONAME + _ZN20crypto_tls_md5_prf_cC2EP18abs_eap_am_tools_c @ 813 NONAME + _ZN20crypto_tls_md5_prf_cD0Ev @ 814 NONAME + _ZN20crypto_tls_md5_prf_cD1Ev @ 815 NONAME + _ZN20crypto_tls_md5_prf_cD2Ev @ 816 NONAME + _ZN20eap_am_crypto_sha1_c10hash_finalEPvPm @ 817 NONAME + _ZN20eap_am_crypto_sha1_c11hash_updateEPKvm @ 818 NONAME + _ZN20eap_am_crypto_sha1_c12copy_contextEPK19eap_variable_data_cyPKmS4_S4_ @ 819 NONAME + _ZN20eap_am_crypto_sha1_c12get_is_validEv @ 820 NONAME + _ZN20eap_am_crypto_sha1_c12hash_cleanupEv @ 821 NONAME + _ZN20eap_am_crypto_sha1_c12set_is_validEv @ 822 NONAME + _ZN20eap_am_crypto_sha1_c14get_block_sizeEv @ 823 NONAME + _ZN20eap_am_crypto_sha1_c14set_is_invalidEv @ 824 NONAME + _ZN20eap_am_crypto_sha1_c17get_digest_lengthEv @ 825 NONAME + _ZN20eap_am_crypto_sha1_c19copy_message_digestEPvPm @ 826 NONAME + _ZN20eap_am_crypto_sha1_c23eap_sha1_dss_G_functionEPKvmPvPm @ 827 NONAME + _ZN20eap_am_crypto_sha1_c32eap_sha1_process_data_host_orderEPKmm @ 828 NONAME + _ZN20eap_am_crypto_sha1_c35eap_sha1_process_data_network_orderEPKmm @ 829 NONAME + _ZN20eap_am_crypto_sha1_c4copyEv @ 830 NONAME + _ZN20eap_am_crypto_sha1_c9hash_initEv @ 831 NONAME + _ZN20eap_am_crypto_sha1_cC1EP18abs_eap_am_tools_c @ 832 NONAME + _ZN20eap_am_crypto_sha1_cC2EP18abs_eap_am_tools_c @ 833 NONAME + _ZN20eap_am_crypto_sha1_cD0Ev @ 834 NONAME + _ZN20eap_am_crypto_sha1_cD1Ev @ 835 NONAME + _ZN20eap_am_crypto_sha1_cD2Ev @ 836 NONAME + _ZN20eap_buf_chain_base_c10initializeEm @ 837 NONAME + _ZN20eap_buf_chain_base_c11set_encryptEb @ 838 NONAME + _ZN20eap_buf_chain_base_c12get_am_toolsEv @ 839 NONAME + _ZN20eap_buf_chain_base_c13set_is_clientEb @ 840 NONAME + _ZN20eap_buf_chain_base_c15set_data_lengthEm @ 841 NONAME + _ZN20eap_buf_chain_base_c17reset_data_bufferEv @ 842 NONAME + _ZN20eap_buf_chain_base_c17set_buffer_lengthEm @ 843 NONAME + _ZN20eap_buf_chain_base_c17set_stack_addressEPKv @ 844 NONAME + _ZN20eap_buf_chain_base_c18add_data_to_offsetEmPK19eap_variable_data_c @ 845 NONAME + _ZN20eap_buf_chain_base_c18add_data_to_offsetEmPKvm @ 846 NONAME + _ZN20eap_buf_chain_base_c18get_is_manipulatedEv @ 847 NONAME + _ZN20eap_buf_chain_base_c18set_is_manipulatedEv @ 848 NONAME + _ZN20eap_buf_chain_base_c19set_mem_guard_bytesEv @ 849 NONAME + _ZN20eap_buf_chain_base_c20get_mem_guard_lengthEv @ 850 NONAME + _ZN20eap_buf_chain_base_c20set_do_length_checksEb @ 851 NONAME + _ZN20eap_buf_chain_base_c21get_random_error_typeEv @ 852 NONAME + _ZN20eap_buf_chain_base_c21get_send_packet_indexEv @ 853 NONAME + _ZN20eap_buf_chain_base_c21set_random_error_typeE21eap_random_error_type @ 854 NONAME + _ZN20eap_buf_chain_base_c21set_send_packet_indexEm @ 855 NONAME + _ZN20eap_buf_chain_base_c28get_do_packet_retransmissionEv @ 856 NONAME + _ZN20eap_buf_chain_base_c28set_do_packet_retransmissionEb @ 857 NONAME + _ZN20eap_buf_chain_base_c8add_dataEPK19eap_variable_data_c @ 858 NONAME + _ZN20eap_buf_chain_base_c8add_dataEPKvm @ 859 NONAME + _ZN20eap_buf_chain_base_cC2E17eap_read_buffer_eP18abs_eap_am_tools_cPKhmb @ 860 NONAME + _ZN20eap_buf_chain_base_cC2E17eap_read_buffer_eP18abs_eap_am_tools_cm @ 861 NONAME + _ZN20eap_buf_chain_base_cC2E18eap_write_buffer_eP18abs_eap_am_tools_cPhmbbm @ 862 NONAME + _ZN20eap_buf_chain_base_cC2E18eap_write_buffer_eP18abs_eap_am_tools_cm @ 863 NONAME + _ZN20eap_buf_chain_base_cD0Ev @ 864 NONAME + _ZN20eap_buf_chain_base_cD1Ev @ 865 NONAME + _ZN20eap_buf_chain_base_cD2Ev @ 866 NONAME + _ZN20eap_rogue_ap_entry_c15set_mac_addressEPKh @ 867 NONAME + _ZN20eap_rogue_ap_entry_c16set_rogue_reasonE21eap_rogue_ap_reason_e @ 868 NONAME + _ZN20eap_rogue_ap_entry_cC1EP18abs_eap_am_tools_c @ 869 NONAME + _ZN20eap_rogue_ap_entry_cC2EP18abs_eap_am_tools_c @ 870 NONAME + _ZN20eap_rogue_ap_entry_cD0Ev @ 871 NONAME + _ZN20eap_rogue_ap_entry_cD1Ev @ 872 NONAME + _ZN20eap_rogue_ap_entry_cD2Ev @ 873 NONAME + _ZN20eap_type_selection_cC1EP18abs_eap_am_tools_c19eap_expanded_type_cb @ 874 NONAME + _ZN20eap_type_selection_cC2EP18abs_eap_am_tools_c19eap_expanded_type_cb @ 875 NONAME + _ZN20eap_type_selection_cD0Ev @ 876 NONAME + _ZN20eap_type_selection_cD1Ev @ 877 NONAME + _ZN20eap_type_selection_cD2Ev @ 878 NONAME + _ZN21crypto_tls_base_prf_c12get_is_validEv @ 879 NONAME + _ZN21crypto_tls_base_prf_c12set_is_validEv @ 880 NONAME + _ZN21crypto_tls_base_prf_c14set_is_invalidEv @ 881 NONAME + _ZN21crypto_tls_base_prf_c15tls_prf_A_valueEP27abs_crypto_hmac_algorithm_cP19eap_variable_data_cS3_S3_ @ 882 NONAME + _ZN21crypto_tls_base_prf_c15tls_prf_cleanupEv @ 883 NONAME + _ZN21crypto_tls_base_prf_c17tls_prf_one_roundEP27abs_crypto_hmac_algorithm_cPK19eap_variable_data_cPS2_S5_Pvm @ 884 NONAME + _ZN21crypto_tls_base_prf_cC1EP18abs_eap_am_tools_c @ 885 NONAME + _ZN21crypto_tls_base_prf_cC2EP18abs_eap_am_tools_c @ 886 NONAME + _ZN21crypto_tls_base_prf_cD0Ev @ 887 NONAME + _ZN21crypto_tls_base_prf_cD1Ev @ 888 NONAME + _ZN21crypto_tls_base_prf_cD2Ev @ 889 NONAME + _ZN21crypto_tls_sha1_prf_c12get_is_validEv @ 890 NONAME + _ZN21crypto_tls_sha1_prf_c12set_is_validEv @ 891 NONAME + _ZN21crypto_tls_sha1_prf_c12tls_prf_initEPK19eap_variable_data_cS2_S2_ @ 892 NONAME + _ZN21crypto_tls_sha1_prf_c14set_is_invalidEv @ 893 NONAME + _ZN21crypto_tls_sha1_prf_c14tls_prf_outputEPvm @ 894 NONAME + _ZN21crypto_tls_sha1_prf_c15tls_prf_cleanupEv @ 895 NONAME + _ZN21crypto_tls_sha1_prf_cC1EP18abs_eap_am_tools_c @ 896 NONAME + _ZN21crypto_tls_sha1_prf_cC2EP18abs_eap_am_tools_c @ 897 NONAME + _ZN21crypto_tls_sha1_prf_cD0Ev @ 898 NONAME + _ZN21crypto_tls_sha1_prf_cD1Ev @ 899 NONAME + _ZN21crypto_tls_sha1_prf_cD2Ev @ 900 NONAME + _ZN21eap_am_memory_store_c11remove_dataEPK19eap_variable_data_c @ 901 NONAME + _ZN21eap_am_memory_store_c12get_is_validEv @ 902 NONAME + _ZN21eap_am_memory_store_c12set_is_validEv @ 903 NONAME + _ZN21eap_am_memory_store_c13timer_expiredEmPv @ 904 NONAME + _ZN21eap_am_memory_store_c17timer_delete_dataEmPv @ 905 NONAME + _ZN21eap_am_memory_store_c8add_dataEPK19eap_variable_data_cPK22eap_tlv_message_data_cm @ 906 NONAME + _ZN21eap_am_memory_store_c8get_dataEPK19eap_variable_data_cP22eap_tlv_message_data_c @ 907 NONAME + _ZN21eap_am_memory_store_c8shutdownEv @ 908 NONAME + _ZN21eap_am_memory_store_cC1EP18abs_eap_am_tools_c @ 909 NONAME + _ZN21eap_am_memory_store_cC2EP18abs_eap_am_tools_c @ 910 NONAME + _ZN21eap_am_memory_store_cD0Ev @ 911 NONAME + _ZN21eap_am_memory_store_cD1Ev @ 912 NONAME + _ZN21eap_am_memory_store_cD2Ev @ 913 NONAME + _ZN22eap_am_mutex_symbian_c11mutex_enterEv @ 914 NONAME + _ZN22eap_am_mutex_symbian_c11mutex_leaveEP18abs_eap_am_tools_c @ 915 NONAME + _ZN22eap_am_mutex_symbian_c15dublicate_mutexEv @ 916 NONAME + _ZN22eap_am_mutex_symbian_cC1EPKS_ @ 917 NONAME + _ZN22eap_am_mutex_symbian_cC1Ev @ 918 NONAME + _ZN22eap_am_mutex_symbian_cC2EPKS_ @ 919 NONAME + _ZN22eap_am_mutex_symbian_cC2Ev @ 920 NONAME + _ZN22eap_am_mutex_symbian_cD0Ev @ 921 NONAME + _ZN22eap_am_mutex_symbian_cD1Ev @ 922 NONAME + _ZN22eap_am_mutex_symbian_cD2Ev @ 923 NONAME + _ZN22eap_am_tools_symbian_c10get_cryptoEv @ 924 NONAME + _ZN22eap_am_tools_symbian_c11pulse_timerEm @ 925 NONAME + _ZN22eap_am_tools_symbian_c11timer_sleepEm @ 926 NONAME + _ZN22eap_am_tools_symbian_c12am_set_timerEP20abs_eap_base_timer_cmPvm @ 927 NONAME + _ZN22eap_am_tools_symbian_c13config_strlenEPKc @ 928 NONAME + _ZN22eap_am_tools_symbian_c15am_cancel_timerEP20abs_eap_base_timer_cm @ 929 NONAME + _ZN22eap_am_tools_symbian_c15begin_db_deleteER7RDbView @ 930 NONAME + _ZN22eap_am_tools_symbian_c15begin_db_updateER7RDbView @ 931 NONAME + _ZN22eap_am_tools_symbian_c15enter_crypto_csEv @ 932 NONAME + _ZN22eap_am_tools_symbian_c15formatted_printEPKcz @ 933 NONAME + _ZN22eap_am_tools_symbian_c15get_clock_ticksEv @ 934 NONAME + _ZN22eap_am_tools_symbian_c15get_trace_mutexEv @ 935 NONAME + _ZN22eap_am_tools_symbian_c15leave_crypto_csEv @ 936 NONAME + _ZN22eap_am_tools_symbian_c16get_global_mutexEv @ 937 NONAME + _ZN22eap_am_tools_symbian_c17enter_trace_mutexEv @ 938 NONAME + _ZN22eap_am_tools_symbian_c17get_gmt_unix_timeEv @ 939 NONAME + _ZN22eap_am_tools_symbian_c17leave_trace_mutexEv @ 940 NONAME + _ZN22eap_am_tools_symbian_c18enter_global_mutexEv @ 941 NONAME + _ZN22eap_am_tools_symbian_c18get_hardware_ticksEv @ 942 NONAME + _ZN22eap_am_tools_symbian_c18leave_global_mutexEv @ 943 NONAME + _ZN22eap_am_tools_symbian_c19set_trace_file_nameEPK19eap_variable_data_c @ 944 NONAME + _ZN22eap_am_tools_symbian_c19u64_struct_to_u64_tE10u64_struct @ 945 NONAME + _ZN22eap_am_tools_symbian_c19u64_t_to_u64_structEy @ 946 NONAME + _ZN22eap_am_tools_symbian_c20am_cancel_all_timersEv @ 947 NONAME + _ZN22eap_am_tools_symbian_c20begin_db_transactionER16RDbNamedDatabase @ 948 NONAME + _ZN22eap_am_tools_symbian_c23convert_unicode_to_utf8ER19eap_variable_data_cRKS0_ @ 949 NONAME + _ZN22eap_am_tools_symbian_c23convert_utf8_to_unicodeER19eap_variable_data_cRKS0_ @ 950 NONAME + _ZN22eap_am_tools_symbian_c23get_timer_resolution_msEv @ 951 NONAME + _ZN22eap_am_tools_symbian_c23re_activate_timer_queueEv @ 952 NONAME + _ZN22eap_am_tools_symbian_c23set_max_trace_file_sizeEm @ 953 NONAME + _ZN22eap_am_tools_symbian_c23set_timer_resolution_msEm @ 954 NONAME + _ZN22eap_am_tools_symbian_c24get_timer_queue_is_emptyEv @ 955 NONAME + _ZN22eap_am_tools_symbian_c25get_clock_ticks_of_secondEv @ 956 NONAME + _ZN22eap_am_tools_symbian_c26get_is_timer_thread_activeEv @ 957 NONAME + _ZN22eap_am_tools_symbian_c28get_hardware_ticks_of_secondEv @ 958 NONAME + _ZN22eap_am_tools_symbian_c30get_use_eap_milli_second_timerEv @ 959 NONAME + _ZN22eap_am_tools_symbian_c30set_use_eap_milli_second_timerEb @ 960 NONAME + _ZN22eap_am_tools_symbian_c31convert_am_error_to_eapol_errorEl @ 961 NONAME + _ZN22eap_am_tools_symbian_c31convert_eapol_error_to_am_errorE12eap_status_e @ 962 NONAME + _ZN22eap_am_tools_symbian_c5sleepEm @ 963 NONAME + _ZN22eap_am_tools_symbian_c6getenvEPK19eap_variable_data_cPS0_ @ 964 NONAME + _ZN22eap_am_tools_symbian_c6memchrEPKvhm @ 965 NONAME + _ZN22eap_am_tools_symbian_c6memcmpEPKvS1_m @ 966 NONAME + _ZN22eap_am_tools_symbian_c6memsetEPvlm @ 967 NONAME + _ZN22eap_am_tools_symbian_c6sprintER6TDes16PKcz @ 968 NONAME + _ZN22eap_am_tools_symbian_c6strlenEPKc @ 969 NONAME + _ZN22eap_am_tools_symbian_c7isspaceEh @ 970 NONAME + _ZN22eap_am_tools_symbian_c7memmoveEPvPKvm @ 971 NONAME + _ZN22eap_am_tools_symbian_c7memrchrEPKvhm @ 972 NONAME + _ZN22eap_am_tools_symbian_c8shutdownEv @ 973 NONAME + _ZN22eap_am_tools_symbian_c8snprintfEPhmPKcz @ 974 NONAME + _ZN22eap_am_tools_symbian_c9configureEv @ 975 NONAME + _ZN22eap_am_tools_symbian_cC1EPKc @ 976 NONAME + _ZN22eap_am_tools_symbian_cC2EPKc @ 977 NONAME + _ZN22eap_am_tools_symbian_cD0Ev @ 978 NONAME + _ZN22eap_am_tools_symbian_cD1Ev @ 979 NONAME + _ZN22eap_am_tools_symbian_cD2Ev @ 980 NONAME + _ZN22eap_tlv_message_data_c12get_is_validEv @ 981 NONAME + _ZN22eap_tlv_message_data_c16add_message_dataEmmPKv @ 982 NONAME + _ZN22eap_tlv_message_data_c16set_message_dataEmPKv @ 983 NONAME + _ZN22eap_tlv_message_data_c17copy_message_dataEmPKv @ 984 NONAME + _ZN22eap_tlv_message_data_c18add_message_headerEmm @ 985 NONAME + _ZN22eap_tlv_message_data_c18parse_message_dataEP11eap_array_cI16eap_tlv_header_cE @ 986 NONAME + _ZN22eap_tlv_message_data_c22add_message_data_arrayEmmP11eap_array_cI19eap_variable_data_cE @ 987 NONAME + _ZN22eap_tlv_message_data_c23allocate_message_bufferEmmPPv @ 988 NONAME + _ZN22eap_tlv_message_data_c28allocate_message_data_bufferEm @ 989 NONAME + _ZN22eap_tlv_message_data_c31object_decrease_reference_countEv @ 990 NONAME + _ZN22eap_tlv_message_data_c31object_increase_reference_countEv @ 991 NONAME + _ZN22eap_tlv_message_data_cC1EP18abs_eap_am_tools_c @ 992 NONAME + _ZN22eap_tlv_message_data_cC2EP18abs_eap_am_tools_c @ 993 NONAME + _ZN22eap_tlv_message_data_cD0Ev @ 994 NONAME + _ZN22eap_tlv_message_data_cD1Ev @ 995 NONAME + _ZN22eap_tlv_message_data_cD2Ev @ 996 NONAME + _ZN22eapol_RC4_key_header_c10get_key_IVEv @ 997 NONAME + _ZN22eapol_RC4_key_header_c12set_key_flagE21eapol_RC4_key_flags_e @ 998 NONAME + _ZN22eapol_RC4_key_header_c13set_key_indexEh @ 999 NONAME + _ZN22eapol_RC4_key_header_c14set_key_lengthEt @ 1000 NONAME + _ZN22eapol_RC4_key_header_c17get_header_lengthEv @ 1001 NONAME + _ZN22eapol_RC4_key_header_c18get_replay_counterEv @ 1002 NONAME + _ZN22eapol_RC4_key_header_c18zero_key_signatureEP18abs_eap_am_tools_c @ 1003 NONAME + _ZN22eapol_RC4_key_header_c21set_eapol_packet_typeE19eapol_packet_type_e @ 1004 NONAME + _ZN22eapol_RC4_key_header_c23set_key_descriptor_typeE27eapol_key_descriptor_type_e @ 1005 NONAME + _ZN22eapol_RC4_key_header_c26set_eapol_protocol_versionE24eapol_protocol_version_e @ 1006 NONAME + _ZN22eapol_RC4_key_header_c28set_eapol_packet_body_lengthEt @ 1007 NONAME + _ZN22eapol_RC4_key_header_cC1EP18abs_eap_am_tools_cPvm @ 1008 NONAME + _ZN22eapol_RC4_key_header_cC2EP18abs_eap_am_tools_cPvm @ 1009 NONAME + _ZN22eapol_RC4_key_header_cD0Ev @ 1010 NONAME + _ZN22eapol_RC4_key_header_cD1Ev @ 1011 NONAME + _ZN22eapol_RC4_key_header_cD2Ev @ 1012 NONAME + _ZN23crypto_kd_hmac_sha256_c10expand_keyEP19eap_variable_data_cmPKS0_S3_ @ 1013 NONAME + _ZN23crypto_kd_hmac_sha256_c12get_is_validEv @ 1014 NONAME + _ZN23crypto_kd_hmac_sha256_cC1EP18abs_eap_am_tools_c @ 1015 NONAME + _ZN23crypto_kd_hmac_sha256_cC2EP18abs_eap_am_tools_c @ 1016 NONAME + _ZN23crypto_kd_hmac_sha256_cD0Ev @ 1017 NONAME + _ZN23crypto_kd_hmac_sha256_cD1Ev @ 1018 NONAME + _ZN23crypto_kd_hmac_sha256_cD2Ev @ 1019 NONAME + _ZN23eap_am_crypto_sha_256_c10hash_finalEPvPm @ 1020 NONAME + _ZN23eap_am_crypto_sha_256_c11hash_updateEPKvm @ 1021 NONAME + _ZN23eap_am_crypto_sha_256_c12copy_contextEPK19eap_variable_data_cyPKmS4_S4_ @ 1022 NONAME + _ZN23eap_am_crypto_sha_256_c12get_is_validEv @ 1023 NONAME + _ZN23eap_am_crypto_sha_256_c12hash_cleanupEv @ 1024 NONAME + _ZN23eap_am_crypto_sha_256_c12set_is_validEv @ 1025 NONAME + _ZN23eap_am_crypto_sha_256_c14get_block_sizeEv @ 1026 NONAME + _ZN23eap_am_crypto_sha_256_c14set_is_invalidEv @ 1027 NONAME + _ZN23eap_am_crypto_sha_256_c17get_digest_lengthEv @ 1028 NONAME + _ZN23eap_am_crypto_sha_256_c19copy_message_digestEPvPm @ 1029 NONAME + _ZN23eap_am_crypto_sha_256_c35eap_sha_256_process_data_host_orderEPKmm @ 1030 NONAME + _ZN23eap_am_crypto_sha_256_c38eap_sha_256_process_data_network_orderEPKmm @ 1031 NONAME + _ZN23eap_am_crypto_sha_256_c4copyEv @ 1032 NONAME + _ZN23eap_am_crypto_sha_256_c9hash_initEv @ 1033 NONAME + _ZN23eap_am_crypto_sha_256_cC1EP18abs_eap_am_tools_c @ 1034 NONAME + _ZN23eap_am_crypto_sha_256_cC2EP18abs_eap_am_tools_c @ 1035 NONAME + _ZN23eap_am_crypto_sha_256_cD0Ev @ 1036 NONAME + _ZN23eap_am_crypto_sha_256_cD1Ev @ 1037 NONAME + _ZN23eap_am_crypto_sha_256_cD2Ev @ 1038 NONAME + _ZN23eap_am_crypto_symbian_c10dh_cleanupEPK19eap_variable_data_c @ 1039 NONAME + _ZN23eap_am_crypto_symbian_c10dsa_verifyEP19eap_variable_data_cPKS0_S3_S3_S3_S3_S3_ @ 1040 NONAME + _ZN23eap_am_crypto_symbian_c10md4_updateEP19eap_variable_data_cPKhm @ 1041 NONAME + _ZN23eap_am_crypto_symbian_c10md5_updateEP19eap_variable_data_cPKhm @ 1042 NONAME + _ZN23eap_am_crypto_symbian_c10rsa_verifyEP19eap_variable_data_cPKS0_S3_S3_ @ 1043 NONAME + _ZN23eap_am_crypto_symbian_c10sha1_finalEP19eap_variable_data_cPhPm @ 1044 NONAME + _ZN23eap_am_crypto_symbian_c11aes_cleanupEP19eap_variable_data_c @ 1045 NONAME + _ZN23eap_am_crypto_symbian_c11dsa_cleanupEP19eap_variable_data_c @ 1046 NONAME + _ZN23eap_am_crypto_symbian_c11md4_cleanupEP19eap_variable_data_c @ 1047 NONAME + _ZN23eap_am_crypto_symbian_c11md5_cleanupEP19eap_variable_data_c @ 1048 NONAME + _ZN23eap_am_crypto_symbian_c11rc4_cleanupEP19eap_variable_data_c @ 1049 NONAME + _ZN23eap_am_crypto_symbian_c11rc4_decryptEPK19eap_variable_data_cPKvPvm @ 1050 NONAME + _ZN23eap_am_crypto_symbian_c11rc4_decryptEPK19eap_variable_data_cPvm @ 1051 NONAME + _ZN23eap_am_crypto_symbian_c11rc4_encryptEPK19eap_variable_data_cPKvPvm @ 1052 NONAME + _ZN23eap_am_crypto_symbian_c11rc4_encryptEPK19eap_variable_data_cPvm @ 1053 NONAME + _ZN23eap_am_crypto_symbian_c11rc4_set_keyEP19eap_variable_data_cPKS0_ @ 1054 NONAME + _ZN23eap_am_crypto_symbian_c11rsa_cleanupEP19eap_variable_data_c @ 1055 NONAME + _ZN23eap_am_crypto_symbian_c11sha1_updateEP19eap_variable_data_cPKhm @ 1056 NONAME + _ZN23eap_am_crypto_symbian_c12set_is_validEv @ 1057 NONAME + _ZN23eap_am_crypto_symbian_c12sha1_cleanupEP19eap_variable_data_c @ 1058 NONAME + _ZN23eap_am_crypto_symbian_c12sha_256_initEP19eap_variable_data_c @ 1059 NONAME + _ZN23eap_am_crypto_symbian_c13add_rand_seedEPKhm @ 1060 NONAME + _ZN23eap_am_crypto_symbian_c13sha_256_finalEP19eap_variable_data_cPhPm @ 1061 NONAME + _ZN23eap_am_crypto_symbian_c14aes_block_sizeEv @ 1062 NONAME + _ZN23eap_am_crypto_symbian_c14aes_key_lengthEv @ 1063 NONAME + _ZN23eap_am_crypto_symbian_c14get_rand_bytesEPhm @ 1064 NONAME + _ZN23eap_am_crypto_symbian_c14sha_256_updateEP19eap_variable_data_cPKhm @ 1065 NONAME + _ZN23eap_am_crypto_symbian_c15sha_256_cleanupEP19eap_variable_data_c @ 1066 NONAME + _ZN23eap_am_crypto_symbian_c15use_test_randomEPKhmb @ 1067 NONAME + _ZN23eap_am_crypto_symbian_c16cleanup_3des_edeEP19eap_variable_data_c @ 1068 NONAME + _ZN23eap_am_crypto_symbian_c16md4_copy_contextEP19eap_variable_data_cPKS0_ @ 1069 NONAME + _ZN23eap_am_crypto_symbian_c16md5_copy_contextEP19eap_variable_data_cPKS0_ @ 1070 NONAME + _ZN23eap_am_crypto_symbian_c17aes_decrypt_blockEP19eap_variable_data_cPKhPhm @ 1071 NONAME + _ZN23eap_am_crypto_symbian_c17aes_encrypt_blockEP19eap_variable_data_cPKhPhm @ 1072 NONAME + _ZN23eap_am_crypto_symbian_c17dss_pseudo_randomEPhmS0_m @ 1073 NONAME + _ZN23eap_am_crypto_symbian_c17sha1_copy_contextEP19eap_variable_data_cPKS0_ @ 1074 NONAME + _ZN23eap_am_crypto_symbian_c18get_md4_block_sizeEP19eap_variable_data_c @ 1075 NONAME + _ZN23eap_am_crypto_symbian_c18get_md5_block_sizeEP19eap_variable_data_c @ 1076 NONAME + _ZN23eap_am_crypto_symbian_c19block_size_3des_edeEv @ 1077 NONAME + _ZN23eap_am_crypto_symbian_c19get_sha1_block_sizeEP19eap_variable_data_c @ 1078 NONAME + _ZN23eap_am_crypto_symbian_c19key_length_3des_edeEv @ 1079 NONAME + _ZN23eap_am_crypto_symbian_c20sha_256_copy_contextEP19eap_variable_data_cPKS0_ @ 1080 NONAME + _ZN23eap_am_crypto_symbian_c21get_md4_digest_lengthEP19eap_variable_data_c @ 1081 NONAME + _ZN23eap_am_crypto_symbian_c21get_md5_digest_lengthEP19eap_variable_data_c @ 1082 NONAME + _ZN23eap_am_crypto_symbian_c22add_rand_seed_hw_ticksEv @ 1083 NONAME + _ZN23eap_am_crypto_symbian_c22aes_set_decryption_keyEP19eap_variable_data_cPKhm @ 1084 NONAME + _ZN23eap_am_crypto_symbian_c22aes_set_encryption_keyEP19eap_variable_data_cPKhm @ 1085 NONAME + _ZN23eap_am_crypto_symbian_c22decrypt_block_3des_edeEP19eap_variable_data_cPKhPhm @ 1086 NONAME + _ZN23eap_am_crypto_symbian_c22encrypt_block_3des_edeEP19eap_variable_data_cPKhPhm @ 1087 NONAME + _ZN23eap_am_crypto_symbian_c22generate_g_power_to_xyEPK19eap_variable_data_cS2_PS0_PKhmS5_m @ 1088 NONAME + _ZN23eap_am_crypto_symbian_c22get_sha1_digest_lengthEP19eap_variable_data_c @ 1089 NONAME + _ZN23eap_am_crypto_symbian_c22get_sha_256_block_sizeEP19eap_variable_data_c @ 1090 NONAME + _ZN23eap_am_crypto_symbian_c24open_crypto_memory_leaksEv @ 1091 NONAME + _ZN23eap_am_crypto_symbian_c25close_crypto_memory_leaksEv @ 1092 NONAME + _ZN23eap_am_crypto_symbian_c25get_sha_256_digest_lengthEP19eap_variable_data_c @ 1093 NONAME + _ZN23eap_am_crypto_symbian_c27rsa_decrypt_with_public_keyEP19eap_variable_data_cPKS0_S3_S1_ @ 1094 NONAME + _ZN23eap_am_crypto_symbian_c27rsa_encrypt_with_public_keyEP19eap_variable_data_cPKS0_S3_S1_ @ 1095 NONAME + _ZN23eap_am_crypto_symbian_c27set_decryption_key_3des_edeEP19eap_variable_data_cPKhm @ 1096 NONAME + _ZN23eap_am_crypto_symbian_c27set_encryption_key_3des_edeEP19eap_variable_data_cPKhm @ 1097 NONAME + _ZN23eap_am_crypto_symbian_c28generate_diffie_hellman_keysEP19eap_variable_data_cS1_PKhmS3_m @ 1098 NONAME + _ZN23eap_am_crypto_symbian_c28rsa_decrypt_with_private_keyEP19eap_variable_data_cPKS0_S3_S1_ @ 1099 NONAME + _ZN23eap_am_crypto_symbian_c28rsa_encrypt_with_private_keyEP19eap_variable_data_cPKS0_S3_S1_ @ 1100 NONAME + _ZN23eap_am_crypto_symbian_c8dsa_initEP19eap_variable_data_c @ 1101 NONAME + _ZN23eap_am_crypto_symbian_c8dsa_signEP19eap_variable_data_cPKS0_S3_S1_ @ 1102 NONAME + _ZN23eap_am_crypto_symbian_c8md4_initEP19eap_variable_data_c @ 1103 NONAME + _ZN23eap_am_crypto_symbian_c8md5_initEP19eap_variable_data_c @ 1104 NONAME + _ZN23eap_am_crypto_symbian_c8rsa_initEP19eap_variable_data_c @ 1105 NONAME + _ZN23eap_am_crypto_symbian_c8rsa_signEP19eap_variable_data_cPKS0_S3_S1_ @ 1106 NONAME + _ZN23eap_am_crypto_symbian_c9configureEv @ 1107 NONAME + _ZN23eap_am_crypto_symbian_c9md4_finalEP19eap_variable_data_cPhPm @ 1108 NONAME + _ZN23eap_am_crypto_symbian_c9md5_finalEP19eap_variable_data_cPhPm @ 1109 NONAME + _ZN23eap_am_crypto_symbian_c9sha1_initEP19eap_variable_data_c @ 1110 NONAME + _ZN23eap_am_crypto_symbian_cC1EP18abs_eap_am_tools_c @ 1111 NONAME + _ZN23eap_am_crypto_symbian_cC2EP18abs_eap_am_tools_c @ 1112 NONAME + _ZN23eap_am_crypto_symbian_cD0Ev @ 1113 NONAME + _ZN23eap_am_crypto_symbian_cD1Ev @ 1114 NONAME + _ZN23eap_am_crypto_symbian_cD2Ev @ 1115 NONAME + _ZN23eapol_RSNA_key_header_c11set_bits_onEttmm @ 1116 NONAME + _ZN23eapol_RSNA_key_header_c12reset_headerEh31eapol_key_authentication_type_eNS_19eapol_RSNA_cipher_eEybbbbbbbbb24eapol_protocol_version_e27eapol_key_descriptor_type_e @ 1117 NONAME + _ZN23eapol_RSNA_key_header_c12zero_key_MICEP18abs_eap_am_tools_c @ 1118 NONAME + _ZN23eapol_RSNA_key_header_c12zero_key_RSCEP18abs_eap_am_tools_c @ 1119 NONAME + _ZN23eapol_RSNA_key_header_c14set_key_lengthEt @ 1120 NONAME + _ZN23eapol_RSNA_key_header_c14zero_key_NONCEEP18abs_eap_am_tools_c @ 1121 NONAME + _ZN23eapol_RSNA_key_header_c17get_header_lengthEv @ 1122 NONAME + _ZN23eapol_RSNA_key_header_c17zero_EAPOL_key_IVEP18abs_eap_am_tools_c @ 1123 NONAME + _ZN23eapol_RSNA_key_header_c17zero_key_reservedEP18abs_eap_am_tools_c @ 1124 NONAME + _ZN23eapol_RSNA_key_header_c19set_key_data_lengthEt @ 1125 NONAME + _ZN23eapol_RSNA_key_header_c19set_key_informationEt @ 1126 NONAME + _ZN23eapol_RSNA_key_header_c21set_eapol_packet_typeE19eapol_packet_type_e @ 1127 NONAME + _ZN23eapol_RSNA_key_header_c22set_key_replay_counterEy @ 1128 NONAME + _ZN23eapol_RSNA_key_header_c23set_key_descriptor_typeE27eapol_key_descriptor_type_e @ 1129 NONAME + _ZN23eapol_RSNA_key_header_c24zero_key_STA_MAC_addressEP18abs_eap_am_tools_c @ 1130 NONAME + _ZN23eapol_RSNA_key_header_c25set_key_information_errorEb @ 1131 NONAME + _ZN23eapol_RSNA_key_header_c26set_eapol_protocol_versionE24eapol_protocol_version_e @ 1132 NONAME + _ZN23eapol_RSNA_key_header_c26set_key_information_secureEb @ 1133 NONAME + _ZN23eapol_RSNA_key_header_c27set_key_information_installEb @ 1134 NONAME + _ZN23eapol_RSNA_key_header_c27set_key_information_key_MICEb @ 1135 NONAME + _ZN23eapol_RSNA_key_header_c27set_key_information_key_ackEb @ 1136 NONAME + _ZN23eapol_RSNA_key_header_c27set_key_information_requestEb @ 1137 NONAME + _ZN23eapol_RSNA_key_header_c28set_eapol_packet_body_lengthEm @ 1138 NONAME + _ZN23eapol_RSNA_key_header_c28set_key_information_key_typeEb @ 1139 NONAME + _ZN23eapol_RSNA_key_header_c29set_key_information_key_indexEh @ 1140 NONAME + _ZN23eapol_RSNA_key_header_c36zero_EAPOL_header_and_Key_descriptorEP18abs_eap_am_tools_c @ 1141 NONAME + _ZN23eapol_RSNA_key_header_c38set_key_information_encrypted_key_dataEb @ 1142 NONAME + _ZN23eapol_RSNA_key_header_c42set_key_information_key_descriptor_versionEh @ 1143 NONAME + _ZN23eapol_RSNA_key_header_cC1EP18abs_eap_am_tools_cbbPvm @ 1144 NONAME + _ZN23eapol_RSNA_key_header_cC2EP18abs_eap_am_tools_cbbPvm @ 1145 NONAME + _ZN23eapol_RSNA_key_header_cD0Ev @ 1146 NONAME + _ZN23eapol_RSNA_key_header_cD1Ev @ 1147 NONAME + _ZN23eapol_RSNA_key_header_cD2Ev @ 1148 NONAME + _ZN23network_key_and_index_c12get_is_validEv @ 1149 NONAME + _ZN23network_key_and_index_c15get_network_keyEv @ 1150 NONAME + _ZN23network_key_and_index_c17get_is_valid_dataEv @ 1151 NONAME + _ZN23network_key_and_index_c21get_network_key_indexEv @ 1152 NONAME + _ZN23network_key_and_index_c21set_network_key_indexEh @ 1153 NONAME + _ZN23network_key_and_index_c4copyEv @ 1154 NONAME + _ZN23network_key_and_index_cC1EP18abs_eap_am_tools_c @ 1155 NONAME + _ZN23network_key_and_index_cC2EP18abs_eap_am_tools_c @ 1156 NONAME + _ZN23network_key_and_index_cD0Ev @ 1157 NONAME + _ZN23network_key_and_index_cD1Ev @ 1158 NONAME + _ZN23network_key_and_index_cD2Ev @ 1159 NONAME + _ZN24eap_am_mutex_reference_c13add_referenceEv @ 1160 NONAME + _ZN24eap_am_mutex_reference_c15get_is_reservedEv @ 1161 NONAME + _ZN24eap_am_mutex_reference_c15set_is_reservedEb @ 1162 NONAME + _ZN24eap_am_mutex_reference_c16remove_referenceEv @ 1163 NONAME + _ZN24eap_am_mutex_reference_c19get_reference_countEv @ 1164 NONAME + _ZN24eap_am_mutex_reference_cC1Ev @ 1165 NONAME + _ZN24eap_am_mutex_reference_cC2Ev @ 1166 NONAME + _ZN24eap_am_mutex_reference_cD0Ev @ 1167 NONAME + _ZN24eap_am_mutex_reference_cD1Ev @ 1168 NONAME + _ZN24eap_am_mutex_reference_cD2Ev @ 1169 NONAME + _ZN24eap_master_session_key_c12set_eap_typeE19eap_expanded_type_c @ 1170 NONAME + _ZN24eap_master_session_key_c18copy_leap_passwordEPK19eap_variable_data_c @ 1171 NONAME + _ZN24eap_master_session_key_c8set_copyEPKS_ @ 1172 NONAME + _ZN24eap_master_session_key_cC1EP18abs_eap_am_tools_c19eap_expanded_type_c @ 1173 NONAME + _ZN24eap_master_session_key_cC2EP18abs_eap_am_tools_c19eap_expanded_type_c @ 1174 NONAME + _ZN24eap_master_session_key_cD0Ev @ 1175 NONAME + _ZN24eap_master_session_key_cD1Ev @ 1176 NONAME + _ZN24eap_master_session_key_cD2Ev @ 1177 NONAME + _ZN24eap_state_notification_c16get_state_stringEmm @ 1178 NONAME + _ZN24eap_state_notification_c19get_protocol_stringEmm @ 1179 NONAME + _ZN24eap_state_notification_c23set_notification_stringEPK19eap_variable_data_cb @ 1180 NONAME + _ZN24eap_state_notification_c24set_authentication_errorE12eap_status_e @ 1181 NONAME + _ZN24eap_state_notification_c25get_protocol_layer_stringEm @ 1182 NONAME + _ZN24eap_state_notification_cC1EP18abs_eap_am_tools_cPK19eap_am_network_id_cb28eap_state_notification_eap_e20eap_protocol_layer_e19eap_expanded_type_cmmhb @ 1183 NONAME + _ZN24eap_state_notification_cC1EP18abs_eap_am_tools_cPK19eap_am_network_id_cb28eap_state_notification_eap_e20eap_protocol_layer_e22eap_type_ietf_values_emmhb @ 1184 NONAME + _ZN24eap_state_notification_cC1EP18abs_eap_am_tools_cPK19eap_am_network_id_cb32eap_state_notification_generic_e20eap_protocol_layer_emmmhb @ 1185 NONAME + _ZN24eap_state_notification_cC2EP18abs_eap_am_tools_cPK19eap_am_network_id_cb28eap_state_notification_eap_e20eap_protocol_layer_e19eap_expanded_type_cmmhb @ 1186 NONAME + _ZN24eap_state_notification_cC2EP18abs_eap_am_tools_cPK19eap_am_network_id_cb28eap_state_notification_eap_e20eap_protocol_layer_e22eap_type_ietf_values_emmhb @ 1187 NONAME + _ZN24eap_state_notification_cC2EP18abs_eap_am_tools_cPK19eap_am_network_id_cb32eap_state_notification_generic_e20eap_protocol_layer_emmmhb @ 1188 NONAME + _ZN24eap_state_notification_cD0Ev @ 1189 NONAME + _ZN24eap_state_notification_cD1Ev @ 1190 NONAME + _ZN24eap_state_notification_cD2Ev @ 1191 NONAME + _ZN24eapol_key_state_string_cC1Ev @ 1192 NONAME + _ZN24eapol_key_state_string_cC2Ev @ 1193 NONAME + _ZN24eapol_key_state_string_cD0Ev @ 1194 NONAME + _ZN24eapol_key_state_string_cD1Ev @ 1195 NONAME + _ZN24eapol_key_state_string_cD2Ev @ 1196 NONAME + _ZN25eap_core_retransmission_c19get_send_network_idEv @ 1197 NONAME + _ZN25eap_core_retransmission_c28get_next_retransmission_timeEv @ 1198 NONAME + _ZN25eap_core_retransmission_c31get_next_retransmission_counterEv @ 1199 NONAME + _ZN25eap_core_retransmission_cC1EP18abs_eap_am_tools_cPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmmm16eap_code_value_eh19eap_expanded_type_c @ 1200 NONAME + _ZN25eap_core_retransmission_cC2EP18abs_eap_am_tools_cPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmmm16eap_code_value_eh19eap_expanded_type_c @ 1201 NONAME + _ZN25eap_core_retransmission_cD0Ev @ 1202 NONAME + _ZN25eap_core_retransmission_cD1Ev @ 1203 NONAME + _ZN25eap_core_retransmission_cD2Ev @ 1204 NONAME + _ZN25eap_general_header_base_c17set_header_bufferEPhm @ 1205 NONAME + _ZN25eap_general_header_base_cC2EP18abs_eap_am_tools_cPvm @ 1206 NONAME + _ZN25eap_general_header_base_cD0Ev @ 1207 NONAME + _ZN25eap_general_header_base_cD1Ev @ 1208 NONAME + _ZN25eap_general_header_base_cD2Ev @ 1209 NONAME + _ZN25eap_network_id_selector_c12set_selectorEPK19eap_am_network_id_c @ 1210 NONAME + _ZN25eap_network_id_selector_cC1EP18abs_eap_am_tools_c @ 1211 NONAME + _ZN25eap_network_id_selector_cC1EP18abs_eap_am_tools_cPK19eap_am_network_id_c @ 1212 NONAME + _ZN25eap_network_id_selector_cC1EP18abs_eap_am_tools_cPKS_ @ 1213 NONAME + _ZN25eap_network_id_selector_cC2EP18abs_eap_am_tools_c @ 1214 NONAME + _ZN25eap_network_id_selector_cC2EP18abs_eap_am_tools_cPK19eap_am_network_id_c @ 1215 NONAME + _ZN25eap_network_id_selector_cC2EP18abs_eap_am_tools_cPKS_ @ 1216 NONAME + _ZN25eap_network_id_selector_cD0Ev @ 1217 NONAME + _ZN25eap_network_id_selector_cD1Ev @ 1218 NONAME + _ZN25eap_network_id_selector_cD2Ev @ 1219 NONAME + _ZN26eapol_ethernet_header_rd_cC1EP18abs_eap_am_tools_cPKhm @ 1220 NONAME + _ZN26eapol_ethernet_header_rd_cC2EP18abs_eap_am_tools_cPKhm @ 1221 NONAME + _ZN26eapol_ethernet_header_rd_cD0Ev @ 1222 NONAME + _ZN26eapol_ethernet_header_rd_cD1Ev @ 1223 NONAME + _ZN26eapol_ethernet_header_rd_cD2Ev @ 1224 NONAME + _ZN26eapol_ethernet_header_wr_c10get_sourceEv @ 1225 NONAME + _ZN26eapol_ethernet_header_wr_c12reset_headerE21eapol_ethernet_type_et @ 1226 NONAME + _ZN26eapol_ethernet_header_wr_c15get_destinationEv @ 1227 NONAME + _ZN26eapol_ethernet_header_wr_cC1EP18abs_eap_am_tools_cPKhm @ 1228 NONAME + _ZN26eapol_ethernet_header_wr_cC2EP18abs_eap_am_tools_cPKhm @ 1229 NONAME + _ZN26eapol_ethernet_header_wr_cD0Ev @ 1230 NONAME + _ZN26eapol_ethernet_header_wr_cD1Ev @ 1231 NONAME + _ZN26eapol_ethernet_header_wr_cD2Ev @ 1232 NONAME + _ZN26eapol_rsna_variable_data_c10set_bufferEPK28eapol_rsna_key_data_header_cPhmbb @ 1233 NONAME + _ZN26eapol_rsna_variable_data_cC1EP18abs_eap_am_tools_cbb @ 1234 NONAME + _ZN26eapol_rsna_variable_data_cC2EP18abs_eap_am_tools_cbb @ 1235 NONAME + _ZN26eapol_rsna_variable_data_cD0Ev @ 1236 NONAME + _ZN26eapol_rsna_variable_data_cD1Ev @ 1237 NONAME + _ZN26eapol_rsna_variable_data_cD2Ev @ 1238 NONAME + _ZN26simple_config_credential_c12get_is_validEv @ 1239 NONAME + _ZN26simple_config_credential_c15get_MAC_addressEv @ 1240 NONAME + _ZN26simple_config_credential_c16get_network_keysEv @ 1241 NONAME + _ZN26simple_config_credential_c17get_network_indexEv @ 1242 NONAME + _ZN26simple_config_credential_c17set_network_indexEh @ 1243 NONAME + _ZN26simple_config_credential_c19get_Encryption_TypeEv @ 1244 NONAME + _ZN26simple_config_credential_c19set_Encryption_TypeE31simple_config_Encryption_Type_e @ 1245 NONAME + _ZN26simple_config_credential_c23get_Authentication_TypeEv @ 1246 NONAME + _ZN26simple_config_credential_c23set_Authentication_TypeE35simple_config_Authentication_Type_e @ 1247 NONAME + _ZN26simple_config_credential_c8get_SSIDEv @ 1248 NONAME + _ZN26simple_config_credential_cC1EP18abs_eap_am_tools_c @ 1249 NONAME + _ZN26simple_config_credential_cC2EP18abs_eap_am_tools_c @ 1250 NONAME + _ZN26simple_config_credential_cD0Ev @ 1251 NONAME + _ZN26simple_config_credential_cD1Ev @ 1252 NONAME + _ZN26simple_config_credential_cD2Ev @ 1253 NONAME + _ZN27abs_crypto_hash_algorithm_cD0Ev @ 1254 NONAME + _ZN27abs_crypto_hash_algorithm_cD1Ev @ 1255 NONAME + _ZN27abs_crypto_hash_algorithm_cD2Ev @ 1256 NONAME + _ZN27abs_crypto_hmac_algorithm_cD0Ev @ 1257 NONAME + _ZN27abs_crypto_hmac_algorithm_cD1Ev @ 1258 NONAME + _ZN27abs_crypto_hmac_algorithm_cD2Ev @ 1259 NONAME + _ZN27eap_am_file_input_symbian_c10file_closeEv @ 1260 NONAME + _ZN27eap_am_file_input_symbian_c10file_writeEPK19eap_variable_data_c @ 1261 NONAME + _ZN27eap_am_file_input_symbian_c11file_deleteEPK19eap_variable_data_c @ 1262 NONAME + _ZN27eap_am_file_input_symbian_c11file_existsEPK19eap_variable_data_c @ 1263 NONAME + _ZN27eap_am_file_input_symbian_c14file_read_lineEP19eap_variable_data_c @ 1264 NONAME + _ZN27eap_am_file_input_symbian_c9file_copyEPK19eap_variable_data_cS2_ @ 1265 NONAME + _ZN27eap_am_file_input_symbian_c9file_openEPK19eap_variable_data_c23eap_file_io_direction_e @ 1266 NONAME + _ZN27eap_am_file_input_symbian_c9file_readEP19eap_variable_data_c @ 1267 NONAME + _ZN27eap_am_file_input_symbian_c9file_sizeEv @ 1268 NONAME + _ZN27eap_am_file_input_symbian_cC1EP18abs_eap_am_tools_c @ 1269 NONAME + _ZN27eap_am_file_input_symbian_cC2EP18abs_eap_am_tools_c @ 1270 NONAME + _ZN27eap_am_file_input_symbian_cD0Ev @ 1271 NONAME + _ZN27eap_am_file_input_symbian_cD1Ev @ 1272 NONAME + _ZN27eap_am_file_input_symbian_cD2Ev @ 1273 NONAME + _ZN27eapol_wlan_authentication_c11load_moduleE19eap_expanded_type_cS0_P19abs_eap_base_type_cPP15eap_base_type_cbPK19eap_am_network_id_c @ 1274 NONAME + _ZN27eapol_wlan_authentication_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 1275 NONAME + _ZN27eapol_wlan_authentication_c12add_rogue_apER11eap_array_cI20eap_rogue_ap_entry_cE @ 1276 NONAME + _ZN27eapol_wlan_authentication_c12cancel_timerEP20abs_eap_base_timer_cm @ 1277 NONAME + _ZN27eapol_wlan_authentication_c12get_is_validEv @ 1278 NONAME + _ZN27eapol_wlan_authentication_c12set_is_validEv @ 1279 NONAME + _ZN27eapol_wlan_authentication_c13get_is_clientEv @ 1280 NONAME + _ZN27eapol_wlan_authentication_c13timer_expiredEmPv @ 1281 NONAME + _ZN27eapol_wlan_authentication_c13unload_moduleE19eap_expanded_type_c @ 1282 NONAME + _ZN27eapol_wlan_authentication_c14disassociationEPK19eap_am_network_id_c @ 1283 NONAME + _ZN27eapol_wlan_authentication_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 1284 NONAME + _ZN27eapol_wlan_authentication_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 1285 NONAME + _ZN27eapol_wlan_authentication_c15eap_acknowledgeEPK19eap_am_network_id_c @ 1286 NONAME + _ZN27eapol_wlan_authentication_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 1287 NONAME + _ZN27eapol_wlan_authentication_c16eapol_indicationEPK19eap_am_network_id_c33eapol_wlan_authentication_state_e @ 1288 NONAME + _ZN27eapol_wlan_authentication_c16tkip_mic_failureEPK19eap_am_network_id_cbN23eapol_RSNA_key_header_c29eapol_tkip_mic_failure_type_eE @ 1289 NONAME + _ZN27eapol_wlan_authentication_c17cancel_all_timersEv @ 1290 NONAME + _ZN27eapol_wlan_authentication_c17check_pmksa_cacheEP11eap_array_cI19eap_am_network_id_cE31eapol_key_authentication_type_eN23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES6_ @ 1291 NONAME + _ZN27eapol_wlan_authentication_c17get_eap_type_listEP11eap_array_cI19eap_expanded_type_cE @ 1292 NONAME + _ZN27eapol_wlan_authentication_c17get_header_offsetEPmS0_ @ 1293 NONAME + _ZN27eapol_wlan_authentication_c17timer_delete_dataEmPv @ 1294 NONAME + _ZN27eapol_wlan_authentication_c18create_upper_stackEv @ 1295 NONAME + _ZN27eapol_wlan_authentication_c18state_notificationEPK28abs_eap_state_notification_c @ 1296 NONAME + _ZN27eapol_wlan_authentication_c19start_reassociationEPK19eap_am_network_id_cS2_31eapol_key_authentication_type_e @ 1297 NONAME + _ZN27eapol_wlan_authentication_c20complete_associationE33eapol_wlan_authentication_state_ePK19eap_am_network_id_cPK19eap_variable_data_cS6_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES8_ @ 1298 NONAME + _ZN27eapol_wlan_authentication_c20start_authenticationEPK19eap_variable_data_c31eapol_key_authentication_type_eS2_bPK19eap_am_network_id_c @ 1299 NONAME + _ZN27eapol_wlan_authentication_c21get_current_eap_indexEv @ 1300 NONAME + _ZN27eapol_wlan_authentication_c21set_current_eap_indexEm @ 1301 NONAME + _ZN27eapol_wlan_authentication_c22complete_reassociationE33eapol_wlan_authentication_state_ePK19eap_am_network_id_cPK19eap_variable_data_cS6_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES8_ @ 1302 NONAME + _ZN27eapol_wlan_authentication_c23check_is_valid_eap_typeE19eap_expanded_type_c @ 1303 NONAME + _ZN27eapol_wlan_authentication_c23packet_data_session_keyEPK19eap_am_network_id_cPK19eapol_session_key_c @ 1304 NONAME + _ZN27eapol_wlan_authentication_c23start_preauthenticationEPK19eap_am_network_id_c @ 1305 NONAME + _ZN27eapol_wlan_authentication_c24start_WPXM_reassociationEPK19eap_am_network_id_cS2_P19eap_variable_data_cPKS3_S6_ @ 1306 NONAME + _ZN27eapol_wlan_authentication_c26get_authentication_counterEv @ 1307 NONAME + _ZN27eapol_wlan_authentication_c26save_simple_config_sessionE21simple_config_state_ePK11eap_array_cI26simple_config_credential_cEPK19eap_variable_data_c34simple_config_Device_Password_ID_ePK24simple_config_payloads_c @ 1308 NONAME + _ZN27eapol_wlan_authentication_c27complete_WPXM_reassociationE33eapol_wlan_authentication_state_ePK19eap_am_network_id_cPK19eap_variable_data_c @ 1309 NONAME + _ZN27eapol_wlan_authentication_c29new_eapol_wlan_authenticationEP18abs_eap_am_tools_cP31abs_eapol_wlan_authentication_cbPK38abs_eapol_wlan_database_reference_if_c @ 1310 NONAME + _ZN27eapol_wlan_authentication_c32increment_authentication_counterEv @ 1311 NONAME + _ZN27eapol_wlan_authentication_c8shutdownEv @ 1312 NONAME + _ZN27eapol_wlan_authentication_c9configureEv @ 1313 NONAME + _ZN27eapol_wlan_authentication_c9set_timerEP20abs_eap_base_timer_cmPvm @ 1314 NONAME + _ZN27eapol_wlan_authentication_cC1EP18abs_eap_am_tools_cP31abs_eapol_wlan_authentication_cP30eapol_am_wlan_authentication_cb @ 1315 NONAME + _ZN27eapol_wlan_authentication_cC2EP18abs_eap_am_tools_cP31abs_eapol_wlan_authentication_cP30eapol_am_wlan_authentication_cb @ 1316 NONAME + _ZN27eapol_wlan_authentication_cD0Ev @ 1317 NONAME + _ZN27eapol_wlan_authentication_cD1Ev @ 1318 NONAME + _ZN27eapol_wlan_authentication_cD2Ev @ 1319 NONAME + _ZN28abs_crypto_block_algorithm_cD0Ev @ 1320 NONAME + _ZN28abs_crypto_block_algorithm_cD1Ev @ 1321 NONAME + _ZN28abs_crypto_block_algorithm_cD2Ev @ 1322 NONAME + _ZN28eapol_ethernet_header_base_c17get_header_lengthEv @ 1323 NONAME + _ZN28eapol_ethernet_header_base_c8set_typeE21eapol_ethernet_type_e @ 1324 NONAME + _ZN28eapol_ethernet_header_base_cC1EP18abs_eap_am_tools_cPvm @ 1325 NONAME + _ZN28eapol_ethernet_header_base_cC2EP18abs_eap_am_tools_cPvm @ 1326 NONAME + _ZN28eapol_ethernet_header_base_cD0Ev @ 1327 NONAME + _ZN28eapol_ethernet_header_base_cD1Ev @ 1328 NONAME + _ZN28eapol_ethernet_header_base_cD2Ev @ 1329 NONAME + _ZN29abs_crypto_stream_algorithm_cD0Ev @ 1330 NONAME + _ZN29abs_crypto_stream_algorithm_cD1Ev @ 1331 NONAME + _ZN29abs_crypto_stream_algorithm_cD2Ev @ 1332 NONAME + _ZN30abs_eap_am_memory_store_data_cC1Ev @ 1333 NONAME + _ZN30abs_eap_am_memory_store_data_cC2Ev @ 1334 NONAME + _ZN30abs_eap_am_memory_store_data_cD0Ev @ 1335 NONAME + _ZN30abs_eap_am_memory_store_data_cD1Ev @ 1336 NONAME + _ZN30abs_eap_am_memory_store_data_cD2Ev @ 1337 NONAME + _ZN30crypto_wpa_psk_password_hash_c12get_is_validEv @ 1338 NONAME + _ZN30crypto_wpa_psk_password_hash_c13password_hashEPK19eap_variable_data_cS2_PS0_PvPF12eap_status_eS4_mE @ 1339 NONAME + _ZN30crypto_wpa_psk_password_hash_cC1EP18abs_eap_am_tools_c @ 1340 NONAME + _ZN30crypto_wpa_psk_password_hash_cC2EP18abs_eap_am_tools_c @ 1341 NONAME + _ZN30crypto_wpa_psk_password_hash_cD0Ev @ 1342 NONAME + _ZN30crypto_wpa_psk_password_hash_cD1Ev @ 1343 NONAME + _ZN30crypto_wpa_psk_password_hash_cD2Ev @ 1344 NONAME + _ZN30eap_am_memory_store_tlv_data_c17copy_message_dataEPK22eap_tlv_message_data_cm @ 1345 NONAME + _ZN30eap_am_memory_store_tlv_data_c31object_decrease_reference_countEv @ 1346 NONAME + _ZN30eap_am_memory_store_tlv_data_c31object_increase_reference_countEv @ 1347 NONAME + _ZN30eap_am_memory_store_tlv_data_cC1EP18abs_eap_am_tools_c @ 1348 NONAME + _ZN30eap_am_memory_store_tlv_data_cC2EP18abs_eap_am_tools_c @ 1349 NONAME + _ZN30eap_am_memory_store_tlv_data_cD0Ev @ 1350 NONAME + _ZN30eap_am_memory_store_tlv_data_cD1Ev @ 1351 NONAME + _ZN30eap_am_memory_store_tlv_data_cD2Ev @ 1352 NONAME + _ZN30eapol_am_wlan_authentication_c32new_eapol_am_wlan_authenticationEP18abs_eap_am_tools_cbPK38abs_eapol_wlan_database_reference_if_c @ 1353 NONAME + _ZN30eapol_rsna_key_data_payloads_c14check_payloadsENS_36eapol_rsna_key_data_payload_status_eES0_S0_S0_ @ 1354 NONAME + _ZN30eapol_rsna_key_data_payloads_c17check_one_payloadENS_36eapol_rsna_key_data_payload_status_eEPK11eap_array_cI19eap_variable_data_cE @ 1355 NONAME + _ZN30eapol_rsna_key_data_payloads_c17check_one_payloadENS_36eapol_rsna_key_data_payload_status_eEPK26eapol_rsna_variable_data_c @ 1356 NONAME + _ZN30eapol_rsna_key_data_payloads_cC1EP18abs_eap_am_tools_cbb @ 1357 NONAME + _ZN30eapol_rsna_key_data_payloads_cC2EP18abs_eap_am_tools_cbb @ 1358 NONAME + _ZN30eapol_rsna_key_data_payloads_cD0Ev @ 1359 NONAME + _ZN30eapol_rsna_key_data_payloads_cD1Ev @ 1360 NONAME + _ZN30eapol_rsna_key_data_payloads_cD2Ev @ 1361 NONAME + _ZN31crypto_eap_fast_hmac_sha1_prf_c10t_prf_initEPK19eap_variable_data_cS2_S2_ @ 1362 NONAME + _ZN31crypto_eap_fast_hmac_sha1_prf_c12get_is_validEv @ 1363 NONAME + _ZN31crypto_eap_fast_hmac_sha1_prf_c12set_is_validEv @ 1364 NONAME + _ZN31crypto_eap_fast_hmac_sha1_prf_c12t_prf_outputEPvt @ 1365 NONAME + _ZN31crypto_eap_fast_hmac_sha1_prf_c13t_prf_cleanupEv @ 1366 NONAME + _ZN31crypto_eap_fast_hmac_sha1_prf_c14set_is_invalidEv @ 1367 NONAME + _ZN31crypto_eap_fast_hmac_sha1_prf_cC1EP18abs_eap_am_tools_c @ 1368 NONAME + _ZN31crypto_eap_fast_hmac_sha1_prf_cC2EP18abs_eap_am_tools_c @ 1369 NONAME + _ZN31crypto_eap_fast_hmac_sha1_prf_cD0Ev @ 1370 NONAME + _ZN31crypto_eap_fast_hmac_sha1_prf_cD1Ev @ 1371 NONAME + _ZN31crypto_eap_fast_hmac_sha1_prf_cD2Ev @ 1372 NONAME + _ZN31eapol_handle_tlv_message_data_c12get_is_validEv @ 1373 NONAME + _ZN31eapol_handle_tlv_message_data_c15get_type_stringE24eapol_tlv_message_type_e @ 1374 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataE12eap_status_e @ 1375 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataE19eap_expanded_type_c @ 1376 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataE24eapol_tlv_message_type_em @ 1377 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataE33eapol_tlv_message_type_function_e @ 1378 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEPK11eap_array_cI26simple_config_credential_cE @ 1379 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEPK18eap_buf_chain_wr_c @ 1380 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEPK19eap_am_network_id_c @ 1381 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEPK19eap_variable_data_c @ 1382 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEPK19eapol_session_key_c @ 1383 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEPK25eap_general_header_base_c @ 1384 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEPK28abs_eap_state_notification_c @ 1385 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEb @ 1386 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEh @ 1387 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEm @ 1388 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEt @ 1389 NONAME + _ZN31eapol_handle_tlv_message_data_c18add_parameter_dataEy @ 1390 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cP11eap_array_cI23network_key_and_index_cE @ 1391 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cP11eap_array_cI26simple_config_credential_cE @ 1392 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cP19eap_am_network_id_c @ 1393 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cP19eap_expanded_type_c @ 1394 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cP19eap_variable_data_c @ 1395 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cP19eapol_session_key_c @ 1396 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cP23network_key_and_index_c @ 1397 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cP26simple_config_credential_c @ 1398 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cP33eapol_tlv_message_type_function_e @ 1399 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cPP24eap_state_notification_c @ 1400 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cPh @ 1401 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cPm @ 1402 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cPt @ 1403 NONAME + _ZN31eapol_handle_tlv_message_data_c18get_parameter_dataEPK16eap_tlv_header_cPy @ 1404 NONAME + _ZN31eapol_handle_tlv_message_data_c19get_function_stringE33eapol_tlv_message_type_function_e @ 1405 NONAME + _ZN31eapol_handle_tlv_message_data_c31add_structured_parameter_headerE24eapol_tlv_message_type_em @ 1406 NONAME + _ZN31eapol_handle_tlv_message_data_c31object_decrease_reference_countEv @ 1407 NONAME + _ZN31eapol_handle_tlv_message_data_c31object_increase_reference_countEv @ 1408 NONAME + _ZN31eapol_handle_tlv_message_data_cC1EP18abs_eap_am_tools_c @ 1409 NONAME + _ZN31eapol_handle_tlv_message_data_cC2EP18abs_eap_am_tools_c @ 1410 NONAME + _ZN31eapol_handle_tlv_message_data_cD0Ev @ 1411 NONAME + _ZN31eapol_handle_tlv_message_data_cD1Ev @ 1412 NONAME + _ZN31eapol_handle_tlv_message_data_cD2Ev @ 1413 NONAME + _ZN32abs_crypto_cbc_block_algorithm_cD0Ev @ 1414 NONAME + _ZN32abs_crypto_cbc_block_algorithm_cD1Ev @ 1415 NONAME + _ZN32abs_crypto_cbc_block_algorithm_cD2Ev @ 1416 NONAME + _ZN32eap_simple_config_trace_string_cC1Ev @ 1417 NONAME + _ZN32eap_simple_config_trace_string_cC2Ev @ 1418 NONAME + _ZN32eap_simple_config_trace_string_cD0Ev @ 1419 NONAME + _ZN32eap_simple_config_trace_string_cD1Ev @ 1420 NONAME + _ZN32eap_simple_config_trace_string_cD2Ev @ 1421 NONAME + _ZN33crypto_ephemeral_diffie_hellman_c10dh_cleanupEPK19eap_variable_data_c @ 1422 NONAME + _ZN33crypto_ephemeral_diffie_hellman_c12get_is_validEv @ 1423 NONAME + _ZN33crypto_ephemeral_diffie_hellman_c12set_is_validEv @ 1424 NONAME + _ZN33crypto_ephemeral_diffie_hellman_c22generate_g_power_to_xyEPK19eap_variable_data_cS2_PS0_PKvmS5_m @ 1425 NONAME + _ZN33crypto_ephemeral_diffie_hellman_c28generate_diffie_hellman_keysEP19eap_variable_data_cS1_PKvmS3_m @ 1426 NONAME + _ZN33crypto_ephemeral_diffie_hellman_cC1EP18abs_eap_am_tools_c @ 1427 NONAME + _ZN33crypto_ephemeral_diffie_hellman_cC2EP18abs_eap_am_tools_c @ 1428 NONAME + _ZN33crypto_ephemeral_diffie_hellman_cD0Ev @ 1429 NONAME + _ZN33crypto_ephemeral_diffie_hellman_cD1Ev @ 1430 NONAME + _ZN33crypto_ephemeral_diffie_hellman_cD2Ev @ 1431 NONAME + _ZN35eapol_message_wlan_authentication_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 1432 NONAME + _ZN35eapol_message_wlan_authentication_c11reassociateEPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_c @ 1433 NONAME + _ZN35eapol_message_wlan_authentication_c12add_rogue_apER11eap_array_cI20eap_rogue_ap_entry_cE @ 1434 NONAME + _ZN35eapol_message_wlan_authentication_c12disassociateEPK19eap_am_network_id_cb @ 1435 NONAME + _ZN35eapol_message_wlan_authentication_c12get_is_validEv @ 1436 NONAME + _ZN35eapol_message_wlan_authentication_c12process_dataEPKvm @ 1437 NONAME + _ZN35eapol_message_wlan_authentication_c12send_messageEP31eapol_handle_tlv_message_data_c @ 1438 NONAME + _ZN35eapol_message_wlan_authentication_c13timer_expiredEmPv @ 1439 NONAME + _ZN35eapol_message_wlan_authentication_c14disassociationEPK11eap_array_cI16eap_tlv_header_cE @ 1440 NONAME + _ZN35eapol_message_wlan_authentication_c14packet_processEPK11eap_array_cI16eap_tlv_header_cE @ 1441 NONAME + _ZN35eapol_message_wlan_authentication_c15eap_acknowledgeEPK11eap_array_cI16eap_tlv_header_cE @ 1442 NONAME + _ZN35eapol_message_wlan_authentication_c15process_messageEP31eapol_handle_tlv_message_data_c @ 1443 NONAME + _ZN35eapol_message_wlan_authentication_c16tkip_mic_failureEPK11eap_array_cI16eap_tlv_header_cE @ 1444 NONAME + _ZN35eapol_message_wlan_authentication_c17check_pmksa_cacheEPK11eap_array_cI16eap_tlv_header_cE @ 1445 NONAME + _ZN35eapol_message_wlan_authentication_c17get_header_offsetEPmS0_ @ 1446 NONAME + _ZN35eapol_message_wlan_authentication_c17timer_delete_dataEmPv @ 1447 NONAME + _ZN35eapol_message_wlan_authentication_c18send_error_messageE12eap_status_e33eapol_tlv_message_type_function_e @ 1448 NONAME + _ZN35eapol_message_wlan_authentication_c18state_notificationEPK28abs_eap_state_notification_c @ 1449 NONAME + _ZN35eapol_message_wlan_authentication_c19start_reassociationEPK11eap_array_cI16eap_tlv_header_cE @ 1450 NONAME + _ZN35eapol_message_wlan_authentication_c20complete_associationEPK11eap_array_cI16eap_tlv_header_cE @ 1451 NONAME + _ZN35eapol_message_wlan_authentication_c20start_authenticationEPK11eap_array_cI16eap_tlv_header_cE @ 1452 NONAME + _ZN35eapol_message_wlan_authentication_c20update_header_offsetEPK11eap_array_cI16eap_tlv_header_cE @ 1453 NONAME + _ZN35eapol_message_wlan_authentication_c22complete_reassociationEPK11eap_array_cI16eap_tlv_header_cE @ 1454 NONAME + _ZN35eapol_message_wlan_authentication_c23packet_data_session_keyEPK19eap_am_network_id_cPK19eapol_session_key_c @ 1455 NONAME + _ZN35eapol_message_wlan_authentication_c23start_preauthenticationEPK11eap_array_cI16eap_tlv_header_cE @ 1456 NONAME + _ZN35eapol_message_wlan_authentication_c24start_WPXM_reassociationEPK11eap_array_cI16eap_tlv_header_cE @ 1457 NONAME + _ZN35eapol_message_wlan_authentication_c26process_message_type_errorEPK11eap_array_cI16eap_tlv_header_cE @ 1458 NONAME + _ZN35eapol_message_wlan_authentication_c26save_simple_config_sessionE21simple_config_state_ePK11eap_array_cI26simple_config_credential_cEPK19eap_variable_data_c34simple_config_Device_Password_ID_ePK24simple_config_payloads_c @ 1459 NONAME + _ZN35eapol_message_wlan_authentication_c27complete_WPXM_reassociationEPK11eap_array_cI16eap_tlv_header_cE @ 1460 NONAME + _ZN35eapol_message_wlan_authentication_c37update_wlan_database_reference_valuesEPK11eap_array_cI16eap_tlv_header_cE @ 1461 NONAME + _ZN35eapol_message_wlan_authentication_c8shutdownEv @ 1462 NONAME + _ZN35eapol_message_wlan_authentication_c9associateE38eapol_key_802_11_authentication_mode_e @ 1463 NONAME + _ZN35eapol_message_wlan_authentication_c9configureEmmm @ 1464 NONAME + _ZN35eapol_message_wlan_authentication_cC1EP18abs_eap_am_tools_cP39abs_eapol_message_wlan_authentication_c @ 1465 NONAME + _ZN35eapol_message_wlan_authentication_cC2EP18abs_eap_am_tools_cP39abs_eapol_message_wlan_authentication_c @ 1466 NONAME + _ZN35eapol_message_wlan_authentication_cD0Ev @ 1467 NONAME + _ZN35eapol_message_wlan_authentication_cD1Ev @ 1468 NONAME + _ZN35eapol_message_wlan_authentication_cD2Ev @ 1469 NONAME + _ZN36wlan_eap_if_send_status_conversion_c7convertE12eap_status_e @ 1470 NONAME + _ZN36wlan_eap_if_send_status_conversion_c7convertE25wlan_eap_if_send_status_e @ 1471 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c11associationEPK19eap_am_network_id_c @ 1472 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c11load_moduleE19eap_expanded_type_cS0_P19abs_eap_base_type_cPP15eap_base_type_cbPK19eap_am_network_id_c @ 1473 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c12cancel_timerEP20abs_eap_base_timer_cm @ 1474 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c12get_is_validEv @ 1475 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c13unload_moduleE19eap_expanded_type_c @ 1476 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c14disassociationEPK19eap_am_network_id_c @ 1477 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 1478 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c14set_am_partnerEP34abs_eapol_am_wlan_authentication_cP26abs_eap_configuration_if_c @ 1479 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 1480 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c17cancel_all_timersEv @ 1481 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c17get_eap_type_listEP11eap_array_cI19eap_expanded_type_cE @ 1482 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c19set_wlan_parametersEPK19eap_variable_data_cbS2_31eapol_key_authentication_type_e @ 1483 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c22get_selected_eap_typesEP11eap_array_cI20eap_type_selection_cE @ 1484 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c22get_wlan_configurationEP19eap_variable_data_c @ 1485 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c23authentication_finishedEb19eap_expanded_type_c31eapol_key_authentication_type_e @ 1486 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c23check_is_valid_eap_typeE19eap_expanded_type_c @ 1487 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c23reset_eap_configurationEv @ 1488 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c26save_simple_config_sessionE21simple_config_state_ePK11eap_array_cI26simple_config_credential_cEPK19eap_variable_data_c34simple_config_Device_Password_ID_ePK24simple_config_payloads_c @ 1489 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c8shutdownEv @ 1490 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c9configureEv @ 1491 NONAME + _ZN38eapol_am_wlan_authentication_symbian_c9set_timerEP20abs_eap_base_timer_cmPvm @ 1492 NONAME + _ZN38eapol_am_wlan_authentication_symbian_cC1EP18abs_eap_am_tools_cbPK38abs_eapol_wlan_database_reference_if_c @ 1493 NONAME + _ZN38eapol_am_wlan_authentication_symbian_cC2EP18abs_eap_am_tools_cbPK38abs_eapol_wlan_database_reference_if_c @ 1494 NONAME + _ZN38eapol_am_wlan_authentication_symbian_cD0Ev @ 1495 NONAME + _ZN38eapol_am_wlan_authentication_symbian_cD1Ev @ 1496 NONAME + _ZN38eapol_am_wlan_authentication_symbian_cD2Ev @ 1497 NONAME + _ZNK10eap_core_c19get_is_tunneled_eapEv @ 1498 NONAME + _ZNK14eap_am_tools_c14get_trace_maskEv @ 1499 NONAME + _ZNK15eap_header_wr_c13get_type_dataEm @ 1500 NONAME + _ZNK15eap_header_wr_c20get_type_data_offsetEmm @ 1501 NONAME + _ZNK16eap_tlv_header_c12check_headerEv @ 1502 NONAME + _ZNK16eap_tlv_header_c16get_value_lengthEv @ 1503 NONAME + _ZNK16eap_tlv_header_c16get_value_offsetEmm @ 1504 NONAME + _ZNK16eap_tlv_header_c8get_typeEv @ 1505 NONAME + _ZNK16eap_tlv_header_c9get_valueEm @ 1506 NONAME + _ZNK17eap_header_base_c10get_lengthEv @ 1507 NONAME + _ZNK17eap_header_base_c12check_headerEv @ 1508 NONAME + _ZNK17eap_header_base_c13get_ietf_typeEv @ 1509 NONAME + _ZNK17eap_header_base_c13get_type_dataEm @ 1510 NONAME + _ZNK17eap_header_base_c14get_identifierEv @ 1511 NONAME + _ZNK17eap_header_base_c15get_code_stringEv @ 1512 NONAME + _ZNK17eap_header_base_c15get_data_lengthEv @ 1513 NONAME + _ZNK17eap_header_base_c15get_data_offsetEmm @ 1514 NONAME + _ZNK17eap_header_base_c15get_type_stringEv @ 1515 NONAME + _ZNK17eap_header_base_c20get_type_data_lengthEv @ 1516 NONAME + _ZNK17eap_header_base_c20get_type_data_offsetEmm @ 1517 NONAME + _ZNK17eap_header_base_c21get_type_field_lengthEv @ 1518 NONAME + _ZNK17eap_header_base_c8get_codeEv @ 1519 NONAME + _ZNK17eap_header_base_c8get_dataEm @ 1520 NONAME + _ZNK17eap_header_base_c8get_typeEv @ 1521 NONAME + _ZNK17eapol_header_rd_c14get_eap_headerEv @ 1522 NONAME + _ZNK17eapol_key_state_c19get_eapol_key_stateEv @ 1523 NONAME + _ZNK18eap_buf_chain_rd_c15get_data_offsetEmm @ 1524 NONAME + _ZNK18eap_buf_chain_rd_c19get_ethernet_headerEv @ 1525 NONAME + _ZNK18eap_buf_chain_rd_c8get_dataEm @ 1526 NONAME + _ZNK19eap_am_mutex_base_c12get_is_validEv @ 1527 NONAME + _ZNK19eap_am_mutex_base_c13get_referenceEv @ 1528 NONAME + _ZNK19eap_am_mutex_base_c15get_is_reservedEv @ 1529 NONAME + _ZNK19eap_am_network_id_c10get_sourceEv @ 1530 NONAME + _ZNK19eap_am_network_id_c12get_is_validEv @ 1531 NONAME + _ZNK19eap_am_network_id_c13get_source_idEv @ 1532 NONAME + _ZNK19eap_am_network_id_c14get_network_idEv @ 1533 NONAME + _ZNK19eap_am_network_id_c15get_destinationEv @ 1534 NONAME + _ZNK19eap_am_network_id_c17get_is_valid_dataEv @ 1535 NONAME + _ZNK19eap_am_network_id_c17get_source_lengthEv @ 1536 NONAME + _ZNK19eap_am_network_id_c18compare_network_idEPKS_ @ 1537 NONAME + _ZNK19eap_am_network_id_c18get_destination_idEv @ 1538 NONAME + _ZNK19eap_am_network_id_c22get_destination_lengthEv @ 1539 NONAME + _ZNK19eap_am_network_id_c4copyEv @ 1540 NONAME + _ZNK19eap_am_network_id_c8get_typeEv @ 1541 NONAME + _ZNK19eap_core_nak_info_c18get_eap_identifierEv @ 1542 NONAME + _ZNK19eap_core_nak_info_c21get_proposed_eap_typeEv @ 1543 NONAME + _ZNK19eap_expanded_type_c13get_vendor_idEv @ 1544 NONAME + _ZNK19eap_expanded_type_c15get_vendor_typeEv @ 1545 NONAME + _ZNK19eap_expanded_type_c7compareEPKS_ @ 1546 NONAME + _ZNK19eap_expanded_type_cadEv @ 1547 NONAME + _ZNK19eap_expanded_type_ceqE22eap_type_ietf_values_e @ 1548 NONAME + _ZNK19eap_expanded_type_ceqERKS_ @ 1549 NONAME + _ZNK19eap_expanded_type_cneE22eap_type_ietf_values_e @ 1550 NONAME + _ZNK19eap_expanded_type_cneERKS_ @ 1551 NONAME + _ZNK19eap_variable_data_c10get_bufferEm @ 1552 NONAME + _ZNK19eap_variable_data_c12get_is_validEv @ 1553 NONAME + _ZNK19eap_variable_data_c14compare_lengthEPKS_m @ 1554 NONAME + _ZNK19eap_variable_data_c14compare_lengthEPKvmm @ 1555 NONAME + _ZNK19eap_variable_data_c15get_data_lengthEv @ 1556 NONAME + _ZNK19eap_variable_data_c15get_data_offsetEmm @ 1557 NONAME + _ZNK19eap_variable_data_c15get_is_writableEv @ 1558 NONAME + _ZNK19eap_variable_data_c17get_buffer_lengthEv @ 1559 NONAME + _ZNK19eap_variable_data_c17get_buffer_offsetEmm @ 1560 NONAME + _ZNK19eap_variable_data_c17get_is_valid_dataEv @ 1561 NONAME + _ZNK19eap_variable_data_c4copyEv @ 1562 NONAME + _ZNK19eap_variable_data_c4hashEm @ 1563 NONAME + _ZNK19eap_variable_data_c7compareEPKS_ @ 1564 NONAME + _ZNK19eap_variable_data_c7compareEPKvm @ 1565 NONAME + _ZNK19eap_variable_data_c8get_dataEm @ 1566 NONAME + _ZNK19eap_variable_data_c8get_dataEv @ 1567 NONAME + _ZNK19eapol_header_base_c11get_versionEv @ 1568 NONAME + _ZNK19eapol_header_base_c12check_headerEv @ 1569 NONAME + _ZNK19eapol_header_base_c15get_data_lengthEv @ 1570 NONAME + _ZNK19eapol_header_base_c15get_packet_typeEv @ 1571 NONAME + _ZNK19eapol_header_base_c15get_type_stringEv @ 1572 NONAME + _ZNK19eapol_header_base_c8get_dataEm @ 1573 NONAME + _ZNK19eapol_session_key_c12get_is_validEv @ 1574 NONAME + _ZNK19eapol_session_key_c12get_key_typeEv @ 1575 NONAME + _ZNK19eapol_session_key_c13get_key_indexEv @ 1576 NONAME + _ZNK19eapol_session_key_c14get_key_tx_bitEv @ 1577 NONAME + _ZNK19eapol_session_key_c19get_sequence_numberEv @ 1578 NONAME + _ZNK19eapol_session_key_c7get_keyEv @ 1579 NONAME + _ZNK20eap_buf_chain_base_c11get_encryptEv @ 1580 NONAME + _ZNK20eap_buf_chain_base_c12check_guardsEv @ 1581 NONAME + _ZNK20eap_buf_chain_base_c12get_is_validEv @ 1582 NONAME + _ZNK20eap_buf_chain_base_c13get_is_clientEv @ 1583 NONAME + _ZNK20eap_buf_chain_base_c15get_data_lengthEv @ 1584 NONAME + _ZNK20eap_buf_chain_base_c15get_data_offsetEmm @ 1585 NONAME + _ZNK20eap_buf_chain_base_c17check_guard_bytesEPKh @ 1586 NONAME + _ZNK20eap_buf_chain_base_c17get_buffer_lengthEv @ 1587 NONAME + _ZNK20eap_buf_chain_base_c17get_is_valid_dataEv @ 1588 NONAME + _ZNK20eap_buf_chain_base_c17get_stack_addressEv @ 1589 NONAME + _ZNK20eap_buf_chain_base_c20get_do_length_checksEv @ 1590 NONAME + _ZNK20eap_buf_chain_base_c8get_dataEm @ 1591 NONAME + _ZNK20eap_rogue_ap_entry_c15get_mac_addressEPh @ 1592 NONAME + _ZNK20eap_rogue_ap_entry_c15get_mac_addressEv @ 1593 NONAME + _ZNK20eap_rogue_ap_entry_c16get_rogue_reasonEv @ 1594 NONAME + _ZNK20eap_rogue_ap_entry_c4copyEv @ 1595 NONAME + _ZNK20eap_type_selection_c12get_is_validEv @ 1596 NONAME + _ZNK20eap_type_selection_c14get_is_enabledEv @ 1597 NONAME + _ZNK20eap_type_selection_c17get_is_valid_dataEv @ 1598 NONAME + _ZNK20eap_type_selection_c4copyEv @ 1599 NONAME + _ZNK20eap_type_selection_c8get_typeEv @ 1600 NONAME + _ZNK22eap_am_mutex_symbian_c12get_is_validEv @ 1601 NONAME + _ZNK22eap_am_mutex_symbian_c15get_is_reservedEv @ 1602 NONAME + _ZNK22eap_am_mutex_symbian_c16get_owner_threadEv @ 1603 NONAME + _ZNK22eap_am_mutex_symbian_c9get_mutexEv @ 1604 NONAME + _ZNK22eap_am_tools_symbian_c12get_is_validEv @ 1605 NONAME + _ZNK22eap_tlv_message_data_c16get_message_dataEv @ 1606 NONAME + _ZNK22eap_tlv_message_data_c23get_message_data_lengthEv @ 1607 NONAME + _ZNK22eapol_RC4_key_header_c12check_headerEv @ 1608 NONAME + _ZNK22eapol_RC4_key_header_c12get_key_flagEv @ 1609 NONAME + _ZNK22eapol_RC4_key_header_c13get_key_indexEv @ 1610 NONAME + _ZNK22eapol_RC4_key_header_c14get_key_lengthEv @ 1611 NONAME + _ZNK22eapol_RC4_key_header_c17get_key_signatureEv @ 1612 NONAME + _ZNK22eapol_RC4_key_header_c21get_eapol_packet_typeEv @ 1613 NONAME + _ZNK22eapol_RC4_key_header_c23get_key_descriptor_typeEv @ 1614 NONAME + _ZNK22eapol_RC4_key_header_c26get_eapol_protocol_versionEv @ 1615 NONAME + _ZNK22eapol_RC4_key_header_c28get_eapol_packet_body_lengthEv @ 1616 NONAME + _ZNK22eapol_RC4_key_header_c7get_keyEv @ 1617 NONAME + _ZNK23eap_am_crypto_symbian_c12get_is_validEv @ 1618 NONAME + _ZNK23eapol_RSNA_key_header_c11get_key_MICEv @ 1619 NONAME + _ZNK23eapol_RSNA_key_header_c11get_key_RSCEv @ 1620 NONAME + _ZNK23eapol_RSNA_key_header_c12check_headerEv @ 1621 NONAME + _ZNK23eapol_RSNA_key_header_c12get_key_dataEm @ 1622 NONAME + _ZNK23eapol_RSNA_key_header_c13get_key_NONCEEv @ 1623 NONAME + _ZNK23eapol_RSNA_key_header_c14get_key_lengthEv @ 1624 NONAME + _ZNK23eapol_RSNA_key_header_c16get_EAPOL_key_IVEv @ 1625 NONAME + _ZNK23eapol_RSNA_key_header_c16get_key_reservedEv @ 1626 NONAME + _ZNK23eapol_RSNA_key_header_c19get_key_data_lengthEv @ 1627 NONAME + _ZNK23eapol_RSNA_key_header_c19get_key_data_offsetEmm @ 1628 NONAME + _ZNK23eapol_RSNA_key_header_c19get_key_informationEv @ 1629 NONAME + _ZNK23eapol_RSNA_key_header_c21get_eapol_packet_typeEv @ 1630 NONAME + _ZNK23eapol_RSNA_key_header_c22get_key_replay_counterEv @ 1631 NONAME + _ZNK23eapol_RSNA_key_header_c23get_eapol_packet_lengthEv @ 1632 NONAME + _ZNK23eapol_RSNA_key_header_c23get_key_STA_MAC_addressEv @ 1633 NONAME + _ZNK23eapol_RSNA_key_header_c23get_key_descriptor_typeEv @ 1634 NONAME + _ZNK23eapol_RSNA_key_header_c25get_key_information_errorEv @ 1635 NONAME + _ZNK23eapol_RSNA_key_header_c26get_eapol_protocol_versionEv @ 1636 NONAME + _ZNK23eapol_RSNA_key_header_c26get_key_information_secureEv @ 1637 NONAME + _ZNK23eapol_RSNA_key_header_c27get_key_information_installEv @ 1638 NONAME + _ZNK23eapol_RSNA_key_header_c27get_key_information_key_MICEv @ 1639 NONAME + _ZNK23eapol_RSNA_key_header_c27get_key_information_key_ackEv @ 1640 NONAME + _ZNK23eapol_RSNA_key_header_c27get_key_information_requestEv @ 1641 NONAME + _ZNK23eapol_RSNA_key_header_c28get_eapol_packet_body_lengthEv @ 1642 NONAME + _ZNK23eapol_RSNA_key_header_c28get_key_information_key_typeEv @ 1643 NONAME + _ZNK23eapol_RSNA_key_header_c29get_key_information_key_indexEv @ 1644 NONAME + _ZNK23eapol_RSNA_key_header_c30get_key_information_reserved_aEv @ 1645 NONAME + _ZNK23eapol_RSNA_key_header_c30get_key_information_reserved_bEv @ 1646 NONAME + _ZNK23eapol_RSNA_key_header_c38get_key_information_encrypted_key_dataEv @ 1647 NONAME + _ZNK23eapol_RSNA_key_header_c42get_key_information_key_descriptor_versionEv @ 1648 NONAME + _ZNK24eap_master_session_key_c12get_eap_typeEv @ 1649 NONAME + _ZNK24eap_master_session_key_c17get_leap_passwordEv @ 1650 NONAME + _ZNK24eap_state_notification_c12get_eap_typeEv @ 1651 NONAME + _ZNK24eap_state_notification_c12get_protocolEv @ 1652 NONAME + _ZNK24eap_state_notification_c13get_is_clientEv @ 1653 NONAME + _ZNK24eap_state_notification_c17get_current_stateEv @ 1654 NONAME + _ZNK24eap_state_notification_c18get_eap_identifierEv @ 1655 NONAME + _ZNK24eap_state_notification_c18get_previous_stateEv @ 1656 NONAME + _ZNK24eap_state_notification_c18get_protocol_layerEv @ 1657 NONAME + _ZNK24eap_state_notification_c19get_protocol_stringEv @ 1658 NONAME + _ZNK24eap_state_notification_c19get_send_network_idEv @ 1659 NONAME + _ZNK24eap_state_notification_c23get_notification_stringEv @ 1660 NONAME + _ZNK24eap_state_notification_c24get_authentication_errorEv @ 1661 NONAME + _ZNK24eap_state_notification_c24get_current_state_stringEv @ 1662 NONAME + _ZNK24eap_state_notification_c25get_previous_state_stringEv @ 1663 NONAME + _ZNK24eap_state_notification_c25get_protocol_layer_stringEv @ 1664 NONAME + _ZNK24eap_state_notification_c26get_allow_send_eap_successEv @ 1665 NONAME + _ZNK24eap_state_notification_c32get_needs_confirmation_from_userEv @ 1666 NONAME + _ZNK24eapol_key_state_string_c26get_eapol_key_state_stringE17eapol_key_state_e @ 1667 NONAME + _ZNK24eapol_key_state_string_c35get_eapol_key_handshake_type_stringE26eapol_key_handshake_type_e @ 1668 NONAME + _ZNK24eapol_key_state_string_c40get_eapol_key_authentication_type_stringE31eapol_key_authentication_type_e @ 1669 NONAME + _ZNK25eap_core_retransmission_c12get_eap_codeEv @ 1670 NONAME + _ZNK25eap_core_retransmission_c12get_eap_typeEv @ 1671 NONAME + _ZNK25eap_core_retransmission_c12get_is_validEv @ 1672 NONAME + _ZNK25eap_core_retransmission_c15get_buffer_sizeEv @ 1673 NONAME + _ZNK25eap_core_retransmission_c15get_data_lengthEv @ 1674 NONAME + _ZNK25eap_core_retransmission_c15get_sent_packetEv @ 1675 NONAME + _ZNK25eap_core_retransmission_c17get_header_offsetEv @ 1676 NONAME + _ZNK25eap_core_retransmission_c18get_eap_identifierEv @ 1677 NONAME + _ZNK25eap_core_retransmission_c26get_retransmission_counterEv @ 1678 NONAME + _ZNK25eap_general_header_base_c12get_am_toolsEv @ 1679 NONAME + _ZNK25eap_general_header_base_c12get_is_validEv @ 1680 NONAME + _ZNK25eap_general_header_base_c17get_header_bufferEm @ 1681 NONAME + _ZNK25eap_general_header_base_c17get_header_offsetEmm @ 1682 NONAME + _ZNK25eap_general_header_base_c24get_header_buffer_lengthEv @ 1683 NONAME + _ZNK25eap_network_id_selector_c4copyEv @ 1684 NONAME + _ZNK26eap_static_expanded_type_c8get_typeEv @ 1685 NONAME + _ZNK26eapol_ethernet_header_rd_c16get_eapol_headerEv @ 1686 NONAME + _ZNK26eapol_ethernet_header_wr_c16get_eapol_headerEv @ 1687 NONAME + _ZNK26eapol_rsna_variable_data_c19get_original_headerEv @ 1688 NONAME + _ZNK28eapol_ethernet_header_base_c10get_sourceEv @ 1689 NONAME + _ZNK28eapol_ethernet_header_base_c12check_headerEv @ 1690 NONAME + _ZNK28eapol_ethernet_header_base_c15get_data_lengthEv @ 1691 NONAME + _ZNK28eapol_ethernet_header_base_c15get_destinationEv @ 1692 NONAME + _ZNK28eapol_ethernet_header_base_c17get_source_lengthEv @ 1693 NONAME + _ZNK28eapol_ethernet_header_base_c22get_destination_lengthEv @ 1694 NONAME + _ZNK28eapol_ethernet_header_base_c8get_dataEm @ 1695 NONAME + _ZNK28eapol_ethernet_header_base_c8get_typeEv @ 1696 NONAME + _ZNK30eap_am_memory_store_tlv_data_c12get_timer_idEv @ 1697 NONAME + _ZNK30eap_am_memory_store_tlv_data_c16get_message_dataEv @ 1698 NONAME + _ZNK30eap_am_memory_store_tlv_data_c23get_message_data_lengthEv @ 1699 NONAME + _ZNK31eapol_handle_tlv_message_data_c16get_payload_sizeEP23network_key_and_index_c @ 1700 NONAME + _ZNK31eapol_handle_tlv_message_data_c16get_payload_sizeEP26simple_config_credential_c @ 1701 NONAME + _ZNK31eapol_handle_tlv_message_data_c16get_payload_sizeEPK11eap_array_cI23network_key_and_index_cE @ 1702 NONAME + _ZNK31eapol_handle_tlv_message_data_c16get_payload_sizeEPK11eap_array_cI26simple_config_credential_cE @ 1703 NONAME + _ZNK31eapol_handle_tlv_message_data_c16get_payload_sizeEPK19eap_am_network_id_c @ 1704 NONAME + _ZNK31eapol_handle_tlv_message_data_c16get_payload_sizeEPK19eapol_session_key_c @ 1705 NONAME + _ZNK31eapol_handle_tlv_message_data_c16get_payload_sizeEPK28abs_eap_state_notification_c @ 1706 NONAME + _ZNK32eap_simple_config_trace_string_c16get_state_stringE21simple_config_state_e @ 1707 NONAME + _ZNK32eap_simple_config_trace_string_c23get_message_type_stringE28simple_config_Message_Type_e @ 1708 NONAME + _ZNK32eap_simple_config_trace_string_c25get_attribute_type_stringE30simple_config_Attribute_Type_e @ 1709 NONAME + _ZNK35eapol_message_wlan_authentication_c34get_wlan_database_reference_valuesEP19eap_variable_data_c @ 1710 NONAME + _ZTI10eap_core_c @ 1711 NONAME + _ZTI12crypto_aes_c @ 1712 NONAME + _ZTI12crypto_cbc_c @ 1713 NONAME + _ZTI12crypto_dsa_c @ 1714 NONAME + _ZTI12crypto_md4_c @ 1715 NONAME + _ZTI12crypto_md5_c @ 1716 NONAME + _ZTI12crypto_rc4_c @ 1717 NONAME + _ZTI12crypto_rsa_c @ 1718 NONAME + _ZTI12eapol_core_c @ 1719 NONAME + _ZTI13crypto_hmac_c @ 1720 NONAME + _ZTI13crypto_sha1_c @ 1721 NONAME + _ZTI14eap_am_tools_c @ 1722 NONAME + _ZTI15crypto_random_c @ 1723 NONAME + _ZTI15eap_base_type_c @ 1724 NONAME + _ZTI15eap_header_rd_c @ 1725 NONAME + _ZTI15eap_header_wr_c @ 1726 NONAME + _ZTI15ethernet_core_c @ 1727 NONAME + _ZTI16crypto_nt_hash_c @ 1728 NONAME + _ZTI16crypto_sha_256_c @ 1729 NONAME + _ZTI16crypto_tls_prf_c @ 1730 NONAME + _ZTI16eap_tlv_header_c @ 1731 NONAME + _ZTI17crypto_3des_ede_c @ 1732 NONAME + _ZTI17crypto_aes_wrap_c @ 1733 NONAME + _ZTI17eap_file_config_c @ 1734 NONAME + _ZTI17eap_header_base_c @ 1735 NONAME + _ZTI17eap_timer_queue_c @ 1736 NONAME + _ZTI17eapol_header_rd_c @ 1737 NONAME + _ZTI17eapol_header_wr_c @ 1738 NONAME + _ZTI17eapol_key_state_c @ 1739 NONAME + _ZTI18abs_eap_am_mutex_c @ 1740 NONAME + _ZTI18eap_buf_chain_rd_c @ 1741 NONAME + _ZTI18eap_buf_chain_wr_c @ 1742 NONAME + _ZTI18eap_config_value_c @ 1743 NONAME + _ZTI18eap_session_core_c @ 1744 NONAME + _ZTI19eap_am_crypto_md4_c @ 1745 NONAME + _ZTI19eap_am_crypto_rc4_c @ 1746 NONAME + _ZTI19eap_am_mutex_base_c @ 1747 NONAME + _ZTI19eap_am_network_id_c @ 1748 NONAME + _ZTI19eap_core_nak_info_c @ 1749 NONAME + _ZTI19eap_header_string_c @ 1750 NONAME + _ZTI19eap_status_string_c @ 1751 NONAME + _ZTI19eap_variable_data_c @ 1752 NONAME + _ZTI19eapol_header_base_c @ 1753 NONAME + _ZTI19eapol_session_key_c @ 1754 NONAME + _ZTI20crypto_tls_md5_prf_c @ 1755 NONAME + _ZTI20eap_am_crypto_sha1_c @ 1756 NONAME + _ZTI20eap_buf_chain_base_c @ 1757 NONAME + _ZTI20eap_rogue_ap_entry_c @ 1758 NONAME + _ZTI20eap_type_selection_c @ 1759 NONAME + _ZTI21crypto_tls_base_prf_c @ 1760 NONAME + _ZTI21crypto_tls_sha1_prf_c @ 1761 NONAME + _ZTI21eap_am_memory_store_c @ 1762 NONAME + _ZTI21tls_peap_tlv_header_c @ 1763 NONAME + _ZTI22eap_am_mutex_symbian_c @ 1764 NONAME + _ZTI22eap_am_tools_symbian_c @ 1765 NONAME + _ZTI22eap_timer_queue_hash_c @ 1766 NONAME + _ZTI22eap_tlv_message_data_c @ 1767 NONAME + _ZTI22eapol_RC4_key_header_c @ 1768 NONAME + _ZTI23crypto_kd_hmac_sha256_c @ 1769 NONAME + _ZTI23eap_am_crypto_sha_256_c @ 1770 NONAME + _ZTI23eap_am_crypto_symbian_c @ 1771 NONAME + _ZTI23eap_timer_queue_event_c @ 1772 NONAME + _ZTI23eapol_RSNA_key_header_c @ 1773 NONAME + _ZTI23network_key_and_index_c @ 1774 NONAME + _ZTI24eap_am_mutex_reference_c @ 1775 NONAME + _ZTI24eap_master_session_key_c @ 1776 NONAME + _ZTI24eap_state_notification_c @ 1777 NONAME + _ZTI24eapol_key_state_string_c @ 1778 NONAME + _ZTI25eap_core_retransmission_c @ 1779 NONAME + _ZTI25eap_general_header_base_c @ 1780 NONAME + _ZTI25eap_network_id_selector_c @ 1781 NONAME + _ZTI26eapol_ethernet_header_rd_c @ 1782 NONAME + _ZTI26eapol_ethernet_header_wr_c @ 1783 NONAME + _ZTI26eapol_rsna_variable_data_c @ 1784 NONAME + _ZTI26simple_config_credential_c @ 1785 NONAME + _ZTI27abs_crypto_hash_algorithm_c @ 1786 NONAME + _ZTI27abs_crypto_hmac_algorithm_c @ 1787 NONAME + _ZTI27eap_am_file_input_symbian_c @ 1788 NONAME + _ZTI27eapol_wlan_authentication_c @ 1789 NONAME + _ZTI28abs_crypto_block_algorithm_c @ 1790 NONAME + _ZTI28eapol_ethernet_header_base_c @ 1791 NONAME + _ZTI28eapol_rsna_key_data_header_c @ 1792 NONAME + _ZTI29abs_crypto_stream_algorithm_c @ 1793 NONAME + _ZTI30abs_eap_am_memory_store_data_c @ 1794 NONAME + _ZTI30crypto_wpa_psk_password_hash_c @ 1795 NONAME + _ZTI30eap_am_memory_store_tlv_data_c @ 1796 NONAME + _ZTI30eapol_am_wlan_authentication_c @ 1797 NONAME + _ZTI30eapol_rsna_key_data_payloads_c @ 1798 NONAME + _ZTI31crypto_eap_fast_hmac_sha1_prf_c @ 1799 NONAME + _ZTI31eapol_handle_tlv_message_data_c @ 1800 NONAME + _ZTI32abs_crypto_cbc_block_algorithm_c @ 1801 NONAME + _ZTI32eap_simple_config_trace_string_c @ 1802 NONAME + _ZTI32eapol_rsna_key_data_gtk_header_c @ 1803 NONAME + _ZTI33crypto_ephemeral_diffie_hellman_c @ 1804 NONAME + _ZTI35eapol_message_wlan_authentication_c @ 1805 NONAME + _ZTI38eapol_am_wlan_authentication_symbian_c @ 1806 NONAME + _ZTV10eap_core_c @ 1807 NONAME + _ZTV12crypto_aes_c @ 1808 NONAME + _ZTV12crypto_cbc_c @ 1809 NONAME + _ZTV12crypto_dsa_c @ 1810 NONAME + _ZTV12crypto_md4_c @ 1811 NONAME + _ZTV12crypto_md5_c @ 1812 NONAME + _ZTV12crypto_rc4_c @ 1813 NONAME + _ZTV12crypto_rsa_c @ 1814 NONAME + _ZTV12eapol_core_c @ 1815 NONAME + _ZTV13crypto_hmac_c @ 1816 NONAME + _ZTV13crypto_sha1_c @ 1817 NONAME + _ZTV14eap_am_tools_c @ 1818 NONAME + _ZTV15crypto_random_c @ 1819 NONAME + _ZTV15eap_base_type_c @ 1820 NONAME + _ZTV15eap_header_rd_c @ 1821 NONAME + _ZTV15eap_header_wr_c @ 1822 NONAME + _ZTV15ethernet_core_c @ 1823 NONAME + _ZTV16crypto_nt_hash_c @ 1824 NONAME + _ZTV16crypto_sha_256_c @ 1825 NONAME + _ZTV16crypto_tls_prf_c @ 1826 NONAME + _ZTV16eap_tlv_header_c @ 1827 NONAME + _ZTV17crypto_3des_ede_c @ 1828 NONAME + _ZTV17crypto_aes_wrap_c @ 1829 NONAME + _ZTV17eap_file_config_c @ 1830 NONAME + _ZTV17eap_header_base_c @ 1831 NONAME + _ZTV17eap_timer_queue_c @ 1832 NONAME + _ZTV17eapol_header_rd_c @ 1833 NONAME + _ZTV17eapol_header_wr_c @ 1834 NONAME + _ZTV17eapol_key_state_c @ 1835 NONAME + _ZTV18abs_eap_am_mutex_c @ 1836 NONAME + _ZTV18eap_buf_chain_rd_c @ 1837 NONAME + _ZTV18eap_buf_chain_wr_c @ 1838 NONAME + _ZTV18eap_config_value_c @ 1839 NONAME + _ZTV18eap_session_core_c @ 1840 NONAME + _ZTV19eap_am_crypto_md4_c @ 1841 NONAME + _ZTV19eap_am_crypto_rc4_c @ 1842 NONAME + _ZTV19eap_am_mutex_base_c @ 1843 NONAME + _ZTV19eap_am_network_id_c @ 1844 NONAME + _ZTV19eap_core_nak_info_c @ 1845 NONAME + _ZTV19eap_header_string_c @ 1846 NONAME + _ZTV19eap_status_string_c @ 1847 NONAME + _ZTV19eap_variable_data_c @ 1848 NONAME + _ZTV19eapol_header_base_c @ 1849 NONAME + _ZTV19eapol_session_key_c @ 1850 NONAME + _ZTV20crypto_tls_md5_prf_c @ 1851 NONAME + _ZTV20eap_am_crypto_sha1_c @ 1852 NONAME + _ZTV20eap_buf_chain_base_c @ 1853 NONAME + _ZTV20eap_rogue_ap_entry_c @ 1854 NONAME + _ZTV20eap_type_selection_c @ 1855 NONAME + _ZTV21crypto_tls_base_prf_c @ 1856 NONAME + _ZTV21crypto_tls_sha1_prf_c @ 1857 NONAME + _ZTV21eap_am_memory_store_c @ 1858 NONAME + _ZTV21tls_peap_tlv_header_c @ 1859 NONAME + _ZTV22eap_am_mutex_symbian_c @ 1860 NONAME + _ZTV22eap_am_tools_symbian_c @ 1861 NONAME + _ZTV22eap_timer_queue_hash_c @ 1862 NONAME + _ZTV22eap_tlv_message_data_c @ 1863 NONAME + _ZTV22eapol_RC4_key_header_c @ 1864 NONAME + _ZTV23crypto_kd_hmac_sha256_c @ 1865 NONAME + _ZTV23eap_am_crypto_sha_256_c @ 1866 NONAME + _ZTV23eap_am_crypto_symbian_c @ 1867 NONAME + _ZTV23eap_timer_queue_event_c @ 1868 NONAME + _ZTV23eapol_RSNA_key_header_c @ 1869 NONAME + _ZTV23network_key_and_index_c @ 1870 NONAME + _ZTV24eap_am_mutex_reference_c @ 1871 NONAME + _ZTV24eap_master_session_key_c @ 1872 NONAME + _ZTV24eap_state_notification_c @ 1873 NONAME + _ZTV24eapol_key_state_string_c @ 1874 NONAME + _ZTV25eap_core_retransmission_c @ 1875 NONAME + _ZTV25eap_general_header_base_c @ 1876 NONAME + _ZTV25eap_network_id_selector_c @ 1877 NONAME + _ZTV26eapol_ethernet_header_rd_c @ 1878 NONAME + _ZTV26eapol_ethernet_header_wr_c @ 1879 NONAME + _ZTV26eapol_rsna_variable_data_c @ 1880 NONAME + _ZTV26simple_config_credential_c @ 1881 NONAME + _ZTV27abs_crypto_hash_algorithm_c @ 1882 NONAME + _ZTV27abs_crypto_hmac_algorithm_c @ 1883 NONAME + _ZTV27eap_am_file_input_symbian_c @ 1884 NONAME + _ZTV27eapol_wlan_authentication_c @ 1885 NONAME + _ZTV28abs_crypto_block_algorithm_c @ 1886 NONAME + _ZTV28eapol_ethernet_header_base_c @ 1887 NONAME + _ZTV28eapol_rsna_key_data_header_c @ 1888 NONAME + _ZTV29abs_crypto_stream_algorithm_c @ 1889 NONAME + _ZTV30abs_eap_am_memory_store_data_c @ 1890 NONAME + _ZTV30crypto_wpa_psk_password_hash_c @ 1891 NONAME + _ZTV30eap_am_memory_store_tlv_data_c @ 1892 NONAME + _ZTV30eapol_am_wlan_authentication_c @ 1893 NONAME + _ZTV30eapol_rsna_key_data_payloads_c @ 1894 NONAME + _ZTV31crypto_eap_fast_hmac_sha1_prf_c @ 1895 NONAME + _ZTV31eapol_handle_tlv_message_data_c @ 1896 NONAME + _ZTV32abs_crypto_cbc_block_algorithm_c @ 1897 NONAME + _ZTV32eap_simple_config_trace_string_c @ 1898 NONAME + _ZTV32eapol_rsna_key_data_gtk_header_c @ 1899 NONAME + _ZTV33crypto_ephemeral_diffie_hellman_c @ 1900 NONAME + _ZTV35eapol_message_wlan_authentication_c @ 1901 NONAME + _ZTV38eapol_am_wlan_authentication_symbian_c @ 1902 NONAME + _ZThn12_N10eap_core_c12get_is_validEv @ 1903 NONAME + _ZThn12_N10eap_core_c12set_is_validEv @ 1904 NONAME + _ZThn12_N10eap_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 1905 NONAME + _ZThn12_N10eap_core_c8shutdownEv @ 1906 NONAME + _ZThn12_N10eap_core_c9configureEv @ 1907 NONAME + _ZThn12_N10eap_core_cD0Ev @ 1908 NONAME + _ZThn12_N10eap_core_cD1Ev @ 1909 NONAME + _ZThn12_N12eapol_core_c12cancel_timerEP20abs_eap_base_timer_cm @ 1910 NONAME + _ZThn12_N12eapol_core_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 1911 NONAME + _ZThn12_N12eapol_core_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 1912 NONAME + _ZThn12_N12eapol_core_c17cancel_all_timersEv @ 1913 NONAME + _ZThn12_N12eapol_core_c18state_notificationEPK28abs_eap_state_notification_c @ 1914 NONAME + _ZThn12_N12eapol_core_c23packet_data_session_keyEPK19eap_am_network_id_cPK19eapol_session_key_c @ 1915 NONAME + _ZThn12_N12eapol_core_c36get_and_increment_global_key_counterEP19eap_variable_data_c @ 1916 NONAME + _ZThn12_N12eapol_core_c9set_timerEP20abs_eap_base_timer_cmPvm @ 1917 NONAME + _ZThn12_N12eapol_core_cD0Ev @ 1918 NONAME + _ZThn12_N12eapol_core_cD1Ev @ 1919 NONAME + _ZThn12_N18eap_session_core_c12get_is_validEv @ 1920 NONAME + _ZThn12_N18eap_session_core_c12set_is_validEv @ 1921 NONAME + _ZThn12_N18eap_session_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 1922 NONAME + _ZThn12_N18eap_session_core_c8shutdownEv @ 1923 NONAME + _ZThn12_N18eap_session_core_c9configureEv @ 1924 NONAME + _ZThn12_N18eap_session_core_cD0Ev @ 1925 NONAME + _ZThn12_N18eap_session_core_cD1Ev @ 1926 NONAME + _ZThn12_N27eapol_wlan_authentication_c26save_simple_config_sessionE21simple_config_state_ePK11eap_array_cI26simple_config_credential_cEPK19eap_variable_data_c34simple_config_Device_Password_ID_ePK24simple_config_payloads_c @ 1927 NONAME + _ZThn16_N12eapol_core_cD0Ev @ 1928 NONAME + _ZThn16_N12eapol_core_cD1Ev @ 1929 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c11associationEPK19eap_am_network_id_c @ 1930 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c11load_moduleE19eap_expanded_type_cS0_P19abs_eap_base_type_cPP15eap_base_type_cbPK19eap_am_network_id_c @ 1931 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c12cancel_timerEP20abs_eap_base_timer_cm @ 1932 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c12get_is_validEv @ 1933 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c13unload_moduleE19eap_expanded_type_c @ 1934 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c14disassociationEPK19eap_am_network_id_c @ 1935 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 1936 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c14set_am_partnerEP34abs_eapol_am_wlan_authentication_cP26abs_eap_configuration_if_c @ 1937 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 1938 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c17cancel_all_timersEv @ 1939 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c17get_eap_type_listEP11eap_array_cI19eap_expanded_type_cE @ 1940 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c19set_wlan_parametersEPK19eap_variable_data_cbS2_31eapol_key_authentication_type_e @ 1941 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c22get_selected_eap_typesEP11eap_array_cI20eap_type_selection_cE @ 1942 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c22get_wlan_configurationEP19eap_variable_data_c @ 1943 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c23authentication_finishedEb19eap_expanded_type_c31eapol_key_authentication_type_e @ 1944 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c23check_is_valid_eap_typeE19eap_expanded_type_c @ 1945 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c23reset_eap_configurationEv @ 1946 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c8shutdownEv @ 1947 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c9configureEv @ 1948 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_c9set_timerEP20abs_eap_base_timer_cmPvm @ 1949 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_cD0Ev @ 1950 NONAME + _ZThn28_N38eapol_am_wlan_authentication_symbian_cD1Ev @ 1951 NONAME + _ZThn32_N38eapol_am_wlan_authentication_symbian_c26save_simple_config_sessionE21simple_config_state_ePK11eap_array_cI26simple_config_credential_cEPK19eap_variable_data_c34simple_config_Device_Password_ID_ePK24simple_config_payloads_c @ 1952 NONAME + _ZThn4_N10eap_core_c11load_moduleE19eap_expanded_type_cS0_P19abs_eap_base_type_cPP15eap_base_type_cbPK19eap_am_network_id_c @ 1953 NONAME + _ZThn4_N10eap_core_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 1954 NONAME + _ZThn4_N10eap_core_c12add_rogue_apER11eap_array_cI20eap_rogue_ap_entry_cE @ 1955 NONAME + _ZThn4_N10eap_core_c12cancel_timerEP20abs_eap_base_timer_cm @ 1956 NONAME + _ZThn4_N10eap_core_c13unload_moduleE19eap_expanded_type_c @ 1957 NONAME + _ZThn4_N10eap_core_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 1958 NONAME + _ZThn4_N10eap_core_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 1959 NONAME + _ZThn4_N10eap_core_c17cancel_all_timersEv @ 1960 NONAME + _ZThn4_N10eap_core_c17get_eap_type_listEP11eap_array_cI19eap_expanded_type_cE @ 1961 NONAME + _ZThn4_N10eap_core_c17get_header_offsetEPmS0_ @ 1962 NONAME + _ZThn4_N10eap_core_c18state_notificationEPK28abs_eap_state_notification_c @ 1963 NONAME + _ZThn4_N10eap_core_c19set_session_timeoutEm @ 1964 NONAME + _ZThn4_N10eap_core_c22get_saved_eap_identityEP19eap_variable_data_c @ 1965 NONAME + _ZThn4_N10eap_core_c22restart_authenticationEPK19eap_am_network_id_cb @ 1966 NONAME + _ZThn4_N10eap_core_c23check_is_valid_eap_typeE19eap_expanded_type_c @ 1967 NONAME + _ZThn4_N10eap_core_c23packet_data_crypto_keysEPK19eap_am_network_id_cPK24eap_master_session_key_c @ 1968 NONAME + _ZThn4_N10eap_core_c23set_authentication_roleEb @ 1969 NONAME + _ZThn4_N10eap_core_c27complete_eap_identity_queryEPK19eap_am_network_id_cPK19eap_variable_data_ch @ 1970 NONAME + _ZThn4_N10eap_core_c9set_timerEP20abs_eap_base_timer_cmPvm @ 1971 NONAME + _ZThn4_N10eap_core_cD0Ev @ 1972 NONAME + _ZThn4_N10eap_core_cD1Ev @ 1973 NONAME + _ZThn4_N12eapol_core_c13timer_expiredEmPv @ 1974 NONAME + _ZThn4_N12eapol_core_c17timer_delete_dataEmPv @ 1975 NONAME + _ZThn4_N12eapol_core_cD0Ev @ 1976 NONAME + _ZThn4_N12eapol_core_cD1Ev @ 1977 NONAME + _ZThn4_N14eap_am_tools_cD0Ev @ 1978 NONAME + _ZThn4_N14eap_am_tools_cD1Ev @ 1979 NONAME + _ZThn4_N15ethernet_core_c12get_is_validEv @ 1980 NONAME + _ZThn4_N15ethernet_core_c12set_is_validEv @ 1981 NONAME + _ZThn4_N15ethernet_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 1982 NONAME + _ZThn4_N15ethernet_core_c8shutdownEv @ 1983 NONAME + _ZThn4_N15ethernet_core_c9configureEv @ 1984 NONAME + _ZThn4_N15ethernet_core_cD0Ev @ 1985 NONAME + _ZThn4_N15ethernet_core_cD1Ev @ 1986 NONAME + _ZThn4_N18eap_session_core_cD0Ev @ 1987 NONAME + _ZThn4_N18eap_session_core_cD1Ev @ 1988 NONAME + _ZThn4_N21eap_am_memory_store_c13timer_expiredEmPv @ 1989 NONAME + _ZThn4_N21eap_am_memory_store_c17timer_delete_dataEmPv @ 1990 NONAME + _ZThn4_N21eap_am_memory_store_cD0Ev @ 1991 NONAME + _ZThn4_N21eap_am_memory_store_cD1Ev @ 1992 NONAME + _ZThn4_N22eap_am_mutex_symbian_cD0Ev @ 1993 NONAME + _ZThn4_N22eap_am_mutex_symbian_cD1Ev @ 1994 NONAME + _ZThn4_N22eap_am_tools_symbian_cD0Ev @ 1995 NONAME + _ZThn4_N22eap_am_tools_symbian_cD1Ev @ 1996 NONAME + _ZThn4_N27eapol_wlan_authentication_c11load_moduleE19eap_expanded_type_cS0_P19abs_eap_base_type_cPP15eap_base_type_cbPK19eap_am_network_id_c @ 1997 NONAME + _ZThn4_N27eapol_wlan_authentication_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 1998 NONAME + _ZThn4_N27eapol_wlan_authentication_c12add_rogue_apER11eap_array_cI20eap_rogue_ap_entry_cE @ 1999 NONAME + _ZThn4_N27eapol_wlan_authentication_c12cancel_timerEP20abs_eap_base_timer_cm @ 2000 NONAME + _ZThn4_N27eapol_wlan_authentication_c13get_is_clientEv @ 2001 NONAME + _ZThn4_N27eapol_wlan_authentication_c13unload_moduleE19eap_expanded_type_c @ 2002 NONAME + _ZThn4_N27eapol_wlan_authentication_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 2003 NONAME + _ZThn4_N27eapol_wlan_authentication_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 2004 NONAME + _ZThn4_N27eapol_wlan_authentication_c17cancel_all_timersEv @ 2005 NONAME + _ZThn4_N27eapol_wlan_authentication_c17get_eap_type_listEP11eap_array_cI19eap_expanded_type_cE @ 2006 NONAME + _ZThn4_N27eapol_wlan_authentication_c17get_header_offsetEPmS0_ @ 2007 NONAME + _ZThn4_N27eapol_wlan_authentication_c18state_notificationEPK28abs_eap_state_notification_c @ 2008 NONAME + _ZThn4_N27eapol_wlan_authentication_c23check_is_valid_eap_typeE19eap_expanded_type_c @ 2009 NONAME + _ZThn4_N27eapol_wlan_authentication_c23packet_data_session_keyEPK19eap_am_network_id_cPK19eapol_session_key_c @ 2010 NONAME + _ZThn4_N27eapol_wlan_authentication_c9set_timerEP20abs_eap_base_timer_cmPvm @ 2011 NONAME + _ZThn4_N27eapol_wlan_authentication_cD1Ev @ 2012 NONAME + _ZThn4_N35eapol_message_wlan_authentication_c13timer_expiredEmPv @ 2013 NONAME + _ZThn4_N35eapol_message_wlan_authentication_c17timer_delete_dataEmPv @ 2014 NONAME + _ZThn4_N35eapol_message_wlan_authentication_cD0Ev @ 2015 NONAME + _ZThn4_N35eapol_message_wlan_authentication_cD1Ev @ 2016 NONAME + _ZThn4_NK10eap_core_c19get_is_tunneled_eapEv @ 2017 NONAME + _ZThn536_N22eap_am_tools_symbian_cD0Ev @ 2018 NONAME + _ZThn536_N22eap_am_tools_symbian_cD1Ev @ 2019 NONAME + _ZThn8_N10eap_core_c13timer_expiredEmPv @ 2020 NONAME + _ZThn8_N10eap_core_c17timer_delete_dataEmPv @ 2021 NONAME + _ZThn8_N10eap_core_cD0Ev @ 2022 NONAME + _ZThn8_N10eap_core_cD1Ev @ 2023 NONAME + _ZThn8_N12eapol_core_c12get_is_validEv @ 2024 NONAME + _ZThn8_N12eapol_core_c12set_is_validEv @ 2025 NONAME + _ZThn8_N12eapol_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 2026 NONAME + _ZThn8_N12eapol_core_c8shutdownEv @ 2027 NONAME + _ZThn8_N12eapol_core_c9configureEv @ 2028 NONAME + _ZThn8_N12eapol_core_cD0Ev @ 2029 NONAME + _ZThn8_N12eapol_core_cD1Ev @ 2030 NONAME + _ZThn8_N18eap_session_core_c13timer_expiredEmPv @ 2031 NONAME + _ZThn8_N18eap_session_core_c17timer_delete_dataEmPv @ 2032 NONAME + _ZThn8_N18eap_session_core_cD0Ev @ 2033 NONAME + _ZThn8_N18eap_session_core_cD1Ev @ 2034 NONAME + _ZThn8_N27eapol_wlan_authentication_c13timer_expiredEmPv @ 2035 NONAME + _ZThn8_N27eapol_wlan_authentication_c17timer_delete_dataEmPv @ 2036 NONAME + _ZThn8_N27eapol_wlan_authentication_cD1Ev @ 2037 NONAME + _ZThn8_N35eapol_message_wlan_authentication_cD0Ev @ 2038 NONAME + _ZThn8_N35eapol_message_wlan_authentication_cD1Ev @ 2039 NONAME + _ZThn8_NK35eapol_message_wlan_authentication_c34get_wlan_database_reference_valuesEP19eap_variable_data_c @ 2040 NONAME + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/eabi/eapakau.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/eabi/eapakau.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + _Z24ImplementationGroupProxyRi @ 1 NONAME + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/eabi/eapmschapv2u.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/eabi/eapmschapv2u.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + _Z24ImplementationGroupProxyRi @ 1 NONAME + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/eabi/eapprotectedsetupu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/eabi/eapprotectedsetupu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + _Z24ImplementationGroupProxyRi @ 1 NONAME + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/eabi/eapsecuridu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/eabi/eapsecuridu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + _Z24ImplementationGroupProxyRi @ 1 NONAME + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/eabi/eapsimu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/eabi/eapsimu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + _Z24ImplementationGroupProxyRi @ 1 NONAME + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/eabi/eaptlspeapu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/eabi/eaptlspeapu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + _Z24ImplementationGroupProxyRi @ 1 NONAME + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/eabi/eapvpnifu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/eabi/eapvpnifu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + _Z24ImplementationGroupProxyRi @ 1 NONAME + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/eabi/wlaneapolifu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/eabi/wlaneapolifu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + _Z24ImplementationGroupProxyRi @ 1 NONAME + diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/backup_registration_eapol.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/backup_registration_eapol.xml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Build information file for project EAPOL +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +// Exporting IBY file (only for 5.0). +../rom/eapol.iby CORE_MW_LAYER_IBY_EXPORT_PATH(eapol.iby) + +// Secure policy file for saving all EAPOL AND EAP databases in DBMS. +../am/include/102072e9.spd /epoc32/data/z/private/100012a5/policy/102072e9.spd +../am/include/102072e9.spd /epoc32/release/winscw/udeb/z/private/100012a5/policy/102072e9.spd +../am/include/102072e9.spd /epoc32/release/winscw/urel/z/private/100012a5/policy/102072e9.spd + +// Backup registration file for backing up all EAPOL related databases. Exported to the private cage path for WLAN engine. +backup_registration_eapol.xml /epoc32/data/z/private/101F8EC5/backup_registration_eapol.xml +backup_registration_eapol.xml /epoc32/release/winscw/udeb/z/private/101F8EC5/backup_registration_eapol.xml +backup_registration_eapol.xml /epoc32/release/winscw/urel/z/private/101F8EC5/backup_registration_eapol.xml + +// Copies configuration file of EAPOL. +../am/core/symbian/file_config/eap_symbian.conf /epoc32/data/z/private/101F8EC5/eap.conf +../am/core/symbian/file_config/eap_symbian.conf /epoc32/release/winscw/udeb/z/private/101F8EC5/eap.conf +../am/core/symbian/file_config/eap_symbian.conf /epoc32/release/winscw/urel/z/private/101F8EC5/eap.conf + +#ifndef __SERIES60_HELP +../am/type/securid/symbian/plugin/inc/eapgtc.hlp.hrh /epoc32/include/cshelp/eapgtc.hlp.hrh +../am/type/mschapv2/symbian/plugin/inc/eapmschap.hlp.hrh /epoc32/include/cshelp/eapmschap.hlp.hrh +../am/type/tls_peap/symbian/plugin/inc/eappeap.hlp.hrh /epoc32/include/cshelp/eappeap.hlp.hrh +../am/type/gsmsim/symbian/plugin/inc/eapsim.hlp.hrh /epoc32/include/cshelp/eapsim.hlp.hrh +../am/type/tls_peap/symbian/plugin/inc/eaptls.hlp.hrh /epoc32/include/cshelp/eaptls.hlp.hrh +#endif + +#ifndef __SERIES60_HELP +// EAP-LEAP is part of WPX. You need special release to compile this. However the header is needed. +../am/type/leap/symbian/plugin/inc/eapleap.hlp.hrh /epoc32/include/cshelp/eapleap.hlp.hrh +#endif + + +PRJ_MMPFILES + +// This compiles stub of EAPOL WPX, the empty functions that implement WPX. +eapolwpxstub.mmp + +// This is the basic set that should always be compiled for every environment. +eapol.mmp +eapsim.mmp +eaptlspeap.mmp +eapmschapv2.mmp +eapsecurid.mmp +eapaka.mmp + +// API for VPN. +eapvpnif.mmp + +eapprotectedsetup.mmp + +// API for WLAN-engine. +wlaneapolif.mmp + + +// End of file. diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/eapaka.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/eapaka.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project definition file for project EAPOL +* +*/ + + +#include +#include "eapol.mmh" + +CAPABILITY CAP_ECOM_PLUGIN +VENDORID VID_DEFAULT +TARGETTYPE PLUGIN + +TARGET eapaka.dll +UID 0x10009d8d 0x102073c1 + +SOURCEPATH ../am/type/aka/symbian/plugin/src + +START RESOURCE 102073c1.rss + TARGET eapaka.rsc +END + +SOURCE EapAka.cpp +SOURCE EapAkaProxy.cpp +SOURCE EapAkaDbUtils.cpp + +SOURCEPATH ../am/type/aka/symbian +SOURCE eap_am_type_aka_symbian.cpp + +SOURCEPATH ../am/type/symbian/plugin/common +SOURCE EapTypeInfo.cpp + +SOURCEPATH ../../eapol_common/type/aka/core +SOURCE eap_type_aka_state_notification.cpp +SOURCE eap_type_aka_payloads.cpp +SOURCE eap_type_aka_state.cpp +SOURCE eap_type_aka.cpp +SOURCE eap_type_aka_client.cpp +SOURCE eap_type_aka_server.cpp +SOURCE eap_type_aka_header.cpp +SOURCE eap_type_aka_authentication_vector.cpp + +SOURCEPATH ../am/common/symbian +SOURCE eap_am_trace_symbian.cpp + +SOURCEPATH ../am/type/aka/symbian/plugin/src +SOURCE EapAkaUiConnection.cpp +SOURCE EapAkaUiDataConnection.cpp +SOURCE EapAkaUiAkaData.cpp +LIBRARY avkon.lib +STATICLIBRARY eapakaui.lib + +USERINCLUDE ../am/include +USERINCLUDE ../am/type/symbian/plugin/include +USERINCLUDE ../../eapol_common +USERINCLUDE ../../eapol_common/include +USERINCLUDE ../../eapol_common/am/include +USERINCLUDE ../../eapol_common/type/aka/include +USERINCLUDE ../am/type/aka/symbian/plugin/inc +USERINCLUDE ../../eapol_common/type + +//SYSTEMINCLUDE /epoc32/include/ecom +//SYSTEMINCLUDE /epoc32/include/libc +//SYSTEMINCLUDE /epoc32/include/cshelp + +MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers. + +LIBRARY euser.lib ecom.lib eapol.lib edbms.lib efsrv.lib +LIBRARY cone.lib eikcoctl.lib eikctl.lib bafl.lib +LIBRARY estor.lib // For RReadStream + +LANG SC + +#if !defined(WINS) && defined(USE_EAP_AKA_INTERFACE) + +SOURCEPATH ../am/type/aka/symbian +SOURCE EapAkaInterface.cpp +LIBRARY CustomAPI.lib etelmm.lib etel.lib // For ETel connection + +#endif // End of #if !defined(WINS) && defined(USE_EAP_AKA_INTERFACE) + +MACRO EAP_NO_EXPORTS + +LIBRARY eikdlg.lib +LIBRARY eikcore.lib +LIBRARY hlplch.lib +LIBRARY featmgr.lib +//------------------------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/eapmschapv2.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/eapmschapv2.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project definition file for project EAPOL +* +*/ + + +#include +#include "eapol.mmh" + +CAPABILITY CAP_ECOM_PLUGIN +VENDORID VID_DEFAULT +TARGETTYPE PLUGIN + +TARGET eapmschapv2.dll +UID 0x10009d8d 0x101F8E66 + +SOURCEPATH ../am/type/mschapv2/symbian/plugin/src + +START RESOURCE 101F8E66.rss + TARGET eapmschapv2.rsc +END + +SOURCE EapMsChapV2.cpp +SOURCE EapMsChapV2Proxy.cpp +SOURCE EapMsChapV2DbUtils.cpp + +SOURCEPATH ../am/type/symbian/plugin/common +SOURCE EapTypeInfo.cpp + +SOURCEPATH ../am/type/mschapv2/symbian +SOURCE eap_am_type_mschapv2_symbian.cpp + +SOURCEPATH ../../eapol_common/type/mschapv2/core +SOURCE eap_type_mschapv2.cpp +SOURCE eap_type_mschapv2_client.cpp +SOURCE eap_type_mschapv2_state.cpp +SOURCE eap_type_mschapv2_header.cpp +SOURCE eap_type_mschapv2_credential_store.cpp + +#define COMPILE_EAP_MSCHAPV2_SERVER +#ifdef COMPILE_EAP_MSCHAPV2_SERVER + MACRO EAP_MSCHAPV2_SERVER=1 + SOURCE eap_type_mschapv2_server.cpp +#endif + +SOURCEPATH ../am/common/symbian +SOURCE eap_am_trace_symbian.cpp + +SOURCEPATH ../am/type/mschapv2/symbian/plugin/src +SOURCE EapMsChapV2UiConnection.cpp +SOURCE EapMsChapV2UiDataConnection.cpp +SOURCE EapMsChapV2UiMsChapV2Data.cpp +LIBRARY avkon.lib +STATICLIBRARY EAPMSCHAPV2UI.LIB + +USERINCLUDE ../am/type/mschapv2/symbian/plugin/inc +USERINCLUDE ../../eapol_common/type/mschapv2/include +USERINCLUDE ../../eapol_common/include +USERINCLUDE ../am/include +USERINCLUDE ../../eapol_common/am/include +USERINCLUDE ../am/type/symbian/plugin/include +USERINCLUDE ../../eapol_common/type + +//SYSTEMINCLUDE /epoc32/include/ecom +//SYSTEMINCLUDE /epoc32/include/libc +//SYSTEMINCLUDE /epoc32/include/cshelp + +MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers. + +LIBRARY euser.lib +LIBRARY ecom.lib +LIBRARY eapol.lib +LIBRARY edbms.lib +LIBRARY efsrv.lib +LIBRARY cone.lib +LIBRARY eikcoctl.lib +LIBRARY eikctl.lib +LIBRARY bafl.lib +LIBRARY eikdlg.lib +LIBRARY eikcore.lib +LIBRARY hlplch.lib +LIBRARY featmgr.lib + +LANG SC + +MACRO EAP_NO_EXPORTS=1 + +//------------------------------------------------------------------- + +//------------------------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/eapol.mmh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/eapol.mmh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,173 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project definition file for project EAPOL +* +*/ + + +//------------------------------------------------------------------- + +// Set up the preprocessor macros for source files + +// This enables TTLS +MACRO USE_TTLS_EAP_TYPE + +// This flag activates start WPXM functionaly. +MACRO USE_EAPOL_START_WPXM_REASSOCIATION + +// This flag tells the 64-bit multiplication of platform can be used. +MACRO USE_EAP_64_BIT_MULTIPLICATION + +// This flag activates the EAP-TTLS/MsChapv2 authentication. +// Note this is inside EAP protocol. +// We did not have any plan to make this authentication. +MACRO EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK +#define EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK + +MACRO USE_EAP_GSMSIM_INTERFACE +// Comment the below line for Test environment. ( Eg: for Plugin Tester ) +// Also use the directory wlaneapol_testing. Otherwise EAP GSM SIM won't compile. +#define USE_EAP_GSMSIM_INTERFACE + +// Comment the below lines for Test environment ( Eg: for Plugin Tester in emulator or simulator tests on hardware ) +// Also use the directory wlaneapol_testing. Otherwise EAP AKA won't compile. +MACRO USE_EAP_AKA_INTERFACE +#define USE_EAP_AKA_INTERFACE + +// This might be useless. +//MACRO SYMBIAN_CRYPTO=1 + +// This is very important definition. +MACRO EAP_LITTLE_ENDIAN=1 + +//------------------------------------------------------------------- + +// This macro activates stack trace of EAP_ASSERT(). +// When assertion is false the current stack is traced before abort of program. +//MACRO USE_EAP_ASSERT_STACK_TRACE +//#define USE_EAP_ASSERT_STACK_TRACE + +// This is used to enable configuring from file. +MACRO USE_EAP_FILECONFIG=1 + +// Add this when database compatibility is not needed anymore. +// This fixes some names of database fields. +MACRO USE_EAP_FIXED_DATABASE_FIELDS=1 + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// This flag enables EAP expanded types. +MACRO USE_EAP_EXPANDED_TYPES=1 +#define USE_EAP_EXPANDED_TYPES + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// This flag activates message based WLAN engine EAPOL interface. +MACRO USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_IF +#define USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_IF + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// This flag enables EAP Protected setup (or Simple Config or Easy Setup or EAP-WSC). +MACRO USE_EAP_SIMPLE_CONFIG=1 +#define USE_EAP_SIMPLE_CONFIG + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +#if defined(FF_WLAN_EXTENSIONS) + +MACRO USE_FAST_EAP_TYPE=1 +#define USE_FAST_EAP_TYPE + +MACRO USE_EAP_TLS_SESSION_TICKET=1 +#define USE_EAP_TLS_SESSION_TICKET + +MACRO USE_EAP_TLS_IDENTITY_PRIVACY=1 + +MACRO USE_PAC_STORE=1 +#define USE_PAC_STORE + +#endif // End: #if defined(FF_WLAN_EXTENSIONS) + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// This macro enables some traces for release error log. +// EAP_TRACE_ALWAYS() and EAP_TRACE_DATA_ALWAYS() are left +// active if USE_EAP_TRACE_ALWAYS is defined. +//MACRO USE_EAP_TRACE_ALWAYS=1 + +// This very heavy trace. Do use only when other things fail. +//MACRO USE_EAP_FUNCTION_TRACE=1 + +// This flag activates minimum traces for release version. +// Traces will be written to log file. +//MACRO USE_EAP_MINIMUM_RELEASE_TRACES + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// This flag activates some interoperability PEAPv0 and PEAPv1 fixes. +MACRO USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES=1 + +// This flag activates server codes of EAP-SIM. +// Uncomment the below lines for activating the server codes ( for plugin tester). +//MACRO USE_EAP_TYPE_SERVER_GSMSIM=1 + +// This flag activates server codes of EAP-AKA. +// Uncomment the below lines for activating the server codes ( for plugin tester). +// MACRO USE_EAP_TYPE_SERVER_AKA +// #define USE_EAP_TYPE_SERVER_AKA + +// This flag activates server codes of EAP-SECURID and GTC. +// Uncomment the below lines for activating the server codes ( for plugin tester). +//MACRO COMPILE_EAP_SECURID_SERVER=1 +//MACRO EAP_SECURID_SERVER=1 + +// This flag activates server codes of EAPOL +MACRO USE_EAP_CORE_SERVER=1 + +// This is to enable password change functionality for MSCHAPv2 +// MACRO EAP_MSCHAPV2_ENABLE_PASSWORD_CHANGE=1 + +// These following macros should be adjusted depending on the test environment. +// For WLM compatibility only NO_EAP_MUTEX should be defined. +MACRO NO_EAP_MUTEX=1 +MACRO USE_EAPOL_KEY_STATE=1 + +// The following marco activates optimized 4-Way Handshake. +// Note the interface between WLAN engine and EAPOL changes too. +MACRO USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE=1 + +// Enables configuration option to skips user interactions in selected test cases. +MACRO USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS=1 + +// Enables timer to stop authentication with broken authentication server or access point configuration that blocks WLAN connection for too long time. +MACRO USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER=1 + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if defined(FF_WLAN_EXTENSIONS) + #define USE_EAPOL_WLAN_WPX + // This activates WPXM. + // You need all EAPOL WPX sources or binary eapolwpx.lib to compile WPX version. + MACRO EAP_USE_WPXM=1 + #define EAP_USE_WPXM +#else + // The WPX stub is needed even without WPX functionality. + #define USE_EAPOL_WLAN_WPX_STUB +#endif // #if defined(FF_WLAN_EXTENSIONS) + + +//------------------------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/eapol.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/eapol.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,196 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project definition file for project EAPOL +* +*/ + + + +//------------------------------------------------------------------- + +#include +#include "eapol.mmh" + +//------------------------------------------------------------------- +CAPABILITY ALL -TCB +VENDORID VID_DEFAULT + +TARGET eapol.dll +TARGETTYPE dll +UID 0x1000008d 0x101f8e48 + +deffile EAPOLPROTECTED.DEF + +SOURCEPATH ../am/common/symbian +SOURCE dll_entry.cpp +SOURCE eap_am_tools_symbian.cpp + +// This source uses Symbian crypto library. +SOURCEPATH ../am/common/symbian +SOURCE eap_am_crypto_symbian.cpp +SOURCE eap_am_mutex_symbian.cpp + +SOURCEPATH ../am/common/DSS_random +SOURCE dss_random_symbian.cpp + +#if defined(USE_EAP_ASSERT_STACK_TRACE) +SOURCEPATH ../../eapol_common/am/common/stack +SOURCE eap_am_stack_trace.cpp +#endif //#if defined(USE_EAP_ASSERT_STACK_TRACE) + +SOURCEPATH ../../eapol_common/am/common/crypto/md4 +SOURCE eap_am_crypto_md4.cpp + +SOURCEPATH ../../eapol_common/am/common/crypto/rc4 +SOURCE eap_am_crypto_rc4.cpp + +SOURCEPATH ../../eapol_common/am/common/crypto/sha1 +SOURCE eap_am_crypto_sha1.cpp + +SOURCEPATH ../../eapol_common/am/common/crypto/sha-256 +SOURCE eap_am_crypto_sha_256.cpp + +SOURCEPATH ../../eapol_common/am/common +SOURCE eap_am_memory.cpp +SOURCE eap_am_network_id.cpp +SOURCE eap_am_tools.cpp +SOURCE eap_timer_queue.cpp +SOURCE eap_am_memory_store.cpp +SOURCE eap_am_memory_store_data.cpp +SOURCE abs_eap_am_mutex.cpp + +SOURCEPATH ../../eapol_common/am/common +SOURCE eap_file_config.cpp +SOURCEPATH ../am/common/file_io/symbian +SOURCE eap_am_file_input_symbian.cpp + +SOURCEPATH ../../eapol_common/am/core +SOURCE eapol_am_wlan_authentication.cpp + +SOURCEPATH ../am/core/symbian + +SOURCE eapol_am_wlan_authentication_symbian.cpp + +LIBRARY bafl.lib +LIBRARY wlandbif.lib + +/////////////////////////////////////////////////////////////////// + +LANG SC + +SOURCEPATH ../../eapol_common/common +SOURCE eap_base_type.cpp +SOURCE eap_buffer.cpp +SOURCE eap_crypto_api.cpp +SOURCE eap_header.cpp +SOURCE eap_expanded_type.cpp +SOURCE eap_header_string.cpp +SOURCE eap_state_notification.cpp +SOURCE eap_tools.cpp +SOURCE eap_status_string.cpp +SOURCE eap_variable_data.cpp +SOURCE eap_master_session_key.cpp +SOURCE eap_general_header_base.cpp +SOURCE eap_rogue_ap_entry.cpp +SOURCE eap_memory_store_variable_data.cpp +SOURCE eapol_session_key.cpp +SOURCE eap_network_id_selector.cpp +SOURCE eapol_ethernet_header.cpp +SOURCE eapol_header.cpp +SOURCE eap_tlv_header.cpp +SOURCE eap_tlv_message_data.cpp + +#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_IF) +SOURCEPATH ../../eapol_common/common +SOURCE wlan_eap_if_send_status.cpp +#endif //#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_IF) + +SOURCEPATH ../../eapol_common/core +SOURCE eap_core.cpp +SOURCE eap_core_nak_info.cpp +SOURCE eap_core_retransmission.cpp +SOURCE eap_session_core.cpp +SOURCE eap_type_selection.cpp +SOURCE eapol_core.cpp +SOURCE ethernet_core.cpp +SOURCE eapol_key_state_common.cpp +SOURCE eapol_key_state_client.cpp +SOURCE eapol_key_state_server.cpp +SOURCE eapol_key_state_string.cpp +SOURCE eapol_rsna_key_data_payloads.cpp +SOURCE eapol_rc4_key_header.cpp +SOURCE eapol_rsna_key_data_header.cpp +SOURCE eapol_rsna_key_header.cpp +SOURCE eapol_rsna_key_data_gtk_header.cpp +SOURCE eapol_wlan_authentication.cpp +SOURCE eapol_wlan_database_reference.cpp + +#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_IF) +SOURCEPATH ../../eapol_common/core +SOURCE eapol_message_wlan_authentication.cpp +SOURCE eapol_handle_tlv_message_data.cpp +#endif //#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_IF) + +SOURCEPATH ../am/eap_test_timer/symbian +SOURCE eap_test_timer.cpp + +SOURCEPATH ../../eapol_common/type/tls_peap/tls/src +SOURCE tls_peap_tlv_header.cpp + +SOURCEPATH ../../eapol_common/type/simple_config/simple_config/src +SOURCE simple_config_credential.cpp +SOURCE simple_config_types.cpp + +#if !defined(USE_EAPOL_WLAN_WPX_STUB) +// This library includes real WPX functionality. +STATICLIBRARY eapolwpx.lib +#endif //#if !defined(USE_EAPOL_WLAN_WPX_STUB) + +#if defined(USE_EAPOL_WLAN_WPX_STUB) +// This library includes stubs of non working WPX functions. +STATICLIBRARY eapolwpxstub.lib +#endif //#if defined(USE_EAPOL_WLAN_WPX_STUB) + +USERINCLUDE .. +USERINCLUDE ../am/type/symbian/plugin/include +USERINCLUDE ../am/common +USERINCLUDE ../../eapol_common/am/common +USERINCLUDE ../am/include +USERINCLUDE ../../eapol_common/am/include +USERINCLUDE ../../eapol_common/include +USERINCLUDE ../../eapol_common/type +USERINCLUDE ../../eapol_common/am/common/DSS_random +USERINCLUDE ../../eapol_common/type/tls_peap/tls/include +USERINCLUDE ../../eapol_common/type/simple_config/simple_config/include +USERINCLUDE ../../eapol_common/type/simple_config/eap/include + +#if defined(EAP_USE_WPXM) +USERINCLUDE ../../eapol_common/wpx_include +#endif //#if defined(EAP_USE_WPXM) + + +//SYSTEMINCLUDE /epoc32/include/ecom +SYSTEMINCLUDE /epoc32/include/kernel +SYSTEMINCLUDE /epoc32/include/libc +SYSTEMINCLUDE /epoc32/include/libc/netinet + +MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers. + +LIBRARY ecom.lib +LIBRARY euser.lib hash.lib random.lib cryptography.lib efsrv.lib asn1.lib edbms.lib +LIBRARY charconv.lib + +MACRO USE_EAP_INTERFACE_EXPORTS +//------------------------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/eapolwpxstub.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/eapolwpxstub.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project definition file for project EAPOL +* +*/ + + + +//------------------------------------------------------------------- + +#include +#include "eapol.mmh" + +//------------------------------------------------------------------- + +TARGET eapolwpxstub.lib + +TARGETTYPE lib +UID 0x1000008d 0x101f8e48 + +/////////////////////////////////////////////////////////////////// + +LANG SC + +SOURCEPATH ../../eapol_common/wpxstub +SOURCE eapol_core_wpxm_stub.cpp +SOURCE eapol_key_state_common_wpxm_stub.cpp +SOURCE ethernet_core_wpxm_stub.cpp + +USERINCLUDE .. +USERINCLUDE ../am/type/symbian/plugin/include +USERINCLUDE ../am/common +USERINCLUDE ../../eapol_common/am/common +USERINCLUDE ../am/include +USERINCLUDE ../../eapol_common/am/include +USERINCLUDE ../../eapol_common/include +USERINCLUDE ../../eapol_common/type +USERINCLUDE ../../eapol_common/am/common/DSS_random + +SYSTEMINCLUDE /epoc32/include/ecom +SYSTEMINCLUDE /epoc32/include/kernel +SYSTEMINCLUDE /epoc32/include/libc +SYSTEMINCLUDE /epoc32/include/libc/netinet + +MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers. + +//------------------------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/eapprotectedsetup.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/eapprotectedsetup.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,154 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project definition file for project EAP-Protected setup +* +*/ + + +#include +#include "eapol.mmh" + +CAPABILITY CAP_ECOM_PLUGIN +VENDORID VID_DEFAULT +TARGETTYPE PLUGIN + +TARGET eapprotectedsetup.dll +UID 0x10009d8d 0x2000b003 + +SOURCEPATH ../am/type/protected_setup/symbian/plugin/src + +START RESOURCE 2000b003.rss + TARGET eapprotectedsetup.rsc +END + +// For Symbian Side +SOURCEPATH ../am/type/protected_setup/symbian/plugin/src +SOURCE EapProtectedSetup.cpp +SOURCE EapProtectedSetupProxy.cpp + +SOURCEPATH ../am/type/symbian/plugin/common +SOURCE EapTypeInfo.cpp + +//SOURCEPATH ../am/type/symbian/plugin/common +//SOURCE EapProtectedSetupInfo.cpp + +SOURCEPATH ../am/type/protected_setup +SOURCE eap_am_type_protected_setup_symbian.cpp +SOURCE EapProtectedSetupInterface.cpp + +SOURCEPATH ../am/common/symbian +SOURCE eap_am_trace_symbian.cpp + +// For Common Side +SOURCEPATH ../../eapol_common/type/simple_config/eap/src +SOURCE eap_type_simple_config.cpp +SOURCE eap_type_simple_config_header.cpp +SOURCE eap_type_simple_config_state_notification.cpp + +SOURCEPATH ../../eapol_common/type/simple_config/simple_config/src +SOURCE simple_config_base_record.cpp +SOURCE simple_config_completion.cpp +SOURCE simple_config_message.cpp +SOURCE simple_config_record.cpp +SOURCE simple_config_tlv_header.cpp +SOURCE simple_config_types.cpp +SOURCE simple_config_payloads.cpp +SOURCE simple_config_credential.cpp + +// For Common Side +USERINCLUDE ../../eapol_common/include +USERINCLUDE ../../eapol_common/am/include +USERINCLUDE ../../eapol_common/type/simple_config/eap/include +USERINCLUDE ../../eapol_common/type/simple_config/simple_config/include + +// For Symbian Side +USERINCLUDE ../am/include +USERINCLUDE ../am/type/protected_setup/symbian/plugin/inc + +/* + +//USERINCLUDE ../am/type/tls_peap/symbian/plugin/inc + +USERINCLUDE ../../eapol_common/am/include +USERINCLUDE ../../eapol_common/type +USERINCLUDE ../../eapol_common/type/diameter/include + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) +USERINCLUDE ../../eapol_common/type/mschapv2/include +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) +SOURCEPATH ../../eapol_common/type/mschapv2/core +SOURCE eap_type_mschapv2_header.cpp +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +*/ + +//SOURCEPATH ../am/type/tls_peap/symbian/plugin/inc +//DOCUMENT 101f8e4c.loc + +/* +// UI +SOURCEPATH ../am/type/tls_peap/symbian/plugin/src +SOURCE EapTlsPeapUiConnection.cpp +SOURCE EapTlsPeapUiDataConnection.cpp +SOURCE EapTlsPeapUiTlsPeapData.cpp +SOURCE EapTlsPeapCertFetcher.cpp +SOURCE EapTlsPeapUiEapTypes.cpp +SOURCE EapTlsPeapUiCertificates.cpp +SOURCE EapTlsPeapUiCipherSuites.cpp +*/ +/* +LIBRARY avkon.lib +LIBRARY AknSkins.lib +LIBRARY AknIcon.lib +STATICLIBRARY eaptlsui.lib +STATICLIBRARY eappeapui.lib +STATICLIBRARY eapttlsui.lib +LIBRARY x509certnameparser.lib // For parsing of certificate label. + +//SYSTEMINCLUDE /epoc32/include/ecom +//SYSTEMINCLUDE /epoc32/include/libc +//SYSTEMINCLUDE /epoc32/include/cshelp +*/ + +LANG SC + +MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers. + +LIBRARY euser.lib ecom.lib eapol.lib //edbms.lib efsrv.lib +LIBRARY cone.lib eikcoctl.lib +LIBRARY etelmm.lib etel.lib // For ETel connection + +LIBRARY wlandbif.lib + +//LIBRARY x509.lib crypto.lib certstore.lib ctframework.lib pkixcert.lib +//LIBRARY asn1.lib x500.lib bafl.lib eikctl.lib egul.lib fbscli.lib +/* +LIBRARY gdi.lib +LIBRARY cryptography.lib +LIBRARY eikdlg.lib +LIBRARY eikcore.lib +LIBRARY CommonEngine.lib + +LIBRARY hlplch.lib +LIBRARY featmgr.lib +*/ + +MACRO EAP_NO_EXPORTS=1 + +//------------------------------------------------------------------- + +//------------------------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/eapsecurid.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/eapsecurid.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project definition file for project EAPOL +* +*/ + + +#include +#include "eapol.mmh" + +CAPABILITY CAP_ECOM_PLUGIN +VENDORID VID_DEFAULT +TARGETTYPE PLUGIN + +TARGET eapsecurid.dll +UID 0x10009d8d 0x101F8E74 + +SOURCEPATH ../am/type/securid/symbian/plugin/src + +START RESOURCE 101F8E74.rss + TARGET eapsecurid.rsc +END + +SOURCE EapSecurID.cpp +SOURCE EapSecurIDProxy.cpp + +SOURCE EapSecurIDDbUtils.cpp +SOURCE EapGtcDbUtils.cpp + +SOURCEPATH ../am/type/symbian/plugin/common +SOURCE EapTypeInfo.cpp + +SOURCEPATH ../am/type/securid/symbian +SOURCE eap_am_type_securid_symbian.cpp + +SOURCEPATH ../../eapol_common/type/securid/core +SOURCE eap_type_securid.cpp +SOURCE eap_type_securid_client.cpp +SOURCE eap_type_securid_state.cpp + +#ifdef COMPILE_EAP_SECURID_SERVER + SOURCE eap_type_securid_server.cpp +#endif + +SOURCEPATH ../am/common/symbian +SOURCE eap_am_trace_symbian.cpp + +SOURCEPATH ../am/type/securid/symbian/plugin/src +SOURCE EapGtcUiConnection.cpp +SOURCE EapGtcUiDataConnection.cpp +SOURCE EapGtcUiGtcData.cpp +LIBRARY avkon.lib +STATICLIBRARY eapgtcui.lib + +USERINCLUDE ../am/type/securid/symbian/plugin/inc +USERINCLUDE ../../eapol_common/type/securid/include +USERINCLUDE ../../eapol_common/include +USERINCLUDE ../am/include +USERINCLUDE ../../eapol_common/am/include +USERINCLUDE ../am/type/symbian/plugin/include +USERINCLUDE ../../eapol_common/type + +//SYSTEMINCLUDE /epoc32/include/ecom +//SYSTEMINCLUDE /epoc32/include/libc +//SYSTEMINCLUDE /epoc32/include/cshelp + +MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers. + +LIBRARY euser.lib ecom.lib eapol.lib edbms.lib efsrv.lib cone.lib eikcoctl.lib +LIBRARY bafl.lib +LIBRARY eikdlg.lib +LIBRARY eikcore.lib +LIBRARY hlplch.lib +LIBRARY featmgr.lib + +LANG SC + +MACRO EAP_NO_EXPORTS=1 + +//------------------------------------------------------------------- + +//------------------------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/eapsim.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/eapsim.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project definition file for project EAPOL +* +*/ + + +#include +#include "eapol.mmh" + +CAPABILITY CAP_ECOM_PLUGIN +VENDORID VID_DEFAULT +TARGETTYPE PLUGIN + +TARGET eapsim.dll +UID 0x10009d8d 0x101f8e49 + +SOURCEPATH ../am/type/gsmsim/symbian/plugin/src + +START RESOURCE 101f8e49.rss + TARGET eapsim.rsc +END + +SOURCE EapSim.cpp +SOURCE EapSimProxy.cpp +SOURCE EapSimDbUtils.cpp +SOURCEPATH ../am/type/symbian/plugin/common +SOURCE EapTypeInfo.cpp + +SOURCEPATH ../am/type/gsmsim/symbian +SOURCE eap_am_type_gsmsim_symbian.cpp + +SOURCEPATH ../../eapol_common/type/gsmsim/core +SOURCE eap_type_gsmsim_state_notification.cpp +SOURCE eap_type_gsmsim_payloads.cpp +SOURCE eap_type_gsmsim_state.cpp +SOURCE eap_type_gsmsim.cpp +SOURCE eap_type_gsmsim_client.cpp +SOURCE eap_type_gsmsim_server.cpp +SOURCE eap_type_gsmsim_header.cpp +SOURCE eap_type_gsmsim_initialized.cpp +SOURCE eap_type_gsmsim_mac_attributes.cpp + +SOURCEPATH ../../eapol_common/common +SOURCE eap_sim_triplets.cpp + +SOURCEPATH ../am/common/symbian +SOURCE eap_am_trace_symbian.cpp + +SOURCEPATH ../am/type/gsmsim/symbian/plugin/src +SOURCE EapSimUiConnection.cpp +SOURCE EapSimUiDataConnection.cpp +SOURCE EapSimUiSimData.cpp + +LIBRARY avkon.lib +STATICLIBRARY eapsimui.lib + +USERINCLUDE ../am/type/gsmsim/symbian/plugin/inc +USERINCLUDE ../../eapol_common/type/gsmsim/include +USERINCLUDE ../../eapol_common/include +USERINCLUDE ../am/include +USERINCLUDE ../../eapol_common/am/include +USERINCLUDE ../../eapol_common/type + +MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers. + +LIBRARY euser.lib ecom.lib eapol.lib edbms.lib efsrv.lib +LIBRARY cone.lib eikcoctl.lib eikctl.lib bafl.lib +LIBRARY estor.lib // For RReadStream + +LANG SC + +SOURCEPATH ../am/type/gsmsim/symbian/plugin/inc +DOCUMENT 101f8e49.loc + +// For test environment, comment out USE_EAP_GSMSIM_INTERFACE in eapol.mmh. +#if !defined(WINS) && defined(USE_EAP_GSMSIM_INTERFACE) + SOURCEPATH ../am/type/gsmsim/symbian + SOURCE EapSimInterface.cpp + LIBRARY CustomAPI.lib etelmm.lib etel.lib // For ETel connection +#endif // End of #if !defined(WINS) && defined(USE_EAP_GSMSIM_INTERFACE) + +MACRO EAP_NO_EXPORTS + +LIBRARY eikdlg.lib +LIBRARY eikcore.lib +LIBRARY hlplch.lib +LIBRARY featmgr.lib + +//------------------------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/eaptlspeap.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/eaptlspeap.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,164 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project definition file for project EAPOL +* +*/ + + +#include +#include "eapol.mmh" + +CAPABILITY CAP_ECOM_PLUGIN +VENDORID VID_DEFAULT +TARGETTYPE PLUGIN + +TARGET eaptlspeap.dll +UID 0x10009d8d 0x101f8e4c + +SOURCEPATH ../am/type/tls_peap/symbian/plugin/src + +START RESOURCE 101f8e4c.rss + TARGET eaptlspeap.rsc +END + +SOURCEPATH ../am/type/tls_peap/symbian +SOURCE EapTlsPeapCertInterface.cpp // For certificate interface. + +SOURCEPATH ../am/type/tls_peap/symbian/plugin/src +SOURCE EapTlsPeap.cpp +SOURCE EapTlsPeapProxy.cpp +SOURCE EapTlsPeapUtils.cpp + +SOURCEPATH ../am/type/symbian/plugin/common +SOURCE EapTypeInfo.cpp + +SOURCEPATH ../am/type/tls_peap/symbian +SOURCE eap_am_type_tls_peap_symbian.cpp + +SOURCEPATH ../../eapol_common/type/tls_peap/eap/src +SOURCE eap_type_tls_peap_state_notification.cpp +SOURCE eap_type_tls_peap.cpp +SOURCE eap_type_tls_peap_header.cpp + +SOURCEPATH ../../eapol_common/type/tls_peap/tls/src +SOURCE tls_application_eap_core.cpp +SOURCE tls_application_ttls_plain_mschapv2.cpp +SOURCE tls_base_application.cpp +SOURCE tls_base_record.cpp +SOURCE tls_record.cpp +SOURCE tls_handshake_message.cpp +SOURCE tls_message.cpp +SOURCE tls_record_message.cpp +SOURCE tls_peap_types.cpp +SOURCE tls_completion.cpp +SOURCE tls_change_cipher_spec_message.cpp +SOURCE tls_application_data_message.cpp +SOURCE tls_alert_message.cpp +SOURCE tls_peap_tlv_payloads.cpp +SOURCE tls_handshake_header.cpp +SOURCE tls_peap_tlv_header.cpp +SOURCE tls_record_header.cpp +SOURCE tls_extension.cpp + + +SOURCEPATH ../../eapol_common/type/diameter/src +SOURCE eap_diameter_avp_header.cpp +SOURCE eap_diameter_payloads.cpp +SOURCE eap_diameter_avp_code.cpp + +SOURCEPATH ../am/common/symbian +SOURCE eap_am_trace_symbian.cpp + +SOURCEPATH ../am/type/ttls_pap/symbian/src +SOURCE eap_ttls_pap_active.cpp + +USERINCLUDE ../am/type/tls_peap/symbian/plugin/inc +USERINCLUDE ../../eapol_common/type/tls_peap/eap/include +USERINCLUDE ../../eapol_common/type/tls_peap/tls/include +#if defined(USE_FAST_EAP_TYPE) +USERINCLUDE ../../eapol_common/type/tls_peap/tls/include/wpx +#endif //#if defined(USE_FAST_EAP_TYPE) +USERINCLUDE ../../eapol_common/include +USERINCLUDE ../am/include +USERINCLUDE ../../eapol_common/am/include +USERINCLUDE ../../eapol_common/type +USERINCLUDE ../../eapol_common/type/diameter/include +USERINCLUDE ../am/type/ttls_pap/symbian/inc + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) +USERINCLUDE ../../eapol_common/type/mschapv2/include +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) +SOURCEPATH ../../eapol_common/type/mschapv2/core +SOURCE eap_type_mschapv2_header.cpp +#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) + +#if defined(USE_FAST_EAP_TYPE) +#include "wpxeap/eapfast.mmp" +#endif +LANG SC + +SOURCEPATH ../am/type/tls_peap/symbian/plugin/inc +DOCUMENT 101f8e4c.loc + +// UI +SOURCEPATH ../am/type/tls_peap/symbian/plugin/src +SOURCE EapTlsPeapUiConnection.cpp +SOURCE EapTlsPeapUiDataConnection.cpp +SOURCE EapTlsPeapUiTlsPeapData.cpp +SOURCE EapTlsPeapCertFetcher.cpp +SOURCE EapTlsPeapUiEapTypes.cpp +SOURCE EapTlsPeapUiCertificates.cpp +SOURCE EapTlsPeapUiCipherSuites.cpp + +LIBRARY avkon.lib +LIBRARY AknSkins.lib +LIBRARY AknIcon.lib +LIBRARY aknnotify.lib +LIBRARY eiksrv.lib +STATICLIBRARY eaptlsui.lib +STATICLIBRARY eappeapui.lib +STATICLIBRARY eapttlsui.lib + +STATICLIBRARY papui.lib + +LIBRARY x509certnameparser.lib // For parsing of certificate label. + +//SYSTEMINCLUDE /epoc32/include/ecom +//SYSTEMINCLUDE /epoc32/include/libc +//SYSTEMINCLUDE /epoc32/include/cshelp + +MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers. + +LIBRARY euser.lib ecom.lib eapol.lib edbms.lib efsrv.lib cone.lib eikcoctl.lib +LIBRARY x509.lib crypto.lib certstore.lib ctframework.lib pkixcert.lib +LIBRARY asn1.lib x500.lib bafl.lib eikctl.lib egul.lib fbscli.lib +LIBRARY gdi.lib +LIBRARY cryptography.lib +LIBRARY eikdlg.lib +LIBRARY eikcore.lib +LIBRARY CommonEngine.lib + +LIBRARY hlplch.lib +LIBRARY featmgr.lib + +LIBRARY charconv.lib + +MACRO EAP_NO_EXPORTS=1 + +//------------------------------------------------------------------- + +//------------------------------------------------------------------- +// End of File diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/eapvpnif.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/eapvpnif.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2000 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project definition file for project EAPOL +* +*/ + + +#include +#include "eapol.mmh" + +CAPABILITY CAP_ECOM_PLUGIN +TARGET eapvpnif.dll +TARGETTYPE PLUGIN + +VENDORID VID_DEFAULT + +// ECom Dll recognition UID followed by the unique UID for this dll +UID 0x10009D8D 0x10200ec9 + +SOURCEPATH ../am/eapvpnif/src +//SOURCE eap_vpn_if_main.cpp +SOURCE eap_vpn_if_proxy.cpp +SOURCE eap_vpn_if_implementation.cpp +SOURCE eap_vpn_if_timer.cpp + +USERINCLUDE ../am/eapvpnif/inc +USERINCLUDE ../../eapol_common/include +USERINCLUDE ../am/include +USERINCLUDE ../../eapol_common/am/include +USERINCLUDE ../../eapol_common/type/aka/include +USERINCLUDE ../../eapol_common/type/gsmsim/include + +USERINCLUDE ../am/type/gsmsim/symbian/plugin/inc +USERINCLUDE ../am/type/aka/symbian/plugin/inc + +SYSTEMINCLUDE /epoc32/include/ecom +SYSTEMINCLUDE /epoc32/include/libc +SYSTEMINCLUDE /epoc32/include/cshelp + +MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers. + +SOURCEPATH ../am/eapvpnif/data +START RESOURCE 10200ec9.rss +TARGET eapvpnif.rsc +END + +LIBRARY euser.lib ECom.lib eapol.lib edbms.lib efsrv.lib PlatformEnv.lib +DEBUGLIBRARY flogger.lib + +// End diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/group/wlaneapolif.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/group/wlaneapolif.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project definition file for project EAPOL +* +*/ + + +#include +#include "eapol.mmh" + +#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_IF) + +CAPABILITY CAP_ECOM_PLUGIN +TARGET wlaneapolif.dll +TARGETTYPE PLUGIN + +VENDORID VID_DEFAULT + +// ECom Dll recognition UID followed by the unique UID for this dll +UID 0x10009D8D 0x2000b05a + +SOURCEPATH ../am/wlaneapolif/src +SOURCE wlan_eapol_if_implementation.cpp + +USERINCLUDE ../am/wlaneapolif/inc +USERINCLUDE .. +USERINCLUDE ../am/type/symbian/plugin/include +USERINCLUDE ../am/common +USERINCLUDE ../../eapol_common/am/common +USERINCLUDE ../am/include +USERINCLUDE ../../eapol_common/am/include +USERINCLUDE ../../eapol_common/include +USERINCLUDE ../../eapol_common/type +USERINCLUDE ../../eapol_common/am/common/DSS_random + +#if defined(USE_EAP_SIMPLE_CONFIG) +USERINCLUDE ../../eapol_common/type/simple_config/simple_config/include +USERINCLUDE ../../eapol_common/type/simple_config/eap/include +#endif // #if defined(USE_EAP_SIMPLE_CONFIG) + +SYSTEMINCLUDE /epoc32/include/ecom +SYSTEMINCLUDE /epoc32/include/libc +SYSTEMINCLUDE /epoc32/include/cshelp + +MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers. + +SOURCEPATH ../am/wlaneapolif/data +START RESOURCE 2000b05a.rss +TARGET wlaneapolif.rsc +END + +LIBRARY euser.lib ECom.lib eapol.lib edbms.lib efsrv.lib +DEBUGLIBRARY flogger.lib + +#else + +TARGETTYPE NONE + +#endif //#if defined(USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_IF) + +// End diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_symbian/rom/eapol.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_symbian/rom/eapol.iby Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Image description file for project EAPOL +* +*/ + + + +#ifndef __EAPOL_IBY__ +#define __EAPOL_IBY__ +#include + +#ifdef __PROTOCOL_WLAN + +/* EAPOL + EAP types */ + +file=ABI_DIR\BUILD_DIR\eapol.dll SHARED_LIB_DIR\Eapol.dll + +// EAP SIM +ECOM_PLUGIN( eapsim.dll,101f8e49.rsc ) + +// EAP AKA +ECOM_PLUGIN( eapaka.dll,102073c1.rsc ) + +// EAP MSCHAPV2 +ECOM_PLUGIN( eapmschapv2.dll,101f8e66.rsc ) + +// EAP TLS PEAP +ECOM_PLUGIN( eaptlspeap.dll,101f8e4c.rsc ) + +// EAP Secure ID +ECOM_PLUGIN( eapsecurid.dll,101f8e74.rsc ) + +#ifdef FF_WLAN_EXTENSIONS +// EAP LEAP +ECOM_PLUGIN( eapleap.dll,101f8ea6.rsc ) +#endif //#ifdef FF_WLAN_EXTENSIONS + +// The VPN interface +ECOM_PLUGIN(eapvpnif.dll, 10200ec9.rsc) + +// The Engine EAPOL interface +ECOM_PLUGIN(wlaneapolif.dll, 2000b05a.rsc) + +// EAP Protected Setup +ECOM_PLUGIN( eapprotectedsetup.dll,2000b003.rsc ) + +// For database policy file (For secured databases of different EAP types and EAPOL.dat) +data=ZPRIVATE\100012A5\policy\102072e9.spd private\100012A5\policy\102072e9.spd + + +// For additional backup registration file for EAPOL. +data=ZPRIVATE\101F8EC5\backup_registration_eapol.xml private\101F8EC5\backup_registration_eapol.xml + +// Copies configuration file of EAPOL. +data=ZPRIVATE\101F8EC5\eap.conf private\101F8EC5\eap.conf + +#endif // __PROTOCOL_WLAN +#endif // #ifndef __EAPOL_IBY__ diff -r 000000000000 -r c8830336c852 eapol/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Build information file for project EAPOL +* +*/ + + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +PRJ_MMPFILES +#include "../eapol_framework/eapol_symbian/group/bld.inf" + +PRJ_TESTMMPFILES + +// End of file. diff -r 000000000000 -r c8830336c852 group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Build information file for all project in eapol subsystem +* +*/ + + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +PRJ_MMPFILES +#include "../wlansecuritysettings/group/bld.inf" +#include "../accesssec_plat/group/bld.inf" +#include "../eapol/group/bld.inf" + +PRJ_TESTMMPFILES \ No newline at end of file diff -r 000000000000 -r c8830336c852 layers.sysdef.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layers.sysdef.xml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,19 @@ + + +]> + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r c8830336c852 package_definition.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/package_definition.xml Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r c8830336c852 sysdef_1_4_0.dtd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysdef_1_4_0.dtd Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Build information file +* +*/ + + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +PRJ_MMPFILES +#include "../wapisecuritysettingsui/stub/group/bld.inf" +#include "../wepsecuritysettingsui/group/bld.inf" +#include "../wifiprotectedsetup/group/bld.inf" +#include "../wlaneapsettingsui/group/bld.inf" +#include "../wpasecuritysettingsui/group/bld.inf" + +PRJ_TESTMMPFILES \ No newline at end of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wapisecuritysettingsui/bwinscw/wapisecuritysettingsuiu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wapisecuritysettingsui/bwinscw/wapisecuritysettingsuiu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,12 @@ +EXPORTS + ?LoadL@CWAPISecuritySettings@@QAEXKAAVCMDBSession@CommsDat@@@Z @ 1 NONAME ; void CWAPISecuritySettings::LoadL(unsigned long, class CommsDat::CMDBSession &) + ?SetPreSharedKeyL@CWAPISecuritySettings@@QAEXW4TWapiKeyFormat@1@ABVTDesC16@@@Z @ 2 NONAME ; void CWAPISecuritySettings::SetPreSharedKeyL(enum CWAPISecuritySettings::TWapiKeyFormat, class TDesC16 const &) + ?EditL@CWAPISecuritySettings@@QAEHAAVCWAPISecuritySettingsUi@@ABVTDesC16@@@Z @ 3 NONAME ; int CWAPISecuritySettings::EditL(class CWAPISecuritySettingsUi &, class TDesC16 const &) + ?SaveL@CWAPISecuritySettings@@QBEXKAAVCMDBSession@CommsDat@@@Z @ 4 NONAME ; void CWAPISecuritySettings::SaveL(unsigned long, class CommsDat::CMDBSession &) const + ?NewL@CWAPISecuritySettings@@SAPAV1@XZ @ 5 NONAME ; class CWAPISecuritySettings * CWAPISecuritySettings::NewL(void) + ??1CWAPISecuritySettings@@UAE@XZ @ 6 NONAME ; CWAPISecuritySettings::~CWAPISecuritySettings(void) + ??1CWAPISecuritySettingsUi@@UAE@XZ @ 7 NONAME ; CWAPISecuritySettingsUi::~CWAPISecuritySettingsUi(void) + ?NewL@CWAPISecuritySettingsUi@@SAPAV1@AAVCEikonEnv@@@Z @ 8 NONAME ; class CWAPISecuritySettingsUi * CWAPISecuritySettingsUi::NewL(class CEikonEnv &) + ?DeleteAPSpecificDataL@CWAPISecuritySettings@@QAEXH@Z @ 9 NONAME ; void CWAPISecuritySettings::DeleteAPSpecificDataL(int) + ?IsValid@CWAPISecuritySettings@@QBEHXZ @ 10 NONAME ; int CWAPISecuritySettings::IsValid(void) const + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wapisecuritysettingsui/eabi/wapisecuritysettingsuiu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wapisecuritysettingsui/eabi/wapisecuritysettingsuiu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,16 @@ +EXPORTS + _ZN21CWAPISecuritySettings16SetPreSharedKeyLENS_14TWapiKeyFormatERK7TDesC16 @ 1 NONAME + _ZN21CWAPISecuritySettings21DeleteAPSpecificDataLEi @ 2 NONAME + _ZN21CWAPISecuritySettings4NewLEv @ 3 NONAME + _ZN21CWAPISecuritySettings5EditLER23CWAPISecuritySettingsUiRK7TDesC16 @ 4 NONAME + _ZN21CWAPISecuritySettings5LoadLEmRN8CommsDat11CMDBSessionE @ 5 NONAME + _ZN21CWAPISecuritySettingsD0Ev @ 6 NONAME + _ZN21CWAPISecuritySettingsD1Ev @ 7 NONAME + _ZN21CWAPISecuritySettingsD2Ev @ 8 NONAME + _ZN23CWAPISecuritySettingsUi4NewLER9CEikonEnv @ 9 NONAME + _ZN23CWAPISecuritySettingsUiD0Ev @ 10 NONAME + _ZN23CWAPISecuritySettingsUiD1Ev @ 11 NONAME + _ZN23CWAPISecuritySettingsUiD2Ev @ 12 NONAME + _ZNK21CWAPISecuritySettings5SaveLEmRN8CommsDat11CMDBSessionE @ 13 NONAME + _ZNK21CWAPISecuritySettings7IsValidEv @ 14 NONAME + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wapisecuritysettingsui/rom/wapisecuritysettingsui.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wapisecuritysettingsui/rom/wapisecuritysettingsui.iby Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Image description file for project wapisecuritysettingsui +* +*/ + + + +#ifndef __WAPISECURITYSETTINGSUI_IBY__ +#define __WAPISECURITYSETTINGSUI_IBY__ + +#ifndef FF_WLAN_WAPI_INCLUDE_IN_ROM +// Use stub implementation +FILE=ABI_DIR\BUILD_DIR\wapisecuritysettingsui.dll SHARED_LIB_DIR\wapisecuritysettingsui.dll +#else +// Use real implementation +FILE=ABI_DIR\BUILD_DIR\realwapisecuritysettingsui.dll SHARED_LIB_DIR\wapisecuritysettingsui.dll +#endif // FF_WLAN_WAPI_INCLUDE_IN_ROM + +#endif // #ifndef __WAPISECURITYSETTINGSUI_IBY__ diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wapisecuritysettingsui/rom/wapisecuritysettingsuiresources.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wapisecuritysettingsui/rom/wapisecuritysettingsuiresources.iby Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Image description file for project wapisecuritysettingsui +* +*/ + + + +#ifndef __WAPISECURITYSETTINGSUIRESOURCES_IBY__ +#define __WAPISECURITYSETTINGSUIRESOURCES_IBY__ + +DATA=DATAZ_\RESOURCE_FILES_DIR\wapisecuritysettingsui.rsc RESOURCE_FILES_DIR\wapisecuritysettingsui.rsc + +#endif \ No newline at end of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wapisecuritysettingsui/stub/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wapisecuritysettingsui/stub/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This file provides the information required for building the wapisecuritysettings stub. +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +// export iby files +../../rom/wapisecuritysettingsui.iby CORE_MW_LAYER_IBY_EXPORT_PATH(wapisecuritysettingsui.iby) + +PRJ_MMPFILES +./wapisecuritysettingsstub.mmp + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wapisecuritysettingsui/stub/group/wapisecuritysettingsstub.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wapisecuritysettingsui/stub/group/wapisecuritysettingsstub.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is project specification file for the wapisecuritysettings stub. +* +*/ + + +#include +#include + + +TARGET wapisecuritysettingsui.dll +TARGETTYPE DLL + +CAPABILITY CAP_GENERAL_DLL +VENDORID VID_DEFAULT + +SOURCEPATH ../src + +SOURCE wapisecuritysettingsstub.cpp +SOURCE wapisecuritysettingsuistub.cpp + + +// Component specific internal headers +USERINCLUDE ../../inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE + +//Used libraries +LIBRARY euser.lib + +#if defined( WINSCW ) +DEFFILE ../../bwinscw/wapisecuritysettingsui.def +#else +DEFFILE ../../eabi/wapisecuritysettingsui.def +#endif + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wapisecuritysettingsui/stub/src/wapisecuritysettingsstub.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wapisecuritysettingsui/stub/src/wapisecuritysettingsstub.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,108 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Stub Implementation of class CWAPISecuritySettings. +* +*/ + + +// INCLUDE FILES +#include +#include + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWAPISecuritySettings::NewL +// --------------------------------------------------------- +// +EXPORT_C CWAPISecuritySettings* CWAPISecuritySettings::NewL() + { + User::Leave(KErrNotSupported); + return NULL; + } + + +// --------------------------------------------------------- +// CWAPISecuritySettings::~CWAPISecuritySettings +// --------------------------------------------------------- +// +EXPORT_C CWAPISecuritySettings::~CWAPISecuritySettings() + { + + } + + +// --------------------------------------------------------- +// CWAPISecuritySettings::EditL +// --------------------------------------------------------- +// +EXPORT_C TInt CWAPISecuritySettings::EditL( CWAPISecuritySettingsUi& /* aUi */, + const TDesC& /* aTitle */ ) + { + return 0; + } + + +// --------------------------------------------------------- +// CWAPISecuritySettings::LoadL +// --------------------------------------------------------- +// +EXPORT_C void CWAPISecuritySettings::LoadL( TUint32 /* aIapRecordId */, CMDBSession& /* aSession */) + { + + } + + +// --------------------------------------------------------- +// CWAPISecuritySettings::IsValid +// --------------------------------------------------------- +// +EXPORT_C TBool CWAPISecuritySettings::IsValid( ) const + + { + return EFalse; + } + + +// --------------------------------------------------------- +// CWAPISecuritySettings::SaveL +// --------------------------------------------------------- +// +EXPORT_C void CWAPISecuritySettings::SaveL( TUint32 /* aIapRecordId */, CMDBSession& /* aSession */ ) const + + { + + } + + +// --------------------------------------------------------- +// CWAPISecuritySettings::SetPreSharedKey +// --------------------------------------------------------- +// +EXPORT_C void CWAPISecuritySettings::SetPreSharedKeyL( const TWapiKeyFormat /* aKeyFormat */, const TDesC& /* aPreSharedKey */ ) + { + } + + +// --------------------------------------------------------- +// CWAPISecuritySettings::DeleteAPSpecificDataL +// --------------------------------------------------------- +// +EXPORT_C void CWAPISecuritySettings::DeleteAPSpecificDataL( const TInt /* aId */) + { + + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wapisecuritysettingsui/stub/src/wapisecuritysettingsuistub.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wapisecuritysettingsui/stub/src/wapisecuritysettingsuistub.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Stub implementation of class CWAPISecuritySettingsUi. +* +*/ + + +// INCLUDE FILES +#include +#include + + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWAPISecuritySettingsUi::NewL +// --------------------------------------------------------- +// +EXPORT_C CWAPISecuritySettingsUi* CWAPISecuritySettingsUi::NewL( + CEikonEnv& /* aEikEnv */) + { + User::Leave(KErrNotSupported); + return NULL; + } + + +// --------------------------------------------------------- +// CWAPISecuritySettingsUi::~CWAPISecuritySettingsUi +// --------------------------------------------------------- +// +EXPORT_C CWAPISecuritySettingsUi::~CWAPISecuritySettingsUi() + { + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/Rom/WEPSecuritySettingsUI.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/Rom/WEPSecuritySettingsUI.iby Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Image description file for project WEPSecuritySettingsUI +* +*/ + + + +#ifndef __WEPSECURITYSETTINGSUI_IBY__ +#define __WEPSECURITYSETTINGSUI_IBY__ + + +FILE=ABI_DIR\BUILD_DIR\WEPSecuritySettingsUI.dll SHARED_LIB_DIR\WEPSecuritySettingsUI.dll + + +#endif diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/Rom/WEPSecuritySettingsUIResources.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/Rom/WEPSecuritySettingsUIResources.iby Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Image description file for project WEPSecuritySettingsUI +* +*/ + + + +#ifndef __WEPSECURITYSETTINGSUIRESOURCES_IBY__ +#define __WEPSECURITYSETTINGSUIRESOURCES_IBY__ + + +DATA=DATAZ_\RESOURCE_FILES_DIR\WEPSecuritySettingsUI.rsc RESOURCE_FILES_DIR\WEPSecuritySettingsUI.rsc + + +#endif \ No newline at end of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/bwinscw/WEPSecuritySettingsUI_EKA2_ALRu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/bwinscw/WEPSecuritySettingsUI_EKA2_ALRu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,16 @@ +EXPORTS + ??1CWEPSecuritySettings@@UAE@XZ @ 1 NONAME ; CWEPSecuritySettings::~CWEPSecuritySettings(void) + ??1CWEPSecuritySettingsUi@@UAE@XZ @ 2 NONAME ; CWEPSecuritySettingsUi::~CWEPSecuritySettingsUi(void) + ?Cvt@CWEPSecuritySettingsUi@@SAHXZ @ 3 NONAME ; int CWEPSecuritySettingsUi::Cvt(void) + ?EditL@CWEPSecuritySettings@@QAEHAAVCWEPSecuritySettingsUi@@ABVTDesC16@@@Z @ 4 NONAME ; int CWEPSecuritySettings::EditL(class CWEPSecuritySettingsUi &, class TDesC16 const &) + ?LoadL@CWEPSecuritySettings@@QAEXKAAVCCommsDatabase@@@Z @ 5 NONAME ; void CWEPSecuritySettings::LoadL(unsigned long, class CCommsDatabase &) + ?NewL@CWEPSecuritySettings@@SAPAV1@XZ @ 6 NONAME ; class CWEPSecuritySettings * CWEPSecuritySettings::NewL(void) + ?NewL@CWEPSecuritySettingsUi@@SAPAV1@AAVCEikonEnv@@@Z @ 7 NONAME ; class CWEPSecuritySettingsUi * CWEPSecuritySettingsUi::NewL(class CEikonEnv &) + ?SaveL@CWEPSecuritySettings@@QBEXKAAVCCommsDatabase@@@Z @ 8 NONAME ; void CWEPSecuritySettings::SaveL(unsigned long, class CCommsDatabase &) const + ?IsValid@CWEPSecuritySettings@@QBEHXZ @ 9 NONAME ; int CWEPSecuritySettings::IsValid(void) const + ?SetKeyDataL@CWEPSecuritySettings@@QAEHHABVTDesC16@@H@Z @ 10 NONAME ; int CWEPSecuritySettings::SetKeyDataL(int, class TDesC16 const &, int) + ?LoadL@CWEPSecuritySettings@@QAEXKAAVCMDBSession@CommsDat@@@Z @ 11 NONAME ; void CWEPSecuritySettings::LoadL(unsigned long, class CommsDat::CMDBSession &) + ?SaveL@CWEPSecuritySettings@@QBEXKAAVCMDBSession@CommsDat@@@Z @ 12 NONAME ; void CWEPSecuritySettings::SaveL(unsigned long, class CommsDat::CMDBSession &) const + ?SetAuthentication@CWEPSecuritySettings@@QAEXW4TWEPAuthentication@1@@Z @ 13 NONAME ; void CWEPSecuritySettings::SetAuthentication(enum CWEPSecuritySettings::TWEPAuthentication) + ?SetKeyInUse@CWEPSecuritySettings@@QAEXW4TWEPKeyInUse@1@@Z @ 14 NONAME ; void CWEPSecuritySettings::SetKeyInUse(enum CWEPSecuritySettings::TWEPKeyInUse) + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/data/WEPSecuritySettingsUI.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/data/WEPSecuritySettingsUI.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,387 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This file contains all the resources for the WEP Security Settings UI. +* +*/ + + +// RESOURCE IDENTIFIER +NAME AWSS // 4 letter ID + +// INCLUDES +#include +#include +#include +#include +#include + +#include "WEPSecuritySettingsUI.hrh" +#include + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + +RESOURCE TBUF { buf="WEPSecuritySettings"; } + + +//---------------------------------------------------- +// +// r_wep_security_settings_menubar +// Menubar +// +//---------------------------------------------------- +// +RESOURCE MENU_BAR r_wep_security_settings_menubar + { + titles= + { + MENU_TITLE + { + menu_pane = r_wep_security_settings_menu; + } + }; + } + + + +//---------------------------------------------------- +// +// r_wep_security_settings_menu +// The Options menu +// +//---------------------------------------------------- +// +RESOURCE MENU_PANE r_wep_security_settings_menu + { + items= + { + MENU_ITEM + { + command = EWepSelCmdChange; + txt = qtn_set_options_change; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = EAknCmdHelp; + txt = qtn_options_help; + }, + + MENU_ITEM + { + command = EAknCmdExit; + txt = qtn_options_exit; + } + }; + } + + + +//---------------------------------------------------- +// +// r_wepsettings_pane_softkeys_options_back_edit +// WEP Security Settings softkeys +// +//---------------------------------------------------- +// +RESOURCE CBA r_wepsettings_pane_softkeys_options_back_edit + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EWepSelCmdChange; txt = qtn_msk_change; } + }; + } + + + +//---------------------------------------------------- +// +// r_wepsettings_dialog +// WEP Security Settings main dialog +// +//---------------------------------------------------- +// +RESOURCE DIALOG r_wepsettings_dialog + { + flags = EEikDialogFlagWait | EEikDialogFlagNoDrag | + EEikDialogFlagNoTitleBar | EEikDialogFlagFillAppClientRect | + EEikDialogFlagCbaButtons; + + buttons = r_wepsettings_pane_softkeys_options_back_edit; + + items = + { + DLG_LINE + { + type = EAknCtSettingListBox; + id = KWepMainSettingsListboxId; + control = LISTBOX + { + flags = EAknListBoxSelectionList; + }; + } + }; + } + + + +//---------------------------------------------------- +// +// r_setting_app_edwin_key_data +// Window to enter key data +// +//---------------------------------------------------- +// +RESOURCE EDWIN r_setting_app_edwin_key_data + { + avkon_flags = EAknEditorFlagNoT9 | EAknEditorFlagLatinInputModesOnly; + lines = 8; + } + + +//---------------------------------------------------- +// +// r_text_setting_page_key_data +// Setting page for entering key data +// +//---------------------------------------------------- +// +RESOURCE AVKON_SETTING_PAGE r_text_setting_page_key_data + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + number= EAknSettingPageNoOrdinalDisplayed; + label= qtn_wlan_sett_wep_key_data; + type = EEikCtEdwin; + editor_resource_id = r_setting_app_edwin_key_data; + } + + + +//---------------------------------------------------- +// +// r_setting_app_listbox +// Listbox for setting page +// +//---------------------------------------------------- +// +RESOURCE LISTBOX r_setting_app_listbox + { + flags = EEikListBoxMultipleSelection; + } + + + +//---------------------------------------------------- +// +// r_wepsettings_pane_softkeys_ok_cancel_select +// WEP Security Settings softkeys +// +//---------------------------------------------------- +// +RESOURCE CBA r_wepsettings_pane_softkeys_ok_cancel_select + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOk; txt = text_softkey_ok; }, + CBA_BUTTON { id = EAknSoftkeyCancel; txt = text_softkey_cancel; }, + CBA_BUTTON { id = EAknSoftkeyOk; txt = qtn_msk_select; } + }; + } + + +//---------------------------------------------------- +// +// r_radio_button_setting_page +// Setting page with radio buttons +// +//---------------------------------------------------- +// +RESOURCE AVKON_SETTING_PAGE r_radio_button_setting_page + { + number = EAknSettingPageNoOrdinalDisplayed; + softkey_resource = r_wepsettings_pane_softkeys_ok_cancel_select; + type = EAknSetListBox; + editor_resource_id= r_setting_app_listbox; + } + + + +//---------------------------------------------------- +// +// r_wep_sec_sett_conf_query +// ConfirmationQuery dialog +// +//---------------------------------------------------- +// +RESOURCE DIALOG r_wep_sec_sett_conf_query + { + flags = EGeneralQueryFlags; + buttons = R_AVKON_SOFTKEYS_YES_NO__YES; + items = + { + DLG_LINE + { + type = EAknCtQuery; + id = EGeneralQuery; + control = AVKON_CONFIRMATION_QUERY + { + layout = EConfirmationQueryLayout; + }; + } + }; + } + + + +RESOURCE TBUF r_wep_view_text_cannot_access_db + { + buf = qtn_set_err_db_inaccessible; + } + +RESOURCE TBUF r_wep_key_in_use + { + buf = qtn_wlan_sett_wep_key_in_use; + } + +RESOURCE TBUF r_wep_authentication + { + buf = qtn_wlan_sett_wep_auth_mode; + } + +RESOURCE TBUF r_wep_key_configuration + { + buf = qtn_wlan_sett_wep_key_settings; + } + +RESOURCE TBUF r_wep_key_number_1 + { + buf = qtn_wlan_sett_wep_key_1; + } + +RESOURCE TBUF r_wep_key_number_2 + { + buf = qtn_wlan_sett_wep_key_2; + } + +RESOURCE TBUF r_wep_key_number_3 + { + buf = qtn_wlan_sett_wep_key_3; + } + +RESOURCE TBUF r_wep_key_number_4 + { + buf = qtn_wlan_sett_wep_key_4; + } + +RESOURCE TBUF r_wep_tab_key_1 + { + buf = qtn_wlan_tab_wep_key_1; + } + +RESOURCE TBUF r_wep_tab_key_2 + { + buf = qtn_wlan_tab_wep_key_2; + } + +RESOURCE TBUF r_wep_tab_key_3 + { + buf = qtn_wlan_tab_wep_key_3; + } + +RESOURCE TBUF r_wep_tab_key_4 + { + buf = qtn_wlan_tab_wep_key_4; + } + +RESOURCE TBUF r_wep_authentication_open + { + buf = qtn_wlan_sett_wep_auth_mode_open; + } + +RESOURCE TBUF r_wep_authentication_shared + { + buf = qtn_wlan_sett_wep_auth_mode_shared; + } + +RESOURCE TBUF r_wep_key_length + { + buf = qtn_wlan_sett_wep_key_length; + } + +RESOURCE TBUF r_wep_key_format + { + buf = qtn_wlan_sett_wep_key_format; + } + +RESOURCE TBUF r_wep_key_data + { + buf = qtn_wlan_sett_wep_key_data; + } + +RESOURCE TBUF r_wep_key_length_64_bits + { + buf = qtn_wlan_sett_wep_key_length_64_bits; + } + +RESOURCE TBUF r_wep_key_length_128_bits + { + buf = qtn_wlan_sett_wep_key_length_128_bits; + } + +RESOURCE TBUF r_wep_key_length_256_bits + { + buf = qtn_wlan_sett_wep_key_length_256_bits; + } + +RESOURCE TBUF r_wep_key_format_ascii + { + buf = qtn_wlan_sett_wep_key_format_ascii; + } + +RESOURCE TBUF r_wep_key_format_hex + { + buf = qtn_wlan_sett_wep_key_format_hexa; + } + +RESOURCE TBUF r_wep_key_data_must_be_defined + { + buf = qtn_selec_setting_compulsory; + } + +RESOURCE TBUF r_wep_key_data_stars + { + buf = qtn_wlan_sett_wep_key_format_hexa; + } + +RESOURCE TBUF r_wep_data_missing + { + buf = qtn_wlan_quest_wep_key_data_missing; + } + +RESOURCE TBUF r_info_wep_key_too_short + { + buf = qtn_wlan_info_wep_key_too_short; + } + +RESOURCE TBUF r_info_wep_key_illegal_chars + { + buf = qtn_wlan_info_wep_key_illegal_chars; + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/eabi/WEPSecuritySettingsUI_EKA2_ALRu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/eabi/WEPSecuritySettingsUI_EKA2_ALRu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,20 @@ +EXPORTS + _ZN20CWEPSecuritySettings4NewLEv @ 1 NONAME + _ZN20CWEPSecuritySettings5EditLER22CWEPSecuritySettingsUiRK7TDesC16 @ 2 NONAME + _ZN20CWEPSecuritySettings5LoadLEmR14CCommsDatabase @ 3 NONAME + _ZN20CWEPSecuritySettingsD0Ev @ 4 NONAME + _ZN20CWEPSecuritySettingsD1Ev @ 5 NONAME + _ZN20CWEPSecuritySettingsD2Ev @ 6 NONAME + _ZN22CWEPSecuritySettingsUi3CvtEv @ 7 NONAME + _ZN22CWEPSecuritySettingsUi4NewLER9CEikonEnv @ 8 NONAME + _ZN22CWEPSecuritySettingsUiD0Ev @ 9 NONAME + _ZN22CWEPSecuritySettingsUiD1Ev @ 10 NONAME + _ZN22CWEPSecuritySettingsUiD2Ev @ 11 NONAME + _ZNK20CWEPSecuritySettings5SaveLEmR14CCommsDatabase @ 12 NONAME + _ZNK20CWEPSecuritySettings7IsValidEv @ 13 NONAME + _ZN20CWEPSecuritySettings11SetKeyDataLEiRK7TDesC16i @ 14 NONAME + _ZN20CWEPSecuritySettings5LoadLEmRN8CommsDat11CMDBSessionE @ 15 NONAME + _ZNK20CWEPSecuritySettings5SaveLEmRN8CommsDat11CMDBSessionE @ 16 NONAME + _ZN20CWEPSecuritySettings11SetKeyInUseENS_12TWEPKeyInUseE @ 17 NONAME + _ZN20CWEPSecuritySettings17SetAuthenticationENS_18TWEPAuthenticationE @ 18 NONAME + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/group/WEPSecuritySettingsUI.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/group/WEPSecuritySettingsUI.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is project specification file for the WEPSecuritySettingsUI. +* +*/ + + +#include +#include + + +TARGET WEPSecuritySettingsUI.dll +TARGETTYPE DLL + +CAPABILITY CAP_GENERAL_DLL +VENDORID VID_DEFAULT + + +START RESOURCE ../data/WEPSecuritySettingsUI.rss +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS +END // RESOURCE + + +SOURCEPATH ../src + +SOURCE WEPSecuritySettings.cpp +SOURCE WEPSecuritySettingsImpl.cpp +SOURCE WEPSecuritySettingsUI.cpp +SOURCE WEPSecuritySettingsUiImpl.cpp +SOURCE WEPSecuritySettingsDlg.cpp +SOURCE WepKeyDataTextSettingPage.cpp +SOURCE WEPSecuritySettingsUiPanic.cpp + +// Component specific internal headers +USERINCLUDE ../inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE +APP_LAYER_SYSTEMINCLUDE + +LIBRARY hlplch.lib +LIBRARY euser.lib +LIBRARY cone.lib +LIBRARY eikcore.lib +LIBRARY eikcoctl.lib +LIBRARY avkon.lib +LIBRARY eikdlg.lib +LIBRARY bafl.lib +LIBRARY commonengine.lib +LIBRARY commdb.lib +LIBRARY FeatMgr.lib +LIBRARY commsdat.lib + +DEBUGLIBRARY flogger.lib + +#if defined( WINSCW ) + DEFFILE ../bwinscw/WEPSecuritySettingsUI_EKA2_ALR.def +#else + DEFFILE ../eabi/WEPSecuritySettingsUI_EKA2_ALR.def +#endif + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This file provides the information required for building the whole of a WEPSecuritySettingsUI. +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +// export iby files +../Rom/WEPSecuritySettingsUI.iby CORE_MW_LAYER_IBY_EXPORT_PATH(WEPSecuritySettingsUI.iby) +../Rom/WEPSecuritySettingsUIResources.iby LANGUAGE_MW_LAYER_IBY_EXPORT_PATH(WEPSecuritySettingsUIResources.iby) + +// export localised loc file +../loc/wepsecuritysettingsui.loc MW_LAYER_LOC_EXPORT_PATH(wepsecuritysettingsui.loc) + + +PRJ_MMPFILES +./WEPSecuritySettingsUI.mmp + + +PRJ_TESTMMPFILES + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/inc/SecuritySettingsLogger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/inc/SecuritySettingsLogger.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,152 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Logger utility. +* +*/ + + +#ifndef SECURITYSETTINGSLOGGER_H +#define SECURITYSETTINGSLOGGER_H + + +// INCLUDES + +#include +#include +#include + + +#ifdef _DEBUG +#define __SEC_SETT_LOG__ +#endif // _DEBUG + + +#ifdef __SEC_SETT_LOG__ + +// CONSTANTS + +// SecuritySettingsLogger logging directory. +_LIT( KSecSettLogDir, "TestSecSett" ); +// SecSett log file name. +_LIT( KSecSettLogFile, "SecSett.log" ); +// Format string: enter function. +_LIT( KSecSettLogEnterFn, "-> %S" ); +// Format string: leave function. +_LIT( KSecSettLogLeaveFn, "<- %S" ); +// Format string: time. +_LIT( KSecSettLogTimeFormatString, "%H:%T:%S:%*C2" ); +// Format string: timestamp. +_LIT( KSecSettLogTimeStampFormatString, "%S %S" ); + +// DEFINES + +// Write log: enter function. +#define CLOG_ENTERFN( a ) \ + { \ + _LIT( temp, a ); \ + RFileLogger::WriteFormat \ + ( \ + KSecSettLogDir, \ + KSecSettLogFile, \ + EFileLoggingModeAppend, \ + KSecSettLogEnterFn, \ + &temp \ + ); \ + } + +// Write log: leave function. +#define CLOG_LEAVEFN( a ) \ + { \ + _LIT( temp, a ); \ + RFileLogger::WriteFormat \ + ( \ + KSecSettLogDir, \ + KSecSettLogFile, \ + EFileLoggingModeAppend, \ + KSecSettLogLeaveFn, \ + &temp \ + ); \ + } + +// Write log: string 'a'. +#define CLOG_WRITE( a ) \ + { \ + _LIT( temp, a ); \ + RFileLogger::Write \ + ( \ + KSecSettLogDir, \ + KSecSettLogFile, \ + EFileLoggingModeAppend, \ + temp \ + ); \ + } + +// Write log: formatted. +#define CLOG_WRITE_FORMAT( a, b ) \ + { \ + _LIT( temp, a ); \ + RFileLogger::WriteFormat \ + ( \ + KSecSettLogDir, \ + KSecSettLogFile, \ + EFileLoggingModeAppend, \ + temp, \ + b \ + ); \ + } + +// Write log: timestamp. +#define CLOG_WRITE_TIMESTAMP( a ) \ + { \ + _LIT( temp, a ); \ + TTime time; \ + time.HomeTime(); \ + TBuf<32> timeBuf; \ + TRAPD( err, time.FormatL( timeBuf, KSecSettLogTimeFormatString ) ); \ + if ( !err ) \ + { \ + RFileLogger::WriteFormat \ + ( \ + KSecSettLogDir, \ + KSecSettLogFile, \ + EFileLoggingModeAppend, \ + KSecSettLogTimeStampFormatString, \ + &temp, \ + &timeBuf \ + ); \ + } \ + } + +#else // not defined __SEC_SETT_LOG__ + +// DEFINES + +// Empty definition (disable log). +#define CLOG_ENTERFN( a ) + +// Empty definition (disable log). +#define CLOG_LEAVEFN( a ) + +// Empty definition (disable log). +#define CLOG_WRITE( a ) + +// Empty definition (disable log). +#define CLOG_WRITE_FORMAT( a, b ) + +// Empty definition (disable log). +#define CLOG_WRITE_TIMESTAMP( a ) + +#endif // __SEC_SETT_LOG__ + +#endif diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsDlg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsDlg.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,315 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declares dialog. +* +*/ + + +#ifndef WEP_SECURITY_SETTINGS_DLG_H +#define WEP_SECURITY_SETTINGS_DLG_H + + +// INCLUDES +#include +#include +#include +#include +#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#else +#include +#include +#endif + +#include "WepSecuritySettingsDefs.h" + + +// FORWARD DECLARATIONS +class CAknTitlePane; +class CAknNavigationControlContainer; +class CAknNavigationDecorator; +class CAknTabGroup; + + +// CLASS DECLARATION +/** +* CWEPSecuritySettingsDlg dialog class +*/ +NONSHARABLE_CLASS( CWEPSecuritySettingsDlg ) : public CAknDialog, + public MEikListBoxObserver, + public MAknTabObserver + { + + public: // Constructors and destructor + + /** + * Create and launch dialog. + * @param aSecuritySettings Security settings + * @param aTitle Title of the dialog + * @return The ID of the button that closed the dialog + */ + TInt ConstructAndRunLD( CWEPSecuritySettingsImpl* aSecuritySettings, + const TDesC& aTitle ); + + + /** + * Two-phase construction. + * @param aEventStore A reference to hold the events happened + * @return The constructed CWEPSecuritySettingsDlg object. + */ + static CWEPSecuritySettingsDlg* NewL( TInt& aEventStore ); + + + /** + * Destructor. + */ + ~CWEPSecuritySettingsDlg(); + + + protected: + /** + * Constructor. + * @param aEventStore A reference to hold the events happened + */ + CWEPSecuritySettingsDlg( TInt& aEventStore ); + + + public: // Functions from base classes + /** + * Handle key events. + * @param aKeyEvent: key event + * @param aType: type of event + * @return The key response, if it was consumed or not. + */ + TKeyResponse OfferKeyEventL( const TKeyEvent& aKeyEvent, + TEventCode aType ); + + + public: // From MAknTabObserver + + /** + * Called when a key is tab change happens. + * @param aIndex index of the new tab + */ + void TabChangedL( TInt aIndex ); + + + private: + + /** + * This function is called by the dialog framework before the dialog is + * sized and laid out. + */ + virtual void PreLayoutDynInitL(); + + + /** + * Handles a dialog button press for the specified button + * @param aButtonId The ID of the button that was activated. + * @return ETrue to validate and exit the dialog, + * EFalse to keep the dialog active + */ + TBool OkToExitL( TInt aButtonId ); + + + /** + * Processes user commands. + * @param aCommandId ID of the command to respond to. + */ + virtual void ProcessCommandL( TInt aCommandId ); + + + /** + * Handles list box events. + * @param aListBox The originating list box. + * @param aEventType A code for the event. + */ + void HandleListBoxEventL( CEikListBox* aListBox, + TListBoxEvent aEventType ); + + /** + * Get help context. + * @param aContext Help context is returned here. + */ + void GetHelpContext( TCoeHelpContext& aContext ) const; + + /** + * Initialize menu pane. + * @param aResourceId Menu pane resource id. + * @param CEikMenuPane Menu pane. + */ + void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ); + + + protected: // New functions + + /** + * Handles listbox data change + */ + void HandleListboxDataChangeL(); + + + /** + * Fills up the listbox with data + * @param aItemArray Array where to add the elements + * @param arr Array to be used as list elements + * @param aLength The number of elements in the above array + * @param aRes Array of resource IDs to be used for the + * elements of arr + */ + void FillListWithDataL( CDesCArrayFlat& aItemArray, + const CWEPSecuritySettings::TWepMember& arr, + TInt aLength, + const TInt* aRes ); + + + /** + * Updates one listbox item for the given member + * @param aMember Value specifying which member has to be added to + * the list + * @param aRes Resource ID for the 'title text' for this member + * @param aPos The current position of the item in the list + */ + void UpdateListBoxItemL( CWEPSecuritySettings::TWepMember aMember, + TInt aRes, TInt aPos ); + + + /** + * Creates one 'textual' listbox item for the given member + * @param aMember Value specifying which member has to be added to + * the list + * @param aRes Resource ID for the 'title text' for this member + * @return The created listbox item text. + */ + HBufC* CreateTextualListBoxItemL( CWEPSecuritySettings::TWepMember aMember, + TInt aRes ); + + + /** + * Changes one setting. The setting, which is + * highlighted as current in the listbox is changed. + * @param aQuick ETrue if the setting is "two-choices", and can be + * automatically changed, without showing the list of + * elements + */ + void ChangeSettingsL( TBool aQuick ); + + + /** + * Shows a popup setting page (radio buttons) for the given member + * @param aDataMember The member which needs to be changed + * @return A boolean indicating whether the current setting + * has been changed or not. + */ + TBool ShowPopupSettingPageL( + CWEPSecuritySettings::TWepMember aDataMember ); + + + /** + * Shows a popup text setting page for the given member + * @return A boolean indicating whether the current setting + * has been changed or not. + */ + TBool ShowPopupTextSettingPageL(); + + + /** + * Fills up a pop-up radio button setting page with the currently + * valid and available choices for the given member. + * @param aData The member whose new setting is needed + * @param aCurrvalue The current value of the setting + * @return An array of choices for the given member, pushed to the + * CleanupStack. + */ + CDesCArrayFlat* FillPopupSettingPageLC( + CWEPSecuritySettings::TWepMember aData, + TInt& aCurrvalue ); + + + /** + * Updates the given member's data with the new setting from the setting + * page. + * @param aData The member to update + * @param aCurrvalue The new value + * @return A boolean indicating if the value is actually changed + */ + TBool UpdateFromPopupSettingPage( CWEPSecuritySettings::TWepMember aData, + TInt aCurrvalue ); + + + /** + * Inverts one boolean member + * @param aDataMember the member to invert. + */ + void InvertSettings( CWEPSecuritySettings::TWepMember aDataMember ); + + + private: //data + + // Stores the name of the connection, to be showed as the title. + TBuf iConnectionName; + + // Title pane. Not owned. + CAknTitlePane* iTitlePane; + + // Pointer to the old title. Owned. + HBufC* iOldTitleText; + + // Empty Navigation decorator. Owned. + CAknNavigationDecorator* iNaviDecoratorEmpty; + + // Tabbed Navigation decorator. Owned. + CAknNavigationDecorator* iNaviDecoratorTabbed; + + // Navi Pane. Not owned. + CAknNavigationControlContainer* iNaviPane; + + // Tab Group. Not owned. + CAknTabGroup* iTabGroup; + + // Index of the active tab + TInt iActiveTab; + + // Owned through resources, destroyed automatically by the dialog. + CAknSettingStyleListBox* iList; + + // Array of the items. Not owned. + CDesCArrayFlat* iItemArray; + + // Fields of the main view. Not owned. + CWEPSecuritySettings::TWepMember* iFieldsMain; + + // Titles of the main view. Not owned. + TInt* iTitlesMain; + + // Fields of the key configuration view. Not owned. + CWEPSecuritySettings::TWepMember* iFieldsKeyConfiguration; + + // Titles of the key configuration view. Not owned. + TInt* iTitlesKeyConfiguration; + + // Pointer to the WEP Security Settings. Not owned. + CWEPSecuritySettingsImpl* iSecuritySettings; + + // current level (main or key configuration) + TInt iLevel; + + // To hold the events. Not owned. + TInt* iEventStore; + }; + + +#endif // WEP_SECURITY_SETTINGS_DLG_H + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsImpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsImpl.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,266 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of class CWEPSecuritySettingsImpl. +* +*/ + + +#ifndef WEPSECURITYSETTINGSIMPL_H +#define WEPSECURITYSETTINGSIMPL_H + +// INCLUDES +#include + +#include +#include "WepSecuritySettingsDefs.h" + +#include +using namespace CommsDat; + +// FORWARD DECLARATIONS + +class CCommsDatabase; + + +// CLASS DECLARATION + +/** +* WEP Security Settings. +* Implementation behind proxy class CWEPSecuritySettings. +*/ +NONSHARABLE_CLASS( CWEPSecuritySettingsImpl ) : public CBase + { + + public: // Constructors and destructor + + /** + * Two-phased constructor. Leaves on failure. + * @return The constructed CWEPSecuritySettings object. + */ + static CWEPSecuritySettingsImpl* NewL(); + + /** + * Destructor. + */ + virtual ~CWEPSecuritySettingsImpl(); + + protected: // Constructors + + /** + * Constructor. + * @param aEikEnv Eikon environment. + */ + CWEPSecuritySettingsImpl(); + + /** + * Second-phase constructor. + */ + void ConstructL(); + + public: // New methods + + /** + * Load from database. + * @param aIapId Wlan Service Table Id of the IAP to be loaded + * @param aCommsDb Comms database. + */ + void LoadL( TUint32 aIapId, CCommsDatabase& aCommsDb ); + + /** + * Save to database. + * @param aIapId Wlan Service Table Id of the IAP to be saved + * @param aCommsDb Comms database. + */ + void SaveL( TUint32 aIapId, CCommsDatabase& aCommsDb ) const; + + /** + * Tells if the settings are valid and can be saved + * @return ETrue if all the compulsory settings have been entered + */ + TBool IsValid(); + + + /** + * Sets the new data of the key + * @param aElement Index of the element whose data has to be set. + * @param aKeyData The new value for data of the key. + * @param aHex ETrue if data is in Ascii format + */ + TInt SetKeyDataL( const TInt aElement, const TDesC& aKeyData, + const TBool aHex ); + + + /** + * Calculates expected length of hex string of keyData on the base of + * the selected key length. + * @param aKeyLength Chosen key length + * @return Expected length + */ + TInt ExpectedLengthOfKeyData( CWEPSecuritySettings::TWEPKeyLength + aKeyLength ); + + + /** + * Gets Key currently in use + * @return The key in use. + */ + inline CWEPSecuritySettings::TWEPKeyInUse KeyInUse () const; + + /** + * Sets Key currently in use + * @param aKeyInUse The new value for key in use. + */ + inline void SetKeyInUse ( const CWEPSecuritySettings::TWEPKeyInUse + aKeyInUse ); + + + /** + * Gets type of Authentication + * @return The type of Authentication. + */ + inline CWEPSecuritySettings::TWEPAuthentication Authentication () const; + + /** + * Sets type of Authentication + * @param aAuthentication The new value for type of Authentication. + */ + inline void SetAuthentication( + const CWEPSecuritySettings::TWEPAuthentication aAuthentication ); + + + /** + * Gets the length of the key + * @param aElement Index of the element whose length has to be + * retrieved. + * @return The length of the key + */ + inline CWEPSecuritySettings::TWEPKeyLength KeyLength ( + const TInt aElement ) const; + + /** + * Sets the length of the key + * @param aElement Index of the element whose length has to be set. + * @param aKeyLength The new value for length of the key. + */ + inline void SetKeyLength( const TInt aElement, + const CWEPSecuritySettings::TWEPKeyLength aKeyLength ); + + + /** + * Gets the format of the key + * @param aElement Index of the element whose format has to be + * retrieved. + * @return The format of the key + */ + inline CWEPSecuritySettings::TWEPKeyFormat KeyFormat( + const TInt aElement ) const; + + /** + * Sets the format of the key + * @param aElement Index of the element whose format has to be set. + * @param aKeyLength The new value for format of the key. + */ + inline void SetKeyFormat( const TInt aElement, + const CWEPSecuritySettings::TWEPKeyFormat aKeyFormat ); + + + /** + * Gets the key data + * @param aElement Index of the element whose keyData has to be + * retrieved. + * @return The data of the key + */ + inline TDes8* KeyData( const TInt aElement ); + + /** + * Sets the new data of the key + * @param aElement Index of the element whose data has to be set. + * @param aKeyLength The new value for data of the key. + */ + inline void SetKeyData( const TInt aElement, const TDesC8& aKeyData ); + + /** + * Tells if the Wep256 feature is enabled or not + * @return ETrue if the flag is enabled + */ + inline TBool WEP256Enabled() const; + + /** + * Verify if the entered keyData is valid + * @param aTextToTest The text to be verified + * @param aLengthOfKeyData The expected length of the keyData + * @param aWEPKeyFormat The format chosen to enter the keyData + * @return KErrNone if the text is valid, or error code if not. + */ + TInt VerifyKeyData( const TDesC8& aTextToTest, TInt aLengthOfKeyData, + CWEPSecuritySettings::TWEPKeyFormat aWEPKeyFormat ); + + /** + * Converts keyData enetered in Ascii format to hex format + * @param aSource Source string + * @param aDest destination string + */ + void ConvertAsciiToHex( const TDesC8& aSource, HBufC8*& aDest ); + + /** + * Load from database. + * @param aIapId Wlan Service Table Id of the IAP to be loaded + * @param aSession CommsDat session. + */ + void LoadL( TUint32 aIapId, CMDBSession& aSession ); + + /** + * Save to database. + * @param aIapId Wlan Service Table Id of the IAP to be saved + * @param aSession CommsDat session. + */ + void SaveL( TUint32 aIapId, CMDBSession& aSession ) const; + + + private: + + /** + * Sets keyLength parsing data contained in iKeyData + * @param aIndex Index of the element whose length has to be calculated. + */ + void SetLenKeyDataFromText( const TInt aIndex ); + + + private: // Data + + // Index of the key currently in use (EKeyNumber1, EKeyNumber2, + // EKeyNumber3, EKeyNumber4 + CWEPSecuritySettings::TWEPKeyInUse iKeyInUse; + + // Type of authentication (EAuthOpen, EAuthShared) + CWEPSecuritySettings::TWEPAuthentication iAuthentication; + + // Length of the key (E40Bits, E104Bits, E232Bits) + CWEPSecuritySettings::TWEPKeyLength iKeyLength[KMaxNumberofKeys]; + + // Format of the key (EAscii, EHexadecimal) + CWEPSecuritySettings::TWEPKeyFormat iKeyFormat[KMaxNumberofKeys]; + + // Data of the key + TBuf8 iKeyData[KMaxNumberofKeys]; + + // Tells if the Wep256 feature is enabled + TBool iIsWEP256Enabled; + }; + +// Include inline functions +#include "WEPSecuritySettingsImpl.inl" + + +#endif diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsImpl.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsImpl.inl Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,146 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: CWEPSecuritySettingsImpl inline functions +* +*/ + + + +#ifndef WEPSECURITYSETTINGSIMPL_INL +#define WEPSECURITYSETTINGSIMPL_INL + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::KeyInUse +// --------------------------------------------------------- +// +inline CWEPSecuritySettings::TWEPKeyInUse + CWEPSecuritySettingsImpl::KeyInUse() const + { + return iKeyInUse; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::Authentication +// --------------------------------------------------------- +// +inline CWEPSecuritySettings::TWEPAuthentication + CWEPSecuritySettingsImpl::Authentication() const + { + return iAuthentication; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::KeyLength +// --------------------------------------------------------- +// +inline CWEPSecuritySettings::TWEPKeyLength + CWEPSecuritySettingsImpl::KeyLength( const TInt aElement ) const + { + return iKeyLength[aElement]; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::KeyFormat +// --------------------------------------------------------- +// +inline CWEPSecuritySettings::TWEPKeyFormat + CWEPSecuritySettingsImpl::KeyFormat( const TInt aElement ) const + { + return iKeyFormat[aElement]; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::KeyData +// --------------------------------------------------------- +// +inline TDes8* CWEPSecuritySettingsImpl::KeyData( const TInt aElement ) + { + return &iKeyData[aElement]; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::SetKeyInUse +// --------------------------------------------------------- +// +inline void CWEPSecuritySettingsImpl::SetKeyInUse( + const CWEPSecuritySettings::TWEPKeyInUse aKeyInUse ) + { + iKeyInUse = aKeyInUse; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::SetAuthentication +// --------------------------------------------------------- +// +inline void CWEPSecuritySettingsImpl::SetAuthentication( + const CWEPSecuritySettings::TWEPAuthentication aAuthentication ) + { + iAuthentication = aAuthentication; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::SetKeyLength +// --------------------------------------------------------- +// +inline void CWEPSecuritySettingsImpl::SetKeyLength( const TInt aElement, + const CWEPSecuritySettings::TWEPKeyLength aKeyLength ) + { + iKeyLength[aElement] = aKeyLength; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::SetKeyFormat +// --------------------------------------------------------- +// +inline void CWEPSecuritySettingsImpl::SetKeyFormat( const TInt aElement, + const CWEPSecuritySettings::TWEPKeyFormat aKeyFormat ) + { + iKeyFormat[aElement] = aKeyFormat; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::SetKeyData +// --------------------------------------------------------- +// +inline void CWEPSecuritySettingsImpl::SetKeyData( const TInt aElement, + const TDesC8& aKeyData ) + { + iKeyData[aElement] = aKeyData; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::WEP256Enabled +// --------------------------------------------------------- +// +inline TBool CWEPSecuritySettingsImpl::WEP256Enabled() const + { + // WEP256 is deprecated. + return EFalse; + } + + +#endif + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsUI.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsUI.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This file contains declarations for resources of WEPSecuritySettingsUI. The file can be included in C++ or resource file. +* +*/ + + +#ifndef WEPSecuritySettingsUI_HRH +#define WEPSecuritySettingsUI_HRH + + +// Menu command IDs +enum TWepSelectorMenuCommands + { + EWepSelCmdChange = 1357 + }; + + +// dialog line IDs +enum TWepSelectorDllDlgLineId + { + KWepMainSettingsListboxId = 3 + }; + + +// IDs of the tabs +enum TWepTabId + { + EWEPSecuritySettingsTab1 = 1, + EWEPSecuritySettingsTab2, + EWEPSecuritySettingsTab3, + EWEPSecuritySettingsTab4 + }; + + +#endif // WEPSecuritySettingsUI_HRH + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsUiImpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsUiImpl.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of class CWEPSecuritySettingsUiImpl. +* +*/ + + +#ifndef WEPSECURITYSETTINGSUIIMPL_H +#define WEPSECURITYSETTINGSUIIMPL_H + +// INCLUDES + +#include + + +// FORWARD DECLARATIONS + +class CEikonEnv; +class CWEPSecuritySettings; +class CWEPSecuritySettingsUiImpl; +class CWEPSecuritySettingsImpl; + + +// CLASS DECLARATION + +/** +* WEP Security Settings UI implementation (behind proxy class +* CWEPSecuritySettingsUi) +*/ +NONSHARABLE_CLASS( CWEPSecuritySettingsUiImpl ) : public CBase + { + + public: // Constructors and destructor + + /** + * Two-phased constructor. Leaves on failure. + * @param aEikEnv Eikon environment. + * @return The constructed CWEPSecuritySettingsUiImpl object. + */ + static CWEPSecuritySettingsUiImpl* NewL( CEikonEnv& aEikEnv ); + + /** + * Destructor. + */ + virtual ~CWEPSecuritySettingsUiImpl(); + + protected: // Constructors + + /** + * Constructor. + * @param aEikEnv Eikon environment. + */ + CWEPSecuritySettingsUiImpl( CEikonEnv& aEikEnv ); + + /** + * Second-phase constructor. + */ + void ConstructL(); + + public: // New methods + + /** + * Edit the settings. + * @param aSettings Settings to edit. + * @param aTitle Title Pane text to display during edit. + * @return Exit code. Value from CWEPSecuritySettings::TEvent bits + * combined. + */ + TInt EditL( CWEPSecuritySettingsImpl& aSettings, const TDesC& aTitle ); + + + private: // Data + + // To hold the events + TInt iEventStore; + + // Resource file offset. + TInt iResOffset; + + // Eikon environment. Not owned. + CEikonEnv* iEikEnv; + }; + +#endif diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsUiPanic.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/inc/WEPSecuritySettingsUiPanic.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Panic function and codes. +* +*/ + + +#ifndef WEPSECURITYSETTINGSUIPANIC_H +#define WEPSECURITYSETTINGSUIPANIC_H + +// TYPES + +/** +* Panic reasons for WEP Security Settings UI. +*/ +enum TWepSecuritySettingsPanicCodes + { + EUnknownCase, + ETableNotFound + }; + + +// FUNCTION DECLARATIONS + +/** +* Panic the thread. +* @param aReason Reason for the panic. +*/ +void Panic( TWepSecuritySettingsPanicCodes aPanic ); + +#endif diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/inc/WepKeyDataTextSettingPage.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/inc/WepKeyDataTextSettingPage.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of class CWEPKeyDataTextSettingPage. +* +*/ + + +#ifndef WEPKEYDATA_TEXT_SETTING_PAGE_H +#define WEPKEYDATA_TEXT_SETTING_PAGE_H + + +// INCLUDE FILES +#include +#include +#include "WepSecuritySettingsDefs.h" + + +// CLASS DECLARATION + +/* +* Setting page for KeyData text. Overrides standard CAknTextSettingPage +* to set some parameters at runtime, according to the KeyFormat +*/ +NONSHARABLE_CLASS( CWEPKeyDataTextSettingPage ) : public CAknTextSettingPage + { + public: // Constructors + + /** + * Constructor. + * @param aText Reference to text for editing + * @param aMaxLength Number of characters to be entered + * @param aWEPKeyFormat Format of data (EAscii or EHexadecimal) + */ + CWEPKeyDataTextSettingPage( TDes& aText, TInt aMaxLength, + CWEPSecuritySettings::TWEPKeyFormat aWEPKeyFormat ); + + /** + * Constructs the setting page. Called by ExecuteLD + */ + virtual void ConstructL(); + + private: + + // Number of characters to be entered + TInt iLengthOfKeyData; + + // Format of data (EAscii or EHexadecimal) + CWEPSecuritySettings::TWEPKeyFormat iWEPKeyFormat; + }; + + +#endif + +// End of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/inc/WepSecuritySettingsDefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/inc/WepSecuritySettingsDefs.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Definitions. +* +*/ + + +#ifndef WEPSECURITYSETTINGSDEFS_H +#define WEPSECURITYSETTINGSDEFS_H + + +// CONSTANTS + +// Empty key +LOCAL_D const TUint KKeyDataLengthEmpty = 0; + +// Number of characters for a 40 bits key +LOCAL_D const TUint KKeyDataLength40Bits = 10; + +// Number of characters for a 104 bits key +LOCAL_D const TUint KKeyDataLength104Bits = 26; + +// Number of characters for a 232 bits key +LOCAL_D const TUint KKeyDataLength232Bits = 58; + +// The maximum length of key data +LOCAL_D const TUint KMaxLengthOfKeyData = KKeyDataLength232Bits; + +// Number of keys +LOCAL_D const TUint KMaxNumberofKeys = 4; + +// Invalid id +LOCAL_D const TUint32 KUidNone = 0; + + +// UID of application containing help texts (General Settings). +LOCAL_D const TUid KWEPSecuritySettingsUiHelpMajor = { 0x100058EC }; + +// Error code for invalid length of key data +LOCAL_D const TInt KErrInvalidLength = 101; + +// Error code for key data containing invalid characters +LOCAL_D const TInt KErrInvalidChar = 102; + + +#endif // WEPSECURITYSETTINGSDEFS_H diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/loc/wepsecuritysettingsui.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/loc/wepsecuritysettingsui.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,246 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is a localisation file for WEPSecuritySettingsUI A .loc file is the one and only place where the logical strings to be localised are defined. +* +*/ + + + +// LOCALISATION STRINGS + + +//d:Command in options menu. +//d:Exits WEP Security Settings. +//l:list_single_pane_t1_cp2 +//w: +//r:3.0 +// +#define qtn_set_options_exit "Exit" + + +//d:Command in options menu. +//d:Modifies the currently selected item. +//l:list_single_pane_t1_cp2 +//w: +//r:3.0 +// +#define qtn_set_options_change "Change" + + +//d:Name of the first tab of four +//l:tabs_4_active_pane_t1/opt1 +//w: +//r:3.0 +// +#define qtn_wlan_tab_wep_key_1 "#1" + + +//d:Name of the second tab of four +//l:tabs_4_active_pane_t1/opt1 +//w: +//r:3.0 +// +#define qtn_wlan_tab_wep_key_2 "#2" + + +//d:Name of the third tab of four +//l:tabs_4_active_pane_t1/opt1 +//w: +//r:3.0 +// +#define qtn_wlan_tab_wep_key_3 "#3" + + +//d:Name of the fourth tab of four +//l:tabs_4_active_pane_t1/opt1 +//w: +//r:3.0 +// +#define qtn_wlan_tab_wep_key_4 "#4" + + +//d:Error note message: database is inaccessible. +//l:popup_note_window +//w: +//r:3.0 +// +#define qtn_set_err_db_inaccessible "Cannot access\ndatabase.\nTry again later." + + +//d:Item text in setting list. +//l:list_setting_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_in_use "WEP key in use" + + +//d:Item text in setting list. +//l:list_setting_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_auth_mode "Authentication type" + + +//d:Item text in setting list. +//l:list_setting_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_settings "WEP key settings" + + +//d:Item text in setting list. +//l:list_setting_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_length "WEP key length" + + +//d:Item text in setting list. +//l:list_setting_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_format "WEP key format" + + +//d:Item text in setting list. +//l:list_setting_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_data "WEP key data" + + +//d:List pane for the setting value item list qtn_wlan_sett_wep_key_in_use +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_1 "#1" + + +//d:List pane for the setting value item list qtn_wlan_sett_wep_key_in_use +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_2 "#2" + + +//d:List pane for the setting value item list qtn_wlan_sett_wep_key_in_use +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_3 "#3" + + +//d:List pane for the setting value item list qtn_wlan_sett_wep_key_in_use +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_4 "#4" + + +//d:List pane for the setting value item list qtn_wlan_sett_wep_auth_mode +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_auth_mode_open "Open" + + +//d:List pane for the setting value item list qtn_wlan_sett_wep_auth_mode +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_auth_mode_shared "Shared" + + +//d:List pane for the setting value item list qtn_wlan_sett_wep_key_length +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_length_64_bits "64 bits" + + +//d:List pane for the setting value item list qtn_wlan_sett_wep_key_length +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_length_128_bits "128 bits" + + +//d:List pane for the setting value item list qtn_wlan_sett_wep_key_length +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_length_256_bits "256 bits" + + +//d:List pane for the setting value item list qtn_wlan_sett_wep_key_format +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_format_ascii "ASCII" + + +//d:List pane for the setting value item list qtn_wlan_sett_wep_key_format +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wep_key_format_hexa "Hexadecimal" + + +//d:Confirmation query text to ask the user if he wants to continue even if +//d:qtn_wlan_sett_wep_key_data was not entered and therefore security settings +//d:will not be saved. +//l:popup_note_window +//w: +//r:3.0 +// +#define qtn_wlan_quest_wep_key_data_missing "WEP key data for the key in use is compulsory. Security settings will not be saved. Continue?" + + +//d:Error note to be showed when invalid number of characters have been +//d:entered for qtn_wlan_sett_wep_key_data editor. +//d:%N is the number of characters that must be entered. +//l:popup_note_window +//w: +//r:3.0 +// +#define qtn_wlan_info_wep_key_too_short "WEP key too short. Key must be exactly %N characters long" + + +//d:Error note to be showed when invalid characters have been entered for +//d:qtn_wlan_sett_wep_key_data editor +//l:popup_note_window +//w: +//r:3.0 +// +#define qtn_wlan_info_wep_key_illegal_chars "Illegal characters in WEP key" + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettings.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettings.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,151 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWEPSecuritySettings. +* +*/ + + +// INCLUDE FILES + +#include + +#include "WEPSecuritySettingsImpl.h" +#include "WEPSecuritySettingsUiImpl.h" + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWEPSecuritySettings::NewL +// --------------------------------------------------------- +// +EXPORT_C CWEPSecuritySettings* CWEPSecuritySettings::NewL() + { + CWEPSecuritySettings* settings = new ( ELeave ) CWEPSecuritySettings(); + CleanupStack::PushL( settings ); + settings->iImpl = CWEPSecuritySettingsImpl::NewL(); + CleanupStack::Pop( settings ); + return settings; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettings::~CWEPSecuritySettings +// --------------------------------------------------------- +// +EXPORT_C CWEPSecuritySettings::~CWEPSecuritySettings() + { + delete iImpl; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettings::LoadL +// --------------------------------------------------------- +// +EXPORT_C void CWEPSecuritySettings::LoadL( TUint32 aIapId, + CCommsDatabase& aCommsDb ) + { + iImpl->LoadL( aIapId, aCommsDb ); + } + + +// --------------------------------------------------------- +// CWEPSecuritySettings::SaveL +// --------------------------------------------------------- +// +EXPORT_C void CWEPSecuritySettings::SaveL( TUint32 aIapId, + CCommsDatabase& aCommsDb ) const + { + iImpl->SaveL( aIapId, aCommsDb ); + } + + +// --------------------------------------------------------- +// CWEPSecuritySettings::EditL +// --------------------------------------------------------- +// +EXPORT_C TInt CWEPSecuritySettings::EditL( CWEPSecuritySettingsUi& aUi, + const TDesC& aTitle ) + { + return aUi.iImpl->EditL( *iImpl, aTitle ); + } + + +// --------------------------------------------------------- +// CWEPSecuritySettings::IsValid +// --------------------------------------------------------- +// +EXPORT_C TBool CWEPSecuritySettings::IsValid() const + { + return iImpl->IsValid(); + } + + +// --------------------------------------------------------- +// CWEPSecuritySettings::SetKeyDataL +// --------------------------------------------------------- +// +EXPORT_C TInt CWEPSecuritySettings::SetKeyDataL( const TInt aElement, + const TDesC& aKeyData, + const TBool aHex ) + { + return iImpl->SetKeyDataL( aElement, aKeyData, aHex ); + } + + +// --------------------------------------------------------- +// CWEPSecuritySettings::LoadL +// --------------------------------------------------------- +// +EXPORT_C void CWEPSecuritySettings::LoadL( TUint32 aIapId, + CMDBSession& aSession ) + { + iImpl->LoadL( aIapId, aSession ); + } + + +// --------------------------------------------------------- +// CWEPSecuritySettings::SaveL +// --------------------------------------------------------- +// +EXPORT_C void CWEPSecuritySettings::SaveL( TUint32 aIapId, + CMDBSession& aSession ) const + { + iImpl->SaveL( aIapId, aSession ); + } + + +// --------------------------------------------------------- +// CWEPSecuritySettings::SetKeyInUse +// --------------------------------------------------------- +// +EXPORT_C void CWEPSecuritySettings::SetKeyInUse( + CWEPSecuritySettings::TWEPKeyInUse aKey ) + { + iImpl->SetKeyInUse( aKey ); + } + + +// --------------------------------------------------------- +// CWEPSecuritySettings::SetAuthentication +// --------------------------------------------------------- +// +EXPORT_C void CWEPSecuritySettings::SetAuthentication( + CWEPSecuritySettings::TWEPAuthentication aAuthentication ) + { + iImpl->SetAuthentication( aAuthentication ); + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsDlg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsDlg.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1319 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 dialog. +* +*/ + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "WEPSecuritySettingsImpl.h" +#include "WEPSecuritySettingsUiPanic.h" +#include "WEPSecuritySettingsDlg.h" +#include "WepKeyDataTextSettingPage.h" + +#include "WEPSecuritySettingsUI.hrh" + +#include +#include + +#include + + +// CONSTANT DECLARATIONS + +// Number of fields of main view +LOCAL_D const TInt KNumOfFieldsMain = 3; + +// Number of fields of key configuration view +LOCAL_D const TInt KNumOfFieldsKeyConfiguration = 3; + +// Ratio of ascii and hex key sizes +LOCAL_D const TInt KAsciiHexRatio = 2; + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::CWEPSecuritySettingsDlg +// --------------------------------------------------------- +// +CWEPSecuritySettingsDlg::CWEPSecuritySettingsDlg( TInt& aEventStore ) +: iNaviPane( NULL ), +iTabGroup( NULL ), +iActiveTab( 0 ), +iLevel( 0 ), +iEventStore( &aEventStore ) + { + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::~CWEPSecuritySettingsDlg +// --------------------------------------------------------- +// +CWEPSecuritySettingsDlg::~CWEPSecuritySettingsDlg() + { + if ( iNaviDecoratorEmpty ) + { + delete iNaviDecoratorEmpty; + } + + if ( iNaviDecoratorTabbed ) + { + delete iNaviDecoratorTabbed; + } + + if ( iTitlePane ) + { + // set old text back, if we have it... + if ( iOldTitleText ) + { + TRAP_IGNORE( iTitlePane->SetTextL( *iOldTitleText ) ); + delete iOldTitleText; + } + } + + FeatureManager::UnInitializeLib(); + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::NewL +// --------------------------------------------------------- +// +CWEPSecuritySettingsDlg* CWEPSecuritySettingsDlg::NewL( TInt& aEventStore ) + { + CWEPSecuritySettingsDlg* secSett = + new ( ELeave )CWEPSecuritySettingsDlg( aEventStore ); + return secSett; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::ConstructAndRunLD +// --------------------------------------------------------- +// +TInt CWEPSecuritySettingsDlg::ConstructAndRunLD( + CWEPSecuritySettingsImpl* aSecuritySettings, + const TDesC& aTitle ) + { + CleanupStack::PushL( this ); + + const TInt Titles_Wep_Main[KNumOfFieldsMain] = + { + R_WEP_KEY_IN_USE, + R_WEP_AUTHENTICATION, + R_WEP_KEY_CONFIGURATION + }; + + const TInt Fields_Wep_Main[KNumOfFieldsMain] = + { + CWEPSecuritySettings::EWepKeyInUse, + CWEPSecuritySettings::EWepAuthentication, + CWEPSecuritySettings::EWepKeyConfiguration + }; + + const TInt Fields_Wep_Key_Configuration[KNumOfFieldsKeyConfiguration] = + { + CWEPSecuritySettings::EWepKeyLength, + CWEPSecuritySettings::EWepKeyFormat, + CWEPSecuritySettings::EWepKeyData + }; + + const TInt Titles_Wep_Key_Configuration[KNumOfFieldsKeyConfiguration] = + { + R_WEP_KEY_LENGTH, + R_WEP_KEY_FORMAT, + R_WEP_KEY_DATA + }; + + iSecuritySettings = aSecuritySettings; + iConnectionName = aTitle; + + iFieldsMain = ( CWEPSecuritySettings::TWepMember* ) Fields_Wep_Main; + iTitlesMain = MUTABLE_CAST( TInt*, Titles_Wep_Main ); + + iFieldsKeyConfiguration = ( CWEPSecuritySettings::TWepMember* ) + Fields_Wep_Key_Configuration; + iTitlesKeyConfiguration = MUTABLE_CAST( TInt*, + Titles_Wep_Key_Configuration ); + + FeatureManager::InitializeLibL(); + + ConstructL( R_WEP_SECURITY_SETTINGS_MENUBAR ); + + // ExecuteLD will PushL( this ), so we have to Pop it... + CleanupStack::Pop( this ); // this + + return ExecuteLD( R_WEPSETTINGS_DIALOG ); + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::OkToExitL +// --------------------------------------------------------- +// +TBool CWEPSecuritySettingsDlg::OkToExitL( TInt aButtonId ) +{ + // Translate the button presses into commands for the appui & current + // view to handle + TBool retval( EFalse ); + if ( aButtonId == EAknSoftkeyOptions ) + { + DisplayMenuL(); + } + else if ( aButtonId == EEikCmdExit ) // ShutDown requested + { + *iEventStore |= CWEPSecuritySettings::EShutDownReq; + retval = ETrue; + } + else if ( aButtonId == EAknSoftkeyBack || aButtonId == EAknCmdExit ) + { + if ( iSecuritySettings->IsValid() ) + { + *iEventStore |= CWEPSecuritySettings::EValid; + retval = ETrue; + } + else if ( aButtonId == EAknSoftkeyBack ) + { + HBufC* stringHolder = StringLoader::LoadL( + R_WEP_DATA_MISSING, iEikonEnv ); + CleanupStack::PushL( stringHolder ); + + CAknQueryDialog *queryDialog = new (ELeave) CAknQueryDialog(); + + queryDialog->PrepareLC( R_WEP_SEC_SETT_CONF_QUERY ); + queryDialog->SetPromptL( stringHolder->Des() ); + if ( queryDialog->RunLD() ) + { + retval = ETrue; + } + else + { + iActiveTab = iSecuritySettings->KeyInUse(); + iTabGroup->SetActiveTabByIndex( iActiveTab ); + HandleListboxDataChangeL(); + } + CleanupStack::PopAndDestroy( stringHolder ); // stringHolder + } + else + { + retval = ETrue; + } + + if ( aButtonId == EAknCmdExit ) + { + *iEventStore |= CWEPSecuritySettings::EExitReq; + } + } + else if( aButtonId == EWepSelCmdChange ) + { + ChangeSettingsL( ETrue ); + retval = EFalse; // don't exit the dialog + } + + return retval; +} + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::OfferKeyEventL +// --------------------------------------------------------- +// +TKeyResponse CWEPSecuritySettingsDlg::OfferKeyEventL( + const TKeyEvent& aKeyEvent, TEventCode aType ) + { + TKeyResponse retval( EKeyWasNotConsumed ); + TChar charCode( aKeyEvent.iCode ); + + // Only interested in standard key events + if ( aType == EEventKey ) + { + // If a menu is showing offer key events to it. + if ( CAknDialog::MenuShowing() ) + { + retval = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + else + { + if ( iList ) + { + // as list IS consuming, must handle because it IS the SHUTDOWN... + // or, a view switch is shutting us down... + if ( aKeyEvent.iCode == EKeyEscape ) + { + ProcessCommandL( EEikCmdExit ); + retval = EKeyWasConsumed; + } + else if ( iLevel && ( charCode == EKeyLeftArrow || + charCode == EKeyRightArrow ) ) + { + if ( iTabGroup ) + { + return iTabGroup->OfferKeyEventL( aKeyEvent, aType ); + } + } + else + { + retval = iList->OfferKeyEventL( aKeyEvent, aType ); + } + } + else + { + if ( aKeyEvent.iCode == EKeyOK ) + { + ProcessCommandL( EWepSelCmdChange ); + retval = EKeyWasConsumed; + } + } + } + } + + return retval; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::HandleListboxDataChangeL +// --------------------------------------------------------- +// +void CWEPSecuritySettingsDlg::HandleListboxDataChangeL() + { + // fill up our new list with data + CDesCArrayFlat* itemArray = new ( ELeave ) CDesCArrayFlat( 4 ); + CleanupStack::PushL( itemArray ); + + if ( iLevel ) + { + FillListWithDataL( *itemArray, *iFieldsKeyConfiguration, + KNumOfFieldsKeyConfiguration, + iTitlesKeyConfiguration ); + + iNaviPane->ReplaceL( *iNaviDecoratorEmpty, *iNaviDecoratorTabbed ); + } + else + { + FillListWithDataL( *itemArray, *iFieldsMain, KNumOfFieldsMain, + iTitlesMain ); + iNaviPane->ReplaceL( *iNaviDecoratorTabbed, *iNaviDecoratorEmpty ); + } + + iList->Model()->SetItemTextArray( itemArray ); + + CleanupStack::Pop( itemArray ); // now it is owned by the LB, so pop it + iItemArray = itemArray; + + iList->HandleItemAdditionL(); + } + + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::ProcessCommandL +// --------------------------------------------------------- +// +void CWEPSecuritySettingsDlg::ProcessCommandL( TInt aCommandId ) + { + if ( MenuShowing() ) + { + HideMenu(); + } + + switch ( aCommandId ) + { + case EWepSelCmdChange: + { + ChangeSettingsL( EFalse ); + break; + } + + case EAknCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + iEikonEnv->EikAppUi()->AppHelpContextL() ); + break; + } + + case EAknSoftkeyBack: + case EAknCmdExit: + case EEikCmdExit: + { + TryExitL( aCommandId ); + break; + } + + default: + { + // silently ignore it + break; + } + } + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::HandleListBoxEventL +// --------------------------------------------------------- +// +void CWEPSecuritySettingsDlg::HandleListBoxEventL( CEikListBox* /*aListBox*/, + TListBoxEvent aEventType ) + { + switch ( aEventType ) + { + case EEventEnterKeyPressed: + // both handled in the same way for now... + case EEventItemSingleClicked: + { + ChangeSettingsL( ETrue ); + break; + } + + case EEventEditingStarted: + case EEventEditingStopped: + case EEventPenDownOnItem: + case EEventItemDraggingActioned: + { + break; + } + + + default: + { + __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) ); + break; + }; + }; + } + + + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::PreLayoutDynInitL() +// --------------------------------------------------------- +// +void CWEPSecuritySettingsDlg::PreLayoutDynInitL() + { + // first get StatusPane + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + + // then get TitlePane + iTitlePane = ( CAknTitlePane* ) statusPane->ControlL( TUid::Uid( + EEikStatusPaneUidTitle ) ); + // if not already stored, store it for restoring + if ( !iOldTitleText ) + { + iOldTitleText = iTitlePane->Text()->AllocL(); + } + + // set new titlepane text + iTitlePane->SetTextL( iConnectionName ); + + // Fetch pointer to the default navi pane control + iNaviPane = ( CAknNavigationControlContainer* ) + statusPane->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) ); + + _LIT( KEmpty, "" ); + if ( !iNaviDecoratorEmpty ) + { + iNaviDecoratorEmpty = iNaviPane->CreateNavigationLabelL( KEmpty ); + } + + if ( !iNaviDecoratorTabbed ) + { + iNaviDecoratorTabbed = iNaviPane->CreateTabGroupL(); + + if (iNaviDecoratorTabbed) + { + iTabGroup = static_cast< CAknTabGroup* > + ( iNaviDecoratorTabbed->DecoratedControl() ); + + HBufC16* tabText = iEikonEnv->AllocReadResourceLC( R_WEP_TAB_KEY_1 ); + TPtr localizedTabText( tabText->Des() ); + AknTextUtils::LanguageSpecificNumberConversion( localizedTabText ); + iTabGroup->AddTabL( EWEPSecuritySettingsTab1, *tabText ); + CleanupStack::PopAndDestroy( tabText ); // tabText + + tabText = iEikonEnv->AllocReadResourceLC( R_WEP_TAB_KEY_2 ); + localizedTabText.Set( tabText->Des() ); + AknTextUtils::LanguageSpecificNumberConversion( localizedTabText ); + iTabGroup->AddTabL( EWEPSecuritySettingsTab2, *tabText ); + CleanupStack::PopAndDestroy( tabText ); // tabText + + tabText = iEikonEnv->AllocReadResourceLC( R_WEP_TAB_KEY_3 ); + localizedTabText.Set( tabText->Des() ); + AknTextUtils::LanguageSpecificNumberConversion( localizedTabText ); + iTabGroup->AddTabL( EWEPSecuritySettingsTab3, *tabText ); + CleanupStack::PopAndDestroy( tabText ); // tabText + + tabText = iEikonEnv->AllocReadResourceLC( R_WEP_TAB_KEY_4 ); + localizedTabText.Set( tabText->Des() ); + AknTextUtils::LanguageSpecificNumberConversion( localizedTabText ); + iTabGroup->AddTabL( EWEPSecuritySettingsTab4, *tabText ); + CleanupStack::PopAndDestroy( tabText ); // tabText + + iTabGroup->SetTabFixedWidthL( EAknTabWidthWithFourTabs ); + iTabGroup->SetActiveTabByIndex( 0 ); + + iTabGroup->SetObserver( this ); + } + } + + iNaviPane->PushL( *iNaviDecoratorEmpty ); + iList = STATIC_CAST( CAknSettingStyleListBox*, + Control( KWepMainSettingsListboxId ) ); + + iList->CreateScrollBarFrameL( ETrue ); + iList->ScrollBarFrame()->SetScrollBarVisibilityL + ( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto ); + + HandleListboxDataChangeL(); + + iList->SetCurrentItemIndex( 0 ); + iList->SetListBoxObserver( this ); + } + + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::DynInitMenuPaneL +// --------------------------------------------------------- +// +void CWEPSecuritySettingsDlg::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + CAknDialog::DynInitMenuPaneL( aResourceId, aMenuPane ); + if ( aResourceId == R_WEP_SECURITY_SETTINGS_MENU ) + { + if( !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + } + } + + +//---------------------------------------------------------- +// CWEPSecuritySettingsDlg::FillListWithDataL +//---------------------------------------------------------- +// +void CWEPSecuritySettingsDlg::FillListWithDataL( CDesCArrayFlat& aItemArray, + const CWEPSecuritySettings::TWepMember& arr, + TInt aLength, + const TInt* aRes ) + { + _LIT( KTxtMenuListItemFormat, " \t%S\t\t" ); + const TInt KSpaceAndTabsLength = 4; + + CWEPSecuritySettings::TWepMember* wepMember = + MUTABLE_CAST( CWEPSecuritySettings::TWepMember*, &arr ); + + for( TInt i = 0; i < aLength; i++ ) + { + if ( *wepMember == CWEPSecuritySettings::EWepKeyConfiguration ) + { + // Define a heap descriptor to hold all the item text + // HBufC is non-modifiable + HBufC* title = iEikonEnv->AllocReadResourceLC( *aRes ); + + // Define a heap descriptor to hold all the item text + HBufC* itemText = HBufC::NewLC( title->Length() + + KSpaceAndTabsLength ); + + // Define a modifiable pointer descriptor to be able to append + // text to the non-modifiable heap descriptor itemText + TPtr itemTextPtr = itemText->Des(); + itemTextPtr.Format( KTxtMenuListItemFormat, title ); + + aItemArray.AppendL( *itemText ); + + CleanupStack::PopAndDestroy( 2, title ); // itemText, title + } + else + { + HBufC* itemText = CreateTextualListBoxItemL( *wepMember, + *aRes ); + CleanupStack::PushL( itemText ); + aItemArray.AppendL( itemText->Des() ); + CleanupStack::PopAndDestroy( itemText ); + } + + wepMember++; + aRes++; + } + } + + +//---------------------------------------------------------- +// CWEPSecuritySettingsDlg::UpdateListBoxItemL +//---------------------------------------------------------- +// +void CWEPSecuritySettingsDlg::UpdateListBoxItemL( + CWEPSecuritySettings::TWepMember aMember, + TInt aRes, TInt aPos ) + { + HBufC* itemText = CreateTextualListBoxItemL( aMember, aRes ); + CleanupStack::PushL( itemText ); + // first try to add, if Leaves, list will be untouched + iItemArray->InsertL( aPos, itemText->Des() ); + // if successful, previous item is scrolled up with one, + // so delete that one... + if ( ++aPos < iItemArray->MdcaCount() ) + { + iItemArray->Delete( aPos ); + } + CleanupStack::PopAndDestroy( itemText ); + } + + +//---------------------------------------------------------- +// CWEPSecuritySettingsDlg::CreateTextualListBoxItemL +//---------------------------------------------------------- +// +HBufC* CWEPSecuritySettingsDlg::CreateTextualListBoxItemL( + CWEPSecuritySettings::TWepMember aMember, + TInt aRes ) + { + // Define a heap descriptor to hold all the item text + // HBufC is non-modifiable + HBufC* title = iEikonEnv->AllocReadResourceLC( aRes ); + + // both variables needed independently of the following conditions so I + // must declare them here... + HBufC16* value; + TUint32 valueResourceID; + + switch ( aMember ) + { + case CWEPSecuritySettings::EWepKeyInUse: + { + switch ( iSecuritySettings->KeyInUse() ) + { + case CWEPSecuritySettings::EKeyNumber1: + { + valueResourceID = R_WEP_KEY_NUMBER_1; + break; + } + + case CWEPSecuritySettings::EKeyNumber2: + { + valueResourceID = R_WEP_KEY_NUMBER_2; + break; + } + + case CWEPSecuritySettings::EKeyNumber3: + { + valueResourceID = R_WEP_KEY_NUMBER_3; + break; + } + + case CWEPSecuritySettings::EKeyNumber4: + { + valueResourceID = R_WEP_KEY_NUMBER_4; + break; + } + + default: + { + valueResourceID = 0; + break; + } + } + break; + } + + case CWEPSecuritySettings::EWepAuthentication: + { + switch ( iSecuritySettings->Authentication() ) + { + case CWEPSecuritySettings::EAuthOpen: + { + valueResourceID = R_WEP_AUTHENTICATION_OPEN; + break; + } + + case CWEPSecuritySettings::EAuthShared: + { + valueResourceID = R_WEP_AUTHENTICATION_SHARED; + break; + } + + default: + { + valueResourceID = 0; + break; + } + } + break; + } + + case CWEPSecuritySettings::EWepKeyLength: + { + switch ( iSecuritySettings->KeyLength( iActiveTab ) ) + { + case CWEPSecuritySettings::E40Bits: + { + valueResourceID = R_WEP_KEY_LENGTH_64_BITS; + break; + } + + case CWEPSecuritySettings::E104Bits: + { + valueResourceID = R_WEP_KEY_LENGTH_128_BITS; + break; + } + + case CWEPSecuritySettings::E232Bits: + { + valueResourceID = iSecuritySettings->WEP256Enabled() ? + R_WEP_KEY_LENGTH_256_BITS : 0; + break; + } + + default: + { + valueResourceID = 0; + break; + } + } + break; + } + + case CWEPSecuritySettings::EWepKeyFormat: + { + switch ( iSecuritySettings->KeyFormat( iActiveTab ) ) + { + case CWEPSecuritySettings::EAscii: + { + valueResourceID = R_WEP_KEY_FORMAT_ASCII; + break; + } + + case CWEPSecuritySettings::EHexadecimal: + { + valueResourceID = R_WEP_KEY_FORMAT_HEX; + break; + } + + default: + { + valueResourceID = 0; + break; + } + } + break; + } + + case CWEPSecuritySettings::EWepKeyData: + { + if ( !iSecuritySettings->KeyData( iActiveTab )->Length() ) + { + valueResourceID = R_WEP_KEY_DATA_MUST_BE_DEFINED; + } + else + { + valueResourceID = 0; + } + + break; + } + + default: + { + valueResourceID = 0; + break; + } + } + + _LIT( KStars, "****" ); + _LIT( KTxtListItemFormat, " \t%S\t\t%S" ); + const TInt KSpaceAndTabsLength = 4; + _LIT( KTxtCompulsory, "\t*" ); + + if ( valueResourceID ) + { + // Read up value text from resource + value = iEikonEnv->AllocReadResourceLC( valueResourceID ); + if( aMember == CWEPSecuritySettings::EWepKeyInUse ) + { + TPtr localizedValue( value->Des() ); + AknTextUtils::LanguageSpecificNumberConversion( localizedValue ); + } + } + else + { + value = HBufC::NewLC( KStars().Length() ); + value->Des().Copy( KStars ); + } + + // Define a heap descriptor to hold all the item text + // +4 for space and tab characters + TInt length = title->Length() + value->Length() + KSpaceAndTabsLength; + if ( aMember == CWEPSecuritySettings::EWepKeyData ) // Compulsory + { + length += KTxtCompulsory().Length(); + } + + HBufC* itemText = HBufC::NewLC( length ); + + // Define a modifiable pointer descriptor to be able to append text to the + // non-modifiable heap descriptor itemText + TPtr itemTextPtr = itemText->Des(); + itemTextPtr.Format( KTxtListItemFormat, title, value ); + if ( aMember == CWEPSecuritySettings::EWepKeyData ) // Compulsory + { + itemTextPtr.Append( KTxtCompulsory ); + } + CleanupStack::Pop( itemText ); // itemtext, + + CleanupStack::PopAndDestroy( 2, title ); // title, value + + return itemText; + } + + + +//---------------------------------------------------------- +// CWEPSecuritySettingsDlg::ShowPopupSettingPageL +//---------------------------------------------------------- +// +TBool CWEPSecuritySettingsDlg::ShowPopupSettingPageL( + CWEPSecuritySettings::TWepMember aData ) + { + TInt currvalue( 0 ); + TBool retval( EFalse ); + CDesCArrayFlat* items = FillPopupSettingPageLC( aData, currvalue ); + + TInt attr_resid( 0 ); + + // not text based ones: + switch ( aData ) + { + case CWEPSecuritySettings::EWepKeyInUse: + { + attr_resid = R_WEP_KEY_IN_USE; + break; + } + + case CWEPSecuritySettings::EWepAuthentication: + { + attr_resid = R_WEP_AUTHENTICATION; + break; + } + + case CWEPSecuritySettings::EWepKeyLength: + { + attr_resid = R_WEP_KEY_LENGTH; + break; + } + + case CWEPSecuritySettings::EWepKeyFormat: + { + attr_resid = R_WEP_KEY_FORMAT; + break; + } + + default: + { + __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) ); + attr_resid = 0; + break; + } + } + + HBufC* titlebuf; + CAknRadioButtonSettingPage* dlg; + if ( attr_resid ) + { + titlebuf = iEikonEnv->AllocReadResourceLC( attr_resid ); + dlg = new ( ELeave )CAknRadioButtonSettingPage( + R_RADIO_BUTTON_SETTING_PAGE, currvalue, items ); + CleanupStack::PushL( dlg ); + TPtrC ptr( titlebuf->Des() ); + dlg->SetSettingTextL( ptr ); + CleanupStack::Pop( dlg ); // dlg + } + else + { + dlg = new ( ELeave )CAknRadioButtonSettingPage( + R_RADIO_BUTTON_SETTING_PAGE, currvalue, items ); + } + if ( dlg->ExecuteLD( CAknSettingPage::EUpdateWhenAccepted ) ) + { + retval = UpdateFromPopupSettingPage( aData, currvalue ); + } + + if ( attr_resid ) + { + CleanupStack::PopAndDestroy( titlebuf ); // titlebuf + } + + CleanupStack::PopAndDestroy( items ); // items. It deletes also all + // elements in the array. + return retval; + } + + + +//---------------------------------------------------------- +// CWEPSecuritySettingsDlg::ShowPopupTextSettingPageL +//---------------------------------------------------------- +// +TBool CWEPSecuritySettingsDlg::ShowPopupTextSettingPageL() + { + TBool retval( EFalse ); + + CWEPSecuritySettings::TWEPKeyFormat keyFormat = + iSecuritySettings->KeyFormat( iActiveTab ); + TInt expectedLength = iSecuritySettings->ExpectedLengthOfKeyData( + iSecuritySettings->KeyLength( iActiveTab ) ); + + if ( keyFormat == CWEPSecuritySettings::EAscii ) + { + expectedLength /= KAsciiHexRatio; //Ascii key is half the length of Hex + } + + HBufC16* bufKeyData = HBufC16::NewLC( expectedLength ); + TPtr16 ptrKeyData( bufKeyData->Des() ); + + TBool showPage( ETrue ); + while ( showPage ) + { + CWEPKeyDataTextSettingPage* dlg = + new( ELeave )CWEPKeyDataTextSettingPage( ptrKeyData, + expectedLength, + keyFormat ); + + if ( dlg->ExecuteLD( CAknSettingPage::EUpdateWhenAccepted ) ) + { + HBufC8* buf8 = HBufC8::NewLC( bufKeyData->Des().Length() ); + buf8->Des().Copy( bufKeyData->Des() ); + + TInt err = iSecuritySettings->VerifyKeyData( *buf8, expectedLength, + iSecuritySettings->KeyFormat( iActiveTab ) ); + if ( err == KErrNone ) + { + if ( keyFormat == CWEPSecuritySettings::EAscii ) + { + HBufC8* buf8Conv = + HBufC8::NewLC( bufKeyData->Des().Length() + * KAsciiHexRatio ); + // Ascii key is half the length of Hex + + iSecuritySettings->ConvertAsciiToHex( buf8->Des(), + buf8Conv ); + iSecuritySettings->SetKeyData( iActiveTab, + buf8Conv->Des() ); + CleanupStack::PopAndDestroy( buf8Conv ); // buf8Conv + } + else + { + iSecuritySettings->SetKeyData( iActiveTab, buf8->Des() ); + } + + retval = ETrue; + showPage = EFalse; + } + else + { + HBufC* stringLabel; + + if ( err == KErrInvalidLength ) + { + stringLabel = StringLoader::LoadL( R_INFO_WEP_KEY_TOO_SHORT, + expectedLength, + iEikonEnv ); + } + else + { + stringLabel = StringLoader::LoadL( + R_INFO_WEP_KEY_ILLEGAL_CHARS, + iEikonEnv ); + } + + CleanupStack::PushL( stringLabel ); + + CAknInformationNote* dialog = new (ELeave)CAknInformationNote( + ETrue ); + CleanupStack::Pop( stringLabel ); + + dialog->ExecuteLD( *stringLabel ); + + CleanupStack::PopAndDestroy( stringLabel ); // stringLabel + + ptrKeyData.Zero(); + } + + CleanupStack::PopAndDestroy( buf8 ); // buf8 + } + else + { + showPage = EFalse; + } + } + + CleanupStack::PopAndDestroy( bufKeyData ); // bufKeyData + + return retval; + } + + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::FillPopupSettingPageLC +// --------------------------------------------------------- +// +CDesCArrayFlat* CWEPSecuritySettingsDlg::FillPopupSettingPageLC( + CWEPSecuritySettings::TWepMember aData, + TInt& aCurrvalue ) + { + CDesCArrayFlat* items = new( ELeave)CDesCArrayFlat( 1 ); + CleanupStack::PushL( items ); + + switch ( aData ) + { + case CWEPSecuritySettings::EWepKeyInUse: + { + RBuf16 convert( iEikonEnv->AllocReadResourceL( + R_WEP_KEY_NUMBER_1 ) ); + AknTextUtils::LanguageSpecificNumberConversion( convert ); + items->AppendL( convert ); + convert.Close(); + + convert.Assign( iEikonEnv->AllocReadResourceL( + R_WEP_KEY_NUMBER_2 ) ); + AknTextUtils::LanguageSpecificNumberConversion( convert ); + items->AppendL( convert ); + convert.Close(); + + convert.Assign( iEikonEnv->AllocReadResourceL( + R_WEP_KEY_NUMBER_3 ) ); + AknTextUtils::LanguageSpecificNumberConversion( convert ); + items->AppendL( convert ); + convert.Close(); + + convert.Assign( iEikonEnv->AllocReadResourceL( + R_WEP_KEY_NUMBER_4 ) ); + AknTextUtils::LanguageSpecificNumberConversion( convert ); + items->AppendL( convert ); + convert.Close(); + + aCurrvalue = iSecuritySettings->KeyInUse(); + break; + } + + case CWEPSecuritySettings::EWepAuthentication: + { + items->AppendL( *iEikonEnv->AllocReadResourceLC( + R_WEP_AUTHENTICATION_OPEN ) ); + CleanupStack::PopAndDestroy(); + items->AppendL( *iEikonEnv->AllocReadResourceLC( + R_WEP_AUTHENTICATION_SHARED ) ); + CleanupStack::PopAndDestroy(); + + aCurrvalue = iSecuritySettings->Authentication(); + break; + } + + case CWEPSecuritySettings::EWepKeyLength: + { + items->AppendL( *iEikonEnv->AllocReadResourceLC( + R_WEP_KEY_LENGTH_64_BITS ) ); + CleanupStack::PopAndDestroy(); + items->AppendL( *iEikonEnv->AllocReadResourceLC( + R_WEP_KEY_LENGTH_128_BITS ) ); + CleanupStack::PopAndDestroy(); + + if ( iSecuritySettings->WEP256Enabled() ) + { + items->AppendL( *iEikonEnv->AllocReadResourceLC( + R_WEP_KEY_LENGTH_256_BITS ) ); + CleanupStack::PopAndDestroy(); + } + + aCurrvalue = iSecuritySettings->KeyLength( iActiveTab ); + break; + } + + case CWEPSecuritySettings::EWepKeyFormat: + { + items->AppendL( *iEikonEnv->AllocReadResourceLC( + R_WEP_KEY_FORMAT_ASCII ) ); + CleanupStack::PopAndDestroy(); + items->AppendL( *iEikonEnv->AllocReadResourceLC( + R_WEP_KEY_FORMAT_HEX ) ); + CleanupStack::PopAndDestroy(); + + aCurrvalue = iSecuritySettings->KeyFormat( iActiveTab ); + break; + } + + default: + { + __ASSERT_DEBUG( EFalse, Panic ( EUnknownCase ) ); + break; + } + } + return items; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::UpdateFromPopupSettingPage +// --------------------------------------------------------- +// +TBool CWEPSecuritySettingsDlg::UpdateFromPopupSettingPage( + CWEPSecuritySettings::TWepMember aData, + TInt aCurrvalue ) + { + TBool retVal( EFalse ); + + switch ( aData ) + { + case CWEPSecuritySettings::EWepKeyInUse: + { + if ( iSecuritySettings->KeyInUse() != + ( CWEPSecuritySettings::TWEPKeyInUse )aCurrvalue ) + { + iSecuritySettings->SetKeyInUse( + ( CWEPSecuritySettings::TWEPKeyInUse )aCurrvalue ); + retVal = ETrue; + } + break; + } + + case CWEPSecuritySettings::EWepAuthentication: + { + if ( iSecuritySettings->Authentication() != + ( CWEPSecuritySettings::TWEPAuthentication )aCurrvalue ) + { + iSecuritySettings->SetAuthentication( + ( CWEPSecuritySettings::TWEPAuthentication )aCurrvalue ); + retVal = ETrue; + } + break; + } + + case CWEPSecuritySettings::EWepKeyLength: + { + if ( iSecuritySettings->KeyLength( iActiveTab ) != + ( CWEPSecuritySettings::TWEPKeyLength )aCurrvalue ) + { + iSecuritySettings->SetKeyLength( iActiveTab, + ( CWEPSecuritySettings::TWEPKeyLength )aCurrvalue ); + retVal = ETrue; + } + break; + } + + case CWEPSecuritySettings::EWepKeyFormat: + { + if ( iSecuritySettings->KeyFormat( iActiveTab ) != + ( CWEPSecuritySettings::TWEPKeyFormat )aCurrvalue ) + { + iSecuritySettings->SetKeyFormat( iActiveTab, + ( CWEPSecuritySettings::TWEPKeyFormat )aCurrvalue ); + retVal = ETrue; + } + break; + } + + default: + { + __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) ); + break; + } + } + + return retVal; + } + + + +//---------------------------------------------------------- +// CWEPSecuritySettingsDlg::ChangeSettingsL +//---------------------------------------------------------- +// +void CWEPSecuritySettingsDlg::ChangeSettingsL( TBool aQuick ) + { + TInt itemIndex = ( Max( iList->CurrentItemIndex(), 0 ) ); + CWEPSecuritySettings::TWepMember* ptr = + (iLevel ? iFieldsKeyConfiguration : iFieldsMain) + itemIndex; + TInt* tptr = ( iLevel ? iTitlesKeyConfiguration : iTitlesMain ) + itemIndex; + + const TInt KShiftFromKeyLengthToKeyData = 2; + switch ( *ptr ) + { + case CWEPSecuritySettings::EWepKeyInUse: + case CWEPSecuritySettings::EWepKeyLength: + { // Pop-up setting item + if ( ShowPopupSettingPageL( *ptr ) ) + { + UpdateListBoxItemL( *ptr, *tptr, itemIndex ); + *iEventStore |= CWEPSecuritySettings::EModified; + if ( *ptr == CWEPSecuritySettings::EWepKeyLength ) + { + ptr += KShiftFromKeyLengthToKeyData; + tptr += KShiftFromKeyLengthToKeyData; + iSecuritySettings->KeyData( iActiveTab )->Zero(); + UpdateListBoxItemL( *ptr, *tptr, + itemIndex+KShiftFromKeyLengthToKeyData ); + iList->SetCurrentItemIndexAndDraw( itemIndex+ + KShiftFromKeyLengthToKeyData ); + } + } + break; + } + + case CWEPSecuritySettings::EWepAuthentication: + case CWEPSecuritySettings::EWepKeyFormat: + { // Setting item with two available values + TBool changed( ETrue ); + if ( aQuick ) + { + InvertSettings( *ptr ); + } + else + { + changed = ShowPopupSettingPageL( *ptr ); + } + + if ( changed ) + { + UpdateListBoxItemL( *ptr, *tptr, itemIndex ); + if ( *ptr == CWEPSecuritySettings::EWepAuthentication ) + { + *iEventStore |= CWEPSecuritySettings::EModified; + } + } + break; + } + + case CWEPSecuritySettings::EWepKeyData: + { // Text setting item + if ( ShowPopupTextSettingPageL() ) + { + UpdateListBoxItemL( *ptr, *tptr, itemIndex ); + *iEventStore |= CWEPSecuritySettings::EModified; + } + break; + } + + case CWEPSecuritySettings::EWepKeyConfiguration: + { + iLevel = 1; + + iActiveTab = iSecuritySettings->KeyInUse(); + iTabGroup->SetActiveTabByIndex( iActiveTab ); + + HandleListboxDataChangeL(); + itemIndex = 0; + + break; + } + + default: + { + __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) ); + break; + } + } + + iList->ScrollToMakeItemVisible( itemIndex ); + iList->SetCurrentItemIndexAndDraw( itemIndex ); + } + + + + +//---------------------------------------------------------- +// CWEPSecuritySettingsDlg::InvertSettings +//---------------------------------------------------------- +// +void CWEPSecuritySettingsDlg::InvertSettings( CWEPSecuritySettings::TWepMember + aDataMember ) + { + if ( aDataMember == CWEPSecuritySettings::EWepAuthentication ) + { + if ( iSecuritySettings->Authentication() == + CWEPSecuritySettings::EAuthOpen ) + { + iSecuritySettings->SetAuthentication( + CWEPSecuritySettings::EAuthShared ); + } + else + { + iSecuritySettings->SetAuthentication( + CWEPSecuritySettings::EAuthOpen ); + } + } + else if ( aDataMember == CWEPSecuritySettings::EWepKeyFormat ) + { + if ( iSecuritySettings->KeyFormat( iActiveTab ) == + CWEPSecuritySettings::EAscii ) + { + iSecuritySettings->SetKeyFormat( iActiveTab, + CWEPSecuritySettings::EHexadecimal ); + } + else + { + iSecuritySettings->SetKeyFormat( iActiveTab, + CWEPSecuritySettings::EAscii ); + } + } + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsDlg::GetHelpContext +// --------------------------------------------------------- +// +void CWEPSecuritySettingsDlg::GetHelpContext( TCoeHelpContext& aContext ) const + { + aContext.iMajor = KWEPSecuritySettingsUiHelpMajor; + if ( iLevel ) + { + aContext.iContext = KSET_HLP_WLAN_WEP_KEY_SETT; + } + else + { + aContext.iContext = KSET_HLP_WLAN_WEP_MAIN; + } + } + + +// ----------------------------------------------------------------------------- +// CWEPSecuritySettingsDlg::TabChangedL( TInt aIndex ) +// ----------------------------------------------------------------------------- +// +void CWEPSecuritySettingsDlg::TabChangedL( TInt aIndex ) + { + iActiveTab = aIndex; + HandleListboxDataChangeL(); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsImpl.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,603 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWEPSecuritySettingsImpl. +* +*/ + + +// INCLUDE FILES + +#include "WEPSecuritySettingsImpl.h" +#include "WEPSecuritySettingsUiPanic.h" + +#include +#include +#include +#include + +#include +#include +#include + +// CONSTANT DECLARATIONS + +// Index of first key +LOCAL_D const TInt KFirstKey = 0; + +// Index of second key +LOCAL_D const TInt KSecondKey = 1; + +// Index of third key +LOCAL_D const TInt KThirdKey = 2; + +// Index of fourth key +LOCAL_D const TInt KFourthKey = 3; + +// Ratio of ascii and hex key sizes +LOCAL_D const TInt KAsciiHexRatio = 2; + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::NewL +// --------------------------------------------------------- +// +CWEPSecuritySettingsImpl* CWEPSecuritySettingsImpl::NewL() + { + CWEPSecuritySettingsImpl* settings = + new ( ELeave ) CWEPSecuritySettingsImpl(); + CleanupStack::PushL( settings ); + settings->ConstructL(); + CleanupStack::Pop( settings ); + return settings; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::CWEPSecuritySettingsImpl +// --------------------------------------------------------- +// +CWEPSecuritySettingsImpl::CWEPSecuritySettingsImpl() +: iIsWEP256Enabled( ETrue ) + { + iKeyInUse = CWEPSecuritySettings::EKeyNumber1; + iAuthentication = CWEPSecuritySettings::EAuthOpen; + for ( TUint i = 0; i < KMaxNumberofKeys; i++) + { + iKeyLength[i] = CWEPSecuritySettings::E40Bits; + iKeyFormat[i] = CWEPSecuritySettings::EAscii; + iKeyData[i].Zero(); + } + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::ConstructL +// --------------------------------------------------------- +// +void CWEPSecuritySettingsImpl::ConstructL() + { + // WEP256 is deprecated. + iIsWEP256Enabled = EFalse; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::~CWEPSecuritySettingsImpl +// --------------------------------------------------------- +// +CWEPSecuritySettingsImpl::~CWEPSecuritySettingsImpl() + { + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::LoadL +// --------------------------------------------------------- +// +void CWEPSecuritySettingsImpl::LoadL( TUint32 aIapId, + CCommsDatabase& aCommsDb ) + { + if ( aIapId == KUidNone ) + { + return; + } + + CCommsDbTableView* wLanServiceTable; + + wLanServiceTable = aCommsDb.OpenViewMatchingUintLC( + TPtrC( WLAN_SERVICE ), TPtrC( WLAN_SERVICE_ID ), aIapId ); + + TInt errorCode = wLanServiceTable->GotoFirstRecord(); + if ( errorCode == KErrNone ) + { + // Get index of key in use + TRAPD( err, wLanServiceTable->ReadUintL( TPtrC( WLAN_WEP_INDEX ), + ( TUint32& ) iKeyInUse ) ); + + // Get index of key in use + TRAP( err, wLanServiceTable->ReadUintL( + TPtrC( NU_WLAN_AUTHENTICATION_MODE ), + ( TUint32& ) iAuthentication ) ); + + // Get first WEP key + wLanServiceTable->ReadTextL( TPtrC( NU_WLAN_WEP_KEY1 ), + iKeyData[KFirstKey] ); + SetLenKeyDataFromText( KFirstKey ); + + // Get second WEP key + wLanServiceTable->ReadTextL( TPtrC( NU_WLAN_WEP_KEY2 ), + iKeyData[KSecondKey] ); + SetLenKeyDataFromText( KSecondKey ); + + // Get third WEP key + wLanServiceTable->ReadTextL( TPtrC( NU_WLAN_WEP_KEY3 ), + iKeyData[KThirdKey] ); + SetLenKeyDataFromText( KThirdKey ); + + // Get fourth WEP key + wLanServiceTable->ReadTextL( TPtrC( NU_WLAN_WEP_KEY4 ), + iKeyData[KFourthKey] ); + SetLenKeyDataFromText( KFourthKey ); + + + // Get the format of the keys + TRAP( err, wLanServiceTable->ReadUintL( TPtrC( WLAN_WEP_KEY1_FORMAT ), + ( TUint32& ) iKeyFormat[KFirstKey] ) ); + + TRAP( err, wLanServiceTable->ReadUintL( TPtrC( WLAN_WEP_KEY2_FORMAT ), + ( TUint32& ) iKeyFormat[KSecondKey] ) ); + + TRAP( err, wLanServiceTable->ReadUintL( TPtrC( WLAN_WEP_KEY3_FORMAT ), + ( TUint32& ) iKeyFormat[KThirdKey] ) ); + + TRAP( err, wLanServiceTable->ReadUintL( TPtrC( WLAN_WEP_KEY4_FORMAT ), + ( TUint32& ) iKeyFormat[KFourthKey] ) ); + } + else + { + // silently ignore KErrNotFound. It is caused by incorrect DB, + // we are 'repairing it' this way. + if ( errorCode != KErrNotFound ) + { + User::Leave( errorCode ); + } + } + + CleanupStack::PopAndDestroy( wLanServiceTable ); // wLanServiceTable + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::SaveL +// --------------------------------------------------------- +// +void CWEPSecuritySettingsImpl::SaveL( TUint32 aIapId, + CCommsDatabase& aCommsDb ) const + { + CCommsDbTableView* wLanServiceTable; + + // Caller MUST initiate a transaction, WE WILL NOT. + + wLanServiceTable = aCommsDb.OpenViewMatchingUintLC( + TPtrC( WLAN_SERVICE ), TPtrC( WLAN_SERVICE_ID ), aIapId ); + TInt errorCode = wLanServiceTable->GotoFirstRecord(); + + if ( errorCode == KErrNone ) + { + wLanServiceTable->UpdateRecord(); + } + else + { + TUint32 dummyUid( KUidNone ); + User::LeaveIfError( wLanServiceTable->InsertRecord( dummyUid ) ); + + // Save link to LAN service + wLanServiceTable->WriteUintL( TPtrC( WLAN_SERVICE_ID ), aIapId ); + } + + // Save index of key in use + wLanServiceTable->WriteUintL( TPtrC( WLAN_WEP_INDEX ), + ( TUint32& ) iKeyInUse ); + + // Save index of key in use + wLanServiceTable->WriteUintL( TPtrC( NU_WLAN_AUTHENTICATION_MODE ), + ( TUint32& ) iAuthentication ); + + // Save first WEP key + wLanServiceTable->WriteTextL( TPtrC( NU_WLAN_WEP_KEY1 ), + iKeyData[KFirstKey] ); + + // Save second WEP key + wLanServiceTable->WriteTextL( TPtrC( NU_WLAN_WEP_KEY2 ), + iKeyData[KSecondKey] ); + + // Save third WEP key + wLanServiceTable->WriteTextL( TPtrC( NU_WLAN_WEP_KEY3 ), + iKeyData[KThirdKey] ); + + // Save fourth WEP key + wLanServiceTable->WriteTextL( TPtrC( NU_WLAN_WEP_KEY4 ), + iKeyData[KFourthKey] ); + + // Save the format of the keys + wLanServiceTable->WriteUintL( TPtrC( WLAN_WEP_KEY1_FORMAT ), + ( TUint32& ) iKeyFormat[KFirstKey] ); + + wLanServiceTable->WriteUintL( TPtrC( WLAN_WEP_KEY2_FORMAT ), + ( TUint32& ) iKeyFormat[KSecondKey] ); + + wLanServiceTable->WriteUintL( TPtrC( WLAN_WEP_KEY3_FORMAT ), + ( TUint32& ) iKeyFormat[KThirdKey] ); + + wLanServiceTable->WriteUintL( TPtrC( WLAN_WEP_KEY4_FORMAT ), + ( TUint32& ) iKeyFormat[KFourthKey] ); + + wLanServiceTable->PutRecordChanges(); + + CleanupStack::PopAndDestroy( wLanServiceTable ); // wLanServiceTable + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::SetLenKeyDataFromText +// --------------------------------------------------------- +// +void CWEPSecuritySettingsImpl::SetLenKeyDataFromText( const TInt aIndex ) + { + const TUint keyDataLength = iKeyData[aIndex].Length(); + + if ( keyDataLength == KKeyDataLength104Bits ) + { + iKeyLength[aIndex] = CWEPSecuritySettings::E104Bits; + } + else if ( keyDataLength == KKeyDataLength232Bits && iIsWEP256Enabled ) + { + iKeyLength[aIndex] = CWEPSecuritySettings::E232Bits; + } + else // if ( aKeyDataLength == KKeyDataLength40Bits ) or any + { // other case, by default + iKeyLength[aIndex] = CWEPSecuritySettings::E40Bits; + } + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::IsValid +// --------------------------------------------------------- +// +TBool CWEPSecuritySettingsImpl::IsValid() + { + return ( KeyData( KeyInUse() )->Length() == + ExpectedLengthOfKeyData( KeyLength( KeyInUse() ) ) ); + } + + +//---------------------------------------------------------- +// CWEPSecuritySettingsImpl::ExpectedLengthOfKeyData +//---------------------------------------------------------- +// +TInt CWEPSecuritySettingsImpl::ExpectedLengthOfKeyData( + CWEPSecuritySettings::TWEPKeyLength aKeyLength ) + { + TInt retVal; + + switch ( aKeyLength ) + { + case CWEPSecuritySettings::E40Bits: + { + retVal = KKeyDataLength40Bits; + break; + } + + case CWEPSecuritySettings::E104Bits: + { + retVal = KKeyDataLength104Bits; + break; + } + + case CWEPSecuritySettings::E232Bits: + { + retVal = WEP256Enabled() ? KKeyDataLength232Bits : 0; + break; + } + + default: + { + retVal = 0; + break; + } + } + + return retVal; + } + + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::SetKeyDataL +// --------------------------------------------------------- +// +TInt CWEPSecuritySettingsImpl::SetKeyDataL( const TInt aElement, + const TDesC& aKeyData, + const TBool aHex ) + { + CWEPSecuritySettings::TWEPKeyFormat keyFormat = aHex ? + CWEPSecuritySettings::EHexadecimal : + CWEPSecuritySettings::EAscii; + SetKeyFormat( aElement, keyFormat ); + + TInt dataLength = aKeyData.Length(); + if ( dataLength == KKeyDataLength40Bits || + dataLength == KKeyDataLength40Bits / KAsciiHexRatio ) + { + SetKeyLength( aElement, CWEPSecuritySettings::E40Bits ); + } + else if ( dataLength == KKeyDataLength104Bits || + dataLength == KKeyDataLength104Bits / KAsciiHexRatio ) + { + SetKeyLength( aElement, CWEPSecuritySettings::E104Bits ); + } + else if ( dataLength == KKeyDataLength232Bits || + dataLength == KKeyDataLength232Bits / KAsciiHexRatio ) + { + SetKeyLength( aElement, CWEPSecuritySettings::E232Bits ); + } + else + { + return KErrInvalidLength; + } + + TInt expectedLength = ExpectedLengthOfKeyData( KeyLength( aElement ) ); + + if ( keyFormat == CWEPSecuritySettings::EAscii ) + { + expectedLength /= KAsciiHexRatio; //Ascii key is half the length of Hex + } + + HBufC8* buf8 = HBufC8::NewL( dataLength ); + CleanupStack::PushL( buf8 ); + buf8->Des().Copy( aKeyData ); + + TInt errData = VerifyKeyData( *buf8, expectedLength, + KeyFormat( aElement ) ); + if ( errData == KErrNone ) + { + if ( aHex ) + { + SetKeyData( aElement, buf8->Des() ); + } + else + { + HBufC8* buf8Conv = HBufC8::NewL( dataLength * KAsciiHexRatio ); + // Ascii key is half the length of Hex + ConvertAsciiToHex( buf8->Des(), buf8Conv ); + SetKeyData( aElement, buf8Conv->Des() ); + delete buf8Conv; + } + } + + CleanupStack::PopAndDestroy( buf8 ); // buf8 + + return errData; + } + + +//---------------------------------------------------------- +// CWEPSecuritySettingsImpl::VerifyKeyData +//---------------------------------------------------------- +// +TInt CWEPSecuritySettingsImpl::VerifyKeyData( const TDesC8& aTextToTest, + TInt aLengthOfKeyData, + CWEPSecuritySettings::TWEPKeyFormat aWEPKeyFormat ) + { + TInt err = KErrNone; + TInt lengthOfText = aTextToTest.Length(); + + if ( aTextToTest.Length() != aLengthOfKeyData ) + { + err = KErrInvalidLength; + } + else if ( aWEPKeyFormat == CWEPSecuritySettings::EHexadecimal ) + { + for ( TInt i = 0; i < lengthOfText; i++ ) + { + TChar c ( aTextToTest[i] ); + + if ( !c.IsHexDigit() ) + { + err = KErrInvalidChar; + break; + } + } + } + + return err; + } + + +//---------------------------------------------------------- +// CWEPSecuritySettingsImpl::ConvertAsciiToHex +//---------------------------------------------------------- +// +void CWEPSecuritySettingsImpl::ConvertAsciiToHex( const TDesC8& aSource, + HBufC8*& aDest ) + { + _LIT( hex, "0123456789ABCDEF" ); + TInt size = aSource.Size(); + TPtr8 ptr = aDest->Des(); + for ( TInt ii = 0; ii < size; ii++ ) + { + TText8 ch = aSource[ii]; + ptr.Append( hex()[(ch/16)&0x0f] ); + ptr.Append( hex()[ch&0x0f] ); + } + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::LoadL +// --------------------------------------------------------- +// +void CWEPSecuritySettingsImpl::LoadL( TUint32 aIapId, + CMDBSession& aSession ) + { + + if ( aIapId == KUidNone ) + { + return; + } + + // Load WLAN service table + // first get WLAN table id + CMDBGenericRecord* generic = static_cast + ( CCDRecordBase::RecordFactoryL( 0 ) ); + CleanupStack::PushL( generic ); + generic->InitializeL( TPtrC( WLAN_SERVICE ), NULL ); + generic->LoadL( aSession ); + TMDBElementId wlanTableId = generic->TableId(); + + CMDBField* sidField = static_cast*> + (generic->GetFieldByIdL( KCDTIdWlanServiceId)); + + // prime with service id + *sidField = aIapId; + + if( generic->FindL( aSession) ) + { + // get the values + CMDBField* keyInUseField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepIndex ) ); + ( TUint32& )iKeyInUse = *keyInUseField; + CMDBField* authenticationField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanAuthMode ) ); + ( TUint32& )iAuthentication = *authenticationField; + + CMDBField* wepKey1Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey1 ) ); + iKeyData[ KFirstKey ] = *wepKey1Field; + SetLenKeyDataFromText( KFirstKey ); + + CMDBField* wepKey2Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey2 ) ); + iKeyData[ KSecondKey ] = *wepKey2Field; + SetLenKeyDataFromText( KSecondKey ); + + CMDBField* wepKey3Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey3 ) ); + iKeyData[ KThirdKey ] = *wepKey3Field; + SetLenKeyDataFromText( KThirdKey ); + + CMDBField* wepKey4Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey4 ) ); + iKeyData[ KFourthKey ] = *wepKey4Field; + SetLenKeyDataFromText( KFourthKey ); + + CMDBField* formatKey1Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanFormatKey1 ) ); + ( TUint32& )iKeyFormat[ KFirstKey ] = *formatKey1Field; + CMDBField* formatKey2Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanFormatKey2 ) ); + ( TUint32& )iKeyFormat[ KSecondKey ] = *formatKey2Field; + CMDBField* formatKey3Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanFormatKey3 ) ); + ( TUint32& )iKeyFormat[ KThirdKey ] = *formatKey3Field; + CMDBField* formatKey4Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanFormatKey4 ) ); + ( TUint32& )iKeyFormat[ KFourthKey ] = *formatKey4Field; + } + + CleanupStack::PopAndDestroy( generic ); + + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsImpl::SaveL +// --------------------------------------------------------- +// +void CWEPSecuritySettingsImpl::SaveL( TUint32 aIapId, + CMDBSession& aSession ) const + { + // Load WLAN service table + // first get WLAN table id + CMDBGenericRecord* generic = static_cast + ( CCDRecordBase::RecordFactoryL( 0 ) ); + CleanupStack::PushL( generic ); + generic->InitializeL( TPtrC( WLAN_SERVICE ), NULL ); + generic->LoadL( aSession ); + TMDBElementId wlanTableId = generic->TableId(); + + CMDBField* sidField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanServiceId ) ); + + // prime with service id + *sidField = aIapId; + + TBool found = generic->FindL( aSession); + + // If loading failed, WLAN service record will be + // created and StoreL()-d, otherwise, ModifyL() + + CMDBField* keyInUseField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepIndex ) ); + keyInUseField->SetL( iKeyInUse ); + + CMDBField* authenticationField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanAuthMode ) ); + authenticationField->SetL( iAuthentication ); + + CMDBField* wepKey1Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey1 ) ); + wepKey1Field->SetL( iKeyData[ KFirstKey ] ); + CMDBField* wepKey2Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey2 ) ); + wepKey2Field->SetL( iKeyData[ KSecondKey ] ); + CMDBField* wepKey3Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey3 ) ); + wepKey3Field->SetL( iKeyData[ KThirdKey ] ); + CMDBField* wepKey4Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey4 ) ); + wepKey4Field->SetL( iKeyData[ KFourthKey ] ); + + CMDBField* formatKey1Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanFormatKey1 ) ); + formatKey1Field->SetL( iKeyFormat[ KFirstKey ] ); + CMDBField* formatKey2Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanFormatKey2 ) ); + formatKey2Field->SetL( iKeyFormat[ KSecondKey ] ); + CMDBField* formatKey3Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanFormatKey3 ) ); + formatKey3Field->SetL( iKeyFormat[ KThirdKey ] ); + CMDBField* formatKey4Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanFormatKey4 ) ); + formatKey4Field->SetL( iKeyFormat[ KFourthKey ] ); + + // If table existed modify it + if( found ) + { + generic->ModifyL( aSession ); + } + // Otherwise store a new record + else + { + generic->SetRecordId( KCDNewRecordRequest ); + generic->StoreL( aSession ); + } + CleanupStack::PopAndDestroy( generic ); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsUI.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsUI.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWEPSecuritySettingsUi. +* +*/ + + +// INCLUDE FILES +#include + +#include "WEPSecuritySettingsUiImpl.h" + + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWEPSecuritySettingsUi::NewLC +// --------------------------------------------------------- +// +EXPORT_C CWEPSecuritySettingsUi* CWEPSecuritySettingsUi::NewL( + CEikonEnv& aEikEnv ) + { + CWEPSecuritySettingsUi* secSett = new( ELeave ) CWEPSecuritySettingsUi(); + CleanupStack::PushL( secSett ); + secSett->iImpl = CWEPSecuritySettingsUiImpl::NewL( aEikEnv ); + CleanupStack::Pop( secSett ); // secSett + return secSett; + } + + + +// --------------------------------------------------------- +// CWEPSecuritySettingsUi::~CWEPSecuritySettingsUi +// --------------------------------------------------------- +// +EXPORT_C CWEPSecuritySettingsUi::~CWEPSecuritySettingsUi() + { + delete iImpl; + } + + + +// --------------------------------------------------------- +// CWEPSecuritySettingsUi::Cvt() +// --------------------------------------------------------- +// +EXPORT_C TInt CWEPSecuritySettingsUi::Cvt() + { + return KErrNone; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsUiImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsUiImpl.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,112 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWEPSecuritySettingsUiImpl. +* +*/ + + +// INCLUDE FILES +#include +#include + +#include + +#include "WEPSecuritySettingsUiImpl.h" +#include "WEPSecuritySettingsDlg.h" + + +// CONSTANTS +_LIT( KDriveZ, "z:" ); // ROM folder +_LIT( KResourceFileName, "WEPSecuritySettingsUI.rsc" ); // RSC file name. + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWEPSecuritySettingsUiImpl::NewL +// --------------------------------------------------------- +// +CWEPSecuritySettingsUiImpl* CWEPSecuritySettingsUiImpl::NewL( + CEikonEnv& aEikEnv ) + { + CWEPSecuritySettingsUiImpl* uiImpl = + new( ELeave ) CWEPSecuritySettingsUiImpl( aEikEnv ); + CleanupStack::PushL( uiImpl ); + uiImpl->ConstructL(); + CleanupStack::Pop( uiImpl ); // uiImpl + return uiImpl; + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsUiImpl::CWEPSecuritySettingsUiImpl +// --------------------------------------------------------- +// +CWEPSecuritySettingsUiImpl::CWEPSecuritySettingsUiImpl( CEikonEnv& aEikEnv ) +: iEventStore( ENone ), + iEikEnv( &aEikEnv ) + { + } + + +// --------------------------------------------------------- +// CWEPSecuritySettingsUiImpl::~CWEPSecuritySettingsUiImpl +// --------------------------------------------------------- +// +CWEPSecuritySettingsUiImpl::~CWEPSecuritySettingsUiImpl() + { + if ( iResOffset ) + { + iEikEnv->DeleteResourceFile( iResOffset ); + } + } + + + +// --------------------------------------------------------- +// CWEPSecuritySettingsUiImpl::ConstructL +// --------------------------------------------------------- +// +void CWEPSecuritySettingsUiImpl::ConstructL() + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + BaflUtils::NearestLanguageFile( iEikEnv->FsSession(), fileName ); + iResOffset = iEikEnv->AddResourceFileL( fileName ); + } + + + +// --------------------------------------------------------- +// CWEPSecuritySettingsUiImpl::EditL +// --------------------------------------------------------- +// +TInt CWEPSecuritySettingsUiImpl::EditL( CWEPSecuritySettingsImpl& aSettings, + const TDesC& aTitle ) + { + iEventStore = ENone; + + CWEPSecuritySettingsDlg* secSettDlg = + CWEPSecuritySettingsDlg::NewL( iEventStore ); + secSettDlg->ConstructAndRunLD( &aSettings, aTitle ); + + return iEventStore; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsUiPanic.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsUiPanic.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 panic function. +* +*/ + + +// INCLUDE FILES + +#include + +#include "WEPSecuritySettingsUiPanic.h" + + +// ================= LOCAL FUNCTIONS ======================= + +// --------------------------------------------------------- +// Panic() +// --------------------------------------------------------- +// +void Panic( TWepSecuritySettingsPanicCodes aPanic ) + { + _LIT( kWepSet, "WEPSecuritySettingsUi" ); + User::Panic( kWepSet, aPanic ); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wepsecuritysettingsui/src/WepKeyDataTextSettingPage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wepsecuritysettingsui/src/WepKeyDataTextSettingPage.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 CWEPKeyDataTextSettingPage. +* +*/ + + +// INCLUDE FILES + +//#include + +#include + +#include "WepKeyDataTextSettingPage.h" + + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWEPKeyDataTextSettingPage::CWEPKeyDataTextSettingPage +// --------------------------------------------------------- +// +CWEPKeyDataTextSettingPage::CWEPKeyDataTextSettingPage( TDes& aText, + TInt aMaxLength, + CWEPSecuritySettings::TWEPKeyFormat aWEPKeyFormat ) +:CAknTextSettingPage( R_TEXT_SETTING_PAGE_KEY_DATA, aText, + EAknSettingPageNoOrdinalDisplayed ), + iLengthOfKeyData( aMaxLength ), + iWEPKeyFormat( aWEPKeyFormat ) + { + } + + + +// --------------------------------------------------------- +// CWEPKeyDataTextSettingPage::ConstructL +// --------------------------------------------------------- +// +void CWEPKeyDataTextSettingPage::ConstructL() + { + CAknTextSettingPage::ConstructL(); + + CEikEdwin* editor = TextControl(); + + editor->SetMaxLength( iLengthOfKeyData ); + + if ( iWEPKeyFormat == CWEPSecuritySettings::EAscii ) + { + editor->SetOnlyASCIIChars( ETrue ); + editor->SetAknEditorCase( EAknEditorLowerCase ); + } + else + { + editor->SetAknEditorCase( EAknEditorUpperCase ); + editor->SetAknEditorSpecialCharacterTable( 0 ); + } + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/bwinscw/wifiprotclient_alru.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/bwinscw/wifiprotclient_alru.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,8 @@ +EXPORTS + ??1CWiFiProtUiClient@@UAE@XZ @ 1 NONAME ; CWiFiProtUiClient::~CWiFiProtUiClient(void) + ?CancelWiFiProt@CWiFiProtUiClient@@QAEXXZ @ 2 NONAME ; void CWiFiProtUiClient::CancelWiFiProt(void) + ?NewL@CWiFiProtUiClient@@SAPAV1@XZ @ 3 NONAME ; class CWiFiProtUiClient * CWiFiProtUiClient::NewL(void) + ?StartWiFiProtL@CWiFiProtUiClient@@QAEXABV?$TBuf8@$0CA@@@HAAV?$RArray@K@@AAW4TWiFiReturn@WiFiProt@@AAVTRequestStatus@@@Z @ 4 NONAME ; void CWiFiProtUiClient::StartWiFiProtL(class TBuf8<32> const &, int, class RArray &, enum WiFiProt::TWiFiReturn &, class TRequestStatus &) + ?StartWiFiProtSyncL@CWiFiProtUiClient@@QAE?AW4TWiFiReturn@WiFiProt@@ABV?$TBuf8@$0CA@@@HAAV?$RArray@K@@@Z @ 5 NONAME ; enum WiFiProt::TWiFiReturn CWiFiProtUiClient::StartWiFiProtSyncL(class TBuf8<32> const &, int, class RArray &) + ?StartWiFiProtConnL@CWiFiProtUiClient@@QAEXABV?$TBuf8@$0CA@@@AAUTWlanProtectedSetupCredentialAttribute@@AAW4TWiFiReturn@WiFiProt@@AAVTRequestStatus@@@Z @ 6 NONAME ; void CWiFiProtUiClient::StartWiFiProtConnL(class TBuf8<32> const &, struct TWlanProtectedSetupCredentialAttribute &, enum WiFiProt::TWiFiReturn &, class TRequestStatus &) + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/bwinscw/wifiprotpluginu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/bwinscw/wifiprotpluginu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,5 @@ +EXPORTS + ?NotifierArray@@YAPAV?$CArrayPtr@VMEikSrvNotifierBase2@@@@XZ @ 1 NONAME ; class CArrayPtr * NotifierArray(void) + ?NewL@CWifiProtUiInProcess@@SAPAV1@PAVRCmManagerExt@@@Z @ 2 NONAME ; class CWifiProtUiInProcess * CWifiProtUiInProcess::NewL(class RCmManagerExt *) + ?StartFromUiL@CWifiProtUiInProcess@@QAE?AW4TWiFiReturn@WiFiProt@@ABV?$TBuf8@$0CA@@@HAAV?$RArray@K@@@Z @ 3 NONAME ; enum WiFiProt::TWiFiReturn CWifiProtUiInProcess::StartFromUiL(class TBuf8<32> const &, int, class RArray &) + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/data/wifiprotplugin.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/data/wifiprotplugin.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,328 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This file contains all the resources for the Connection Ui Utilities Notifier +* +*/ + + +// RESOURCE IDENTIFIER +NAME AWPS // 4 letter ID + +// INCLUDES +#include +#include +#include +#include +#include + +#include +#include "wifiprotplugin.hrh" +#include + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + +RESOURCE TBUF { buf="WiFiProtPlugin"; } + + + +RESOURCE DIALOG r_wifiprot_configure_auto_dialog + { + flags = EEikDialogFlagNotifyEsc | EEikDialogFlagCbaButtons | + EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar ; + buttons = R_AVKON_SOFTKEYS_YES_NO__YES; + items = + { + DLG_LINE + { + type = EAknCtQuery; + id = EGeneralQuery; + control = AVKON_CONFIRMATION_QUERY + { + layout = EConfirmationLayout; + animation = R_QGN_NOTE_QUERY_ANIM; + label = qtn_ntw_conset_quest_wps_configure_auto; + }; + } + }; + } + +RESOURCE CBA r_softkeys_continue_cancel__continue + { + buttons = + { + CBA_BUTTON { id = EWiFiSoftkeyContinue; txt = qtn_text_sotkey_continue; }, + CBA_BUTTON { id = EAknSoftkeyCancel; txt = text_softkey_cancel; }, + CBA_BUTTON { id = EWiFiSoftkeyContinue; txt = qtn_text_sotkey_continue;} + }; + } + +RESOURCE CBA r_softkeys_select_cancel__select + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyView; txt = text_softkey_select; }, + CBA_BUTTON { id = EAknSoftkeyNo; txt = text_softkey_cancel; }, + CBA_BUTTON { id = EAknSoftkeyView; txt = text_softkey_select;} + }; + } + +RESOURCE DIALOG r_wifiprot_initiate_easy_setup_dialog + { + flags = EEikDialogFlagNotifyEsc | EEikDialogFlagCbaButtons | + EEikDialogFlagNoDrag ; + buttons = r_softkeys_continue_cancel__continue; + items = + { + DLG_LINE + { + type = EAknCtPopupHeadingPane; + id = EAknMessageQueryHeaderId; + control = AVKON_HEADING + { + label = qtn_netw_conset_prmpt_wps_initiate; + }; + }, + DLG_LINE + { + type = EAknCtMessageQuery; + id = EAknMessageQueryContentId; + control = AVKON_MESSAGE_QUERY + { + }; + } + }; + } + +RESOURCE DIALOG r_wifiprot_enter_pin_code_dialog + { + flags = EEikDialogFlagNotifyEsc | EEikDialogFlagCbaButtons | + EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar ; + buttons = r_softkeys_continue_cancel__continue; + items = + { + DLG_LINE + { + type = EAknCtQuery; + id = EGeneralQuery; + control = AVKON_CONFIRMATION_QUERY + { + layout = EConfirmationLayout; + animation = R_QGN_NOTE_INFO_ANIM; + label = qtn_netw_conset_wps_info_enter_pin_code; + }; + } + }; + } + + +RESOURCE DIALOG r_wifiprot_wait_note + { + flags = EAknWaitNoteFlags; + buttons = R_AVKON_SOFTKEYS_CANCEL; + items = + { + DLG_LINE + { + type = EAknCtNote; + id = EGeneralNote; + control= AVKON_NOTE + { + layout = EWaitLayout; + animation = R_QGN_GRAF_WAIT_BAR_ANIM; + }; + } + }; + } + + +RESOURCE DIALOG r_wifiprot_ok_note + { + flags = EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar | + EEikDialogFlagCbaButtons | EEikDialogFlagWait; + buttons = R_AVKON_SOFTKEYS_EMPTY; + items = + { + DLG_LINE + { + type = EAknCtNote; + id = EGeneralNote; + control = AVKON_NOTE + { + layout = EGeneralLayout; + animation = R_QGN_NOTE_OK_ANIM; + }; + } + }; + } + +RESOURCE DIALOG r_wifiprot_info_note + { + flags = EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar | + EEikDialogFlagCbaButtons | EEikDialogFlagWait; + buttons = R_AVKON_SOFTKEYS_EMPTY; + items = + { + DLG_LINE + { + type = EAknCtNote; + id = EGeneralNote; + control = AVKON_NOTE + { + layout = EGeneralLayout; + animation = R_QGN_NOTE_INFO_ANIM; + }; + } + }; + } + +RESOURCE DIALOG r_wifiprot_error_note + { + flags = EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar | + EEikDialogFlagCbaButtons | EEikDialogFlagWait; + buttons = R_AVKON_SOFTKEYS_EMPTY; + items = + { + DLG_LINE + { + type = EAknCtNote; + id = EGeneralNote; + control = AVKON_NOTE + { + layout = EGeneralLayout; + animation = R_QGN_NOTE_ERROR_ANIM; + }; + } + }; + } + +RESOURCE AVKON_LIST_QUERY r_conn_list_query + { + softkeys = R_AVKON_SOFTKEYS_SELECT_CANCEL__SELECT; + flags = EEikDialogFlagNotifyEsc; + + items = + { + AVKON_LIST_QUERY_DLG_LINE + { + id = EListQueryControl; + control = AVKON_LIST_QUERY_CONTROL_WITH_MSGBOX + { + actuallisttype = EAknCtSingleGraphicPopupMenuListBox; + listbox = AVKON_LIST_QUERY_LIST + { + flags = EAknListBoxSelectionList; + }; + + heading = qtn_netw_conset_wps_prmpt_select_network; + }; + } + }; + } + + + +RESOURCE TBUF r_qtn_wlan_info_no_networks_found + { + buf = qtn_wlan_info_no_networks_found; + } + +RESOURCE TBUF r_qtn_netw_conset_wps_detail_select_network + { + buf = qtn_netw_conset_wps_detail_select_network; + } + +RESOURCE TBUF r_qtn_netw_conset_wps_msg_pbc + { + buf = qtn_netw_conset_wps_msg_pbc; + } + +RESOURCE TBUF r_qtn_netw_conset_wps_info_enter_pin_code + { + buf = qtn_netw_conset_wps_info_enter_pin_code; + } + +RESOURCE TBUF r_qtn_netw_conset_wps_msg_link_use_pin + { + buf = qtn_netw_conset_wps_msg_link_use_pin; + } + +RESOURCE TBUF r_qtn_netw_conset_wait_wps_configuring + { + buf = qtn_netw_conset_wait_wps_configuring; + } + +RESOURCE TBUF r_qtn_netw_conset_conf_wps_one_network_configured + { + buf = qtn_netw_conset_conf_wps_one_network_configured; + } + +RESOURCE TBUF r_qtn_netw_conset_conf_wps_multiple_networks_config + { + buf = qtn_netw_conset_conf_wps_multiple_networks_config; + } + +RESOURCE TBUF r_qtn_netw_conset_conf_wps_no_networks_configured + { + buf = qtn_netw_conset_conf_wps_no_networks_configured; + } + +RESOURCE TBUF r_qtn_err_wlan_sc_config_failed_try_again + { + buf = qtn_err_wlan_sc_config_failed_try_again; + } + +RESOURCE TBUF r_qtn_err_wlan_sc_config_failed + { + buf = qtn_err_wlan_sc_config_failed; + } + +RESOURCE TBUF r_qtn_err_wlan_signal_too_weak + { + buf = qtn_err_wlan_signal_too_weak; + } + +RESOURCE TBUF r_qtn_err_wlan_network_not_found + { + buf = qtn_err_wlan_network_not_found; + } + +RESOURCE TBUF r_qtn_err_wlan_sc_config_failed_multiple_pb_sessions + { + buf = qtn_err_wlan_sc_config_failed_multiple_pb_sessions; + } + +RESOURCE TBUF r_qtn_err_wlan_sc_config_failed_rogue_activity + { + buf = qtn_err_wlan_sc_config_failed_rogue_activity; + } + +RESOURCE TBUF r_qtn_err_wlan_sc_config_failed_pin_not_supported + { + buf = qtn_err_wlan_sc_config_failed_pin_not_supported; + } + +RESOURCE TBUF r_qtn_err_wlan_sc_config_failed_pb_not_supported + { + buf = qtn_err_wlan_sc_config_failed_pb_not_supported; + } + +RESOURCE TBUF r_qtn_wlan_info_connection_already_active + { + buf = qtn_wlan_info_connection_already_active; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/eabi/wifiprotclient_alru.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/eabi/wifiprotclient_alru.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,14 @@ +EXPORTS + _ZN17CWiFiProtUiClient14CancelWiFiProtEv @ 1 NONAME + _ZN17CWiFiProtUiClient14StartWiFiProtLERK5TBuf8ILi32EEiR6RArrayImERN8WiFiProt11TWiFiReturnER14TRequestStatus @ 2 NONAME + _ZN17CWiFiProtUiClient18StartWiFiProtSyncLERK5TBuf8ILi32EEiR6RArrayImE @ 3 NONAME + _ZN17CWiFiProtUiClient4NewLEv @ 4 NONAME + _ZN17CWiFiProtUiClientD0Ev @ 5 NONAME + _ZN17CWiFiProtUiClientD1Ev @ 6 NONAME + _ZN17CWiFiProtUiClientD2Ev @ 7 NONAME + _ZTI17CWiFiProtUiClient @ 8 NONAME ; ## + _ZTI19CWiFiProtSyncClient @ 9 NONAME ; ## + _ZTV17CWiFiProtUiClient @ 10 NONAME ; ## + _ZTV19CWiFiProtSyncClient @ 11 NONAME ; ## + _ZN17CWiFiProtUiClient18StartWiFiProtConnLERK5TBuf8ILi32EER38TWlanProtectedSetupCredentialAttributeRN8WiFiProt11TWiFiReturnER14TRequestStatus @ 12 NONAME + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/eabi/wifiprotpluginu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/eabi/wifiprotpluginu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,11 @@ +EXPORTS + _Z13NotifierArrayv @ 1 NONAME + _ZN20CWifiProtUiInProcess12StartFromUiLERK5TBuf8ILi32EEiR6RArrayImE @ 2 NONAME + _ZN20CWifiProtUiInProcess4NewLEP13RCmManagerExt @ 3 NONAME + _ZTI19CWiFiProtDlgsPlugin @ 4 NONAME ; ## + _ZTI20CWifiProtUiInProcess @ 5 NONAME ; ## + _ZTI21CWiFiProtActiveRunner @ 6 NONAME ; ## + _ZTV19CWiFiProtDlgsPlugin @ 7 NONAME ; ## + _ZTV20CWifiProtUiInProcess @ 8 NONAME ; ## + _ZTV21CWiFiProtActiveRunner @ 9 NONAME ; ## + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This file provides the information required for building the Wi-Fi Protected Setup Ui. +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS +// export iby files + +../rom/WiFiProt.iby CORE_MW_LAYER_IBY_EXPORT_PATH(WiFiProt.iby) +../rom/WiFiProtResources.iby LANGUAGE_MW_LAYER_IBY_EXPORT_PATH(WiFiProtResources.iby) + + +// export localised loc file +../loc/wifiprot.loc MW_LAYER_LOC_EXPORT_PATH(wifiprot.loc) + +PRJ_MMPFILES + +./wifiprotclient.mmp +./wifiprotplugin.mmp + +// gnumakefile wifiprot_icons.mk + +PRJ_EXTENSIONS + +START EXTENSION s60/mifconv +OPTION TARGETFILE wifiprot.mif +OPTION HEADERFILE wifiprot.mbg +OPTION SOURCES -c8,1 qgn_prop_wlan_bearer +END + +PRJ_TESTMMPFILES + +// End of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/group/wifiprot_icons.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/group/wifiprot_icons.mk Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,66 @@ +# +# Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Symbian Foundation License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: Makefile for icons of Wi-Fi Protected Setup UI +# + +ifeq (WINS,$(findstring WINS, $(PLATFORM))) +ZDIR=\epoc32\release\$(PLATFORM)\$(CFG)\Z +else +ZDIR=\epoc32\data\z +endif + + +TARGETDIR=$(ZDIR)\resource\apps +ICONTARGETFILENAME=$(TARGETDIR)\wifiprot.mif + +HEADERDIR=\epoc32\include +HEADERFILENAME=$(HEADERDIR)\wifiprot.mbg + +do_nothing : + @rem do_nothing + +MAKMAKE : do_nothing + +BLD : do_nothing + +CLEAN : do_nothing + +LIB : do_nothing + +CLEANLIB : do_nothing + +# ---------------------------------------------------------------------------- +# NOTE 1: DO NOT DEFINE MASK FILE NAMES! They are included automatically by +# MifConv if the mask detph is defined. +# +# NOTE 2: Usually, source paths should not be included in the bitmap +# definitions. MifConv searches for the icons in all icon directories in a +# predefined order, which is currently \s60\icons, \s60\bitmaps2, \s60\bitmaps. +# The directory \s60\icons is included in the search only if the feature flag +# __SCALABLE_ICONS is defined. +# ---------------------------------------------------------------------------- + +RESOURCE : + mifconv $(ICONTARGETFILENAME) /h$(HEADERFILENAME) \ + /c8,1 qgn_prop_wlan_bearer.bmp + +FREEZE : do_nothing + +SAVESPACE : do_nothing + +RELEASABLES : + @echo $(HEADERFILENAME)&& \ + @echo $(ICONTARGETFILENAME) + +FINAL : do_nothing diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/group/wifiprotclient.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/group/wifiprotclient.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is project specification file for the ConnectionUiUtilities. +* +*/ + + +#include +#include + + +TARGET wifiprotclient.dll +TARGETTYPE DLL + +CAPABILITY CAP_GENERAL_DLL +VENDORID VID_DEFAULT + + +SOURCEPATH ../src +SOURCE wifiprotuiclient.cpp +SOURCE wifiprotsession.cpp +SOURCE wifiprotuiclientimpl.cpp +SOURCE wifiprotactiveresp.cpp +SOURCE wifiprotsyncclient.cpp + + +// Component specific internal headers +USERINCLUDE ../inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib +LIBRARY cone.lib +LIBRARY eikcore.lib +LIBRARY eikcoctl.lib +LIBRARY avkon.lib +LIBRARY eikdlg.lib +LIBRARY bafl.lib +LIBRARY commonengine.lib +LIBRARY aknskins.lib +LIBRARY featmgr.lib +LIBRARY aknnotify.lib +LIBRARY ecom.lib +LIBRARY aknlayout.lib + +LIBRARY flogger.lib + +#if defined( ARMCC ) + DEFFILE ../eabi/wifiprotclient_alr.def +#elif defined( WINSCW ) + DEFFILE ../bwinscw/wifiprotclient_alr.def +#endif + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/group/wifiprotplugin.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/group/wifiprotplugin.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is project specification file for the Wi-Fi Protected Setup Notifier +* +*/ + + +#include +#include + +TARGET wifiprotplugin.dll + +TARGETTYPE DLL + +TARGETPATH /system/libs + +UID 0x101FDFAE 0x10281BC0 + +CAPABILITY CAP_GENERAL_DLL + +VENDORID VID_DEFAULT + +START RESOURCE ../data/wifiprotplugin.rss +HEADER + TARGETPATH RESOURCE_FILES_DIR + LANGUAGE_IDS +END // RESOURCE + +SOURCEPATH ../pluginsrc +SOURCE wifiprotplugin.cpp +SOURCE wifiprotdlgsplugin.cpp +SOURCE wifiprotconfirmationnotedlg.cpp +SOURCE wifiprotenterpindlg.cpp +SOURCE wifiprotinitiateeasysetupdlg.cpp +SOURCE wifiprotselectnetworkdlg.cpp +SOURCE wifiprotactiverunner.cpp +SOURCE wifiprotuiinprocess.cpp + + +USERINCLUDE ../plugininc + +// Component specific internal headers +USERINCLUDE ../inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib +LIBRARY eikdlg.lib +LIBRARY eiksrv.lib +LIBRARY cone.lib +LIBRARY eikcore.lib +LIBRARY eikcoctl.lib +LIBRARY bafl.lib +LIBRARY avkon.lib +LIBRARY aknskins.lib +LIBRARY ecom.lib +LIBRARY eiksrvui.lib +LIBRARY aknnotify.lib +LIBRARY aknicon.lib +LIBRARY egul.lib +LIBRARY aknlayout.lib +LIBRARY akncapserverclient.lib +LIBRARY featmgr.lib +LIBRARY commonengine.lib +LIBRARY cmmanager.lib +LIBRARY wpasecuritysettingsui.lib +LIBRARY wepsecuritysettingsui.lib +LIBRARY commsdat.lib +LIBRARY charconv.lib +LIBRARY flogger.lib +LIBRARY efsrv.lib +LIBRARY centralrepository.lib + +#if defined(ARMCC) + DEFFILE ../eabi/wifiprotplugin.def +#elif defined( WINSCW ) + DEFFILE ../bwinscw/wifiprotplugin.def +#endif + + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/inc/wifiparams.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/inc/wifiparams.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declares the common used constants and types for Wi-Fi Protected Setup. +* +*/ + + +#ifndef T_WIFIPARAMS_H +#define T_WIFIPARAMS_H + +#include +#include +#include + +namespace WiFiProt + { + struct TWiFiInputParams + { + // ssid of the network we want to configure + TWlanSsid iSSid; + // a flag to indicate that a connection is needed + // when setup is complete + TBool iConnectionNeeded; + // constructor to initialise input parameters data + inline TWiFiInputParams( const TDesC8& aInitBuf, + const TBool aConnectionNeeded ); + }; + + const TInt KMaxNumberOfUids = 30; //to be specified + + struct TWiFiOutputParams + { + // returned iapids of the configured connection methods + TBuf8 iIapIds; + // return value, see TWiFiReturn + TWiFiReturn iReturn; + // constructor to initialise output parameters data + inline TWiFiOutputParams( const TDesC8& aInitBuf ); + }; + + struct TWiFiConnOutputParams + { + // returned iapids of the configured connection methods + TWlanProtectedSetupCredentialAttribute iNetworkSettings; + // return value, see TWiFiReturn + TWiFiReturn iReturn; + // constructor to initialise output parameters data + inline TWiFiConnOutputParams( + const TWlanProtectedSetupCredentialAttribute& aNetworkSettings ); + // default constructor + inline TWiFiConnOutputParams( ); + }; + } +#include "wifiparams.inl" +#endif // T_WIFIPARAMS_H + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/inc/wifiparams.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/inc/wifiparams.inl Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declares inline functions for input/output parameter sructures +* +*/ + + +#ifndef WIFIPARAMS_INL +#define WIFIPARAMS_INL + +using namespace WiFiProt; + +WiFiProt::TWiFiInputParams::TWiFiInputParams(const TDesC8& aInitBuf, + const TBool aConnectionNeeded): + iSSid(aInitBuf), + iConnectionNeeded(aConnectionNeeded) + { + + } + + +WiFiProt::TWiFiOutputParams::TWiFiOutputParams(const TDesC8& aInitBuf): + iIapIds(aInitBuf), + iReturn(EWiFiCancel) + { + + } + +WiFiProt::TWiFiConnOutputParams::TWiFiConnOutputParams( + const TWlanProtectedSetupCredentialAttribute& aNetworkSettings): + iNetworkSettings(aNetworkSettings), + iReturn(EWiFiCancel) + { + + } + +WiFiProt::TWiFiConnOutputParams::TWiFiConnOutputParams( ): + iNetworkSettings( TWlanProtectedSetupCredentialAttribute() ), + iReturn(EWiFiCancel) + { + + } +#endif // WIFIPARAMS_INL +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/inc/wifiprot.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/inc/wifiprot.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,148 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is a localisation file for Wi-Fi Protected Setup A .loc file is the one and only place where the logical strings to be localised are defined. +* +*/ + + + +// LOCALISATION STRINGS + +//d:Wi-Fi protected Setup initial query dialog. Asks the user if he wants to use easy setup. +//l:popup_note_window +//w: +//r:3.2 +#define qtn_ntw_conset_quest_wps_configure_auto "Selected network supports easy setup for receiving settings. Configure automatically?" + +//d:Left softkey text +//l:control_pane_t1 +//w: +//r:3.2 +// +#define qtn_text_sotkey_continue "Continue" + +//d:Wi-Fi protected Setup 'Initiate easy setup' query dialog heading text +//l:heading_pane_t1 +//w: +//r:3.2 +// +#define qtn_netw_conset_prmpt_wps_initiate "Initiate easy setup" + +//d:Wi-Fi protected Setup 'Initiate easy setup' query dialog text +//l:popup_info_list_pane_t1 +//w: +//r:3.2 +// +#define qtn_netw_conset_wps_msg_pbc "Push a button on the wireless station to initiate the easy setup process, and select 'Continue'." + + +//d:Link inside 'Initiate easy setup' to activate 'use PIN code' option +//l:popup_info_list_pane_t1 +//w: +//r:3.2 +// +#define qtn_netw_conset_wps_msg_link_use_pin "Use PIN code instead" + +//d:Wi-Fi protected Setup dialog to display PIN code that should be entered to wireless station. +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_netw_conset_wps_info_enter_pin_code "Enter '%N' on the wireless station and select 'Continue'" + +//d:Wi-Fi protected Setup wait note shown during configuring connection +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_netw_conset_wait_wps_configuring "Configuring connection..." + +//d:Wi-Fi protected Setup ok note shown after successful configuration of a single connection +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_netw_conset_conf_wps_one_network_configured "Settings configured for '%U' network" + +//d:Wi-Fi protected Setup ok note shown after successful configuration of multiple connections +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_netw_conset_conf_wps_multiple_networks_config "Settings for multiple networks configured" + +//d:Wi-Fi protected Setup ok note shown after unsuccessful configuration of network(s) +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_netw_conset_conf_wps_no_networks_configured "No settings received" + +//d:Wi-Fi protected Setup error note show when configuration fails +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed_try_again "Configuration failed. Please try again." + +//d:Wi-Fi protected Setup error note show when configuration fails and user is requested to try again +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed "Configuration failed." + +//d:Wi-Fi protected Setup error note show when configuration fails because signal is too weak +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_signal_too_weak "WLAN signal too weak. Move closer to wireless station." + +//d:Wi-Fi protected Setup error note show when configuration fails because WLAN network can't be found +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_network_not_found "Connection failed. Could not find WLAN network." + +//d:Wi-Fi protected Setup error note show when configuration fails because multiple push-button sessions +//d:were detected +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed_multiple_pb_sessions "Multiple push-button sessions detected. Wait a moment and try again, or use PIN code mechanism instead." + +//d:Wi-Fi protected Setup error note show when configuration fails and user is requested to try again with PIN code +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed_rogue_activity "Connection failed. Please try again with PIN code mechanism." + +//d:Wi-Fi protected Setup error note show when configuration fails because PIN code mechanism is not supported +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed_pin_not_supported "Configuration failed. Device you tried to connect to does not support PIN code mechanism." + +//d:Wi-Fi protected Setup error note show when configuration fails because push-button mechanism is not supported +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed_pb_not_supported "Configuration failed. Device you tried to connect to does not support push-button mechanism." +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/inc/wifiprotactiveresp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/inc/wifiprotactiveresp.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,164 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: CWiFiProtActiveResp class +* +*/ + + + +#ifndef C_WIFIPROTACTIVERESP_H +#define C_WIFIPROTACTIVERESP_H + +// INCLUDES +#include +#include "wifiparams.h" + +// CLASS DECLARATION + +/** +* ActiveObject for asynchronous operations +*/ +NONSHARABLE_CLASS( CWiFiProtActiveResp ) : public CActive + { + public: // Constructors and destructor + /** + * Two-phased constructor. + * @param aSSid contains SSid of the network we want to configure + * @param aConnectionNeeded ETrue if we need a connection + * via the configured network + * @param aUidsReturned uids of the configured connection methods + * @param aReturnValue - possible return values are ok, cancel + * process and not use + * protected setup (No Automatic Setup). + */ + static CWiFiProtActiveResp* NewL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, RArray& aUidsReturned, + WiFiProt::TWiFiReturn& aReturnValue ); + + /** + * Two-phased constructor. + * @param aSSid contains SSid of the network we want to configure + * via the configured network + * @param aNetworkSettings the configured network settings + * to be returned + * @param aReturnValue - possible return values are ok, cancel + * process and not use + * protected setup (No Automatic Setup). + */ + static CWiFiProtActiveResp* NewL( const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& aNetworkSettings, + WiFiProt::TWiFiReturn& aReturnValue ); + + /** + * Destructor. + */ + virtual ~CWiFiProtActiveResp(); + + public: // From base class + /** + * This function is called when the scheduled function ends. + */ + void RunL(); + + /** + * Cancel operations. + */ + void DoCancel(); + + + public: // New functions + /** + * Add this class on the ActiveScheduler and puts itself active. + * @param aStatus The status that is checked by the caller of the + * Authenticate dialog. + */ + void Observe( TRequestStatus &aStatus ); + + /** + * Returns the TWiFiInputParams + * @return A pointer to iWiFiInputParams. + */ + TPckgBuf* InputBuffer(); + + /** + * Returns the TWiFiOutputParams + * @return A pointer to iWiFiOutputParams. + */ + TPckgBuf* OutputBuffer(); + + /** + * Returns the TWiFiConnOutputParams + * @return A pointer to iConnWiFiOutputParams. + */ + TPckgBuf* ConnOutputBuffer(); + + private: + /** + * C++ default constructor. + * @param aSSid contains SSid of the network we want to configure + * @param aConnectionNeeded ETrue if we need a connection via the + * configured network + * @param aUidsReturned uids of the configured connection methods + * @param aReturnValue - possible return values are ok, cancel + * process and not use + * protected setup (No Automatic Setup). + */ + CWiFiProtActiveResp( const TWlanSsid& aSSid, + TBool aConnectionNeeded, RArray& aUidsReturned, + WiFiProt::TWiFiReturn& aReturnValue ); + + /** + * C++ default constructor. + * @param aSSid contains SSid of the network we want to configure + * @param aNetworkSettings network settings to be returned + * @param aReturnValue - possible return values are ok, cancel + * process and not use + * protected setup (No Automatic Setup). + */ + CWiFiProtActiveResp( const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& aNetworkSettings, + WiFiProt::TWiFiReturn& aReturnValue ); + /** + * By default Symbian 2nd phase constructor is private. + */ + void ConstructL( ); + + private: // Data + // The status that is checked by the caller of the Wi-Fi + // Protected Setup ui. Not owned. + TRequestStatus* iRequestStatus; + + // The address of the area where the caller of the Wi-Fi + // Protected Setup ui expects the value for iap list. Not owned. + RArray* iIapIds; + + //Contains the return value passed to the client + WiFiProt::TWiFiReturn& iReturnValue; + + // Packed buffer containing Wi-Fi Protected Setup output parameters. + TPckgBuf iWiFiOutputParams; + // Packed buffer containing Wi-Fi Protected Setup input parameters. + TPckgBuf iWiFiInputParams; + // Packed buffer containing Wi-Fi Protected Setup output parameters + // for connection creation mode. + TPckgBuf iWiFiConnOutputParams; + // network settings to be returned + // used only for connection creation + TWlanProtectedSetupCredentialAttribute* iNetworkSettings; + }; + + +#endif //C_WIFIPROTACTIVERESP_H + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/inc/wifiprotlogger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/inc/wifiprotlogger.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,123 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Definition of macros used for logging +* +*/ + + +#ifndef WIFIPROTLOGGER_H_INCLUDED +#define WIFIPROTLOGGER_H_INCLUDED + +// ========== INCLUDE FILES ================================ + +#include +#include + +#ifdef _DEBUG + +// Format string: enter function. +_LIT( KCCDLGLogEnterFn, "-> %S" ); +// Format string: leave function. +_LIT( KCCDLGLogLeaveFn, "<- %S" ); +// Format string: time. +_LIT( KCCDLGLogTimeFormatString, "%H:%T:%S:%*C2" ); + +// Logging directory. +_LIT( KCCDLGLogDir, "wps" ); +// Log file name. +_LIT( KCCDLGLogFile, "wps.txt" ); +_LIT( KCCDLGLogBanner, "****************\n\nWiFiProtectedSetupUi\n\n****************" ); +_LIT( KCCDLGLogExit, "WiFiProtectedSetupUi: Exit" ); + +#define CLOG_CREATE {FCreate();} +#define CLOG_DELETE {RFileLogger::Write(KCCDLGLogDir, KCCDLGLogFile, EFileLoggingModeAppend, KCCDLGLogExit);} +#define CLOG_ENTERFN(a) {_LIT(temp, a); RFileLogger::WriteFormat(KCCDLGLogDir, KCCDLGLogFile, EFileLoggingModeAppend, KCCDLGLogEnterFn, &temp);} +#define CLOG_LEAVEFN(a) {_LIT(temp, a); RFileLogger::WriteFormat(KCCDLGLogDir, KCCDLGLogFile, EFileLoggingModeAppend, KCCDLGLogLeaveFn, &temp);} +#define CLOG_WRITE(a) {_LIT(temp, a); RFileLogger::Write(KCCDLGLogDir, KCCDLGLogFile, EFileLoggingModeAppend, temp);} +#define CLOG_WRITE_TIMESTAMP(a) {_LIT(temp, a); TTime time; time.HomeTime(); TBuf<256> buffer; time.FormatL( buffer, KCCDLGLogTimeFormatString ); buffer.Insert(0, temp); RFileLogger::Write(KCCDLGLogDir, KCCDLGLogFile, EFileLoggingModeAppend, buffer); } +#define CLOG_WRITEF FPrint + +// --------------------------------------------------------- +// FPrint +// --------------------------------------------------------- +// +inline void FPrint(const TRefByValue aFmt, ...) + { + VA_LIST list; + VA_START(list,aFmt); + RFileLogger::WriteFormat(KCCDLGLogDir, KCCDLGLogFile, EFileLoggingModeAppend, aFmt, list); + } + +// --------------------------------------------------------- +// FPrint +// --------------------------------------------------------- +// +inline void FPrint(const TDesC& aDes) + { + RFileLogger::WriteFormat(KCCDLGLogDir, KCCDLGLogFile, EFileLoggingModeAppend, aDes); + } + +// --------------------------------------------------------- +// FHex +// --------------------------------------------------------- +// +inline void FHex(const TUint8* aPtr, TInt aLen) + { + RFileLogger::HexDump(KCCDLGLogDir, KCCDLGLogFile, EFileLoggingModeAppend, 0, 0, aPtr, aLen); + } + +// --------------------------------------------------------- +// FHex +// --------------------------------------------------------- +// +inline void FHex(const TDesC8& aDes) + { + FHex(aDes.Ptr(), aDes.Length()); + } + +// --------------------------------------------------------- +// FCreate +// --------------------------------------------------------- +// +inline void FCreate() + { + TFileName path( _L( "c:\\logs\\" ) ); + path.Append( KCCDLGLogDir ); + path.Append( _L( "\\" ) ); + RFs& fs = CEikonEnv::Static()->FsSession(); + fs.MkDirAll( path ); + RFileLogger::WriteFormat( KCCDLGLogDir, KCCDLGLogFile, + EFileLoggingModeAppend, KCCDLGLogBanner ); + } + +#else // ! _DEBUG + +// --------------------------------------------------------- +// FPrint +// --------------------------------------------------------- +// +inline void FPrint(const TRefByValue /*aFmt*/, ...) { }; + +#define CLOG_CREATE +#define CLOG_DELETE +#define CLOG_ENTERFN(a) +#define CLOG_LEAVEFN(a) +#define CLOG_WRITE(a) +#define CLOG_WRITEF 1 ? ((void)0) : FPrint +#define CLOG_WRITE_TIMESTAMP(a) + +#endif // _DEBUG + + +#endif // WIFIPROTLOGGER_H_INCLUDED diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/inc/wifiprotsession.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/inc/wifiprotsession.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: RWiFiProtSession class. +* +*/ + + + +#ifndef R_WIFIPROTSESSION_H +#define R_WIFIPROTSESSION_H + +// INCLUDES +#include + +#include "wifiparams.h" +#include "wifiprotactiveresp.h" + +// CLASS DECLARATION + +/** + * RWiFiProtSession + * Session class to handle communication with Notifier Framework + */ +class RWiFiProtSession : public RSessionBase + { + public: + + /** + * Constructor. + */ + RWiFiProtSession(); + + /** + * Destructor. + */ + ~RWiFiProtSession(); + + /** + * Connect to the notifier server. Must be called before any other + * function. + * @return KErrNone if connection succeeded and a standard error code + * otherwise. + */ + TInt Connect(); + + /** + * Disconnect from the notifier server. + */ + void Close(); + + /** + * Starts WiFi Protected Setup sequence + * @param aSSid contains SSid of the network we want to configure + * @param aConnectionNeeded not used anymore + * @param aUidsReturned uids of the configured connection methods + * @param aReturnValue - possible return values are ok, cancel + * process and not use protected setup (No Automatic Setup). + * @param aStatus - Request status of the client + */ + void StartWiFiProtL( const TWlanSsid& aSSid, TBool aConnectionNeeded, + RArray& aUidsReturned, + WiFiProt::TWiFiReturn& aReturnValue, + TRequestStatus& aStatus ); + + /** + * Starts WiFi Protected Setup sequence in Connection initiation mode + * (WPS phase 2 implementation) + * @param aSSid contains SSid of the network we want to configure + * @param aNetworkSettings configuration settings of the network to use + * for the connection (returned as the result of Protected Setup) + * @param aReturnValue - possible return values are ok, cancel + * process and not use protected setup (No Automatic Setup). + * @param aStatus - Request status of the client + */ + void StartWiFiProtConnL( const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& + aNetworkSettings, + WiFiProt::TWiFiReturn& aReturnValue, + TRequestStatus& aStatus ); + /** + * Cancels WiFi Protected Setup sequence + */ + void CancelWiFiProt(); + + private: + // Pointer to the client interface + RNotifier* iNotifier; + // Active object used to get TDesC data from the Notifier Framework + // message + CWiFiProtActiveResp* iWiFiProtActiveResp; + }; + +#endif /* R_WIFIPROTSESSION_H */ + +// End of File + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/inc/wifiprotsyncclient.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/inc/wifiprotsyncclient.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,120 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: CWiFiProtSyncClient class. +* +*/ + + +#ifndef C_WIFIPROTSYNCCLIENT_H +#define C_WIFIPROTSYNCCLIENT_H + +// INCLUDES +#include + +#include "wifiprotsession.h" + +/** +* CWiFiProtSyncClient +* Active object to convert a sychronous client call asynchronous, and +* return only when the request is completed +*/ +class CWiFiProtSyncClient : public CActive + { + public: + /** + * Two phased constructor + * @param aClient RWiFiProtSession class to handle communication with + * Notifier Framework + * @param aPriority Active object priority + **/ + static CWiFiProtSyncClient* NewL( RWiFiProtSession& aClient, + TInt aPriority = CActive::EPriorityStandard ); + /** + * Destructor + **/ + ~CWiFiProtSyncClient(); + + /** + * Starts WiFi Protected Setup sequence + * @param aSSid contains SSid of the network we want to configure + * @param aConnectionNeeded ETrue if we need a connection via the + * configured network + * @param aUidsReturned uids of the configured connection methods + * @return possible return values are ok, cancel process and not use + * protected setup (No Automatic Setup). + */ + WiFiProt::TWiFiReturn StartWiFiProtL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned + ); + + private: + // Each Notifier Framework call has a corresponding enum, + // and CWiFiProtSyncClient uses it to keep track of the + // currently active call + // The only one is ERunWiFiProt at the moment + enum TWiFiState + { + ENoState = 0, + // StartWiFiProtL was called + ERunWiFiProt + }; + + private: + /** + * Constructor + * @param aClient RWiFiProtSession class to handle communication + * with Notifier Framework + * @param aPriority Active object priority + **/ + CWiFiProtSyncClient( RWiFiProtSession& aClient, TInt aPriority ); + + /** + * Second phase constructor + **/ + void ConstructL(); + + /** + * Calls CActive::SetActive() and sets TWiFiState also + * @param aState identifier of the active call + **/ + void SetActive( TWiFiState aState ); + + /** From CActive */ + + /** + * @see CActive::DoCancel + **/ + virtual void DoCancel(); + + /** + * @see CActive::RunL + **/ + virtual void RunL(); + + private: + // RWiFiProtSession class to handle communication with Notifier + // Framework + RWiFiProtSession& iClient; + // identifier of the active call + CWiFiProtSyncClient::TWiFiState iState; + // Active Scheduler Waiter class to halt the process until the + // call is completed + CActiveSchedulerWait iWait; + }; + + +#endif //C_WIFIPROTSYNCCLIENT_H + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/inc/wifiprotuiclientimpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/inc/wifiprotuiclientimpl.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of class CWiFiProtUiClientImpl. +* +*/ + + +#ifndef C_WIFIPROTUICLIENTIMPL_H +#define C_WIFIPROTUICLIENTIMPL_H + +// INCLUDES +#include +#include + +#include "wifiparams.h" +#include "wifiprotsyncclient.h" + +// FORWARD DECLARATIONS +class CCommsDatabase; +class TConnectionPrefs; +class CAknGlobalNote; + + +// CLASS DECLARATION + +/** +* Wi-Fi Protected Setup. +* Implementation behind proxy class CWiFiProt. +*/ +NONSHARABLE_CLASS( CWiFiProtUiClientImpl ) : public CBase + { + public: + + /** + * Two-phased constructor. Leaves on failure. + * @return The constructed CConnectionUiUtilities object. + */ + static CWiFiProtUiClientImpl* NewL(); + + /** + * Destructor. + */ + virtual ~CWiFiProtUiClientImpl(); + + public: + /** + * Starts WiFi Protected Setup sequence - async version + * @param aSSid contains SSid of the network we want to configure + * @param aConnectionNeeded not used anymore + * @param aUidsReturned uids of the configured connection methods + * @param aReturnValue - possible return values are ok, cancel + * process and not use + * protected setup (No Automatic Setup). + */ + void StartWiFiProtL ( const TWlanSsid& aSSid, + TBool aConnectionNeeded, RArray& aUidsReturned, + WiFiProt::TWiFiReturn& aReturnValue, TRequestStatus& aStatus ); + + /** + * Starts WiFi Protected Setup sequence - sync version, returns + * when completed + * @param aSSid contains SSid of the network we want to configure + * @param aConnectionNeeded not used anymore + * @param aUidsReturned uids of the configured connection methods + * @return possible return values are ok, cancel process and not use + * protected setup (No Automatic Setup). + * We can return a value since the call is sychronous. + */ + WiFiProt::TWiFiReturn StartWiFiProtSyncL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned ); + + /** + * Starts WiFi Protected Setup sequence in Connection initiation mode + * (WPS phase 2 implementation) + * @param aSSid contains SSid of the network we want to configure + * @param aNetworkSettings configuration settings of the network to use + * for the connection (returned as the result of Protected Setup) + * @param aReturnValue - possible return values are ok, cancel + * process and not use protected setup (No Automatic Setup). + * @param aStatus - Request status of the client + */ + void StartWiFiProtConnL( const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& + aNetworkSettings, + WiFiProt::TWiFiReturn& aReturnValue, + TRequestStatus& aStatus ); + + /** + * Cancels WiFi Protected Setup sequence + */ + void CancelWiFiProt( ); + + private: // Constructors + + /** + * Constructor. + */ + CWiFiProtUiClientImpl(); + + /** + * Second-phase constructor. + */ + void ConstructL(); + + + // Data + private: + // notifier client + RWiFiProtSession iNotif; + // Synchronously callable client + CWiFiProtSyncClient* iWiFiProtSyncClient; + }; + + +#endif // C_WIFIPROTUICLIENTIMPL_H + +// End of File + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/loc/wifiprot.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/loc/wifiprot.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,177 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is a localisation file for Wi-Fi Protected Setup A .loc file is the one and only place where the logical strings to be localised are defined. +* +*/ + + + +// LOCALISATION STRINGS + +//d:Wi-Fi protected Setup initial query dialog. Asks the user if he wants to use easy setup. +//l:popup_note_window +//w: +//r:3.2 +#define qtn_ntw_conset_quest_wps_configure_auto "Selected network supports easy setup for receiving settings. Configure automatically?" + +//d:Left softkey text +//l:control_pane_t1 +//w: +//r:3.2 +// +#define qtn_text_sotkey_continue "Continue" + +//d:Wi-Fi protected Setup 'Initiate easy setup' query dialog heading text +//l:heading_pane_t1 +//w: +//r:3.2 +// +#define qtn_netw_conset_prmpt_wps_initiate "Initiate easy setup" + +//d:Wi-Fi protected Setup 'Initiate easy setup' query dialog text +//l:popup_info_list_pane_t1 +//w: +//r:3.2 +// +#define qtn_netw_conset_wps_msg_pbc "Push a button on the wireless station to initiate the easy setup process, and select 'Continue'." + + +//d:Link inside 'Initiate easy setup' to activate 'use PIN code' option +//l:popup_info_list_pane_t1 +//w: +//r:3.2 +// +#define qtn_netw_conset_wps_msg_link_use_pin "Use PIN code instead" + +//d:Wi-Fi protected Setup dialog to display PIN code that should be entered to wireless station. +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_netw_conset_wps_info_enter_pin_code "Enter '%N' on the wireless station and select 'Continue'" + +//d:Wi-Fi protected Setup 'Select Network' query dialog heading text +//l:heading_pane_t1 +//w: +//r:5.0 +// +#define qtn_netw_conset_wps_prmpt_select_network "Select network:" + +//d:Wi-Fi protected Setup 'Select Network' query dialog description text +//l:loc_type_pane +//w: +//r:5.0 +// +#define qtn_netw_conset_wps_detail_select_network "Settings for multiple networks received. Select the network to connect to:" + +//d:Wi-Fi protected Setup wait note shown during configuring connection +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_netw_conset_wait_wps_configuring "Configuring connection..." + +//d:Wi-Fi protected Setup ok note shown after successful configuration of a single connection +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_netw_conset_conf_wps_one_network_configured "Settings configured for '%U' network" + +//d:Wi-Fi protected Setup ok note shown after successful configuration of multiple connections +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_netw_conset_conf_wps_multiple_networks_config "Settings for multiple networks configured" + +//d:Wi-Fi protected Setup ok note shown after unsuccessful configuration of network(s) +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_netw_conset_conf_wps_no_networks_configured "No settings received" + +//d:"Search for WLAN" - information note +//l:popup_note_window +//w: +//r:5.0 +// +#define qtn_wlan_info_no_networks_found "No WLAN networks found" + + +//d:Wi-Fi protected Setup error note show when configuration fails +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed_try_again "Configuration failed. Please try again." + +//d:Wi-Fi protected Setup error note show when configuration fails and user is requested to try again +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed "Configuration failed." + +//d:Wi-Fi protected Setup error note show when configuration fails because signal is too weak +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_signal_too_weak "WLAN signal too weak. Move closer to wireless station." + +//d:Wi-Fi protected Setup error note show when configuration fails because WLAN network can't be found +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_network_not_found "Connection failed. Could not find WLAN network." + +//d:Wi-Fi protected Setup error note show when configuration fails because multiple push-button sessions +//d:were detected +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed_multiple_pb_sessions "Multiple push-button sessions detected. Wait a moment and try again, or use PIN code mechanism instead." + +//d:Wi-Fi protected Setup error note show when configuration fails and user is requested to try again with PIN code +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed_rogue_activity "Connection failed. Please try again with PIN code mechanism." + +//d:Wi-Fi protected Setup error note show when configuration fails because PIN code mechanism is not supported +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed_pin_not_supported "Configuration failed. Device you tried to connect to does not support PIN code mechanism." + +//d:Wi-Fi protected Setup error note show when configuration fails because push-button mechanism is not supported +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_err_wlan_sc_config_failed_pb_not_supported "Configuration failed. Device you tried to connect to does not support push-button mechanism." + +//d:Wi-Fi protected Setup error note show when WLAN connection already exists +//l:popup_note_window/opt1 +//w: +//r:3.2 +// +#define qtn_wlan_info_connection_already_active "A WLAN connection is already active. Close connection and try again." +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotactiverunner.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotactiverunner.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,504 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Implements a state - machine like active object that controls Wi-Fi Protected Setup Process. +* +*/ + + +#ifndef C_WIFIPROTACTIVERUNNER_H +#define C_WIFIPROTACTIVERUNNER_H + +// INCLUDES +#include +#include +#include +#include + +#include "wifiprotdlgsplugin.h" +#include "wifiparams.h" +#include "wifiprotactiverunnercallback.h" + + +//FORWARD DECLARATIONS +class CWlanMgmtClient; +class CMDBSession; +class CWiFiProtConfirmationNoteDlg; +class CWiFiProtInitiateEasySetupDlg; +class CWlanScanInfo; +class CWiFiProtEnterPinDlg; +class CWEPSecuritySettings; +class RCmConnectionMethodExt; + +//CONSTS +const TInt KMaxPINLength = 8; //is it really 8? +// ID of OfflineWlanNote dialog +const TUid KUidCOfflineWlanNoteDlg = { 0x101FD671 }; + +/** +* CWiFiProtActiveRunner +* State machine like object that manages Wi-Fi Protected setup ui process +* @since S60 v3.2 +*/ +class CWiFiProtActiveRunner : public CActive, public MProgressDialogCallback, + MActiveRunnerCallback + { + private: + // States to control Wi-Fi Protected Setup sequence + enum TWiFiProtStates + { + // Display 'Configure Automatically?' Dialog + EWiFiProtAskConfigureAutomatically = 1, + // Display 'Initiate Easy Setup?' Dialog + EWiFiProtInitiateEasySetup, + // If phone is in offline mode, continue with + // "Create WLAN connection in offline mode?" confirmation + EWifiProtOfflineQuery, + // Display 'Enter PIN code' Dialog + EWiFiProtUsePinCode, + // Starting wait dialog + EWiFiProtStartingWaitDlg, + // Configuring (Creating temp iap and making a call to wlan + // mgmt server ) + EWiFiProtConfiguring, + // Wlan Mgmt server returned + EWiFiProtWlanMgmtEngineReturned, + // Creating iap from parameters from wlan mgmt server + EWiFiProtCreateAllIaps, + // Configuration finished + EWiFiProtConfFinished, + // Destroying wait note + EWiFiProtDestroyWaitNote, + // Waiting for PIN query to exit + EWiFiProtWaitForPINQuery, + // Wlan Scan + EWiFiProtWlanScan, + // Displaying Select Connection Dialog + EWiFiProtSelectConnection, + // Displaying final note about configured settings + EWiFiProtSettingsConfNote, + // Finished, exiting + EWiFiProtFinished, + // Cancelled, exiting + EWiFiProtCancelled + }; + + // Asynchronous service to cancel + enum TWiFiProtOutstandingRequest + { + EWiFiProtReqNone = 0, + EWiFiProtReqConfirmDialog, + EWiFiProtReqInitDialog, + EWiFiProtReqWPS, + EWiFiProtReqWlanScan + }; + + public: + /** + * Two phased constructor + * @param aPriority Active object priority + */ + static CWiFiProtActiveRunner* NewL( CWiFiProtDlgsPlugin* aParent, + TInt aPriority = CActive::EPriorityStandard ); + + /** + * Destructor + */ + ~CWiFiProtActiveRunner(); + + + /** + * Starts Wi-Fi Protected Setup + * @param aSSid contains SSid of the network we want to configure + * @param aCmManagerToUse - RCmManagerExt to use. Must pass this + * to avoid CmManager database + * locking problems + */ + void StartProtectedSetupAsyncL ( const TWlanSsid& aSSid, + RArray& aUids, + RCmManagerExt& aCmManagerToUse ); + + /** + * Starts Wi-Fi Protected Setup in Connection creation mode + * @param aSSid contains SSid of the network we want to configure + * @param aNetworkSettings the configured network's settings to be + * returned + * @param aCmManagerToUse - RCmManagerExt to use. Must pass this + * to avoid CmManager database + * locking problems + * @return possible return values are ok, cancel process and not use + * protected setup (No Automatic Setup). + */ + void StartProtectedSetupConnL ( + const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& + aNetworkSettings, + RCmManagerExt& aCmManagerToUse ); + + /** + * Starts Wi-Fi Protected Setup using CActiveSchedulerWait block + * @param aSSid contains SSid of the network we want to configure + * @param aCmManagerToUse - RCmManagerExt to use. Must pass this + * to avoid CmManager database + * locking problems + * @return possible return values are ok, cancel process and not use + * protected setup (No Automatic Setup). + */ + WiFiProt::TWiFiReturn StartProtectedSetupL ( const TWlanSsid& aSSid, + RArray& aUids, + RCmManagerExt& aCmManagerToUse ); + + /** + * When the process is cancelled by the client rather than + * cancelled by the user, some things are taken care of + * a bit differently. + */ + void CancelByClient(); + + private: + + + /** + * Shows the first dialog in the sequence + */ + void ShowInitialDialogL (); + /** + * Shows connect in offline -notification. + */ + void ShowOfflineQuery (); + /** + * Shows the Initiate Easy Setup dialog + */ + void ShowInitiateEasySetupDialogL (); + + /** + * Shows the 'Enter PIN on Wireless Station' dialog + */ + void ShowEnterPinOnStationDialogL(); + + /** + * Shows waiting dialog + */ + void ShowWaitingDialogL(); + + /** + * Shows waiting dialog and proceeds with the process + */ + void ShowWaitingDialogAndProceedL(); + + /** + * Shows 'settings configured' dialog + * @param aWiFiProtState state to decide which note to display + */ + void ShowFinalNoteL(); + + /** + * wait note callback + */ + void DialogDismissedL( TInt aButtonId ); + + /** + * Creates Temporary iap (cm) which contains parameters to be passed + * to wlan engine + * @param aTempServId Temporary iap service id + * @return TUint32 iap id (cm uid) + */ + TUint32 CreateTempIapL( TUint32& aTempServId ); + + /** + * Calls the active object that calls wlan engine's RunProtectedSetup + * @param TUint32 aIap iap id (cm uid) + */ + void RunProtectedSetup( const TInt32 aIap ); + + /** + * Constructor + * @param aParent Parent object + * @param aPriority Active object priority + */ + CWiFiProtActiveRunner( CWiFiProtDlgsPlugin* aParent, TInt aPriority ); + + /** + * Second phase constructor + */ + void ConstructL(); + + /** From CActive */ + /** + @see CActive::DoCancel + */ + virtual void DoCancel(); + + /** + @see CActive::RunL + */ + virtual void RunL(); + + + /** + * Sets iNextWiFiProtState and completes the pending request + * used to step forward in the 'state machine' + * @param aNextState - the state to step to + */ + void SetNextStateAndComplete( TWiFiProtStates aNextState, + TInt aError = KErrNone ); + + /** + * Called from RunL in EWiFiProtConfiguring state + * Starts configuring the connection methods + */ + void ConfigureL(); + + /** + * Proceeds after DestroyWaitDialog or after PinQueryExitL and + * checks error state and continues with Wlan availability + * scan if needed + */ + void EvaluateResult(); + + /** + * Called from RunL in EWiFiProtConfFinished state + * Destroys the wait dialog as configuring is complete + */ + void DestroyWaitDialog(); + + /* + * Computes checksum number which is the last number of + * the 8 digit PIN code passed to wlan mgmt engine + * algorythm copied from Wi-Fi spec + * @param aPin Pin code + * @return last digit, to be appended to PIN + */ + TInt ComputeChecksum(TInt aPin); + + /* + * Creates a single iap (from the first network's parameters), + * and then repeats the process for each iap + * The iap parameters at 0 index (in iIapParametersArray) will be + * used to create an iap. passed to CreateIapL. + */ + void CreateAllIapsL(); + + /** + * Creates Connection Method using RCmManagerExt + * The iap parameters at the given index (in iIapParametersArray) + * will be used to create an iap. Then the parameters entry will + * be deleted from iIapParametersArray + * and the new iap's id will be added to iCmArray. + * @param TInt aIndex index of the connection method (iap) to create + * in iIapParametersArray + * @return IapId of the cm + */ + TUint32 CreateIapL( const TInt aIndex ); + + /** + * Sets iap settings to a given connection method object and saves it + * @param TInt aIndex index of the connection method (iap) + * in iIapParametersArray + * @param aCmToSet target connection method object + * @return IapId of the cm + */ + TUint32 SetIapDataL( const TInt aIndex, RCmConnectionMethodExt& aCmToSet ); + + // calls DeleteTempIapL, and also steps the state machine + void CleanupTempIapL(); + + /** + * Deletes temporary iap + */ + void DeleteTempIapL(); + + /** + * Returns wep format, ETrue if it is in hex + * @param aLength Wep key length + */ + TBool IsWepFormatHexL( TInt aLength ); + + /** + * Saves wep security settings from the + * given credential parameters + * @param aCredentialAttribute credential parameters including wep + * security settings data + * @param aWlanServiceId Wlan service id + * @param aDb Database session needed for saving + * wep security settings + */ + void SaveWepSecuritySettingsL( + TWlanProtectedSetupCredentialAttribute + aCredentialAttribute, + TUint32 aWlanServiceId, + CommsDat::CMDBSession& aDb ); + + /** + * Handles the given error code by dispaying an error note + * @param aErrorCode error code to handle + */ + TBool HandleErrorL( TInt aErrorCode ); + + /** + * Steps into the next state of Wi-Fi Protected Setup sequence + * called from RunL() + */ + void HandleNoErrorL (); + + + /** + * From MActiveRunnerCallback + * called when CWifiProtEnterPinDlg is finished + * @param TInt aResponse can be KErrNone or KErrCancel + */ + void PinQueryExitL( TInt aResponse ); + + /** + * Called by UsePinCodeLinkSelectedL when pin code mechanism + * is selected. Sets iUsePin flag and completes Active Runner + * (this) object + */ + void DoUsePinCodeLinkSelectedL(); + + /** + * Starts wlan scan + */ + void StartWlanScan(); + + /** + * Compares the fresh wlan networks list with the + * items returned by WPS. Puts the available network indexes + * into iAvailableNetworks + */ + void CheckNetworkAvailabilityL(); + + /* + * Displays the Select Connection Dialog + * When there are more connections available to use + * (used in Create Connection Mode) + */ + void SelectConnectionL(); + + /* + * Displays a note to show the user that + * no wlan networks were found during wlan scan + */ + void ShowNoWlanNetworksNoteL(); + + /* + * Calls cancel on the possibly currently ongoing request + */ + void CancelOngoingRequest(); + + /** + * Sets wep key + * @param aWepSecSettings Wep security settings object + * @param aWepKey Wep key to set + * @param aKeyNumber number of wep key to set + */ + void SetWepKeyL( CWEPSecuritySettings& aWepSecSettings, + TWlanWepKey& aWepKey, TInt aKeyNumber ); + + public: + /** + * Callback to handle pin code pin code mechanism link selection + */ + static TInt UsePinCodeLinkSelectedL( TAny* aObject ); + + private: + // reference to parent object + CWiFiProtDlgsPlugin* iParent; + // wait dialog + CAknWaitDialog* iWaitDlg; ///Owned + // RCmManagerExt object for Cm Manager operations + RCmManagerExt* iCmManagerExt; //NOT OWNED!!! + // ETrue if connection is needed after the Wi-Fi Protected + // setup. + TBool iIsConnectionNeeded; + // Array to store returned uids of created iaps (connection methods) + RArray* iUids;//NOT OWNED!!! + // flag to indicate that wait dialog was cancelled + TBool iWaitDlgCancelled; + // ssid of the network to setup + TWlanSsid iSsid; + // iap id of the temporary iap + TUint32 iTempIapId ; + // service id of the temporary iap + TUint32 iTempServId ; + // PIN code (holds a value only if PIN method is used) + // for Wi-Fi Protected Setup authentication + TBuf iPIN; + // Wlan mgmt engine + CWlanMgmtClient* iWlanMgmtEngine; + // Next state, checked in RunL to control the setup process + TWiFiProtStates iNextWiFiProtState; + // return value + WiFiProt::TWiFiReturn iReturn; + // A flag to indicate that PIN method is used + TBool iUsePin; + // Holds the error code from wlan mgmt engine after + // our wlan mgmt server request is complete + TInt iError; + // Active Scheduler wait object to hold the process until we are + // complete + CActiveSchedulerWait iWait; + // Array to hold the connection methods which are created from + // the data returned from wlan mgmt engine + RPointerArray iCmArray;//used to store cms + // before submitting them + // The connection metod parameters returned from wlan mgmt engine + CArrayFixSeg* + iIapParametersArray; //parameters from wlan mgmt engine + // ETrue if Pin Query Dialog is active + TBool iPinQueryActive; + // ETrue if a wait note is needed to be shown + TBool iWaitNoteNeeded; + // initiate setup dialog is stored to handle link selection callback, + // not owned + CWiFiProtInitiateEasySetupDlg* iInitDialog; + // Wlan Scan Info + CWlanScanInfo* iScanInfo; + // List of available networks, contains indexes for iIapParametersArray + RArray iAvailableNetworks; + // index of selected network in iAvailableNetworks + TInt iSelectedNetworkIndex; + // ongoing request to cancel if cancelled + TWiFiProtOutstandingRequest iORequest; + // Cancel called by user, cancel at next RunL cycle + TBool iUserCancelled; + // ETrue if the process is cancelled by the client. + TBool iClientCancelled; + // Flag to indicate that the 'use pin code' link was used + // and we have to destroy the dialog later, because avkon crashes if + // we do it in the callback (DoUsePinCodeLinkSelectedL) + TBool iDestroyInitDialogLater; + // not owned, just keeping pointer to handle cancel softkey removal + CWiFiProtEnterPinDlg* iPinDlg; + //pointer to network settings to be returned if WPS is used for + // connection creation + TWlanProtectedSetupCredentialAttribute* iNetworkSettings; + // ETrue if the WPS process is used in synchronous mode + TBool iSyncMode; + // ETrue if phone is in offline mode. + TBool iInOfflineMode; + // Stores data for offline note. Used + // only for writing result. Not read. + TPckgBuf iOfflineReply; + // Interface to Notifier + RNotifier iNotifier; + // Pointer to the 1st confirmation dialog. Owned. + CWiFiProtConfirmationNoteDlg* iConfirmationDialog; + + + + }; + +#endif //C_WIFIPROTACTIVERUNNER_H + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotactiverunnercallback.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotactiverunnercallback.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Defines MActiveRunnerCallback interface +* +*/ + + +#ifndef M_ACTIVERUNNERCALLBACK_H +#define M_ACTIVERUNNERCALLBACK_H +/** + * MActiveRunnerCallback + * callback interface to handle PIN query exit + * @since S60 v3.2 +*/ +class MActiveRunnerCallback + { + public: + /** + * called when CWifiProtEnterPinDlg is finished + * @param TInt aResponse can be KErrNone or KErrCancel + */ + virtual void PinQueryExitL( TInt aResponse ) = 0; + }; +#endif //M_ACTIVERUNNERCALLBACK_H \ No newline at end of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotconfirmationnotedlg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotconfirmationnotedlg.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWiFiProtConfirmationNoteDlg. +* +*/ + + +#ifndef C_WIFIPROTCONFIRMATIONNOTEDLG_H__ +#define C_WIFIPROTCONFIRMATIONNOTEDLG_H__ + +// INCLUDES +#include + +// CLASS DECLARATIONS + +/** + * Class implements a query dialog. + */ +NONSHARABLE_CLASS( CWiFiProtConfirmationNoteDlg ) : public CAknQueryDialog + { +public: + /** + * Constructor the CWiFiProtConfirmationNoteDlg class + * @param aStatus TRequestStatus of the client, + * gets completed when dialog finishes + * @return - + */ + CWiFiProtConfirmationNoteDlg( TRequestStatus& aStatus ); + + /** + * Destructor + */ + virtual ~CWiFiProtConfirmationNoteDlg(); + + /** + * From @c MEikCommandObserver. + * + * Acts on the menu selection if menu is showing + * @param aCommandId id of the command to process + * + * Responds to @c EAknSoftkeyOk and @c EAknSoftkeyYes and + * @c EAknSoftkeyDone and @c EWiFiSoftkeyContinue commands. + * + * @since S60 3.0 + */ + void ProcessCommandL( TInt aCommandId ); + +private: + + /** + * Exit function the CWiFiProtConfirmationNoteDlg + * @param aButtonId Button id which is checked before + * deciding to exit or not + * @return TBool exit or no + */ + virtual TBool OkToExitL( TInt aButtonId ); + + /** + * PreLayoutDynInitL + */ + virtual void PreLayoutDynInitL(); + +private: + // Client's request status, dialog completes it when it finished + TRequestStatus& iRequestStatus; + }; + + +#endif // C_WIFIPROTCONFIRMATIONNOTEDLG_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotdlgsplugin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotdlgsplugin.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,221 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of CWiFiProtDlgsPlugin +* +*/ + + + +#ifndef C_WIFIPROTDLGSPLUGIN_H +#define C_WIFIPROTDLGSPLUGIN_H + + +// INCLUDES +#include +#include +#include +#include + +using namespace WiFiProt; + +class TWiFiOutputParams; +class CWiFiProtActiveRunner; + + + + + +/** + * CWiFiProtDlgsPlugin class + * Notifier Framework plugin for Wi-Fi Protected Setup + */ +class CWiFiProtDlgsPlugin : public CBase, public MEikSrvNotifierBase2 + + { + +public: + + /** + * NewL function + * @param aResourceFileResponsible - ETrue if the plugin handles the + * resource file + * @param aCmManagerExt - CmManager to use during Wi-Fi Protected Setup + * return CWiFiProtDlgsPlugin* + */ + static CWiFiProtDlgsPlugin* NewL( const TBool aResourceFileResponsible, + RCmManagerExt* aCmManagerExt ); + + /** + * NewL function + * @param aResourceFileResponsible - ETrue if the plugin handles the + * resource file + * return CWiFiProtDlgsPlugin* + */ + static CWiFiProtDlgsPlugin* NewL( const TBool aResourceFileResponsible ); + + + /** + * Destructor + */ + ~CWiFiProtDlgsPlugin( ); + + // From MEikSrvNotifierBase + + /** + * Get Notifier information + * return TNotifierInfo Notifier info + */ + TNotifierInfo Info() const; + + /** + * Start the Notifier + * @param aBuffer Not used + * return TPtrC8 Always NULL + */ + TPtrC8 StartL( const TDesC8& aBuffer ); + + /** + * Cancel() the notifier + * @param - + * return - + */ + void Cancel(); + + /** + * Release the notifier + * @param - + * return - + */ + void Release(); + + /** + * Update Notifier + * @param aBuffer Not used + * return TPtrC8 Always NULL + */ + TPtrC8 UpdateL( const TDesC8& aBuffer ); + + /** + * CompleteL the notifier is complete + * @param aStatus status + * return - + */ + void CompleteL( TInt aStatus ); + + /** + * Sets iCancelled flag that indicates that the notifier was cancelled + * @param aCancelled Not used + */ + void SetCancelledFlag( TBool aCancelled ); + + /** + * RegisterL register the client notifier function + * return TNotifierInfo Contains uid, channel and priority of + * the registered notifier + */ + TNotifierInfo RegisterL(); + + /** + * Start the Notifier + * @param aBuffer Buffer that stores parameters from client side + * @param aReplySlot Identifies which message argument to use for the + * reply. This message argument will refer to a + * modifiable descriptor, a TDes8 type, into which data + * can be returned. + * @param aMessage Message + */ + void StartL( const TDesC8& aBuffer, TInt aReplySlot, + const RMessagePtr2& aMessage ); + + /** + * Asynchronous notifier dialog sequence is completed by calling this function. + * @param aReturnValue - possible return values are ok, cancel + * process and not use protected setup (No Automatic Setup). + */ + void CompleteProcessL( WiFiProt::TWiFiReturn aReturnValue ); + + /** + * Starts Wi-Fi Protected Setup + * Private interface to be used by applications with ui + * runs in the same process, so pointers can be passed + * @param aSSid contains SSid of the network we want to configure + * @param aConnectionNeeded ETrue if we need a connection via the + * configured network + * @param aUidsReturned uids of the configured connection methods + * @return aReturnValue - possible return values are ok, cancel + * process and not use protected setup (No Automatic Setup). + */ + + WiFiProt::TWiFiReturn StartFromUiL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned); + + +private: + + /** + * Returns the correct RCmManagerExt instance's reference + * it can be an own instance, or a passed reference in case + * StartFromUiL was called (we are in the same process as the caller) + * This is necessary because we can't open two CmManagers the same time + * and the client is possibly using one already. + * @return a passed or an own RCmManagerExt& instance, based on the + * method of calling CWiFiProtDlgsPlugin + */ + RCmManagerExt& CmManagerToUse(); + +private: + + /** + * Constructor + */ + CWiFiProtDlgsPlugin( ); + + /** + * CWiFiProtDlgsPlugin second level constructor + * @param aResourceFileName Resource file to open + * @param aResourceFileResponsible ETrue if this notifier is + * responsible for the resource file + * @param aCmManagerExt CmManager to use + * @see CWiFiProtDlgsPlugin::CmManagerToUse + */ + void ConstructL( const TDesC& aResourceFileName, + const TBool aResourceFileResponsible, + RCmManagerExt* aCmManagerExt = NULL ); + + + +private: + + RCmManagerExt iCmManagerExt; // own CmManager + RCmManagerExt* iPassedCmManagerExt; // passed CmManager, not owned + CWiFiProtActiveRunner* iRunner; // Active Runner object + TWiFiReturn iReturn; // return value towards the client + RArray iUids; // uids of created connection methods + TNotifierInfo iInfo; // Notifier info + RMessagePtr2 iMessage; // Message + TInt iReplySlot; // Reply slot + TBool iCancelled; // ETrue if WPS process is cancelled + TInt iResource; // Resource + TBool iConnMode; // ETrue if creating a connection + // network settings to be returned if WPS is used for connection creation + TWlanProtectedSetupCredentialAttribute iNetworkSettings; + TBool iCancelledFromInside; // ETrue if user or WLAN engine has cancelled + TBool iClientCancelled; // ETrue if the notifier client has called Cancel() + }; + + +#endif // C_WIFIPROTDLGSPLUGIN_H + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotenterpindlg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotenterpindlg.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWiFiProtEnterPinDlg. +* +*/ + + +#ifndef C_WIFIPROTENTERPINDLG_H +#define C_WIFIPROTENTERPINDLG_H + +// INCLUDES +#include + +// FORWARD DECLARATIONS +class MActiveRunnerCallback; + +// CLASS DECLARATIONS + +/** + * Class implements a query dialog. + */ +NONSHARABLE_CLASS( CWiFiProtEnterPinDlg ) : public CAknQueryDialog + { +public: + /** + * Constructor of the CWiFiProtEnterPinDlg class + * @param MActiveRunnerCallback& aActiveRunnerCallback callback to + * notify the client of user response + * Active Runner gets completed when the dialog finishes + */ + CWiFiProtEnterPinDlg( MActiveRunnerCallback& aActiveRunnerCallback ); + + + /** + * Destructor + */ + virtual ~CWiFiProtEnterPinDlg(); + + /** + * From @c MEikCommandObserver. + * + * Acts on the menu selection if menu is showing + * @param aCommandId id of the command to process + * + * Responds to @c EAknSoftkeyOk and @c EAknSoftkeyYes and + * @c EAknSoftkeyDone and @c EWiFiSoftkeyContinue + * @c EAknSoftkeyEmpty commands. + * + * @since S60 3.0 + */ + void ProcessCommandL( TInt aCommandId ); + + /* + * Removes Cancel softkey + */ + void RemoveCancel(); + +private: + + /** + * Exit function the CWiFiProtConfirmationNoteDlg + * @param aButtonId + * @return TBool exit or no + */ + virtual TBool OkToExitL( TInt aButtonId ); + + /** + * PreLayoutDynInitL + * @param - + */ + virtual void PreLayoutDynInitL(); +private: + // Client's request status, dialog completes it when it finished + MActiveRunnerCallback& iActiveRunnerCallback; + }; + + +#endif // C_WIFIPROTENTERPINDLG_H + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotinitiateeasysetupdlg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotinitiateeasysetupdlg.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,106 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of class CWiFiProtInitiateEasySetupDlg. +* +*/ + + +#ifndef C_WIFIPROTINITIATEEASYSETUPDLG_H +#define C_WIFIPROTINITIATEEASYSETUPDLG_H + +// INCLUDES +#include + +// CLASS DECLARATIONS +/** + * Class implements a query dialog. + */ +NONSHARABLE_CLASS( CWiFiProtInitiateEasySetupDlg ) : + public CAknMessageQueryDialog + { +public: + /** + * Constructor the CWiFiProtInitiateEasySetupDlg class + * @param aStatus Request status of the Active Runner + */ + CWiFiProtInitiateEasySetupDlg( TRequestStatus& aStatus ); + + /** + * Destructor + */ + virtual ~CWiFiProtInitiateEasySetupDlg(); + + /** + * From @c MEikCommandObserver. + */ + + /** + * Tries to exit the dialog when the specified button is pressed, if this + * button should exit the dialog. + * + * See @c OkToExitL() to determine which buttons can exit the dialog. + * + * This will fail if user exit is prevented by the + * @c EEikDialogFlagNoUserExit flag. If the @c EEikDialogFlagNotifyEsc flag + * is not set and the dialog has been cancelled it immediately deletes + * itself. + * + * @param aButtonId The id of the pressed button. + */ + void TryExitL( TInt aButtonId ); + +private: + + /** + * Exit function of CWiFiProtInitiateEasySetupDlg + * @param aButtonId + * @return TBool exit or no + */ + virtual TBool OkToExitL( TInt aButtonId ); + + /** + * PreLayoutDynInitL + * @param - + */ + virtual void PreLayoutDynInitL(); + + /** + * From @c CCoeControl. + * + * Handles key events. + * + * If a control wishes to process key events, it should implement this + * function. The implementation must ensure that the function returns + * @c EKeyWasNotConsumed if it does not do anything in response to a + * key event, otherwise, other controls or dialogs may be prevented + * from receiving the key event. If it is able to process the event it + * should return @c EKeyWasConsumed. + * + * @param aKeyEvent The key event. + * @return Indicates whether or not the key event was used + * by this control. + */ + TKeyResponse OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode ); + +private: + // flag to indicate that the button group was changed + // this is needed for changing softkey when selecting link + TBool iButtonGroupPreviouslyChanged; + // Client's request status, dialog completes it when it finished + TRequestStatus& iRequestStatus; + }; + +#endif // C_WIFIPROTINITIATEEASYSETUPDLG_H + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotplugin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotplugin.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of Wi-Fi Protected Setup Notifier Array +* +*/ + + +#ifndef WIFIPROTPLUGIN_H +#define WIFIPROTPLUGIN_H + + +// INCLUDES +#if !defined(__EIKNOTAPI_H__) +#include +#endif + +// GLOBAL FUNCTIONS +// +/** +* Array of connection dialog plugins. +* @return A CArrayPtr of MEikSrvNotifierBase2 based classes. +*/ +IMPORT_C CArrayPtr* NotifierArray(); + + +// RSC file name. +_LIT( KResourceFileName, "WiFiProtPlugin.rsc" ); + + +#endif //WIFIPROTPLUGIN_H + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotplugin.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotplugin.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This file contains declarations for resources of Connection Ui Utilities Notifier. The file can be included in C++ or resource file. +* +*/ + + +#ifndef WIFIPROTPLUGIN_HRH +#define WIFIPROTPLUGIN_HRH + +// IDs of controls + + +enum TWiFiProtPluginIds + { + WiFiProtPlugin = 0x222 // is it correct? + }; + +enum TWiFiProtCommandIds + { + EWiFiSoftkeyContinue = 1 + }; + +#endif // WIFIPROTPLUGIN_HRH + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotselectnetworkdlg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/plugininc/wifiprotselectnetworkdlg.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Definition of class CWiFiProtSelectNetworkDlg. +* +*/ + + +#ifndef C_WIFIPROTSELECTNETWORKDLG_H +#define C_WIFIPROTSELECTNETWORKDLG_H + +// INCLUDES +#include + +// CLASS DECLARATIONS +/** + * Class implements a query dialog. + */ +NONSHARABLE_CLASS( CWiFiProtSelectNetworkDlg ) : public CAknListQueryDialog + { +public: + /** + * Constructor the CWiFiProtSelectNetworkDlg class + * @param aStatus TRequestStatus from activerunner + * @param aSelected returned selection index + * @param CDesCArrayFlat* aItems listbox items, ownership passed + * @param CArrayPtr* aIcons listbox icons, ownership passed + * @return - + */ + CWiFiProtSelectNetworkDlg( TRequestStatus& aStatus , TInt& aSelected , + CDesCArrayFlat* aItems, + CArrayPtr* aIcons ); + + /** + * Destructor + */ + virtual ~CWiFiProtSelectNetworkDlg(); + + /** + * Calls PrepareLC and RunLD with the supplied parameters + */ + void PrepareAndRunLD( ); + + +private: + + /** + * Exit function of CWiFiProtSelectNetworkDlg + * @param aButtonId + * @return TBool exit or no + */ + virtual TBool OkToExitL( TInt aButtonId ); + + /** + * PreLayoutDynInitL + */ + void PreLayoutDynInitL(); + + /** + * Handles a change to the application's resources. + * @param aType Type of resource change + */ + void HandleResourceChange( TInt aType ); + +private: + // Client's request status, dialog completes it when it finished + TRequestStatus& iRequestStatus; + // Selected item's index + TInt& iSelected; + // Icons array + CArrayPtr* iIcons; + // Items array + CDesCArrayFlat* iItems; + }; + +#endif // C_WIFIPROTSELECTNETWORKDLG_H + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotactiverunner.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotactiverunner.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,2053 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Implements a state - machine like active object that controls Wi-Fi Protected Setup Process. +* +*/ + + +//SYSTEM INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +//USER INCLUDES +#include "wifiprotlogger.h" +#include "wifiprotactiverunner.h" +#include "wifiprotconfirmationnotedlg.h" +#include "wifiprotselectnetworkdlg.h" +#include "wifiprotenterpindlg.h" +#include "wifiprotinitiateeasysetupdlg.h" + +#include "FeatMgr.h" + +// valid Wep key lengths, to check wep key format +// (wep key format depends on key length) +const TInt KConnUiUtilsWepLengthASCII5 = 5; +const TInt KConnUiUtilsWepLengthASCII13 = 13; +const TInt KConnUiUtilsWepLengthASCII29 = 29; +const TInt KConnUiUtilsWepLengthHEX10 = 10; +const TInt KConnUiUtilsWepLengthHEX26 = 26; +const TInt KConnUiUtilsWepLengthHEX58 = 58; +#ifdef __WINS__ +const TInt KNumberOfEmulatedAvailableNetworks = 2; +const TInt KIndexOfFirstEmulatedAvailableNetwork = 0; +const TInt KIndexOfSecondEmulatedAvailableNetwork = 1; +#endif + +/** +* Management frame information element IDs. +* needed to determine coverage +*/ +enum T802Dot11InformationElementID + { + E802Dot11SsidIE = 0, + E802Dot11SupportedRatesIE = 1, + E802Doi11FhParameterSetIE = 2, + E802Dot11DsParameterSetIE = 3, + E802Dot11CfParameterSetIE = 4, + E802Dot11TimIE = 5, + E802Dot11IbssParameterSetIE = 6, + E802Dot11CountryIE = 7, + E802Dot11HoppingPatternParamIE = 8, + E802Dot11HoppingPatternTableIE = 9, + E802Dot11RequestIE = 10, + + E802Dot11ChallengeTextIE = 16, + // Reserved for challenge text extension 17 - 31 + E802Dot11ErpInformationIE = 42, + E802Dot11ExtendedRatesIE = 50, + E802Dot11AironetIE = 133, + E802Dot11ApIpAddressIE = 149, + E802Dot11RsnIE = 221 + }; + +const TInt KArrayGranularity = 10; +const TInt KIconsGranularity = 4; + +_LIT( KWiFiFileIcons, "z:wifiprot.mbm" ); + +_LIT8( KEapWsc, "\xFE\x00\x37\x2A\x00\x00\x00\x01"); + +_LIT( KWiFiPanic, "Wi-Fi Protected Setup"); + +using namespace CMManager; + +// ================= MEMBER FUNCTIONS ======================= +// +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::NewL +// -------------------------------------------------------------------------- +// +CWiFiProtActiveRunner* CWiFiProtActiveRunner::NewL( + CWiFiProtDlgsPlugin* aParent, TInt aPriority ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::NewL" ); + + CWiFiProtActiveRunner* self = + new(ELeave) CWiFiProtActiveRunner( aParent, aPriority ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); // self + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::NewL" ); + + return self; + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::~CWiFiProtActiveRunner +// -------------------------------------------------------------------------- +// +CWiFiProtActiveRunner::~CWiFiProtActiveRunner() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::~CWiFiProtActiveRunner" ); + + // Close notifier + iNotifier.Close(); + + Cancel(); + + // If the cancel has been initiated by the client, temp IAP cannot be deleted until + // after the RNotifier Cancel() call has returned (deadlock between MPM and CMM). + // Therefore, temp IAP cleanup must be done later. + if ( !iClientCancelled ) + { + TRAP_IGNORE( DeleteTempIapL() ); //we can't do much if delete fails + } + + delete iWlanMgmtEngine; + + // if cancelled from client, wait note may still be visible + if ( iWaitDlg ) + { + CLOG_WRITE( "iWaitDlg->SetCallback( NULL );" ); + iWaitDlg->SetCallback( NULL ); + CLOG_WRITE( "iWaitDlg->ProcessFinishedL( );" ); + TRAP_IGNORE( iWaitDlg->ProcessFinishedL() ); + delete iWaitDlg; + } + + if ( iPinDlg ) + { + delete iPinDlg; + } + + TBool cleanupCms = EFalse; + if ( iReturn == EWiFiCancel ) + { + cleanupCms = ETrue; + } + + for ( TInt i = 0; i < iCmArray.Count();i++ ) + { + // if we are setting up a connection, we save the settings into + // easy wlan iap (connection method), which we shouldn't ever delete! + if ( ( !iIsConnectionNeeded ) && cleanupCms ) + { + //we can't do much if delete fails + TRAP_IGNORE( iCmArray[i]->DeleteL() ); + } + iCmArray[i]->Close(); + delete iCmArray[i]; + iCmArray[i] = NULL; + } + + iCmArray.ResetAndDestroy(); + iAvailableNetworks.Close(); + delete iIapParametersArray; + delete iScanInfo; + CLOG_LEAVEFN( "CWiFiProtActiveRunner::~CWiFiProtActiveRunner" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::StartProtectedSetupL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::StartProtectedSetupAsyncL ( + const TWlanSsid& aSSid, + RArray& aUids, + RCmManagerExt& aCmManagerToUse ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::StartProtectedSetupAsyncL" ); + + iIsConnectionNeeded = EFalse; + iUids = &aUids; + iCmManagerExt = &aCmManagerToUse; + iSsid.Copy( aSSid ); + ShowInitialDialogL(); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::StartProtectedSetupAsyncL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::StartProtectedSetupConnL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::StartProtectedSetupConnL ( + const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& + aNetworkSettings, + RCmManagerExt& aCmManagerToUse ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::StartProtectedSetupConnL" ); + + iIsConnectionNeeded = ETrue; + iNetworkSettings = &aNetworkSettings; + iCmManagerExt = &aCmManagerToUse; + iSsid.Copy( aSSid ); + ShowInitialDialogL(); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::StartProtectedSetupConnL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::StartProtectedSetupL +// -------------------------------------------------------------------------- +// +WiFiProt::TWiFiReturn CWiFiProtActiveRunner::StartProtectedSetupL ( + const TWlanSsid& aSSid, + RArray& aUids, + RCmManagerExt& aCmManagerToUse ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::StartProtectedSetupL" ); + + iSyncMode = ETrue; + iIsConnectionNeeded = EFalse; + iUids = &aUids; + iCmManagerExt = &aCmManagerToUse; + iSsid.Copy( aSSid ); + ShowInitialDialogL(); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::StartProtectedSetupL" ); + + return iReturn; + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::CancelByClient() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::CancelByClient() + { + iClientCancelled = ETrue; + Cancel(); + if ( iWaitDlg ) + { + CLOG_WRITE( "Removing wait note( );" ); + iWaitDlg->SetCallback( NULL ); + + TRAPD(err, iWaitDlg->ProcessFinishedL()); + if (err) + { + CLOG_WRITE( "LEAVE: iWaitDlg->ProcessFinishedL" ); + + } + delete iWaitDlg; + iWaitDlg = NULL; + } + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::ShowInitialDialogL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::ShowInitialDialogL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::ShowInitialDialogL" ); + + if ( IsActive() == EFalse ) + { + + // Check if offline mode is on: + iInOfflineMode = EFalse; + if ( FeatureManager::FeatureSupported( KFeatureIdOfflineMode ) ) + { + TInt connAllowed; + CRepository* repository = CRepository::NewLC( + KCRUidCoreApplicationUIs ); + repository->Get( KCoreAppUIsNetworkConnectionAllowed, connAllowed ); + CleanupStack::PopAndDestroy(repository); // repository + if ( connAllowed == 0 ) + { + iInOfflineMode = ETrue; + } + } + + if ( iInOfflineMode && iSyncMode ) + { + // If in offline mode, query about offline mode first. + iNextWiFiProtState = EWifiProtOfflineQuery; + } + else + { + // Else initiate easy setup. + iNextWiFiProtState = EWiFiProtInitiateEasySetup; + } + + iConfirmationDialog = + new ( ELeave ) CWiFiProtConfirmationNoteDlg( iStatus ); + iConfirmationDialog->ExecuteLD( R_WIFIPROT_CONFIGURE_AUTO_DIALOG ); + iORequest = EWiFiProtReqConfirmDialog; + SetActive( ); + if ( iSyncMode ) + { + CLOG_WRITE( "CActiveSchedulerWait Started" ); + iWait.Start(); + CLOG_WRITE( "CActiveSchedulerWait Returned" ); + } + + }// do nothing if already active + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::ShowInitialDialogL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::ShowInitiateEasySetupDialogL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::ShowInitiateEasySetupDialogL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::ShowInitiateEasySetupDialogL" ); + + iDestroyInitDialogLater = EFalse; + iNextWiFiProtState = EWiFiProtUsePinCode; + //store it, but not own it + iInitDialog = new ( ELeave ) CWiFiProtInitiateEasySetupDlg( iStatus ); + iInitDialog->PrepareLC( R_WIFIPROT_INITIATE_EASY_SETUP_DIALOG ); + _LIT( KLinkStartTag, "\n" ); + _LIT( KLinkEndTag, "" ); + + HBufC *messageBase = + StringLoader::LoadLC( R_QTN_NETW_CONSET_WPS_MSG_PBC ); + HBufC* linkString1 = StringLoader::LoadLC( + R_QTN_NETW_CONSET_WPS_MSG_LINK_USE_PIN ); + + TInt lenMsg = messageBase->Des().Length()+ + linkString1->Des().Length()+ + KLinkStartTag().Length()+ + KLinkEndTag().Length(); + + HBufC* message = HBufC::NewLC( lenMsg ); + TPtr messagePtr = message->Des(); + + messagePtr.Append( messageBase->Des() ); + + messagePtr.Append( KLinkStartTag ); + messagePtr.Append( linkString1->Des() ); + messagePtr.Append( KLinkEndTag ); + + iInitDialog->SetMessageTextL( messagePtr ); + CleanupStack::PopAndDestroy( message ); + + CleanupStack::PopAndDestroy( linkString1 ); + CleanupStack::PopAndDestroy( messageBase ); + TCallBack callBackLink( CWiFiProtActiveRunner::UsePinCodeLinkSelectedL, + this ); + + iInitDialog->SetLink( callBackLink ); + iInitDialog->RunLD(); + iORequest = EWiFiProtReqInitDialog; + SetActive( ); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::ShowInitiateEasySetupDialogL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::ShowEnterPinOnStationDialogL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::ShowEnterPinOnStationDialogL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::ShowEnterPinOnStationDialogL" ); + + iNextWiFiProtState = EWiFiProtStartingWaitDlg; + TInt pin = 0; + TTime t; + t.HomeTime(); + TInt64 seed = t.Int64(); + do { + pin = Math::Rand( seed ); + } + while ( pin <(10^(KMaxPINLength-2)) + || ( ((pin / 1000000) % 10) ) == 0 ); + //last digit is checksum, so we need 7 digits + //and the first shouldn't be 0 + pin = pin % 10000000; + TInt checkSum = ComputeChecksum(pin); + pin *= 10; + pin += checkSum; + _LIT(KPinFormat,"%d"); + iPIN.Format(KPinFormat, pin); + + CLOG_WRITE( "Enter pin code note" ); + + HBufC* prompt = + StringLoader::LoadLC( R_QTN_NETW_CONSET_WPS_INFO_ENTER_PIN_CODE, pin ); + CWiFiProtEnterPinDlg* pinDlg = new ( ELeave ) CWiFiProtEnterPinDlg( *this ); + + CleanupStack::PushL(pinDlg); + pinDlg->SetPromptL( *prompt ); + CleanupStack::Pop(pinDlg); + + CleanupStack::PopAndDestroy( prompt ); + iPinDlg = pinDlg; + iPinDlg->ExecuteLD( R_WIFIPROT_ENTER_PIN_CODE_DIALOG ); + iPinQueryActive = ETrue; + SetActive( ); + SetNextStateAndComplete( EWiFiProtConfiguring ); + CLOG_LEAVEFN( "CWiFiProtActiveRunner::ShowEnterPinOnStationDialogL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::ShowWaitingDialogL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::ShowWaitingDialogL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::ShowWaitingDialogL" ); + HBufC* text = StringLoader::LoadLC( + R_QTN_NETW_CONSET_WAIT_WPS_CONFIGURING ); + iWaitDlg = new ( ELeave ) CAknWaitDialog( + ( REINTERPRET_CAST( CEikDialog**, &iWaitDlg )), + ETrue ); + iWaitDlg->SetTextL( *text ); + CleanupStack::PopAndDestroy( text ); + iWaitDlg->SetCallback( this ); + iWaitDlg->SetTone( CAknNoteDialog::EConfirmationTone ); + iWaitDlg->ExecuteLD( R_WIFIPROT_WAIT_NOTE ); + CLOG_LEAVEFN( "CWiFiProtActiveRunner::ShowWaitingDialogL" ); + } + + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::ShowWaitingDialogAndProceedL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::ShowWaitingDialogAndProceedL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::ShowWaitingDialogAndProceedL" ); + + iStatus = KRequestPending; //should be set by service provider + ShowWaitingDialogL(); + SetActive( ); + SetNextStateAndComplete( EWiFiProtConfiguring ); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::ShowWaitingDialogAndProceedL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::ShowFinalNoteL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::ShowFinalNoteL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::ShowFinalNoteL" ); + + const TInt KSettingsConfNone = 0; + const TInt KSettingsConfOne = 1; + const TInt KSettingsConfMulti = 2; + const TInt KResourceIdInvalid = 0; + + HBufC* text = NULL; + TInt resId = KResourceIdInvalid; + CAknNoteDialog::TTone tone = CAknNoteDialog::ENoTone; + TInt numberOfNetworksConfigured = 0; + if ( iIsConnectionNeeded ) + { + // we have one network configured if we are here + numberOfNetworksConfigured = 1; + } + else + { + numberOfNetworksConfigured = iCmArray.Count(); + } + + + //more than one = multiple + if ( numberOfNetworksConfigured > KSettingsConfOne) + { + numberOfNetworksConfigured = KSettingsConfMulti; + } + switch ( numberOfNetworksConfigured ) + { + case KSettingsConfOne : + { + CLOG_WRITE( "Show one network configured note " ); + HBufC* name; + if ( iIsConnectionNeeded ) + { + // We have to convert the 8-bit SSID to 16-bit + HBufC* ssid16 = HBufC::NewLC( (*iIapParametersArray) + [iAvailableNetworks[ + iSelectedNetworkIndex]].iSsid.Length()+1 ); + TPtr ssid16Ptr( ssid16->Des() ); + CnvUtfConverter::ConvertToUnicodeFromUtf8( ssid16Ptr, + (*iIapParametersArray)[iAvailableNetworks[ + iSelectedNetworkIndex]].iSsid ); + ssid16Ptr.ZeroTerminate(); + name = ssid16Ptr.AllocL(); + CleanupStack::PopAndDestroy( ssid16 ); + } + else + { + RCmConnectionMethodExt cm = + iCmManagerExt->ConnectionMethodL( + iCmArray[0]->GetIntAttributeL( ECmId ) ); + CleanupClosePushL( cm ); + name = cm.GetStringAttributeL( EWlanSSID ); + CleanupStack::PopAndDestroy( &cm ); + } + CleanupStack::PushL( name ); + text = StringLoader::LoadL( + R_QTN_NETW_CONSET_CONF_WPS_ONE_NETWORK_CONFIGURED , *name); + CleanupStack::PopAndDestroy( name ); + CleanupStack::PushL( text ); + resId = R_WIFIPROT_OK_NOTE; + tone = CAknNoteDialog::EConfirmationTone; + break; + } + case KSettingsConfMulti: + { + CLOG_WRITE( "Show multiple networks configured note " ); + text = StringLoader::LoadLC( + R_QTN_NETW_CONSET_CONF_WPS_MULTIPLE_NETWORKS_CONFIG ); + resId = R_WIFIPROT_OK_NOTE; + tone = CAknNoteDialog::EConfirmationTone; + break; + } + case KSettingsConfNone : + { + CLOG_WRITE( "Show no networks configured note " ); + text = StringLoader::LoadLC( + R_QTN_NETW_CONSET_CONF_WPS_NO_NETWORKS_CONFIGURED ); + resId = R_WIFIPROT_INFO_NOTE; + break; + } + default: + { + //should not ever get here + CLOG_WRITE( "Unhandled Final Note!!!" ); + User::Leave( KErrGeneral ); + break; + } + } + + CAknNoteDialog* dlg = new (ELeave) CAknNoteDialog( + tone, + CAknNoteDialog::ELongTimeout ); + dlg->SetTextL( *text ); + CleanupStack::PopAndDestroy( text ); + iStatus = KRequestPending; //should be set by service provider + SetActive( ); + dlg->ExecuteLD( resId ); + SetNextStateAndComplete( EWiFiProtFinished ); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::ShowFinalNoteL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::DialogDismissedL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::DialogDismissedL( TInt aButtonId ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::DialogDismissedL" ); + + //wait dialog cancelled + if ( aButtonId == EAknSoftkeyCancel ) + { + CLOG_WRITE( "Cancel pressed!" ); + if (iWaitDlg) + { + iWaitDlgCancelled = ETrue; + } + iUserCancelled = ETrue; + CancelOngoingRequest(); + } + // iWaitDlg is destroyed, so we can null it + iWaitDlg = NULL; + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::DialogDismissedL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::CreateTempIapL +// -------------------------------------------------------------------------- +// +TUint32 CWiFiProtActiveRunner::CreateTempIapL( TUint32& aTempServId ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::CreateTempIapL" ); + + RCmConnectionMethodExt cm; + cm = iCmManagerExt->CreateConnectionMethodL( KUidWlanBearerType ); + CleanupClosePushL(cm); + + // We have to convert the 8-bit SSID to 16-bit for CommsDat. + HBufC* ssid16 = HBufC::NewLC( iSsid.Length() ); + TPtr ssid16Ptr( ssid16->Des() ); + CnvUtfConverter::ConvertToUnicodeFromUtf8( ssid16Ptr , iSsid ); + cm.SetStringAttributeL( EWlanSSID, *ssid16 ); + cm.SetStringAttributeL( ECmName, *ssid16 ); + CLOG_WRITEF( _L("SSid: ") ); + CLOG_WRITEF( *ssid16 ); + CleanupStack::PopAndDestroy( ssid16 ); + + + cm.SetIntAttributeL( EWlanSecurityMode, EWlanSecModeWpa2 ); + cm.UpdateL(); + + aTempServId = cm.GetIntAttributeL( ECmIapServiceId ); + TInt32 iapID = cm.GetIntAttributeL( ECmId ); + + CommsDat::CMDBSession* db = + CommsDat::CMDBSession::NewL( CommsDat::CMDBSession::LatestVersion() ); + CleanupStack::PushL( db ); + CWPASecuritySettings* wpaSecSettings = + CWPASecuritySettings::NewL( ESecurityModeWpa ); + CleanupStack::PushL( wpaSecSettings ); + User::LeaveIfError( wpaSecSettings->SetWPAEnabledEAPPlugin( KEapWsc ) ); + CLOG_WRITEF( _L("Enabled EAP plugin set: EAP WSC")); + if (iPIN != KNullDesC) + { + User::LeaveIfError( wpaSecSettings->SetWPAPreSharedKey( iPIN ) ); + CLOG_WRITEF( _L("Pin set as WPA key: ")); + CLOG_WRITEF( iPIN ); + } + + CLOG_WRITEF( _L("WPA settings save - ECmIapServiceId in aTempServId %d"), aTempServId ); + wpaSecSettings->SaveL( aTempServId , *db, ESavingBrandNewAP, 0 ); + CLOG_WRITEF( _L("WPA settings saved!")); + CleanupStack::PopAndDestroy( wpaSecSettings ); + db->Close(); + CleanupStack::PopAndDestroy( db ); + CleanupStack::PopAndDestroy( &cm ); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::CreateTempIapL" ); + + return iapID; + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::RunProtectedSetup +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::RunProtectedSetup ( const TInt32 aIapId ) + { + + CLOG_ENTERFN( "CWiFiProtActiveRunner::RunProtectedSetup" ); + + iNextWiFiProtState = EWiFiProtWlanMgmtEngineReturned; + if ( iWlanMgmtEngine ) + { + CLOG_WRITEF(_L( + "We have a wlanmgmt engine, calling RunProtectedSetup with uid %d") + , aIapId ); + iWlanMgmtEngine->RunProtectedSetup( iStatus, aIapId, + *iIapParametersArray ); + iORequest = EWiFiProtReqWPS; + SetActive( ); + } + else + { + // we complete ourselves after creating these cms synchronously + //just for wins testing + //add 1 conneciton method; +#ifdef __WINS__ + CLOG_WRITE( "No wlanmgmt engine, simulating... " ); + TWlanProtectedSetupCredentialAttribute tmpCred; + tmpCred.iOperatingMode = EWlanOperatingModeInfrastructure; + tmpCred.iAuthenticationMode = EWlanAuthenticationModeOpen; + tmpCred.iSecurityMode = EWlanIapSecurityModeAllowUnsecure; + tmpCred.iSsid = _L8("Available Network"); + + TRAP_IGNORE( iIapParametersArray->AppendL(tmpCred) ); + + tmpCred.iOperatingMode = EWlanOperatingModeInfrastructure; + tmpCred.iAuthenticationMode = EWlanAuthenticationModeOpen; + tmpCred.iSecurityMode = EWlanIapSecurityModeAllowUnsecure; + tmpCred.iSsid = _L8("Available Network 2"); + + TRAP_IGNORE( iIapParametersArray->AppendL(tmpCred) ); + + tmpCred.iOperatingMode = EWlanOperatingModeInfrastructure; + tmpCred.iAuthenticationMode = EWlanAuthenticationModeOpen; + tmpCred.iSecurityMode = EWlanIapSecurityModeAllowUnsecure; + tmpCred.iSsid = _L8("Unavailable Network"); + + TRAP_IGNORE( iIapParametersArray->AppendL(tmpCred) ); + + iStatus = KRequestPending; + SetActive( ); + SetNextStateAndComplete(EWiFiProtWlanMgmtEngineReturned ); +#else + //no engine in hardware, should not ever get here! + User::Panic( KWiFiPanic , KErrNotFound ); +#endif + } + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::RunProtectedSetup" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::CWiFiProtActiveRunner +// -------------------------------------------------------------------------- +// +CWiFiProtActiveRunner::CWiFiProtActiveRunner( + CWiFiProtDlgsPlugin* aParent, TInt aPriority ) + : CActive( aPriority ), + iParent( aParent ), + iIsConnectionNeeded( EFalse ), + iWaitDlgCancelled( EFalse ), + iSsid( KNullDesC8 ), + iPIN( KNullDesC ), + iNextWiFiProtState( EWiFiProtAskConfigureAutomatically ), + iReturn( EWiFiCancel ), + iUsePin( EFalse ), + iError( KErrNone ), + iPinQueryActive( EFalse ), + iWaitNoteNeeded( EFalse ), + iInitDialog( NULL ), + iClientCancelled( EFalse ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::CWiFiProtActiveRunner" ); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::CWiFiProtActiveRunner" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::ConstructL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::ConstructL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::ConstructL" ); + + CActiveScheduler::Add( this ); +#ifndef __WINS__ + iWlanMgmtEngine = CWlanMgmtClient::NewL(); + iScanInfo = CWlanScanInfo::NewL(); +#endif // !__WINS__ + iIapParametersArray = new (ELeave) + CArrayFixSeg + ( KArrayGranularity ); + + User::LeaveIfError(iNotifier.Connect()); // Connects to the extended notifier server + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::ConstructL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::DoCancel +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::DoCancel() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::DoCancel" ); + + CancelOngoingRequest(); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::DoCancel" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::RunL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::RunL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::RunL" ); + + // reset the async request id + iORequest = EWiFiProtReqNone; + + if ( iClientCancelled ) + { + // no further actions needed here, message completion taken care of + // in the notifier + return; + } + + CLOG_WRITEF( _L(" iNextWiFiProtState: %d"), iNextWiFiProtState ); + if ( iNextWiFiProtState == EWiFiProtWlanMgmtEngineReturned ) + { + iORequest = EWiFiProtReqNone; + //if we have a dialog and configuration is finished, + // store error code for destroying dialog + iError = iStatus.Int(); + CleanupTempIapL(); + } + else if ( iNextWiFiProtState == EWiFiProtDestroyWaitNote ) + { + DestroyWaitDialog(); + } + else + { + if ( iUserCancelled ) + { + iStatus = KErrCancel; + } + + if ( iStatus.Int() == KErrNone ) //no error + { + HandleNoErrorL(); + } + // error or cancel + // try to handle error, if can't, just cancel + else if ( !HandleErrorL( iStatus.Int() ) ) + { + if ( (iStatus.Int() != KErrAbort) && + (iNextWiFiProtState == EWifiProtOfflineQuery || iNextWiFiProtState == EWiFiProtInitiateEasySetup) ) + { + // Use WPS to configure or connect in offline mode? -> No -> Continue the traditional way without WPS + iReturn = EWifiNoAuto; + } + else + { + iReturn = EWiFiCancel; + } + + if ( iSyncMode ) + { + if ( iWait.IsStarted() ) + { + iWait.AsyncStop(); + } + } + else + { + iParent->CompleteProcessL( iReturn ); + } + } + } + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::RunL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::SetNextStateAndComplete +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::SetNextStateAndComplete( + TWiFiProtStates aNextState, + TInt aError ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::SetNextStateAndComplete" ); + + iNextWiFiProtState = aNextState; + CLOG_WRITEF( _L(" aNextState: %d"), aNextState ); + TRequestStatus* pS = &iStatus; + User::RequestComplete( pS, aError ); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::SetNextStateAndComplete" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::ConfigureL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::ConfigureL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::ConfigureL" ); + iWaitNoteNeeded = ETrue; + iTempIapId = CreateTempIapL( iTempServId ); + CLOG_WRITEF( _L("Temp Iap created! Id: %d"), iTempIapId ); + RunProtectedSetup( iTempServId ); + // do not complete self, waiting for engine or user cancel to complete us + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::ConfigureL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::EvaluateResult +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::EvaluateResult() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::EvaluateResult" ); + if (iError == KErrNone) + { + if ( iIsConnectionNeeded ) + { + TRAPD(err, CheckNetworkAvailabilityL()); + if (err) + { + CLOG_WRITE( + "LEAVE: CheckNetworkAvailabilityL" ); + } + } + else + { + CLOG_WRITE( + "SetNextStateAndComplete( EWiFiProtSettingsConfNote );" ); + SetNextStateAndComplete( EWiFiProtSettingsConfNote ); + } + } + else + { //now we complete with the error code as dialog is finished + CLOG_WRITE( "SetNextStateAndComplete( EWiFiProtFinished, iError );" ); + SetNextStateAndComplete( EWiFiProtFinished , iError ); + } + CLOG_LEAVEFN( "CWiFiProtActiveRunner::EvaluateResult" ); + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::DestroyWaitDialog +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::DestroyWaitDialog() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::DestroyWaitDialog" ); + + CLOG_WRITE( "SetActive();" ); + SetActive(); + iStatus = KRequestPending; //should be set by service provider + iWaitNoteNeeded = EFalse; + if( !iWaitDlgCancelled ) + { + // iWaitDlg possibly wasn't even shown... + if ( iWaitDlg ) + { + CLOG_WRITE( "iWaitDlg->SetCallback( NULL );" ); + iWaitDlg->SetCallback( NULL ); + CLOG_WRITE( "iWaitDlg->ProcessFinishedL( );" ); + + TRAPD(err, iWaitDlg->ProcessFinishedL()); + if (err) + { + CLOG_WRITE( "LEAVE: iWaitDlg->ProcessFinishedL( );" ); + } + + CLOG_WRITE( "delete iWaitDlg;" ); + delete iWaitDlg; + iWaitDlg = NULL; + } + if ( iPinQueryActive ) //waiting for PIN Query + { + CLOG_WRITE( + "SetNextStateAndComplete( EWiFiProtWaitForPINQuery );" ); + // if pin query is still active, remove the cancel... + if ( iPinQueryActive && iPinDlg) + { + iPinDlg->RemoveCancel(); + } + iNextWiFiProtState = EWiFiProtWaitForPINQuery; + } + else + { + EvaluateResult(); + } + } + else + { + CLOG_WRITE( + "SetNextStateAndComplete( EWiFiProtFinished, KErrCancel );" ); + SetNextStateAndComplete( EWiFiProtFinished , KErrCancel ); + } + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::DestroyWaitDialog" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::ComputeChecksum +// -------------------------------------------------------------------------- +// +TInt CWiFiProtActiveRunner::ComputeChecksum(TInt aPin) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::ComputeChecksum" ); + + TInt accum = 0; + aPin *= 10; + accum += 3 * ((aPin / 10000000) % 10); + accum += 1 * ((aPin / 1000000) % 10); + accum += 3 * ((aPin / 100000) % 10); + accum += 1 * ((aPin / 10000) % 10); + accum += 3 * ((aPin / 1000) % 10); + accum += 1 * ((aPin / 100) % 10); + accum += 3 * ((aPin / 10) % 10); + TInt digit = (accum % 10); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::ComputeChecksum" ); + + return (10 - digit) % 10; + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::CreateAllIapsL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::CreateAllIapsL() + { + CreateIapL(0); + iStatus = KRequestPending; //should be set by service provider + SetActive(); + if ( iIapParametersArray->Count() ) + { + //another cm, another round + SetNextStateAndComplete( EWiFiProtCreateAllIaps ); + } + else + { + //cm creation finished + SetNextStateAndComplete( EWiFiProtDestroyWaitNote ); + } + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::CreateIapL +// -------------------------------------------------------------------------- +// +TUint32 CWiFiProtActiveRunner::CreateIapL( const TInt aIndex ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::CreateIapL" ); + + TInt32 iapID = 0; + if ( iIapParametersArray->Count() ) + { + RCmConnectionMethodExt cm; + cm = iCmManagerExt->CreateConnectionMethodL( KUidWlanBearerType ); + CleanupClosePushL(cm); + iapID = SetIapDataL( aIndex, cm ); + CleanupStack::Pop( &cm ); + + RCmConnectionMethodExt* cmToAppend = + new (ELeave) RCmConnectionMethodExt(cm); + CleanupStack::PushL(cmToAppend); + iCmArray.Append( cmToAppend ); //ownership transferred + CleanupStack::Pop( cmToAppend ); + CLOG_WRITEF( _L("Cm appended to array: ") ); + + + (*iIapParametersArray).Delete(aIndex); + } + + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::CreateIapL" ); + + return iapID; + } + + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::SetIapDataL +// -------------------------------------------------------------------------- +// +TUint32 CWiFiProtActiveRunner::SetIapDataL( const TInt aIndex, + RCmConnectionMethodExt& aCmToSet ) + { + // We have to convert the 8-bit SSID to 16-bit for CommsDat. + HBufC* ssid16 = + HBufC::NewLC( ( *iIapParametersArray)[aIndex].iSsid.Length() ); + TPtr ssid16Ptr( ssid16->Des() ); + CnvUtfConverter::ConvertToUnicodeFromUtf8( + ssid16Ptr , (*iIapParametersArray)[aIndex].iSsid ); + + aCmToSet.SetStringAttributeL( ECmName, *ssid16 ); + aCmToSet.SetStringAttributeL( EWlanSSID, *ssid16 ); + CLOG_WRITEF( _L("Parameters from wlan mgmt engine: ") ); + CLOG_WRITEF( _L("SSid: ") ); + CLOG_WRITEF( *ssid16 ); + CleanupStack::PopAndDestroy( ssid16 ); + + TInt connMode = EAdhoc; + switch ( (*iIapParametersArray)[aIndex].iOperatingMode ) + { + case EWlanOperatingModeAdhoc: + { + CLOG_WRITEF( _L("Operating Mode: Adhoc") ); + break; + } + case EWlanOperatingModeInfrastructure: + { + CLOG_WRITEF( _L("Operating Mode: Infra") ); + connMode = EInfra; + break; + } + default: + { + CLOG_WRITEF( _L("Operating Mode: Not Supported") ); + User::Leave( KErrNotSupported ); + break; + } + } + aCmToSet.SetIntAttributeL( EWlanConnectionMode, connMode ); + + CMManager::TWlanSecMode secMode = EWlanSecModeOpen; + switch( (*iIapParametersArray)[aIndex].iSecurityMode ) + { + case EWlanIapSecurityModeAllowUnsecure: + { + CLOG_WRITEF( _L("Security Mode: Open") ); + secMode = EWlanSecModeOpen; + break; + } + + case EWlanIapSecurityModeWep: + { + CLOG_WRITEF( _L("Security Mode: Wep") ); + secMode = EWlanSecModeWep; + break; + } + + case EWlanIapSecurityMode802d1x: + { + CLOG_WRITEF( _L("Security Mode: 802_1x") ); + secMode = EWlanSecMode802_1x; + break; + } + + // EWlanIapSecurityModeWpa and + // EWlanIapSecurityModeWpa2Only are handled as wpa + case EWlanIapSecurityModeWpa: + case EWlanIapSecurityModeWpa2Only: + { + CLOG_WRITEF( _L("Security Mode: wpa") ); + secMode = EWlanSecModeWpa; + break; + } + + default: + { + User::Leave( KErrNotSupported ); + } + } + + aCmToSet.SetIntAttributeL( EWlanSecurityMode, secMode ); + + aCmToSet.UpdateL(); + TInt32 wlanServId = aCmToSet.GetIntAttributeL( ECmIapServiceId ); + TInt32 iapID = aCmToSet.GetIntAttributeL( ECmId ); + + CommsDat::CMDBSession* db = + CommsDat::CMDBSession::NewL( + CommsDat::CMDBSession::LatestVersion() ); + CleanupStack::PushL( db ); + + switch( (*iIapParametersArray)[aIndex].iSecurityMode ) + { + case EWlanIapSecurityModeWep: + { + SaveWepSecuritySettingsL( + ( *iIapParametersArray )[aIndex], wlanServId, *db ); + break; + } + // EWlanIapSecurityModeWpa and + // EWlanIapSecurityModeWpa2Only are handled as wpa + case EWlanIapSecurityModeWpa: + case EWlanIapSecurityModeWpa2Only: + { + CWPASecuritySettings* wpaSecSettings = + CWPASecuritySettings::NewL( ESecurityModeWpa ); + CleanupStack::PushL( wpaSecSettings ); + if ((*iIapParametersArray) + [aIndex].iWpaPreSharedKey != KNullDesC8) + { + TBuf wpaBuf16; + wpaBuf16.Copy((*iIapParametersArray) + [aIndex].iWpaPreSharedKey); + User::LeaveIfError( + wpaSecSettings->SetWPAPreSharedKey( wpaBuf16 ) ); + CLOG_WRITEF( _L("wpa psk set: ") ); + CLOG_WRITEF( wpaBuf16 ); + + } + + TTypeOfSaving typeOfSaving = ESavingBrandNewAP; + + if ( iapID == iCmManagerExt->EasyWlanIdL() ) + { + typeOfSaving = ESavingEditedAP; + } + + wpaSecSettings->SaveL( wlanServId, *db, + typeOfSaving, 0 ) ; + + CleanupStack::PopAndDestroy( wpaSecSettings ); + break; + } + // EWlanIapSecurityMode802d1x and + // EWlanConnectionSecurityOpen - no key needs to be saved + case EWlanIapSecurityMode802d1x: + case EWlanConnectionSecurityOpen: + default: + { + break; + } + } + + db->Close(); + CleanupStack::PopAndDestroy( db ); + return iapID; + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::CleanupTempIapL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::CleanupTempIapL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::CleanupTempIapL" ); + + //we don't need the temp iap anymore, delete it + //shouldn't be any errors, because nobody else knows about our temp iap + DeleteTempIapL(); + SetActive(); + iStatus = KRequestPending; //should be set by service provider + if ( iError == KErrNone ) + { + if ( iIsConnectionNeeded ) + { + StartWlanScan(); //scan wlan before we close the wait dialog + } + else + { + //start creating iaps + SetNextStateAndComplete( EWiFiProtCreateAllIaps ); + } + } + else + { + //don't create iaps or scan wlan, we had an error! + SetNextStateAndComplete( EWiFiProtDestroyWaitNote ); + } + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::CleanupTempIapL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::DeleteTempIapL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::DeleteTempIapL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::DeleteTempIapL" ); + + if ( iTempIapId ) + { + const TInt KInvalidUid = 0; + + CLOG_WRITE( "Calling iCmManagerExt->ConnectionMethodL" ); + + RCmConnectionMethodExt cm = + iCmManagerExt->ConnectionMethodL(iTempIapId); + + CLOG_WRITE( "Calling cm.DeleteL" ); + + TRAPD(err, cm.DeleteL()); + CLOG_WRITEF( _L("Temp Iap deleted! Error code: %d"), err ); + cm.Close(); + iTempIapId = KInvalidUid; + } + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::DeleteTempIapL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::IsWepFormatHexL +// -------------------------------------------------------------------------- +// +TBool CWiFiProtActiveRunner::IsWepFormatHexL( TInt aLength ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::IsWepFormatHexL" ); + + if ( ( aLength == KConnUiUtilsWepLengthASCII5 ) || + ( aLength == KConnUiUtilsWepLengthASCII13 ) || + ( aLength == KConnUiUtilsWepLengthASCII29 ) ) + { + return EFalse; + } + else if ( ( aLength == KConnUiUtilsWepLengthHEX10 ) || + ( aLength == KConnUiUtilsWepLengthHEX26 ) || + ( aLength == KConnUiUtilsWepLengthHEX58 ) ) + { + return ETrue; + } + else + { + User::Leave( KErrNotSupported ); + } + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::IsWepFormatHexL" ); + + return EFalse; + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::SaveWepSecuritySettingsL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::SaveWepSecuritySettingsL( + TWlanProtectedSetupCredentialAttribute + aCredentialAttribute, + TUint32 aWlanServiceId, + CommsDat::CMDBSession& aDb ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::SaveWepSecuritySettingsL" ); + + CWEPSecuritySettings* wepSecSettings = CWEPSecuritySettings::NewL( ); + CleanupStack::PushL( wepSecSettings ); + TInt keyIndex = 0; + // wep key 1 + SetWepKeyL( *wepSecSettings, aCredentialAttribute.iWepKey1, keyIndex ); + keyIndex++; + // wep key 2 + SetWepKeyL( *wepSecSettings, aCredentialAttribute.iWepKey2, keyIndex ); + keyIndex++; + // wep key 3 + SetWepKeyL( *wepSecSettings, aCredentialAttribute.iWepKey3, keyIndex ); + keyIndex++; + // wep key 4 + SetWepKeyL( *wepSecSettings, aCredentialAttribute.iWepKey4, keyIndex ); + + //should be the same enum + wepSecSettings->SetKeyInUse( (CWEPSecuritySettings::TWEPKeyInUse) + aCredentialAttribute.iWepDefaultKey ); + CLOG_WRITEF( _L("Wep key in use %d:"), + aCredentialAttribute.iWepDefaultKey ); + + CWEPSecuritySettings::TWEPAuthentication auth = + CWEPSecuritySettings::EAuthOpen; + + switch( aCredentialAttribute.iAuthenticationMode ) + { + case EWlanAuthenticationModeOpen: + { + CLOG_WRITEF( _L("Authentication mode: open") ); + break; + } + case EWlanAuthenticationModeShared: + { + CLOG_WRITEF( _L("Authentication mode: shared") ); + auth = CWEPSecuritySettings::EAuthShared; + break; + } + default: + { + break; + } + } + + //should be the same enum + wepSecSettings->SetAuthentication( + (CWEPSecuritySettings::TWEPAuthentication) auth ); + wepSecSettings->SaveL( aWlanServiceId, aDb ) ; + CleanupStack::PopAndDestroy( wepSecSettings ); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::SaveWepSecuritySettingsL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::HandleErrorL() +// -------------------------------------------------------------------------- +// +TBool CWiFiProtActiveRunner::HandleErrorL( TInt aErrorCode ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::HandleErrorL" ); + + CLOG_WRITEF( _L("Error code: %d"), aErrorCode ); + if (iWaitDlg) //close dialog first + { + TInt error = iStatus.Int(); + iStatus = KRequestPending; //should be set by service provider + SetActive( ); + SetNextStateAndComplete( EWiFiProtDestroyWaitNote , error ); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::HandleErrorL" ); + + return ETrue; + } + else + { + TWiFiProtStates nextState = EWiFiProtFinished; + TInt textResId = 0; + TInt status = KErrCancel; + TBool ret = ETrue; + switch (aErrorCode) + { + // Error codes are in the original order + case KErrWlanProtectedSetupOOBInterfaceReadError: + case KErrWlanProtectedSetupDecryptionCRCFailure: + // the same handling here for this error code too + { + textResId = R_QTN_ERR_WLAN_SC_CONFIG_FAILED_TRY_AGAIN; + break; + } + case KErrWlanProtectedSetup5_0ChannelNotSupported: + case KErrWlanProtectedSetup2_4ChannelNotSupported: + // the same handling here for this error code too + { + textResId = R_QTN_ERR_WLAN_SC_CONFIG_FAILED; + break; + } + case KErrWlanSignalTooWeak: + { + textResId = R_QTN_ERR_WLAN_SIGNAL_TOO_WEAK; + break; + } + case KErrWlanProtectedSetupNetworkAuthFailure: + { + status = KErrNone; + textResId = R_QTN_ERR_WLAN_SC_CONFIG_FAILED_TRY_AGAIN; + if ( iUsePin ) + { + // ...pin code dialog if pin code was used + nextState = EWiFiProtUsePinCode; + } + else + { + // ... or initiate WPS dialog if push button was used + nextState = EWiFiProtInitiateEasySetup; + } + break; + } + case KErrWlanProtectedSetupNetworkAssociationFailure: + { + textResId = R_QTN_ERR_WLAN_NETWORK_NOT_FOUND; + break; + } + case KErrWlanProtectedSetupNoDHCPResponse: + case KErrWlanProtectedSetupFailedDHCPConfig: + // the same handling here for this error code too + case KErrWlanProtectedSetupIPAddressConflict: + // the same handling here for this error code too + case KErrWlanProtectedSetupCouldNotConnectToRegistrar: + // the same handling here for this error code too + { + textResId = R_QTN_ERR_WLAN_SC_CONFIG_FAILED; + break; + } + case KErrWlanProtectedSetupMultiplePBCSessionsDetected: + { + nextState = EWiFiProtInitiateEasySetup; + status = KErrNone; + textResId = + R_QTN_ERR_WLAN_SC_CONFIG_FAILED_MULTIPLE_PB_SESSIONS; + break; + } + case KErrWlanProtectedSetupRogueActivitySuspected: + { + nextState = EWiFiProtUsePinCode; + iUsePin = ETrue; + status = KErrNone; + textResId = + R_QTN_ERR_WLAN_SC_CONFIG_FAILED_ROGUE_ACTIVITY; + break; + } + case KErrWlanProtectedSetupDeviceBusy: + case KErrWlanProtectedSetupSetupLocked: + // the same handling here for this error code too + case KErrWlanProtectedSetupMessageTimeout: + // the same handling here for this error code too + { + textResId = R_QTN_ERR_WLAN_SC_CONFIG_FAILED_TRY_AGAIN; + break; + } + case KErrWlanProtectedSetupRegistrationSessionTimeout: + { + textResId = R_QTN_ERR_WLAN_SC_CONFIG_FAILED_TRY_AGAIN; + status = KErrNone; + // Registration session timeout, return to ... + if ( iUsePin ) + { + // ...pin code dialog if pin code was used + nextState = EWiFiProtUsePinCode; + } + else + { + // ... or initiate WPS dialog if push button was used + nextState = EWiFiProtInitiateEasySetup; + } + break; + } + case KErrWlanProtectedSetupDevicePasswordAuthFailure: + { + status = KErrNone; + textResId = R_QTN_ERR_WLAN_SC_CONFIG_FAILED_TRY_AGAIN; + if ( iUsePin ) + { + // ...pin code dialog if pin code was used + nextState = EWiFiProtUsePinCode; + } + else + { + // ... or initiate WPS dialog if push button was used + nextState = EWiFiProtInitiateEasySetup; + } + break; + } + case KErrWlanProtectedSetupPINMethodNotSupported: + { + textResId = + R_QTN_ERR_WLAN_SC_CONFIG_FAILED_PIN_NOT_SUPPORTED; + break; + } + case KErrWlanProtectedSetupPBMethodNotSupported: + { + textResId = + R_QTN_ERR_WLAN_SC_CONFIG_FAILED_PB_NOT_SUPPORTED; + break; + } + case KErrWlanConnAlreadyActive: + { + textResId = R_QTN_WLAN_INFO_CONNECTION_ALREADY_ACTIVE; + break; + } + default: + { + ret = EFalse; + } + } + if (ret) + { + HBufC* text = StringLoader::LoadLC( textResId ); + CLOG_WRITEF( *text ); + CAknNoteDialog* dlg = new (ELeave) CAknNoteDialog( + CAknNoteDialog::EErrorTone, + CAknNoteDialog::ELongTimeout ); + dlg->SetTextL( *text ); + CleanupStack::PopAndDestroy( text ); + iStatus = KRequestPending; //should be set by service provider + SetActive( ); + dlg->ExecuteLD( R_WIFIPROT_ERROR_NOTE ); + SetNextStateAndComplete( nextState , status ); + } + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::HandleErrorL" ); + + return ret; + } + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::ShowOfflineQuery +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::ShowOfflineQuery() + { + iNextWiFiProtState = EWiFiProtInitiateEasySetup; + + iNotifier.StartNotifierAndGetResponse(iStatus,KUidCOfflineWlanNoteDlg, + KNullDesC8(), + iOfflineReply ); + SetActive(); + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::HandleNoErrorL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::HandleNoErrorL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::HandleNoErrorL" ); + + switch (iNextWiFiProtState) + { + case EWifiProtOfflineQuery : + { + ShowOfflineQuery(); + break; + } + case EWiFiProtInitiateEasySetup : + { + ShowInitiateEasySetupDialogL(); + break; + } + case EWiFiProtUsePinCode : + { + if ( iUsePin ) + { + // dismiss the link dialog now + if ( iDestroyInitDialogLater ) + { + iInitDialog->TryExitL( EAknSoftkeyView ); + iDestroyInitDialogLater = EFalse; + } + ShowEnterPinOnStationDialogL(); + } + else + { + iStatus = KRequestPending; + SetActive( ); + SetNextStateAndComplete( EWiFiProtStartingWaitDlg ); + } + break; + } + case EWiFiProtStartingWaitDlg : + { + ShowWaitingDialogAndProceedL( ); + break; + } + case EWiFiProtConfiguring : + { + ConfigureL(); + break; + } + case EWiFiProtCreateAllIaps : + { + CreateAllIapsL(); + break; + } + + // when we are here, wlan scan is finished + case EWiFiProtWlanScan : + { + iORequest = EWiFiProtReqNone; + iStatus = KRequestPending; + SetActive( ); + SetNextStateAndComplete( EWiFiProtDestroyWaitNote ); + break; + } + case EWiFiProtSelectConnection : + { + SelectConnectionL(); + break; + } + + case EWiFiProtSettingsConfNote : + { + ShowFinalNoteL( ); + break; + } + case EWiFiProtFinished : + { + iReturn = EWiFiOK; + + if ( iIsConnectionNeeded ) + { + *iNetworkSettings = (*iIapParametersArray)[ + iAvailableNetworks[iSelectedNetworkIndex] ]; + } + else + { + // Copy the results into the output array + for (TInt i = 0; i< iCmArray.Count();i++ ) + { + CLOG_WRITEF( _L( + "Copy the results into the output array, i == %d"), i ); + if ( iUids == NULL) + { + User::Panic( KWiFiPanic, KErrNotSupported ); + } + iUids->Append( iCmArray[i]->GetIntAttributeL( ECmId ) ); + } + } + + if ( iSyncMode ) + { + if (iWait.IsStarted() ) + { + iWait.AsyncStop(); + } + } + else + { + iParent->CompleteProcessL( iReturn ); + } + break; + } + default: + { + //should not ever get here + CLOG_WRITE( "Unhandled WiFiProtState!!!" ); + User::Leave( KErrGeneral ); + break; + } + } + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::HandleNoErrorL" ); + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::PinQueryExitL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::PinQueryExitL( TInt aResponse ) + { + iPinQueryActive = EFalse; + iPinDlg = NULL; + if ( aResponse == KErrNone ) + { + + if ( iWaitNoteNeeded ) + { + ShowWaitingDialogL(); + } + else + { + EvaluateResult(); //we were just waiting for PIN query to exit + } + } + else + { + iUserCancelled = ETrue; + CancelOngoingRequest(); + } + } + +// -------------------------------------------------------------------------- +// void CWiFiProtActiveRunner::DoUsePinCodeLinkSelectedL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::DoUsePinCodeLinkSelectedL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::DoUsePinCodeLinkSelectedL" ); + if ( !iDestroyInitDialogLater ) + { + iUsePin = ETrue; + TRequestStatus* pS = &iStatus; + User::RequestComplete( pS, KErrNone ); + iDestroyInitDialogLater = ETrue; + } + CLOG_LEAVEFN( "CWiFiProtActiveRunner::DoUsePinCodeLinkSelectedL" ); + } + +// -------------------------------------------------------------------------- +// void CWiFiProtActiveRunner::StartWlanScan() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::StartWlanScan() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::StartWlanScan" ); + // this flag is needed to store the cancel because we cannot + // cancel wlan scan itself +#ifdef __WINS__ + SetNextStateAndComplete( EWiFiProtWlanScan ); +#else + iORequest = EWiFiProtReqWlanScan; + iNextWiFiProtState = EWiFiProtWlanScan; + iWlanMgmtEngine->GetScanResults( iStatus, *iScanInfo ); +#endif + CLOG_LEAVEFN( "CWiFiProtActiveRunner::StartWlanScan" ); + } + +// -------------------------------------------------------------------------- +// void CWiFiProtActiveRunner::CheckNetworkAvailabilityL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::CheckNetworkAvailabilityL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::CheckNetworkAvailabilityL" ); + + iAvailableNetworks.Reset(); + TBool found = EFalse; + for (TInt i = 0; i < iIapParametersArray->Count(); i++ ) + { + found = EFalse; +#ifdef __WINS__ + for (TInt j = 0; jFirst(); (!iScanInfo->IsDone()) + && (!found); iScanInfo->Next() ) +#endif + { + TUint8 ieLen( 0 ); + const TUint8* ieData; + TBuf8 ssid8; +#ifdef __WINS__ + TBuf8 ssidData; + ieData = ssidData.PtrZ(); + switch (j) + { + case KIndexOfFirstEmulatedAvailableNetwork: + { + ssidData = _L8("Available Network"); + break; + } + case KIndexOfSecondEmulatedAvailableNetwork: + { + ssidData = _L8("Available Network 2"); + break; + } + default: + { + User::Panic( KWiFiPanic , KErrNotFound ); + break; + } + } + ieLen = ssidData.Length(); + TInt ret = KErrNone; +#else + TInt ret = iScanInfo->InformationElement( E802Dot11SsidIE, ieLen, + &ieData ); +#endif + User::LeaveIfError( ret ); + if ( ieLen ) + { + CLOG_WRITE( "Starting copying ssid" ); + // get the ssid + ssid8.Copy( ieData, ieLen ); + CLOG_WRITE( "SSID copied" ); + if ( !(*iIapParametersArray)[i].iSsid.Compare( ssid8 ) ) + { + iAvailableNetworks.Append(i); + found = ETrue; + } + } + } + } + + if (iAvailableNetworks.Count() == 1) + { + // only one network available, go to confirmation note + iSelectedNetworkIndex = 0; + SetNextStateAndComplete( EWiFiProtSettingsConfNote ); + } + else if (iAvailableNetworks.Count() > 1) + { + // more are available, select connection dialog + SetNextStateAndComplete( EWiFiProtSelectConnection ); + } + else + { + // no wlan networks found note + ShowNoWlanNetworksNoteL(); + } + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::CheckNetworkAvailabilityL" ); + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::SelectConnection +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::SelectConnectionL( ) + { + CDesCArrayFlat* items = + new ( ELeave ) CDesCArrayFlat( KArrayGranularity ); + CleanupStack::PushL( items ); + + _LIT( KListBoxItemFormat, "%d\t%s\t" ); + const TInt KListBoxItemFormatLength = 4; + TBuf buf; + for (TInt i = 0; i < iAvailableNetworks.Count(); i++ ) + { + // We have to convert the 8-bit SSID to 16-bit + HBufC* ssid16 = HBufC::NewLC( (*iIapParametersArray) + [iAvailableNetworks[i]].iSsid.Length()+1 ); + TPtr ssid16Ptr( ssid16->Des() ); + CnvUtfConverter::ConvertToUnicodeFromUtf8( ssid16Ptr, + (*iIapParametersArray)[iAvailableNetworks[i]].iSsid ); + ssid16Ptr.ZeroTerminate(); + buf.Format( KListBoxItemFormat, + 0/*we use only one icon*/, ssid16->Ptr() ); + CleanupStack::PopAndDestroy( ssid16 ); + items->AppendL(buf); + } + CAknIconArray* icons = new( ELeave ) CAknIconArray( KIconsGranularity ); + CleanupStack::PushL( icons ); + //creating icon + TAknsItemID id; + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + + TParse mbmFile; + User::LeaveIfError( mbmFile.Set( KWiFiFileIcons, + &KDC_BITMAP_DIR, + NULL ) ); + + CGulIcon* icon = AknsUtils::CreateGulIconL( + skinInstance, + id, + mbmFile.FullName(), + EMbmWifiprotQgn_prop_wlan_bearer, + EMbmWifiprotQgn_prop_wlan_bearer_mask ); + /// + + CleanupStack::PushL(icon); + icons->AppendL( icon ); + CleanupStack::Pop(); //icon array takes ownership + // we are finished, don't create any iaps in connection mode! + iNextWiFiProtState = EWiFiProtFinished; + CWiFiProtSelectNetworkDlg* dlg = + new ( ELeave ) CWiFiProtSelectNetworkDlg(iStatus , + iSelectedNetworkIndex, + items, icons ); + CleanupStack::Pop( icons ); // list takes ownership + CleanupStack::Pop( items );// list takes ownership + dlg->PrepareAndRunLD( ); + SetActive(); + } + +// -------------------------------------------------------------------------- +// void CWiFiProtActiveRunner::ShowNoWlanNetworksNoteL() +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::ShowNoWlanNetworksNoteL() + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::ShowNoWlanNetworksNoteL" ); + HBufC* stringLabel = StringLoader::LoadLC( + R_QTN_WLAN_INFO_NO_NETWORKS_FOUND ); + + RAknUiServer* globalNote = CAknSgcClient::AknSrv(); + if ( globalNote->Handle() ) + { + globalNote->ShowGlobalNoteL( *stringLabel, + EAknGlobalInformationNote ); + } + CleanupStack::PopAndDestroy( stringLabel ); + SetNextStateAndComplete( EWiFiProtFinished ); + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::ShowNoWlanNetworksNoteL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::CancelOngoingRequest +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::CancelOngoingRequest() + { + + CLOG_ENTERFN( "CWiFiProtActiveRunner::CancelOngoingRequest" ); + + switch ( iORequest ) + { + case EWiFiProtReqConfirmDialog: + { + // Remove the showing dialog and cancel the request + delete iConfirmationDialog; + iConfirmationDialog = NULL; + TRequestStatus* pS = &iStatus; + User::RequestComplete( pS, KErrCancel ); + break; + } + case EWiFiProtReqInitDialog: + { + // Remove the showing dialog and cancel the request + delete iInitDialog; + iInitDialog = NULL; + TRequestStatus* pS = &iStatus; + User::RequestComplete( pS, KErrCancel ); + break; + } + case EWiFiProtReqWPS : + { + if ( iPinQueryActive ) + { + delete iPinDlg; + iPinDlg = NULL; + } + if ( iWlanMgmtEngine ) + { + CLOG_WRITE( "Calling WPS cancel!" ); + iWlanMgmtEngine->CancelProtectedSetup(); + CLOG_WRITE( "WPS cancel called!" ); + } + break; + } + case EWiFiProtReqWlanScan : + { + iWlanMgmtEngine->CancelGetScanResults(); + break; + } + case EWiFiProtReqNone : + { + // it is possible, especially in emulator, that the pin dialog + // is still visible at this point + if ( iPinQueryActive ) + { + delete iPinDlg; + iPinDlg = NULL; + TRequestStatus* pS = &iStatus; + User::RequestComplete( pS, KErrCancel ); + } + // set CancelCalled flag to make RunL start shutdown next time + iUserCancelled = ETrue; + break; + } + + default: + { + // should not ever get here + } + } + + CLOG_LEAVEFN( "CWiFiProtActiveRunner::CancelOngoingRequest" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveRunner::SetWepKeyL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveRunner::SetWepKeyL( CWEPSecuritySettings& + aWepSecSettings, + TWlanWepKey& aWepKey, + TInt aKeyNumber ) + { + if ( aWepKey != KNullDesC8) + { + TBool wepKeyInAsciiFormat = IsWepFormatHexL( aWepKey.Length() ); + TBuf wepBuf16; + wepBuf16.Copy( aWepKey ); + User::LeaveIfError(aWepSecSettings.SetKeyDataL( aKeyNumber, wepBuf16, + wepKeyInAsciiFormat ) ); + CLOG_WRITEF( _L("Wep key: %d"), aKeyNumber ); + CLOG_WRITEF( wepBuf16 ); + } + } + +// -------------------------------------------------------------------------- +// TInt CWiFiProtActiveRunner::UsePinCodeLinkSelectedL() +// -------------------------------------------------------------------------- +// +TInt CWiFiProtActiveRunner::UsePinCodeLinkSelectedL( TAny* aObject ) + { + CLOG_ENTERFN( "CWiFiProtActiveRunner::UsePinCodeLinkSelectedL" ); + CWiFiProtActiveRunner* myself = + static_cast( aObject ); + myself->DoUsePinCodeLinkSelectedL(); + CLOG_LEAVEFN( "CWiFiProtActiveRunner::UsePinCodeLinkSelectedL" ); + + return 1; + } +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotconfirmationnotedlg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotconfirmationnotedlg.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWiFiProtConfirmationNoteDlg. +* +*/ + + +// INCLUDE FILES +//system includes +#include + +//user includes +#include "wifiprotconfirmationnotedlg.h" +#include "wifiprotdlgsplugin.h" +#include "wifiprotplugin.hrh" + +// ========================== MEMBER FUNCTIONS ============================== +// +// -------------------------------------------------------------------------- +// CWiFiProtConfirmationNoteDlg::CWiFiProtConfirmationNoteDlg +// -------------------------------------------------------------------------- +// +CWiFiProtConfirmationNoteDlg::CWiFiProtConfirmationNoteDlg( + TRequestStatus& aStatus ): + iRequestStatus( aStatus ) + { + iRequestStatus = KRequestPending; + } + + +// -------------------------------------------------------------------------- +// CWiFiProtConfirmationNoteDlg::~CWiFiProtConfirmationNoteDlg +// -------------------------------------------------------------------------- +// +CWiFiProtConfirmationNoteDlg::~CWiFiProtConfirmationNoteDlg() + { + STATIC_CAST( CEikServAppUi*, + CCoeEnv::Static()->AppUi() )->SuppressAppSwitching( EFalse ); + } + +// -------------------------------------------------------------------------- +// CWiFiProtInitiateEasySetupDlg::ProcessCommandL() +// -------------------------------------------------------------------------- +// +void CWiFiProtConfirmationNoteDlg::ProcessCommandL( TInt aCommandId ) + { + switch ( aCommandId ) + { + case EWiFiSoftkeyContinue: //should use callback but it doesn't work + { + TryExitL(aCommandId); + break; + } + default: + { + CAknQueryDialog::ProcessCommandL( aCommandId ); + break; + } + } + } + +// -------------------------------------------------------------------------- +// CWiFiProtConfirmationNoteDlg::OkToExitL +// -------------------------------------------------------------------------- +// +TBool CWiFiProtConfirmationNoteDlg::OkToExitL( TInt aButtonId ) + { + TInt status = KErrCancel; + if (aButtonId == EAknSoftkeyOk + || aButtonId == EAknSoftkeyYes + || aButtonId == EAknSoftkeyDone + || aButtonId == EWiFiSoftkeyContinue ) + { + status = KErrNone; + } + else if ( aButtonId == EAknSoftkeyNo ) + { + status = KErrCancel; // no selected + } + else + { + status = KErrAbort; // end key pressed + } + + TRequestStatus* pS = &iRequestStatus; + User::RequestComplete( pS, status ); + return ETrue; + } + + +// -------------------------------------------------------------------------- +// CWiFiProtConfirmationNoteDlg::PreLayoutDynInitL() +// -------------------------------------------------------------------------- +// +void CWiFiProtConfirmationNoteDlg::PreLayoutDynInitL() + { + CAknQueryDialog::PreLayoutDynInitL(); + STATIC_CAST( CEikServAppUi*, + CCoeEnv::Static()->AppUi() )->SuppressAppSwitching( ETrue ); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotdlgsplugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotdlgsplugin.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,458 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 CWiFiProtDlgsPlugin. +* +*/ + + +// INCLUDE FILES +#include // For RProperty +#include +#include +#include +#include + +#include "wifiprotdlgsplugin.h" +#include "wifiprotplugin.h" +#include "wifiprotlogger.h" +#include "wifiprotactiverunner.h" + + + +using namespace WiFiProt; + +// CONSTS +_LIT( KDriveZ, "z:" ); + +// ============================ MEMBER FUNCTIONS ============================ + +// -------------------------------------------------------------------------- +// CWiFiProtDlgsPlugin* CWiFiProtDlgsPlugin::NewL() +// -------------------------------------------------------------------------- +// +CWiFiProtDlgsPlugin* CWiFiProtDlgsPlugin::NewL( + const TBool aResourceFileResponsible, + RCmManagerExt* aCmManagerExt ) + + { + CLOG_ENTERFN( "CWiFiProtDlgsPlugin::NewL" ); + + CWiFiProtDlgsPlugin* self = new ( ELeave ) CWiFiProtDlgsPlugin(); + CleanupStack::PushL( self ); + self->ConstructL( KResourceFileName, + aResourceFileResponsible, aCmManagerExt ); + CleanupStack::Pop( self ); + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::NewL" ); + + return self; + } + +// -------------------------------------------------------------------------- +// CWiFiProtDlgsPlugin* CWiFiProtDlgsPlugin::NewL() +// -------------------------------------------------------------------------- +// +CWiFiProtDlgsPlugin* CWiFiProtDlgsPlugin::NewL( + const TBool aResourceFileResponsible ) + { + CLOG_ENTERFN( "CWiFiProtDlgsPlugin::NewL (without passed CmManager)" ); + + CWiFiProtDlgsPlugin* ret = NewL( aResourceFileResponsible, NULL ); + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::NewL (without passed CmManager)" ); + + return ret; + } + +// -------------------------------------------------------------------------- +// CWiFiProtDlgsPlugin::~CWiFiProtDlgsPlugin +// -------------------------------------------------------------------------- +// +CWiFiProtDlgsPlugin::~CWiFiProtDlgsPlugin( ) + + { + CLOG_ENTERFN( "CWiFiProtDlgsPlugin::~CWiFiProtDlgsPlugin" ); + + delete iRunner; + + //we didn't get a cmManager from the client, so use our own + if (iPassedCmManagerExt == NULL) + { + iCmManagerExt.Close(); + } + + iUids.Close(); + + if ( iResource ) + { + CCoeEnv::Static()->DeleteResourceFile( iResource ); + } + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::~CWiFiProtDlgsPlugin" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtDlgsPlugin::TNotifierInfo +// CWiFiProtDlgsPlugin::Info() const +// -------------------------------------------------------------------------- +// +CWiFiProtDlgsPlugin::TNotifierInfo CWiFiProtDlgsPlugin::Info() const + { + return iInfo; + } + +// -------------------------------------------------------------------------- +// TPtrC8 CWiFiProtDlgsPlugin::StartL() +// -------------------------------------------------------------------------- +// +TPtrC8 CWiFiProtDlgsPlugin::StartL( const TDesC8& /*aBuffer*/ ) + { + CLOG_WRITE( "CWiFiProtDlgsPlugin::StartL" ); + return KNullDesC8().Ptr(); + } + +// -------------------------------------------------------------------------- +// void CWiFiProtDlgsPlugin::Cancel() +// -------------------------------------------------------------------------- +// +void CWiFiProtDlgsPlugin::Cancel() + { + CLOG_ENTERFN( "CWiFiProtDlgsPlugin::Cancel" ); + + if ( !iCancelled ) + { + if ( iRunner && !iCancelledFromInside ) + { + iClientCancelled = ETrue; + iRunner->CancelByClient(); + } + iCancelled = ETrue; + if ( !iMessage.IsNull() ) + { + if ( iConnMode ) + { + TRAP_IGNORE( iMessage.WriteL( iReplySlot, + TPckg( + TWlanProtectedSetupCredentialAttribute() ) + )); + } + else + { + TRAP_IGNORE( iMessage.WriteL( iReplySlot, + TPckg( KNullDesC8() ) + )); + } + iMessage.Complete( KErrCancel ); + } + } + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::Cancel" ); + + } + +// -------------------------------------------------------------------------- +// void CWiFiProtDlgsPlugin::Release() +// -------------------------------------------------------------------------- +// +void CWiFiProtDlgsPlugin::Release() + { + CLOG_ENTERFN( "CWiFiProtDlgsPlugin::Release" ); + + delete this; + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::Release" ); + } + +// -------------------------------------------------------------------------- +// TPtrC8 CWiFiProtDlgsPlugin::UpdateL() +// -------------------------------------------------------------------------- +// +TPtrC8 CWiFiProtDlgsPlugin::UpdateL(const TDesC8& /*aBuffer*/) + { + return KNullDesC8().Ptr(); + } + +// -------------------------------------------------------------------------- +// void CWiFiProtDlgsPlugin::CompleteL() +// -------------------------------------------------------------------------- +// +void CWiFiProtDlgsPlugin::CompleteL( TInt aStatus ) + { + CLOG_ENTERFN( "CWiFiProtDlgsPlugin::CompleteL" ); + + CLOG_WRITEF( _L( "aStatus:" ), aStatus ); + iCancelled = ETrue; + if ( !iMessage.IsNull() ) + { + if ( iConnMode ) + { + // return a different kind of message + // for connection creation + WiFiProt::TWiFiConnOutputParams connOutputParams = + WiFiProt::TWiFiConnOutputParams( iNetworkSettings ); + connOutputParams.iReturn = iReturn; + iMessage.WriteL( iReplySlot, + TPckg( connOutputParams ) ); + } + else + { + // ... or iap(s) creation + const TInt elementSize = sizeof(TUint32); + TBuf8<(KMaxNumberOfUids * elementSize)> buf; + TInt uidsCount = iUids.Count(); + if ( uidsCount > KMaxNumberOfUids ) + { + uidsCount = KMaxNumberOfUids; + } + // copy data from the array to iIapIds in TWiFiOutputParams + buf.Append((const TUint8 *)(&iUids[0]), uidsCount *elementSize); + //append return value + WiFiProt::TWiFiOutputParams outputParams = + WiFiProt::TWiFiOutputParams(buf); + outputParams.iReturn = iReturn; + iMessage.WriteL( iReplySlot, + TPckg( outputParams ) ); + } + iMessage.Complete( aStatus ); + } + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::CompleteL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtDlgsPlugin::SetCancelledFlag +// -------------------------------------------------------------------------- +// +void CWiFiProtDlgsPlugin::SetCancelledFlag( TBool aCancelled ) + { + iCancelled = aCancelled; + } + +// -------------------------------------------------------------------------- +// CWiFiProtDlgsPlugin::TNotifierInfo CWiFiProtDlgsPlugin::RegisterL() +// -------------------------------------------------------------------------- +// +CWiFiProtDlgsPlugin::TNotifierInfo CWiFiProtDlgsPlugin::RegisterL() + { + CLOG_ENTERFN( "CWiFiProtDlgsPlugin::RegisterL" ); + + iInfo.iUid = KUidWiFiProtSetup; + iInfo.iPriority = ENotifierPriorityHigh; + iInfo.iChannel = KUidWiFiProtSetup; + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::RegisterL" ); + + return iInfo; + } + +// -------------------------------------------------------------------------- +// void CWiFiProtDlgsPlugin::StartL +// -------------------------------------------------------------------------- +// +void CWiFiProtDlgsPlugin::StartL( const TDesC8& aBuffer, + TInt aReplySlot, + const RMessagePtr2& aMessage ) + { + CLOG_ENTERFN( "CWiFiProtDlgsPlugin::StartL" ); + + TPckgBuf pckgParams( + TPckgBuf(TWiFiInputParams(KNullDesC8(), + EFalse))); + pckgParams.Copy( *((TPckgBuf*) (&aBuffer))); + TWiFiInputParams params((pckgParams)()); + iConnMode = params.iConnectionNeeded; + TWlanSsid ssid; + ssid.Copy( params.iSSid ); + + iCancelled = EFalse; + + iReplySlot = aReplySlot; + iMessage = aMessage; + + if ( iConnMode ) + { + // no need for uid array to return, but we need a single network + // settings struct + iRunner->StartProtectedSetupConnL( ssid, iNetworkSettings, + CmManagerToUse()); + } + else + { + iRunner->StartProtectedSetupAsyncL( ssid, iUids, CmManagerToUse() ); + } + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::StartL" ); + } + +// -------------------------------------------------------------------------- +// WiFiProt::TWiFiReturn CWiFiProtDlgsPlugin::CompleteProcessL +// -------------------------------------------------------------------------- +// +void CWiFiProtDlgsPlugin::CompleteProcessL( WiFiProt::TWiFiReturn aReturnValue ) + { + CLOG_ENTERFN( "WiFiProtDlgsPlugin::CompleteProcessL" ); + iReturn = aReturnValue; + switch ( aReturnValue ) + { + case EWiFiOK: + { + CLOG_WRITE("StartProtectedSetupL returned EWiFiOK"); + CompleteL( KErrNone ); + break; + } + case EWifiNoAuto: + { + CLOG_WRITE("StartProtectedSetupL returned EWifiNoAuto"); + CompleteL( KErrNone ); + break; + } + case EWiFiCancel: + { + CLOG_WRITE("StartProtectedSetupL returned EWiFiCancel"); + iCancelledFromInside = ETrue; + Cancel(); + break; + } + default: + { + //should never happen + CLOG_WRITE("Unhandled exit value, leaving..."); + User::Leave( KErrGeneral ); + break; + } + } + CLOG_WRITEF( _L( "Uids returned:" ), iUids.Count() ); + for ( TInt i = 0;i& aUidsReturned) + { + CLOG_ENTERFN( "CWiFiProtDlgsPlugin::StartFromUiL" ); + + CLOG_WRITE("Input params:"); + CLOG_WRITE("SSid:"); + + TBuf buf; + buf.Copy(aSSid); + CLOG_WRITEF( buf ); + CLOG_WRITE("Connection needed:"); + if ( aConnectionNeeded ) + { + CLOG_WRITE("ETrue"); + } + else + { + CLOG_WRITE("EFalse"); + } + //use passed CmManager if present + WiFiProt::TWiFiReturn ret = iRunner->StartProtectedSetupL( + aSSid, aUidsReturned, CmManagerToUse()); + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::StartFromUiL" ); + return ret; + } + +// -------------------------------------------------------------------------- +// void CWiFiProtDlgsPlugin::CmManagerToUse() +// -------------------------------------------------------------------------- +// +RCmManagerExt& CWiFiProtDlgsPlugin::CmManagerToUse() + { + CLOG_ENTERFN( "CWiFiProtDlgsPlugin::CmManagerToUse" ); + + if (iPassedCmManagerExt == NULL ) + { + CLOG_WRITE("Own CmManagerExt used"); + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::CmManagerToUse" ); + + return iCmManagerExt; + } + else + { + CLOG_WRITE("Passed CmManagerExt used"); + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::CmManagerToUse" ); + + return *iPassedCmManagerExt; + } + } + +// -------------------------------------------------------------------------- +// CWiFiProtDlgsPlugin::CWiFiProtDlgsPlugin() +// -------------------------------------------------------------------------- +// +CWiFiProtDlgsPlugin::CWiFiProtDlgsPlugin() +: iCancelled( EFalse ), + iResource( 0 ), + iCancelledFromInside( EFalse ) + + { + CLOG_WRITE("CWiFiProtDlgsPlugin::CWiFiProtDlgsPlugin"); + } + +// -------------------------------------------------------------------------- +// void CWiFiProtDlgsPlugin::ConstructL( ) +// -------------------------------------------------------------------------- +// +void CWiFiProtDlgsPlugin::ConstructL(const TDesC& aResourceFileName, + const TBool aResourceFileResponsible, + RCmManagerExt* aCmManagerExt ) + { + CLOG_ENTERFN( "CWiFiProtDlgsPlugin::ConstructL" ); + + if ( aResourceFileResponsible ) + { + // Since this is a .DLL, resource files that are to be used by the + // notifier aren't added automatically so we do that here. + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( aResourceFileName ); + + BaflUtils::NearestLanguageFile( CCoeEnv::Static()->FsSession(), + fileName ); + iResource = CCoeEnv::Static()->AddResourceFileL( fileName ); + } + + iPassedCmManagerExt = aCmManagerExt; + //we didn't get a cmManager from the client, so use our own + if (iPassedCmManagerExt == NULL) + { + iCmManagerExt.OpenL(); + } + iRunner = CWiFiProtActiveRunner::NewL( this ); + + CLOG_LEAVEFN( "CWiFiProtDlgsPlugin::ConstructL" ); + + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotenterpindlg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotenterpindlg.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,125 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWiFiProtEnterPinDlg. +* +*/ + + +// INCLUDE FILES +//system includes +#include + +//user includes +#include "wifiprotenterpindlg.h" +#include "wifiprotactiverunnercallback.h" +#include "wifiprotplugin.hrh" + + +// FORWARD DECLARATIONS +//class MActiveRunnerCallback; + +// ================= MEMBER FUNCTIONS ======================= +// +// -------------------------------------------------------------------------- +// CWiFiProtEnterPinDlg::CWiFiProtEnterPinDlg +// -------------------------------------------------------------------------- +// +CWiFiProtEnterPinDlg::CWiFiProtEnterPinDlg( + MActiveRunnerCallback& aActiveRunnerCallback ): + iActiveRunnerCallback ( aActiveRunnerCallback ) + { + } + + +// -------------------------------------------------------------------------- +// CWiFiProtEnterPinDlg::~CWiFiProtEnterPinDlg +// -------------------------------------------------------------------------- +// +CWiFiProtEnterPinDlg::~CWiFiProtEnterPinDlg() + { + STATIC_CAST( CEikServAppUi*, + CCoeEnv::Static()->AppUi() )->SuppressAppSwitching( EFalse ); + } + +// -------------------------------------------------------------------------- +// CWiFiProtInitiateEasySetupDlg::ProcessCommandL() +// -------------------------------------------------------------------------- +// +void CWiFiProtEnterPinDlg::ProcessCommandL( TInt aCommandId ) + { + switch ( aCommandId ) + { + case EWiFiSoftkeyContinue: + { + TryExitL(aCommandId); + break; + } + default: + { + CAknQueryDialog::ProcessCommandL( aCommandId ); + break; + } + } + } + +// -------------------------------------------------------------------------- +// CWiFiProtEnterPinDlg::OkToExitL +// -------------------------------------------------------------------------- +// +TBool CWiFiProtEnterPinDlg::OkToExitL( TInt aButtonId ) + { + if (aButtonId == EAknSoftkeyEmpty) + { + return EFalse; + } + else + { + TInt status = KErrCancel; + if ( aButtonId == EAknSoftkeyOk + || aButtonId == EAknSoftkeyYes + || aButtonId == EAknSoftkeyDone + || aButtonId == EWiFiSoftkeyContinue ) + { + status = KErrNone; + } + iActiveRunnerCallback.PinQueryExitL( status ); + return ETrue; + } + } + + +// -------------------------------------------------------------------------- +// CWiFiProtEnterPinDlg::PreLayoutDynInitL() +// -------------------------------------------------------------------------- +// +void CWiFiProtEnterPinDlg::PreLayoutDynInitL() + { + CAknQueryDialog::PreLayoutDynInitL(); + STATIC_CAST( CEikServAppUi*, + CCoeEnv::Static()->AppUi() )->SuppressAppSwitching( ETrue ); + } + +// -------------------------------------------------------------------------- +// CWiFiProtEnterPinDlg::RemoveCancel +// -------------------------------------------------------------------------- +// +void CWiFiProtEnterPinDlg::RemoveCancel() + { + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + TRAP_IGNORE( cba.SetCommandL( CEikButtonGroupContainer::ERightSoftkeyPosition, + EAknSoftkeyEmpty, KNullDesC) ); + cba.DrawNow(); + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotinitiateeasysetupdlg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotinitiateeasysetupdlg.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,227 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWiFiProtInitiateEasySetupDlg. +* +*/ + + +// INCLUDE FILES +//system includes +#include +#include +#include + +//user includes +#include "wifiprotinitiateeasysetupdlg.h" +#include "wifiprotdlgsplugin.h" +#include "wifiprotplugin.hrh" +#include "wifiprotlogger.h" + +// ========================= MEMBER FUNCTIONS =============================== +// +// -------------------------------------------------------------------------- +// CWiFiProtInitiateEasySetupDlg::CWiFiProtInitiateEasySetupDlg +// -------------------------------------------------------------------------- +// +CWiFiProtInitiateEasySetupDlg::CWiFiProtInitiateEasySetupDlg( + TRequestStatus& aStatus ): + iButtonGroupPreviouslyChanged( EFalse ), + iRequestStatus( aStatus ) + { + CLOG_ENTERFN( + "CWiFiProtInitiateEasySetupDlg::CWiFiProtInitiateEasySetupDlg" ); + + iRequestStatus = KRequestPending; + + CLOG_LEAVEFN( + "CWiFiProtInitiateEasySetupDlg::CWiFiProtInitiateEasySetupDlg" ); + + } + + +// -------------------------------------------------------------------------- +// CWiFiProtInitiateEasySetupDlg::~CWiFiProtInitiateEasySetupDlg +// -------------------------------------------------------------------------- +// +CWiFiProtInitiateEasySetupDlg::~CWiFiProtInitiateEasySetupDlg() + { + CLOG_ENTERFN( + "CWiFiProtInitiateEasySetupDlg::~CWiFiProtInitiateEasySetupDlg" ); + + STATIC_CAST( CEikServAppUi*, + CCoeEnv::Static()->AppUi() )->SuppressAppSwitching( EFalse ); + CLOG_LEAVEFN( + "CWiFiProtInitiateEasySetupDlg::~CWiFiProtInitiateEasySetupDlg" ); + + } + + +// -------------------------------------------------------------------------- +// CWiFiProtInitiateEasySetupDlg::OkToExitL +// -------------------------------------------------------------------------- +// +TBool CWiFiProtInitiateEasySetupDlg::OkToExitL( TInt aButtonId ) + { + CLOG_ENTERFN( "CWiFiProtInitiateEasySetupDlg::OkToExitL" ); + + TInt status = KErrCancel; + if ( aButtonId == EAknSoftkeyOk + || aButtonId == EAknSoftkeyYes + || aButtonId == EAknSoftkeyDone + || aButtonId == EWiFiSoftkeyContinue + || aButtonId == EAknSoftkeySelect ) + { + status = KErrNone; + } + // if aButtonId == EAknSoftkeyView then we have to destroy the dialog + // afterwards, not from the callback. In this case we do not complete + // the client, it was completed before, just exit + + if ( !(aButtonId == EAknSoftkeyView )) + { + // this is called when we can destroy the dialog + // and complete the client (activerunner) the same time + TRequestStatus* pS = &iRequestStatus; + User::RequestComplete( pS, status ); + } + CLOG_LEAVEFN( "CWiFiProtInitiateEasySetupDlg::OkToExitL" ); + return ETrue; + } + + +// -------------------------------------------------------------------------- +// CWiFiProtInitiateEasySetupDlg::TryExitL() +// -------------------------------------------------------------------------- +// +void CWiFiProtInitiateEasySetupDlg::TryExitL( TInt aButtonId ) + { + CLOG_ENTERFN( "CWiFiProtInitiateEasySetupDlg::TryExitL" ); + + CAknMessageQueryDialog::TryExitL( aButtonId ); + + CLOG_LEAVEFN( "CWiFiProtInitiateEasySetupDlg::TryExitL" ); + + } + +// -------------------------------------------------------------------------- +// CWiFiProtInitiateEasySetupDlg::PreLayoutDynInitL() +// -------------------------------------------------------------------------- +// +void CWiFiProtInitiateEasySetupDlg::PreLayoutDynInitL() + { + CLOG_ENTERFN( "CWiFiProtInitiateEasySetupDlg::PreLayoutDynInitL" ); + + STATIC_CAST( CEikServAppUi*, + CCoeEnv::Static()->AppUi() )->SuppressAppSwitching( ETrue ); + CAknMessageQueryDialog::PreLayoutDynInitL(); + + CLOG_LEAVEFN( "CWiFiProtInitiateEasySetupDlg::PreLayoutDynInitL" ); + + } + +// -------------------------------------------------------------------------- +// CConfirmationQuery::OfferKeyEventL() +// -------------------------------------------------------------------------- +// +TKeyResponse CWiFiProtInitiateEasySetupDlg::OfferKeyEventL( + const TKeyEvent& aKeyEvent, + TEventCode aModifiers ) + { + CLOG_ENTERFN( "CWiFiProtInitiateEasySetupDlg::OfferKeyEventL" ); + TKeyResponse answer = EKeyWasNotConsumed; + TInt code = aKeyEvent.iCode; + switch ( code ) + { + // both keys are handled the same way + // they mean 'movement in the list' + case EKeyUpArrow: + case EKeyDownArrow: + { + CAknMessageQueryControl* messageQueryControl = STATIC_CAST( + CAknMessageQueryControl*, + Control( EAknMessageQueryContentId ) ); + if ( messageQueryControl ) + { + answer = messageQueryControl->OfferKeyEventL( + aKeyEvent, aModifiers ); + if ( answer == EKeyWasConsumed ) + { + if ( messageQueryControl->LinkHighLighted() ) + { + if ( !iButtonGroupPreviouslyChanged ) + { + CEikButtonGroupContainer& cba = + ButtonGroupContainer(); + + ButtonGroupContainer().AddCommandSetToStackL( + R_SOFTKEYS_SELECT_CANCEL__SELECT ); + cba.UpdateCommandObserverL( + CEikButtonGroupContainer::ELeftSoftkeyPosition, + *this ); + + cba.UpdateCommandObserverL( + CEikButtonGroupContainer::EMiddleSoftkeyPosition, + *this ); + + cba.DrawNow(); + + iButtonGroupPreviouslyChanged = ETrue; + } + } + else if ( iButtonGroupPreviouslyChanged ) + { + CEikButtonGroupContainer& cba = + ButtonGroupContainer(); + + cba.RemoveCommandObserver( + CEikButtonGroupContainer::ELeftSoftkeyPosition ); + + cba.RemoveCommandObserver( + CEikButtonGroupContainer::EMiddleSoftkeyPosition ); + + cba.RemoveCommandFromStack( + CEikButtonGroupContainer::ELeftSoftkeyPosition, + EAknSoftkeyView ); + + cba.RemoveCommandFromStack( + CEikButtonGroupContainer::EMiddleSoftkeyPosition, + EAknSoftkeyView ); + + cba.RemoveCommandFromStack( + CEikButtonGroupContainer::ERightSoftkeyPosition, + EAknSoftkeyNo ); + + cba.DrawNow(); + + iButtonGroupPreviouslyChanged = EFalse; + } + } + } + break; + } + + default: + { + answer = CAknMessageQueryDialog::OfferKeyEventL( aKeyEvent, + aModifiers ); + break; + } + } + + CLOG_LEAVEFN( "CWiFiProtInitiateEasySetupDlg::OfferKeyEventL" ); + + return answer; + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotplugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotplugin.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 base plugin. +* +*/ + + +// INCLUDE FILES + +#include "wifiprotplugin.h" +#include "wifiprotdlgsplugin.h" + + +// CONSTANTS + +LOCAL_D const TInt KPluginGranularity = 4; + +// FORWARD DECLARATIONS + +LOCAL_C void CreateNotifiersL( + CArrayPtrFlat* aNotifiers ); + +// -------------------------------------------------------------------------- +// NotifierArray() +// Lib main entry point +// -------------------------------------------------------------------------- +// +EXPORT_C CArrayPtr* NotifierArray() + { + + CArrayPtrFlat* array = NULL; + TRAPD(err, array = new (ELeave) + CArrayPtrFlat( KPluginGranularity )); + if (err || array == NULL) + { + return array; + } + TRAPD( err1, CreateNotifiersL( array ) ); + if( err1 ) + { + TInt count = array->Count(); + while( count-- ) + { + (*array)[count]->Release(); + } + delete array; + array = NULL; + } + + return( array ); + } + +// -------------------------------------------------------------------------- +// CreateNotifiersL() +// -------------------------------------------------------------------------- +// +LOCAL_C void CreateNotifiersL( + CArrayPtrFlat* aNotifiers ) + { + MEikSrvNotifierBase2 *serNotify; + TBool resourceFileResponsible = ETrue; + + serNotify = CWiFiProtDlgsPlugin::NewL( resourceFileResponsible ); + CleanupStack::PushL( serNotify ); + aNotifiers->AppendL( serNotify ); + CleanupStack::Pop( serNotify ); + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotselectnetworkdlg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotselectnetworkdlg.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,156 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWiFiProtSelectNetworkDlg. +* +*/ + + +// INCLUDE FILES +//system includes +#include +#include +#include +#include + +//user includes +#include "wifiprotselectnetworkdlg.h" +#include "wifiprotdlgsplugin.h" +#include "wifiprotplugin.hrh" +// ========================== MEMBER FUNCTIONS ============================== +// +// -------------------------------------------------------------------------- +// CWiFiProtSelectNetworkDlg::CWiFiProtSelectNetworkDlg +// -------------------------------------------------------------------------- +// +CWiFiProtSelectNetworkDlg::CWiFiProtSelectNetworkDlg( + TRequestStatus& aStatus , + TInt& aSelected , + CDesCArrayFlat* aItems, + CArrayPtr* aIcons ): + CAknListQueryDialog( &aSelected ), + iRequestStatus( aStatus ), + iSelected( aSelected ), + iIcons( aIcons ), + iItems( aItems ) + { + iRequestStatus = KRequestPending; + } + + +// -------------------------------------------------------------------------- +// CWiFiProtSelectNetworkDlg::~CWiFiProtSelectNetworkDlg +// -------------------------------------------------------------------------- +// +CWiFiProtSelectNetworkDlg::~CWiFiProtSelectNetworkDlg() + { + + STATIC_CAST( CEikServAppUi*, + CCoeEnv::Static()->AppUi() )->SuppressAppSwitching( EFalse ); + delete iIcons; + delete iItems; + } + +// -------------------------------------------------------------------------- +// void CSelectDestinationDlg::PrepareAndRunLD +// -------------------------------------------------------------------------- +// +void CWiFiProtSelectNetworkDlg::PrepareAndRunLD() + { + PrepareLC(R_CONN_LIST_QUERY); + // Set the description field on the query + HBufC* desc = StringLoader::LoadLC( + R_QTN_NETW_CONSET_WPS_DETAIL_SELECT_NETWORK ); + //ownership transferred + SetItemTextArray( iItems ); + iItems = NULL; + //ownership transferred + SetIconArrayL( iIcons ); + iIcons = NULL; + + MessageBox()->SetMessageTextL( desc ); + CleanupStack::PopAndDestroy( desc ); + RunLD(); + } + + +// -------------------------------------------------------------------------- +// CWiFiProtSelectNetworkDlg::OkToExitL +// -------------------------------------------------------------------------- +// +TBool CWiFiProtSelectNetworkDlg::OkToExitL( TInt aButtonId ) + { + TInt status = KErrCancel; + if ( aButtonId == EAknSoftkeyOk + || aButtonId == EAknSoftkeyYes + || aButtonId == EAknSoftkeyDone + || aButtonId == EAknSoftkeySelect ) + { + // This should be done automatically + // I have no idea why iSelected isn't updated + iSelected = ListBox()->CurrentItemIndex(); + status = KErrNone; + } + TRequestStatus* pS = &iRequestStatus; + User::RequestComplete( pS, status ); + + return ETrue; + } + +// -------------------------------------------------------------------------- +// CWiFiProtSelectNetworkDlg::PreLayoutDynInitL() +// -------------------------------------------------------------------------- +// +void CWiFiProtSelectNetworkDlg::PreLayoutDynInitL() + { + CAknListQueryDialog::PreLayoutDynInitL(); + STATIC_CAST( CEikServAppUi*, + CCoeEnv::Static()->AppUi() )->SuppressAppSwitching( ETrue ); + + } + +// -------------------------------------------------------------------------- +// void CSelectDestinationDlg::HandleResourceChange +// -------------------------------------------------------------------------- +// +void CWiFiProtSelectNetworkDlg::HandleResourceChange( TInt aType ) + { + if ( aType == KAknsMessageSkinChange ) + { + CAknListQueryDialog::HandleResourceChange( aType ); + + TRAP_IGNORE( SetIconArrayL( iIcons ) ); + + SizeChanged(); + } + else + { + if ( aType == KEikDynamicLayoutVariantSwitch ) + { + TRect mainPaneRect; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, + mainPaneRect ); + + TAknLayoutRect layoutRect; + layoutRect.LayoutRect( TRect( TPoint( 0, 0 ), + mainPaneRect.Size() ), + AKN_LAYOUT_WINDOW_list_gen_pane( 0 ) ); + + ListBox()->SetRect( layoutRect.Rect() ); + } + + // Base call + CAknListQueryDialog::HandleResourceChange( aType ); + } + } +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotuiinprocess.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotuiinprocess.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,108 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 CWifiProtUiInProcess. +* +*/ + + +// INCLUDE FILES + +#include +#include +#include + +#include "wifiprotdlgsplugin.h" +#include "wifiprotlogger.h" + +using namespace WiFiProt; + +// =========================== MEMBER FUNCTIONS ============================= + +// -------------------------------------------------------------------------- +// CWifiProtUiInProcess* CWifiProtUiInProcess::NewL() +// -------------------------------------------------------------------------- +// +EXPORT_C CWifiProtUiInProcess* CWifiProtUiInProcess::NewL( RCmManagerExt* + aCmManagerExt ) + { + CLOG_ENTERFN( "WiFiProtDlgsPlugin::NewL" ); + + CWifiProtUiInProcess* self = new ( ELeave ) CWifiProtUiInProcess(); + CleanupStack::PushL( self ); + self->ConstructL( aCmManagerExt ); + CleanupStack::Pop(); + CLOG_LEAVEFN( "WiFiProtDlgsPlugin::NewL" ); + return self; + } + + +// -------------------------------------------------------------------------- +// CWifiProtUiInProcess::~CWifiProtUiInProcess +// -------------------------------------------------------------------------- +// +CWifiProtUiInProcess::~CWifiProtUiInProcess( ) + + { + CLOG_ENTERFN( "WiFiProtDlgsPlugin::~CWifiProtUiInProcess" ); + delete iWiFiProtDlgsPlugin; + CLOG_LEAVEFN( "WiFiProtDlgsPlugin::~CWifiProtUiInProcess" ); + } + +// -------------------------------------------------------------------------- +// WiFiProt::TWiFiReturn CWifiProtUiInProcess::StartFromUiL +// -------------------------------------------------------------------------- +// +EXPORT_C WiFiProt::TWiFiReturn CWifiProtUiInProcess::StartFromUiL( + const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned ) + { + CLOG_ENTERFN( "WiFiProtDlgsPlugin::StartFromUiL" ); + + WiFiProt::TWiFiReturn ret = + iWiFiProtDlgsPlugin->StartFromUiL( aSSid, + aConnectionNeeded, + aUidsReturned ); + + CLOG_LEAVEFN( "WiFiProtDlgsPlugin::StartFromUiL" ); + + return ret; + } + + +// -------------------------------------------------------------------------- +// CWifiProtUiInProcess::CWifiProtUiInProcess +// -------------------------------------------------------------------------- +// +CWifiProtUiInProcess::CWifiProtUiInProcess( ): + iWiFiProtDlgsPlugin(NULL) + { + CLOG_ENTERFN( "WiFiProtDlgsPlugin::CWifiProtUiInProcess" ); + CLOG_LEAVEFN( "WiFiProtDlgsPlugin::CWifiProtUiInProcess" ); + } + +// -------------------------------------------------------------------------- +// void CWifiProtUiInProcess::ConstructL( ) +// -------------------------------------------------------------------------- +// +void CWifiProtUiInProcess::ConstructL( RCmManagerExt* aCmManagerExt ) + { + CLOG_ENTERFN( "WiFiProtDlgsPlugin::ConstructL" ); + + iWiFiProtDlgsPlugin = CWiFiProtDlgsPlugin::NewL( ETrue, aCmManagerExt ); + + CLOG_LEAVEFN( "WiFiProtDlgsPlugin::ConstructL" ); + + } +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/rom/WiFiProt.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/rom/WiFiProt.iby Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Image description file for WifiProtectedSetup +* +*/ + +#ifndef __WIFIPROT_IBY__ +#define __WIFIPROT_IBY__ + +REM Wi-Fi Protected Setup + +file=ABI_DIR\BUILD_DIR\WIFIPROTCLIENT.DLL SHARED_LIB_DIR\WIFIPROTCLIENT.DLL +file=ABI_DIR\BUILD_DIR\WIFIPROTPLUGIN.DLL SHARED_LIB_DIR\WIFIPROTPLUGIN.DLL + +#endif diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/rom/WiFiProtResources.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/rom/WiFiProtResources.iby Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Image description file for WifiProtectedSetup +* +*/ + +#ifndef __WIFIPROTRESOURCES_IBY__ +#define __WIFIPROTRESOURCES_IBY__ + +data=DATAZ_\RESOURCE_FILES_DIR\WiFiProtPlugin.rsc RESOURCE_FILES_DIR\WiFiProtPlugin.rsc + +#endif \ No newline at end of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/src/wifiprotactiveresp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/src/wifiprotactiveresp.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,240 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 CWiFiProtActiveResp class +* +*/ + + +// INCLUDE FILES +#include "wifiprotactiveresp.h" +#include "wifiprotlogger.h" + +//CONSTS +_LIT( KActiveRespPanic , "WPS Active Resp"); +// ================= MEMBER FUNCTIONS ======================= + + +// -------------------------------------------------------------------------- +// CWiFiProtActiveResp::NewL +// -------------------------------------------------------------------------- +// +CWiFiProtActiveResp* CWiFiProtActiveResp::NewL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned, + WiFiProt::TWiFiReturn& + aReturnValue ) + { + CLOG_ENTERFN( "CWiFiProtActiveResp::NewL" ); + CWiFiProtActiveResp* self = + new( ELeave )CWiFiProtActiveResp( aSSid , aConnectionNeeded, + aUidsReturned, + aReturnValue ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + CLOG_LEAVEFN( "CWiFiProtActiveResp::NewL" ); + return self; + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveResp::NewL +// -------------------------------------------------------------------------- +// +CWiFiProtActiveResp* CWiFiProtActiveResp::NewL( const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& + aNetworkSettings, + WiFiProt::TWiFiReturn& + aReturnValue ) + { + CLOG_ENTERFN( "CWiFiProtActiveResp::NewL" ); + CWiFiProtActiveResp* self = + new( ELeave )CWiFiProtActiveResp( aSSid , + aNetworkSettings, + aReturnValue ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + CLOG_LEAVEFN( "CWiFiProtActiveResp::NewL" ); + return self; + } + +// ---------------------------------------------------- +// CWiFiProtActiveResp::~CWiFiProtActiveResp() +// ---------------------------------------------------- +// +CWiFiProtActiveResp::~CWiFiProtActiveResp() + { + CLOG_ENTERFN( "CWiFiProtActiveResp::~CWiFiProtActiveResp" ); + Cancel(); + CLOG_LEAVEFN( "CWiFiProtActiveResp::~CWiFiProtActiveResp" ); + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveResp::RunL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveResp::RunL() + { + CLOG_ENTERFN( "CWiFiProtActiveResp::RunL"); + + if ( iWiFiInputParams().iConnectionNeeded ) + { + *iNetworkSettings = iWiFiConnOutputParams().iNetworkSettings; + iReturnValue = iWiFiConnOutputParams().iReturn; + } + else + { + if ( iStatus.Int() == KErrNone ) + { + //CM creation mode (WPS phase 1), return iap id array + const TInt elementSize = sizeof( TUint32 ); + const TInt elementCount = iWiFiOutputParams().iIapIds.Length() + / elementSize; + const TUint8* ptr = iWiFiOutputParams().iIapIds.Ptr(); + + for ( TInt i = 0; i < elementCount; i++) + { + iIapIds->Append( *( (TUint32*) &( ptr[elementSize*i] ) ) ); + } + } + iReturnValue = iWiFiOutputParams().iReturn; + } + + TRequestStatus* pS = iRequestStatus; + User::RequestComplete( pS, iStatus.Int() ); + + CLOG_LEAVEFN( "CWiFiProtActiveResp::RunL"); + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveResp::DoCancel +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveResp::DoCancel() + { + CLOG_ENTERFN( "CWiFiProtActiveResp:DoCancel"); + TRequestStatus* pS = iRequestStatus; + User::RequestComplete( pS, KErrCancel ); + CLOG_LEAVEFN( "CWiFiProtActiveResp::DoCancel"); + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveResp::Observe +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveResp::Observe( TRequestStatus &aStatus ) + { + CLOG_ENTERFN( "CWiFiProtActiveResp::Observe"); + CActiveScheduler::Add( this ); + + iRequestStatus = &aStatus; + *iRequestStatus = KRequestPending; + + SetActive(); + CLOG_LEAVEFN( "CWiFiProtActiveResp::Observe"); + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveResp::InputBuffer +// -------------------------------------------------------------------------- +// +TPckgBuf* CWiFiProtActiveResp::InputBuffer() + { + return &iWiFiInputParams; + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveResp::OutputBuffer +// -------------------------------------------------------------------------- +// +TPckgBuf* CWiFiProtActiveResp::OutputBuffer() + { + if ( iWiFiInputParams().iConnectionNeeded ) + { + // Should use ConnOutputBuffer() if configuring a connection! + User::Panic( KActiveRespPanic , KErrNotSupported); + } + return &iWiFiOutputParams; + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveResp::ConnOutputBuffer +// -------------------------------------------------------------------------- +// +TPckgBuf* CWiFiProtActiveResp::ConnOutputBuffer() + { + if ( !(iWiFiInputParams().iConnectionNeeded) ) + { + // Should use OutputBuffer() if not configuring a connection! + User::Panic( KActiveRespPanic , KErrNotSupported); + } + return &iWiFiConnOutputParams; + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveResp::CWiFiProtActiveResp +// -------------------------------------------------------------------------- +// +CWiFiProtActiveResp::CWiFiProtActiveResp( + const TWlanSsid& aSSid, TBool aConnectionNeeded, + RArray& aUidsReturned, + WiFiProt::TWiFiReturn& aReturnValue ) + : CActive( CActive::EPriorityUserInput ), + iIapIds( &aUidsReturned ), + iReturnValue( aReturnValue ), + iWiFiOutputParams( KNullDesC8() ), + iWiFiInputParams( TPckgBuf + ( WiFiProt::TWiFiInputParams( aSSid, + aConnectionNeeded ) ) ), + iWiFiConnOutputParams(TPckgBuf + ( WiFiProt::TWiFiConnOutputParams( + TWlanProtectedSetupCredentialAttribute() ) ) ) + { + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveResp::CWiFiProtActiveResp +// -------------------------------------------------------------------------- +// +CWiFiProtActiveResp::CWiFiProtActiveResp( + const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& + aNetworkSettings, + WiFiProt::TWiFiReturn& aReturnValue ) + : CActive( CActive::EPriorityUserInput ), + iIapIds( NULL ), + iReturnValue( aReturnValue ), + iWiFiOutputParams( KNullDesC8() ), + iWiFiInputParams( TPckgBuf + ( WiFiProt::TWiFiInputParams( aSSid, + ETrue ) ) ), + iWiFiConnOutputParams(TPckgBuf + ( WiFiProt::TWiFiConnOutputParams( + TWlanProtectedSetupCredentialAttribute() ) ) ), + iNetworkSettings( &aNetworkSettings ) + + { + } + +// -------------------------------------------------------------------------- +// CWiFiProtActiveResp::ConstructL +// -------------------------------------------------------------------------- +// +void CWiFiProtActiveResp::ConstructL() + { + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/src/wifiprotsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/src/wifiprotsession.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,210 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 RWiFiProtSession +* +*/ + + +// INCLUDE FILES +#include "wifiprotsession.h" +#include "e32ver.h" +#include +#include "wifiprotlogger.h" + +using namespace WiFiProt; + +// -------------------------------------------------------------------------- +// RWiFiProtSession::RWiFiProtSession() +// -------------------------------------------------------------------------- +// +RWiFiProtSession::RWiFiProtSession() : + RSessionBase(), + iNotifier( NULL ), + iWiFiProtActiveResp( NULL ) + { + CLOG_ENTERFN( "RWiFiProtSession::RWiFiProtSession" ); + CLOG_LEAVEFN( "RWiFiProtSession::RWiFiProtSession" ); + } + + +// -------------------------------------------------------------------------- +// ~RWiFiProtSession +// -------------------------------------------------------------------------- +// +RWiFiProtSession::~RWiFiProtSession() + { + CLOG_ENTERFN( "RWiFiProtSession::~RWiFiProtSession" ); + Close(); + CLOG_LEAVEFN( "RWiFiProtSession::~RWiFiProtSession" ); + } + + +// -------------------------------------------------------------------------- +// Connect +// +// Create a session to the extended notifier framework +// -------------------------------------------------------------------------- +// +TInt RWiFiProtSession::Connect() + { + CLOG_ENTERFN( "RWiFiProtSession::Connect" ); + + TInt error( KErrNone ); + if ( !iNotifier ) + { + TRAP( error, iNotifier = new (ELeave) RNotifier() ); + } + if ( !error && iNotifier ) + { + error = iNotifier->Connect(); + } + CLOG_LEAVEFN( "RWiFiProtSession::Connect" ); + return error; + } + +// -------------------------------------------------------------------------- +// Close +// -------------------------------------------------------------------------- +// +void RWiFiProtSession::Close() + { + CLOG_ENTERFN( "RWiFiProtSession::Close" ); + + RSessionBase::Close(); + + if (iWiFiProtActiveResp) + { + iWiFiProtActiveResp->Cancel(); + delete iWiFiProtActiveResp; + iWiFiProtActiveResp = NULL; + } + if ( iNotifier ) + { + iNotifier->Close(); + delete iNotifier; + iNotifier = NULL; + } + + CLOG_LEAVEFN( "RWiFiProtSession::Close" ); + } + +// -------------------------------------------------------------------------- +// StartWiFiProtL +// -------------------------------------------------------------------------- +// +void RWiFiProtSession::StartWiFiProtL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned, + WiFiProt::TWiFiReturn& aReturnValue, + TRequestStatus& aStatus ) + { + CLOG_ENTERFN( "RWiFiProtSession::StartWiFiProtL" ); + + aConnectionNeeded = EFalse; // this parameter is not supported anymore + // to be set from the API, but it is used + // internally from StartWiFiProtConnL + TRAPD( err, iWiFiProtActiveResp = + CWiFiProtActiveResp::NewL( aSSid, + aConnectionNeeded, + aUidsReturned, + aReturnValue ) ); + + + if ( err != KErrNone ) + { + TRequestStatus* pS = &aStatus; + User::RequestComplete( pS, err ); + } + else + { + iWiFiProtActiveResp->Observe( aStatus ); + + TPckgBuf* outputParams = + iWiFiProtActiveResp->OutputBuffer(); + TPckgBuf* inputParams = + iWiFiProtActiveResp->InputBuffer(); + + if ( iNotifier ) + { + TRequestStatus& status = iWiFiProtActiveResp->iStatus; + iNotifier->StartNotifierAndGetResponse( status, + KUidWiFiProtSetup, + *inputParams, + *outputParams ); + } + } + + CLOG_LEAVEFN( "RWiFiProtSession::StartWiFiProtL" ); + } + +// -------------------------------------------------------------------------- +// StartWiFiProtConnL +// -------------------------------------------------------------------------- +// +void RWiFiProtSession::StartWiFiProtConnL( const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& + aNetworkSettings, + WiFiProt::TWiFiReturn& aReturnValue, + TRequestStatus& aStatus ) + { + CLOG_ENTERFN( "RWiFiProtSession::StartWiFiProtConnL" ); + + TRAPD( err, iWiFiProtActiveResp = + CWiFiProtActiveResp::NewL( aSSid, + aNetworkSettings, + aReturnValue ) ); + + + if ( err != KErrNone ) + { + TRequestStatus* pS = &aStatus; + User::RequestComplete( pS, err ); + } + else + { + iWiFiProtActiveResp->Observe( aStatus ); + + TPckgBuf* connoutputParams = + iWiFiProtActiveResp->ConnOutputBuffer(); + TPckgBuf* inputParams = + iWiFiProtActiveResp->InputBuffer(); + + if ( iNotifier ) + { + TRequestStatus& status = iWiFiProtActiveResp->iStatus; + iNotifier->StartNotifierAndGetResponse( status, + KUidWiFiProtSetup, + *inputParams, + *connoutputParams ); + } + } + + CLOG_LEAVEFN( "RWiFiProtSession::StartWiFiProtConnL" ); + } + +// -------------------------------------------------------------------------- +// CancelWiFiProt +// -------------------------------------------------------------------------- +// +void RWiFiProtSession::CancelWiFiProt() + { + CLOG_ENTERFN( "RWiFiProtSession::CancelWiFiProt()" ); + iNotifier->CancelNotifier( KUidWiFiProtSetup ); + iWiFiProtActiveResp->Cancel(); + delete iWiFiProtActiveResp ; + iWiFiProtActiveResp = NULL; + CLOG_LEAVEFN( "RWiFiProtSession::CancelWiFiProt()" ); + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/src/wifiprotsyncclient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/src/wifiprotsyncclient.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,145 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWiFiProtSyncClient. +* +*/ + + +// INCLUDE FILES +#include "wifiprotsyncclient.h" +#include "wifiprotlogger.h" + +// +// WiFiProtSyncClient definitions +// +// -------------------------------------------------------------------------- +// NewL +// -------------------------------------------------------------------------- +// +CWiFiProtSyncClient* CWiFiProtSyncClient::NewL( RWiFiProtSession& aClient, + TInt aPriority ) + { + CWiFiProtSyncClient* self = new(ELeave) CWiFiProtSyncClient( aClient, + aPriority ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); // self + return self; + } + +// -------------------------------------------------------------------------- +// CWiFiProtSyncClient +// -------------------------------------------------------------------------- +// +CWiFiProtSyncClient::CWiFiProtSyncClient( RWiFiProtSession& aClient, + TInt aPriority ) + : CActive( aPriority ), + iClient( aClient ) + { + } + +// -------------------------------------------------------------------------- +// ConstructL +// -------------------------------------------------------------------------- +// +void CWiFiProtSyncClient::ConstructL() + { + CActiveScheduler::Add( this ); + iState = ENoState; + } + +// -------------------------------------------------------------------------- +// ~CWiFiProtSyncClient +// -------------------------------------------------------------------------- +// +CWiFiProtSyncClient::~CWiFiProtSyncClient() + { + Cancel(); + } + +// -------------------------------------------------------------------------- +// StartWiFiProtL +// -------------------------------------------------------------------------- +// +WiFiProt::TWiFiReturn + CWiFiProtSyncClient::StartWiFiProtL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned ) + { + WiFiProt::TWiFiReturn ret; + iClient.StartWiFiProtL( aSSid, aConnectionNeeded, aUidsReturned, ret, + iStatus ); + SetActive( ERunWiFiProt ); + iWait.Start(); //wait for request to complete + return ret; + } + + + +// -------------------------------------------------------------------------- +// SetActive +// -------------------------------------------------------------------------- +// +void CWiFiProtSyncClient::SetActive( TWiFiState aState ) + { + iState = aState; + CActive::SetActive(); + } + +// -------------------------------------------------------------------------- +// RunL +// -------------------------------------------------------------------------- +// +void CWiFiProtSyncClient::RunL() + { + const TWiFiState state = iState; + iState = ENoState; + + switch (state) + { + case ERunWiFiProt: + { + iWait.AsyncStop(); + break; + } + default: + { + User::Leave(KErrGeneral); + break; + } + } + } + +// -------------------------------------------------------------------------- +// DoCancel +// -------------------------------------------------------------------------- +// +void CWiFiProtSyncClient::DoCancel() + { + switch (iState) + { + case ERunWiFiProt: + { + CLOG_WRITE( "CWiFiProtSyncClient::DoCancel()" ); + iClient.CancelWiFiProt(); + break; + } + default: + { + break; + } + } + iState = ENoState; + } +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/src/wifiprotuiclient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/src/wifiprotuiclient.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWiFiProtUiClient. +* +*/ + + +// INCLUDE FILES + +#include + +#include "wifiprotuiclientimpl.h" +#include "wifiprotlogger.h" + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWiFiProtUiClient::NewL +// --------------------------------------------------------- +// +EXPORT_C CWiFiProtUiClient* CWiFiProtUiClient::NewL() + { + CLOG_ENTERFN( "CWiFiProtUiClient::NewL" ); + CWiFiProtUiClient* wifi = new ( ELeave ) CWiFiProtUiClient(); + CleanupStack::PushL( wifi ); + wifi->iImpl = CWiFiProtUiClientImpl::NewL(); + CleanupStack::Pop( wifi ); + CLOG_LEAVEFN( "CWiFiProtUiClient::NewL" ); + return wifi; + } + + +// --------------------------------------------------------- +// CWiFiProtUiClient::~CWiFiProtUiClient +// --------------------------------------------------------- +// +EXPORT_C CWiFiProtUiClient::~CWiFiProtUiClient() + { + CLOG_ENTERFN( "CWiFiProtUiClient::~CWiFiProtUiClient" ); + delete iImpl; + CLOG_LEAVEFN( "CWiFiProtUiClient::~CWiFiProtUiClient" ); + } + +// --------------------------------------------------------- +// CWiFiProtUiClient::StartWiFiProtL +// --------------------------------------------------------- +// +EXPORT_C void CWiFiProtUiClient::StartWiFiProtL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned, + WiFiProt::TWiFiReturn& aReturnValue, + TRequestStatus& aStatus ) + { + CLOG_ENTERFN( "CWiFiProtUiClient::StartWiFiProtL" ); + iImpl->StartWiFiProtL( aSSid, aConnectionNeeded, aUidsReturned, aReturnValue, aStatus ); + CLOG_LEAVEFN( "CWiFiProtUiClient::StartWiFiProtL" ); + } + +// --------------------------------------------------------- +// CWiFiProtUiClient::StartWiFiProtL +// --------------------------------------------------------- +// +EXPORT_C WiFiProt::TWiFiReturn CWiFiProtUiClient::StartWiFiProtSyncL( + const TWlanSsid& aSSid, TBool aConnectionNeeded,RArray& aUidsReturned ) + { + CLOG_WRITE( "CWiFiProtUiClient::StartWiFiProtSyncL" ); + return iImpl->StartWiFiProtSyncL( aSSid, aConnectionNeeded, aUidsReturned ); + } + +// --------------------------------------------------------- +// CWiFiProtUiClient::CancelWiFiProt +// --------------------------------------------------------- +// +EXPORT_C void CWiFiProtUiClient::CancelWiFiProt() + { + CLOG_ENTERFN( "CWiFiProtUiClient::CancelWiFiProt" ); + iImpl->CancelWiFiProt(); + CLOG_LEAVEFN( "CWiFiProtUiClient::CancelWiFiProt" ); + } + +// --------------------------------------------------------- +// CWiFiProtUiClient::StartWiFiProtConnL +// --------------------------------------------------------- +// +EXPORT_C void CWiFiProtUiClient::StartWiFiProtConnL( const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& + aNetworkSettings, + WiFiProt::TWiFiReturn& aReturnValue, + TRequestStatus& aStatus ) + { + CLOG_ENTERFN( "CWiFiProtUiClient::StartWiFiProtConnL" ); + iImpl->StartWiFiProtConnL( aSSid, aNetworkSettings, aReturnValue, aStatus ); + CLOG_LEAVEFN( "CWiFiProtUiClient::StartWiFiProtConnL" ); + } +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wifiprotectedsetup/src/wifiprotuiclientimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wifiprotectedsetup/src/wifiprotuiclientimpl.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,146 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWiFiProtUiClientImpl. +* +*/ + + +// INCLUDE FILES + +#include +#include +#include +#include +#include +#include + +#ifndef __WINS__ +#include +#include +#endif // ! __WINS__ +#include + +#include "wifiprotuiclientimpl.h" +#include "wifiprotlogger.h" + + +// ================= MEMBER FUNCTIONS ======================= + +// -------------------------------------------------------------------------- +// CWiFiProtUiClientImpl::NewL +// -------------------------------------------------------------------------- +// +CWiFiProtUiClientImpl* CWiFiProtUiClientImpl::NewL() + { + CLOG_ENTERFN( "CWiFiProtUiClientImpl::NewL" ); + CWiFiProtUiClientImpl* clientImpl = + new ( ELeave ) CWiFiProtUiClientImpl(); + CleanupStack::PushL( clientImpl ); + clientImpl->ConstructL(); + CleanupStack::Pop( clientImpl ); + CLOG_LEAVEFN( "CWiFiProtUiClientImpl::NewL" ); + return clientImpl; + } + +// -------------------------------------------------------------------------- +// CWiFiProtUiClientImpl::~CWiFiProtUiClientImpl +// -------------------------------------------------------------------------- +// +CWiFiProtUiClientImpl::~CWiFiProtUiClientImpl() + { + CLOG_ENTERFN( "CWiFiProtUiClientImpl::~CWiFiProtUiClientImpl" ); + delete iWiFiProtSyncClient; + iNotif.Close(); + CLOG_LEAVEFN( "CWiFiProtUiClientImpl::~CWiFiProtUiClientImpl" ); + } + +// -------------------------------------------------------------------------- +// CWiFiProtUiClientImpl::StartWiFiProtL +// -------------------------------------------------------------------------- +// +void CWiFiProtUiClientImpl::StartWiFiProtL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned, + WiFiProt::TWiFiReturn& aReturnValue, + TRequestStatus& aStatus ) + { + CLOG_ENTERFN( "CWiFiProtUiClientImpl::StartWiFiProtL" ); + iNotif.StartWiFiProtL( aSSid, aConnectionNeeded, + aUidsReturned, aReturnValue, aStatus ); + CLOG_LEAVEFN( "CWiFiProtUiClientImpl::StartWiFiProtL" ); + } + + // -------------------------------------------------------------------------- +// CWiFiProtUiClientImpl::StartWiFiProtSyncL +// -------------------------------------------------------------------------- +// +WiFiProt::TWiFiReturn +CWiFiProtUiClientImpl::StartWiFiProtSyncL( const TWlanSsid& aSSid, + TBool aConnectionNeeded, + RArray& aUidsReturned ) + { + CLOG_WRITE( "CWiFiProtUiClientImpl::StartWiFiProtSyncL" ); + if (iWiFiProtSyncClient == NULL) + { + iWiFiProtSyncClient = CWiFiProtSyncClient::NewL( iNotif ); + } + return iWiFiProtSyncClient->StartWiFiProtL( aSSid, + aConnectionNeeded, aUidsReturned ); + } + +// --------------------------------------------------------- +// CWiFiProtUiClientImpl::StartWiFiProtConnL +// --------------------------------------------------------- +// +void CWiFiProtUiClientImpl::StartWiFiProtConnL( const TWlanSsid& aSSid, + TWlanProtectedSetupCredentialAttribute& + aNetworkSettings, + WiFiProt::TWiFiReturn& aReturnValue, + TRequestStatus& aStatus ) + { + CLOG_ENTERFN( "CWiFiProtUiClientImpl::StartWiFiProtConnL" ); + iNotif.StartWiFiProtConnL( aSSid, aNetworkSettings, aReturnValue, aStatus ); + CLOG_LEAVEFN( "CWiFiProtUiClientImpl::StartWiFiProtConnL" ); + } + +// -------------------------------------------------------------------------- +// CWiFiProtUiClientImpl::CancelWiFiProt +// -------------------------------------------------------------------------- +// +void CWiFiProtUiClientImpl::CancelWiFiProt( ) + { + CLOG_ENTERFN( "CWiFiProtUiClientImpl::CancelWiFiProt()" ); + iNotif.CancelWiFiProt( ); + CLOG_LEAVEFN( "CWiFiProtUiClientImpl::CancelWiFiProt()" ); + } + +// -------------------------------------------------------------------------- +// CWiFiProtUiClientImpl::CWiFiProtUiClientImpl +// -------------------------------------------------------------------------- +// +CWiFiProtUiClientImpl::CWiFiProtUiClientImpl() + { + } + +// -------------------------------------------------------------------------- +// CWiFiProtUiClientImpl::ConstructL +// -------------------------------------------------------------------------- +// +void CWiFiProtUiClientImpl::ConstructL() + { + CLOG_ENTERFN( "CWiFiProtUiClientImpl::ConstructL" ); + User::LeaveIfError( iNotif.Connect() ); + CLOG_LEAVEFN( "CWiFiProtUiClientImpl::ConstructL" ); + } +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/data/EapAkaUi.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/data/EapAkaUi.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,251 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP AKA UI resource file +* +*/ + + + +CHARACTER_SET UTF8 + +// RESOURCE IDENTIFIER +NAME EPAK + +// INCLUDES +#include +#include "EapAkaUi.hrh" // Enums for these resources +#include // Localisation file +#include +#include +#include +#include +#include +#include + + +// CONSTANTS +#define KUsernameMaxNameLength 255 +#define KEdwinWidth 9 +#define KEdwinLines 5 + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + + +RESOURCE TBUF16 { buf = ""; } + +RESOURCE CBA r_aka_softkeys_options_back_change + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EAkaUiCmdChange; txt = qtn_msk_change; } + }; + } + +RESOURCE DIALOG r_aka_setting_dialog + { + flags = EAknDialogSelectionList | EEikDialogFlagWait; + buttons = r_aka_softkeys_options_back_change; + items = + { + DLG_LINE + { + id = EAkaSettingsListBox; + type = EAknCtSettingListBox; + control = LISTBOX + { + flags = EAknListBoxMenuList; + }; + } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_aka_username_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_username; + type = EEikCtEdwin; + editor_resource_id = r_aka_setting_edwin; + } + + +RESOURCE AVKON_SETTING_PAGE r_aka_realm_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_realm; + type = EEikCtEdwin; + editor_resource_id = r_aka_setting_edwin; + } + + +RESOURCE EDWIN r_aka_setting_edwin + { + width = KEdwinWidth; + lines = KEdwinLines; + maxlength = KUsernameMaxNameLength; + allowed_input_modes = EAknEditorTextInputMode | EAknEditorNumericInputMode; + default_input_mode = EAknEditorTextInputMode; + default_case = EAknEditorLowerCase; + avkon_flags = EAknEditorFlagLatinInputModesOnly; + flags = EEikEdwinAutoSelection | EEikEdwinNoLineOrParaBreaks; + } + + +RESOURCE MENU_BAR r_aka_menubar + { + titles = + { + MENU_TITLE { menu_pane = r_aka_menu_pane; txt = ""; } + }; + } + + +RESOURCE MENU_PANE r_aka_menu_pane + { + items= + { + MENU_ITEM + { + command = EAkaUiCmdChange; + txt = qtn_options_change; + flags = EEikMenuItemAction; + }, + MENU_ITEM + { + command = EAknCmdHelp; + txt = qtn_options_help; + }, + MENU_ITEM + { + command = EAknCmdExit; + txt = qtn_options_exit; + } + }; + } + + +// Resource strings +RESOURCE TBUF r_aka_settings_title \ + { buf = qtn_wlan_eap_aka_title; } +RESOURCE TBUF r_aka_username_inusestring \ + { buf = qtn_wlan_eap_sett_username_inuse; } +RESOURCE TBUF r_aka_username_inusestring_auto \ + { buf = qtn_wlan_eap_sett_username_inuse_from_sim; } +RESOURCE TBUF r_aka_username_inusestring_conf \ + { buf = qtn_wlan_eap_sett_username_inuse_user; } +RESOURCE TBUF r_aka_username_string \ + { buf = qtn_wlan_eap_sett_username; } +RESOURCE TBUF r_aka_realm_inusestring \ + { buf = qtn_wlan_eap_sett_realm_inuse; } +RESOURCE TBUF r_aka_realm_inusestring_auto \ + { buf = qtn_wlan_eap_sett_realm_inuse_from_sim; } +RESOURCE TBUF r_aka_realm_inusestring_conf \ + { buf = qtn_wlan_eap_sett_realm_inuse_user; } +RESOURCE TBUF r_aka_realm_string \ + { buf = qtn_wlan_eap_sett_realm; } + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_aka_username_autouseconf_texts + { + setting_texts_resource = r_aka_username_autouseconf_texts_resource; + popped_up_texts_resource = r_aka_username_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_aka_username_autouseconf_texts_resource + { + items = + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_username_inuse_from_sim; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_username_inuse_user; + } + }; + } + + +RESOURCE ARRAY r_aka_username_automatic_useconfigured_array + { + items = + { + LBUF { txt = qtn_wlan_eap_sett_username_inuse_from_sim; }, + LBUF { txt = qtn_wlan_eap_sett_username_inuse_user; } + }; + } + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_aka_realm_autouseconf_texts + { + setting_texts_resource = r_aka_realm_autouseconf_texts_resource; + popped_up_texts_resource = r_aka_realm_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_aka_realm_autouseconf_texts_resource + { + items= + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_realm_inuse_from_sim; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_realm_inuse_user; + } + }; + } + + +RESOURCE ARRAY r_aka_realm_automatic_useconfigured_array + { + items= + { + LBUF { txt = qtn_wlan_eap_sett_realm_inuse_from_sim; }, + LBUF { txt = qtn_wlan_eap_sett_realm_inuse_user; } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_aka_display_autouseconf_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_realm_inuse; + type = EAknCtPopupSettingList; + editor_resource_id = r_aka_setting_enumerated_popup; + } + + +RESOURCE POPUP_SETTING_LIST r_aka_setting_enumerated_popup + { + flags=EAknPopupSettingListFlagInitialised; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/inc/EapAkaUi.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/inc/EapAkaUi.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP AKA UI hrh file +* +*/ + + +#ifndef _EAPAKAUI_HRH_ +#define _EAPAKAUI_HRH_ + + +enum TEapAKaUiMenuCommands + { + EAkaUiCmdUndefined = 6000, + EAkaUiCmdChange + }; + +enum TEapAkaUiNotes + { + TEapAkaUiGeneralError = 6100 + }; + +enum TEapAkaUiLines + { + EAkaSettingsListBox = 6200 + }; + +enum TEapAkaUiSettingIds + { + EAkaSettingUsernameinUseSettingId=6300, + EAkaSettingUsernameSettingId, + EAkaSettingPageRealminUseSettingId, + EAkaSettingRealmSettingId + }; + +enum TEapAkaUiSettingPageIds + { + EAkaSettingPageUsernameinUse=6400, + EAkaSettingPageUsername, + EAkaSettingPageRealminUse, + EAkaSettingPageRealm + }; + + +#endif //_EAPAKAUI_HRH_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/inc/EapAkaUiSettingArray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/inc/EapAkaUiSettingArray.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP AKA UI settings array +* +*/ + + + +#ifndef _EAPAKAUISETTINGARRAY_H_ +#define _EAPAKAUISETTINGARRAY_H_ + +// INCLUDES +#include +#include "EapAkaUi.hrh" + + +// CLASS DECLARATION + +/** +*/ +class CEapAkaSettingItemArray : public CBase + { + public: + static CEapAkaSettingItemArray* NewL(); + + virtual ~CEapAkaSettingItemArray(); + + CAknSettingItem* Item(TEapAkaUiSettingPageIds aItem); + + CAknSettingItemArray* Array(); + + void StoreSettingsL(); + + void AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal); + + void AddBinarySettingItemL( TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue); + + protected: + CEapAkaSettingItemArray(); + void ConstructL(); + + private: + CAknSettingItemArray* iArray; + }; + +#endif // _EAPAKAUISETTINGARRAY_H_ + +// End of File \ No newline at end of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/inc/EapAkaUiView.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/inc/EapAkaUiView.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,115 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP AKA UI setting dialog +* +*/ + + + +#ifndef _EAPAKAUIVIEW_H_ +#define _EAPAKAUIVIEW_H_ + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include "EapAkaUi.hrh" + + +// FORWARD DECLARATIONS +class CAknSettingStyleListBox; +class CSettingsListBoxItemDrawer; +class CEapAkaSettingItemArray; +class CEapAkaUiConnection; +class CEapAkaUiDataConnection; +class CEapAkaUiAkaData; + + +// CLASS DECLARATION + +/** +* Settings dialog class definition +*/ +class CEapAkaUiDialog : public CAknDialog, + public MEikListBoxObserver + { + public: + CEapAkaUiDialog( CEapAkaUiConnection* aConnection, + TInt& aButtonId ); + + ~CEapAkaUiDialog(); + + /** + * Create and launch dialog. + * @param aResourceId The resource ID of the dialog to load. + * @return The ID of the button that closed the dialog + */ + TInt ConstructAndRunLD( TInt aResourceId ); + + public: // From MEikListBoxObserver + + /** + * Handles list box events. + * @param aListBox The originating list box. + * @param aEventType A code for the event. + */ + void HandleListBoxEventL( CEikListBox* aListBox, TListBoxEvent aEventType ); + + + protected: + void PreLayoutDynInitL(); + TBool OkToExitL( TInt aButtonId ); + + private: + void InitializeSettingsL(); + void DrawSettingsListL(); + void ChangeTitleL( TBool aIsStarted ); + void ShowSettingPageL( TInt aCalledFromMenu ); + void ProcessCommandL( TInt aCommand ); + void SaveSettings(); + + private: + void GetHelpContext( TCoeHelpContext& aContext ) const; + + /** + * Initialize menu pane. + * @param aResourceId Menu pane resource id. + * @param CEikMenuPane Menu pane. + */ + void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ); + + + private: + CEapAkaUiConnection* iConnection; + CEapAkaUiDataConnection* iDataConnection; + CEapAkaUiAkaData* iUiData; + CEapAkaSettingItemArray* iSettingArray; + CAknSettingStyleListBox* iSettingListBox; + CSettingsListBoxItemDrawer* iSettingListItemDrawer; + CAknNavigationControlContainer* iNaviPane; + CAknNavigationDecorator* iNaviDecorator; + HBufC* iPreviousText; + TInt* iButtonId; + + // Tells the status of UI construction. TRUE if UI construction is completed. + TBool iIsUIConstructionCompleted; + }; + + +#endif // _EAPAKAUIVIEW_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/loc/eapakaui.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/loc/eapakaui.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI strings for WLAN EAP-AKA authentication settings +* +*/ + + + +// LOCALISATION STRINGS + + +//d:UI title for main view +//l:title_pane_t2/opt9 +//w: +//r:3.1 +// +#define qtn_wlan_eap_aka_title "EAP-AKA settings" + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUi.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,135 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP AKA UI class +* +*/ + + + +// INCLUDE FILES +#include "EapAkaUi.h" +#include "EapAkaUiView.h" +#include +#include +#include +#include +#include + + +// CONSTANTS +_LIT( KDriveZ, "z:" ); // ROM folder +_LIT( KResourceFileName, "eapAkaui.rsc" ); + + +// CLASS DECLARATION +class TResourceFileCleanupItem + { + public: + CCoeEnv* iCoeEnv; + TInt iResourceFileOffset; + }; + + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CleanupResourceFile +// ----------------------------------------------------------------------------- +// +static void CleanupResourceFile( TAny* aObject ) + { + TResourceFileCleanupItem* item = + REINTERPRET_CAST( TResourceFileCleanupItem*, aObject ); + item->iCoeEnv->DeleteResourceFile( item->iResourceFileOffset ); + delete item; + } + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapAkaUi::CEapAkaUi +// ----------------------------------------------------------------------------- +// +CEapAkaUi::CEapAkaUi( CEapAkaUiConnection* aConnection ) +: iConnection( aConnection ) + { + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUi::NewL +// ----------------------------------------------------------------------------- +// +CEapAkaUi* CEapAkaUi::NewL( CEapAkaUiConnection* aConnection ) + { + CEapAkaUi* self = new ( ELeave ) CEapAkaUi( aConnection ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUi::ConstructL() +// ----------------------------------------------------------------------------- +// +void CEapAkaUi::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUi::~CEapAkaUi +// ----------------------------------------------------------------------------- +// +CEapAkaUi::~CEapAkaUi() + { + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUi::InvokeUiL +// ----------------------------------------------------------------------------- +// +TInt CEapAkaUi::InvokeUiL() + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + CCoeEnv* coeEnv = CCoeEnv::Static(); + BaflUtils::NearestLanguageFile( coeEnv->FsSession(), fileName ); + + TResourceFileCleanupItem* item = new( ELeave ) TResourceFileCleanupItem; + + item->iCoeEnv = coeEnv; + CleanupStack::PushL( TCleanupItem( CleanupResourceFile, item ) ); + item->iResourceFileOffset = coeEnv->AddResourceFileL( fileName ); + + TInt buttonId; + CEapAkaUiDialog* settingsDlg = new( ELeave ) CEapAkaUiDialog( iConnection, + buttonId ); + settingsDlg->ConstructAndRunLD( R_AKA_SETTING_DIALOG ); + + CleanupStack::PopAndDestroy(); // For resource file + + return buttonId; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUiSettingArray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUiSettingArray.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,183 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP AKA UI settings array +* +*/ + + + +// INCLUDE FILES +#include "EapAkaUiSettingArray.h" +#include "EapAkaUi.hrh" +#include +#include + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapAkaSettingItemArray::CEapAkaSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapAkaSettingItemArray::CEapAkaSettingItemArray() + { + } + + +// ----------------------------------------------------------------------------- +// CEapAkaSettingItemArray::NewL +// ----------------------------------------------------------------------------- +// +CEapAkaSettingItemArray* CEapAkaSettingItemArray::NewL() + { + CEapAkaSettingItemArray* self = new( ELeave ) CEapAkaSettingItemArray(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapAkaSettingItemArray::~CEapAkaSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapAkaSettingItemArray::~CEapAkaSettingItemArray() + { + if( iArray ) + { + // ResetAndDestroy() + iArray->ResetAndDestroy(); + } + delete iArray; + iArray = NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapAkaSettingItemArray::Item +// ----------------------------------------------------------------------------- +// +CAknSettingItem* CEapAkaSettingItemArray::Item( TEapAkaUiSettingPageIds aId ) + { + for( TInt i = 0; i < iArray->Count(); i++ ) + { + if( iArray->At( i )->Identifier() == aId ) + { + return iArray->At( i ); + } + } + + __ASSERT_DEBUG( EFalse, User::Invariant() ); + return NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapAkaSettingItemArray::Array +// ----------------------------------------------------------------------------- +// +CAknSettingItemArray* CEapAkaSettingItemArray::Array() + { + return iArray; + } + + +// ----------------------------------------------------------------------------- +// CEapAkaSettingItemArray::StoreSettingsL +// ----------------------------------------------------------------------------- +// +void CEapAkaSettingItemArray::StoreSettingsL() + { + // Do what SettingItemList::StoreSettings would do. + for( TInt i( 0 ); i < iArray->Count(); ++i ) + { + iArray->At( i )->StoreL(); + } + } + + +// ----------------------------------------------------------------------------- +// CEapAkaSettingItemArray::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapAkaSettingItemArray::ConstructL() + { + iArray = new( ELeave ) CAknSettingItemArray( 2, EFalse, 0 ); + } + + +// ----------------------------------------------------------------------------- +// CEapAkaSettingItemArray::AddTextItemL +// ----------------------------------------------------------------------------- +// +void CEapAkaSettingItemArray::AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal ) + { + // Create new setting item + CAknTextSettingItem* settingItem = new( ELeave ) CAknTextSettingItem( aId, + aBuffer ); + CleanupStack::PushL( settingItem ); + settingItem->SetEmptyItemTextL( KNullDesC ); + settingItem->SetSettingPageFlags( + CAknTextSettingPage::EZeroLengthAllowed ); + + // Construct setting item with parametrized values + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResource ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResource, EAknCtPopupSettingList, + NULL, aAssociatedResource ); + + // Append item to settingitem-array + iArray->InsertL( aOrdinal, settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + + // Items are destroyed in destructor when resetting array + CleanupStack::Pop( settingItem ); + } + + +// ----------------------------------------------------------------------------- +// CEapAkaSettingItemArray::AddBinarySettingItemL +// ----------------------------------------------------------------------------- +// +void CEapAkaSettingItemArray::AddBinarySettingItemL( + TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue ) + { + CAknSettingItem* settingItem = new ( ELeave ) + CAknBinaryPopupSettingItem( 0, aModifiedValue ); + CleanupStack::PushL( settingItem ); + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResourceId ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResourceId, EAknCtPopupSettingList, + NULL, aAssociatedResourceId ); + + iArray->AppendL( settingItem ); + CleanupStack::PopAndDestroy( itemTitle ); + CleanupStack::Pop( settingItem ); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUiView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUiView.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,461 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP AKA UI settings dialog +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include "EapAkaUiView.h" +#include "EapAkaUi.hrh" +#include +#include +#include +#include "EapAkaUiSettingArray.h" +#include +#include +#include + +#include +#include +#include + + +// LOCAL CONSTANTS AND MACROS +// UID of general settings app, in which help texts are included +const TUid KHelpUidPlugin = { 0x100058EC }; + +_LIT( KEmptyString, "" ); + + +// MODULE DATA STRUCTURES +enum + { + EUsernameInUseItem = 0, + EUsernameItem, + ERealmInUseItem, + ERealmItem + }; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapAkaUiDialog::CEapAkaUiDialog +// ----------------------------------------------------------------------------- +// +CEapAkaUiDialog::CEapAkaUiDialog( CEapAkaUiConnection* aConnection, + TInt& aButtonId ) +: CAknDialog(), + iConnection( aConnection ), + iDataConnection( 0 ), + iUiData( 0 ), + iSettingArray( 0 ), + iSettingListBox( 0 ), + iSettingListItemDrawer( 0 ), + iNaviPane( 0 ), + iNaviDecorator( 0 ), + iPreviousText( 0 ), + iButtonId( &aButtonId ), + iIsUIConstructionCompleted( EFalse ) + { + } + + +// --------------------------------------------------------- +// CEapAkaUiDialog::ConstructAndRunLD +// --------------------------------------------------------- +// +TInt CEapAkaUiDialog::ConstructAndRunLD( TInt aResourceId ) + { + CleanupStack::PushL( this ); + + iSettingArray = CEapAkaSettingItemArray::NewL(); + + User::LeaveIfError( iConnection->Connect() ); + iDataConnection = iConnection->GetDataConnection(); + if ( iDataConnection == 0 ) + { + User::Leave( KErrNoMemory ); + } + User::LeaveIfError( iDataConnection->Open() ); + User::LeaveIfError( iDataConnection->GetData( &iUiData ) ); + + FeatureManager::InitializeLibL(); + + ConstructL( R_AKA_MENUBAR ); + + // ExecuteLD will PushL( this ), so we have to Pop it... + CleanupStack::Pop( this ); // this + + return CAknDialog::ExecuteLD( aResourceId ); + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUiDialog::~CEapAkaUiDialog +// ----------------------------------------------------------------------------- +// +CEapAkaUiDialog::~CEapAkaUiDialog() + { + if ( iSettingArray ) + { + iSettingArray->Array()->ResetAndDestroy(); + delete iSettingArray; + } + + delete iNaviDecorator; + iNaviDecorator = NULL; + + iSettingListBox = 0; + iSettingListItemDrawer = 0; + + iDataConnection->Close(); + delete iDataConnection; + iConnection->Close(); + delete iPreviousText; + + FeatureManager::UnInitializeLib(); + } + +// --------------------------------------------------------- +// CEapAkaUiDialog::HandleListBoxEventL +// --------------------------------------------------------- +// +void CEapAkaUiDialog::HandleListBoxEventL( CEikListBox* /*aListBox*/, + TListBoxEvent aEventType ) + { + switch ( aEventType ) + { + case EEventEnterKeyPressed: + case EEventItemSingleClicked: + { + OkToExitL( EAkaUiCmdChange ); + break; + } + + case EEventItemActioned: + case EEventEditingStarted: + case EEventEditingStopped: + case EEventPenDownOnItem: + case EEventItemDraggingActioned: + { + break; + } + + default: + { + break; + }; + }; + } + + + + +// ----------------------------------------------------------------------------- +// CEapAkaUiDialog::PreLayoutDynInitL +// ----------------------------------------------------------------------------- +// +void CEapAkaUiDialog::PreLayoutDynInitL() + { + ChangeTitleL( ETrue ); + + TUid naviPaneUid; + naviPaneUid.iUid = EEikStatusPaneUidNavi; + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( naviPaneUid ); + if ( subPane.IsPresent() && subPane.IsAppOwned() ) + { + iNaviPane = static_cast( + statusPane->ControlL( naviPaneUid ) ); + + // Set empty text to hide tabs. + iNaviDecorator = iNaviPane->CreateNavigationLabelL( KEmptyString ); + iNaviPane->PushL( *iNaviDecorator ); + } + + iSettingListBox = static_cast( + ControlOrNull( EAkaSettingsListBox ) ); + iSettingListItemDrawer=static_cast( + iSettingListBox->ItemDrawer() ); + iSettingListBox->SetMopParent( this ); + iSettingListBox->CreateScrollBarFrameL( ETrue ); + iSettingListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iSettingListBox->SetListBoxObserver( this ); + DrawSettingsListL(); + + iIsUIConstructionCompleted = ETrue; + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUiDialog::ShowSettingPageL +// ----------------------------------------------------------------------------- +// +void CEapAkaUiDialog::ShowSettingPageL( TInt aCalledFromMenu ) + { + TInt index = iSettingListBox->CurrentItemIndex(); + CAknSettingItem* item = iSettingArray->Array()->At( index ); + item->EditItemL( aCalledFromMenu ); + item->StoreL(); + DrawNow(); + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUiDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CEapAkaUiDialog::OkToExitL( TInt aButtonId ) + { + TBool ret( EFalse ); + switch ( aButtonId ) + { + case EEikBidOk: + { + if( iIsUIConstructionCompleted ) + { + if ( iSettingListBox->IsFocused() ) + { + ShowSettingPageL( EFalse ); + } + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapAkaUiDialog::OkToExitL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + case EAknSoftkeyOptions: + { + DisplayMenuL(); + break; + } + + case EAknSoftkeyBack: + case EAknCmdExit: + { + if( iIsUIConstructionCompleted ) + { + iDataConnection->Update(); + ChangeTitleL( EFalse ); + ret = ETrue; + } + break; + } + case EAkaUiCmdChange: + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( EFalse ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapAkaUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + default: + { + break; + } + } + + if ( ret ) + { + *iButtonId = aButtonId; + } + + return ret; + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUiDialog::DrawSettingsListL +// ----------------------------------------------------------------------------- +// +void CEapAkaUiDialog::DrawSettingsListL() + { + iSettingArray->Array()->ResetAndDestroy(); + TInt ordinal = 0; + iSettingArray->AddBinarySettingItemL( R_AKA_DISPLAY_AUTOUSECONF_PAGE, + R_AKA_USERNAME_INUSESTRING, + R_AKA_USERNAME_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetUseManualUsername() ); + + iSettingArray->AddTextItemL( iUiData->GetManualUsername(), + EAkaSettingPageUsername, + R_AKA_USERNAME_STRING, + R_AKA_USERNAME_PAGE, + NULL, + ordinal++ ); + + + iSettingArray->AddBinarySettingItemL( R_AKA_DISPLAY_AUTOUSECONF_PAGE, + R_AKA_REALM_INUSESTRING, + R_AKA_REALM_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetUseManualRealm() ); + + iSettingArray->AddTextItemL( iUiData->GetManualRealm(), + EAkaSettingUsernameSettingId, + R_AKA_REALM_STRING, + R_AKA_REALM_PAGE, + NULL, + ordinal++ ); + + iSettingListBox->Model()->SetItemTextArray( iSettingArray->Array() ); + iSettingListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iSettingArray->Array()->RecalculateVisibleIndicesL(); + iSettingListBox->HandleItemAdditionL(); + iSettingListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUiDialog::ChangeTitleL +// ----------------------------------------------------------------------------- +// +void CEapAkaUiDialog::ChangeTitleL( TBool aIsStarted ) + { + TUid titlePaneUid; + titlePaneUid.iUid=EEikStatusPaneUidTitle; + + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( titlePaneUid ); + + if ( subPane.IsPresent() && subPane.IsAppOwned() ) + { + CAknTitlePane* titlePane = static_cast( + statusPane->ControlL( titlePaneUid ) ); + if ( aIsStarted ) + { + // Store previous application title text + const TDesC* prevText = titlePane->Text(); + + iPreviousText = HBufC::NewL( prevText->Length() ); + iPreviousText->Des().Append( *prevText ); + TDesC* titleText = iEikonEnv->AllocReadResourceLC( + R_AKA_SETTINGS_TITLE ); + titlePane->SetTextL( *titleText ); + CleanupStack::PopAndDestroy( titleText ); + } + else + { + // Set calling application title text back + titlePane->SetTextL( *iPreviousText ); + + // pop navidecorator when exiting + iNaviPane->Pop( iNaviDecorator ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUiDialog::DynInitMenuPaneL +// ----------------------------------------------------------------------------- +// +void CEapAkaUiDialog::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + CAknDialog::DynInitMenuPaneL( aResourceId, aMenuPane ); + + if ( aResourceId == R_AKA_MENU_PANE ) + { + if ( aMenuPane && !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUiDialog::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CEapAkaUiDialog::ProcessCommandL( TInt aCommand ) + { + if ( MenuShowing() ) + { + HideMenu(); + } + + switch( aCommand ) + { + case EAknCmdExit: + { + TryExitL( aCommand ); + break; + } + + case EAknCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + iEikonEnv->EikAppUi()->AppHelpContextL() ); + break; + } + + case EAkaUiCmdChange: + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( ETrue ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapAkaUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + default: + { + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapAkaUiDialog::GetHelpContext +// ----------------------------------------------------------------------------- +// +void CEapAkaUiDialog::GetHelpContext( TCoeHelpContext& aContext ) const + { + aContext.iMajor = KHelpUidPlugin; + aContext.iContext = KSET_HLP_WLAN_EAP_AKA; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/data/EapGtcUi.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/data/EapGtcUi.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP GTC UI resource file +* +*/ + + + +CHARACTER_SET UTF8 + +// RESOURCE IDENTIFIER +NAME EPGT + +// INCLUDES +#include +#include "EapGtcUi.hrh" // Enums for these resources +#include // Localisation file +#include +#include +#include +#include +#include +#include + + +// CONSTANTS +#define KUsernameMaxNameLength 255 + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + + +RESOURCE TBUF16 { buf=""; } + +RESOURCE CBA r_gtc_ui_softkeys_options_back_change + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EGtcUiCmdChange; txt = qtn_msk_change; } + }; + } + + +RESOURCE DIALOG r_gtc_setting_dialog + { + flags = EAknDialogSelectionList|EEikDialogFlagWait; + buttons = r_gtc_ui_softkeys_options_back_change; + items= + { + DLG_LINE + { + id = EGtcSettingsListBox; + type = EAknCtSettingListBox; + control = LISTBOX + { + flags = EAknListBoxMenuList; + }; + } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_gtc_username_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_username; + type = EEikCtEdwin; + editor_resource_id = r_gtc_setting_edwin; + } + + +RESOURCE EDWIN r_gtc_setting_edwin + { + width = 9; + lines = 5; + maxlength = 255; + allowed_input_modes = EAknEditorTextInputMode | EAknEditorNumericInputMode; + default_input_mode = EAknEditorTextInputMode; + flags = EEikEdwinAutoSelection | EEikEdwinNoLineOrParaBreaks; + } + + +RESOURCE MENU_BAR r_gtc_menubar + { + titles = + { + MENU_TITLE { menu_pane = r_gtc_menu_pane; txt=""; } + }; + } + + +RESOURCE MENU_PANE r_gtc_menu_pane + { + items = + { + MENU_ITEM + { + command = EGtcUiCmdChange; + txt = qtn_options_change; + flags = EEikMenuItemAction; + }, + MENU_ITEM + { + command = EAknCmdHelp; + txt = qtn_options_help; + }, + MENU_ITEM + { + command = EAknCmdExit; + txt = qtn_options_exit; + } + }; + } + + +// Resource strings +RESOURCE TBUF r_gtc_settings_title { buf = qtn_wlan_eap_gtc_title; } +RESOURCE TBUF r_gtc_username_string { buf = qtn_wlan_eap_sett_username; } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/inc/EapGtcUi.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/inc/EapGtcUi.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP GTC UI hrh file +* +*/ + + +#ifndef _EAPGTCUI_HRH_ +#define _EAPGTCUI_HRH_ + +enum TEapGtcUiMenuCommands + { + EGtcUiCmdUndefined = 6000, + EGtcUiCmdChange + }; + +enum TEapGtcUiNotes + { + TEapGtcUiGeneralError = 6100 + }; + +enum TEapGtcUiLines + { + EGtcSettingsListBox = 6200 + }; + +enum TEapGtcUiSettingIds + { + EGtcSettingUsernameinUseSettingId=6300, + EGtcSettingUsernameSettingId, + EGtcSettingPageRealminUseSettingId, + EGtcSettingRealmSettingId + }; + +enum TEapGtcUiSettingPageIds + { + EGtcSettingPageUsernameinUse=6400, + EGtcSettingPageUsername, + EGtcSettingPageRealminUse, + EGtcSettingPageRealm + }; + + +#endif //_EAPGTCUI_HRH_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/inc/EapGtcUiSettingArray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/inc/EapGtcUiSettingArray.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP GTC UI settings array +* +*/ + + +#ifndef _EAPGTCUISETTINGARRAY_H_ +#define _EAPGTCUISETTINGARRAY_H_ + +// INCLUDES +#include +#include "EapGtcUi.hrh" + + +// CLASS DECLARATION + +/** +*/ +class CEapGtcSettingItemArray : public CBase + { + public: + static CEapGtcSettingItemArray* NewL(); + + virtual ~CEapGtcSettingItemArray(); + + CAknSettingItem* Item( TEapGtcUiSettingPageIds aItem ); + + CAknSettingItemArray* Array(); + + void StoreSettingsL(); + + void AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal); + + protected: + CEapGtcSettingItemArray(); + + void ConstructL(); + + private: + CAknSettingItemArray* iArray; + }; + +#endif // _EAPGTCUISETTINGARRAY_H_ + +// End of File \ No newline at end of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/inc/EapGtcUiView.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/inc/EapGtcUiView.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP GTC UI setting dialog +* +*/ + + + +#ifndef _EAPGTCUIVIEW_H_ +#define _EAPGTCUIVIEW_H_ + +// INCLUDES +#include +#include +#include +#include +#include "EapGtcUi.hrh" +#include +#include + + +// FORWARD DECLARATIONS +class CAknSettingStyleListBox; +class CSettingsListBoxItemDrawer; +class CEapGtcSettingItemArray; +class CEapGtcUiConnection; +class CEapGtcUiGtcData; +class CEapGtcUiDataConnection; + + +// CLASS DECLARATION + +/** +* Settings dialog class definition +*/ +class CEapGtcUiDialog : public CAknDialog, + public MEikListBoxObserver + { + public: + CEapGtcUiDialog( CEapGtcUiConnection* aConnection, + TInt& aButtonId ); + + ~CEapGtcUiDialog(); + + /** + * Create and launch dialog. + * @param aResourceId The resource ID of the dialog to load. + * @return The ID of the button that closed the dialog + */ + TInt ConstructAndRunLD( TInt aResourceId ); + + + public: // From MEikListBoxObserver + + /** + * Handles list box events. + * @param aListBox The originating list box. + * @param aEventType A code for the event. + */ + void HandleListBoxEventL( CEikListBox* aListBox, TListBoxEvent aEventType ); + + + protected: + void PreLayoutDynInitL(); + TBool OkToExitL( TInt aButtonId ); + + private: + void InitializeSettingsL(); + void DrawSettingsListL(); + void ChangeTitleL( TBool aIsStarted ); + void ShowSettingPageL( TInt aCalledFromMenu ); + void ProcessCommandL( TInt aCommand ); + void SaveSettings(); + + void GetHelpContext( TCoeHelpContext& aContext ) const; + + /** + * Initialize menu pane. + * @param aResourceId Menu pane resource id. + * @param CEikMenuPane Menu pane. + */ + void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ); + + + private: + CEapGtcUiConnection* iConnection; + CEapGtcUiGtcData* iUiData; + CEapGtcUiDataConnection* iDataConnection; + CEapGtcSettingItemArray* iSettingArray; + CAknSettingStyleListBox* iSettingListBox; + CSettingsListBoxItemDrawer* iSettingListItemDrawer; + CAknNavigationControlContainer* iNaviPane; + CAknNavigationDecorator* iNaviDecorator; + HBufC* iPreviousText; + TInt* iButtonId; + + // Tells the status of UI construction. TRUE if UI construction is completed. + TBool iIsUIConstructionCompleted; + }; + +#endif // _EAPGTCUIVIEW_H_ + +// End of File \ No newline at end of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/loc/eapgtcui.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/loc/eapgtcui.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI strings for WLAN EAP-GTC authentication settings +* +*/ + + + +// LOCALISATION STRINGS + + +//d:UI title for main view +//l:title_pane_t2/opt9 +//w: +//r:3.1 +// +#define qtn_wlan_eap_gtc_title "EAP-GTC settings" + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUi.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,137 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP GTC UI class +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include + +#include "EapGtcUi.h" +#include "EapGtcUiView.h" + + +// CONSTANTS +_LIT( KDriveZ, "z:" ); // ROM folder +_LIT( KResourceFileName, "eapgtcui.rsc"); + + +// CLASS DECLARATION +class TResourceFileCleanupItem + { + public: + CCoeEnv* iCoeEnv; + TInt iResourceFileOffset; + }; + + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CleanupResourceFile +// ----------------------------------------------------------------------------- +// +static void CleanupResourceFile( TAny* aObject ) + { + TResourceFileCleanupItem* item = + REINTERPRET_CAST( TResourceFileCleanupItem*,aObject ); + item->iCoeEnv->DeleteResourceFile( item->iResourceFileOffset ); + delete item; + } + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapGtcUi::CEapGtcUi +// ----------------------------------------------------------------------------- +// +CEapGtcUi::CEapGtcUi( CEapGtcUiConnection* aConnection ) +: iConnection( aConnection ) + { + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUi::NewL +// ----------------------------------------------------------------------------- +// +CEapGtcUi* CEapGtcUi::NewL( CEapGtcUiConnection* aConnection ) + { + CEapGtcUi* self = new ( ELeave ) CEapGtcUi( aConnection ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUi::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapGtcUi::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUi::~CEapGtcUi +// ----------------------------------------------------------------------------- +// +CEapGtcUi::~CEapGtcUi() + { + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUi::InvokeUiL +// ----------------------------------------------------------------------------- +// +TInt CEapGtcUi::InvokeUiL() + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + CCoeEnv* coeEnv = CCoeEnv::Static(); + BaflUtils::NearestLanguageFile( coeEnv->FsSession(), fileName ); + + TResourceFileCleanupItem* item = new( ELeave ) TResourceFileCleanupItem; + + item->iCoeEnv = coeEnv; + CleanupStack::PushL( TCleanupItem( CleanupResourceFile, item ) ); + item->iResourceFileOffset = coeEnv->AddResourceFileL( fileName ); + + TInt buttonId; + CEapGtcUiDialog* settingsDlg = new( ELeave ) CEapGtcUiDialog( iConnection, + buttonId ); + settingsDlg->ConstructAndRunLD( R_GTC_SETTING_DIALOG ); + + CleanupStack::PopAndDestroy(); // For resource file + + return buttonId; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUiSettingArray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUiSettingArray.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,157 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP GTC UI settings array +* +*/ + + + +// INCLUDE FILES +#include "EapGtcUiSettingArray.h" +#include "EapGtcUi.hrh" +#include +#include + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapGtcSettingItemArray::CEapGtcSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapGtcSettingItemArray::CEapGtcSettingItemArray() + { + } + + +// ----------------------------------------------------------------------------- +// CEapGtcSettingItemArray::NewL +// ----------------------------------------------------------------------------- +// +CEapGtcSettingItemArray* CEapGtcSettingItemArray::NewL() + { + CEapGtcSettingItemArray* self = new (ELeave) CEapGtcSettingItemArray(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapGtcSettingItemArray::~CEapGtcSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapGtcSettingItemArray::~CEapGtcSettingItemArray() + { + if( iArray ) + { + // ResetAndDestroy() + iArray->ResetAndDestroy(); + } + delete iArray; + iArray = NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapGtcSettingItemArray::Item +// ----------------------------------------------------------------------------- +// +CAknSettingItem* CEapGtcSettingItemArray::Item( TEapGtcUiSettingPageIds aId ) + { + for( TInt i = 0; i < iArray->Count(); i++ ) + { + if( iArray->At( i )->Identifier() == aId ) + { + return iArray->At( i ); + } + } + + __ASSERT_DEBUG( EFalse, User::Invariant() ); + return NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapGtcSettingItemArray::Array +// ----------------------------------------------------------------------------- +// +CAknSettingItemArray* CEapGtcSettingItemArray::Array() + { + return iArray; + } + + +// ----------------------------------------------------------------------------- +// CEapGtcSettingItemArray::StoreSettingsL +// ----------------------------------------------------------------------------- +// +void CEapGtcSettingItemArray::StoreSettingsL() + { + // Do what SettingItemList::StoreSettings would do. + for( TInt i(0); i < iArray->Count(); ++i ) + { + iArray->At(i)->StoreL(); + } + } + + +// ----------------------------------------------------------------------------- +// CEapGtcSettingItemArray::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapGtcSettingItemArray::ConstructL() + { + iArray = new ( ELeave ) CAknSettingItemArray( 2, EFalse, 0 ); + } + + +// ----------------------------------------------------------------------------- +// CEapGtcSettingItemArray::AddTextItemL +// ----------------------------------------------------------------------------- +// +void CEapGtcSettingItemArray::AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal) + { + // Create new setting item + CAknTextSettingItem* settingItem = new ( ELeave ) CAknTextSettingItem( aId, + aBuffer ); + CleanupStack::PushL( settingItem ); + settingItem->SetEmptyItemTextL( KNullDesC ); + settingItem->SetSettingPageFlags( + CAknTextSettingPage::EZeroLengthAllowed ); + + // Construct setting item with parametrized values + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResource ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResource, EAknCtPopupSettingList, + NULL, aAssociatedResource ); + + // Append item to settingitem-array + iArray->InsertL( aOrdinal, settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + + // Items are destroyed in destructor when resetting array + CleanupStack::Pop( settingItem ); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUiView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUiView.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,455 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP GTC UI settings dialog +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include // TEMPORARY, for info message... +#include +#include +#include + +#include "EapGtcUiView.h" +#include "EapGtcUi.hrh" +#include "EapGtcUiSettingArray.h" + +#include +#include +#include + + +// CONSTANTS +// UID of general settings app, in which help texts are included +const TUid KHelpUidPlugin = { 0x100058EC }; + +_LIT( KEmptyString, "" ); + +// MODULE DATA STRUCTURES +enum + { + EUsernameItem = 0 + }; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapGtcUiDialog::CEapGtcUiDialog +// ----------------------------------------------------------------------------- +// +CEapGtcUiDialog::CEapGtcUiDialog( CEapGtcUiConnection* aConnection, + TInt& aButtonId ) +: CAknDialog(), + iConnection( aConnection ), + iDataConnection( 0 ), + iSettingArray( 0 ), + iSettingListBox( 0 ), + iSettingListItemDrawer( 0 ), + iNaviPane( 0 ), + iNaviDecorator( 0 ), + iPreviousText( 0 ), + iButtonId( &aButtonId ), + iIsUIConstructionCompleted( EFalse ) + { + } + + +// --------------------------------------------------------- +// CEapGtcUiDialog::ConstructAndRunLD +// --------------------------------------------------------- +// +TInt CEapGtcUiDialog::ConstructAndRunLD( TInt aResourceId ) + { + CleanupStack::PushL( this ); + iSettingArray = CEapGtcSettingItemArray::NewL(); + + User::LeaveIfError( iConnection->Connect() ); + + iDataConnection = iConnection->GetDataConnection(); + if ( iDataConnection == 0 ) + { + User::Leave( KErrNoMemory ); + } + User::LeaveIfError( iDataConnection->Open() ); + User::LeaveIfError( iDataConnection->GetData( &iUiData ) ); + + FeatureManager::InitializeLibL(); + + ConstructL( R_GTC_MENUBAR ); + + // ExecuteLD will PushL( this ), so we have to Pop it... + CleanupStack::Pop( this ); // this + + return CAknDialog::ExecuteLD( aResourceId ); + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUiDialog::~CEapGtcUiDialog +// ----------------------------------------------------------------------------- +// +CEapGtcUiDialog::~CEapGtcUiDialog() + { + if ( iNaviDecorator ) + { + delete iNaviDecorator; + iNaviDecorator = NULL; + } + + if ( iSettingArray ) + { + iSettingArray->Array()->ResetAndDestroy(); + delete iSettingArray; + } + + if ( iSettingListBox ) + { + iSettingListBox = 0; + } + + if ( iSettingListItemDrawer ) + { + iSettingListItemDrawer = 0; + } + + if ( iDataConnection ) + { + iDataConnection->Close(); + delete iDataConnection; + } + + if ( iConnection ) + { + iConnection->Close(); + } + + delete iPreviousText; + + FeatureManager::UnInitializeLib(); + } + +// --------------------------------------------------------- +// CEapGtcUiDialog::HandleListBoxEventL +// --------------------------------------------------------- +// +void CEapGtcUiDialog::HandleListBoxEventL( CEikListBox* /*aListBox*/, + TListBoxEvent aEventType ) + { + switch ( aEventType ) + { + case EEventEnterKeyPressed: + case EEventItemSingleClicked: + { + OkToExitL( EGtcUiCmdChange ); + break; + } + + case EEventItemActioned: + case EEventEditingStarted: + case EEventEditingStopped: + case EEventPenDownOnItem: + case EEventItemDraggingActioned: + { + break; + } + + default: + { + break; + }; + }; + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUiDialog::PreLayoutDynInitL +// ----------------------------------------------------------------------------- +// +void CEapGtcUiDialog::PreLayoutDynInitL() + { + TUid naviPaneUid; + naviPaneUid.iUid = EEikStatusPaneUidNavi; + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( naviPaneUid ); + + if ( subPane.IsPresent() && subPane.IsAppOwned() ) + { + iNaviPane = static_cast( + statusPane->ControlL( naviPaneUid ) ); + + // Set empty text to hide tabs. + iNaviDecorator = iNaviPane->CreateNavigationLabelL( KEmptyString ); + iNaviPane->PushL( *iNaviDecorator ); + } + + // Change title + ChangeTitleL( ETrue ); + + iSettingListBox = static_cast( + ControlOrNull( EGtcSettingsListBox ) ); + iSettingListItemDrawer = static_cast( + iSettingListBox->ItemDrawer() ); + iSettingListBox->SetMopParent( this ); + iSettingListBox->CreateScrollBarFrameL( ETrue ); + iSettingListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iSettingListBox->SetListBoxObserver( this ); + DrawSettingsListL(); + + iIsUIConstructionCompleted = ETrue; + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUiDialog::ShowSettingPageL +// ----------------------------------------------------------------------------- +// +void CEapGtcUiDialog::ShowSettingPageL( TInt aCalledFromMenu ) + { + TInt index = iSettingListBox->CurrentItemIndex(); + CAknSettingItem* item = iSettingArray->Array()->At( index ); + item->EditItemL( aCalledFromMenu ); + item->StoreL(); + DrawSettingsListL(); + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUiDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CEapGtcUiDialog::OkToExitL( TInt aButtonId ) + { + TBool ret( EFalse ); + switch ( aButtonId ) + { + case EEikBidOk: + { + if( iIsUIConstructionCompleted ) + { + if ( iSettingListBox->IsFocused() ) + { + ShowSettingPageL( EFalse ); + } + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapGtcUiDialog::OkToExitL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + case EAknSoftkeyOptions: + { + DisplayMenuL(); + break; + } + + case EAknSoftkeyBack: + case EAknCmdExit: + { + if( iIsUIConstructionCompleted ) + { + iDataConnection->Update(); + ChangeTitleL( EFalse ); + ret = ETrue; + } + break; + } + + case EGtcUiCmdChange: + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( EFalse ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapGtcUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + default: + { + break; + } + } + + if ( ret ) + { + *iButtonId = aButtonId; + } + + return ret; + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUiDialog::DrawSettingsListL +// ----------------------------------------------------------------------------- +// +void CEapGtcUiDialog::DrawSettingsListL() + { + iSettingArray->Array()->ResetAndDestroy(); + TInt ordinal = 0; + iSettingArray->AddTextItemL( iUiData->GetIdentity(), + EGtcSettingPageUsername, + R_GTC_USERNAME_STRING, + R_GTC_USERNAME_PAGE, + NULL, + ordinal++ ); + + iSettingListBox->Model()->SetItemTextArray( iSettingArray->Array() ); + iSettingListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iSettingArray->Array()->RecalculateVisibleIndicesL(); + iSettingListBox->HandleItemAdditionL(); + iSettingListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUiDialog::ChangeTitleL +// ----------------------------------------------------------------------------- +// +void CEapGtcUiDialog::ChangeTitleL( TBool aIsStarted ) + { + TUid titlePaneUid; + titlePaneUid.iUid = EEikStatusPaneUidTitle; + + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( titlePaneUid ); + + if (subPane.IsPresent()&&subPane.IsAppOwned()) + { + CAknTitlePane* titlePane = static_cast( + statusPane->ControlL( titlePaneUid ) ); + if ( aIsStarted ) + { + // Store previous application title text + const TDesC* prevText = titlePane->Text(); + iPreviousText = HBufC::NewL( prevText->Length() ); + iPreviousText->Des().Append( *prevText ); + TDesC* titleText = iEikonEnv->AllocReadResourceLC( + R_GTC_SETTINGS_TITLE ); + titlePane->SetTextL( *titleText ); + CleanupStack::PopAndDestroy( titleText ); + } + else + { + // Set calling application title text back + titlePane->SetTextL( *iPreviousText ); + iNaviPane->Pop( iNaviDecorator ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUiDialog::DynInitMenuPaneL +// ----------------------------------------------------------------------------- +// +void CEapGtcUiDialog::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + CAknDialog::DynInitMenuPaneL( aResourceId, aMenuPane ); + + if ( aResourceId == R_GTC_MENU_PANE ) + { + if ( aMenuPane && !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUiDialog::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CEapGtcUiDialog::ProcessCommandL( TInt aCommand ) + { + if ( MenuShowing() ) + { + HideMenu(); + } + + switch( aCommand ) + { + case EAknCmdExit: + { + TryExitL( aCommand ); + break; + } + + case EAknCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + iEikonEnv->EikAppUi()->AppHelpContextL() ); + break; + } + + case EGtcUiCmdChange: + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( ETrue ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapGtcUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + default: + { + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapGtcUiDialog::GetHelpContext +// ----------------------------------------------------------------------------- +// +void CEapGtcUiDialog::GetHelpContext( TCoeHelpContext& aContext ) const + { + aContext.iMajor = KHelpUidPlugin; + aContext.iContext = KSET_HLP_WLAN_EAP_GTC; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/data/GtcNotifDlgUi.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/data/GtcNotifDlgUi.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,124 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resorce file of GtcNotif. +* +*/ + + + +// RESOURCE IDENTIFIER +NAME EGTC + + +// INCLUDES +#include +#include + +#include +#include +#include + +#include +#include + +#include + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + + +RESOURCE CBA r_gtcnotif_softkeys_ok_cancel_select + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOk; txt = text_softkey_ok; }, + CBA_BUTTON { id = EAknSoftkeyCancel; txt = text_softkey_cancel; }, + CBA_BUTTON { id = EAknSoftkeyOk; txt = qtn_msk_select; } + }; + } + + +RESOURCE DIALOG r_gtc_password_query + { + flags = EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar | + EEikDialogFlagCbaButtons | EEikDialogFlagNotifyEsc; + buttons = r_gtcnotif_softkeys_ok_cancel_select; + items = + { + DLG_LINE + { + type = EAknCtQuery; + id = EGeneralQuery; + control= AVKON_DATA_QUERY + { + layout = ECodeLayout; + label = ""; + control = SECRETED + { + num_letters = 255; + }; + }; + } + }; + } + + +RESOURCE CBA r_gtcnotif_softkeys_ok___select + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOk; txt = text_softkey_ok; }, + CBA_BUTTON { }, + CBA_BUTTON { id = EAknSoftkeyOk; txt = qtn_msk_select; } + }; + } + + +RESOURCE DIALOG r_message_query + { + flags = EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar | + EEikDialogFlagCbaButtons | EEikDialogFlagNotifyEsc; + buttons = r_gtcnotif_softkeys_ok___select; + items = + { + DLG_LINE + { + type = EAknCtPopupHeadingPane; + id = EAknMessageQueryHeaderId; + control = AVKON_HEADING + { + label = qtn_wlan_eap_gtc_notif_message; + }; + }, + + DLG_LINE + { + type = EAknCtMessageQuery; + id = EAknMessageQueryContentId; + control = AVKON_MESSAGE_QUERY + { + }; + } + }; + } + + +RESOURCE TBUF r_gtc_response { buf = qtn_wlan_eap_gtc_notif_response; } +RESOURCE TBUF r_gtc_message { buf = qtn_wlan_eap_gtc_notif_message; } +RESOURCE TBUF r_gtc_username { buf = qtn_wlan_eap_gtc_notif_username; } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/inc/GTCMessageDisplayDialog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/inc/GTCMessageDisplayDialog.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of Gtc Message Display Dialog +* +*/ + + + +#ifndef __GTCMESSAGEDISPLAYDIALOG_H__ +#define __GTCMESSAGEDISPLAYDIALOG_H__ + +// INCLUDES +#include + + +class CGTCMessageDisplayDialog : public CAknMessageQueryDialog + { + public: + static CGTCMessageDisplayDialog* NewL( const TDesC& aMessage, + CGtcDialogPlugin* aPlugin ); + ~CGTCMessageDisplayDialog(); + + private: + CGTCMessageDisplayDialog( CGtcDialogPlugin* aPlugin ); + + virtual TBool OkToExitL( TInt aButtonId ); + void HandleResourceChange( TInt aType ); + + private: + CGtcDialogPlugin* iPlugin; // Pointer to the notifier plugin + }; + +#endif // __GTCMESSAGEDISPLAYDIALOG_H__ + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/inc/GTCResponseQueryDialog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/inc/GTCResponseQueryDialog.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of Gtc Response Query Dialog +* +*/ + + + +#ifndef __GTCRESPONSEQUERYDIALOG_H__ +#define __GTCRESPONSEQUERYDIALOG_H__ + +// INCLUDES +#include + + +class CGTCResponseQueryDialog : public CAknTextQueryDialog + { + public: + static CGTCResponseQueryDialog* NewL( TDes& aResponse, + CGtcDialogPlugin* aPlugin ); + ~CGTCResponseQueryDialog(); + + private: + CGTCResponseQueryDialog( TDes& aResponse, CGtcDialogPlugin* aPlugin ); + + virtual TBool OkToExitL( TInt aButtonId ); + void HandleResourceChange( TInt aType ); + + private: + CGtcDialogPlugin* iPlugin; // Pointer to the notifier plugin + }; + + +#endif // __GTCMESSAGEDISPLAYDIALOG_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/inc/GtcNotifDlgPlugin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/inc/GtcNotifDlgPlugin.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of GtcNotifDlg Dialog Plugins +* +*/ + + + +#ifndef __GTCNOTIFDLGPLUGIN_H__ +#define __GTCNOTIFDLGPLUGIN_H__ + + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// CONSTANTS + +// UIDs for dialogs + +// ID of GTC username & password dialog +const TUid KUidGtcDialog = { 0x101f8e7f }; + +// Channel used for screen +const TUid KScreenOutputChannel = { 0x00000123 }; + +// Number of dialogs in this plugin +const TInt KPluginGranularity = 1; + +// ROM folder +_LIT( KDriveZ, "z:" ); + +// RSC file name. +_LIT( KResourceFileName, "GtcNotifDlgUi.rsc" ); + + +// GLOBAL FUNCTIONS +// + +/** +* Array of connection dialog plugins. +* @return A CArray of MEikSrvNotifierBase2 based classes. +*/ +IMPORT_C CArrayPtr< MEikSrvNotifierBase2 >* NotifierArray(); + + +// CLASS DECLARATION + +class CGTCResponseQueryDialog; +class CGTCMessageDisplayDialog; + + +struct TEapGtcUsernamePasswordInfo + { + TBool iIsFirstQuery; + TBuf16<128> iIdentity; + TBuf16<256> iPasscode; + TPassword iPincode; + }; + + +/** + * Gtc dialog plugin class + */ +class CGtcDialogPlugin : public CBase, + public MEikSrvNotifierBase2 + { + public: + static CGtcDialogPlugin* NewL(); + + ~CGtcDialogPlugin(); + + TNotifierInfo RegisterL(); + TNotifierInfo Info() const; + + TPtrC8 StartL( const TDesC8& aBuffer ); + void StartL( const TDesC8& aBuffer, TInt aReplySlot, + const RMessagePtr2& aMessage ); + + TPtrC8 UpdateL( const TDesC8& aBuffer ); + void Cancel(); + void CompleteL( TInt aStatus ); + void Release(); + void CompleteMessageDisplayL( TInt aStatus ); + + protected: + CGtcDialogPlugin(); + + void ConstructL(); + + protected: + TNotifierInfo iInfo; // Notifier info + RMessagePtr2 iMessage; // Message + TInt iReplySlot; // Reply slot + TBool iCancelled; // ETrue if dialog cancelled. For Query dialog. + TBool iGtcMessageCancelled; // ETrue if message dialog is cancelled. + + private: + CGTCResponseQueryDialog* iGTCResponseQueryDlg; + CGTCMessageDisplayDialog* iGTCMessageDisplayDlg; + + TEapGtcUsernamePasswordInfo* iDataPtr; + TPckg* iDataPckgPtr; + TInt iResource; // Resource + }; + + +#endif // __GTCNOTIFDLGPLUGIN_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/loc/gtcnotifdlg.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/loc/gtcnotifdlg.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI strings for WLAN EAP-GTC Notifier +* +*/ + + + +// LOCALISATION STRINGS + + +//d:Message in query used to send GTC output. +//l:popup_query_code_window +//w: +//r:3.1 +// +#define qtn_wlan_eap_gtc_notif_response "EAP-GTC response:" + + +//d:Title of the message query. +//l:heading_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_gtc_notif_message "EAP-GTC message:" + + +//d:Username query string +//l:popup_query_code_window +//w: +//r:3.1 +// +#define qtn_wlan_eap_gtc_notif_username "EAP-GTC user name:" + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/src/GTCMessageDisplayDialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/src/GTCMessageDisplayDialog.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 Gtc Message Display Dialog. +* +*/ + + +// INCLUDE FILES +#include "GtcNotifDlgPlugin.h" +#include "GTCMessageDisplayDialog.h" + + +// ----------------------------------------------------------------------------- +// CGTCMessageDisplayDialog::CGTCMessageDisplayDialog +// ----------------------------------------------------------------------------- +// +CGTCMessageDisplayDialog::CGTCMessageDisplayDialog( CGtcDialogPlugin* aPlugin ) +: CAknMessageQueryDialog( ENoTone ), + iPlugin( aPlugin ) + { + } + + +// ----------------------------------------------------------------------------- +// CGTCMessageDisplayDialog::~CGTCMessageDisplayDialog +// ----------------------------------------------------------------------------- +// +CGTCMessageDisplayDialog::~CGTCMessageDisplayDialog() + { + } + + +// ----------------------------------------------------------------------------- +// CGTCMessageDisplayDialog::NewL +// ----------------------------------------------------------------------------- +// +CGTCMessageDisplayDialog* CGTCMessageDisplayDialog::NewL( const TDesC& aMessage, + CGtcDialogPlugin* aPlugin ) + { + CGTCMessageDisplayDialog* self = new( ELeave ) CGTCMessageDisplayDialog( + aPlugin ); + + CleanupStack::PushL( self ); + if ( aMessage.Length() ) + { + self->SetMessageTextL( aMessage ); + } + + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CGTCMessageDisplayDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CGTCMessageDisplayDialog::OkToExitL( TInt aButtonId ) + { + if ( CAknMessageQueryDialog::OkToExitL( aButtonId ) ) + { + if ( aButtonId == EAknSoftkeyOk ) + { + iPlugin->CompleteMessageDisplayL( KErrNone ); + } + else + { + // Some cancel. + iPlugin->CompleteMessageDisplayL( KErrCancel ); + } + + return( ETrue ); + } + + return( EFalse ); + } + + +// ----------------------------------------------------------------------------- +// CGTCMessageDisplayDialog::HandleResourceChange +// ----------------------------------------------------------------------------- +// +void CGTCMessageDisplayDialog::HandleResourceChange( TInt aType ) + { + CAknMessageQueryDialog::HandleResourceChange( aType ); + if ( aType == KAknsMessageSkinChange ) + { + } + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/src/GTCResponseQueryDialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/src/GTCResponseQueryDialog.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,98 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 Gtc Response Query Dialog. +* +*/ + + + +// INCLUDE FILES +#include "GtcNotifDlgPlugin.h" +#include "GTCResponseQueryDialog.h" + + +// ----------------------------------------------------------------------------- +// CGTCResponseQueryDialog::CGTCResponseQueryDialog +// ----------------------------------------------------------------------------- +// +CGTCResponseQueryDialog::CGTCResponseQueryDialog( TDes& aResponse, + CGtcDialogPlugin* aPlugin ) +: CAknTextQueryDialog( aResponse ), + iPlugin( aPlugin ) + { + } + + +// ----------------------------------------------------------------------------- +// CGTCResponseQueryDialog::~CGTCResponseQueryDialog +// ----------------------------------------------------------------------------- +// +CGTCResponseQueryDialog::~CGTCResponseQueryDialog() + { + } + + +// ----------------------------------------------------------------------------- +// CGTCResponseQueryDialog::NewL +// ----------------------------------------------------------------------------- +// +CGTCResponseQueryDialog* CGTCResponseQueryDialog::NewL( TDes& aResponse, + CGtcDialogPlugin* aPlugin ) + { + CGTCResponseQueryDialog* self = new( ELeave ) CGTCResponseQueryDialog( + aResponse, aPlugin ); + return self; +} + + +// ----------------------------------------------------------------------------- +// CGTCResponseQueryDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CGTCResponseQueryDialog::OkToExitL( TInt aButtonId ) + { + if ( CAknTextQueryDialog::OkToExitL( aButtonId ) ) + { + // This will be the case always since there is no "cancel" in this dialog. + if ( aButtonId==EAknSoftkeyOk ) + { + iPlugin->CompleteL( KErrNone ); + } + else + { + // Everything else is for cancel. + iPlugin->CompleteL( KErrCancel ); + } + + return( ETrue ); + } + + return( EFalse ); + } + + +// ----------------------------------------------------------------------------- +// CGTCResponseQueryDialog::HandleResourceChange +// ----------------------------------------------------------------------------- +// +void CGTCResponseQueryDialog::HandleResourceChange( TInt aType ) + { + CAknTextQueryDialog::HandleResourceChange( aType ); + if ( aType == KAknsMessageSkinChange ) + { + } + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/src/GtcNotifDlgPlugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/src/GtcNotifDlgPlugin.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,401 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 GtcNotif dialog plugin. +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include + +#include // For RProperty +#include // For KPSUidUikon and KUikGlobalNotesAllowed. + +#include "GtcNotifDlgPlugin.h" +#include "GTCResponseQueryDialog.h" +#include "GTCMessageDisplayDialog.h" + + +// CONSTANTS +static const TInt KMaxLengthOfGtcResponse = 256; + +// Ratio between ascii and unicode character sizes +static const TUint KAsciiUnicodeRatio = 2; + + + +// ================= OTHER EXPORTED FUNCTIONS ============== + +// ----------------------------------------------------------------------------- +// CreateNotifiersL +// ----------------------------------------------------------------------------- +// +LOCAL_C void CreateNotifiersL( + CArrayPtrFlat< MEikSrvNotifierBase2 >* aNotifiers ) + { + MEikSrvNotifierBase2 *serNotify; + + serNotify = CGtcDialogPlugin::NewL(); + CleanupStack::PushL( serNotify ); + aNotifiers->AppendL( serNotify ); + CleanupStack::Pop( serNotify ); + } + + +// ----------------------------------------------------------------------------- +// NotifierArray +// ----------------------------------------------------------------------------- +// +EXPORT_C CArrayPtr< MEikSrvNotifierBase2 >* NotifierArray() + { + // NotifierArray() can't leave + CArrayPtrFlat< MEikSrvNotifierBase2 >* array = + new CArrayPtrFlat< MEikSrvNotifierBase2 >( KPluginGranularity ); + + if ( array ) + { + TRAPD( err, CreateNotifiersL( array ) ); + + if( err ) + { + TInt count = array->Count(); + + while( count-- ) + { + ( *array )[ count ]->Release(); + } + + delete array; + array = NULL; + } + } + + return( array ); + } + + +////////////////////////////////////////////////////////////// +// Gtc dialog plugin +///////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::CGtcDialogPlugin +// ----------------------------------------------------------------------------- +// +CGtcDialogPlugin::CGtcDialogPlugin() +: iCancelled( EFalse ), + iGtcMessageCancelled( EFalse ) + { + iManager = NULL; + } + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::~CGtcDialogPlugin +// ----------------------------------------------------------------------------- +// +CGtcDialogPlugin::~CGtcDialogPlugin() + { + CCoeEnv::Static()->DeleteResourceFile( iResource ); + + if ( !iGtcMessageCancelled ) + { + delete iGTCMessageDisplayDlg; + } + + if ( !iCancelled ) + { + delete iGTCResponseQueryDlg; + } + } + + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::RegisterL +// ----------------------------------------------------------------------------- +// +CGtcDialogPlugin::TNotifierInfo CGtcDialogPlugin::RegisterL() + { + iInfo.iUid = KUidGtcDialog; + iInfo.iPriority = ENotifierPriorityHigh; + iInfo.iChannel = KUidGtcDialog; + return iInfo; + } + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::NewL +// ----------------------------------------------------------------------------- +// +CGtcDialogPlugin* CGtcDialogPlugin::NewL() + { + CGtcDialogPlugin* self = new ( ELeave ) CGtcDialogPlugin(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::ConstructL +// ----------------------------------------------------------------------------- +// +void CGtcDialogPlugin::ConstructL() + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + BaflUtils::NearestLanguageFile( CCoeEnv::Static()->FsSession(), fileName ); + iResource = CCoeEnv::Static()->AddResourceFileL( fileName ); + } + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::StartL +// ----------------------------------------------------------------------------- +// +TPtrC8 CGtcDialogPlugin::StartL( const TDesC8& /*aBuffer*/ ) + { + return KNullDesC8().Ptr(); + } + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::StartL +// ----------------------------------------------------------------------------- +// +void CGtcDialogPlugin::StartL( const TDesC8& aBuffer, + TInt aReplySlot, + const RMessagePtr2& aMessage ) + { + iCancelled = EFalse; + iReplySlot = aReplySlot; + iMessage = aMessage; + + // This object gets constructed only once where as this gets called many + // times, if user is not answering the query. + // So initialize everything here itself. + iGTCResponseQueryDlg = NULL; + iGTCMessageDisplayDlg = NULL; + iDataPtr = NULL; + iDataPckgPtr = NULL; + iGtcMessageCancelled = EFalse; + + // We are about to display the password prompt. + // Since this part of the code can be executed during the bootup, check if + // the UI has really started up to display notes/dialogs. + TInt notesAllowed = 0; + TInt error = RProperty::Get( KPSUidUikon, KUikGlobalNotesAllowed, + notesAllowed ); + + // The above call can return error. Don't care the error. What we care is + // if notesAllowed has turned to 1 from 0. + if ( notesAllowed ) + { + // Display EAP-GTC message if there's one... + if ( aBuffer.Length() != 0 ) + { + HBufC16* buffer = HBufC16::NewLC( aBuffer.Size() / + KAsciiUnicodeRatio ); + TPtr16 text = buffer->Des(); + text.Copy( reinterpret_cast( const_cast ( + aBuffer.Ptr() ) ), aBuffer.Size() / + KAsciiUnicodeRatio ); + + iGTCMessageDisplayDlg = CGTCMessageDisplayDialog::NewL( text, + this ); + iGTCMessageDisplayDlg->ExecuteLD( R_MESSAGE_QUERY ); + + // Do not set iGTCMessageDisplayDlg to NULL here, because then + // a timeout cancel will cause a crash. Prevent double deletion + // by checking iGtcMessageCancelled in the destructor. + + CleanupStack::PopAndDestroy( buffer ); + } + else + { + // Show the data query directly since there is no message to display. + CompleteMessageDisplayL( KErrNone ); + } + } + + // In case if the notes are not allowed, this message gets completed when + // EAPOL time out occurs and a subsequent call to cancel from + // eap_am_type_securid_symbian_c::DoCancel(). + + } + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::UpdateL +// ----------------------------------------------------------------------------- +// +TPtrC8 CGtcDialogPlugin::UpdateL( const TDesC8& /*aBuffer*/ ) + { + return KNullDesC8().Ptr(); + } + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::Cancel +// ----------------------------------------------------------------------------- +// +void CGtcDialogPlugin::Cancel() + { + if ( !iCancelled ) + { + iCancelled = ETrue; + + if ( !iMessage.IsNull() ) + { + iMessage.Complete( KErrCancel ); + } + + if ( iGTCResponseQueryDlg ) + { + delete iGTCResponseQueryDlg; + iGTCResponseQueryDlg = NULL; + } + + if ( !iGtcMessageCancelled && iGTCMessageDisplayDlg ) + { + iGtcMessageCancelled = ETrue; + delete iGTCMessageDisplayDlg; + iGTCMessageDisplayDlg = NULL; + } + } + + if( iDataPtr ) + { + delete iDataPtr; + iDataPtr = NULL; + } + + if( iDataPckgPtr ) + { + delete iDataPckgPtr; + iDataPckgPtr = NULL; + } + } + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::CompleteL +// ----------------------------------------------------------------------------- +// +void CGtcDialogPlugin::CompleteL( TInt aStatus ) + { + if ( aStatus == KErrNone && !iMessage.IsNull() ) + { + iMessage.WriteL( iReplySlot, *iDataPckgPtr); + } + + iCancelled = ETrue; + + if ( !iMessage.IsNull() ) + { + iMessage.Complete( aStatus ); + } + + if( iDataPtr ) + { + delete iDataPtr; + iDataPtr = NULL; + } + + if( iDataPckgPtr ) + { + delete iDataPckgPtr; + iDataPckgPtr = NULL; + } + } + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::Release +// ----------------------------------------------------------------------------- +// +void CGtcDialogPlugin::Release() + { + delete this; + } + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::Info +// ----------------------------------------------------------------------------- +// +CGtcDialogPlugin::TNotifierInfo CGtcDialogPlugin::Info() const + { + return iInfo; + } + + +// ----------------------------------------------------------------------------- +// CGtcDialogPlugin::CompleteMessageDisplayL +// ----------------------------------------------------------------------------- +// +void CGtcDialogPlugin::CompleteMessageDisplayL( TInt aStatus ) + { + iGtcMessageCancelled = ETrue; + + if ( aStatus == KErrNone ) + { + // Now user has acknowledged the GTC message. + // Show the response query to enter the password. + + iDataPtr = new( ELeave ) TEapGtcUsernamePasswordInfo; + iDataPckgPtr = new( ELeave ) TPckg( + *iDataPtr ); + + TBuf16 response; + + iGTCResponseQueryDlg = CGTCResponseQueryDialog::NewL( + iDataPtr->iPasscode, this ); + + HBufC* text = StringLoader::LoadLC( R_GTC_RESPONSE ); + iGTCResponseQueryDlg->SetPromptL( *text ); + CleanupStack::PopAndDestroy( text ); + + iGTCResponseQueryDlg->ExecuteLD( R_GTC_PASSWORD_QUERY); + + // Do not set iGTCResponseQueryDlg to NULL here, because then + // a timeout cancel will cause a crash. Prevent double deletion + // by checking iCancelled in the destructor. + } + else + { + // User probably cancelled the message, some how. + // Can not continue to show the password query. + if ( !iMessage.IsNull() ) + { + iMessage.Complete( aStatus ); + } + } + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/data/EapMschapv2Ui.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/data/EapMschapv2Ui.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,210 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP MsChapv2 UI resource file +* +*/ + + + +CHARACTER_SET UTF8 + +// RESOURCE IDENTIFIER +NAME EPLM + + +// INCLUDES +#include +#include "EapMschapv2Ui.hrh" // Enums for these resources +#include // Localisation file +#include +#include +#include +#include +#include +#include + + +// CONSTANTS +#define KUsernameMaxNameLength 255 + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + + +RESOURCE TBUF16 { buf = ""; } + +RESOURCE CBA r_mschap_ui_softkeys_options_back_edit + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EMschapv2UiCmdChange; txt = qtn_msk_change; } + }; + } + +RESOURCE DIALOG r_mschapv2_setting_dialog + { + flags = EAknDialogSelectionList | EEikDialogFlagWait; + buttons = r_mschap_ui_softkeys_options_back_edit; + items = + { + DLG_LINE + { + id = EMschapv2SettingsListBox; + type = EAknCtSettingListBox; + control = LISTBOX + { + flags = EAknListBoxMenuList; + }; + } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_mschapv2_username_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_username; + type = EEikCtEdwin; + editor_resource_id = r_mschapv2_setting_edwin; + } + + +RESOURCE AVKON_SETTING_PAGE r_mschapv2_password_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_password; + type = EEikCtSecretEd; + editor_resource_id = r_mschapv2_setting_password; + } + + +RESOURCE SECRETED r_mschapv2_setting_password + { + num_letters = KUsernameMaxNameLength; + } + + +RESOURCE EDWIN r_mschapv2_setting_edwin + { + width = 9; + lines = 5; + maxlength=KUsernameMaxNameLength; + allowed_input_modes = EAknEditorTextInputMode | EAknEditorNumericInputMode; + default_input_mode = EAknEditorTextInputMode; + flags = EEikEdwinAutoSelection | EEikEdwinNoLineOrParaBreaks; + } + + +RESOURCE MENU_BAR r_mschapv2_menubar + { + titles = + { + MENU_TITLE { menu_pane = r_mschapv2_menu_pane; txt = ""; } + }; + } + + +RESOURCE MENU_PANE r_mschapv2_menu_pane + { + items = + { + MENU_ITEM + { + command = EMschapv2UiCmdChange; + txt = qtn_options_change; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = EAknCmdHelp; + txt = qtn_options_help; + }, + + MENU_ITEM + { + command = EAknCmdExit; + txt = qtn_options_exit; + } + }; + } + + +// Resource strings +RESOURCE TBUF r_mschapv2_settings_title { buf = qtn_wlan_eap_mschapv2_title; } +RESOURCE TBUF r_plain_mschapv2_settings_title { buf = qtn_wlan_eap_plain_mschapv2_title; } +RESOURCE TBUF r_mschapv2_username_string { buf = qtn_wlan_eap_sett_username; } +RESOURCE TBUF r_mschapv2_passprompt_string { buf = qtn_wlan_eap_sett_passprompt; } +RESOURCE TBUF r_mschapv2_password_string { buf = qtn_wlan_eap_sett_password; } +RESOURCE TBUF r_mschapv2_passprompt_on { buf = qtn_wlan_eap_sett_passprompt_on; } +RESOURCE TBUF r_mschapv2_passprompt_off { buf = qtn_wlan_eap_sett_passprompt_off; } + + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_mschapv2_yesno_texts + { + setting_texts_resource = r_mschapv2_yes_no_texts_resource; + popped_up_texts_resource = r_mschapv2_yes_no_array; + } + + +RESOURCE ARRAY r_mschapv2_yes_no_texts_resource + { + items= + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_passprompt_off; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_passprompt_on; + } + }; + } + + +RESOURCE ARRAY r_mschapv2_yes_no_array + { + items= + { + LBUF { txt = qtn_wlan_eap_sett_passprompt_off; }, + LBUF { txt = qtn_wlan_eap_sett_passprompt_on; } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_mschapv2_display_yesno_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_passprompt; + type = EAknCtPopupSettingList; + editor_resource_id = r_mschapv2_setting_enumerated_popup; + } + + +RESOURCE POPUP_SETTING_LIST r_mschapv2_setting_enumerated_popup + { + flags = EAknPopupSettingListFlagInitialised; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/inc/EapMschapv2Ui.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/inc/EapMschapv2Ui.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP Mschapv2 UI hrh file +* +*/ + + +#ifndef _EAPMSCHAPV2UI_HRH_ +#define _EAPMSCHAPV2UI_HRH_ + +enum TEAPMschapv2UIMenuCommands + { + EMschapv2UiCmdUndefined = 6000, + EMschapv2UiCmdChange + }; + +enum TEAPMschapv2UINotes + { + EEAPMschapv2UIGeneralError = 6100 + }; + +enum TEapMschapv2IiLines + { + EMschapv2SettingsListBox = 6200 + }; + +enum TEapMschapv2SettingIds + { + EMschapv2SettingUsernameSettingId=6300, + EMschapv2SettingPassPromptSettingId, + EMschapv2SettingPasswordSettingId + }; + +enum TEapMschapv2SettingItemId + { + EMschapv2SettingPageUserName=6400, + EMschapv2SettingPagePasswordPrompt, + EMschapv2SettingPagePassword + }; + + +#endif //_EAPMSCHAPV2UI_HRH_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/inc/EapMschapv2UiSettingArray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/inc/EapMschapv2UiSettingArray.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP MsChapv2 UI settings array +* +*/ + + + +#ifndef _EAPMSCHAPV2UISETTINGARRAY_H_ +#define _EAPMSCHAPV2UISETTINGARRAY_H_ + +// INCLUDES +#include +#include "EapMschapv2Ui.hrh" + + +// CLASS DECLARATION + +/** +*/ +class CEapMsChapV2SettingItemArray : public CBase + { + public: + static CEapMsChapV2SettingItemArray* NewL(); + + virtual ~CEapMsChapV2SettingItemArray(); + + CAknSettingItem* Item( TEapMschapv2SettingItemId aItem ); + + CAknSettingItemArray* Array(); + + void StoreSettingsL(); + + void AddTextItemL( TDes& aBuffer, TInt aId, TInt aTitleResource, + TInt aSettingPageResource, TInt aAssociatedResource, + TInt aOrdinal); + + void AddPasswordItemL( TDes& aPassword, TInt aId, TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, TInt aOrdinal); + + void AddBinarySettingItemL( TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue); + + protected: + CEapMsChapV2SettingItemArray(); + void ConstructL(); + + private: + CAknSettingItemArray* iArray; + }; + +#endif // _EAPMSCHAPV2UISETTINGARRAY_H_ + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/inc/EapMschapv2UiView.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/inc/EapMschapv2UiView.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP MsChapv2 UI setting dialog +* +*/ + + + +#ifndef _EAPMSCHAPV2UIVIEW_H_ +#define _EAPMSCHAPV2UIVIEW_H_ + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include "EapMschapv2Ui.hrh" + + +// FORWARD DECLARATIONS +class CAknSettingStyleListBox; +class CSettingsListBoxItemDrawer; +class CEapMsChapV2SettingItemArray; +class CEapMsChapV2UiConnection; +class CEapMsChapV2UiMsChapV2Data; +class CEapMsChapV2UiDataConnection; + + +// CLASS DECLARATION + +/** +* Settings dialog class definition +*/ +class CEapMsChapV2UiDialog : public CAknDialog, + public MEikListBoxObserver + { + public: + CEapMsChapV2UiDialog( CEapMsChapV2UiConnection* aConnection, + TInt& aButtonId ); + + ~CEapMsChapV2UiDialog(); + + /** + * Create and launch dialog. + * @param aResourceId The resource ID of the dialog to load. + * @return The ID of the button that closed the dialog + */ + TInt ConstructAndRunLD( TInt aResourceId ); + + + public: // From MEikListBoxObserver + + /** + * Handles list box events. + * @param aListBox The originating list box. + * @param aEventType A code for the event. + */ + void HandleListBoxEventL( CEikListBox* aListBox, TListBoxEvent aEventType ); + + + protected: + void PreLayoutDynInitL(); + TBool OkToExitL( TInt aButtonId ); + + private: + void InitializeSettingsL(); + void DrawSettingsListL(); + void ChangeTitleL( TBool aIsStarted ); + void ShowSettingPageL( TInt aCalledFromMenu ); + void ProcessCommandL( TInt aCommand ); + void GetHelpContext( TCoeHelpContext& aContext ) const; + + /** + * Initialize menu pane. + * @param aResourceId Menu pane resource id. + * @param CEikMenuPane Menu pane. + */ + void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ); + + + private: + CEapMsChapV2UiConnection* iConnection; + CEapMsChapV2UiMsChapV2Data* iUiData; + CEapMsChapV2UiDataConnection* iDataConnection; + CEapMsChapV2SettingItemArray* iSettingArray; + CAknSettingStyleListBox* iSettingListBox; + CSettingsListBoxItemDrawer* iSettingListItemDrawer; + TBool iPassPrompt; + CAknNavigationControlContainer* iNaviPane; + CAknNavigationDecorator* iNaviDecorator; + HBufC* iPreviousText; + TInt* iButtonId; + + // Tells the status of UI construction. TRUE if UI construction is completed. + TBool iIsUIConstructionCompleted; + }; + + +#endif //_EAPMSCHAPV2UIVIEW_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/loc/eapmschapv2ui.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/loc/eapmschapv2ui.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI strings for WLAN EAP-MsChapV2 authentication settings +* +*/ + + + +// LOCALISATION STRINGS + + +//d:UI title for main view (EAP-MSCHAPv2) +//l:title_pane_t2/opt9 +//w: +//r:3.1 +// +#define qtn_wlan_eap_mschapv2_title "EAP-MSCHAPv2 settings" + +//d:UI title for main view (MSCHAPv2) +//l:title_pane_t2/opt9 +//w: +//r:3.1 +// +#define qtn_wlan_eap_plain_mschapv2_title "MSCHAPv2 settings" + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2Ui.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2Ui.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,135 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP MsChapv2 UI class +* +*/ + + + +// INCLUDE FILES +#include "EapMschapv2Ui.h" +#include +#include "EapMschapv2UiView.h" +#include +#include +#include +#include +#include + + +// CONSTANTS +_LIT( KDriveZ, "z:" ); // ROM folder +_LIT( KResourceFileName, "eapmschapv2ui.rsc" ); + + +// CLASS DECLARATION +class TResourceFileCleanupItem + { + public: + CCoeEnv* iCoeEnv; + TInt iResourceFileOffset; + }; + + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CleanupResourceFile +// ----------------------------------------------------------------------------- +// +static void CleanupResourceFile( TAny* aObject ) + { + TResourceFileCleanupItem* item = + REINTERPRET_CAST( TResourceFileCleanupItem*, aObject ); + item->iCoeEnv->DeleteResourceFile( item->iResourceFileOffset ); + delete item; + } + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapMsChapV2Ui::CEapMsChapV2Ui +// ----------------------------------------------------------------------------- +// +CEapMsChapV2Ui::CEapMsChapV2Ui( CEapMsChapV2UiConnection* aConnection ) +: iConnection( aConnection ) + { + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2Ui::NewL +// ----------------------------------------------------------------------------- +// +CEapMsChapV2Ui* CEapMsChapV2Ui::NewL( CEapMsChapV2UiConnection* aConnection ) + { + CEapMsChapV2Ui* self = new ( ELeave ) CEapMsChapV2Ui( aConnection ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2Ui::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2Ui::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2Ui::~CEapMsChapV2Ui +// ----------------------------------------------------------------------------- +// +CEapMsChapV2Ui::~CEapMsChapV2Ui() + { + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2Ui::InvokeUiL +// ----------------------------------------------------------------------------- +// +TInt CEapMsChapV2Ui::InvokeUiL() + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + CCoeEnv* coeEnv = CCoeEnv::Static(); + BaflUtils::NearestLanguageFile( coeEnv->FsSession(), fileName ); + + TResourceFileCleanupItem* item = new( ELeave ) TResourceFileCleanupItem; + + item->iCoeEnv = coeEnv; + CleanupStack::PushL( TCleanupItem( CleanupResourceFile, item ) ); + item->iResourceFileOffset = coeEnv->AddResourceFileL( fileName ); + + TInt buttonId; + CEapMsChapV2UiDialog* settingsDlg = new( ELeave ) CEapMsChapV2UiDialog( + iConnection, buttonId ); + settingsDlg->ConstructAndRunLD( R_MSCHAPV2_SETTING_DIALOG ); + + CleanupStack::PopAndDestroy(); // For resource file + + return buttonId; + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2UiSettingArray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2UiSettingArray.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,225 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP MsChapv2 UI settings array +* +*/ + + + +// INCLUDE FILES +#include "EapMschapv2UiSettingArray.h" +#include "EapMschapv2Ui.hrh" +#include +#include + +// CONSTANTS + +// String representing an empty password field on the UI +_LIT( KEmptyPassword, "****" ); + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapMsChapV2SettingItemArray::CEapMsChapV2SettingItemArray +// ----------------------------------------------------------------------------- +// +CEapMsChapV2SettingItemArray::CEapMsChapV2SettingItemArray() + { + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2SettingItemArray::NewL +// ----------------------------------------------------------------------------- +// +CEapMsChapV2SettingItemArray* CEapMsChapV2SettingItemArray::NewL() + { + CEapMsChapV2SettingItemArray* self = + new( ELeave ) CEapMsChapV2SettingItemArray(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2SettingItemArray::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2SettingItemArray::ConstructL() + { + iArray = new( ELeave ) CAknSettingItemArray( 2, EFalse, 0 ); + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2SettingItemArray::~CEapMsChapV2SettingItemArray +// ----------------------------------------------------------------------------- +// +CEapMsChapV2SettingItemArray::~CEapMsChapV2SettingItemArray() + { + if( iArray ) + { + // ResetAndDestroy() + iArray->ResetAndDestroy(); + } + delete iArray; + iArray = NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2SettingItemArray::Item +// ----------------------------------------------------------------------------- +// +CAknSettingItem* CEapMsChapV2SettingItemArray::Item( + TEapMschapv2SettingItemId aId ) + { + for( TInt i = 0; i < iArray->Count(); i++ ) + { + if( iArray->At( i )->Identifier() == aId ) + { + return iArray->At( i ); + } + } + __ASSERT_DEBUG( EFalse, User::Invariant() ); + + return NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2SettingItemArray::Array +// ----------------------------------------------------------------------------- +// +CAknSettingItemArray* CEapMsChapV2SettingItemArray::Array() + { + return iArray; + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2SettingItemArray::StoreSettingsL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2SettingItemArray::StoreSettingsL() + { + // Do what SettingItemList::StoreSettings would do. + for( TInt i( 0 ); i < iArray->Count(); ++i ) + { + iArray->At( i )->StoreL(); + } + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2SettingItemArray::AddTextItemL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2SettingItemArray::AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal) + { + // Create new setting item + CAknSettingItem* settingItem = + new( ELeave ) CAknTextSettingItem( aId, aBuffer ); + CleanupStack::PushL( settingItem ); + settingItem->SetEmptyItemTextL( KNullDesC ); + settingItem->SetSettingPageFlags( + CAknTextSettingPage::EZeroLengthAllowed ); + + // Construct setting item with parametrized values + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResource ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResource, EAknCtPopupSettingList, + NULL, aAssociatedResource ); + + // Append item to settingitem-array + iArray->InsertL( aOrdinal, settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + + // Items are destroyed in destructor when resetting array + CleanupStack::Pop( settingItem ); + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2SettingItemArray::AddPasswordItemL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2SettingItemArray::AddPasswordItemL( TDes& aPassword, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal) + { + // Create new setting item + CAknSettingItem* settingItem = new ( ELeave ) CAknPasswordSettingItem( aId, + CAknPasswordSettingItem::EAlpha, + aPassword ); + CleanupStack::PushL( settingItem ); + settingItem->SetEmptyItemTextL( KEmptyPassword ); + + // Construct setting item with parametrized values + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResource ); + + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResource, EAknCtPopupSettingList, + NULL, aAssociatedResource ); + + // Append item to settingitem-array + iArray->InsertL( aOrdinal, settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + CleanupStack::Pop( settingItem ); + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2SettingItemArray::AddBinarySettingItemL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2SettingItemArray::AddBinarySettingItemL( + TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue ) + { + CAknSettingItem* settingItem = + new( ELeave ) CAknBinaryPopupSettingItem( 0, aModifiedValue ); + CleanupStack::PushL( settingItem ); + + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResourceId ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResourceId, EAknCtPopupSettingList, + NULL, aAssociatedResourceId ); + iArray->AppendL( settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + CleanupStack::Pop( settingItem ); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2UiView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2UiView.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,516 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP Mschapv2 UI settings dialog +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include "EapMschapv2UiView.h" +#include "EapMschapv2Ui.hrh" +#include +#include +#include +#include "EapMschapv2UiSettingArray.h" +#include +#include +#include +#include +#include + +#include +#include +#include + + +// CONSTANTS +// UID of general settings app, in which help texts are included +const TUid KHelpUidPlugin = { 0x100058EC }; + +_LIT( KEmptyString, "" ); + +static const TInt KEapMsChapv2Id = 26; + +// MODULE DATA STRUCTURES +enum + { + EUsernameItem=0, + EPasswordPromptItem, + EPasswordItem + }; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapMsChapV2UiDialog::CEapMsChapV2UiDialog +// ----------------------------------------------------------------------------- +// +CEapMsChapV2UiDialog::CEapMsChapV2UiDialog( + CEapMsChapV2UiConnection* aConnection, + TInt& aButtonId ) +: CAknDialog(), + iConnection( aConnection ), + iUiData( 0 ), + iDataConnection( 0 ), + iSettingArray( 0 ), + iSettingListBox( 0 ), + iSettingListItemDrawer( 0 ), + iPassPrompt( EFalse ), + iNaviPane( 0 ), + iNaviDecorator( 0 ), + iPreviousText( 0 ), + iButtonId( &aButtonId ), + iIsUIConstructionCompleted( EFalse ) + { + } + + +// --------------------------------------------------z------- +// CEapMsChapV2UiDialog::ConstructAndRunLD +// --------------------------------------------------------- +// +TInt CEapMsChapV2UiDialog::ConstructAndRunLD( TInt aResourceId ) + { + CleanupStack::PushL( this ); + + iSettingArray = CEapMsChapV2SettingItemArray::NewL(); + + User::LeaveIfError( iConnection->Connect() ); + + iDataConnection = iConnection->GetDataConnection(); + if ( iDataConnection == 0 ) + { + User::Leave( KErrNoMemory ); + } + + User::LeaveIfError( iDataConnection->Open() ); + User::LeaveIfError( iDataConnection->GetData( &iUiData ) ); + + FeatureManager::InitializeLibL(); + + ConstructL( R_MSCHAPV2_MENUBAR ); + + // ExecuteLD will PushL( this ), so we have to Pop it... + CleanupStack::Pop( this ); // this + + return CAknDialog::ExecuteLD( aResourceId ); + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2UiDialog::~CEapMsChapV2UiDialog +// ----------------------------------------------------------------------------- +// +CEapMsChapV2UiDialog::~CEapMsChapV2UiDialog() + { + if ( iNaviDecorator ) + { + delete iNaviDecorator; + iNaviDecorator = NULL; + } + + if ( iSettingArray ) + { + iSettingArray->Array()->ResetAndDestroy(); + delete iSettingArray; + } + + if ( iSettingListBox ) + { + iSettingListBox = 0; + } + + if ( iSettingListItemDrawer ) + { + iSettingListItemDrawer = 0; + } + + if ( iDataConnection ) + { + iDataConnection->Close(); + delete iDataConnection; + } + + if ( iConnection ) + { + iConnection->Close(); + } + + delete iPreviousText; + + FeatureManager::UnInitializeLib(); + } + + +// --------------------------------------------------------- +// CEapMsChapV2UiDialog::HandleListBoxEventL +// --------------------------------------------------------- +// +void CEapMsChapV2UiDialog::HandleListBoxEventL( CEikListBox* /*aListBox*/, + TListBoxEvent aEventType ) + { + switch ( aEventType ) + { + case EEventEnterKeyPressed: + case EEventItemSingleClicked: + { + OkToExitL( EMschapv2UiCmdChange ); + break; + } + + case EEventItemActioned: + case EEventEditingStarted: + case EEventEditingStopped: + case EEventPenDownOnItem: + case EEventItemDraggingActioned: + { + break; + } + + default: + { + break; + }; + }; + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2UiDialog::PreLayoutDynInitL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2UiDialog::PreLayoutDynInitL() + { + ChangeTitleL( ETrue ); + + TUid naviPaneUid; + naviPaneUid.iUid = EEikStatusPaneUidNavi; + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( naviPaneUid ); + if ( subPane.IsPresent() && subPane.IsAppOwned() ) + { + iNaviPane = static_cast( + statusPane->ControlL(naviPaneUid) ); + // Set empty text to hide tabs. + iNaviDecorator = iNaviPane->CreateNavigationLabelL( KEmptyString ); + iNaviPane->PushL( *iNaviDecorator ); + } + + iSettingListBox = static_cast( + ControlOrNull( EMschapv2SettingsListBox) ); + iSettingListItemDrawer = static_cast( + iSettingListBox->ItemDrawer() ); + + iSettingListBox->SetMopParent( this ); + iSettingListBox->CreateScrollBarFrameL( ETrue ); + iSettingListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iSettingListBox->SetListBoxObserver( this ); + DrawSettingsListL(); + + iIsUIConstructionCompleted = ETrue; + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2UiDialog::ShowSettingPageL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2UiDialog::ShowSettingPageL( TInt aCalledFromMenu ) + { + TInt index = iSettingListBox->CurrentItemIndex(); + + CAknSettingItem* item = iSettingArray->Array()->At( index ); + item->EditItemL( aCalledFromMenu ); + item->StoreL(); + + if ( index == EPasswordPromptItem ) + { + if ( !iPassPrompt ) + *iUiData->GetPasswordPrompt() = EFalse; + else + *iUiData->GetPasswordPrompt() = ETrue; + } + + DrawNow(); + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2UiDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CEapMsChapV2UiDialog::OkToExitL( TInt aButtonId ) + { + TBool ret( EFalse ); + switch ( aButtonId ) + { + case EEikBidOk: + { + if( iIsUIConstructionCompleted ) + { + if ( iSettingListBox->IsFocused() ) + { + ShowSettingPageL( EFalse ); + } + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapMsChapV2UiDialog::OkToExitL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + case EAknSoftkeyOptions: + { + DisplayMenuL(); + break; + } + + case EAknSoftkeyBack: + case EAknCmdExit: + { + if( iIsUIConstructionCompleted ) + { + iDataConnection->Update(); + ChangeTitleL( EFalse ); + ret = ETrue; + } + break; + } + + case EMschapv2UiCmdChange: + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( EFalse ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapMsChapV2UiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + default: + { + break; + } + } + + if ( ret ) + { + *iButtonId = aButtonId; + } + + return ret; + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2UiDialog::DrawSettingsListL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2UiDialog::DrawSettingsListL() + { + iSettingArray->Array()->ResetAndDestroy(); + + TInt ordinal = 0; + iSettingArray->AddTextItemL( iUiData->GetUsername(), + EMschapv2SettingPageUserName, + R_MSCHAPV2_USERNAME_STRING, + R_MSCHAPV2_USERNAME_PAGE, + NULL, + ordinal++ ); + + if ( *iUiData->GetPasswordPrompt() ) + { + iPassPrompt = ETrue; + } + else{ + iPassPrompt = EFalse; + } + + iSettingArray->AddBinarySettingItemL( R_MSCHAPV2_DISPLAY_YESNO_PAGE, + R_MSCHAPV2_PASSPROMPT_STRING, + R_MSCHAPV2_YESNO_TEXTS, + ordinal++, + iPassPrompt ); + + iSettingArray->AddPasswordItemL( iUiData->GetPassword(), + EMschapv2SettingPagePassword, + R_MSCHAPV2_PASSWORD_STRING, + R_MSCHAPV2_PASSWORD_PAGE, + NULL, + ordinal++ ); + + + iSettingListBox->Model()->SetItemTextArray( iSettingArray->Array() ); + iSettingListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iSettingArray->Array()->RecalculateVisibleIndicesL(); + iSettingListBox->HandleItemAdditionL(); + iSettingListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2UiDialog::ChangeTitleL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2UiDialog::ChangeTitleL( TBool aIsStarted ) + { + TUid titlePaneUid; + titlePaneUid.iUid = EEikStatusPaneUidTitle; + + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( titlePaneUid ); + + if ( subPane.IsPresent() && subPane.IsAppOwned()) + { + CAknTitlePane* titlePane = static_cast( + statusPane->ControlL( titlePaneUid ) ); + if ( aIsStarted ) + { + // Store previous application title text + const TDesC* prevText = titlePane->Text(); + + iPreviousText = HBufC::NewL( prevText->Length() ); + iPreviousText->Des().Append( *prevText ); + + // EAGN-6QZD6U + // Loadd different titles for plain MSCHAPv2 and EAP-MSCHAPv2 + TDesC* titleText; + if( iConnection->GetBearerEAPType() == KEapMsChapv2Id ) + { + titleText = iEikonEnv->AllocReadResourceLC( + R_MSCHAPV2_SETTINGS_TITLE ); + } + else + { + titleText = iEikonEnv->AllocReadResourceLC( + R_PLAIN_MSCHAPV2_SETTINGS_TITLE ); + } + titlePane->SetTextL( *titleText ); + CleanupStack::PopAndDestroy( titleText ); + } + else + { + // Set calling application title text back + titlePane->SetTextL( *iPreviousText ); + // pop navidecorator when exiting + iNaviPane->Pop( iNaviDecorator ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2UiDialog::DynInitMenuPaneL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2UiDialog::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + CAknDialog::DynInitMenuPaneL( aResourceId, aMenuPane ); + + if ( aResourceId == R_MSCHAPV2_MENU_PANE ) + { + if ( aMenuPane && !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2UiDialog::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2UiDialog::ProcessCommandL( TInt aCommand ) + { + if ( MenuShowing() ) + { + HideMenu(); + } + + switch( aCommand ) + { + case EAknCmdExit: + { + TryExitL( aCommand ); + break; + } + + case EAknCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + iEikonEnv->EikAppUi()->AppHelpContextL() ); + break; + } + + case EMschapv2UiCmdChange: + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( ETrue ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapMsChapV2UiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + default: + { + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapMsChapV2UiDialog::GetHelpContext +// ----------------------------------------------------------------------------- +// +void CEapMsChapV2UiDialog::GetHelpContext( TCoeHelpContext& aContext ) const + { + aContext.iMajor = KHelpUidPlugin; + if( iConnection->GetBearerEAPType() == KEapMsChapv2Id ) + { + aContext.iContext = KSET_HLP_WLAN_EAP_MSCHAPV2; + } + else + { + aContext.iContext = KSET_HLP_WLAN_EAP_PLAIN_MSCHAP; + } + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/data/MsChapv2NotifDlgUi.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/data/MsChapv2NotifDlgUi.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource file of MsChapv2Notif. +* +*/ + + + +// RESOURCE IDENTIFIER +NAME MSCN + + +// INCLUDES +#include +#include + +#include +#include +#include + +#include + +#include + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + + +RESOURCE DIALOG r_mschapv2notif_username_password_query + { + flags = EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar | + EEikDialogFlagCbaButtons|EEikDialogFlagNotifyEsc; + buttons = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + items = + { + DLG_LINE + { + type = EAknCtMultilineQuery; + id = EMultilineFirstLine; + control = AVERELL_DATA_QUERY + { + layout = EMultiDataFirstEdwin; + label = qtn_wlan_eap_mschapv2_notif_username; + control = EDWIN + { + flags = 0; + width = 5; + lines = 1; + maxlength = 255; + default_case = EAknEditorLowerCase; + allowed_case_modes = EAknEditorAllCaseModes; + allowed_input_modes = EAknEditorAlphaInputMode | + EAknEditorNumericInputMode | + EAknEditorPredictiveInputMode; + default_input_mode = EAknEditorPredictiveInputMode; + }; + }; + }, + + DLG_LINE + { + type = EAknCtMultilineQuery; + id = EMultilineSecondLine; + control = AVERELL_DATA_QUERY + { + layout = EMultiDataSecondSecEd; + label = qtn_wlan_eap_mschapv2_notif_password; + control = SECRETED + { + num_letters=255; + }; + }; + } + }; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/inc/MsChapv2NotifDialog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/inc/MsChapv2NotifDialog.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of dialog class of MsChapv2NotifDialog. +* +*/ + + + +#ifndef __MSCHAPV2DIALOG_H__ +#define __MSCHAPV2DIALOG_H__ + +// INCLUDES +#include +#include +#include +#include +#include +#include "MsChapv2NotifDlgPlugin.h" + + +// CLASS DECLARATION + +/** +*/ +class CMsChapv2Dialog : public CAknMultiLineDataQueryDialog + { + protected: + CMsChapv2Dialog( CMsChapv2DialogPlugin* aPlugin, + TBool aUsernameExists ); + void ConstructL(); + + public: + static CMsChapv2Dialog* NewL( TDes& aUsername, TDes& aPassword, + CMsChapv2DialogPlugin* aPlugin ); + ~CMsChapv2Dialog(); + + private: + virtual TBool OkToExitL( TInt aButtonId ); + void HandleResourceChange( TInt aType ); + + private: + CMsChapv2DialogPlugin* iPlugin; // Pointer to the notifier plugin + TBool iUsernameExists; + }; + +#endif // __MSCHAPV2DIALOG_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/inc/MsChapv2NotifDlgPlugin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/inc/MsChapv2NotifDlgPlugin.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of MsChapv2Notif Dialog Plugins +* +*/ + + + +#ifndef __MSCHAPV2NOTIFDLGPLUGIN_H__ +#define __MSCHAPV2NOTIFDLGPLUGIN_H__ + + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include + + +// CONSTANTS + +// UIDs for dialogs + +// ID of MsChapv2 username & password dialog +const TUid KUidMsChapv2Dialog = { 0x101f8e69 }; + +// Channel used for screen +const TUid KScreenOutputChannel = { 0x00000123 }; + +// Number of dialogs in this plugin +const TInt KPluginGranularity = 1; + +// ROM folder +_LIT( KDriveZ, "z:" ); + +// RSC file name. +_LIT( KResourceFileName, "MsChapv2NotifDlgUi.rsc" ); + + +// GLOBAL FUNCTIONS + +/** +* Array of connection dialog plugins. +* @return A CArray of MEikSrvNotifierBase2 based classes. +*/ +IMPORT_C CArrayPtr< MEikSrvNotifierBase2 >* NotifierArray(); + + +// CLASS DECLARATION + +struct TEapMsChapv2UsernamePasswordInfo + { + TBool iIsIdentityQuery; + TBool iPasswordPromptEnabled; + TBuf16<256> iUsername; + TBuf16<256> iPassword; + TBuf16<256> iOldPassword; + }; + +class CMsChapv2Dialog; + +/** + * MsChapv2 dialog plugin class + */ +class CMsChapv2DialogPlugin : public CBase, + public MEikSrvNotifierBase2 + { + public: + static CMsChapv2DialogPlugin* NewL(); + + ~CMsChapv2DialogPlugin(); + + TNotifierInfo RegisterL(); + TNotifierInfo Info() const; + + TPtrC8 StartL( const TDesC8& aBuffer ); + void StartL( const TDesC8& aBuffer, TInt aReplySlot, + const RMessagePtr2& aMessage ); + + TPtrC8 UpdateL( const TDesC8& aBuffer ); + void Cancel(); + void CompleteL( TInt aStatus ); + void Release(); + + inline TDes& GetUsername(); + inline TDes& GetPassword(); + inline void SetOldPassword( const TDesC& aOldPwd ); + + protected: + CMsChapv2DialogPlugin(); + + void ConstructL(); + + protected: + TNotifierInfo iInfo; // Notifier info + RMessagePtr2 iMessage; // Message + TInt iReplySlot; // Reply slot + TBool iCancelled; // ETrue if dialog cancelled + + private: + CMsChapv2Dialog* iMSCHAPV2Dialog; + TEapMsChapv2UsernamePasswordInfo* iDataPtr; + TPckg* iDataPckgPtr; + TInt iResource; // Resource + }; + +// Include inline functions +#include "MsChapv2NotifDlgPlugin.inl" + + +#endif // __MSCHAPV2NOTIFDLGPLUGIN_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/inc/MsChapv2NotifDlgPlugin.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/inc/MsChapv2NotifDlgPlugin.inl Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Inline functions of MsChapv2Notif Dialog Plugins +* +*/ + + + +#ifndef __MSCHAPV2NOTIFDLGPLUGIN_INL__ +#define __MSCHAPV2NOTIFDLGPLUGIN_INL__ + + +// --------------------------------------------------------- +// CMsChapv2DialogPlugin::GetUsername +// --------------------------------------------------------- +// +inline TDes& CMsChapv2DialogPlugin::GetUsername() + { + return iDataPtr->iUsername; + } + + +// --------------------------------------------------------- +// CMsChapv2DialogPlugin::GetPassword +// --------------------------------------------------------- +// +inline TDes& CMsChapv2DialogPlugin::GetPassword() + { + return iDataPtr->iPassword; + } + + +// --------------------------------------------------------- +// CMsChapv2DialogPlugin::SetOldPassword +// --------------------------------------------------------- +// +inline void CMsChapv2DialogPlugin::SetOldPassword( const TDesC& aOldPwd ) + { + iDataPtr->iOldPassword = aOldPwd; + } + +#endif // __MSCHAPV2NOTIFDLGPLUGIN_INL__ + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/loc/mschapv2notifdlg.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/loc/mschapv2notifdlg.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI strings for WLAN EAP-MsChapV2 Notifier +* +*/ + + + +// LOCALISATION STRINGS + + +//d:Username query string. +//l:popup_query_data_code_window +//w: +//r:3.1 +// +#define qtn_wlan_eap_mschapv2_notif_username "EAP-MSCHAPv2 user name:" + + +//d:Password query string. +//l:popup_query_data_code_window/opt2 +//w: +//r:3.1 +// +#define qtn_wlan_eap_mschapv2_notif_password "Password:" + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/src/MsChapv2NotifDialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/src/MsChapv2NotifDialog.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,126 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 dialog class of MsChapv2NotifDlg +* +*/ + + + +// INCLUDE FILES +#include +#include "MsChapv2NotifDlgPlugin.h" +#include "MsChapv2NotifDialog.h" + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMsChapv2Dialog::CMsChapv2Dialog +// ----------------------------------------------------------------------------- +// +CMsChapv2Dialog::CMsChapv2Dialog( CMsChapv2DialogPlugin* aPlugin, TBool aUsernameExists ) +: CAknMultiLineDataQueryDialog( ENoTone ), + iPlugin( aPlugin ), + iUsernameExists( aUsernameExists ) + { + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2Dialog::NewL +// ----------------------------------------------------------------------------- +// +CMsChapv2Dialog* CMsChapv2Dialog::NewL( TDes& aUsername, TDes& aPassword, + CMsChapv2DialogPlugin* aPlugin ) + { + CMsChapv2Dialog* self = new( ELeave ) CMsChapv2Dialog( aPlugin, aUsername.Length() > 0 ); + CleanupStack::PushL( self ); + if ( aUsername.Length() ) + { + self->SetDataL( aUsername, aPassword ); + } + + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2Dialog::ConstructL +// ----------------------------------------------------------------------------- +// +void CMsChapv2Dialog::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2Dialog::~CMsChapv2Dialog +// ----------------------------------------------------------------------------- +// +CMsChapv2Dialog::~CMsChapv2Dialog() + { + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2Dialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CMsChapv2Dialog::OkToExitL( TInt aButtonId ) + { + if ( CAknMultiLineDataQueryDialog::OkToExitL( aButtonId ) ) + { + if ( aButtonId == EAknSoftkeyOk ) + { + CAknMultilineQueryControl* firstControl = FirstControl(); + firstControl->GetText( iPlugin->GetUsername() ); + + CAknMultilineQueryControl* secondControl = SecondControl(); + secondControl->GetText( iPlugin->GetPassword() ); + + _LIT( KEmpty, "" ); // Empty string + + // Empty when we are not changing password + iPlugin->SetOldPassword( KEmpty ); + + iPlugin->CompleteL( KErrNone ); + return( ETrue ); + } + else + { + iPlugin->CompleteL( KErrCancel ); + return( ETrue ); + } + } + + return( EFalse ); + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2Dialog::HandleResourceChange +// ----------------------------------------------------------------------------- +// +void CMsChapv2Dialog::HandleResourceChange( TInt aType ) + { + CAknMultiLineDataQueryDialog::HandleResourceChange( aType ); + + if ( aType == KAknsMessageSkinChange ) + { + } + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/src/MsChapv2NotifDlgPlugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/src/MsChapv2NotifDlgPlugin.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,311 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 MsChapv2NotifDlg dialog plugin. +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include + +#include // For RProperty +#include // For KPSUidUikon and KUikGlobalNotesAllowed. + +#include "MsChapv2NotifDlgPlugin.h" +#include "MsChapv2NotifDialog.h" + + + +// ================= OTHER EXPORTED FUNCTIONS ============== + +// ----------------------------------------------------------------------------- +// CreateNotifiersL +// ----------------------------------------------------------------------------- +// +LOCAL_C void CreateNotifiersL( + CArrayPtrFlat< MEikSrvNotifierBase2 >* aNotifiers ) + { + MEikSrvNotifierBase2 *serNotify; + serNotify = CMsChapv2DialogPlugin::NewL(); + CleanupStack::PushL( serNotify ); + aNotifiers->AppendL( serNotify ); + CleanupStack::Pop( serNotify ); + } + + +// ----------------------------------------------------------------------------- +// NotifierArray +// ----------------------------------------------------------------------------- +// +EXPORT_C CArrayPtr< MEikSrvNotifierBase2 >* NotifierArray() + { + // NotifierArray() can't leave + CArrayPtrFlat< MEikSrvNotifierBase2 >* array = + new CArrayPtrFlat< MEikSrvNotifierBase2 >( KPluginGranularity ); + + if ( array ) + { + TRAPD( err, CreateNotifiersL( array ) ); + + if( err ) + { + TInt count = array->Count(); + + while( count-- ) + { + ( *array )[ count ]->Release(); + } + + delete array; + array = NULL; + } + } + + return( array ); + } + + +////////////////////////////////////////////////////////////// +// MsChapv2 dialog plugin +///////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::CMsChapv2DialogPlugin +// ----------------------------------------------------------------------------- +// +CMsChapv2DialogPlugin::CMsChapv2DialogPlugin() +: iCancelled( EFalse ) + { + iManager = NULL; + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::~CMsChapv2DialogPlugin +// ----------------------------------------------------------------------------- +// +CMsChapv2DialogPlugin::~CMsChapv2DialogPlugin() + { + CCoeEnv::Static()->DeleteResourceFile( iResource ); + + if ( !iCancelled ) + { + delete iMSCHAPV2Dialog; + } + } + + + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::RegisterL +// ----------------------------------------------------------------------------- +// +CMsChapv2DialogPlugin::TNotifierInfo CMsChapv2DialogPlugin::RegisterL() + { + iInfo.iUid = KUidMsChapv2Dialog; + iInfo.iPriority = ENotifierPriorityHigh; + iInfo.iChannel = KUidMsChapv2Dialog; + return iInfo; + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::NewL +// ----------------------------------------------------------------------------- +// +CMsChapv2DialogPlugin* CMsChapv2DialogPlugin::NewL() + { + CMsChapv2DialogPlugin* self = new( ELeave ) CMsChapv2DialogPlugin(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::ConstructL +// ----------------------------------------------------------------------------- +// +void CMsChapv2DialogPlugin::ConstructL() + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + BaflUtils::NearestLanguageFile( CCoeEnv::Static()->FsSession(), fileName ); + iResource = CCoeEnv::Static()->AddResourceFileL( fileName ); + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::StartL +// ----------------------------------------------------------------------------- +// +TPtrC8 CMsChapv2DialogPlugin::StartL( const TDesC8& /*aBuffer*/ ) + { + return KNullDesC8().Ptr(); + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::StartL +// ----------------------------------------------------------------------------- +// +void CMsChapv2DialogPlugin::StartL( const TDesC8& aBuffer, + TInt aReplySlot, + const RMessagePtr2& aMessage ) + { + iCancelled = EFalse; + iReplySlot = aReplySlot; + iMessage = aMessage; + + // This object gets constructed only once where as this gets called many + // times, if user is not answering the query. + // So initialize everything here itself. + iMSCHAPV2Dialog = NULL; + iDataPtr = NULL; + iDataPckgPtr = NULL; + + // We are about to display the password prompt. + // Since this part of the code can be executed during the bootup, check if + // the UI has really started up to display notes/dialogs. + TInt notesAllowed = 0; + TInt error = RProperty::Get( KPSUidUikon, KUikGlobalNotesAllowed, + notesAllowed ); + + // The above call can return error. Don't care the error. What we care is + // if notesAllowed has turned to 1 from 0. + if ( notesAllowed ) + { + iDataPtr = new( ELeave ) TEapMsChapv2UsernamePasswordInfo; + iDataPtr->iIsIdentityQuery = ETrue; + iDataPtr->iPasswordPromptEnabled = ETrue; + iDataPckgPtr = new( ELeave ) TPckg( + *iDataPtr ); + iDataPckgPtr->Copy(aBuffer); + + iMSCHAPV2Dialog = CMsChapv2Dialog::NewL( iDataPtr->iUsername, + iDataPtr->iPassword, this ); + iMSCHAPV2Dialog->ExecuteLD( R_MSCHAPV2NOTIF_USERNAME_PASSWORD_QUERY ); + } + + // In case if the notes are not allowed, this message gets completed when + // EAPOL time out occurs and a subsequent call to cancel from + // eap_am_type_mschapv2_symbian_c::DoCancel(). + } + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::UpdateL +// ----------------------------------------------------------------------------- +// +TPtrC8 CMsChapv2DialogPlugin::UpdateL( const TDesC8& /*aBuffer*/ ) + { + return KNullDesC8().Ptr(); + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::Cancel +// ----------------------------------------------------------------------------- +// +void CMsChapv2DialogPlugin::Cancel() + { + if ( !iCancelled ) + { + iCancelled = ETrue; + if ( !iMessage.IsNull() ) + { + iMessage.Complete( KErrCancel ); + } + + if ( iMSCHAPV2Dialog ) + { + delete iMSCHAPV2Dialog; + iMSCHAPV2Dialog = NULL; + } + } + + if ( iDataPtr ) + { + delete iDataPtr; + iDataPtr = NULL; + } + + if ( iDataPckgPtr ) + { + delete iDataPckgPtr; + iDataPckgPtr = NULL; + } + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::CompleteL +// ----------------------------------------------------------------------------- +// +void CMsChapv2DialogPlugin::CompleteL( TInt aStatus ) + { + if ( aStatus == KErrNone && !iMessage.IsNull() ) + { + iMessage.WriteL( iReplySlot, *iDataPckgPtr ); + } + iCancelled = ETrue; + if ( !iMessage.IsNull() ) + { + iMessage.Complete( aStatus ); + } + + if ( iDataPtr ) + { + delete iDataPtr; + iDataPtr = NULL; + } + + if ( iDataPckgPtr ) + { + delete iDataPckgPtr; + iDataPckgPtr = NULL; + } + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::Release +// ----------------------------------------------------------------------------- +// +void CMsChapv2DialogPlugin::Release() + { + delete this; + } + + +// ----------------------------------------------------------------------------- +// CMsChapv2DialogPlugin::Info +// ----------------------------------------------------------------------------- +// +CMsChapv2DialogPlugin::TNotifierInfo CMsChapv2DialogPlugin::Info() const + { + return iInfo; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/data/EapPeapUi.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/data/EapPeapUi.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,555 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP PEAP UI resource file +* +*/ + + + +CHARACTER_SET UTF8 + +// RESOURCE IDENTIFIER +NAME EPEP + +// INCLUDES +#include +#include "EapPeapUi.hrh" // Enums for these resources +#include // Localisation file +#include +#include +#include +#include +#include +#include + + +// CONSTANTS +#define KUsernameMaxNameLength 255 + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + + +RESOURCE TBUF16 { buf=""; } + + +RESOURCE CBA r_peap_ui_softkeys_options_back_edit + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EPeapUiCmdChange; txt = qtn_msk_change; } + }; + } + + +RESOURCE CBA r_peap_ui_softkeys_options_back_configure + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EPeapUiCmdConfigure; txt = qtn_msk_wlan_eap_configure; } + }; + } + + +RESOURCE CBA r_peap_ui_softkeys_options_back_enable + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EPeapUiCmdEnable; txt = qtn_msk_wlan_eap_cs_enable; } + }; + } + + +RESOURCE CBA r_peap_ui_softkeys_options_back_disable + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EPeapUiCmdDisable; txt = qtn_msk_wlan_eap_cs_disable; } + }; + } + + +RESOURCE DIALOG r_peap_setting_dialog + { + flags = EEikDialogFlagFillAppClientRect | + EEikDialogFlagCbaButtons | + EEikDialogFlagWait | + EEikDialogFlagNotifyEsc; + buttons = r_peap_ui_softkeys_options_back_edit; + pages = r_peap_pages; + } + + +RESOURCE ARRAY r_peap_pages + { + items= + { + PAGE + { + id = KEAPPEAPSETTINGSPAGE; + text = qtn_wlan_eap_tab_settings; + lines = r_peap_tab_settings; + }, + + PAGE + { + id = KEAPPEAPEAPPAGE; + text = qtn_wlan_eap_tab_eap_types; + lines = r_peap_tab_eap_types; + }, + + PAGE + { + id = KEAPPEAPCIPHERPAGE; + text = qtn_wlan_eap_tab_cipher_suites; + lines = r_peap_tab_cipher_suites; + } + }; + } + + +// ******* PAGES ************ +// ******* 1st page ********* +RESOURCE ARRAY r_peap_tab_settings + { + items = + { + DLG_LINE + { + id = EPeapSettingsListbox; + type = EAknCtSettingListBox; + control = LISTBOX + { + flags = EAknListBoxMenuList; + }; + } + }; + } + + +// ******* 2nd page ********* +RESOURCE ARRAY r_peap_tab_eap_types + { + items = + { + DLG_LINE + { + id = EPeapSettingsEapTypeListbox; + type = EAknCtSingleNumberListBox; + control = LISTBOX + { + flags = EAknGenericListBoxFlags; + array_id = r_peap_eap_types_array; + }; + } + }; + } + + +// ******* 3rd page ********* +RESOURCE ARRAY r_peap_tab_cipher_suites + { + items = + { + DLG_LINE + { + id = EPeapSettingsCipherSuiteListbox; + type = EAknCtSingleNumberListBox; + control = LISTBOX + { + flags = EAknGenericListBoxFlags; + }; + } + }; + } + + +RESOURCE ARRAY r_peap_eap_types_array + { + items = + { + LBUF { txt = "1\tEAP-TLS"; }, + LBUF { txt = "2\tEAP-MSCHAPv2"; }, + LBUF { txt = "3\tEAP-SIM"; }, + LBUF { txt = "4\tEAP-GTC"; } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_peap_username_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label= qtn_wlan_eap_sett_username; + type = EEikCtEdwin; + editor_resource_id = r_peap_setting_edwin; + } + + +RESOURCE AVKON_SETTING_PAGE r_peap_realm_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_realm; + type = EEikCtEdwin; + editor_resource_id = r_peap_setting_edwin; + } + + +RESOURCE EDWIN r_peap_setting_edwin + { + flags = 0; + width = 9; + lines = 5; + maxlength = 255; + } + + +RESOURCE AVKON_SETTING_PAGE r_radio_button_setting_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + type = EAknSetListBox; + editor_resource_id= r_setting_listbox; + } + + +RESOURCE LISTBOX r_setting_listbox + { + flags = EEikListBoxMultipleSelection; + } + + + +RESOURCE MENU_BAR r_peap_menubar + { + titles = + { + MENU_TITLE + { + menu_pane = r_peap_menu_pane; + txt = ""; + } + }; + } + + +RESOURCE MENU_PANE r_peap_menu_pane + { + items = + { + MENU_ITEM + { + command = EPeapUiCmdConfigure; + txt = qtn_wlan_options_eap_plugin_configure; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = EPeapUiCmdEnable; + txt = qtn_wlan_options_eap_plugin_enable; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = EPeapUiCmdDisable; + txt = qtn_wlan_options_eap_plugin_disable; + flags = EEikMenuItemSpecific; + }, + + MENU_ITEM + { + command = EPeapUiCmdMoveUp; + txt = qtn_wlan_options_eap_plugin_priority_up; + flags = EEikMenuItemSpecific; + }, + + MENU_ITEM + { + command = EPeapUiCmdMoveDown; + txt = qtn_wlan_options_eap_plugin_priority_down; + flags = EEikMenuItemSpecific; + }, + + MENU_ITEM + { + command = EPeapUiCmdChange; + txt = qtn_options_change; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = EAknCmdHelp; + txt = qtn_options_help; + }, + + MENU_ITEM + { + command = EAknCmdExit; + txt = qtn_options_exit; + } + }; + } + + +// Resource strings +RESOURCE TBUF r_peap_settings_title { buf = qtn_wlan_eap_peap_title; } +RESOURCE TBUF r_peap_username_inusestring \ + { buf = qtn_wlan_eap_sett_username_inuse; } +RESOURCE TBUF r_peap_username_inusestring_auto \ + { buf = qtn_wlan_eap_sett_username_inuse_from_cert; } +RESOURCE TBUF r_peap_username_inusestring_conf \ + { buf = qtn_wlan_eap_sett_username_inuse_user; } +RESOURCE TBUF r_peap_username_string { buf = qtn_wlan_eap_sett_username; } +RESOURCE TBUF r_peap_realm_inusestring \ + { buf = qtn_wlan_eap_sett_realm_inuse; } +RESOURCE TBUF r_peap_realm_inusestring_auto \ + { buf = qtn_wlan_eap_sett_realm_inuse_from_cert; } +RESOURCE TBUF r_peap_realm_inusestring_conf \ + { buf = qtn_wlan_eap_sett_realm_inuse_user; } +RESOURCE TBUF r_peap_realm_string { buf = qtn_wlan_eap_sett_realm; } +RESOURCE TBUF r_peap_user_cert_string \ + { buf = qtn_wlan_eap_sett_user_certificate; } +RESOURCE TBUF r_peap_ca_cert_string \ + { buf = qtn_wlan_eap_sett_ca_certificate; } +RESOURCE TBUF r_peap_not_defined { buf = qtn_wlan_eap_cert_not_defined; } +RESOURCE TBUF r_peap_none_selection \ + { buf = qtn_wlan_eap_cert_none_selection; } + +RESOURCE TBUF r_peap_suite_rsarc4md5 { buf = qtn_wlan_eap_cipher_rsarc4md5; } +RESOURCE TBUF r_peap_suite_rsarc4sha { buf = qtn_wlan_eap_cipher_rsarc4sha; } +RESOURCE TBUF r_peap_suite_rsa3dessha \ + { buf = qtn_wlan_eap_cipher_rsa3dessha; } +RESOURCE TBUF r_peap_suite_dhersa3dessha \ + { buf = qtn_wlan_eap_cipher_dhersa3dessha; } +RESOURCE TBUF r_peap_suite_dhedss3dessha \ + { buf = qtn_wlan_eap_cipher_dhedss3dessha; } +RESOURCE TBUF r_peap_suite_rsaaessha { buf = qtn_wlan_eap_cipher_rsaaessha; } +RESOURCE TBUF r_peap_suite_dhersaaessha \ + { buf = qtn_wlan_eap_cipher_dhersaaessha; } +RESOURCE TBUF r_peap_suite_dhedssaessha \ + { buf = qtn_wlan_eap_cipher_dhedssaessha; } + +RESOURCE TBUF r_peap_allow_peapv0 { buf = qtn_wlan_eap_sett_allow_peapv0; } +RESOURCE TBUF r_peap_allow_peapv1 { buf = qtn_wlan_eap_sett_allow_peapv1; } +RESOURCE TBUF r_peap_allow_peapv2 { buf = qtn_wlan_eap_sett_allow_peapv2; } +RESOURCE TBUF r_peap_allow_yes { buf = qtn_wlan_eap_sett_allow_peap_yes; } +RESOURCE TBUF r_peap_allow_no { buf = qtn_wlan_eap_sett_allow_peap_no; } +RESOURCE TBUF r_peap_info_cannot_disable_all_eap_plugins \ + { buf = qtn_wlan_info_cannot_disable_all_eap_plugins; } +RESOURCE TBUF r_peap_tls_privacy_string + { buf = qtn_wlan_eap_sett_tls_privacy; } + + +// ******************************************** +// USERNAME IN USE AND REALM POPUP DEFINITION +// ******************************************** +RESOURCE AVKON_POPUP_SETTING_TEXTS r_peap_username_autouseconf_texts + { + setting_texts_resource = r_peap_username_autouseconf_texts_resource; + popped_up_texts_resource = r_peap_username_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_peap_username_autouseconf_texts_resource + { + items = + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_username_inuse_from_cert; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_username_inuse_user; + } + }; + } + + +RESOURCE ARRAY r_peap_username_automatic_useconfigured_array + { + items = + { + LBUF { txt = qtn_wlan_eap_sett_username_inuse_from_cert; }, + LBUF { txt = qtn_wlan_eap_sett_username_inuse_user; } + }; + } + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_peap_realm_autouseconf_texts + { + setting_texts_resource = r_peap_realm_autouseconf_texts_resource; + popped_up_texts_resource = r_peap_realm_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_peap_realm_autouseconf_texts_resource + { + items= + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_realm_inuse_from_cert; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_realm_inuse_user; + } + }; + } + + +RESOURCE ARRAY r_peap_realm_automatic_useconfigured_array + { + items= + { + LBUF { txt = qtn_wlan_eap_sett_realm_inuse_from_cert; }, + LBUF { txt = qtn_wlan_eap_sett_realm_inuse_user; } + }; + } + +RESOURCE ARRAY r_peap_tls_privacy_autouseconf_texts_resource + { + items= + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_tls_privacy_off; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_tls_privacy_on; + } + }; + } + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_peap_tls_privacy_autouseconf_texts + { + setting_texts_resource = r_peap_tls_privacy_autouseconf_texts_resource; + popped_up_texts_resource = r_peap_tls_privacy_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_peap_tls_privacy_automatic_useconfigured_array + { + items = + { + LBUF { txt = qtn_wlan_eap_sett_tls_privacy_off; }, + LBUF { txt = qtn_wlan_eap_sett_tls_privacy_on; } + }; + } + +RESOURCE AVKON_SETTING_PAGE r_peap_display_autouseconf_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_realm_inuse; + type = EAknCtPopupSettingList; + editor_resource_id = r_peap_setting_enumerated_popup; + } + + +RESOURCE POPUP_SETTING_LIST r_peap_setting_enumerated_popup + { + flags = EAknPopupSettingListFlagInitialised; + } + + +// ******************************************** +// ALLOW PEAP VERSIONS POPUP DEFINITION +// ******************************************** +RESOURCE AVKON_POPUP_SETTING_TEXTS r_peap_allow_version_texts + { + setting_texts_resource = r_peap_allow_version_texts_resource; + popped_up_texts_resource = r_peap_allow_version_array; + } + + +RESOURCE ARRAY r_peap_allow_version_texts_resource + { + items = + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_allow_peap_no; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_allow_peap_yes; + } + }; + } + + +RESOURCE ARRAY r_peap_allow_version_array + { + items= + { + LBUF { txt = qtn_wlan_eap_sett_allow_peap_no; }, + LBUF { txt = qtn_wlan_eap_sett_allow_peap_yes; } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_peap_allow_version_0 + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_allow_peapv0; + type = EAknCtPopupSettingList; + editor_resource_id = r_peap_setting_enumerated_popup; + } + + +RESOURCE AVKON_SETTING_PAGE r_peap_allow_version_1 + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_allow_peapv1; + type = EAknCtPopupSettingList; + editor_resource_id = r_peap_setting_enumerated_popup; + } + + +RESOURCE AVKON_SETTING_PAGE r_peap_allow_version_2 + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_allow_peapv2; + type = EAknCtPopupSettingList; + editor_resource_id = r_peap_setting_enumerated_popup; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/inc/EapPeapUi.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/inc/EapPeapUi.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP PEAP UI hrh file +* +*/ + + +#ifndef _EAPPEAPUI_HRH_ +#define _EAPPEAPUI_HRH_ + +enum TEapPeapUiMenuCommands + { + EPeapUiCmdUndefined = 6000, + EPeapUiCmdChange, + EPeapUiCmdEnable, + EPeapUiCmdDisable, + EPeapUiCmdConfigure, + EPeapUiCmdMoveUp, + EPeapUiCmdMoveDown, + EPeapUiCmdViewDetails + }; + +enum TEapPeapUiNotes + { + TEapPeapUiGeneralError = 6100 + }; + +enum TEapPeapUiLines + { + EPeapSettingsListBox = 6200 + }; + +enum TEapPeapUiSettingIds + { + EPeapSettingUserCert=6300, + EPeapSettingCaCert, + EPeapSettingUsernameInUseId, + EPeapSettingUsernameId, + EPeapSettingRealmInUseId, + EPeapSettingRealmId, + EPeapSettingTlsPrivacyId + }; + +enum TEapPeapUiSettingPageIds + { + EPeapSettingPageUserCertificates=6400, + EPeapSettingPageCaCertificates, + EPeapSettingPageCipherSuites, + EPeapSettingPageEapTypes, + EPeapSettingPageSettings + }; + +enum TEapPeapUiListBoxes + { + EPeapSettingsUserCertListbox=6500, + EPeapSettingsCaCertListbox, + EPeapSettingsCipherSuiteListbox, + EPeapSettingsEapTypeListbox, + EPeapSettingsListbox + }; + +enum TEapPeapSettingItems + { + EPeapTabSheetSettingsUsernameInUse=6600, + EPeapTabSheetSettingsUsername, + EPeapTabSheetSettingsRealmInUse, + EPeapTabSheetSettingsRealm + }; + +// Constants that are used as page ids +// TEapPeapUiSettingPageIds does not work for this purpose +#define KEAPPEAPSETTINGSPAGE 1 +#define KEAPPEAPEAPPAGE 2 +#define KEAPPEAPCIPHERPAGE 3 + + + +#endif //_EAPPEAPUI_HRH_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/inc/EapPeapUiSettingArray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/inc/EapPeapUiSettingArray.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP PEAP UI settings array +* +*/ + + + +#ifndef _EAPPEAPUISETTINGARRAY_H_ +#define _EAPPEAPUISETTINGARRAY_H_ + +// INCLUDES +#include +#include "EapPeapUi.hrh" + + +// CLASS DECLARATION + +/** +*/ +class CEapPeapSettingItemArray : public CBase + { + public: + static CEapPeapSettingItemArray* NewL(); + virtual ~CEapPeapSettingItemArray(); + CAknSettingItem* Item( TEapPeapUiSettingPageIds aItem ); + CAknSettingItemArray* Array(); + void StoreSettingsL(); + void AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal ); + void AddBinarySettingItemL( TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue); + + protected: + CEapPeapSettingItemArray(); + void ConstructL(); + + private: + CAknSettingItemArray* iArray; + }; + +#endif // _EAPPEAPUISETTINGARRAY_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/inc/EapPeapUiView.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/inc/EapPeapUiView.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,172 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP PEAP UI setting dialog +* +*/ + + + +#ifndef _EAPPEAPUIVIEW_H_ +#define _EAPPEAPUIVIEW_H_ + +// INCLUDES +#include // AVKON components +#include // For changing status pane +#include +#include +#include +#include +#include +#include "EapPeapUi.hrh" +#include +#include +#include +#include +#include +#include +#include + +// FORWARD DECLARATIONS +class CAknSettingStyleListBox; +class CSettingsListBoxItemDrawer; +class CEapPeapSettingItemArray; + + +// CLASS DECLARATION + +/** +* Settings dialog class definition +*/ +class CEapPeapUiDialog : public CAknDialog, + public MEapTlsPeapUiCertificates, + public MEikListBoxObserver + { + public: + CEapPeapUiDialog( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, TInt aIndex, + TInt& aButtonId ); + + ~CEapPeapUiDialog(); + + /** + * Create and launch dialog. + * @param aResourceId The resource ID of the dialog to load. + * @return The ID of the button that closed the dialog + */ + TInt ConstructAndRunLD( TInt aResourceId ); + + /** + * Chain into key event handler. + * @param aKeyEvent The event. + * @param aType The type of key event. + * @return Was the key consumed or not. + */ + TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, + TEventCode aType); + + + public: // From MEikListBoxObserver + + /** + * Handles list box events. + * @param aListBox The originating list box. + * @param aEventType A code for the event. + */ + void HandleListBoxEventL( CEikListBox* aListBox, TListBoxEvent aEventType ); + + + public: // From CEikDialog + + /** + * @see CEikDialog + */ + void HandleDialogPageEventL( TInt aEventID ); + + + protected: + void PreLayoutDynInitL(); + void PostLayoutDynInitL(); + TBool OkToExitL( TInt aButtonId ); + void ProcessCommandL( TInt aCommand ); + void PageChangedL( TInt aPageId ); + + private: + void ChangeTitleL( TBool aIsStarted ); + void DrawSettingsListL(); + void ShowSettingPageL( TInt aCalledFromMenu ); + void MoveEapTypeL( TInt aOldPos, TInt aNewPos ); + void DrawEapListL(TInt aWantedIndex); + TInt ShowRadioButtonSettingPageL( TInt aTitle, CDesCArrayFlat* aValues, + TInt aCurrentItem ); + void DrawCipherSuitesL(); + void CompleteReadCertificates( const TInt aResult ); + void CompleteUiConstructionL(); + TInt CheckActiveUserCertificate(); + TInt CheckActiveCaCertificate(); + void UserCertificateHouseKeeping( TInt aSelected ); + void CaCertificateHouseKeeping( TInt aSelected ); + void CreateEapTypeDataBaseL(); + void SetCipherIconsL(); + void SetEapIconsL(); + TUint GetEnabledEapTypeCount(); + void GetHelpContext(TCoeHelpContext& aContext) const; + + void GetFullCertLabelL( const SCertEntry& aCert, TDes& aFullLabel ); + + /** + * Initialize menu pane. + * @param aResourceId Menu pane resource id. + * @param CEikMenuPane Menu pane. + */ + void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ); + + void ConfigureL( TBool aQuick ); + + private: + CEapTlsPeapUiConnection* iConnection; + CEapTlsPeapUiDataConnection* iDataConnection; + CEapTlsPeapUiCipherSuites* iCipherSuites; + CEapTlsPeapUiCertificates* iCertificates; + + CEapTlsPeapUiTlsPeapData* iUiData; + CArrayFixFlat* iUiCipherSuites; + CArrayFixFlat* iUiUserCertificates; + CArrayFixFlat* iUiCACertificates; + CArrayFixFlat* iUiEapTypes; + + CAknSingleNumberStyleListBox* iUserCertificateListBox; + CAknSingleNumberStyleListBox* iCaCertificateListBox; + CAknSingleNumberStyleListBox* iCipherSuiteListBox; + CAknSingleNumberStyleListBox* iEapTypesListBox; + CEapPeapSettingItemArray* iSettingArray; + CAknSettingStyleListBox* iSettingListBox; + CDesCArray* iEapTypeViewArray; + CDesCArray* iCipherSuitesViewArray; + CEapTlsPeapUiEapTypes* iEapTypes; + TIndexType iIndexType; + TInt iIndex; + HBufC* iPreviousText; + TInt* iButtonId; + + // Tells the status of UI construction. TRUE if UI construction is completed. + TBool iIsUIConstructionCompleted; + + // For exiting dialog + TBool iExiting; + }; + + +#endif // _EAPPEAPUIVIEW_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/loc/eappeapui.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/loc/eappeapui.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI strings for WLAN EAP-PEAP authentication settings +* +*/ + + + +// LOCALISATION STRINGS + + +//d:UI title for main view +//l:title_pane_t2/opt9 +//w: +//r:3.1 +// +#define qtn_wlan_eap_peap_title "EAP-PEAP settings" + + +//d:Setting list item, static part. User is able to define the settings for +//d:the usage of different PEAP versions in WLAN authentication. +//l:list_setting_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_allow_peapv0 "Allow PEAPv0" + + +//d:Setting list item, static part. User is able to define the settings for +//d:the usage of different PEAP versions in WLAN authentication. +//l:list_setting_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_allow_peapv1 "Allow PEAPv1" + + +//d:Setting list item, static part. User is able to define the settings for +//d:the usage of different PEAP versions in WLAN authentication. +//l:list_setting_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_allow_peapv2 "Allow PEAPv2" + + +//d:Setting list item, dynamic part. Displayed below one of the texts +//d:"Allow PEAPv0" (qtn_wlan_eap_sett_allow_peapv0), "Allow PEAPv1" +//d:(qtn_wlan_eap_sett_allow_peapv1) or "Allow PEAPv2" +//d:(qtn_wlan_eap_sett_allow_peapv2). +//d:Allows the usage of a different version of PEAP. +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_allow_peap_yes "Yes" + + +//d:Setting list item, dynamic part. Displayed below one of the texts +//d:"Allow PEAPv0" (qtn_wlan_eap_sett_allow_peapv0), "Allow PEAPv1" +//d:(qtn_wlan_eap_sett_allow_peapv1) or "Allow PEAPv2" +//d:(qtn_wlan_eap_sett_allow_peapv2). +//d: Denies the usage of a different version of PEAP. +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_allow_peap_no "No" + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUi.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,143 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP PEAP UI class +* +*/ + + + +// INCLUDE FILES +#include "EapPeapUi.h" +#include "EapTlsPeapUiConnection.h" +#include "EapPeapUiView.h" +#include +#include +#include +#include +#include + + +// CONSTANTS +_LIT( KDriveZ, "z:" ); // ROM folder +_LIT( KResourceFileName, "eappeapui.rsc" ); + + +// CLASS DECLARATION +class TResourceFileCleanupItem + { + public: + CCoeEnv* iCoeEnv; + TInt iResourceFileOffset; + }; + + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CleanupResourceFile +// ----------------------------------------------------------------------------- +// +static void CleanupResourceFile( TAny* aObject ) + { + TResourceFileCleanupItem* item = + REINTERPRET_CAST( TResourceFileCleanupItem*, aObject ); + item->iCoeEnv->DeleteResourceFile( item->iResourceFileOffset ); + delete item; + } + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapPeapUi::CEapPeapUi +// ----------------------------------------------------------------------------- +// +CEapPeapUi::CEapPeapUi( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, + TInt aIndex ) +: iConnection( aConnection ), + iIndexType( aIndexType ), + iIndex( aIndex ) + { + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUi::NewL +// ----------------------------------------------------------------------------- +// +CEapPeapUi* CEapPeapUi::NewL( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, + TInt aIndex ) + { + CEapPeapUi* self = + new( ELeave ) CEapPeapUi( aConnection, aIndexType, aIndex ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUi::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapPeapUi::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUi::~CEapPeapUi +// ----------------------------------------------------------------------------- +// +CEapPeapUi::~CEapPeapUi() + { + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUi::InvokeUiL +// ----------------------------------------------------------------------------- +// +TInt CEapPeapUi::InvokeUiL() + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + CCoeEnv* coeEnv = CCoeEnv::Static(); + BaflUtils::NearestLanguageFile( coeEnv->FsSession(), fileName ); + + TResourceFileCleanupItem* item = new( ELeave ) TResourceFileCleanupItem; + + item->iCoeEnv = coeEnv; + CleanupStack::PushL( TCleanupItem( CleanupResourceFile, item ) ); + item->iResourceFileOffset = coeEnv->AddResourceFileL( fileName ); + + TInt buttonId; + CEapPeapUiDialog* settingsDlg = new( ELeave ) CEapPeapUiDialog( + iConnection, iIndexType, iIndex, buttonId ); + settingsDlg->ConstructAndRunLD( R_PEAP_SETTING_DIALOG ); + + CleanupStack::PopAndDestroy(); // For resource file + + return buttonId; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUiSettingArray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUiSettingArray.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,183 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP PEAP UI settings array +* +*/ + + + +// INCLUDE FILES +#include "EapPeapUiSettingArray.h" +#include "EapPeapUi.hrh" +#include +#include + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapPeapSettingItemArray::CEapPeapSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapPeapSettingItemArray::CEapPeapSettingItemArray() + { + } + + +// ----------------------------------------------------------------------------- +// CEapPeapSettingItemArray::NewL +// ----------------------------------------------------------------------------- +// +CEapPeapSettingItemArray* CEapPeapSettingItemArray::NewL() + { + CEapPeapSettingItemArray* self = new( ELeave ) CEapPeapSettingItemArray(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); // self + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapSettingItemArray::~CEapPeapSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapPeapSettingItemArray::~CEapPeapSettingItemArray() + { + if( iArray ) + { + // ResetAndDestroy() + iArray->ResetAndDestroy(); + } + delete iArray; + iArray = NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapSettingItemArray::Item +// ----------------------------------------------------------------------------- +// +CAknSettingItem* CEapPeapSettingItemArray::Item( TEapPeapUiSettingPageIds aId ) + { + for( TInt i = 0; i < iArray->Count(); i++ ) + { + if( iArray->At( i )->Identifier() == aId ) + { + return iArray->At( i ); + } + } + + __ASSERT_DEBUG( EFalse, User::Invariant() ); + return NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapSettingItemArray::Array +// ----------------------------------------------------------------------------- +// +CAknSettingItemArray* CEapPeapSettingItemArray::Array() + { + return iArray; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapSettingItemArray::StoreSettingsL +// ----------------------------------------------------------------------------- +// +void CEapPeapSettingItemArray::StoreSettingsL() + { + // Do what SettingItemList::StoreSettings would do. + for( TInt i( 0 ); i < iArray->Count(); ++i ) + { + iArray->At( i )->StoreL(); + } + } + + +// ----------------------------------------------------------------------------- +// CEapPeapSettingItemArray::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapPeapSettingItemArray::ConstructL() + { + iArray = new( ELeave ) CAknSettingItemArray( 2, EFalse, 0 ); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapSettingItemArray::AddTextItemL +// ----------------------------------------------------------------------------- +// +void CEapPeapSettingItemArray::AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal) + { + // Create new setting item + CAknTextSettingItem* settingItem = + new( ELeave ) CAknTextSettingItem( aId, aBuffer ); + CleanupStack::PushL( settingItem ); + settingItem->SetEmptyItemTextL( KNullDesC ); + settingItem->SetSettingPageFlags( + CAknTextSettingPage::EZeroLengthAllowed ); + + // Construct setting item with parametrized values + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResource ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResource, EAknCtPopupSettingList, + NULL, aAssociatedResource ); + + // Append item to settingitem-array + iArray->InsertL( aOrdinal, settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + // Items are destroyed in destructor when resetting array + CleanupStack::Pop( settingItem ); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapSettingItemArray::AddBinarySettingItemL +// ----------------------------------------------------------------------------- +// +void CEapPeapSettingItemArray::AddBinarySettingItemL( + TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue ) + { + CAknSettingItem* settingItem = new ( ELeave ) + CAknBinaryPopupSettingItem( 0, aModifiedValue ); + CleanupStack::PushL( settingItem ); + + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResourceId ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResourceId, EAknCtPopupSettingList, + NULL, aAssociatedResourceId ); + iArray->AppendL( settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + CleanupStack::Pop( settingItem ); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUiView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUiView.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1860 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP PEAP UI settings dialog +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include "EapPeapUiView.h" +#include "EapPeapUi.hrh" +#include +#include +#include +#include "EapPeapUiSettingArray.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // For EAP type info query +#include +#include +#include +#include +#include + + +// CONSTANTS +// UID of general settings app, in which help texts are included +const TUid KHelpUidPlugin = { 0x100058EC }; + + +static const TInt KSettingArrayGranularity = 4; +static const TInt KSuiteArrayGranularity = 5; +static const TInt KMaxLengthOfEapLine = 270; +static const TInt KCertificateArrayGranularity = 5; +static const TInt KMaxLengthOfSuiteName = 255; +static const TInt KEapPeapId = 25; + +_LIT( KNameSeparator, " " ); +_LIT( KEmptyString, "" ); +const TUint KFirstElement = 0; +const TUint KSecondElement = 1; +const TUint KMinEnabledCount = 1; + +/* This is the maximum length of a certificate's full name, includes +label, primary and secondary names */ +const TUint32 KMaxFullCertLabelLength = KMaxCertLabelLength + 2 * + KMaxNameLength + 1; // 1 is for separator. + + +// MODULE DATA STRUCTURES +enum TPageIds + { + ESettingsPage=0, + EEapTypePage, + ECipherSuitePage + }; + + +enum TSettingIds + { + EUserCertificateItem=0, + ECaCertificateItem, + EUsernameInUseItem, + EUsernameItem, + ERealmInUseItem, + ERealmItem + }; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::CEapPeapUiDialog +// ----------------------------------------------------------------------------- +// +CEapPeapUiDialog::CEapPeapUiDialog( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, + TInt aIndex, + TInt& aButtonId ) +: CAknDialog(), + iConnection( aConnection ), + iIndexType( aIndexType ), + iIndex( aIndex ), + iButtonId( &aButtonId ), + iIsUIConstructionCompleted( EFalse ), + iExiting( EFalse ) + { + } + + +// --------------------------------------------------------- +// CEapPeapUiDialog::ConstructAndRunLD +// --------------------------------------------------------- +// +TInt CEapPeapUiDialog::ConstructAndRunLD( TInt aResourceId ) + { + CleanupStack::PushL( this ); + + iSettingArray = CEapPeapSettingItemArray::NewL(); + + User::LeaveIfError( iConnection->Connect() ); + + // Basic data + iDataConnection = iConnection->GetDataConnection(); + if ( iDataConnection == 0 ) + { + User::Leave( KErrNoMemory ); + } + User::LeaveIfError( iDataConnection->Open() ); + User::LeaveIfError( iDataConnection->GetData( &iUiData ) ); + + // Cipher suites + iCipherSuites = iConnection->GetCipherSuiteConnection(); + if ( iCipherSuites == 0 ) + { + User::Leave( KErrNoMemory ); + } + + User::LeaveIfError( iCipherSuites->Open() ); + User::LeaveIfError( iCipherSuites->GetCipherSuites( &iUiCipherSuites ) ); + + iCipherSuitesViewArray = new( ELeave ) CDesCArrayFlat( + KSuiteArrayGranularity ); + + //EAP types + iEapTypes = iConnection->GetEapTypeConnection(); + if ( iEapTypes == 0 ) + { + User::Leave( KErrNoMemory ); + } + User::LeaveIfError( iEapTypes->Open() ); + User::LeaveIfError( iEapTypes->GetEapTypes( &iUiEapTypes ) ); + + if ( iUiEapTypes->Count() == 0 ) + { + CreateEapTypeDataBaseL(); + } + iEapTypeViewArray = new( ELeave ) CDesCArrayFlat( + KSettingArrayGranularity ); + + FeatureManager::InitializeLibL(); + + ConstructL( R_PEAP_MENUBAR ); + + // ExecuteLD will PushL( this ), so we have to Pop it... + CleanupStack::Pop( this ); // this + + return CAknDialog::ExecuteLD( aResourceId ); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::OfferKeyEventL +// ----------------------------------------------------------------------------- +// +TKeyResponse CEapPeapUiDialog::OfferKeyEventL( const TKeyEvent& aKeyEvent, + TEventCode aType ) + { + TKeyResponse result( EKeyWasNotConsumed ); + + // gently handle impatient users + if ( !iIsUIConstructionCompleted ) + { + return CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + + TInt pageId = ActivePageId(); + + if ( aType == EEventKey && pageId == KEAPPEAPCIPHERPAGE ) + { + + TInt indexBefore = iCipherSuiteListBox->CurrentItemIndex(); + + // Handle Enter key here, since it doesn't seem to convert into + // the proper command id via the normal route + // (maybe some Avkon support for Enter key is still missing in + // S60 3.2 2008_wk22) + if ( aKeyEvent.iCode == EKeyEnter ) + { + if ( ( *iUiCipherSuites )[indexBefore].iIsEnabled ) + { + OkToExitL( EPeapUiCmdDisable ); + } + else + { + OkToExitL( EPeapUiCmdEnable ); + } + + result = EKeyWasConsumed; + } + else + { + result = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + TInt indexAfter = iCipherSuiteListBox->CurrentItemIndex(); + + if ( indexBefore != indexAfter ) + { + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + if( ( *iUiCipherSuites )[indexAfter].iIsEnabled ) + { + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_DISABLE ); + } + else + { + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + } + + cba.DrawDeferred(); + } + } + else if ( aType == EEventKey && pageId == KEAPPEAPEAPPAGE ) + { + TInt indexBefore = iEapTypesListBox->CurrentItemIndex(); + // Handle Enter key here, since it doesn't seem to convert into + // the proper command id via the normal route + // (maybe some Avkon support for Enter key is still missing in + // S60 3.2 2008_wk22) + if ( aKeyEvent.iCode == EKeyEnter ) + { + if ( ( *iUiEapTypes )[indexBefore].iIsEnabled ) + { + OkToExitL( EPeapUiCmdConfigure ); + } + else + { + OkToExitL( EPeapUiCmdEnable ); + } + + result = EKeyWasConsumed; + } + else + { + result = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + + + TInt indexAfter = iEapTypesListBox->CurrentItemIndex(); + + if ( indexBefore != indexAfter ) + { + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + if( ( *iUiEapTypes )[indexAfter].iIsEnabled ) + { + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_CONFIGURE ); + } + else + { + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + } + + cba.DrawDeferred(); + } + } + else + { + result = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + + return result; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::~CEapPeapUiDialog +// ----------------------------------------------------------------------------- +// +CEapPeapUiDialog::~CEapPeapUiDialog() + { + if ( iSettingArray ) + { + iSettingArray->Array()->ResetAndDestroy(); + } + + delete iSettingArray; + iSettingListBox = NULL; + + iDataConnection->Close(); + delete iDataConnection; + + iCipherSuitesViewArray->Reset(); + delete iCipherSuitesViewArray; + + iEapTypeViewArray->Reset(); + delete iEapTypeViewArray; + + iCertificates->Close(); + delete iCertificates; + + iCipherSuites->Close(); + delete iCipherSuites; + + iEapTypes->Close(); + delete iEapTypes; + + iConnection->Close(); + + delete iPreviousText; + + FeatureManager::UnInitializeLib(); + } + + +// --------------------------------------------------------- +// CEapPeapUiDialog::HandleListBoxEventL +// --------------------------------------------------------- +// +void CEapPeapUiDialog::HandleListBoxEventL( CEikListBox* aListBox, + TListBoxEvent aEventType ) + { + switch ( aEventType ) + { + case EEventEnterKeyPressed: + case EEventItemSingleClicked: + { + if ( aListBox == iSettingListBox ) + { + OkToExitL( EPeapUiCmdChange ); + } + + else if ( aListBox == iEapTypesListBox ) + { + TInt index = iEapTypesListBox->CurrentItemIndex(); + if ( iUiEapTypes->At( index ).iIsEnabled ) + { + ConfigureL( ETrue ); + } + else + { + OkToExitL( EPeapUiCmdEnable ); + } + } + + else if ( aListBox == iCipherSuiteListBox ) + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + if ( iUiCipherSuites->At( index ).iIsEnabled ) + { + OkToExitL( EPeapUiCmdDisable ); + } + else + { + OkToExitL( EPeapUiCmdEnable ); + } + } + + else + { + // Do nothing; we should never end up here + } + + break; + } + + case EEventItemActioned: + case EEventEditingStarted: + case EEventEditingStopped: + case EEventPenDownOnItem: + case EEventItemDraggingActioned: + { + break; + } + + default: + { + break; + }; + }; + } + + +// --------------------------------------------------------- +// CEapPeapUiDialog::HandleDialogPageEventL +// --------------------------------------------------------- +// +void CEapPeapUiDialog::HandleDialogPageEventL( TInt aEventID ) + { + CAknDialog::HandleDialogPageEventL( aEventID ); + if( iExiting ) + { + // Exit requested. + TryExitL( EAknCmdExit ); + } + } + + +// --------------------------------------------------------- +// CEapPeapUiDialog::ConfigureL +// --------------------------------------------------------- +// +void CEapPeapUiDialog::ConfigureL( TBool aQuick ) + { + RImplInfoPtrArray eapArray; + eapArray.Reset(); + + REComSession::ListImplementationsL( KEapTypeInterfaceUid, + eapArray ); + TInt itemIndex = iEapTypesListBox->CurrentItemIndex(); + TInt eapIndex( 0 ); + for ( TInt i = 0; i < eapArray.Count(); i++ ) + { + CImplementationInformation* tempInfo = eapArray[i]; + if ( iUiEapTypes->At( itemIndex ).iEapType == + tempInfo->DataType() ) + { + eapIndex = i; + break; + } + } + + CEapType* eapType; + eapType = CEapType::NewL( eapArray[eapIndex]->DataType(), + iIndexType, iIndex ); + eapArray.ResetAndDestroy(); + eapType->SetTunnelingType( KEapPeapId ); + CleanupStack::PushL( eapType ); + TInt buttonId = eapType->InvokeUiL(); + CleanupStack::PopAndDestroy( eapType ); + + if ( buttonId == EAknCmdExit || buttonId == EEikCmdExit ) + { + if (aQuick == EFalse) + { + TryExitL( buttonId ); + } + else + { + iExiting = ETrue; + // Don't exit here. Framework command chain will + // cause a KERN-EXEC 3 panic. Handle the exit in + // HandleDialogPageEventL(). + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::PreLayoutDynInitL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::PreLayoutDynInitL() + { + // Change title + ChangeTitleL( ETrue ); + + iSettingListBox = static_cast( + ControlOrNull( EPeapSettingsListbox ) ); + iSettingListBox->SetComponentsToInheritVisibility( ETrue ); + + iEapTypesListBox = static_cast( + ControlOrNull( EPeapSettingsEapTypeListbox ) ); + iEapTypesListBox->SetComponentsToInheritVisibility( ETrue ); + + iCipherSuiteListBox = static_cast( + ControlOrNull( EPeapSettingsCipherSuiteListbox ) ); + iCipherSuiteListBox->SetComponentsToInheritVisibility( ETrue ); + + // Get certificates before building the UI. + // Will continue when certificates are received + iCertificates = iConnection->GetCertificateConnection( this ); + User::LeaveIfError( iCertificates->Open() ); + iCertificates->GetCertificates( &iUiUserCertificates, &iUiCACertificates ); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::CompleteReadCertificates +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::CompleteReadCertificates( const TInt aResult ) + { + if ( aResult == KErrNone ) // Certificates are received from core + { + TRAPD( err, CompleteUiConstructionL() ); + if ( err != KErrNone ) + { + TRAP_IGNORE( TryExitL( KErrCancel ) ); + } + } + else + { + TRAP_IGNORE( TryExitL( KErrCancel ) ); + } + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::CompleteUiConstructionL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::CompleteUiConstructionL() + { + // Initialize setting page + iSettingListBox = static_cast( + ControlOrNull( EPeapSettingsListbox ) ); + iSettingListBox->SetMopParent( this ); + iSettingListBox->CreateScrollBarFrameL( ETrue ); + iSettingListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iSettingListBox->SetListBoxObserver( this ); + DrawSettingsListL(); + + // Initialize EAP types page + iEapTypesListBox = static_cast( + ControlOrNull( EPeapSettingsEapTypeListbox ) ); + iEapTypesListBox->SetMopParent( this ); + iEapTypesListBox->CreateScrollBarFrameL( ETrue ); + iEapTypesListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iEapTypesListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iEapTypesListBox->SetListBoxObserver( this ); + + // Following deletes internal array created from resources. + // To prevent memory leak. + MDesCArray* internalArray1 = iEapTypesListBox->Model()->ItemTextArray(); + delete internalArray1; + + // Initialize cipher suites page + iCipherSuiteListBox = static_cast( + ControlOrNull( EPeapSettingsCipherSuiteListbox ) ); + iCipherSuiteListBox->CreateScrollBarFrameL( ETrue ); + iCipherSuiteListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iCipherSuiteListBox->UpdateScrollBarsL(); + iCipherSuiteListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iCipherSuiteListBox->SetListBoxObserver( this ); + + //Following deletes internal array created from resources. + // To prevent memory leak. + MDesCArray* internalArray2 = iCipherSuiteListBox->Model()->ItemTextArray(); + delete internalArray2; + + SetEapIconsL(); + DrawEapListL( 0 ); + + SetCipherIconsL(); + DrawCipherSuitesL(); + + iIsUIConstructionCompleted = ETrue; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::PostLayoutDynInitL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::PostLayoutDynInitL() + { + TUid naviPaneUid; + naviPaneUid.iUid = EEikStatusPaneUidNavi; + + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( naviPaneUid ); + if ( subPane.IsPresent()&&subPane.IsAppOwned() ) + { + CAknNavigationControlContainer* naviPane = + static_cast( + statusPane->ControlL( naviPaneUid ) ); + CAknNavigationDecorator* naviDecorator = naviPane->ResourceDecorator(); + if ( naviDecorator ) + { + CAknTabGroup* tabGroup = static_cast( + naviDecorator->DecoratedControl() ); + tabGroup->SetActiveTabById( 0 ); + tabGroup->SetTabFixedWidthL( KTabWidthWithOneTab ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::ChangeTitleL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::ChangeTitleL( TBool aIsStarted ) + { + TUid titlePaneUid; + titlePaneUid.iUid = EEikStatusPaneUidTitle; + + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( titlePaneUid ); + + if ( subPane.IsPresent() && subPane.IsAppOwned() ) + { + CAknTitlePane* titlePane = static_cast( + statusPane->ControlL( titlePaneUid) ); + if ( aIsStarted ) + { + // Store previous application title text + const TDesC* prevText = titlePane->Text(); + iPreviousText = HBufC::NewL( prevText->Length() ); + iPreviousText->Des().Append( *prevText ); + TDesC* titleText = iEikonEnv->AllocReadResourceLC( + R_PEAP_SETTINGS_TITLE ); + titlePane->SetTextL( *titleText ); + CleanupStack::PopAndDestroy( titleText ); + } + else + { + // Set calling application title text back + titlePane->SetTextL( *iPreviousText ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CEapPeapUiDialog::OkToExitL( TInt aButtonId ) + { + TBool ret( EFalse ); + switch ( aButtonId ) + { + case EEikBidOk: + { + if( iIsUIConstructionCompleted ) + { + TPageIds index = static_cast( ActivePageIndex() ); + if ( index == ESettingsPage ) + { + ShowSettingPageL( EFalse ); + } + else if ( index == EEapTypePage ) + { + ProcessCommandL( EPeapUiCmdConfigure ); + } + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapPeapUiDialog::OkToExitL - UI not ready - Ignoring key press.\n") ); + #endif + } + + break; + } + + case EAknSoftkeyOptions: + { + DisplayMenuL(); + break; + } + + case EAknSoftkeyBack: + case EAknCmdExit: + { + if( iIsUIConstructionCompleted ) + { + iDataConnection->Update(); + ChangeTitleL( EFalse ); + ret = ETrue; + } + break; + } + + case EPeapUiCmdChange: + { + TInt pageId = ActivePageId(); + if ( pageId == KEAPPEAPSETTINGSPAGE ) + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( EFalse ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapPeapUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + } + break; + } + case EPeapUiCmdConfigure: + case EPeapUiCmdEnable: + case EPeapUiCmdDisable: + { + ProcessCommandL( aButtonId ); + ret = EFalse; + break; + } + + default: + { + break; + } + } + + if ( ret ) + { + *iButtonId = aButtonId; + } + + return ret; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::DrawSettingsListL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::DrawSettingsListL() + { + iSettingArray->Array()->ResetAndDestroy(); + TInt ordinal = 0; + TInt activeUserCertificate = CheckActiveUserCertificate(); + TBuf aActiveuserCertificateName = KEmptyString(); + if ( activeUserCertificate != KErrNotFound ) + { + TBuf text; + GetFullCertLabelL( + iUiUserCertificates->At( activeUserCertificate ).iCertEntry, + text ); + aActiveuserCertificateName.Copy( text ); + } + else + { + TDesC* notDefinedText = iEikonEnv->AllocReadResourceLC( + R_PEAP_NOT_DEFINED ); + aActiveuserCertificateName.Copy( *notDefinedText ); + CleanupStack::PopAndDestroy( notDefinedText ); + } + + iSettingArray->AddTextItemL( aActiveuserCertificateName, + EPeapSettingUserCert, + R_PEAP_USER_CERT_STRING, + R_PEAP_USERNAME_PAGE, + NULL, + ordinal++ ); + + TInt activeCaCertificate = CheckActiveCaCertificate(); + TBuf aActiveCaCertificateName = KEmptyString(); + if ( activeCaCertificate != KErrNotFound ) + { + TBuf text; + GetFullCertLabelL( + iUiCACertificates->At( activeCaCertificate ).iCertEntry, + text ); + aActiveCaCertificateName.Copy( text ); + } + else + { + TDesC* notDefinedText = iEikonEnv->AllocReadResourceLC( + R_PEAP_NOT_DEFINED ); + aActiveCaCertificateName.Copy( *notDefinedText ); + CleanupStack::PopAndDestroy( notDefinedText ); + } + + iSettingArray->AddTextItemL( aActiveCaCertificateName, + EPeapSettingCaCert, + R_PEAP_CA_CERT_STRING, + R_PEAP_USERNAME_PAGE, + NULL, + ordinal++ ); + + iSettingArray->AddBinarySettingItemL( R_PEAP_DISPLAY_AUTOUSECONF_PAGE, + R_PEAP_USERNAME_INUSESTRING, + R_PEAP_USERNAME_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetUseManualUsername() ); + + iSettingArray->AddTextItemL( iUiData->GetManualUsername(), + EPeapTabSheetSettingsUsername, + R_PEAP_USERNAME_STRING, + R_PEAP_USERNAME_PAGE, + NULL, + ordinal++ ); + + iSettingArray->AddBinarySettingItemL( R_PEAP_DISPLAY_AUTOUSECONF_PAGE, + R_PEAP_REALM_INUSESTRING, + R_PEAP_REALM_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetUseManualRealm() ); + + iSettingArray->AddTextItemL( iUiData->GetManualRealm(), + EPeapTabSheetSettingsRealm, + R_PEAP_REALM_STRING, + R_PEAP_REALM_PAGE, + NULL, + ordinal++ ); + + iSettingArray->AddBinarySettingItemL( R_PEAP_DISPLAY_AUTOUSECONF_PAGE, + R_PEAP_TLS_PRIVACY_STRING, + R_PEAP_TLS_PRIVACY_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetTlsPrivacy() ); + + + iSettingArray->AddBinarySettingItemL( R_PEAP_ALLOW_VERSION_0, + R_PEAP_ALLOW_PEAPV0, + R_PEAP_ALLOW_VERSION_TEXTS, + ordinal++, + *iUiData->GetAllowVersion0() ); + + iSettingArray->AddBinarySettingItemL( R_PEAP_ALLOW_VERSION_1, + R_PEAP_ALLOW_PEAPV1, + R_PEAP_ALLOW_VERSION_TEXTS, + ordinal++, + *iUiData->GetAllowVersion1() ); + + iSettingArray->AddBinarySettingItemL( R_PEAP_ALLOW_VERSION_2, + R_PEAP_ALLOW_PEAPV2, + R_PEAP_ALLOW_VERSION_TEXTS, + ordinal++, + *iUiData->GetAllowVersion2() ); + + iSettingListBox->Model()->SetItemTextArray( iSettingArray->Array() ); + iSettingListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iSettingArray->Array()->RecalculateVisibleIndicesL(); + iSettingListBox->HandleItemAdditionL(); + iSettingListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::DynInitMenuPaneL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + CAknDialog::DynInitMenuPaneL( aResourceId, aMenuPane ); + + if ( aMenuPane && aResourceId == R_PEAP_MENU_PANE ) + { + if ( !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + + TPageIds index = static_cast( ActivePageIndex() ); + if ( index == ESettingsPage ) + { + aMenuPane->SetItemDimmed( EPeapUiCmdEnable, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdDisable, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdConfigure, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdMoveUp, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdMoveDown, ETrue ); + } + else if ( index == EEapTypePage ) + { + aMenuPane->SetItemDimmed( EPeapUiCmdChange, ETrue ); + + if ( iEapTypeViewArray->Count() > 0 ) + { + TInt currentIndex = iEapTypesListBox->CurrentItemIndex(); + TBool enabled = iUiEapTypes->At( currentIndex ).iIsEnabled; + + // Hide either "Enable" or "Disable", as appropriate. + aMenuPane->SetItemDimmed( EPeapUiCmdEnable, enabled ); + aMenuPane->SetItemDimmed( EPeapUiCmdDisable, !enabled ); + + // Don't display "Configure" for disabled items + aMenuPane->SetItemDimmed( EPeapUiCmdConfigure, !enabled ); + + // Don't display "Raise priority" nor "Lower priority" for + // disabled items + aMenuPane->SetItemDimmed( EPeapUiCmdMoveUp, !enabled ); + aMenuPane->SetItemDimmed( EPeapUiCmdMoveDown, !enabled ); + + if ( enabled ) + { + + if ( currentIndex == 0 ) + { + // Can't go higher than top. + aMenuPane->SetItemDimmed( EPeapUiCmdMoveUp, ETrue ); + } + + if ( currentIndex == iEapTypeViewArray->Count()-1 || + ( currentIndex < iEapTypeViewArray->Count()-1 && + !iUiEapTypes->At( currentIndex + 1 ).iIsEnabled ) ) + { + // Can't go lower than the last enabled item + aMenuPane->SetItemDimmed( EPeapUiCmdMoveDown, ETrue ); + } + + } + + } + else + { + aMenuPane->SetItemDimmed( EPeapUiCmdEnable, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdDisable, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdConfigure, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdMoveUp, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdMoveDown, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdChange, ETrue ); + } + } + else if ( index == ECipherSuitePage ) + { + aMenuPane->SetItemDimmed( EPeapUiCmdConfigure, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdMoveUp, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdMoveDown, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdChange, ETrue ); + + if ( iCipherSuitesViewArray->Count() > 0 ) + { + TInt currIndex = iCipherSuiteListBox->CurrentItemIndex(); + TBool enabled = iUiCipherSuites->At( currIndex ).iIsEnabled; + + // Hide either "Enable" or "Disable", as appropriate. + aMenuPane->SetItemDimmed( EPeapUiCmdEnable, enabled ); + aMenuPane->SetItemDimmed( EPeapUiCmdDisable, !enabled ); + } + else + { + aMenuPane->SetItemDimmed( EPeapUiCmdEnable, ETrue ); + aMenuPane->SetItemDimmed( EPeapUiCmdDisable, ETrue ); + } + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::ProcessCommandL( TInt aCommand ) + { + if ( MenuShowing() ) + { + HideMenu(); + } + + TPageIds pageIndex = static_cast( ActivePageIndex() ); + switch( aCommand ) + { + case EAknCmdExit: + { + TryExitL( aCommand ); + break; + } + + case EAknCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + iEikonEnv->EikAppUi()->AppHelpContextL() ); + break; + } + + case EPeapUiCmdChange: + { + if ( pageIndex == ESettingsPage ) + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( ETrue ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapPeapUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + } + break; + } + + case EPeapUiCmdMoveUp: + { + if ( pageIndex == EEapTypePage ) + { + TInt cur = iEapTypesListBox->CurrentItemIndex(); + MoveEapTypeL( cur, cur - 1 ); + } + break; + } + + case EPeapUiCmdMoveDown: + { + if ( pageIndex == EEapTypePage ) + { + TInt cur = iEapTypesListBox->CurrentItemIndex(); + MoveEapTypeL( cur, cur + 1 ); + } + break; + } + + case EPeapUiCmdEnable: + { + if ( pageIndex == ECipherSuitePage ) + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + iUiCipherSuites->At( index ).iIsEnabled = ETrue; + iCipherSuites->Update(); + DrawCipherSuitesL(); + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_DISABLE ); + cba.DrawDeferred(); + } + else if ( pageIndex == EEapTypePage ) + { + TInt cur = iEapTypesListBox->CurrentItemIndex(); + iUiEapTypes->At( cur ).iIsEnabled = ETrue; + + iEapTypes->Update(); + + // enabling moves item to the top of the list + MoveEapTypeL( cur, 0 ); + + // load the new CBA from resource + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_CONFIGURE ); + cba.DrawDeferred(); + } + break; + } + + case EPeapUiCmdDisable: + { + if ( pageIndex == ECipherSuitePage ) + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + iUiCipherSuites->At( index ).iIsEnabled = EFalse; + iCipherSuites->Update(); + DrawCipherSuitesL(); + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + cba.DrawDeferred(); + } + else if ( pageIndex == EEapTypePage ) + { + TInt itemIndex = iEapTypesListBox->CurrentItemIndex(); + + if( GetEnabledEapTypeCount() > KMinEnabledCount ) + { + // disabling moves item just after the last enabled one, + // so find that position + TInt next = itemIndex; + + while ( next < iUiEapTypes->Count() - 1 && + iUiEapTypes->At( next ).iIsEnabled ) + { + ++next; + } + + if ( next > itemIndex && + !iUiEapTypes->At( next ).iIsEnabled ) + { + --next; + } + + + iUiEapTypes->At( itemIndex ).iIsEnabled = EFalse; + + // move item if needed + MoveEapTypeL( itemIndex, next ); + iEapTypes->Update(); + + // Highlight follows movement. + //iEapTypesListBox->SetCurrentItemIndex( next ); + + // load the new CBA from resource + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + cba.SetCommandSetL( + R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + + cba.DrawDeferred(); + } + else + { + HBufC* stringLabel; + stringLabel = StringLoader::LoadL( + R_PEAP_INFO_CANNOT_DISABLE_ALL_EAP_PLUGINS, + iEikonEnv ); + CleanupStack::PushL( stringLabel ); + CAknInformationNote* dialog = new ( ELeave ) + CAknInformationNote( ETrue ); + dialog->ExecuteLD( *stringLabel ); + CleanupStack::PopAndDestroy( stringLabel ); + } + } + break; + } + + case EPeapUiCmdConfigure: + { + if ( pageIndex == EEapTypePage ) + { + ConfigureL(EFalse); + } + break; + } + + default: + { + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::PageChangedL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::PageChangedL( TInt aPageId ) + { + if ( !iIsUIConstructionCompleted ) + { + return; + } + + if ( aPageId == KEAPPEAPSETTINGSPAGE ) + { + if (iSettingListBox->ScrollBarFrame()) + { + iSettingListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(ETrue); + } + if (iEapTypesListBox->ScrollBarFrame()) + { + iEapTypesListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + if (iCipherSuiteListBox->ScrollBarFrame()) + { + iCipherSuiteListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + } + else if ( aPageId == KEAPPEAPEAPPAGE ) + { + if (iSettingListBox->ScrollBarFrame()) + { + iSettingListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + if (iEapTypesListBox->ScrollBarFrame()) + { + iEapTypesListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(ETrue); + } + if (iCipherSuiteListBox->ScrollBarFrame()) + { + iCipherSuiteListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + } + else if ( aPageId == KEAPPEAPCIPHERPAGE ) + { + if (iSettingListBox->ScrollBarFrame()) + { + iSettingListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + if (iEapTypesListBox->ScrollBarFrame()) + { + iEapTypesListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + if (iCipherSuiteListBox->ScrollBarFrame()) + { + iCipherSuiteListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(ETrue); + } + } + + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + if( aPageId == KEAPPEAPSETTINGSPAGE ) + { + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_EDIT ); + } + else if( aPageId == KEAPPEAPEAPPAGE ) + { + TInt index = iEapTypesListBox->CurrentItemIndex(); + if ( ( *iUiEapTypes )[index].iIsEnabled ) + { + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_CONFIGURE ); + } + else + { + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + } + + } + else if( aPageId == KEAPPEAPCIPHERPAGE ) + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + if( ( *iUiCipherSuites )[ index ].iIsEnabled ) + { + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_DISABLE ); + } + else + { + cba.SetCommandSetL( R_PEAP_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + } + } + cba.DrawDeferred(); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::ShowSettingPageL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::ShowSettingPageL( TInt aCalledFromMenu ) + { + TInt index = iSettingListBox->CurrentItemIndex(); + if ( index == EUserCertificateItem ) + { + TInt activeUserCertificate = CheckActiveUserCertificate(); + CDesCArrayFlat* tempArray = new( ELeave )CDesCArrayFlat( + KCertificateArrayGranularity ); + CleanupStack::PushL( tempArray ); + + TDesC* noneText = iEikonEnv->AllocReadResourceLC( + R_PEAP_NONE_SELECTION ); + tempArray->InsertL( 0, *noneText ); + CleanupStack::PopAndDestroy( noneText ); + + for ( TInt i = 0; i < iUiUserCertificates->Count(); i++ ) + { + TEapTlsPeapUiCertificate certificate = + iUiUserCertificates->At( i ); + SCertEntry entry = certificate.iCertEntry; + TBuf text; + GetFullCertLabelL( entry, text); + tempArray->InsertL( i+1, text ); + } + + TInt selected( 0 ); + if ( activeUserCertificate == KErrNotFound ) + { + selected = ShowRadioButtonSettingPageL( R_PEAP_USER_CERT_STRING, + tempArray, 0 ); + } + else + { + selected = ShowRadioButtonSettingPageL( R_PEAP_USER_CERT_STRING, + tempArray, + activeUserCertificate+1 ); + //Plus 1 cause we added 'none' selection + } + + CleanupStack::PopAndDestroy( tempArray ); + UserCertificateHouseKeeping( selected ); + iCertificates->Update(); + DrawSettingsListL(); // List must be drawn again at this stage + } + else if ( index == ECaCertificateItem ) + { + TInt activeCaCertificate = CheckActiveCaCertificate(); + + CDesCArrayFlat* tempArray = new( ELeave )CDesCArrayFlat( + KCertificateArrayGranularity ); + CleanupStack::PushL( tempArray); + + TDesC* noneText = iEikonEnv->AllocReadResourceLC( + R_PEAP_NONE_SELECTION ); + tempArray->InsertL( 0, *noneText); + CleanupStack::PopAndDestroy( noneText); + + for ( TInt i = 0; i < iUiCACertificates->Count(); i++ ) + { + TEapTlsPeapUiCertificate certificate = iUiCACertificates->At( i ); + SCertEntry entry = certificate.iCertEntry; + TBuf text; + GetFullCertLabelL( entry, text ); + tempArray->InsertL( i+1, text ); + } + + TInt selected( 0 ); + if ( activeCaCertificate == KErrNotFound ) + { + selected = ShowRadioButtonSettingPageL( R_PEAP_CA_CERT_STRING, + tempArray, 0 ); + } + else + { + selected = ShowRadioButtonSettingPageL( R_PEAP_CA_CERT_STRING, + tempArray, + activeCaCertificate+1 ); + //Plus 1 cause we added 'none' selection + } + CleanupStack::PopAndDestroy( tempArray ); + CaCertificateHouseKeeping( selected ); + iCertificates->Update(); + DrawSettingsListL(); // List must be drawn again at this stage + } + else + { + CAknSettingItem* item = iSettingArray->Array()->At( index ); + item->EditItemL( aCalledFromMenu ); + item->StoreL(); + } + + DrawNow(); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::MoveEapTypeL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::MoveEapTypeL( TInt aOldPos, TInt aNewPos ) + { + TEapTlsPeapUiEapType originalUpper = iUiEapTypes->At( aOldPos ); + iUiEapTypes->Delete( aOldPos ); + iUiEapTypes->InsertL( aNewPos, originalUpper ); + iUiEapTypes->Compress(); // Might not be needed + iEapTypes->Update(); + DrawEapListL( aNewPos ); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::DrawEapListL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::DrawEapListL( TInt aWantedIndex ) + { + iEapTypeViewArray->Reset(); + + RImplInfoPtrArray eapArray; + eapArray.Reset(); + + REComSession::ListImplementationsL( KEapTypeInterfaceUid, eapArray ); + for ( TInt i = 0; i < iUiEapTypes->Count(); i++ ) + { + TBuf tempLine; + + if ( iUiEapTypes->At( i ).iIsEnabled ) + { + _LIT( KNumTab, "%d\t" ); + tempLine.AppendFormat( KNumTab, i+1 ); + } + else + { + _LIT( KTab, "\t" ); + tempLine.Append( KTab ); + } + + for ( TInt index = 0; index < eapArray.Count(); index++ ) + { + TBuf8<100> egyik( eapArray[index]->DataType() ); + TBuf8<100> masik( iUiEapTypes->At( i ).iEapType ); + if ( eapArray[index]->DataType() == iUiEapTypes->At( i ).iEapType ) + { + tempLine.Append( eapArray[ index ]->DisplayName() ); + break; + } + } + if ( iUiEapTypes->At( i ).iIsEnabled ) + { // Add mark icon to indicate that the eap type is enabled + _LIT( KTab0, "\t0" ); + tempLine.Append( KTab0 ); + } + iEapTypeViewArray->InsertL( i, tempLine ); + } + + eapArray.ResetAndDestroy(); + iEapTypesListBox->Model()->SetItemTextArray( iEapTypeViewArray ); + iEapTypesListBox->HandleItemAdditionL(); + iEapTypesListBox->SetCurrentItemIndex( aWantedIndex ); + iEapTypesListBox->DrawDeferred(); + iEapTypesListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::ShowRadioButtonSettingPageL +// ----------------------------------------------------------------------------- +// +TInt CEapPeapUiDialog::ShowRadioButtonSettingPageL( TInt aTitle, + CDesCArrayFlat* aValues, + TInt aCurrentItem ) + { + // title of the dialog + HBufC* title = iCoeEnv->AllocReadResourceLC( aTitle ); + // We have everything to create dialog + CAknRadioButtonSettingPage* dlg = new( ELeave )CAknRadioButtonSettingPage( + R_RADIO_BUTTON_SETTING_PAGE, + aCurrentItem, + aValues ); + CleanupStack::PushL( dlg ); + dlg->SetSettingTextL( *title ); + CleanupStack::Pop( dlg ); + dlg->ExecuteLD( CAknSettingPage::EUpdateWhenChanged ); + CleanupStack::PopAndDestroy( title ); + // index must be re-turned upside down, because options list is upside down + return aCurrentItem; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::DrawCipherSuitesL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::DrawCipherSuitesL() + { + iCipherSuitesViewArray->Reset(); + TInt listCount( 0 ); + TBuf temp; + for ( TInt i = 0; i < iUiCipherSuites->Count(); i++ ) + { + temp.Zero(); + _LIT( KTab, "\t" ); + temp.Append( KTab ); + TEapTlsPeapUiCipherSuite suite = iUiCipherSuites->At( i ); + TUint32 suiteId = suite.iCipherSuite; + switch ( suiteId ) + { + case 0x0004: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_PEAP_SUITE_RSARC4MD5 ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0005: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_PEAP_SUITE_RSARC4SHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x000a: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_PEAP_SUITE_RSA3DESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0016: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_PEAP_SUITE_DHERSA3DESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0013: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_PEAP_SUITE_DHEDSS3DESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x002F: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_PEAP_SUITE_RSAAESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0032: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_PEAP_SUITE_DHERSAAESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0033: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_PEAP_SUITE_DHEDSSAESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + default: + { + temp.Append( KEmptyString ); + break; + } + } + + if ( iUiCipherSuites->At( i ).iIsEnabled ) + { // Add mark icon to indicate that the suite is enabled + _LIT( KTab0, "\t0" ); + temp.Append( KTab0 ); + } + + iCipherSuitesViewArray->InsertL( listCount, temp ); + listCount++; + } + + iCipherSuiteListBox->Model()->SetItemTextArray( iCipherSuitesViewArray ); + iCipherSuiteListBox->HandleItemAdditionL(); + iCipherSuiteListBox->DrawDeferred(); + iCipherSuiteListBox->UpdateScrollBarsL(); +} + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::CheckActiveUserCertificate +// ----------------------------------------------------------------------------- +// +TInt CEapPeapUiDialog::CheckActiveUserCertificate() + { + for ( TInt i = 0; i < iUiUserCertificates->Count(); i++ ) + { + if ( iUiUserCertificates->At( i ).iIsEnabled ) + { + return i; + } + } + + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::CheckActiveCaCertificate +// ----------------------------------------------------------------------------- +// +TInt CEapPeapUiDialog::CheckActiveCaCertificate() + { + for ( TInt i = 0; iCount(); i++ ) + { + if ( iUiCACertificates->At( i ).iIsEnabled ) + { + return i; + } + } + + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::UserCertificateHouseKeeping +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::UserCertificateHouseKeeping( TInt aSelected ) + { + for ( TInt i = 0; i < iUiUserCertificates->Count(); i++ ) + { + iUiUserCertificates->At( i ).iIsEnabled = EFalse; + } + + if ( aSelected != 0 ) // Zero index is none + { + iUiUserCertificates->At( aSelected-1 ).iIsEnabled = ETrue; + } + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::CaCertificateHouseKeeping +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::CaCertificateHouseKeeping( TInt aSelected ) + { + for ( TInt i = 0; iCount() ; i++ ) + { + iUiCACertificates->At( i ).iIsEnabled = EFalse; + } + + if ( aSelected != 0 ) // Zero index is none + { + iUiCACertificates->At( aSelected-1 ).iIsEnabled = ETrue; + } + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::CreateEapTypeDataBaseL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::CreateEapTypeDataBaseL() + { + RImplInfoPtrArray eapArray; + eapArray.Reset(); + REComSession::ListImplementationsL( KEapTypeInterfaceUid, eapArray ); + TInt allowedInPeapCount( 0 ); + for ( TInt i = 0; i < eapArray.Count(); i++ ) + { + if ( !CEapType::IsDisallowedInsidePEAP( *eapArray[i] ) ) + { + CImplementationInformation* info = eapArray[i]; + TEapTlsPeapUiEapType tempEapType; + tempEapType.iEapType = info->DataType(); + + // MNOL-6RNHEX + // Only EAP-SIM and EAP-AKA should be enabled, in that order + + // BINARY RESOURCE DATA + + // [FE] [00 00 00] [TEapType_bigendian] + _LIT8( KExpEapFirstQuad, "\xFE\0\0\0" ); + TPtrC8 firstQuad( tempEapType.iEapType.Ptr(), 4 ); + // TUint32 dataType = BigEndian::Get32( tempEapType.iEapType.Ptr()+4 ); + + TUint32 dataType = ( tempEapType.iEapType[4] << 24 ) | + ( tempEapType.iEapType[5] << 16 ) | + ( tempEapType.iEapType[6] << 8 ) | + tempEapType.iEapType[7]; + + if ( !firstQuad.Compare( KExpEapFirstQuad ) && + ( dataType == EAPSettings::EEapSim || + dataType == EAPSettings::EEapAka ) ) + { + tempEapType.iIsEnabled = ETrue; + iUiEapTypes->InsertL( KFirstElement, tempEapType ); + } + else + { + tempEapType.iIsEnabled = EFalse; + iUiEapTypes->InsertL( allowedInPeapCount, tempEapType ); + } + + allowedInPeapCount++; + } + } + + __ASSERT_DEBUG( iUiEapTypes->Count() >= 2, User::Panic( _L("EAP-SIM/AKA missing"), 1) ); + + // Check if EAP-SIM and EAP-AKA are in correct order + + // BINARY RESOURCE DATA + + const TDesC8& firstEap = iUiEapTypes->At( KFirstElement ).iEapType; + const TDesC8& secondEap = iUiEapTypes->At( KSecondElement ).iEapType; + + TUint32 dataTypeFirst = ( firstEap[4] << 24 ) | + ( firstEap[5] << 16 ) | + ( firstEap[6] << 8 ) | + firstEap[7]; + TUint32 dataTypeSecond = ( secondEap[4] << 24 ) | + ( secondEap[5] << 16 ) | + ( secondEap[6] << 8 ) | + secondEap[7]; + + // If not, switch them + if ( dataTypeFirst == EAPSettings::EEapAka && + dataTypeSecond == EAPSettings::EEapSim ) + { + TEapTlsPeapUiEapType tempEapType = iUiEapTypes->At( KFirstElement ); + iUiEapTypes->Delete( KFirstElement ); + iUiEapTypes->InsertL( KSecondElement, tempEapType ); + } + + iEapTypes->Update(); + eapArray.ResetAndDestroy(); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::SetCipherIconsL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::SetCipherIconsL() + { + CArrayPtr< CGulIcon >* icons = new( ELeave ) CAknIconArray( 1 ); + CleanupStack::PushL( icons ); + + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + +/* icons->AppendL( AknsUtils::CreateGulIconL( skinInstance, + KAknsIIDQgnIndiMarkedAdd, + AknIconUtils::AvkonIconFileName(), + EMbmAvkonQgn_indi_marked_add, + EMbmAvkonQgn_indi_marked_add_mask ) ); +*/ + + CGulIcon* icon = CGulIcon::NewLC(); + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + AknsUtils::CreateColorIconL( skinInstance, + KAknsIIDQgnIndiMarkedAdd, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG13, + bitmap, + mask, + AknIconUtils::AvkonIconFileName(), + EMbmAvkonQgn_indi_marked_add, + EMbmAvkonQgn_indi_marked_add_mask, + KRgbBlack ); + icon->SetBitmap( bitmap ); + icon->SetMask( mask ); + icons->AppendL( icon ); + + CleanupStack::Pop( icon ); + CleanupStack::Pop( icons ); + + iCipherSuiteListBox->ItemDrawer()->ColumnData()->SetIconArray( icons ); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::SetEapIconsL +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::SetEapIconsL() + { + CArrayPtr< CGulIcon >* icons = new( ELeave ) CAknIconArray( 1 ); + CleanupStack::PushL( icons ); + + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + +/* icons->AppendL( AknsUtils::CreateGulIconL( skinInstance, + KAknsIIDQgnIndiMarkedAdd, + AknIconUtils::AvkonIconFileName(), + EMbmAvkonQgn_indi_marked_add, + EMbmAvkonQgn_indi_marked_add_mask ) ); +*/ + + CGulIcon* icon = CGulIcon::NewLC(); + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + AknsUtils::CreateColorIconL( skinInstance, + KAknsIIDQgnIndiMarkedAdd, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG13, + bitmap, + mask, + AknIconUtils::AvkonIconFileName(), + EMbmAvkonQgn_indi_marked_add, + EMbmAvkonQgn_indi_marked_add_mask, + KRgbBlack ); + icon->SetBitmap( bitmap ); + icon->SetMask( mask ); + icons->AppendL( icon ); + + CleanupStack::Pop( icon ); + CleanupStack::Pop( icons ); + + iEapTypesListBox->ItemDrawer()->ColumnData()->SetIconArray( icons ); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::GetEnabledEapTypeCount +// ----------------------------------------------------------------------------- +// +TUint CEapPeapUiDialog::GetEnabledEapTypeCount() + { + TUint itemCount( 0 ); + for( TInt i( 0 ); i < iUiEapTypes->Count(); ++i ) + { + if( iUiEapTypes->At( i ).iIsEnabled ) + { + ++itemCount; + } + } + return itemCount; + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::GetHelpContext +// ----------------------------------------------------------------------------- +// +void CEapPeapUiDialog::GetHelpContext(TCoeHelpContext& aContext) const + { + aContext.iMajor = KHelpUidPlugin; + TPageIds index = static_cast< TPageIds >( ActivePageIndex() ); + switch ( index ) + { + case EEapTypePage: + { + aContext.iContext = KSET_HLP_WLAN_EAP_PEAP_TYPES; + break; + } + + case ECipherSuitePage: + { + aContext.iContext = KSET_HLP_WLAN_EAP_PEAP_SUITES; + break; + } + + default: + { + aContext.iContext = KSET_HLP_WLAN_EAP_PEAP_SETT; + break; + } + } + } + + + +void CEapPeapUiDialog::GetFullCertLabelL( const SCertEntry& aCert, + TDes& aFullLabel ) + { + TInt length = 0; + + // For label. + length += aCert.iLabel.Length(); + + // For separator between label and primary name. + length += KNameSeparator.iTypeLength; + + // For primary name. + length += aCert.iPrimaryName.Length(); + + if ( !( aCert.iLabel.Length() ) ) + { + // For secondary name. + length += aCert.iSecondaryName.Length(); + } + + if( length > aFullLabel.MaxLength() ) + { +#if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapTtlsUiDialog::GetFullCertLabel - ERROR! Length Mismatch in Certificate's full name\n") ); +#endif + } + + HBufC* label = HBufC::NewL( length ); + label->Des().Append( aCert.iLabel ); + + label->Des().Append( KNameSeparator ); + label->Des().Append( aCert.iPrimaryName ); + + if ( !( aCert.iLabel.Length() ) ) + { + // Secondary name, only if no label. Certificate manager does the same way. + label->Des().Append( aCert.iSecondaryName ); + } + + aFullLabel.Copy( label->Des().Left( aFullLabel.MaxLength() ) ); + + delete label; + label = NULL; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/data/102072bb.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/data/102072bb.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: ECom resource definition for EAPPluginConfiguration. +* +*/ + + + +// INCLUDES +#include +#include "EAPPluginConfigUid.h" + + +// RESOURCE DEFINITIONS + +// --------------------------------------------------------------------------- +// +// theInfo +// Contains the ECom registration information for EAP Plugin Configuration +// +// --------------------------------------------------------------------------- +// +RESOURCE REGISTRY_INFO theInfo + { + dll_uid = EAP_PLUGIN_CONFIG_DLL_UID; + interfaces = + { + INTERFACE_INFO + { + interface_uid = EAP_PLUGIN_CONFIG_INTERFACE_UID; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = EAP_PLUGIN_CONFIG_IMPLEMENTATION_UID; + version_no = 1; + display_name = EAP_PL_CONFIG_NAME; + default_data = "EAPPConfig"; + opaque_data = ""; + } + }; + } + }; + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/data/EAPPluginConfigRes.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/data/EAPPluginConfigRes.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,160 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI resources for the EAPPluginConfig module. +* +*/ + + + +CHARACTER_SET UTF8 + +// INCLUDES +#include +#include +#include +#include + +#include "EAPPluginConfig.hrh" +#include +#include + + +// RESOURCE IDENTIFIER +NAME EPCG + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + + +RESOURCE TBUF { buf = "EAPPluginConfiguration"; } + + +RESOURCE MENU_BAR r_wpa_eap_plugin_menubar + { + titles = + { + MENU_TITLE + { + menu_pane = r_wpa_eap_plugin_menu; + } + }; + } + + +RESOURCE MENU_PANE r_wpa_eap_plugin_menu + { + items = + { + MENU_ITEM + { + command = EWPAEAPPluginCmdConfigure; + txt = qtn_wlan_options_eap_plugin_configure; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = EWPAEAPPluginCmdEnable; + txt = qtn_wlan_options_eap_plugin_enable; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = EWPAEAPPluginCmdDisable; + txt = qtn_wlan_options_eap_plugin_disable; + flags = EEikMenuItemSpecific; + }, + + MENU_ITEM + { + command = EWPAEAPPluginCmdPriorityUp; + txt = qtn_wlan_options_eap_plugin_priority_up; + flags = EEikMenuItemSpecific; + }, + + MENU_ITEM + { + command = EWPAEAPPluginCmdPriorityDown; + txt = qtn_wlan_options_eap_plugin_priority_down; + flags = EEikMenuItemSpecific; + }, + + MENU_ITEM + { + command = EAknCmdHelp; + txt = qtn_options_help; + }, + + MENU_ITEM + { + command = EAknCmdExit; + txt = qtn_options_exit; + } + }; + } + + +RESOURCE CBA r_wpa_eap_config_softkeys_options_back_configure + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EWPAEAPPluginCmdConfigure; txt = \ + qtn_msk_wlan_eap_configure; } + }; + } + + +RESOURCE CBA r_wpa_eap_config_softkeys_options_back_enable + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EWPAEAPPluginCmdEnable; txt = \ + qtn_msk_wlan_eap_cs_enable; } + }; + } + + +RESOURCE DIALOG r_wpa_eap_config_dialog + { + flags = EAknDialogSelectionList; + buttons = r_wpa_eap_config_softkeys_options_back_configure; + items = + { + DLG_LINE + { + type = EAknCtSingleNumberListBox; + id = ESelectionListControl; + control = LISTBOX + { + flags = EAknListBoxSelectionList; + }; + } + }; + } + + +RESOURCE TBUF r_info_cannot_disable + { + buf = qtn_wlan_info_cannot_disable_all_eap_plugins; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPlugInConfigurationDlg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPlugInConfigurationDlg.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,172 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declares dialog +* +*/ + + + +#ifndef __EAPPLUGINCONFIGURATIONDLG_H__ +#define __EAPPLUGINCONFIGURATIONDLG_H__ + + +// INCLUDES +#include +#include + +#include "EAPPluginList.h" + + +// FORWARD DECLARATIONS +class CAknTitlePane; +class CEAPPluginConfigurationModel; + + +// CONSTANTS +/** +* Maximum length of a SSID in BYTES +*/ +const TUint8 KMaxSSIDLength = 32; + + +// CLASS DECLARATION +/** +* CEAPPluginConfigurationDlg dialog class +*/ +class CEAPPluginConfigurationDlg : public CAknSelectionListDialog + { + public: // Constructors and destructor + + /** + * Constructor. + * @param aButtonId Button used to close the dialog + * @param aModel UI model. + */ + CEAPPluginConfigurationDlg( TInt& aButtonId, + CEAPPluginConfigurationModel& aModel, + const TUint32 iIapId ); + /** + * Create and launch dialog. + * @param aPlugins Plugin list + * @param aTitle Title of the dialog + * @return The ID of the button that closed the dialog + */ + TInt ConstructAndRunLD( const REAPPluginList& aPlugins, + const TDesC& aTitle ); + + + /** + * Destructor. + */ + ~CEAPPluginConfigurationDlg(); + + /** + * Handles list box events. + * @param aListBox The originating list box. + * @param aEventType A code for the event. + */ + void HandleListBoxEventL( CEikListBox* aListBox, TListBoxEvent aEventType ); + + + private: + + /** + * This function is called by the dialog framework before the dialog is + * sized and laid out. + */ + virtual void PreLayoutDynInitL(); + + + /** + * Handles a dialog button press for the specified button + * @param aButtonId The ID of the button that was activated. + * @return ETrue to validate and exit the dialog, + * EFalse to keep the dialog active + */ + TBool OkToExitL( TInt aButtonId ); + + + /** + * Processes user commands. + * @param aCommandId ID of the command to respond to. + */ + virtual void ProcessCommandL( TInt aCommandId ); + + + /** + * Get help context. + * @param aContext Help context is returned here. + */ + void GetHelpContext( TCoeHelpContext& aContext ) const; + + + /** + * Initialize menu pane. + * @param aResourceId Menu pane resource id. + * @param aMenuPane Menu pane. + */ + void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ); + + + /** + * Catch offered key events. + * @param aKeyEvent Key event + * @param aModifiers Modifiers + * @return EKeyWasConsumed or EKeyWasNotConsumed, appropriately. + */ + TKeyResponse OfferKeyEventL( const TKeyEvent& aKeyEvent, + TEventCode aModifiers ); + + void SetIconsL(); + void HandleResourceChange( TInt aType ); + + /** + * @see CEikDialog + */ + void HandleDialogPageEventL( TInt aEventID ); + + void ConfigureL( TBool aQuick ); + + private: //data + + // Stores the name of the connection, to be showed as the title. + TBuf iConnectionName; + + // Title pane. Not owned. + CAknTitlePane* iTitlePane; + + // Pointer to the old title. Owned. + HBufC* iOldTitleText; + + REAPPluginList iPlugins; + + TInt* iButtonId; + + // For base class, unused. + TInt iDummy; + + // UI model. Not owned. + CEAPPluginConfigurationModel* iModel; + + TUint32 iIapId; + + // For exiting dialog + TBool iExiting; + + }; + + +#endif // __EAPPLUGINCONFIGURATIONDLG_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginConfig.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginConfig.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP Plugin Configuration UI hrh file +* +*/ + + +#ifndef _EAPPLUGINCONFIG_HRH_ +#define _EAPPLUGINCONFIG_HRH_ + +enum TEapPluginConfigMenuCommands + { + EWPAEAPPluginCmdConfigure = 1000, + EWPAEAPPluginCmdEnable, + EWPAEAPPluginCmdDisable, + EWPAEAPPluginCmdPriorityUp, + EWPAEAPPluginCmdPriorityDown + }; + + +#endif //_EAPPLUGINCONFIG_HRH_ + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginConfigUid.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginConfigUid.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UIDs +* +*/ + + + +#ifndef _EAPPLUGINCONFIGUID_H_ +#define _EAPPLUGINCONFIGUID_H_ + + +// CONSTANTS +#define EAP_PLUGIN_CONFIG_DLL_UID 0x102072BB + +#define EAP_PLUGIN_CONFIG_INTERFACE_UID 0x102072CA + +#define EAP_PLUGIN_CONFIG_IMPLEMENTATION_UID 0x102072C9 + + +#endif // _EAPPLUGINCONFIGUID_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginConfiguration.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginConfiguration.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,132 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP Plugin Configuration +* +*/ + + +#ifndef __EAPPLUGINCONFIGURATION_H__ +#define __EAPPLUGINCONFIGURATION_H__ + + +// INCLUDES +#include + +#include "EAPPluginConfigurationIf.h" +#include "EAPPluginConfigUid.h" +#include "EAPPluginList.h" +#include "EapSettings.h" + + +// CLASS DECLARATION +/** +* CEAPPluginConfiguration class +*/ +class CEAPPluginConfiguration : public CEAPPluginConfigurationIf + { + public: + static CEAPPluginConfiguration* NewL(); + static CEAPPluginConfiguration* NewLC(); + + ~CEAPPluginConfiguration(); + + /** + * Load the EAP Plugin configuration + * @param aWPAEAPPlugin The list of EAPs in use as it was read from + * WlanEapList column of WLANServiceTable. In + * output it contains the new list as it has + * to be written in the same column of + * database. + * @param aConnectionName The name of the connection. + * @return The ID of the button pressed to close configuration: + * typically EAknSoftkeyBack for back, EAknCmdExit for a + * request of exit or EEikCmdExit for a request of shutdown + */ + TInt EAPPluginConfigurationL( TDes& aWPAEAPPlugin, + const TUint32 aIapID, + const TDes& aConnectionName ); + + /** + * Load the EAP Plugin configuration (with expanded EAP types) + * @param aWPAEnabledEAPPlugin The list of enabled EAPs in use as + * it was read from WlanEnabledEapList column + * of WLANServiceTable. In output it contains + * the new list as it has to be written in the + * same column of database. + * @param aWPADisabledEAPPlugin The list of disabled EAPs in use as + * it was read from WlanDisabledEapList column + * of WLANServiceTable. In output it contains + * the new list as it has to be written in the + * same column of database. + * @param aConnectionName The name of the connection. + * @return The ID of the button pressed to close configuration: + * typically EAknSoftkeyBack for back, EAknCmdExit for a + * request of exit or EEikCmdExit for a request of shutdown + */ + TInt EAPPluginConfigurationL( TDes8& aWPAEnabledEAPPlugin, + TDes8& aWPADisabledEAPPlugin, + const TUint32 aIapID, + const TDes& aConnectionName ); + + /** + * Shows the EAP type info. + */ + void ShowEAPTypeInfo(); + + /** + * Deletes all EAP types' settings for + * the given IAP. + */ + void DeleteSettingsL( const TUint32 aIapID ); + + /** + * Changes the index of the EAP settings for all EAP types + */ + void ChangeIapIDL( const TUint32 aOldIapID, const TUint32 aNewIapID ); + + /** + * Copies the EAP type settings to another ID + */ + void CopySettingsL( const TUint32 aSourceIapID, + const TUint32 aDestinationIapID ); + + private: + void ConstructL(); + CEAPPluginConfiguration(); + void LoadPluginInfoL( TDes& aWPAEAPPlugin, REAPPluginList& aPlugins ); + void LoadPluginInfoL( TDes8& aWPAEnabledEAPPlugin, + TDes8& aWPADisabledEAPPlugin, + REAPPluginList& aPlugins ); + + void SavePluginInfoL( TDes& aWPAEAPPlugin, REAPPluginList& aPlugins ); + void SavePluginInfoL( TDes8& aWPAEnabledEAPPlugin, + TDes8& aWPADisabledEAPPlugin, + REAPPluginList& aPlugins ); + + + TInt MoveEAPType( EAPSettings::TEapType aEapType, TInt aPos ); + + TInt MoveEAPType( const TDesC8& aEapType, TInt aPos ); + + private: // Data + // Resource file offset. + TInt iResOffset; + TUint32 iIapId; + RImplInfoPtrArray iEapArray; + }; + + +#endif // __EAPPLUGINCONFIGURATION_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginConfigurationModel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginConfigurationModel.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of class CEAPPluginConfigurationModel. +* +*/ + + + +#ifndef __EAPPLUGINCONFIGURATIONMODEL_H__ +#define __EAPPLUGINCONFIGURATIONMODEL_H__ + +// INCLUDES +#include +#include + + +// FORWARD DECLARATION +class REAPPluginList; + + +// CLASS DECLARATION + +/** +* UI model for WPA Security Settings UI. +* This class formats real data so it can be displayed in the listbox. +*/ +class CEAPPluginConfigurationModel : public CBase, + public MDesCArray + { + public: // Constructors and destructor + /** + * Constructor. + * @param aPlugins Plugin list. + */ + inline CEAPPluginConfigurationModel( const REAPPluginList& aPlugins ); + + + public: // from MDesCArray + /** + * Get number of elements in the descriptor array. + * @return The number of elements in the descriptor array. + */ + TInt MdcaCount() const; + + /** + * Index into the descriptor array. + * @param aIndex Index. + * @return Descriptor at position aIndex. + */ + TPtrC16 MdcaPoint( TInt aIndex ) const; + + + public: // new functions + TInt MdcaEnabledCount() const; + + + private: // types + enum + { + EBufSize = 128 ///< Formatting buffer size. + }; + + private: // data + const REAPPluginList& iPlugins; ///< Plugins. + __MUTABLE TBuf iBuf; ///< Formatting buffer. + + }; + +#include "EAPPluginConfigurationModel.inl" + +#endif // __EAPPLUGINCONFIGURATIONMODEL_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginConfigurationModel.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginConfigurationModel.inl Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Inline method definitions of CEAPPluginConfigurationModel. +* +*/ + + + +#ifndef __EAPPLUGINCONFIGURATIONMODEL_INL__ +#define __EAPPLUGINCONFIGURATIONMODEL_INL__ + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CEAPPluginConfigurationModel::CEAPPluginConfigurationModel +// --------------------------------------------------------- +// +CEAPPluginConfigurationModel::CEAPPluginConfigurationModel( + const REAPPluginList& aPlugins ) +: iPlugins( aPlugins ) + { + } + + +#endif // __EAPPLUGINCONFIGURATIONMODEL_INL__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginInfo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginInfo.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of class TEAPPluginInfo. +* +*/ + + + +#ifndef __EAPPLUGININFO_H__ +#define __EAPPLUGININFO_H__ + +// INCLUDES +#include + + +// FORWARD DECLARATIONS +class CImplementationInformation; + + +// CLASS DECLARATION + +/** +* Information for EAP plug-ins. +*/ +struct TEAPPluginInfo + { + public: // Data + const CImplementationInformation* iInfo; ///< Impl. info. Not own. + TBool iEnabled; ///< ETrue if enabled. + }; + +#endif // __EAPPLUGININFO_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginList.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/inc/EAPPluginList.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of class REAPPluginList. +* +*/ + + + +#ifndef __EAP_PLUGIN_LIST_H__ +#define __EAP_PLUGIN_LIST_H__ + +// INCLUDES +#include +#include "EAPPluginInfo.h" + + +// CLASS DECLARATION + +/** +* Plugin info list. +*/ +class REAPPluginList: public RArray + { + public: // New methods + /** + * Change plugin position (reorder). + * @param aOldPos Current position of plugin. Must be a valid index. + * @param aOldPos New position of plugin. Must be a valid index. + */ + void MovePos( TInt aOldPos, TInt aNewPos ); + }; + +#endif // __EAP_PLUGIN_LIST_H__ + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPlugInConfigurationDlg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPlugInConfigurationDlg.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,615 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP Plugin Configuration dialog +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "EAPPluginConfig.hrh" + +#include + +#include "EAPPluginList.h" +#include "EAPPlugInConfigurationDlg.h" +#include "EAPPluginConfigurationModel.h" + + +#include +#include +#include +#include + + +// CONSTANTS +// UID of general settings app, in which help texts are included +const TUid KHelpUidPlugin = { 0x100058EC }; + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::CEAPPluginConfigurationDlg +// --------------------------------------------------------- +// +CEAPPluginConfigurationDlg::CEAPPluginConfigurationDlg( TInt& aButtonId, + CEAPPluginConfigurationModel& aModel, + const TUint32 aIapId ) +: CAknSelectionListDialog( iDummy, &aModel, NULL ), + iButtonId( &aButtonId ), + iModel( &aModel ), + iIapId( aIapId ), + iExiting( EFalse ) + { + // Passing a dummy (iDummy) for selection index. + // Base class was made for 'select and dismiss' behaviour only, and does + // not work properly in our case (when only "Back" press dismissed the + // dialog and more selections are possible). + // + // iModel (the UI model) should really be owned by this dialog, but + // can't do that due to the malformed API of CAknSelectionListDialog. + } + + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::~CEAPPluginConfigurationDlg +// --------------------------------------------------------- +// +CEAPPluginConfigurationDlg::~CEAPPluginConfigurationDlg() + { + if ( iTitlePane ) + { + // set old text back, if we have it... + if ( iOldTitleText ) + { + TRAP_IGNORE( iTitlePane->SetTextL( *iOldTitleText ) ); + delete iOldTitleText; + } + } + + FeatureManager::UnInitializeLib(); + } + + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::ConstructAndRunLD +// --------------------------------------------------------- +// +TInt CEAPPluginConfigurationDlg::ConstructAndRunLD( + const REAPPluginList& aPlugins, + const TDesC& aTitle ) + { + CleanupStack::PushL( this ); + + iPlugins = aPlugins; + iConnectionName = aTitle; + + FeatureManager::InitializeLibL(); + + ConstructL( R_WPA_EAP_PLUGIN_MENUBAR ); + + // ExecuteLD will PushL( this ), so we have to Pop it... + CleanupStack::Pop( this ); // this + + return CAknSelectionListDialog::ExecuteLD( R_WPA_EAP_CONFIG_DIALOG ); + } + + + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::OkToExitL +// --------------------------------------------------------- +// +TBool CEAPPluginConfigurationDlg::OkToExitL( TInt aButtonId ) + { + // Translate the button presses into commands for the appui & current + // view to handle + TBool retval( EFalse ); + if ( aButtonId == EAknSoftkeyOptions ) + { + DisplayMenuL(); + } + else if ( aButtonId == EEikCmdExit || + aButtonId == EAknCmdExit || + aButtonId == EAknSoftkeyBack ) + { + *iButtonId = aButtonId; + retval = ETrue; + } + else if( aButtonId == EWPAEAPPluginCmdConfigure ) + { + ProcessCommandL( aButtonId ); + } + else if( aButtonId == EWPAEAPPluginCmdEnable ) + { + ProcessCommandL( aButtonId ); + } + + + return retval; + } + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::HandleListBoxEventL +// --------------------------------------------------------- +// +void CEAPPluginConfigurationDlg::HandleListBoxEventL( CEikListBox* /*aListBox*/, + TListBoxEvent aEventType ) + { + switch ( aEventType ) + { + case EEventEnterKeyPressed: + case EEventItemSingleClicked: + { + TInt current = ListBox()->CurrentItemIndex(); + if ( iPlugins[current].iEnabled ) + { + ConfigureL(ETrue); + } + else + { + ProcessCommandL( EWPAEAPPluginCmdEnable ); + } + break; + } + + case EEventItemActioned: + case EEventEditingStarted: + case EEventEditingStopped: + case EEventPenDownOnItem: + case EEventItemDraggingActioned: + { + break; + } + + default: + { + break; + }; + }; + } + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::HandleDialogPageEventL +// --------------------------------------------------------- +// +void CEAPPluginConfigurationDlg::HandleDialogPageEventL( TInt aEventID ) + { + CAknDialog::HandleDialogPageEventL( aEventID ); + if( iExiting ) + { + // Exit requested, exit with ok. + TryExitL( EAknCmdExit ); + } + + } + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::ConfigureL +// --------------------------------------------------------- +// +void CEAPPluginConfigurationDlg::ConfigureL( TBool aQuick ) + { + CEapType* eapType = CEapType::NewL( + iPlugins[ListBox()->CurrentItemIndex()].iInfo->DataType(), + ELan, + iIapId ); + + CleanupStack::PushL( eapType ); + + TInt buttonId = eapType->InvokeUiL(); + CleanupStack::PopAndDestroy( eapType ); + + if ( buttonId == EAknCmdExit || buttonId == EEikCmdExit ) + { + if (aQuick == EFalse) + { + TryExitL( buttonId ); + } + else + { + iExiting = ETrue; + // Don't exit here. Framework command chain will + // cause a KERN-EXEC 3 panic. Handle the exit in + // HandleDialogPageEventL(). + } + } + } + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::ProcessCommandL +// --------------------------------------------------------- +// +void CEAPPluginConfigurationDlg::ProcessCommandL( TInt aCommandId ) + { + if ( MenuShowing() ) + { + HideMenu(); + } + + switch ( aCommandId ) + { + case EAknCmdOpen: + case EWPAEAPPluginCmdConfigure: + { + ConfigureL(EFalse); + break; + } + + case EWPAEAPPluginCmdEnable: + { + TInt cur = ListBox()->CurrentItemIndex(); + iPlugins[cur].iEnabled = ETrue; + + // enabling moves item to the top of the list + iPlugins.MovePos( cur, 0 ); + + // Highlight follows movement. + ListBox()->SetCurrentItemIndex( 0 ); + + // load the new CBA from resource + ButtonGroupContainer().SetCommandSetL( + R_WPA_EAP_CONFIG_SOFTKEYS_OPTIONS_BACK_CONFIGURE ); + ButtonGroupContainer().DrawDeferred(); + DrawNow(); + break; + } + + case EWPAEAPPluginCmdDisable: + { + if ( iModel->MdcaEnabledCount() > 1 ) + { + TInt cur = ListBox()->CurrentItemIndex(); + + // disabling moves item just after the last enabled one, + // so find that position + TInt next = cur; + + while ( next < iModel->MdcaCount() - 1 && + iPlugins[next].iEnabled ) + { + ++next; + } + + if ( next > cur && !iPlugins[next].iEnabled ) + { + --next; + } + + + iPlugins[cur].iEnabled = EFalse; + + // move item if needed + iPlugins.MovePos( cur, next ); + + // Highlight follows movement. + ListBox()->SetCurrentItemIndex( next ); + + // load the new CBA from resource + ButtonGroupContainer().SetCommandSetL( + R_WPA_EAP_CONFIG_SOFTKEYS_OPTIONS_BACK_ENABLE ); + ButtonGroupContainer().DrawDeferred(); + DrawNow(); + } + else + { + HBufC* stringLabel; + + stringLabel = StringLoader::LoadL( R_INFO_CANNOT_DISABLE, + iEikonEnv ); + + CleanupStack::PushL( stringLabel ); + + CAknInformationNote* dialog = new ( ELeave ) + CAknInformationNote( ETrue ); + dialog->ExecuteLD( *stringLabel ); + + CleanupStack::PopAndDestroy( stringLabel ); + } + + break; + } + + case EWPAEAPPluginCmdPriorityUp: + { + TInt cur = ListBox()->CurrentItemIndex(); + iPlugins.MovePos( cur, cur - 1 ); + + // Highlight follows movement. + ListBox()->SetCurrentItemIndexAndDraw( cur - 1 ); + break; + } + + case EWPAEAPPluginCmdPriorityDown: + { + TInt cur = ListBox()->CurrentItemIndex(); + + iPlugins.MovePos( cur, cur + 1 ); + // Highlight follows movement. + ListBox()->SetCurrentItemIndexAndDraw( cur + 1 ); + + break; + } + + case EAknCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + iEikonEnv->EikAppUi()->AppHelpContextL() ); + break; + } + + case EAknSoftkeyBack: + case EAknCmdExit: + case EEikCmdExit: + { + TryExitL( aCommandId ); + break; + } + + default: + { + CAknSelectionListDialog::ProcessCommandL( aCommandId ); + break; + } + } + } + + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::PreLayoutDynInitL +// --------------------------------------------------------- +// +void CEAPPluginConfigurationDlg::PreLayoutDynInitL() + { + CAknSelectionListDialog::PreLayoutDynInitL(); + + // first get StatusPane + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + + // then get TitlePane + iTitlePane = ( CAknTitlePane* ) statusPane->ControlL( TUid::Uid( + EEikStatusPaneUidTitle ) ); + // if not already stored, store it for restoring + if ( !iOldTitleText ) + { + iOldTitleText = iTitlePane->Text()->AllocL(); + } + + // set new titlepane text + iTitlePane->SetTextL( iConnectionName ); + + SetIconsL(); + } + + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::SetIconsL() +// --------------------------------------------------------- +// +void CEAPPluginConfigurationDlg::SetIconsL() + { + CArrayPtr< CGulIcon >* icons = new( ELeave ) CAknIconArray( 1 ); + CleanupStack::PushL( icons ); + + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + + CGulIcon* icon = CGulIcon::NewLC(); + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + AknsUtils::CreateColorIconL( skinInstance, + KAknsIIDQgnIndiMarkedAdd, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG13, + bitmap, + mask, + AknIconUtils::AvkonIconFileName(), + EMbmAvkonQgn_indi_marked_add, + EMbmAvkonQgn_indi_marked_add_mask, + KRgbBlack ); + icon->SetBitmap( bitmap ); + icon->SetMask( mask ); + icons->AppendL( icon ); + + CleanupStack::Pop( icon ); + + SetIconArrayL( icons ); + + CleanupStack::Pop( icons ); + } + + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::DynInitMenuPaneL +// --------------------------------------------------------- +// +void CEAPPluginConfigurationDlg::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + CAknSelectionListDialog::DynInitMenuPaneL( aResourceId, aMenuPane ); + if ( aMenuPane && aResourceId == R_WPA_EAP_PLUGIN_MENU ) + { + if ( !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + if ( !iModel->MdcaCount() ) + { + // if no plug-ins then dim the whole menu. + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdConfigure, ETrue ); + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdEnable, ETrue ); + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdDisable, ETrue ); + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdPriorityUp, ETrue ); + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdPriorityDown, ETrue ); + } + else + { + TInt current = ListBox()->CurrentItemIndex(); + TBool enabled = iPlugins[current].iEnabled; + + // Hide either "Enable" or "Disable", as appropriate. + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdEnable, enabled ); + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdDisable, !enabled ); + + // Don't display "Configure" for disabled items + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdConfigure, !enabled ); + + // Don't display "Raise priority" nor "Lower priority" for + // disabled items + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdPriorityUp, !enabled ); + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdPriorityDown, !enabled ); + + + if ( enabled ) + { + if ( current == 0 ) + { + // Can't go higher than top. + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdPriorityUp, + ETrue ); + } + + if ( current == iModel->MdcaCount() - 1 || + ( current < iModel->MdcaCount() - 1 && + !iPlugins[current + 1].iEnabled ) ) + { + // Can't go lower than the last enabled item + aMenuPane->SetItemDimmed( EWPAEAPPluginCmdPriorityDown, + ETrue ); + } + } + } + } + } + + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::OfferKeyEventL +// --------------------------------------------------------- +// +TKeyResponse CEAPPluginConfigurationDlg::OfferKeyEventL( + const TKeyEvent& aKeyEvent, + TEventCode aType ) + { + TKeyResponse result( EKeyWasNotConsumed ); + + if ( aType == EEventKey ) + { + + // Exit handling + if ( aKeyEvent.iCode == EKeyEscape ) + { + TryExitL( EEikCmdExit ); + return EKeyWasConsumed; + } + + TInt current = ListBox()->CurrentItemIndex(); + + // Handle Enter key here, since it doesn't seem to convert into + // the proper command id via the normal route + // (maybe some Avkon support for Enter key is still missing in + // S60 3.2 2008_wk22) + if ( aKeyEvent.iCode == EKeyEnter ) + { + if ( iPlugins[current].iEnabled ) + { + OkToExitL( EWPAEAPPluginCmdConfigure ); + } + else + { + OkToExitL( EWPAEAPPluginCmdEnable ); + } + + result = EKeyWasConsumed; + } + else + { + result = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + + TInt next = ListBox()->CurrentItemIndex(); + + if ( current != next && + ( iPlugins[current].iEnabled && !iPlugins[next].iEnabled || + !iPlugins[current].iEnabled && iPlugins[next].iEnabled ) ) + { + // status is different, the CBA must be changed + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + + // load the new set from resource + if ( iPlugins[next].iEnabled ) + { + cba.SetCommandSetL( + R_WPA_EAP_CONFIG_SOFTKEYS_OPTIONS_BACK_CONFIGURE ); + } + else + { + cba.SetCommandSetL( + R_WPA_EAP_CONFIG_SOFTKEYS_OPTIONS_BACK_ENABLE ); + } + + cba.DrawDeferred(); + } + } + else + { + // pass event up the hierarchy + result = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + + + + return result; + } + + +// ---------------------------------------------------------------------------- +// CEAPPluginConfigurationDlg::HandleResourceChange +// ---------------------------------------------------------------------------- +// +void CEAPPluginConfigurationDlg::HandleResourceChange( TInt aType ) + { + CAknSelectionListDialog::HandleResourceChange( aType ); + + if ( aType == KAknsMessageSkinChange ) + { + TRAP_IGNORE( SetIconsL() ); + SizeChanged(); + } + } + + +// --------------------------------------------------------- +// CEAPPluginConfigurationDlg::GetHelpContext +// --------------------------------------------------------- +// +void CEAPPluginConfigurationDlg::GetHelpContext( + TCoeHelpContext& aContext ) const + { + aContext.iMajor = KHelpUidPlugin; + aContext.iContext = KSET_HLP_WLAN_EAP_PLUGINS_IAP; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPlugInConfigurationModel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPlugInConfigurationModel.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,106 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CEAPPlugInConfigurationModel +* +*/ + + + +// INCLUDE FILES +#include "EAPPluginConfigurationModel.h" +#include "EAPPluginList.h" +#include + + +// CONSTANTS + +// Format text for MdcaPoint when Enabled +_LIT( KFormatEnabled, "%d\t%S\t%d\t" ); + +// Format text for MdcaPoint when Disabled +_LIT( KFormatDisabled, "\t%S\t\t" ); + + +/** +* Maximum length of the formatted text excluding the name. +* (I.e. if the name is trimmed to this length, there will not be overflow.) +* Includes the formatting tabs (3), the icon index length (1) plus maximum +* length of an integer (11). +*/ +LOCAL_D const TInt KMaxLenForEmptyName = 15; + + +// ============================ MEMBER FUNCTIONS =============================== + +// --------------------------------------------------------- +// CEAPPluginConfigurationModel::MdcaCount +// --------------------------------------------------------- +// +TInt CEAPPluginConfigurationModel::MdcaCount() const + { + return iPlugins.Count(); + } + + +// --------------------------------------------------------- +// CEAPPluginConfigurationModel::MdcaPoint +// --------------------------------------------------------- +// +TPtrC16 CEAPPluginConfigurationModel::MdcaPoint( TInt aIndex ) const + { + // Oddly enough, MdcaPoint is const. We need to use MUTABLE_CAST. + TInt maxName = EBufSize - KMaxLenForEmptyName; + TPtrC name( iPlugins[aIndex].iInfo->DisplayName() ); + if ( name.Length() > maxName ) + { + name.Set( name.Left( maxName ) ); + } + + if ( iPlugins[aIndex].iEnabled ) + { + MUTABLE_CAST( TBuf&, iBuf ).Format( KFormatEnabled, + aIndex+1, &name, 0 ); + } + else + { + MUTABLE_CAST( TBuf&, iBuf ).Format( KFormatDisabled, &name ); + } + + return iBuf; + } + + +// --------------------------------------------------------- +// CEAPPluginConfigurationModel::MdcaEnabledCount +// --------------------------------------------------------- +// +TInt CEAPPluginConfigurationModel::MdcaEnabledCount() const + { + TInt index; + TInt nPlugins = MdcaCount(); + TInt numEnabled = 0; + + for ( index = 0; index < nPlugins; index++ ) + { + if ( iPlugins[index].iEnabled ) + { + numEnabled++; + } + } + + return numEnabled; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPluginConfiguration.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPluginConfiguration.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,834 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP Plugin Configuration +* +*/ + + + +// INCLUDE FILES +#include "EAPPluginConfiguration.h" +#include "EAPPlugInConfigurationDlg.h" +#include "EAPPluginConfigurationModel.h" +#include +#include +#include "EAPPluginList.h" + +#include +#include +#include + +// CONSTANTS +_LIT( KDriveZ, "z:" ); // ROM folder +_LIT( KResourceFileName, "EAPPluginConfigRes.rsc" ); // RSC file name. +_LIT( KSpace, " " ); +_LIT( KPlusSign, "+" ); +_LIT( KMinusSign, "-" ); +_LIT( KComma, "," ); + + +// Length of the UID +static const TInt KLengthOfImplUid = 3; + +// Length of expanded EAP type (RFC 3748) +static const TInt KLengthOfExpEapType = 8; + + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEAPPluginConfiguration::CEAPPluginConfiguration +// ----------------------------------------------------------------------------- +// +CEAPPluginConfiguration::CEAPPluginConfiguration() +: iIapId( 0 ) + { + } + + +// ----------------------------------------------------------------------------- +// CEAPPluginConfiguration::NewL +// ----------------------------------------------------------------------------- +// +CEAPPluginConfiguration* CEAPPluginConfiguration::NewL() + { + CEAPPluginConfiguration* self = NewLC(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEAPPluginConfiguration::NewLC +// ----------------------------------------------------------------------------- +// +CEAPPluginConfiguration* CEAPPluginConfiguration::NewLC() + { + CEAPPluginConfiguration* self = new( ELeave )CEAPPluginConfiguration(); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEAPPluginConfiguration::ConstructL +// ----------------------------------------------------------------------------- +// +void CEAPPluginConfiguration::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CEAPPluginConfiguration::~CEAPPluginConfiguration +// ----------------------------------------------------------------------------- +// +CEAPPluginConfiguration::~CEAPPluginConfiguration() + { + iEapArray.ResetAndDestroy(); + CCoeEnv::Static()->DeleteResourceFile( iResOffset ); + } + + +// --------------------------------------------------------- +// CEAPPluginConfiguration::EAPPluginConfigurationL +// --------------------------------------------------------- +// +TInt CEAPPluginConfiguration::EAPPluginConfigurationL( TDes& aWPAEAPPlugin, + const TUint32 aIapId, + const TDes& aConnectionName ) + { + // Adding the resource file to the CoeEnv. + if( !iResOffset ) + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + BaflUtils::NearestLanguageFile( CCoeEnv::Static()->FsSession(), + fileName ); + + TRAP_IGNORE( iResOffset = + CCoeEnv::Static()->AddResourceFileL( fileName ); ); + } + + TInt buttonId; + + REAPPluginList plugins; ///< Plug-in infos. + + LoadPluginInfoL( aWPAEAPPlugin, plugins ); + CEAPPluginConfigurationModel* model = new( ELeave ) + CEAPPluginConfigurationModel( plugins ); + CleanupStack::PushL( model ); + + CEAPPluginConfigurationDlg* pluginDlg = new( ELeave ) + CEAPPluginConfigurationDlg( buttonId, *model, aIapId ); + + pluginDlg->ConstructAndRunLD( plugins, aConnectionName ); + + SavePluginInfoL( aWPAEAPPlugin, plugins ); + + CleanupStack::PopAndDestroy( model ); + plugins.Close(); + + iIapId = aIapId; + + return buttonId; + } + + +// --------------------------------------------------------- +// CEAPPluginConfiguration::EAPPluginConfigurationL +// --------------------------------------------------------- +// +TInt CEAPPluginConfiguration::EAPPluginConfigurationL( + TDes8& aWPAEnabledEAPPlugin, + TDes8& aWPADisabledEAPPlugin, + const TUint32 aIapId, + const TDes& aConnectionName ) + { + // Adding the resource file to the CoeEnv. + if( !iResOffset ) + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + BaflUtils::NearestLanguageFile( CCoeEnv::Static()->FsSession(), + fileName ); + + TRAP_IGNORE( iResOffset = + CCoeEnv::Static()->AddResourceFileL( fileName ); ); + } + + + TInt buttonId; + + REAPPluginList plugins; ///< Plug-in infos. + + LoadPluginInfoL( aWPAEnabledEAPPlugin, aWPADisabledEAPPlugin, plugins ); + CEAPPluginConfigurationModel* model = new( ELeave ) + CEAPPluginConfigurationModel( plugins ); + CleanupStack::PushL( model ); + + CEAPPluginConfigurationDlg* pluginDlg = new( ELeave ) + CEAPPluginConfigurationDlg( buttonId, *model, aIapId ); + + pluginDlg->ConstructAndRunLD( plugins, aConnectionName ); + + SavePluginInfoL( aWPAEnabledEAPPlugin, aWPADisabledEAPPlugin, plugins ); + + CleanupStack::PopAndDestroy( model ); + plugins.Close(); + + iIapId = aIapId; + + return buttonId; + } + + +// --------------------------------------------------------- +// CEAPPluginConfiguration::LoadPluginInfoL +// --------------------------------------------------------- +// +void CEAPPluginConfiguration::LoadPluginInfoL( TDes& aWPAEAPPlugin, + REAPPluginList& aPlugins ) + { + TInt posComma = aWPAEAPPlugin.Locate( ',' ); + while ( posComma != KErrNotFound ) // Extract the parameters + { + aWPAEAPPlugin.Replace( posComma, 1, KSpace ); + posComma = aWPAEAPPlugin.Locate( ',' ); + } + + TLex lex( aWPAEAPPlugin ); + + CArrayFixFlat* params; // array of parameters + params = new( ELeave ) CArrayFixFlat( sizeof( TPtrC ) ); + CleanupStack::PushL( params ); + + while ( !lex.Eos() ) // Extract the parameters + { + params->AppendL( lex.NextToken() ); + } + + aPlugins.Reset(); // Reset this first: dependent on iEapArray. + iEapArray.ResetAndDestroy(); + REComSession::ListImplementationsL( KEapTypeInterfaceUid, iEapArray ); + + // EAP plugin interface dialog should show only the EAP types that allowed + // outside PEAP. + + for( TInt count = 0; count < iEapArray.Count(); count++ ) + { + // Filter out the EAP types which are NOT allowed outside PEAP. + if( CEapType::IsDisallowedOutsidePEAP( *iEapArray[count] ) ) + { + // Delete the EAP type, which isn't allowed outside PEAP, + // from the array. + delete iEapArray[count]; + iEapArray.Remove( count ); + + // One item removed from the array. So reduce the item count. + count--; + } + } + + TInt numParams = params->Count(); + TBool foundDefaultEAPTypes = EFalse; + + // Rearrange the array so that EAP-SIM and EAP-AKA are on top, in that order. + + // The rearrange is needed only for the first time creation. + if ( numParams == 0 ) + { + TInt topPos = 0; // position in the beginning of arrary. + TInt error( KErrNone ); + + // First move EAP-AKA to top, if it is present in the array. + error = MoveEAPType( EAPSettings::EEapAka, topPos ); + + if ( error != KErrNotFound ) + { + // Found EAP-AKA in the array. + // Doesn't matter if the move was a success or not. + foundDefaultEAPTypes = ETrue; + } + + // Now move EAP-SIM to top. + // EAP-SIM will be always the top most if it is present in the array. + // Otherwise EAP-AKA stays in the top, if it is present. + // The order doesn't matter if these two are not present. + MoveEAPType( EAPSettings::EEapSim, topPos ); + + if( error != KErrNotFound) + { + // Found EAP-SIM in the array. + // Doesn't matter if the move was a success. + foundDefaultEAPTypes = ETrue; + } + } + + TInt i; + TInt j; + TInt numInfoStore = iEapArray.Count(); + TInt eapUid; + + // just to make sure we are not given a non-empty but fully disabled list + TBool gotEnabled = EFalse; + + CArrayFix* usedImplInfo = new( ELeave ) CArrayFixFlat( 4 ); + CleanupStack::PushL( usedImplInfo ); + usedImplInfo->AppendL( 0, numInfoStore ); + + for ( j = 0; j < numParams; j++ ) + { + TLex lexUid( params->At( j ) ); + if ( lexUid.Val( eapUid ) == KErrNone ) + { + for ( i = 0; i < numInfoStore; i++ ) + { + TLex8 lexDataType( iEapArray[i]->DataType() ); + TInt implUID; + + if ( lexDataType.Val( implUID ) == KErrNone ) + { + if ( implUID == Abs( eapUid ) ) + { + usedImplInfo->InsertL( i, 1 ); + if ( i+1 < usedImplInfo->Count() ) + { + usedImplInfo->Delete( i+1 ); + } + + TEAPPluginInfo plugin; + plugin.iInfo = iEapArray[i]; + + plugin.iEnabled = ( eapUid > 0 || + ( eapUid == 0 && + params->At( j ).Left( 1 ) == KPlusSign ) ); + User::LeaveIfError( aPlugins.Append( plugin ) ); + gotEnabled = gotEnabled || plugin.iEnabled; + i = numInfoStore; // to exit from cycle + } + } + } + } + } + + for ( i = 0; i < numInfoStore; i++ ) + { + if ( !usedImplInfo->At( i ) ) + { + TEAPPluginInfo plugin; + plugin.iInfo = iEapArray[i]; + + // Default is enabled. + // There should not be a case of all EAP types disabled. + TBool defaultEnableValue( ETrue ); + + if ( numParams > 0 && gotEnabled) + { + // If there some EAP types which are already enabled/disabled, + // we make the new EAP types disabled. + defaultEnableValue = EFalse; + } + else + { + // Nothing in the string or all disabled. + // Should be the first time execution (creating new IAP). + // Only EAP-SIM and EAP-AKA are enabled in this case. + TLex8 lexDataType( iEapArray[i]->DataType() ); + TInt implDataType; + + if ( lexDataType.Val( implDataType ) == KErrNone ) + { + if( foundDefaultEAPTypes ) + { + defaultEnableValue = + ( implDataType == EAPSettings::EEapSim || + implDataType == EAPSettings::EEapAka ); + } + else + { + // No default EAPs (No EAP-SIM and EAP-AKA). + // So all EAP types are enabled by default. + defaultEnableValue = ETrue; + } + } + } + + plugin.iEnabled = defaultEnableValue; + User::LeaveIfError( aPlugins.Append( plugin ) ); + } + } + + CleanupStack::PopAndDestroy( 2, params ); // usedImplInfo, params + } + + +// --------------------------------------------------------- +// CEAPPluginConfiguration::LoadPluginInfoL +// --------------------------------------------------------- +// +void CEAPPluginConfiguration::LoadPluginInfoL( TDes8& aWPAEnabledEAPPlugin, + TDes8& aWPADisabledEAPPlugin, + REAPPluginList& aPlugins ) + { + // size of aWPAEnabledEAPPlugin and aWPADisabledEAPPlugin must be + // divisible by KLengthOfExpEapType + __ASSERT_DEBUG( ( aWPAEnabledEAPPlugin.Size() % KLengthOfExpEapType == 0 ), + User::Panic( _L( "aWPAEnabledEAPPlugin is corrupted!" ), KErrCorrupt ) ); + + __ASSERT_DEBUG( ( aWPADisabledEAPPlugin.Size() % KLengthOfExpEapType == 0 ), + User::Panic( _L( "aWPADisabledEAPPlugin is corrupted!" ), KErrCorrupt ) ); + + + aPlugins.Reset(); // Reset this first: dependent on iEapArray. + iEapArray.ResetAndDestroy(); + REComSession::ListImplementationsL( KEapTypeInterfaceUid, iEapArray ); + + // EAP plugin interface dialog should show only the EAP types that allowed + // outside PEAP. + + for( TInt count = 0; count < iEapArray.Count(); count++ ) + { + // Filter out the EAP types which are NOT allowed outside PEAP. + if( CEapType::IsDisallowedOutsidePEAP( *iEapArray[count] ) ) + { + // Delete the EAP type, which isn't allowed outside PEAP, + // from the array. + delete iEapArray[count]; + iEapArray.Remove( count ); + + // One item removed from the array. So reduce the item count. + count--; + } + } + + TInt numEnabled = aWPAEnabledEAPPlugin.Size() / KLengthOfExpEapType; + TInt numDisabled = aWPADisabledEAPPlugin.Size() / KLengthOfExpEapType; + TBool foundDefaultEAPTypes = EFalse; + + // Rearrange the array so that EAP-SIM and EAP-AKA are on top, in that order. + + // The rearrange is needed only for the first time creation. + if ( !( numEnabled || numDisabled ) ) + { + TInt topPos = 0; // position in the beginning of array. + TInt error( KErrNone ); + + // First move EAP-AKA to top, if it is present in the array. + _LIT8( KExpEapTypeFormat, "\xFE\0\0\0%c%c%c%c" ); + TBuf8 tmpEap; + + // BigEndian::Put32( const_cast( tmpEap.Ptr() ) + 4, + // EAPSettings::EEapAka ); + tmpEap.Format( KExpEapTypeFormat, ( EAPSettings::EEapAka >> 24 ) & 0xff, + ( EAPSettings::EEapAka >> 16 ) & 0xff, + ( EAPSettings::EEapAka >> 8 ) & 0xff, + EAPSettings::EEapAka & 0xff ); + + error = MoveEAPType( tmpEap, topPos ); + + if ( error != KErrNotFound ) + { + // Found EAP-AKA in the array. + // Doesn't matter if the move was a success or not. + foundDefaultEAPTypes = ETrue; + } + + // Now move EAP-SIM to top. + // EAP-SIM will be always the top most if it is present in the array. + // Otherwise EAP-AKA stays in the top, if it is present. + // The order doesn't matter if these two are not present. + // BigEndian::Put32( const_cast( tmpEap.Ptr() ) + 4, + // EAPSettings::EEapSim ); + tmpEap.Format( KExpEapTypeFormat, ( EAPSettings::EEapSim >> 24 ) & 0xff, + ( EAPSettings::EEapSim >> 16 ) & 0xff, + ( EAPSettings::EEapSim >> 8 ) & 0xff, + EAPSettings::EEapSim & 0xff ); + + error = MoveEAPType( tmpEap, topPos ); + + if( error != KErrNotFound) + { + // Found EAP-SIM in the array. + // Doesn't matter if the move was a success. + foundDefaultEAPTypes = ETrue; + } + } + + TInt i; + TInt j; + TInt numInfoStore = iEapArray.Count(); + + CArrayFix* usedImplInfo = new( ELeave ) CArrayFixFlat( 4 ); + CleanupStack::PushL( usedImplInfo ); + + usedImplInfo->AppendL( 0, numInfoStore ); + + // deal with the enabled first + for ( j = 0; j < numEnabled; j++ ) + { + TPtrC8 param( aWPAEnabledEAPPlugin.Ptr() + KLengthOfExpEapType * j, + KLengthOfExpEapType ); + + for ( i = 0; i < numInfoStore; i++ ) + { + if ( !param.Compare( iEapArray[i]->DataType() ) ) + { + usedImplInfo->InsertL( i, 1 ); + if ( i+1 < usedImplInfo->Count() ) + { + usedImplInfo->Delete( i+1 ); + } + + TEAPPluginInfo plugin; + plugin.iInfo = iEapArray[i]; + plugin.iEnabled = ETrue; + + User::LeaveIfError( aPlugins.Append( plugin ) ); + i = numInfoStore; // to exit from cycle + } + } + } + + + // now come the disabled + for ( j = 0; j < numDisabled; j++ ) + { + TPtrC8 param( aWPADisabledEAPPlugin.Ptr() + KLengthOfExpEapType * j, + KLengthOfExpEapType ); + + for ( i = 0; i < numInfoStore; i++ ) + { + if ( !param.Compare( iEapArray[i]->DataType() ) ) + { + usedImplInfo->InsertL( i, 1 ); + if ( i+1 < usedImplInfo->Count() ) + { + usedImplInfo->Delete( i+1 ); + } + + TEAPPluginInfo plugin; + plugin.iInfo = iEapArray[i]; + plugin.iEnabled = EFalse; + + User::LeaveIfError( aPlugins.Append( plugin ) ); + i = numInfoStore; // to exit from cycle + } + } + } + + + for ( i = 0; i < numInfoStore; i++ ) + { + if ( !usedImplInfo->At( i ) ) + { + TEAPPluginInfo plugin; + plugin.iInfo = iEapArray[i]; + + // Default is enabled. + // There should not be a case of all EAP types disabled. + TBool defaultEnableValue( ETrue ); + + if ( numEnabled > 0 ) + { + // If there some EAP types which are already enabled/disabled, + // we make the new EAP types disabled. + defaultEnableValue = EFalse; + } + else + { + // No EAP types enabled. + // Should be the first time execution (creating new IAP). + // Only EAP-SIM and EAP-AKA are enabled in this case. + + // [FE] [00 00 00] [TEapType_bigendian] + const TDesC8& cue = iEapArray[i]->DataType(); + + TPtrC8 eapType( cue.Ptr() + 4, 4 ); + TUint32 implDataType = ( eapType[0] << 24 ) | + ( eapType[1] << 16 ) | + ( eapType[2] << 8 ) | + eapType[3]; + + if( foundDefaultEAPTypes ) + { + _LIT8( KExpEapFirstQuad, "\xFE\0\0\0" ); + TPtrC8 firstQuad( cue.Ptr(), 4 ); + + defaultEnableValue = + ( !firstQuad.Compare ( KExpEapFirstQuad ) && + ( implDataType == EAPSettings::EEapSim || + implDataType == EAPSettings::EEapAka ) ); + } + else + { + // No default EAPs (No EAP-SIM and EAP-AKA). + // So all EAP types are enabled by default. + defaultEnableValue = ETrue; + } + } + + plugin.iEnabled = defaultEnableValue; + User::LeaveIfError( aPlugins.Append( plugin ) ); + } + } + CleanupStack::PopAndDestroy( usedImplInfo ); + + } + + +// --------------------------------------------------------- +// CEAPPluginConfiguration::SavePluginInfoL +// --------------------------------------------------------- +// +void CEAPPluginConfiguration::SavePluginInfoL( TDes& aWPAEAPPlugin, + REAPPluginList& aPlugins ) + { + aWPAEAPPlugin.Zero(); + for ( TInt index = 0; index < aPlugins.Count(); index++ ) + { + TBuf8 cue = aPlugins[index].iInfo->DataType(); + + TLex8 lexDataType( cue ); + TInt implUID; + if ( lexDataType.Val( implUID ) == KErrNone ) + { + if ( aPlugins[index].iEnabled ) + { + aWPAEAPPlugin.Append( KPlusSign ); + } + else + { + aWPAEAPPlugin.Append( KMinusSign ); + } + + aWPAEAPPlugin.AppendNumFixedWidth( implUID, EDecimal, + KLengthOfImplUid ); + + if ( index != aPlugins.Count()-1 ) + { + aWPAEAPPlugin.Append( KComma ); + } + } + } + } + + +// --------------------------------------------------------- +// CEAPPluginConfiguration::SavePluginInfoL +// --------------------------------------------------------- +// +void CEAPPluginConfiguration::SavePluginInfoL( TDes8& aWPAEnabledEAPPlugin, + TDes8& aWPADisabledEAPPlugin, + REAPPluginList& aPlugins ) + { + aWPAEnabledEAPPlugin.Zero(); + aWPADisabledEAPPlugin.Zero(); + + for ( TInt index = 0; index < aPlugins.Count(); index++ ) + { + if ( aPlugins[index].iEnabled ) + { + aWPAEnabledEAPPlugin.Append( aPlugins[index].iInfo->DataType() ); + } + else + { + aWPADisabledEAPPlugin.Append( aPlugins[index].iInfo->DataType() ); + } + } + + } + + +// --------------------------------------------------------- +// CEAPPluginConfiguration::ShowEAPTypeInfo +// --------------------------------------------------------- +// +void CEAPPluginConfiguration::ShowEAPTypeInfo() + { + + } + + +// --------------------------------------------------------- +// CEAPPluginConfiguration::DeleteSettingsL +// --------------------------------------------------------- +// +void CEAPPluginConfiguration::DeleteSettingsL( const TUint32 aIapID ) + { + iEapArray.ResetAndDestroy(); + REComSession::ListImplementationsL( KEapTypeInterfaceUid, iEapArray ); + + for ( TInt i = 0; i < iEapArray.Count(); i++ ) + { + if ( !CEapType::IsDisallowedOutsidePEAP( *iEapArray[i] ) ) + { + CEapType* eapType = CEapType::NewL( iEapArray[i]->DataType(), + ELan, + aIapID ); + CleanupStack::PushL( eapType ); + + eapType->DeleteConfigurationL(); + CleanupStack::PopAndDestroy( eapType ); + } + } + } + + +// --------------------------------------------------------- +// CEAPPluginConfiguration::ChangeIapIDL +// --------------------------------------------------------- +// +void CEAPPluginConfiguration::ChangeIapIDL( const TUint32 aOldIapID, + const TUint32 aNewIapID ) + { + iEapArray.ResetAndDestroy(); + REComSession::ListImplementationsL( KEapTypeInterfaceUid, iEapArray ); + + for ( TInt i = 0; i < iEapArray.Count(); i++ ) + { + if ( !CEapType::IsDisallowedOutsidePEAP( *iEapArray[i] ) ) + { + CEapType* eapType = CEapType::NewL( iEapArray[i]->DataType(), + ELan, + aOldIapID ); + CleanupStack::PushL( eapType ); + + eapType->SetIndexL( ELan, aNewIapID ); + CleanupStack::PopAndDestroy( eapType ); + } + } +} + +// --------------------------------------------------------- +// CEAPPluginConfiguration::CopySettingsL +// --------------------------------------------------------- +// +void CEAPPluginConfiguration::CopySettingsL( const TUint32 aSourceIapID, + const TUint32 aDestinationIapID ) + { + iEapArray.ResetAndDestroy(); + REComSession::ListImplementationsL( KEapTypeInterfaceUid, iEapArray ); + + for ( TInt i = 0; i < iEapArray.Count(); i++ ) + { + if ( !CEapType::IsDisallowedOutsidePEAP( *iEapArray[i] ) ) + { + CEapType* eapType = CEapType::NewL( iEapArray[i]->DataType(), + ELan, + aSourceIapID ); + CleanupStack::PushL( eapType ); + + eapType->CopySettingsL( ELan, aDestinationIapID ); + CleanupStack::PopAndDestroy( eapType ); + } + } + } + + +// --------------------------------------------------------- +// CEAPPluginConfiguration::MoveEAPType +// --------------------------------------------------------- +// +TInt CEAPPluginConfiguration::MoveEAPType( EAPSettings::TEapType aEapType, + TInt aPos ) + { + TInt error( KErrNotFound ); + + // Parse the array to find out the desired EAP type. + for( TInt count = 0; count < iEapArray.Count(); count++ ) + { + TLex8 lexDataType( iEapArray[count]->DataType() ); + TInt implDataType; + + if ( lexDataType.Val( implDataType ) == KErrNone ) + { + if ( implDataType == aEapType ) + { + // Move this to the required destination. + error = iEapArray.Insert( iEapArray[count], aPos ); + + if( KErrNone == error ) + { + // Delete the old entry. It should be one count up now. + iEapArray.Remove( count+1 ); + } + else + { + // Some problem. Couldn't move. + error = KErrUnknown; + } + + // No need to parse further in the array. + // We found the needed EAP type. + break; + } + } + else + { + error = KErrGeneral; + } + } + + return error; + } + + +// --------------------------------------------------------- +// CEAPPluginConfiguration::MoveEAPType +// --------------------------------------------------------- +// +TInt CEAPPluginConfiguration::MoveEAPType( const TDesC8& aEapType, TInt aPos ) + { + TInt error( KErrNotFound ); + + // Parse the array to find out the desired EAP type. + for( TInt count = 0; count < iEapArray.Count(); count++ ) + { + if ( !iEapArray[count]->DataType().Compare( aEapType ) ) + { + // Move this to the required destination. + error = iEapArray.Insert( iEapArray[count], aPos ); + + if( KErrNone == error ) + { + // Delete the old entry. It should be one count up now. + iEapArray.Remove( count+1 ); + } + else + { + // Some problem. Couldn't move. + error = KErrUnknown; + } + + // No need to parse further in the array. + // We found the needed EAP type. + break; + } + } + + return error; + } + +// End of file. diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPluginConfigurationProxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPluginConfigurationProxy.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Some functions that ECom needs. +* +*/ + + + +// INCLUDE FILES +#include "EAPPluginConfiguration.h" +#include "EAPPluginConfigUid.h" + +#include +#include + + +const TImplementationProxy ImplementationTable[] = + { + {{EAP_PLUGIN_CONFIG_IMPLEMENTATION_UID}, + reinterpret_cast( CEAPPluginConfiguration::NewL ) } + }; + + +// ================= OTHER EXPORTED FUNCTIONS ============== + +// ----------------------------------------------------------------------------- +// ImplementationGroupProxy +// ----------------------------------------------------------------------------- +// +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( + TInt& aTableCount ) + { + aTableCount = sizeof( ImplementationTable ) / + sizeof( TImplementationProxy ); + + return ImplementationTable; + } + + +// End of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPluginList.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPluginList.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class REAPPluginList. +* +*/ + + + +// INCLUDE FILES +#include "EAPPluginList.h" + + +// ============================ MEMBER FUNCTIONS =============================== + +// --------------------------------------------------------- +// REAPPluginList::MovePos +// --------------------------------------------------------- +// +void REAPPluginList::MovePos( TInt aOldPos, TInt aNewPos ) + { + TEAPPluginInfo temp; + TInt i; + if ( aNewPos > aOldPos ) + { + temp = (*this)[aOldPos]; + for ( i = aOldPos; i < aNewPos; i++ ) + { + (*this)[i] = (*this)[i + 1]; + } + (*this)[aNewPos] = temp; + } + else if ( aNewPos < aOldPos ) + { + temp = (*this)[aOldPos]; + for ( i = aOldPos; i > aNewPos; i-- ) + { + (*this)[i] = (*this)[i - 1]; + } + (*this)[aNewPos] = temp; + } + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/data/EapSimUi.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/data/EapSimUi.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,246 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP LEAP UI resource file +* +*/ + + + +CHARACTER_SET UTF8 + +// RESOURCE IDENTIFIER +NAME EPSI + +// INCLUDES +#include +#include "EapSimUi.hrh" // Enums for these resources +#include // Localisation file +#include +#include +#include +#include +#include +#include + + +// CONSTANTS +#define KUsernameMaxNameLength 255 + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + + +RESOURCE TBUF16 { buf = ""; } + + +RESOURCE CBA r_sim_softkeys_options_back_change + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = ESimUiCmdChange; txt = qtn_msk_change; } + }; + } + + +RESOURCE DIALOG r_sim_setting_dialog + { + flags = EAknDialogSelectionList | EEikDialogFlagWait; + buttons = r_sim_softkeys_options_back_change; + items = + { + DLG_LINE + { + id = ESimSettingsListBox; + type = EAknCtSettingListBox; + control = LISTBOX + { + flags = EAknListBoxMenuList; + }; + } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_sim_username_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_username; + type = EEikCtEdwin; + editor_resource_id = r_sim_setting_edwin; + } + + +RESOURCE AVKON_SETTING_PAGE r_sim_realm_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_realm; + type = EEikCtEdwin; + editor_resource_id = r_sim_setting_edwin; + } + + +RESOURCE EDWIN r_sim_setting_edwin + { + width = 9; + lines = 5; + maxlength = KUsernameMaxNameLength; + allowed_input_modes = EAknEditorTextInputMode | EAknEditorNumericInputMode; + default_input_mode = EAknEditorTextInputMode; + flags = EEikEdwinAutoSelection | EEikEdwinNoLineOrParaBreaks; + } + + +RESOURCE MENU_BAR r_sim_menubar + { + titles = + { + MENU_TITLE { menu_pane = r_sim_menu_pane; txt = ""; } + }; + } + + +RESOURCE MENU_PANE r_sim_menu_pane + { + items = + { + MENU_ITEM + { + command = ESimUiCmdChange; + txt = qtn_options_change; + flags = EEikMenuItemAction; + }, + MENU_ITEM + { + command = EAknCmdHelp; + txt = qtn_options_help; + }, + MENU_ITEM + { + command = EAknCmdExit; + txt = qtn_options_exit; + } + }; + } + + +// Resource strings +RESOURCE TBUF r_sim_settings_title { buf = qtn_wlan_eap_sim_title; } +RESOURCE TBUF r_sim_username_inusestring \ + { buf = qtn_wlan_eap_sett_username_inuse; } +RESOURCE TBUF r_sim_username_inusestring_auto \ + { buf = qtn_wlan_eap_sett_username_inuse_from_sim; } +RESOURCE TBUF r_sim_username_inusestring_conf \ + { buf = qtn_wlan_eap_sett_username_inuse_user; } +RESOURCE TBUF r_sim_username_string { buf = qtn_wlan_eap_sett_username; } +RESOURCE TBUF r_sim_realm_inusestring \ + { buf = qtn_wlan_eap_sett_realm_inuse; } +RESOURCE TBUF r_sim_realm_inusestring_auto \ + { buf = qtn_wlan_eap_sett_realm_inuse_from_sim; } +RESOURCE TBUF r_sim_realm_inusestring_conf \ + { buf = qtn_wlan_eap_sett_realm_inuse_user; } +RESOURCE TBUF r_sim_realm_string { buf = qtn_wlan_eap_sett_realm; } + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_sim_username_autouseconf_texts + { + setting_texts_resource = r_sim_username_autouseconf_texts_resource; + popped_up_texts_resource = r_sim_username_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_sim_username_autouseconf_texts_resource + { + items = + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_username_inuse_from_sim; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_username_inuse_user; + } + }; + } + + +RESOURCE ARRAY r_sim_username_automatic_useconfigured_array + { + items = + { + LBUF { txt = qtn_wlan_eap_sett_username_inuse_from_sim; }, + LBUF { txt = qtn_wlan_eap_sett_username_inuse_user; } + }; + } + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_sim_realm_autouseconf_texts + { + setting_texts_resource = r_sim_realm_autouseconf_texts_resource; + popped_up_texts_resource = r_sim_realm_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_sim_realm_autouseconf_texts_resource + { + items= + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_realm_inuse_from_sim; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_realm_inuse_user; + } + }; + } + + +RESOURCE ARRAY r_sim_realm_automatic_useconfigured_array + { + items= + { + LBUF { txt = qtn_wlan_eap_sett_realm_inuse_from_sim; }, + LBUF { txt = qtn_wlan_eap_sett_realm_inuse_user; } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_sim_display_autouseconf_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_realm_inuse; + type = EAknCtPopupSettingList; + editor_resource_id = r_sim_setting_enumerated_popup; + } + + +RESOURCE POPUP_SETTING_LIST r_sim_setting_enumerated_popup + { + flags = EAknPopupSettingListFlagInitialised; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/inc/EapSimUi.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/inc/EapSimUi.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP SIM UI hrh file +* +*/ + + +#ifndef _EAPSIMUI_HRH_ +#define _EAPSIMUI_HRH_ + +enum TEapSimUiMenuCommands + { + ESimUiCmdUndefined = 6000, + ESimUiCmdChange + }; + +enum TEapSimUiNotes + { + TEapSimUiGeneralError = 6100 + }; + +enum TEapSimUiLines + { + ESimSettingsListBox = 6200 + }; + +enum TEapSimUiSettingIds + { + ESimSettingUsernameinUseSettingId=6300, + ESimSettingUsernameSettingId, + ESimSettingPageRealminUseSettingId, + ESimSettingRealmSettingId + }; + +enum TEapSimUiSettingPageIds + { + ESimSettingPageUsernameinUse=6400, + ESimSettingPageUsername, + ESimSettingPageRealminUse, + ESimSettingPageRealm + }; + + +#endif //_EAPSIMUI_HRH_ + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/inc/EapSimUiSettingArray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/inc/EapSimUiSettingArray.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP SIM UI settings array +* +*/ + + + +#ifndef _EAPSIMUISETTINGARRAY_H_ +#define _EAPSIMUISETTINGARRAY_H_ + +// INCLUDES +#include +#include "EapSimUi.hrh" + + +// CLASS DECLARATION + +/** +*/ +class CEapSimSettingItemArray : public CBase + { + public: + static CEapSimSettingItemArray* NewL(); + virtual ~CEapSimSettingItemArray(); + CAknSettingItem* Item( TEapSimUiSettingPageIds aItem ); + CAknSettingItemArray* Array(); + void StoreSettingsL(); + void AddTextItemL( TDes& aBuffer, TInt aId, TInt aTitleResource, + TInt aSettingPageResource, TInt aAssociatedResource, + TInt aOrdinal ); + + void AddPasswordItemL( TDes& aPassword, TInt aId, TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, TInt aOrdinal ); + + void AddBinarySettingItemL( TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue ); + + protected: + CEapSimSettingItemArray(); + void ConstructL(); + + private: + CAknSettingItemArray* iArray; + }; + +#endif // _EAPSIMUISETTINGARRAY_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/inc/EapSimUiView.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/inc/EapSimUiView.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP SIM UI setting dialog +* +*/ + + + +#ifndef _EAPSIMUIVIEW_H_ +#define _EAPSIMUIVIEW_H_ + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include "EapSimUi.hrh" + + +// FORWARD DECLARATIONS +class CAknSettingStyleListBox; +class CSettingsListBoxItemDrawer; +class CEapSimSettingItemArray; +class CEapSimUiConnection; +class CEapSimUiSimData; +class CEapSimUiDataConnection; + + +// CLASS DECLARATION + +/** +* Settings dialog class definition +*/ +class CEapSimUiDialog : public CAknDialog, + public MEikListBoxObserver + { + public: + CEapSimUiDialog( CEapSimUiConnection* aConnection, + TInt& aButtonId ); + + ~CEapSimUiDialog(); + + /** + * Create and launch dialog. + * @param aResourceId The resource ID of the dialog to load. + * @return The ID of the button that closed the dialog + */ + TInt ConstructAndRunLD( TInt aResourceId ); + + + public: // From MEikListBoxObserver + + /** + * Handles list box events. + * @param aListBox The originating list box. + * @param aEventType A code for the event. + */ + void HandleListBoxEventL( CEikListBox* aListBox, TListBoxEvent aEventType ); + + + protected: + void PreLayoutDynInitL(); + TBool OkToExitL( TInt aButtonId ); + + private: + void InitializeSettingsL(); + void DrawSettingsListL(); + void ChangeTitleL( TBool aIsStarted ); + void ShowSettingPageL( TInt aCalledFromMenu ); + void ProcessCommandL( TInt aCommand ); + void SaveSettings(); + void GetHelpContext( TCoeHelpContext& aContext ) const; + + /** + * Initialize menu pane. + * @param aResourceId Menu pane resource id. + * @param CEikMenuPane Menu pane. + */ + void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ); + + + private: + CEapSimUiConnection* iConnection; + CEapSimUiSimData* iUiData; + CEapSimUiDataConnection* iDataConnection; + CEapSimSettingItemArray* iSettingArray; + CAknSettingStyleListBox* iSettingListBox; + CSettingsListBoxItemDrawer* iSettingListItemDrawer; + CAknNavigationControlContainer* iNaviPane; + CAknNavigationDecorator* iNaviDecorator; + HBufC* iPreviousText; + TInt* iButtonId; + + // Tells the status of UI construction. TRUE if UI construction is completed. + TBool iIsUIConstructionCompleted; + }; + + +#endif // _EAPSIMUIVIEW_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/loc/eapsimui.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/loc/eapsimui.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI strings for WLAN EAP-SIM authentication settings +* +*/ + + + +// LOCALISATION STRINGS + + +//d:UI title for main view +//l:title_pane_t2/opt9 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sim_title "EAP-SIM settings" + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUi.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP SIM UI class +* +*/ + + + +// INCLUDE FILES +#include "EapSimUi.h" +#include +#include "EapSimUiView.h" +#include +#include +#include +#include +#include + + +// CONSTANTS +_LIT( KDriveZ, "z:" ); // ROM folder +_LIT( KResourceFileName, "eapsimui.rsc" ); + + +// CLASS DECLARATION +class TResourceFileCleanupItem + { + public: + CCoeEnv* iCoeEnv; + TInt iResourceFileOffset; + }; + + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CleanupResourceFile +// ----------------------------------------------------------------------------- +// +static void CleanupResourceFile( TAny* aObject ) + { + TResourceFileCleanupItem* item = + REINTERPRET_CAST( TResourceFileCleanupItem*, aObject ); + item->iCoeEnv->DeleteResourceFile( item->iResourceFileOffset ); + delete item; + } + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapSimUi::CEapSimUi +// ----------------------------------------------------------------------------- +// +CEapSimUi::CEapSimUi( CEapSimUiConnection* aConnection ) +: iConnection( aConnection ) + { + } + + +// ----------------------------------------------------------------------------- +// CEapSimUi::NewL +// ----------------------------------------------------------------------------- +// +CEapSimUi* CEapSimUi::NewL( CEapSimUiConnection* aConnection ) + { + CEapSimUi* self = new ( ELeave ) CEapSimUi( aConnection ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapSimUi::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapSimUi::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CEapSimUi::~CEapSimUi +// ----------------------------------------------------------------------------- +// +CEapSimUi::~CEapSimUi() + { + } + + +// ----------------------------------------------------------------------------- +// CEapSimUi::InvokeUiL +// ----------------------------------------------------------------------------- +// +TInt CEapSimUi::InvokeUiL() + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + CCoeEnv* coeEnv = CCoeEnv::Static(); + BaflUtils::NearestLanguageFile( coeEnv->FsSession(), fileName ); + + TResourceFileCleanupItem* item = new( ELeave ) TResourceFileCleanupItem; + + item->iCoeEnv = coeEnv; + CleanupStack::PushL( TCleanupItem( CleanupResourceFile, item ) ); + item->iResourceFileOffset = coeEnv->AddResourceFileL( fileName ); + + TInt buttonId; + CEapSimUiDialog* settingsDlg = new( ELeave ) CEapSimUiDialog( iConnection, + buttonId ); + settingsDlg->ConstructAndRunLD( R_SIM_SETTING_DIALOG ); + + CleanupStack::PopAndDestroy(); // For resource file + + return buttonId; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUiSettingArray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUiSettingArray.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,185 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP SIM UI settings array +* +*/ + + + +// INCLUDE FILES +#include "EapSimUiSettingArray.h" + +#include "EapSimUi.hrh" + +#include +#include + + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapSimSettingItemArray::CEapSimSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapSimSettingItemArray::CEapSimSettingItemArray() + { + } + + +// ----------------------------------------------------------------------------- +// CEapSimSettingItemArray::NewL +// ----------------------------------------------------------------------------- +// +CEapSimSettingItemArray* CEapSimSettingItemArray::NewL() + { + CEapSimSettingItemArray* self = new ( ELeave ) CEapSimSettingItemArray(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapSimSettingItemArray::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapSimSettingItemArray::ConstructL() + { + iArray = new ( ELeave ) CAknSettingItemArray( 2, EFalse, 0 ); + } + + +// ----------------------------------------------------------------------------- +// CEapSimSettingItemArray::~CEapSimSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapSimSettingItemArray::~CEapSimSettingItemArray() + { + if( iArray ) + { + // ResetAndDestroy() + iArray->ResetAndDestroy(); + } + delete iArray; + iArray = NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapSimSettingItemArray::Item +// ----------------------------------------------------------------------------- +// +CAknSettingItem* CEapSimSettingItemArray::Item( TEapSimUiSettingPageIds aId ) + { + for( TInt i = 0; i < iArray->Count(); i++) + { + if( iArray->At( i )->Identifier() == aId ) + { + return iArray->At( i ); + } + } + + __ASSERT_DEBUG( EFalse, User::Invariant() ); + return NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapSimSettingItemArray::Array +// ----------------------------------------------------------------------------- +// +CAknSettingItemArray* CEapSimSettingItemArray::Array() + { + return iArray; + } + + +// ----------------------------------------------------------------------------- +// CEapSimSettingItemArray::StoreSettingsL +// ----------------------------------------------------------------------------- +// +void CEapSimSettingItemArray::StoreSettingsL() + { + // Do what SettingItemList::StoreSettings would do. + for( TInt i( 0 ); i < iArray->Count(); ++i) + { + iArray->At( i )->StoreL(); + } + } + + +// ----------------------------------------------------------------------------- +// CEapSimSettingItemArray::AddTextItemL +// ----------------------------------------------------------------------------- +// +void CEapSimSettingItemArray::AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal ) + { + // Create new setting item + CAknTextSettingItem* settingItem = new( ELeave ) CAknTextSettingItem( aId, + aBuffer ); + CleanupStack::PushL( settingItem ); + settingItem->SetEmptyItemTextL( KNullDesC ); + settingItem->SetSettingPageFlags( + CAknTextSettingPage::EZeroLengthAllowed ); + + // Construct setting item with parametrized values + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResource ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResource, EAknCtPopupSettingList, + NULL, aAssociatedResource ); + + // Append item to settingitem-array + iArray->InsertL( aOrdinal, settingItem ); + CleanupStack::PopAndDestroy( itemTitle ); + + // Items are destroyed in destructor when resetting array + CleanupStack::Pop( settingItem ); + } + + +// ----------------------------------------------------------------------------- +// CEapSimSettingItemArray::AddBinarySettingItemL +// ----------------------------------------------------------------------------- +// +void CEapSimSettingItemArray::AddBinarySettingItemL( + TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue ) + { + CAknSettingItem* settingItem = new ( ELeave ) + CAknBinaryPopupSettingItem( 0, aModifiedValue ); + CleanupStack::PushL( settingItem ); + + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResourceId ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResourceId, EAknCtPopupSettingList, + NULL, aAssociatedResourceId ); + iArray->AppendL( settingItem ); + CleanupStack::PopAndDestroy( itemTitle ); + CleanupStack::Pop( settingItem ); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUiView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUiView.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,478 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP SIM UI settings dialog +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include "EapSimUiView.h" +#include "EapSimUi.hrh" +#include +#include +#include +#include "EapSimUiSettingArray.h" +#include // For info message +#include +#include +#include +#include + +#include +#include +#include + + +// CONSTANTS +// UID of general settings app, in which help texts are included +const TUid KHelpUidPlugin = { 0x100058EC }; + +_LIT( KEmptyString, "" ); + +// MODULE DATA STRUCTURES +enum + { + EUsernameInUseItem = 0, + EUsernameItem, + ERealmInUseItem, + ERealmItem + }; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapSimUiDialog::CEapSimUiDialog +// ----------------------------------------------------------------------------- +// +CEapSimUiDialog::CEapSimUiDialog( CEapSimUiConnection* aConnection, + TInt& aButtonId ) +: CAknDialog(), + iConnection( aConnection ), + iUiData( 0 ), + iDataConnection( 0 ), + iSettingArray( 0 ), + iSettingListBox( 0 ), + iSettingListItemDrawer( 0 ), + iNaviPane( 0 ), + iNaviDecorator( 0 ), + iPreviousText( 0 ), + iButtonId( &aButtonId ), + iIsUIConstructionCompleted( EFalse ) + { + } + + +// --------------------------------------------------------- +// CEapSimUiDialog::ConstructAndRunLD +// --------------------------------------------------------- +// +TInt CEapSimUiDialog::ConstructAndRunLD( TInt aResourceId ) + { + CleanupStack::PushL( this ); + + iSettingArray = CEapSimSettingItemArray::NewL(); + + User::LeaveIfError( iConnection->Connect() ); + iDataConnection = iConnection->GetDataConnection(); + if ( iDataConnection == 0 ) + { + User::Leave( KErrNoMemory ); + } + + User::LeaveIfError( iDataConnection->Open() ); + User::LeaveIfError( iDataConnection->GetData( &iUiData ) ); + + FeatureManager::InitializeLibL(); + + ConstructL( R_SIM_MENUBAR ); + + // ExecuteLD will PushL( this ), so we have to Pop it... + CleanupStack::Pop( this ); // this + + return CAknDialog::ExecuteLD( aResourceId ); + } + + +// ----------------------------------------------------------------------------- +// CEapSimUiDialog::~CEapSimUiDialog +// ----------------------------------------------------------------------------- +// +CEapSimUiDialog::~CEapSimUiDialog() + { + if ( iNaviDecorator ) + { + delete iNaviDecorator; + iNaviDecorator = NULL; + } + + if ( iSettingArray ) + { + iSettingArray->Array()->ResetAndDestroy(); + delete iSettingArray; + } + + if ( iSettingListBox ) + { + iSettingListBox = 0; + } + + if ( iSettingListItemDrawer ) + { + iSettingListItemDrawer = 0; + } + + if ( iDataConnection ) + { + iDataConnection->Close(); + delete iDataConnection; + } + + if ( iConnection ) + { + iConnection->Close(); + } + + delete iPreviousText; + + FeatureManager::UnInitializeLib(); + } + +// --------------------------------------------------------- +// CEapSimUiDialog::HandleListBoxEventL +// --------------------------------------------------------- +// +void CEapSimUiDialog::HandleListBoxEventL( CEikListBox* /*aListBox*/, + TListBoxEvent aEventType ) + { + switch ( aEventType ) + { + case EEventEnterKeyPressed: + case EEventItemSingleClicked: + { + OkToExitL( ESimUiCmdChange ); + break; + } + + case EEventItemActioned: + case EEventEditingStarted: + case EEventEditingStopped: + case EEventPenDownOnItem: + case EEventItemDraggingActioned: + { + break; + } + + default: + { + break; + }; + }; + } + + +// ----------------------------------------------------------------------------- +// CEapSimUiDialog::PreLayoutDynInitL +// ----------------------------------------------------------------------------- +// +void CEapSimUiDialog::PreLayoutDynInitL() + { + ChangeTitleL( ETrue ); + + TUid naviPaneUid; + naviPaneUid.iUid = EEikStatusPaneUidNavi; + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( naviPaneUid ); + if ( subPane.IsPresent()&&subPane.IsAppOwned() ) + { + iNaviPane = static_cast( + statusPane->ControlL( naviPaneUid ) ); + + // Set empty text to hide tabs. + iNaviDecorator = iNaviPane->CreateNavigationLabelL( KEmptyString ); + iNaviPane->PushL( *iNaviDecorator ); + } + + iSettingListBox = static_cast( + ControlOrNull( ESimSettingsListBox ) ); + iSettingListItemDrawer=static_cast( + iSettingListBox->ItemDrawer() ); + iSettingListBox->SetMopParent( this ); + iSettingListBox->CreateScrollBarFrameL( ETrue ); + iSettingListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iSettingListBox->SetListBoxObserver( this ); + DrawSettingsListL(); + + iIsUIConstructionCompleted = ETrue; + } + + +// ----------------------------------------------------------------------------- +// CEapSimUiDialog::ShowSettingPageL +// ----------------------------------------------------------------------------- +// +void CEapSimUiDialog::ShowSettingPageL( TInt aCalledFromMenu ) + { + TInt index = iSettingListBox->CurrentItemIndex(); + CAknSettingItem* item = iSettingArray->Array()->At( index ); + item->EditItemL( aCalledFromMenu ); + item->StoreL(); + DrawNow(); + } + + +// ----------------------------------------------------------------------------- +// CEapSimUiDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CEapSimUiDialog::OkToExitL( TInt aButtonId ) + { + TBool ret( EFalse ); + switch ( aButtonId ) + { + case EEikBidOk: + { + if( iIsUIConstructionCompleted ) + { + if ( iSettingListBox->IsFocused() ) + { + ShowSettingPageL( EFalse ); + } + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapSimUiDialog::OkToExitL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + case EAknSoftkeyOptions: + { + DisplayMenuL(); + break; + } + + case EAknSoftkeyBack: + case EAknCmdExit: + { + if( iIsUIConstructionCompleted ) + { + iDataConnection->Update(); + ChangeTitleL( EFalse ); + ret = ETrue; + } + break; + } + + case ESimUiCmdChange: + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( EFalse ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapSimUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + default: + { + break; + } + } + + if ( ret ) + { + *iButtonId = aButtonId; + } + + return ret; + } + + +// ----------------------------------------------------------------------------- +// CEapSimUiDialog::DrawSettingsListL +// ----------------------------------------------------------------------------- +// +void CEapSimUiDialog::DrawSettingsListL() + { + iSettingArray->Array()->ResetAndDestroy(); + TInt ordinal = 0; + iSettingArray->AddBinarySettingItemL( R_SIM_DISPLAY_AUTOUSECONF_PAGE, + R_SIM_USERNAME_INUSESTRING, + R_SIM_USERNAME_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetUseManualUsername() ); + + iSettingArray->AddTextItemL( iUiData->GetManualUsername(), + ESimSettingPageUsername, + R_SIM_USERNAME_STRING, + R_SIM_USERNAME_PAGE, + NULL, + ordinal++ ); + + iSettingArray->AddBinarySettingItemL( R_SIM_DISPLAY_AUTOUSECONF_PAGE, + R_SIM_REALM_INUSESTRING, + R_SIM_REALM_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetUseManualRealm() ); + + iSettingArray->AddTextItemL( iUiData->GetManualRealm(), + ESimSettingUsernameSettingId, + R_SIM_REALM_STRING, + R_SIM_REALM_PAGE, + NULL, + ordinal++ ); + + iSettingListBox->Model()->SetItemTextArray( iSettingArray->Array() ); + iSettingListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iSettingArray->Array()->RecalculateVisibleIndicesL(); + iSettingListBox->HandleItemAdditionL(); + iSettingListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CEapSimUiDialog::ChangeTitleL +// ----------------------------------------------------------------------------- +// +void CEapSimUiDialog::ChangeTitleL( TBool aIsStarted ) + { + TUid titlePaneUid; + titlePaneUid.iUid = EEikStatusPaneUidTitle; + + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( titlePaneUid ); + + if ( subPane.IsPresent() && subPane.IsAppOwned() ) + { + CAknTitlePane* titlePane = static_cast( + statusPane->ControlL( titlePaneUid ) ); + if ( aIsStarted ) + { + // Store previous application title text + const TDesC* prevText = titlePane->Text(); + + iPreviousText = HBufC::NewL( prevText->Length() ); + iPreviousText->Des().Append( *prevText ); + TDesC* titleText = iEikonEnv->AllocReadResourceLC( + R_SIM_SETTINGS_TITLE ); + titlePane->SetTextL( *titleText ); + CleanupStack::PopAndDestroy( titleText ); + } + else + { + // Set calling application title text back + titlePane->SetTextL( *iPreviousText ); + // pop navidecorator when exiting + iNaviPane->Pop( iNaviDecorator ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapSimUiDialog::DynInitMenuPaneL +// ----------------------------------------------------------------------------- +// +void CEapSimUiDialog::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + CAknDialog::DynInitMenuPaneL( aResourceId, aMenuPane ); + + if ( aResourceId == R_SIM_MENU_PANE ) + { + if ( aMenuPane && !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapSimUiDialog::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CEapSimUiDialog::ProcessCommandL( TInt aCommand ) + { + if ( MenuShowing() ) + { + HideMenu(); + } + + switch( aCommand ) + { + case EAknCmdExit: + { + TryExitL( aCommand ); + break; + } + + case EAknCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + iEikonEnv->EikAppUi()->AppHelpContextL() ); + break; + } + + case ESimUiCmdChange: + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( ETrue ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapSimUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + default: + { + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapSimUiDialog::GetHelpContext +// ----------------------------------------------------------------------------- +// +void CEapSimUiDialog::GetHelpContext( TCoeHelpContext& aContext ) const + { + aContext.iMajor = KHelpUidPlugin; + aContext.iContext = KSET_HLP_WLAN_EAP_SIM; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/data/EapTlsUi.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/data/EapTlsUi.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,411 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP TLS UI resource file +* +*/ + + + +CHARACTER_SET UTF8 + +// RESOURCE IDENTIFIER +NAME ETLS + +// INCLUDES +#include +#include "EapTlsUi.hrh" // Enums for these resources +#include // Localisation file +#include +#include +#include +#include +#include +#include + + +// CONSTANTS +#define KUsernameMaxNameLength 255 + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + + +RESOURCE TBUF16 { buf=""; } + + +RESOURCE CBA r_tls_ui_softkeys_options_back_edit + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = ETlsUiCmdChange; txt = qtn_msk_change; } + }; + } + + +RESOURCE CBA r_tls_ui_softkeys_options_back_enable + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = ETlsUiCmdEnable; txt = qtn_msk_wlan_eap_cs_enable; } + }; + } + + +RESOURCE CBA r_tls_ui_softkeys_options_back_disable + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = ETlsUiCmdDisable; txt = qtn_msk_wlan_eap_cs_disable; } + }; + } + + +RESOURCE DIALOG r_tls_setting_dialog + { + flags = EEikDialogFlagFillAppClientRect | EEikDialogFlagCbaButtons | + EEikDialogFlagWait | EEikDialogFlagNotifyEsc; + buttons = r_tls_ui_softkeys_options_back_edit; + pages = r_tls_pages; + } + + +// ******* PAGES ************ +RESOURCE ARRAY r_tls_pages + { + items= + { + PAGE + { + id = KEAPTLSSETTINGSPAGE; + text = qtn_wlan_eap_tab_settings; + lines = r_tls_tab_settings; + }, + + PAGE + { + id = KEAPTLSCIPHERPAGE; + text = qtn_wlan_eap_tab_cipher_suites; + lines = r_tls_tab_cipher_suites; + } + }; + } + + +// ******* 1st page ********* +RESOURCE ARRAY r_tls_tab_settings + { + items= + { + DLG_LINE + { + id = ETlsSettingsListbox; + type = EAknCtSettingListBox; + control = LISTBOX + { + flags = EAknListBoxMenuList; + }; + } + }; + } + + +// ******* 2nd page ********* +RESOURCE ARRAY r_tls_tab_cipher_suites + { + items= + { + DLG_LINE + { + id = ETlsSettingsCipherSuiteListbox; + type = EAknCtSingleNumberListBox; + control = LISTBOX + { + flags = EAknGenericListBoxFlags; + //array_id = r_tls_cipher_suite_array; + }; + } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_tls_username_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_username; + type = EEikCtEdwin; + editor_resource_id = r_tls_setting_edwin; + } + + +RESOURCE AVKON_SETTING_PAGE r_tls_realm_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_realm; + type = EEikCtEdwin; + editor_resource_id = r_tls_setting_edwin; + } + + +RESOURCE EDWIN r_tls_setting_edwin + { + flags = 0; + width = 9; + lines = 5; + maxlength = 255; + } + + +RESOURCE MENU_BAR r_tls_menubar + { + titles = + { + MENU_TITLE + { + menu_pane = r_tls_menu_pane; + txt = ""; + } + }; + } + + +RESOURCE MENU_PANE r_tls_menu_pane + { + items = + { + MENU_ITEM + { + command = ETlsUiCmdEnable; + txt = qtn_wlan_options_eap_plugin_enable; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = ETlsUiCmdDisable; + txt = qtn_wlan_options_eap_plugin_disable; + flags = EEikMenuItemSpecific; + }, + + MENU_ITEM + { + command = ETlsUiCmdChange; + txt = qtn_options_change; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = EAknCmdHelp; + txt = qtn_options_help; + }, + + MENU_ITEM + { + command = EAknCmdExit; + txt = qtn_options_exit; + } + }; + } + + +// Resource strings +RESOURCE TBUF r_tls_settings_title { buf = qtn_wlan_eap_tls_title; } +RESOURCE TBUF r_tls_username_inusestring \ + { buf = qtn_wlan_eap_sett_username_inuse; } +RESOURCE TBUF r_tls_username_inusestring_auto \ + { buf = qtn_wlan_eap_sett_username_inuse_from_cert; } +RESOURCE TBUF r_tls_username_inusestring_conf \ + { buf = qtn_wlan_eap_sett_username_inuse_user; } +RESOURCE TBUF r_tls_username_string { buf = qtn_wlan_eap_sett_username; } +RESOURCE TBUF r_tls_realm_inusestring \ + { buf = qtn_wlan_eap_sett_realm_inuse; } +RESOURCE TBUF r_tls_realm_inusestring_auto \ + { buf = qtn_wlan_eap_sett_realm_inuse_from_cert; } +RESOURCE TBUF r_tls_realm_inusestring_conf \ + { buf = qtn_wlan_eap_sett_realm_inuse_user; } +RESOURCE TBUF r_tls_realm_string { buf = qtn_wlan_eap_sett_realm; } +RESOURCE TBUF r_tls_user_cert_setting \ + { buf = qtn_wlan_eap_sett_user_certificate; } +RESOURCE TBUF r_tls_ca_cert_setting \ + { buf = qtn_wlan_eap_sett_ca_certificate; } +RESOURCE TBUF r_tls_not_defined { buf = qtn_wlan_eap_cert_not_defined; } +RESOURCE TBUF r_tls_none_selection \ + { buf = qtn_wlan_eap_cert_none_selection; } +RESOURCE TBUF r_tls_suite_rsarc4md5 { buf = qtn_wlan_eap_cipher_rsarc4md5; } +RESOURCE TBUF r_tls_suite_rsarc4sha { buf = qtn_wlan_eap_cipher_rsarc4sha; } +RESOURCE TBUF r_tls_suite_rsa3dessha \ + { buf = qtn_wlan_eap_cipher_rsa3dessha; } +RESOURCE TBUF r_tls_suite_dhersa3dessha \ + { buf = qtn_wlan_eap_cipher_dhersa3dessha; } +RESOURCE TBUF r_tls_suite_dhedss3dessha \ + { buf = qtn_wlan_eap_cipher_dhedss3dessha; } +RESOURCE TBUF r_tls_suite_rsaaessha { buf = qtn_wlan_eap_cipher_rsaaessha; } +RESOURCE TBUF r_tls_suite_dhersaaessha \ + { buf = qtn_wlan_eap_cipher_dhersaaessha; } +RESOURCE TBUF r_tls_suite_dhedssaessha \ + { buf = qtn_wlan_eap_cipher_dhedssaessha; } + +RESOURCE TBUF r_tls_tls_privacy_string + { buf = qtn_wlan_eap_sett_tls_privacy; } + + +// ******************************************** +// USERNAME IN USE AND REALM POPUP DEFINITION +// ******************************************** +RESOURCE AVKON_POPUP_SETTING_TEXTS r_tls_username_autouseconf_texts + { + setting_texts_resource = r_tls_username_autouseconf_texts_resource; + popped_up_texts_resource = r_tls_username_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_tls_username_autouseconf_texts_resource + { + items = + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_username_inuse_from_cert; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_username_inuse_user; + } + }; + } + + +RESOURCE ARRAY r_tls_username_automatic_useconfigured_array + { + items = + { + LBUF { txt = qtn_wlan_eap_sett_username_inuse_from_cert; }, + LBUF { txt = qtn_wlan_eap_sett_username_inuse_user; } + }; + } + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_tls_realm_autouseconf_texts + { + setting_texts_resource = r_tls_realm_autouseconf_texts_resource; + popped_up_texts_resource = r_tls_realm_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_tls_realm_autouseconf_texts_resource + { + items= + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_realm_inuse_from_cert; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_realm_inuse_user; + } + }; + } + + +RESOURCE ARRAY r_tls_realm_automatic_useconfigured_array + { + items= + { + LBUF { txt = qtn_wlan_eap_sett_realm_inuse_from_cert; }, + LBUF { txt = qtn_wlan_eap_sett_realm_inuse_user; } + }; + } + +RESOURCE ARRAY r_tls_tls_privacy_autouseconf_texts_resource + { + items= + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_tls_privacy_off; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_tls_privacy_on; + } + }; + } + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_tls_tls_privacy_autouseconf_texts + { + setting_texts_resource = r_tls_tls_privacy_autouseconf_texts_resource; + popped_up_texts_resource = r_tls_tls_privacy_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_tls_tls_privacy_automatic_useconfigured_array + { + items = + { + LBUF { txt = qtn_wlan_eap_sett_tls_privacy_off; }, + LBUF { txt = qtn_wlan_eap_sett_tls_privacy_on; } + }; + } + +RESOURCE AVKON_SETTING_PAGE r_tls_display_autouseconf_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + type = EAknCtPopupSettingList; + editor_resource_id = r_tls_setting_enumerated_popup; + } + + +RESOURCE POPUP_SETTING_LIST r_tls_setting_enumerated_popup + { + flags = EAknPopupSettingListFlagInitialised; + } + + +// ******************************************** +// USER&CA CERTIFICATES POPUP DEFINITION +// ******************************************** +RESOURCE AVKON_SETTING_PAGE r_radio_button_setting_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + type = EAknSetListBox; + editor_resource_id= r_setting_listbox; + } + + +RESOURCE LISTBOX r_setting_listbox + { + flags = EEikListBoxMultipleSelection; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/inc/EapTlsUi.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/inc/EapTlsUi.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP TLS UI hrh file +* +*/ + + +#ifndef _EAPTLSUI_HRH_ +#define _EAPTLSUI_HRH_ + +enum TEapTlsUiMenuCommands + { + ETlsUiCmdUndefined = 6000, + ETlsUiCmdChange, + ETlsUiCmdEnable, + ETlsUiCmdDisable, + ETlsUiCmdMoveUp, + ETlsUiCmdMoveDown, + ETlsUiCmdViewDetails + }; + +enum TEapTlsUiNotes + { + TEapTlsUiGeneralError = 6100 + }; + +enum TEapTlsUiLines + { + ETlsSettingsListBox = 6200 + }; + +enum TEapTlsUiSettingIds + { + ETlsSettingUsernameInUseId=6300, + ETlsSettingUsernameId, + ETlsSettingRealmInUseId, + ETlsSettingRealmId, + ETlsSettingTlsPrivacyId + }; + +enum TEapTlsUiSettingPageIds + { + ETlsSettingPageSettings=6400, + ETlsSettingPageCipherSuites + }; + +enum TEapTlsUiListBoxes + { + ETlsSettingsUserCertListbox=6500, + ETlsSettingsCaCertListbox, + ETlsSettingsCipherSuiteListbox, + ETlsSettingsEapTypeListbox, + ETlsSettingsListbox + }; + +enum TEapTlsSettingItems + { + ETlsSettingsUserCert=6600, + ETlsSettingsCaCert, + ETlsTabSheetSettingsUsernameInUse, + ETlsTabSheetSettingsUsername, + ETlsTabSheetSettingsRealmInUse, + ETlsTabSheetSettingsRealm + }; + + +enum TEapTlsTests + { + ETlsTabSheetTest2=6600, + ETlsTabSheetTest3, + ETlsTabSheetTest4, + ETlsTabSheetTest5, + ETlsTabSheetTest6, + ETlsTabSheetTest7 + }; + +// Constants that are used as page ids +// TEapTlsUiSettingPageIds does not work for this purpose +#define KEAPTLSSETTINGSPAGE 1 +#define KEAPTLSCIPHERPAGE 2 + +#endif //_EAPTLSUI_HRH_ + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/inc/EapTlsUiSettingArray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/inc/EapTlsUiSettingArray.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP TLS UI settings array +* +*/ + + + +#ifndef _EAPTLSUISETTINGARRAY_H_ +#define _EAPTLSUISETTINGARRAY_H_ + +// INCLUDES +#include +#include "EapTlsUi.hrh" + + +// CLASS DECLARATION + +/** +*/ +class CEapTlsSettingItemArray : public CBase + { + public: + static CEapTlsSettingItemArray* NewL(); + virtual ~CEapTlsSettingItemArray(); + CAknSettingItem* Item( TEapTlsUiSettingPageIds aItem ); + CAknSettingItemArray* Array(); + void StoreSettingsL(); + void AddTextItemL( TDes& aBuffer, TInt aId, TInt aTitleResource, + TInt aSettingPageResource, TInt aAssociatedResource, + TInt aOrdinal); + + void AddBinarySettingItemL( TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue); + + protected: + CEapTlsSettingItemArray(); + void ConstructL(); + + private: + CAknSettingItemArray* iArray; + }; + +#endif // _EAPTLSUISETTINGARRAY_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/inc/EapTlsUiView.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/inc/EapTlsUiView.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,151 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP TLS UI setting dialog +* +*/ + + + +#ifndef _EAPTLSUIVIEW_H_ +#define _EAPTLSUIVIEW_H_ + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include "EapTlsPeapUiTlsPeapData.h" +#include "EapTlsUi.hrh" +#include "EapTlsPeapUiCipherSuite.h" +#include "EapTlsPeapUiEapType.h" +#include "EapTlsPeapUiCertificate.h" +#include "AbsEapTlsPeapUiCertificates.h" + + +// FORWARD DECLARATIONS +class CAknSettingStyleListBox; +class CSettingsListBoxItemDrawer; +class CEapTlsSettingItemArray; +class CEapTlsPeapUiConnection; +class CEapTlsPeapUiDataConnection; +class CEapTlsPeapUiCipherSuites; +class CEapTlsPeapUiCertificates; +class CEapTlsPeapUiEapTypes; + + +// CLASS DECLARATION + +/** +* Settings dialog class definition +*/ +class CEapTlsUiDialog : public CAknDialog, + public MEapTlsPeapUiCertificates, + public MEikListBoxObserver + { + public: + CEapTlsUiDialog( CEapTlsPeapUiConnection* aConnection, + TInt& aButtonId ); + ~CEapTlsUiDialog(); + + /** + * Create and launch dialog. + * @param aResourceId The resource ID of the dialog to load. + * @return The ID of the button that closed the dialog + */ + TInt ConstructAndRunLD( TInt aResourceId ); + + /** + * Chain into key event handler. + * @param aKeyEvent The event. + * @param aType The type of key event. + * @return Was the key consumed or not. + */ + TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, + TEventCode aType); + + public: // From MEikListBoxObserver + + /** + * Handles list box events. + * @param aListBox The originating list box. + * @param aEventType A code for the event. + */ + void HandleListBoxEventL( CEikListBox* aListBox, TListBoxEvent aEventType ); + + + protected: + void PreLayoutDynInitL(); + void PostLayoutDynInitL(); + TBool OkToExitL( TInt aButtonId ); + void ProcessCommandL( TInt aCommand ); + void PageChangedL( TInt aPageId ); + + private: + void ChangeTitleL( TBool aIsStarted ); + void DrawSettingsListL(); + void ShowSettingPageL( TInt aCalledFromMenu ); + TInt ShowRadioButtonSettingPageL( TInt aTitle, + CDesCArrayFlat* aValues, + TInt aCurrentItem ); + void DrawCipherSuitesL(); + void CompleteReadCertificates( const TInt aResult ); + void CompleteUiConstructionL(); + TInt CheckActiveUserCertificate(); + TInt CheckActiveCaCertificate(); + void UserCertificateHouseKeeping( TInt aSelected ); + void CaCertificateHouseKeeping( TInt aSelected ); + void SetIconsL(); + void GetHelpContext( TCoeHelpContext& aContext ) const; + + void GetFullCertLabel( const SCertEntry& aCert, TDes& aFullLabel ); + + /** + * Initialize menu pane. + * @param aResourceId Menu pane resource id. + * @param CEikMenuPane Menu pane. + */ + void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ); + + + private: + CEapTlsPeapUiConnection* iConnection; + CEapTlsPeapUiDataConnection* iDataConnection; + CEapTlsPeapUiCipherSuites* iCipherSuites; + CEapTlsPeapUiCertificates* iCertificates; + + CEapTlsPeapUiTlsPeapData* iUiData; + CArrayFixFlat * iUiCipherSuites; + CArrayFixFlat * iUiUserCertificates; + CArrayFixFlat * iUiCACertificates; + + CAknSingleNumberStyleListBox* iUserCertificateListBox; + CAknSingleNumberStyleListBox* iCaCertificateListBox; + CAknSingleGraphicStyleListBox* iCipherSuiteListBox; + CEapTlsSettingItemArray* iSettingArray; + CAknSettingStyleListBox* iSettingListBox; + CDesCArray* iCipherSuitesViewArray; + HBufC* iPreviousText; + TInt* iButtonId; + + // Tells the status of UI construction. TRUE if UI construction is completed. + TBool iIsUIConstructionCompleted; + }; + + +#endif //_EAPTLSUIVIEW_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/loc/eaptlsui.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/loc/eaptlsui.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI strings for WLAN EAP-TLS authentication settings +* +*/ + + + +// LOCALISATION STRINGS + + +//d:UI title for main view +//l:title_pane_t2/opt9 +//w: +//r:3.1 +// +#define qtn_wlan_eap_tls_title "EAP-TLS settings" + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUi.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP TLS UI class +* +*/ + + + +// INCLUDE FILES +#include "EapTlsUi.h" +#include "EapTlsPeapUiConnection.h" +#include "EapTlsUiView.h" +#include +#include +#include +#include +#include + + +// CONSTANTS +_LIT( KDriveZ, "z:" ); // ROM folder +_LIT( KResourceFileName, "eaptlsui.rsc" ); + + +// CLASS DECLARATION +class TResourceFileCleanupItem + { + public: + CCoeEnv* iCoeEnv; + TInt iResourceFileOffset; + }; + + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CleanupResourceFile +// ----------------------------------------------------------------------------- +// +static void CleanupResourceFile( TAny* aObject ) + { + TResourceFileCleanupItem* item = + REINTERPRET_CAST( TResourceFileCleanupItem*, aObject ); + item->iCoeEnv->DeleteResourceFile( item->iResourceFileOffset ); + delete item; + } + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapTlsUi::CEapTlsUi +// ----------------------------------------------------------------------------- +// +CEapTlsUi::CEapTlsUi( CEapTlsPeapUiConnection* aConnection ) +: iConnection( aConnection ) + { + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUi::NewL +// ----------------------------------------------------------------------------- +// +CEapTlsUi* CEapTlsUi::NewL( CEapTlsPeapUiConnection* aConnection ) + { + CEapTlsUi* self = new ( ELeave ) CEapTlsUi( aConnection ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUi::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapTlsUi::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUi::~CEapTlsUi +// ----------------------------------------------------------------------------- +// +CEapTlsUi::~CEapTlsUi() + { + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUi::InvokeUiL +// ----------------------------------------------------------------------------- +// +TInt CEapTlsUi::InvokeUiL() + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + CCoeEnv* coeEnv = CCoeEnv::Static(); + BaflUtils::NearestLanguageFile( coeEnv->FsSession(), fileName ); + + TResourceFileCleanupItem* item = new( ELeave ) TResourceFileCleanupItem; + + item->iCoeEnv = coeEnv; + CleanupStack::PushL( TCleanupItem( CleanupResourceFile, item ) ); + item->iResourceFileOffset = coeEnv->AddResourceFileL( fileName ); + + TInt buttonId; + CEapTlsUiDialog* settingsDlg = new( ELeave ) CEapTlsUiDialog( iConnection, + buttonId ); + settingsDlg->ConstructAndRunLD( R_TLS_SETTING_DIALOG ); + + CleanupStack::PopAndDestroy(); // For resource file + + return buttonId; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUiSettingArray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUiSettingArray.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,183 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP TLS UI settings array +* +*/ + + + +// INCLUDE FILES +#include "EapTlsUiSettingArray.h" +#include "EapTlsUi.hrh" +#include +#include + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapTlsSettingItemArray::CEapTlsSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapTlsSettingItemArray::CEapTlsSettingItemArray() + { + } + + +// ----------------------------------------------------------------------------- +// CEapTlsSettingItemArray::NewL +// ----------------------------------------------------------------------------- +// +CEapTlsSettingItemArray* CEapTlsSettingItemArray::NewL() + { + CEapTlsSettingItemArray* self = new( ELeave ) CEapTlsSettingItemArray(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); // self + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapTlsSettingItemArray::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapTlsSettingItemArray::ConstructL() + { + iArray = new( ELeave ) CAknSettingItemArray( 2, EFalse, 0 ); + } + + +// ----------------------------------------------------------------------------- +// CEapTlsSettingItemArray::~CEapTlsSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapTlsSettingItemArray::~CEapTlsSettingItemArray() + { + if( iArray ) + { + // ResetAndDestroy() + iArray->ResetAndDestroy(); + } + delete iArray; + iArray = NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapTlsSettingItemArray::Item +// ----------------------------------------------------------------------------- +// +CAknSettingItem* CEapTlsSettingItemArray::Item( TEapTlsUiSettingPageIds aId ) + { + for( TInt i = 0; i < iArray->Count(); i++ ) + { + if( iArray->At( i )->Identifier() == aId ) + { + return iArray->At( i ); + } + } + + __ASSERT_DEBUG( EFalse, User::Invariant() ); + return NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapTlsSettingItemArray::Array +// ----------------------------------------------------------------------------- +// +CAknSettingItemArray* CEapTlsSettingItemArray::Array() + { + return iArray; + } + + +// ----------------------------------------------------------------------------- +// CEapTlsSettingItemArray::StoreSettingsL +// ----------------------------------------------------------------------------- +// +void CEapTlsSettingItemArray::StoreSettingsL() + { + // Do what SettingItemList::StoreSettings would do. + for ( TInt i( 0 ); i < iArray->Count(); ++i) + { + iArray->At( i )->StoreL(); + } + } + + +// ----------------------------------------------------------------------------- +// CEapTlsSettingItemArray::AddTextItemL +// ----------------------------------------------------------------------------- +// +void CEapTlsSettingItemArray::AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal ) + { + // Create new setting item + CAknTextSettingItem* settingItem = new( ELeave ) CAknTextSettingItem( aId, + aBuffer ); + CleanupStack::PushL( settingItem ); + settingItem->SetEmptyItemTextL( KNullDesC ); + settingItem->SetSettingPageFlags( + CAknTextSettingPage::EZeroLengthAllowed ); + + // Construct setting item with parametrized values + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResource ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResource, EAknCtPopupSettingList, + NULL, aAssociatedResource ); + + // Append item to settingitem-array + iArray->InsertL( aOrdinal, settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + + // Items are destroyed in destructor when resetting array + CleanupStack::Pop( settingItem ); + } + + +// ----------------------------------------------------------------------------- +// CEapTlsSettingItemArray::AddBinarySettingItemL +// ----------------------------------------------------------------------------- +// +void CEapTlsSettingItemArray::AddBinarySettingItemL( + TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue ) + { + CAknSettingItem* settingItem = new ( ELeave ) + CAknBinaryPopupSettingItem( 0, aModifiedValue ); + CleanupStack::PushL( settingItem ); + + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResourceId ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResourceId, EAknCtPopupSettingList, + NULL, aAssociatedResourceId ); + iArray->AppendL( settingItem ); + CleanupStack::PopAndDestroy( itemTitle ); + CleanupStack::Pop( settingItem ); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUiView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUiView.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1265 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP TLS UI settings dialog +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include "EapTlsUiView.h" +#include "EapTlsUi.hrh" +#include +#include +#include +#include "EapTlsUiSettingArray.h" +#include +#include +#include +#include // TEMPORARY, for info message... +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +// CONSTANTS +// UID of general settings app, in which help texts are included +const TUid KHelpUidPlugin = { 0x100058EC }; + +static const TInt KSuiteArrayGranularity = 4; +static const TInt KCertificateArrayGranularity = 5; +static const TInt KMaxLengthOfSuiteName = 255; + +_LIT( KNameSeparator, " " ); +_LIT( KEmptyString, "" ); + +/* This is the maximum length of a certificate's full name, includes +label, primary and secondary names */ +const TUint32 KMaxFullCertLabelLength = KMaxCertLabelLength + 2 * + KMaxNameLength + 1; // 1 is for separator. + +// MODULE DATA STRUCTURES +enum TPageIds + { + ESettingsPage = 0, + ECipherSuitePage + }; + +enum TSettingIds + { + EUserCertificateItem = 0, + ECaCertificateItem, + EUsernameInUseItem, + EUsernameItem, + ERealmInUseItem, + ERealmItem + }; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::CEapTlsUiDialog +// ----------------------------------------------------------------------------- +// +CEapTlsUiDialog::CEapTlsUiDialog( CEapTlsPeapUiConnection* aConnection, + TInt& aButtonId ) +: CAknDialog(), + iConnection( aConnection ), + iDataConnection( 0 ), + iCipherSuites( 0 ), + iCertificates( 0 ), + iUserCertificateListBox( 0 ), + iCaCertificateListBox( 0 ), + iCipherSuiteListBox( 0 ), + iSettingArray( 0 ), + iSettingListBox( 0 ), + iCipherSuitesViewArray( 0 ), + iPreviousText( 0 ), + iButtonId( &aButtonId ), + iIsUIConstructionCompleted( EFalse ) + { + } + + +// --------------------------------------------------------- +// CEapTlsUiDialog::ConstructAndRunLD +// --------------------------------------------------------- +// +TInt CEapTlsUiDialog::ConstructAndRunLD( TInt aResourceId ) + { + CleanupStack::PushL( this ); + + iSettingArray = CEapTlsSettingItemArray::NewL(); + + User::LeaveIfError( iConnection->Connect() ); + + // Basic data + iDataConnection = iConnection->GetDataConnection(); + if ( iDataConnection == 0 ) + { + User::Leave( KErrNoMemory ); + } + User::LeaveIfError( iDataConnection->Open() ); + User::LeaveIfError( iDataConnection->GetData( &iUiData ) ); + + // Cipher suites + iCipherSuites = iConnection->GetCipherSuiteConnection(); + if ( iCipherSuites == 0 ) + { + User::Leave( KErrNoMemory ); + } + User::LeaveIfError( iCipherSuites->Open() ); + User::LeaveIfError( iCipherSuites->GetCipherSuites( &iUiCipherSuites ) ); + + iCipherSuitesViewArray = new( ELeave ) CDesCArrayFlat( + KSuiteArrayGranularity ); + + FeatureManager::InitializeLibL(); + + ConstructL( R_TLS_MENUBAR ); + + // ExecuteLD will PushL( this ), so we have to Pop it... + CleanupStack::Pop( this ); // this + + return CAknDialog::ExecuteLD( aResourceId ); + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::OfferKeyEventL +// ----------------------------------------------------------------------------- +// +TKeyResponse CEapTlsUiDialog::OfferKeyEventL( const TKeyEvent& aKeyEvent, + TEventCode aType ) + { + TKeyResponse result( EKeyWasNotConsumed ); + + TInt pageId = ActivePageId(); + if ( aType == EEventKey && pageId == KEAPTLSCIPHERPAGE ) + { + TInt indexBefore = iCipherSuiteListBox->CurrentItemIndex(); + + // Handle Enter key here, since it doesn't seem to convert into + // the proper command id via the normal route + // (maybe some Avkon support for Enter key is still missing in + // S60 3.2 2008_wk22) + if ( aKeyEvent.iCode == EKeyEnter ) + { + if ( ( *iUiCipherSuites )[indexBefore].iIsEnabled ) + { + OkToExitL( ETlsUiCmdDisable ); + } + else + { + OkToExitL( ETlsUiCmdEnable ); + } + + result = EKeyWasConsumed; + } + else + { + result = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + + TInt indexAfter = iCipherSuiteListBox->CurrentItemIndex(); + + if ( indexBefore != indexAfter ) + { + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + if( ( *iUiCipherSuites )[ indexAfter ].iIsEnabled ) + { + cba.SetCommandSetL( R_TLS_UI_SOFTKEYS_OPTIONS_BACK_DISABLE ); + } + else + { + cba.SetCommandSetL( R_TLS_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + } + + cba.DrawDeferred(); + } + } + else + { + result = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + + return result; + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::~CEapTlsUiDialog +// ----------------------------------------------------------------------------- +// +CEapTlsUiDialog::~CEapTlsUiDialog() + { + if ( iSettingArray ) + { + iSettingArray->Array()->ResetAndDestroy(); + } + + delete iSettingArray; + iSettingListBox = 0; + + iDataConnection->Close(); + delete iDataConnection; + + iCipherSuites->Close(); + delete iCipherSuites; + + iCertificates->Close(); + delete iCertificates; + + iConnection->Close(); + + iCipherSuitesViewArray->Reset(); + delete iCipherSuitesViewArray; + + delete iPreviousText; + + FeatureManager::UnInitializeLib(); + } + + +// --------------------------------------------------------- +// CEapTlsUiDialog::HandleListBoxEventL +// --------------------------------------------------------- +// +void CEapTlsUiDialog::HandleListBoxEventL( CEikListBox* aListBox, + TListBoxEvent aEventType ) + { + switch ( aEventType ) + { + case EEventEnterKeyPressed: + case EEventItemSingleClicked: + { + if ( aListBox == iSettingListBox ) + { + OkToExitL( ETlsUiCmdChange ); + } + + else if ( aListBox == iCipherSuiteListBox ) + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + if( iUiCipherSuites->At( index ).iIsEnabled ) + { + OkToExitL( ETlsUiCmdDisable ); + } + else + { + OkToExitL( ETlsUiCmdEnable ); + } + } + + else + { + // Do nothing; we should never end up here + } + + break; + } + + case EEventItemActioned: + case EEventEditingStarted: + case EEventEditingStopped: + case EEventPenDownOnItem: + case EEventItemDraggingActioned: + { + break; + } + + default: + { + break; + }; + }; + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::PreLayoutDynInitL +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::PreLayoutDynInitL() + { + // Change title + ChangeTitleL( ETrue ); + + iSettingListBox = static_cast( + ControlOrNull( ETlsSettingsListbox ) ); + iSettingListBox->SetComponentsToInheritVisibility( ETrue ); + + iCipherSuiteListBox = static_cast( + ControlOrNull( ETlsSettingsCipherSuiteListbox ) ); + iCipherSuiteListBox->SetComponentsToInheritVisibility( ETrue ); + + // Certificates + iCertificates = iConnection->GetCertificateConnection( this ); + User::LeaveIfError( iCertificates->Open() ); + iCertificates->GetCertificates( &iUiUserCertificates, &iUiCACertificates ); + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::CompleteReadCertificates +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::CompleteReadCertificates( const TInt aResult ) + { + if ( aResult == KErrNone ) // Certifiocates are received from core + { + TRAPD( err, CompleteUiConstructionL() ); + if ( err != KErrNone) + { + TRAP_IGNORE( TryExitL( KErrCancel ) ); + } + } + else + { + TRAP_IGNORE( TryExitL( KErrCancel ) ); + } + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::CompleteUiConstructionL +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::CompleteUiConstructionL() + { + // Initialize setting page + iSettingListBox = static_cast( + ControlOrNull( ETlsSettingsListbox ) ); + iSettingListBox->SetMopParent( this ); + iSettingListBox->CreateScrollBarFrameL( ETrue ); + iSettingListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iSettingListBox->SetListBoxObserver( this ); + DrawSettingsListL(); + + // Initialize cipher suites page + iCipherSuiteListBox = static_cast( + ControlOrNull( ETlsSettingsCipherSuiteListbox ) ); + iCipherSuiteListBox->CreateScrollBarFrameL( ETrue ); + iCipherSuiteListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iCipherSuiteListBox->UpdateScrollBarsL(); + + iCipherSuiteListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iCipherSuiteListBox->SetListBoxObserver( this ); + + //Following deletes internal array created from resources. + // To prevent memory leak. + MDesCArray* internalArray = iCipherSuiteListBox->Model()->ItemTextArray(); + delete internalArray; + + SetIconsL(); + DrawCipherSuitesL(); + + iIsUIConstructionCompleted = ETrue; + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::PostLayoutDynInitL +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::PostLayoutDynInitL() + { + TUid naviPaneUid; + naviPaneUid.iUid = EEikStatusPaneUidNavi; + + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( naviPaneUid ); + if ( subPane.IsPresent() && subPane.IsAppOwned() ) + { + CAknNavigationControlContainer* naviPane = + static_cast( + statusPane->ControlL( naviPaneUid ) ); + CAknNavigationDecorator* naviDecorator = naviPane->ResourceDecorator(); + if ( naviDecorator ) + { + CAknTabGroup* tabGroup = static_cast( + naviDecorator->DecoratedControl() ); + tabGroup->SetActiveTabById( 0 ); + tabGroup->SetTabFixedWidthL( KTabWidthWithOneTab ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::ChangeTitleL +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::ChangeTitleL( TBool aIsStarted ) + { + TUid titlePaneUid; + titlePaneUid.iUid = EEikStatusPaneUidTitle; + + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( titlePaneUid ); + + if ( subPane.IsPresent() && subPane.IsAppOwned() ) + { + CAknTitlePane* titlePane = static_cast( + statusPane->ControlL( titlePaneUid ) ); + if ( aIsStarted ) + { + // Store previous application title text + const TDesC* prevText = titlePane->Text(); + iPreviousText = HBufC::NewL( prevText->Length() ); + iPreviousText->Des().Append( *prevText ); + + TDesC* titleText = iEikonEnv->AllocReadResourceLC( + R_TLS_SETTINGS_TITLE ); + titlePane->SetTextL( *titleText ); + CleanupStack::PopAndDestroy( titleText ); + } + else + { + // Set calling application title text back + titlePane->SetTextL( *iPreviousText ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CEapTlsUiDialog::OkToExitL( TInt aButtonId ) + { + TBool ret( EFalse ); + switch ( aButtonId ) + { + case EEikBidOk: + { + if( iIsUIConstructionCompleted ) + { + TPageIds index = static_cast( ActivePageIndex() ); + if ( index == ESettingsPage ) + { + ShowSettingPageL( EFalse ); + } + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapTlsUiDialog::OkToExitL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + case EAknSoftkeyOptions: + { + DisplayMenuL(); + break; + } + + case EAknSoftkeyBack: + case EAknCmdExit: + { + if( iIsUIConstructionCompleted ) + { + iDataConnection->Update(); + ChangeTitleL( EFalse ); + ret = ETrue; + } + break; + } + + case ETlsUiCmdChange: + { + TPageIds index = static_cast( ActivePageIndex() ); + if ( index == ESettingsPage ) + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( EFalse ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapPeapUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + } + break; + } + case ETlsUiCmdEnable: + case ETlsUiCmdDisable: + { + ProcessCommandL( aButtonId ); + ret = EFalse; + break; + } + + default: + { + break; + } + } + + if ( ret ) + { + *iButtonId = aButtonId; + } + + return ret; + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::DrawSettingsListL +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::DrawSettingsListL() + { + iSettingArray->Array()->ResetAndDestroy(); + TInt ordinal = 0; + + TInt activeUserCertificate = CheckActiveUserCertificate(); + TBuf aActiveuserCertificateName = KEmptyString(); + if ( activeUserCertificate != KErrNotFound ) + { + TBuf text; + GetFullCertLabel( + iUiUserCertificates->At( activeUserCertificate ).iCertEntry, + text ); + aActiveuserCertificateName.Copy( text ); + } + else + { + TDesC* notDefinedText = iEikonEnv->AllocReadResourceLC( + R_TLS_NOT_DEFINED ); + aActiveuserCertificateName.Copy( *notDefinedText ); + CleanupStack::PopAndDestroy( notDefinedText ); + } + + iSettingArray->AddTextItemL( aActiveuserCertificateName, + ETlsSettingsUserCert, + R_TLS_USER_CERT_SETTING, + R_TLS_USERNAME_PAGE, + NULL, + ordinal++ ); + + TInt activeCaCertificate = CheckActiveCaCertificate(); + TBuf aActiveCaCertificateName = KEmptyString(); + if ( activeCaCertificate != KErrNotFound ) + { + TBuf text; + GetFullCertLabel( + iUiCACertificates->At( activeCaCertificate ).iCertEntry, + text ); + aActiveCaCertificateName.Copy( text ); + } + else + { + TDesC* notDefinedText = iEikonEnv->AllocReadResourceLC( + R_TLS_NOT_DEFINED ); + aActiveCaCertificateName.Copy( *notDefinedText ); + CleanupStack::PopAndDestroy( notDefinedText ); + } + + iSettingArray->AddTextItemL( aActiveCaCertificateName, + ETlsSettingsCaCert, + R_TLS_CA_CERT_SETTING, + R_TLS_USERNAME_PAGE, + NULL, + ordinal++ ); + + iSettingArray->AddBinarySettingItemL( R_TLS_DISPLAY_AUTOUSECONF_PAGE, + R_TLS_USERNAME_INUSESTRING, + R_TLS_USERNAME_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetUseManualUsername() ); + + iSettingArray->AddTextItemL( iUiData->GetManualUsername(), + ETlsTabSheetSettingsUsername, + R_TLS_USERNAME_STRING, + R_TLS_USERNAME_PAGE, + NULL, + ordinal++ ); + + iSettingArray->AddBinarySettingItemL( R_TLS_DISPLAY_AUTOUSECONF_PAGE, + R_TLS_REALM_INUSESTRING, + R_TLS_REALM_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetUseManualRealm() ); + + iSettingArray->AddTextItemL( iUiData->GetManualRealm(), + ETlsTabSheetSettingsRealm, + R_TLS_REALM_STRING, + R_TLS_REALM_PAGE, + NULL, + ordinal++ ); + + iSettingArray->AddBinarySettingItemL( R_TLS_DISPLAY_AUTOUSECONF_PAGE, + R_TLS_TLS_PRIVACY_STRING, + R_TLS_TLS_PRIVACY_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetTlsPrivacy() ); + + iSettingListBox->Model()->SetItemTextArray( iSettingArray->Array() ); + iSettingListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iSettingArray->Array()->RecalculateVisibleIndicesL(); + iSettingListBox->HandleItemAdditionL(); + iSettingListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::DynInitMenuPaneL +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + CAknDialog::DynInitMenuPaneL( aResourceId, aMenuPane ); + + if ( aMenuPane && aResourceId == R_TLS_MENU_PANE ) + { + if ( !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + + TPageIds index = static_cast( ActivePageIndex() ); + if ( index == ESettingsPage ) + { + aMenuPane->SetItemDimmed( ETlsUiCmdEnable, ETrue ); + aMenuPane->SetItemDimmed( ETlsUiCmdDisable, ETrue ); + } + else if ( index == ECipherSuitePage ) + { + aMenuPane->SetItemDimmed( ETlsUiCmdChange, ETrue ); + + if ( iCipherSuitesViewArray->Count() > 0 ) + { + TInt currIndex = iCipherSuiteListBox->CurrentItemIndex(); + TBool enabled = iUiCipherSuites->At( currIndex ).iIsEnabled; + + // Hide either "Enable" or "Disable", as appropriate. + aMenuPane->SetItemDimmed( ETlsUiCmdEnable, enabled ); + aMenuPane->SetItemDimmed( ETlsUiCmdDisable, !enabled ); + } + else + { + aMenuPane->SetItemDimmed( ETlsUiCmdEnable, ETrue ); + aMenuPane->SetItemDimmed( ETlsUiCmdDisable, ETrue ); + } + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::ProcessCommandL( TInt aCommand ) + { + if ( MenuShowing() ) + { + HideMenu(); + } + + TPageIds pageIndex = static_cast( ActivePageIndex() ); + switch( aCommand ) + { + case EAknCmdExit: + { + TryExitL( aCommand ); + break; + } + + case EAknCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + iEikonEnv->EikAppUi()->AppHelpContextL() ); + break; + } + + case ETlsUiCmdChange: + { + if ( pageIndex == ESettingsPage ) + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( ETrue ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapTlsUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + } + break; + } + + case ETlsUiCmdEnable: + { + if ( pageIndex == ECipherSuitePage ) // Safety check in tls. + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + iUiCipherSuites->At( index ).iIsEnabled = ETrue; + iCipherSuites->Update(); + DrawCipherSuitesL(); + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + cba.SetCommandSetL( R_TLS_UI_SOFTKEYS_OPTIONS_BACK_DISABLE ); + cba.DrawDeferred(); + } + break; + } + + case ETlsUiCmdDisable: + { + if ( pageIndex == ECipherSuitePage ) // Safety check in tls. + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + iUiCipherSuites->At( index ).iIsEnabled = EFalse; + iCipherSuites->Update(); + DrawCipherSuitesL(); + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + cba.SetCommandSetL( R_TLS_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + cba.DrawDeferred(); + } + break; + } + + default: + { + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::PageChangedL +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::PageChangedL( TInt aPageId ) + { + if ( !iIsUIConstructionCompleted ) + { + return; + } + + if ( aPageId == KEAPTLSSETTINGSPAGE ) + { + if (iSettingListBox->ScrollBarFrame()) + { + iSettingListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(ETrue); + } + if (iCipherSuiteListBox->ScrollBarFrame()) + { + iCipherSuiteListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + } + + else if ( aPageId == KEAPTLSCIPHERPAGE ) + { + if (iSettingListBox->ScrollBarFrame()) + { + iSettingListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + if (iCipherSuiteListBox->ScrollBarFrame()) + { + iCipherSuiteListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(ETrue); + } + } + + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + if( aPageId == KEAPTLSSETTINGSPAGE ) + { + cba.SetCommandSetL( R_TLS_UI_SOFTKEYS_OPTIONS_BACK_EDIT ); + } + else if( aPageId == KEAPTLSCIPHERPAGE ) + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + if( ( *iUiCipherSuites )[ index ].iIsEnabled ) + { + cba.SetCommandSetL( R_TLS_UI_SOFTKEYS_OPTIONS_BACK_DISABLE ); + } + else + { + cba.SetCommandSetL( R_TLS_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + } + } + cba.DrawDeferred(); + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::ShowSettingPageL +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::ShowSettingPageL( TInt aCalledFromMenu ) + { + TInt index = iSettingListBox->CurrentItemIndex(); + if ( index == EUserCertificateItem ) + { + TInt activeUserCertificate = CheckActiveUserCertificate(); + CDesCArrayFlat* tempArray = new( ELeave )CDesCArrayFlat( + KCertificateArrayGranularity ); + CleanupStack::PushL( tempArray ); + + TDesC* noneText = iEikonEnv->AllocReadResourceLC( + R_TLS_NONE_SELECTION ); + tempArray->InsertL( 0, *noneText ); + CleanupStack::PopAndDestroy( noneText ); + + for ( TInt i = 0; i < iUiUserCertificates->Count() ; i++ ) + { + TEapTlsPeapUiCertificate certificate = + iUiUserCertificates->At( i ); + SCertEntry entry = certificate.iCertEntry; + TBuf text; + GetFullCertLabel( entry, text); + tempArray->InsertL( i+1, text ); + } + + TInt selected( 0 ); + if ( activeUserCertificate == KErrNotFound ) + { + selected = ShowRadioButtonSettingPageL( R_TLS_USER_CERT_SETTING, + tempArray, 0 ); + } + else + { + selected = ShowRadioButtonSettingPageL( R_TLS_USER_CERT_SETTING, + tempArray, + activeUserCertificate+1 ); + //Plus 1 cause we added 'none' selection + } + + CleanupStack::PopAndDestroy( tempArray ); + UserCertificateHouseKeeping( selected ); + iCertificates->Update(); + DrawSettingsListL(); // List must be drawn again at this stage + } + else if ( index == ECaCertificateItem ) + { + TInt activeCaCertificate = CheckActiveCaCertificate(); + + CDesCArrayFlat* tempArray = new( ELeave )CDesCArrayFlat( + KCertificateArrayGranularity ); + CleanupStack::PushL( tempArray ); + + TDesC* noneText = iEikonEnv->AllocReadResourceLC( + R_TLS_NONE_SELECTION ); + tempArray->InsertL( 0, *noneText ); + CleanupStack::PopAndDestroy( noneText ); + + for ( TInt i = 0; i < iUiCACertificates->Count(); i++ ) + { + TEapTlsPeapUiCertificate certificate = iUiCACertificates->At( i ); + SCertEntry entry = certificate.iCertEntry; + TBuf text; + GetFullCertLabel( entry, text ); + tempArray->InsertL( i+1, text ); + } + + TInt selected( 0 ); + if ( activeCaCertificate == KErrNotFound ) + { + selected = ShowRadioButtonSettingPageL( R_TLS_CA_CERT_SETTING, + tempArray, 0 ); + } + else + { + selected = ShowRadioButtonSettingPageL( R_TLS_CA_CERT_SETTING, + tempArray, + activeCaCertificate+1 ); + //Plus 1 cause we added 'none' selection + } + + CleanupStack::PopAndDestroy( tempArray ); + CaCertificateHouseKeeping( selected ); + iCertificates->Update(); + DrawSettingsListL(); // List must be drawn again at this stage + } + else + { + CAknSettingItem* item = iSettingArray->Array()->At( index ); + item->EditItemL( aCalledFromMenu ); + item->StoreL(); + } + DrawNow(); + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::ShowRadioButtonSettingPageL +// ----------------------------------------------------------------------------- +// +TInt CEapTlsUiDialog::ShowRadioButtonSettingPageL( TInt aTitle, + CDesCArrayFlat* aValues, + TInt aCurrentItem ) + { + // title of the dialog + HBufC* title = iCoeEnv->AllocReadResourceLC( aTitle ); + + // We have everything to create dialog + CAknRadioButtonSettingPage* dlg = new( ELeave )CAknRadioButtonSettingPage( + R_RADIO_BUTTON_SETTING_PAGE, + aCurrentItem, + aValues ); + CleanupStack::PushL( dlg ); + dlg->SetSettingTextL( *title ); + CleanupStack::Pop( dlg ); + dlg->ExecuteLD( CAknSettingPage::EUpdateWhenChanged ); + CleanupStack::PopAndDestroy( title ); + // index must be re-turned upside down, because options list is upside down + return aCurrentItem; + } + + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::DrawCipherSuitesL +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::DrawCipherSuitesL() + { + iCipherSuitesViewArray->Reset(); + TInt listCount( 0 ); + TBuf temp; + + for ( TInt i = 0; i < iUiCipherSuites->Count() ; i++ ) + { + temp.Zero(); + _LIT( KTab, "\t" ); + temp.Append( KTab ); + TEapTlsPeapUiCipherSuite suite = iUiCipherSuites->At( i ); + TUint32 suiteId = suite.iCipherSuite; + + switch ( suiteId ) + { + case 0x0004: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TLS_SUITE_RSARC4MD5 ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0005: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TLS_SUITE_RSARC4SHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x000a: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TLS_SUITE_RSA3DESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0016: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TLS_SUITE_DHERSA3DESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0013: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TLS_SUITE_DHEDSS3DESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x002F: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TLS_SUITE_RSAAESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0032: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TLS_SUITE_DHERSAAESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0033: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TLS_SUITE_DHEDSSAESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + default: + { + temp.Append( KEmptyString ); + break; + } + + } + + if (iUiCipherSuites->At( i ).iIsEnabled) + { + // Add mark icon to indicate that the suite is enabled + _LIT( KTab0, "\t0" ); + temp.Append( KTab0 ); + } + + iCipherSuitesViewArray->InsertL( listCount, temp ); + listCount++; + } + + iCipherSuiteListBox->Model()->SetItemTextArray( iCipherSuitesViewArray ); + iCipherSuiteListBox->HandleItemAdditionL(); + iCipherSuiteListBox->DrawDeferred(); + iCipherSuiteListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::CheckActiveUserCertificate +// ----------------------------------------------------------------------------- +// +TInt CEapTlsUiDialog::CheckActiveUserCertificate() + { + for ( TInt i = 0; i < iUiUserCertificates->Count(); i++ ) + { + if ( iUiUserCertificates->At( i ).iIsEnabled ) + { + return i; + } + } + + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::CheckActiveCaCertificate +// ----------------------------------------------------------------------------- +// +TInt CEapTlsUiDialog::CheckActiveCaCertificate() + { + for ( TInt i = 0; i < iUiCACertificates->Count(); i++ ) + { + if ( iUiCACertificates->At( i ).iIsEnabled ) + { + return i; + } + } + + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::UserCertificateHouseKeeping +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::UserCertificateHouseKeeping( TInt aSelected ) + { + for ( TInt i = 0; i < iUiUserCertificates->Count(); i++ ) + { + iUiUserCertificates->At( i ).iIsEnabled = EFalse; + } + + if ( aSelected != 0 ) // Zero index is none + { + iUiUserCertificates->At( aSelected-1 ).iIsEnabled = ETrue; + } + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::CaCertificateHouseKeeping +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::CaCertificateHouseKeeping( TInt aSelected ) + { + for ( TInt i = 0; i < iUiCACertificates->Count(); i++ ) + { + iUiCACertificates->At( i ).iIsEnabled = EFalse; + } + + if ( aSelected != 0 ) // Zero index is none + { + iUiCACertificates->At( aSelected-1 ).iIsEnabled = ETrue; + } + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::SetIconsL +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::SetIconsL() + { + CArrayPtr< CGulIcon >* icons = new( ELeave ) CAknIconArray( 1 ); + CleanupStack::PushL( icons ); + + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + +/* icons->AppendL( AknsUtils::CreateGulIconL( skinInstance, + KAknsIIDQgnIndiMarkedAdd, + AknIconUtils::AvkonIconFileName(), + EMbmAvkonQgn_indi_marked_add, + EMbmAvkonQgn_indi_marked_add_mask ) ); +*/ + + CGulIcon* icon = CGulIcon::NewLC(); + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + AknsUtils::CreateColorIconL( skinInstance, + KAknsIIDQgnIndiMarkedAdd, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG13, + bitmap, + mask, + AknIconUtils::AvkonIconFileName(), + EMbmAvkonQgn_indi_marked_add, + EMbmAvkonQgn_indi_marked_add_mask, + KRgbBlack ); + icon->SetBitmap( bitmap ); + icon->SetMask( mask ); + icons->AppendL( icon ); + + CleanupStack::Pop( icon ); + CleanupStack::Pop( icons ); // icons + + iCipherSuiteListBox->ItemDrawer()->ColumnData()->SetIconArray( icons ); + + } + + +// ----------------------------------------------------------------------------- +// CEapTlsUiDialog::GetHelpContext +// ----------------------------------------------------------------------------- +// +void CEapTlsUiDialog::GetHelpContext( TCoeHelpContext& aContext ) const + { + aContext.iMajor = KHelpUidPlugin; + TPageIds index = static_cast< TPageIds >( ActivePageIndex() ); + switch ( index ) + { + case ECipherSuitePage: + { + aContext.iContext = KSET_HLP_WLAN_EAP_TLS_SUITES; + break; + } + + default: + { + aContext.iContext = KSET_HLP_WLAN_EAP_TLS_SETT; + break; + } + } + } + + + +void CEapTlsUiDialog::GetFullCertLabel( const SCertEntry& aCert, + TDes& aFullLabel ) + { + TInt length = 0; + + // For label. + length += aCert.iLabel.Length(); + + // For separator between label and primary name. + length += KNameSeparator.iTypeLength; + + // For primary name. + length += aCert.iPrimaryName.Length(); + + if ( !( aCert.iLabel.Length() ) ) + { + // For secondary name. + length += aCert.iSecondaryName.Length(); + } + + if( length > aFullLabel.MaxLength() ) + { +#if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapTlsUiDialog::GetFullCertLabel - ERROR! Length Mismatch in Certificate's full name\n") ); +#endif + } + + HBufC* label = NULL; + TRAPD(err, label = HBufC::NewL( length )); + if (err) + { +#if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapTlsUiDialog::GetFullCertLabel - ERROR! LEAVE: HBufC::NewL\n") ); +#endif + return; + } + label->Des().Append( aCert.iLabel ); + + label->Des().Append( KNameSeparator ); + label->Des().Append( aCert.iPrimaryName ); + + if ( !( aCert.iLabel.Length() ) ) + { + // Secondary name, only if no label. Certificate manager does the same way. + label->Des().Append( aCert.iSecondaryName ); + } + + aFullLabel.Copy( label->Des().Left( aFullLabel.MaxLength() ) ); + + delete label; + label = NULL; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/data/EapTtlsUi.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/data/EapTtlsUi.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,471 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP TTLS UI resource file +* +*/ + + + +CHARACTER_SET UTF8 + +// RESOURCE IDENTIFIER +NAME ETTL + +// INCLUDES +#include +#include "EapTtlsUi.hrh" // Enums for these resources +#include // Localisation file +#include +#include +#include +#include +#include +#include + + +// CONSTANTS +#define KUsernameMaxNameLength 255 + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + + +RESOURCE TBUF16 { buf=""; } + + +RESOURCE CBA r_ttls_ui_softkeys_options_back_edit + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = ETtlsUiCmdChange; txt = qtn_msk_change; } + }; + } + + +RESOURCE CBA r_ttls_ui_softkeys_options_back_configure + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = ETtlsUiCmdConfigure; txt = qtn_msk_wlan_eap_configure; } + }; + } + + +RESOURCE CBA r_ttls_ui_softkeys_options_back_enable + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = ETtlsUiCmdEnable; txt = qtn_msk_wlan_eap_cs_enable; } + }; + } + + +RESOURCE CBA r_ttls_ui_softkeys_options_back_disable + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = ETtlsUiCmdDisable; txt = qtn_msk_wlan_eap_cs_disable; } + }; + } + + +RESOURCE DIALOG r_ttls_setting_dialog + { + flags = EEikDialogFlagFillAppClientRect | EEikDialogFlagCbaButtons | + EEikDialogFlagWait | EEikDialogFlagNotifyEsc; + buttons = r_ttls_ui_softkeys_options_back_edit; + pages = r_ttls_pages; + } + + +RESOURCE ARRAY r_ttls_pages + { + items= + { + PAGE + { + id = KEAPTTLSSETTINGSPAGE; + text = qtn_wlan_eap_tab_settings; + lines = r_ttls_tab_settings; + }, + + PAGE + { + id = KEAPTTLSEAPPAGE; + text = qtn_wlan_eap_tab_eap_types; + lines = r_ttls_tab_eap_types; + }, + + PAGE + { + id = KEAPTTLSCIPHERPAGE; + text = qtn_wlan_eap_tab_cipher_suites; + lines = r_ttls_tab_cipher_suites; + } + }; + } + + +// ******* PAGES ************ +// ******* 1st page ********* +RESOURCE ARRAY r_ttls_tab_settings + { + items = + { + DLG_LINE + { + id = ETtlsSettingsListbox; + type = EAknCtSettingListBox; + control = LISTBOX + { + flags = EAknListBoxMenuList; + }; + } + }; + } + + +// ******* 2nd page ********* +RESOURCE ARRAY r_ttls_tab_eap_types + { + items = + { + DLG_LINE + { + id = ETtlsSettingsEapTypeListbox; + type = EAknCtSingleNumberListBox; + control = LISTBOX + { + flags = EAknGenericListBoxFlags; + }; + } + }; + } + + +// ******* 3rd page ********* +RESOURCE ARRAY r_ttls_tab_cipher_suites + { + items = + { + DLG_LINE + { + id = ETtlsSettingsCipherSuiteListbox; + type = EAknCtSingleNumberListBox; + control = LISTBOX + { + flags = EAknGenericListBoxFlags; + }; + } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_ttls_username_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_username; + type = EEikCtEdwin; + editor_resource_id = r_ttls_setting_edwin; + } + + +RESOURCE AVKON_SETTING_PAGE r_ttls_realm_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_realm; + type = EEikCtEdwin; + editor_resource_id = r_ttls_setting_edwin; + } + + +RESOURCE EDWIN r_ttls_setting_edwin + { + flags = 0; + width = 9; + lines = 5; + maxlength = 255; + } + + +RESOURCE AVKON_SETTING_PAGE r_radio_button_setting_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + type = EAknSetListBox; + editor_resource_id = r_setting_listbox; + } + + +RESOURCE LISTBOX r_setting_listbox + { + flags = EEikListBoxMultipleSelection; + } + + + +RESOURCE MENU_BAR r_ttls_menubar + { + titles = + { + MENU_TITLE + { + menu_pane = r_ttls_menu_pane; + txt = ""; + } + }; + } + + +RESOURCE MENU_PANE r_ttls_menu_pane + { + items = + { + MENU_ITEM + { + command = ETtlsUiCmdConfigure; + txt = qtn_wlan_options_eap_plugin_configure; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = ETtlsUiCmdEnable; + txt = qtn_wlan_options_eap_plugin_enable; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = ETtlsUiCmdDisable; + txt = qtn_wlan_options_eap_plugin_disable; + flags = EEikMenuItemSpecific; + }, + + MENU_ITEM + { + command = ETtlsUiCmdMoveUp; + txt = qtn_wlan_options_eap_plugin_priority_up; + flags = EEikMenuItemSpecific; + }, + + MENU_ITEM + { + command = ETtlsUiCmdMoveDown; + txt = qtn_wlan_options_eap_plugin_priority_down; + flags = EEikMenuItemSpecific; + }, + + MENU_ITEM + { + command = ETtlsUiCmdChange; + txt = qtn_options_change; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = EAknCmdHelp; + txt = qtn_options_help; + }, + + MENU_ITEM + { + command = EAknCmdExit; + txt = qtn_options_exit; + } + }; + } + + +// Resource strings +RESOURCE TBUF r_ttls_settings_title { buf = qtn_wlan_eap_ttls_title; } +RESOURCE TBUF r_ttls_username_inusestring \ + { buf = qtn_wlan_eap_sett_username_inuse; } +RESOURCE TBUF r_ttls_username_inusestring_auto \ + { buf = qtn_wlan_eap_sett_username_inuse_from_cert; } +RESOURCE TBUF r_ttls_username_inusestring_conf \ + { buf = qtn_wlan_eap_sett_username_inuse_user; } +RESOURCE TBUF r_ttls_username_string { buf = qtn_wlan_eap_sett_username; } +RESOURCE TBUF r_ttls_realm_inusestring \ + { buf = qtn_wlan_eap_sett_realm_inuse; } +RESOURCE TBUF r_ttls_realm_inusestring_auto \ + { buf = qtn_wlan_eap_sett_realm_inuse_from_cert; } +RESOURCE TBUF r_ttls_realm_inusestring_conf \ + { buf = qtn_wlan_eap_sett_realm_inuse_user; } +RESOURCE TBUF r_ttls_realm_string { buf = qtn_wlan_eap_sett_realm; } +RESOURCE TBUF r_ttls_user_cert_string \ + { buf = qtn_wlan_eap_sett_user_certificate; } +RESOURCE TBUF r_ttls_ca_cert_string \ + { buf = qtn_wlan_eap_sett_ca_certificate; } +RESOURCE TBUF r_ttls_not_defined { buf = qtn_wlan_eap_cert_not_defined; } +RESOURCE TBUF r_ttls_none_selection \ + { buf = qtn_wlan_eap_cert_none_selection; } +RESOURCE TBUF r_ttls_suite_rsarc4md5 { buf = qtn_wlan_eap_cipher_rsarc4md5; } +RESOURCE TBUF r_ttls_suite_rsarc4sha { buf = qtn_wlan_eap_cipher_rsarc4sha; } +RESOURCE TBUF r_ttls_suite_rsa3dessha \ + { buf = qtn_wlan_eap_cipher_rsa3dessha; } +RESOURCE TBUF r_ttls_suite_dhersa3dessha \ + { buf = qtn_wlan_eap_cipher_dhersa3dessha; } +RESOURCE TBUF r_ttls_suite_dhedss3dessha \ + { buf = qtn_wlan_eap_cipher_dhedss3dessha; } +RESOURCE TBUF r_ttls_suite_rsaaessha { buf = qtn_wlan_eap_cipher_rsaaessha; } +RESOURCE TBUF r_ttls_suite_dhersaaessha \ + { buf = qtn_wlan_eap_cipher_dhersaaessha; } +RESOURCE TBUF r_ttls_suite_dhedssaessha \ + { buf = qtn_wlan_eap_cipher_dhedssaessha; } +RESOURCE TBUF r_ttls_info_cannot_disable_all_eap_plugins \ + { buf = qtn_wlan_info_cannot_disable_all_eap_plugins; } +RESOURCE TBUF r_ttls_info_plain_mschap_cannot_enable_along \ + { buf = qtn_wlan_eap_info_plain_mschap_cannot_enable_along; } +RESOURCE TBUF r_ttls_tls_privacy_string + { buf = qtn_wlan_eap_sett_tls_privacy; } +RESOURCE TBUF r_ttls_info_pap_cannot_enable_along \ + { buf = qtn_wlan_eap_info_pap_cannot_enable_along; } + +// ******************************************** +// USERNAME IN USE AND REALM POPUP DEFINITION +// ******************************************** +RESOURCE AVKON_POPUP_SETTING_TEXTS r_ttls_username_autouseconf_texts + { + setting_texts_resource = r_ttls_username_autouseconf_texts_resource; + popped_up_texts_resource = r_ttls_username_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_ttls_username_autouseconf_texts_resource + { + items = + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_username_inuse_from_cert; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_username_inuse_user; + } + }; + } + + +RESOURCE ARRAY r_ttls_username_automatic_useconfigured_array + { + items = + { + LBUF { txt = qtn_wlan_eap_sett_username_inuse_from_cert; }, + LBUF { txt = qtn_wlan_eap_sett_username_inuse_user; } + }; + } + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_ttls_realm_autouseconf_texts + { + setting_texts_resource = r_ttls_realm_autouseconf_texts_resource; + popped_up_texts_resource = r_ttls_realm_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_ttls_realm_autouseconf_texts_resource + { + items= + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_realm_inuse_from_cert; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_realm_inuse_user; + } + }; + } + + +RESOURCE ARRAY r_ttls_realm_automatic_useconfigured_array + { + items= + { + LBUF { txt = qtn_wlan_eap_sett_realm_inuse_from_cert; }, + LBUF { txt = qtn_wlan_eap_sett_realm_inuse_user; } + }; + } + + +RESOURCE ARRAY r_ttls_tls_privacy_autouseconf_texts_resource + { + items= + { + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_sett_tls_privacy_off; + }, + + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_sett_tls_privacy_on; + } + }; + } + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_ttls_tls_privacy_autouseconf_texts + { + setting_texts_resource = r_ttls_tls_privacy_autouseconf_texts_resource; + popped_up_texts_resource = r_ttls_tls_privacy_automatic_useconfigured_array; + } + + +RESOURCE ARRAY r_ttls_tls_privacy_automatic_useconfigured_array + { + items = + { + LBUF { txt = qtn_wlan_eap_sett_tls_privacy_off; }, + LBUF { txt = qtn_wlan_eap_sett_tls_privacy_on; } + }; + } + + +RESOURCE AVKON_SETTING_PAGE r_ttls_display_autouseconf_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_realm_inuse; + type = EAknCtPopupSettingList; + editor_resource_id = r_ttls_setting_enumerated_popup; + } + + +RESOURCE POPUP_SETTING_LIST r_ttls_setting_enumerated_popup + { + flags = EAknPopupSettingListFlagInitialised; + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/inc/EapTtlsUi.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/inc/EapTtlsUi.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,90 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP TTLS UI hrh file +* +*/ + + +#ifndef _EAPTTLSUI_HRH_ +#define _EAPTTLSUI_HRH_ + +enum TEapTtlsUiMenuCommands + { + ETtlsUiCmdUndefined = 6000, + ETtlsUiCmdChange, + ETtlsUiCmdEnable, + ETtlsUiCmdDisable, + ETtlsUiCmdConfigure, + ETtlsUiCmdMoveUp, + ETtlsUiCmdMoveDown, + ETtlsUiCmdViewDetails + }; + +enum TEapTtlsUiNotes + { + TEapTtlsUiGeneralError = 6100 + }; + +enum TEapTtlsUiLines + { + ETtlsSettingsListBox = 6200 + }; + +enum TEapTtlsUiSettingIds + { + ETtlsSettingUserCert=6300, + ETtlsSettingCaCert, + ETtlsSettingUsernameInUseId, + ETtlsSettingUsernameId, + ETtlsSettingRealmInUseId, + ETtlsSettingRealmId, + ETtlsSettingTlsPrivacyId + }; + +enum TEapTtlsUiSettingPageIds + { + ETtlsSettingPageUserCertificates=6400, + ETtlsSettingPageCaCertificates, + ETtlsSettingPageCipherSuites, + ETtlsSettingPageEapTypes, + ETtlsSettingPageSettings + }; + +enum TEapTtlsUiListBoxes + { + ETtlsSettingsUserCertListbox=6500, + ETtlsSettingsCaCertListbox, + ETtlsSettingsCipherSuiteListbox, + ETtlsSettingsEapTypeListbox, + ETtlsSettingsListbox + }; + +enum TEapTtlsSettingItems + { + ETtlsTabSheetSettingsUsernameInUse=6600, + ETtlsTabSheetSettingsUsername, + ETtlsTabSheetSettingsRealmInUse, + ETtlsTabSheetSettingsRealm + }; + +// Constants that are used as page ids +// TEapTtlsUiSettingPageIds does not work for this purpose +#define KEAPTTLSSETTINGSPAGE 1 +#define KEAPTTLSEAPPAGE 2 +#define KEAPTTLSCIPHERPAGE 3 + +#endif //_EAPTTLSUI_HRH_ + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/inc/EapTtlsUiSettingArray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/inc/EapTtlsUiSettingArray.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP TTLS UI settings array +* +*/ + + + +#ifndef _EAPTTLSUISETTINGARRAY_H_ +#define _EAPTTLSUISETTINGARRAY_H_ + + +// INCLUDES +#include +#include "EapTtlsUi.hrh" + + +// CLASS DECLARATION + +/** +*/ +class CEapTtlsSettingItemArray : public CBase + { + public: + static CEapTtlsSettingItemArray* NewL(); + virtual ~CEapTtlsSettingItemArray(); + CAknSettingItem* Item( TEapTtlsUiSettingPageIds aItem ); + CAknSettingItemArray* Array(); + void StoreSettingsL(); + + void AddTextItemL( TDes& aBuffer, TInt aId, TInt aTitleResource, + TInt aSettingPageResource, TInt aAssociatedResource, + TInt aOrdinal); + + void AddBinarySettingItemL( TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue); + + protected: + CEapTtlsSettingItemArray(); + void ConstructL(); + + private: + CAknSettingItemArray* iArray; + }; + +#endif // _EAPTTLSUISETTINGARRAY_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/inc/EapTtlsUiView.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/inc/EapTtlsUiView.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,175 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of EAP TTLS UI setting dialog +* +*/ + + + +#ifndef _EAPTTLSUIVIEW_H_ +#define _EAPTTLSUIVIEW_H_ + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "EapTtlsUi.hrh" +#include +#include +#include +#include + + +// FORWARD DECLARATIONS +class CAknSettingStyleListBox; +class CSettingsListBoxItemDrawer; +class CEapTtlsSettingItemArray; + + +// CLASS DECLARATION + +/** +* Settings dialog class definition +*/ +class CEapTtlsUiDialog : public CAknDialog, + public MEapTlsPeapUiCertificates, + public MEikListBoxObserver + { + public: + CEapTtlsUiDialog( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, TInt aIndex, + TInt& aButtonId ); + + ~CEapTtlsUiDialog(); + + /** + * Create and launch dialog. + * @param aResourceId The resource ID of the dialog to load. + * @return The ID of the button that closed the dialog + */ + TInt ConstructAndRunLD( TInt aResourceId ); + + /** + * Chain into key event handler. + * @param aKeyEvent The event. + * @param aType The type of key event. + * @return Was the key consumed or not. + */ + TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, + TEventCode aType); + + public: // From MEikListBoxObserver + + /** + * Handles list box events. + * @param aListBox The originating list box. + * @param aEventType A code for the event. + */ + void HandleListBoxEventL( CEikListBox* aListBox, TListBoxEvent aEventType ); + + public: // From CEikDialog + + /** + * @see CEikDialog + */ + void HandleDialogPageEventL( TInt aEventID ); + + + protected: + void PreLayoutDynInitL(); + void PostLayoutDynInitL(); + TBool OkToExitL( TInt aButtonId ); + void ProcessCommandL( TInt aCommand ); + void PageChangedL( TInt aPageId ); + + private: + void ChangeTitleL( TBool aIsStarted ); + void DrawSettingsListL(); + void ShowSettingPageL( TInt aCalledFromMenu ); + void MoveEapTypeL( TInt aOldPos, TInt aNewPos ); + void DrawEapListL( TInt aWantedIndex ); + TInt ShowRadioButtonSettingPageL( TInt aTitle, + CDesCArrayFlat* aValues, + TInt aCurrentItem ); + void DrawCipherSuitesL(); + void CompleteReadCertificates( const TInt aResult); + void CompleteUiConstructionL(); + TInt CheckActiveUserCertificate(); + TInt CheckActiveCaCertificate(); + void UserCertificateHouseKeeping( TInt aSelected ); + void CaCertificateHouseKeeping( TInt aSelected ); + void CreateEapTypeDataBaseL(); + void SetCipherIconsL(); + void SetEapIconsL(); + TUint GetEnabledEapTypeCount(); + TBool IsPlainMschapv2Enabled(); + TBool IsPapEnabled(); + void GetHelpContext( TCoeHelpContext& aContext ) const; + + void GetFullCertLabelL( const SCertEntry& aCert, TDes& aFullLabel ); + + /** + * Initialize menu pane. + * @param aResourceId Menu pane resource id. + * @param CEikMenuPane Menu pane. + */ + void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ); + + void ConfigureL( TBool aQuick ); + + + private: + CEapTlsPeapUiConnection* iConnection; + CEapTlsPeapUiDataConnection* iDataConnection; + CEapTlsPeapUiCipherSuites* iCipherSuites; + CEapTlsPeapUiCertificates* iCertificates; + + CEapTlsPeapUiTlsPeapData* iUiData; + CArrayFixFlat* iUiCipherSuites; + CArrayFixFlat* iUiUserCertificates; + CArrayFixFlat* iUiCACertificates; + CArrayFixFlat* iUiEapTypes; + + CAknSingleNumberStyleListBox* iUserCertificateListBox; + CAknSingleNumberStyleListBox* iCaCertificateListBox; + CAknSingleNumberStyleListBox* iCipherSuiteListBox; + CAknSingleNumberStyleListBox* iEapTypesListBox; + CEapTtlsSettingItemArray* iSettingArray; + CAknSettingStyleListBox* iSettingListBox; + CDesCArray* iEapTypeViewArray; + CDesCArray* iCipherSuitesViewArray; + CEapTlsPeapUiEapTypes* iEapTypes; + TIndexType iIndexType; + TInt iIndex; + HBufC* iPreviousText; + TInt* iButtonId; + + // Tells the status of UI construction. TRUE if UI construction is completed. + TBool iIsUIConstructionCompleted; + + // For exiting dialog + TBool iExiting; + }; + + +#endif // _EAPTTLSUIVIEW_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/loc/eapttlsui.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/loc/eapttlsui.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI strings for WLAN EAP-TTLS authentication settings +* +*/ + + + +// LOCALISATION STRINGS + + +//d:UI title for main view +//l:title_pane_t2/opt9 +//w: +//r:3.1 +// +#define qtn_wlan_eap_ttls_title "EAP-TTLS settings" + + +//d:Popup note to signal mschapv2 can only be enabled alone +//l:popup_note_window +//w: +//r:3.1 +// +#define qtn_wlan_eap_info_plain_mschap_cannot_enable_along "Plain MSCHAPv2 cannot be enabled along with other EAP plug-ins" + +//d:Popup note to signal that PAP can only be enabled alone +//l:popup_note_window +//w: +//r:5.1 +// +#define qtn_wlan_eap_info_pap_cannot_enable_along "PAP cannot be enabled along with other EAP plug-ins" + + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUi.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,142 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP TTLS UI class +* +*/ + + + +// INCLUDE FILES +#include "EapTtlsUi.h" +#include "EapTtlsUiView.h" +#include +#include +#include +#include +#include + + +// CONSTANTS +_LIT( KDriveZ, "z:" ); // ROM folder +_LIT( KResourceFileName, "eapttlsui.rsc" ); + + +// CLASS DECLARATION +class TResourceFileCleanupItem + { + public: + CCoeEnv* iCoeEnv; + TInt iResourceFileOffset; + }; + + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CleanupResourceFile +// ----------------------------------------------------------------------------- +// +static void CleanupResourceFile( TAny* aObject ) + { + TResourceFileCleanupItem* item = + REINTERPRET_CAST( TResourceFileCleanupItem*, aObject ); + item->iCoeEnv->DeleteResourceFile( item->iResourceFileOffset ); + delete item; + } + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapTtlsUi::CEapTtlsUi +// ----------------------------------------------------------------------------- +// +CEapTtlsUi::CEapTtlsUi( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, + TInt aIndex ) +: iConnection( aConnection ), + iIndexType( aIndexType ), + iIndex( aIndex ) + { + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUi::NewL +// ----------------------------------------------------------------------------- +// +CEapTtlsUi* CEapTtlsUi::NewL( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, + TInt aIndex ) + { + CEapTtlsUi* self = new( ELeave ) CEapTtlsUi( aConnection, aIndexType, + aIndex ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUi::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUi::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUi::~CEapTtlsUi +// ----------------------------------------------------------------------------- +// +CEapTtlsUi::~CEapTtlsUi() + { + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUi::InvokeUiL +// ----------------------------------------------------------------------------- +// +TInt CEapTtlsUi::InvokeUiL() + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + CCoeEnv* coeEnv = CCoeEnv::Static(); + BaflUtils::NearestLanguageFile( coeEnv->FsSession(), fileName ); + + TResourceFileCleanupItem* item = new( ELeave ) TResourceFileCleanupItem; + + item->iCoeEnv = coeEnv; + CleanupStack::PushL( TCleanupItem( CleanupResourceFile, item ) ); + item->iResourceFileOffset = coeEnv->AddResourceFileL( fileName ); + + TInt buttonId; + CEapTtlsUiDialog* settingsDlg = new( ELeave ) CEapTtlsUiDialog( + iConnection, iIndexType, iIndex, buttonId ); + settingsDlg->ConstructAndRunLD( R_TTLS_SETTING_DIALOG ); + + CleanupStack::PopAndDestroy(); // For resource file + + return buttonId; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUiSettingArray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUiSettingArray.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,183 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP TTLS UI settings array +* +*/ + + + +// INCLUDE FILES +#include "EapTtlsUiSettingArray.h" +#include "EapTtlsUi.hrh" +#include +#include + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapTtlsSettingItemArray::CEapTtlsSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapTtlsSettingItemArray::CEapTtlsSettingItemArray() + { + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsSettingItemArray::NewL +// ----------------------------------------------------------------------------- +// +CEapTtlsSettingItemArray* CEapTtlsSettingItemArray::NewL() + { + CEapTtlsSettingItemArray* self = new( ELeave ) CEapTtlsSettingItemArray(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); // self + return self; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsSettingItemArray::ConstructL +// ----------------------------------------------------------------------------- +// +void CEapTtlsSettingItemArray::ConstructL() + { + iArray = new( ELeave ) CAknSettingItemArray( 2, EFalse, 0 ); + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsSettingItemArray::~CEapTtlsSettingItemArray +// ----------------------------------------------------------------------------- +// +CEapTtlsSettingItemArray::~CEapTtlsSettingItemArray() + { + if( iArray ) + { + // ResetAndDestroy() + iArray->ResetAndDestroy(); + } + delete iArray; + iArray = NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsSettingItemArray::Item +// ----------------------------------------------------------------------------- +// +CAknSettingItem* CEapTtlsSettingItemArray::Item( TEapTtlsUiSettingPageIds aId ) + { + for( TInt i = 0; i < iArray->Count(); i++ ) + { + if( iArray->At( i )->Identifier() == aId ) + { + return iArray->At( i ); + } + } + + __ASSERT_DEBUG( EFalse, User::Invariant() ); + return NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsSettingItemArray::Array +// ----------------------------------------------------------------------------- +// +CAknSettingItemArray* CEapTtlsSettingItemArray::Array() + { + return iArray; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsSettingItemArray::StoreSettingsL +// ----------------------------------------------------------------------------- +// +void CEapTtlsSettingItemArray::StoreSettingsL() + { + // Do what SettingItemList::StoreSettings would do. + for( TInt i( 0 ); i < iArray->Count(); ++i ) + { + iArray->At( i )->StoreL(); + } + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsSettingItemArray::AddTextItemL +// ----------------------------------------------------------------------------- +// +void CEapTtlsSettingItemArray::AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal ) + { + // Create new setting item + CAknTextSettingItem* settingItem = new ( ELeave ) CAknTextSettingItem( aId, + aBuffer ); + CleanupStack::PushL( settingItem ); + settingItem->SetEmptyItemTextL( KNullDesC ); + settingItem->SetSettingPageFlags( + CAknTextSettingPage::EZeroLengthAllowed ); + + // Construct setting item with parametrized values + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResource ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResource, EAknCtPopupSettingList, + NULL, aAssociatedResource ); + + // Append item to settingitem-array + iArray->InsertL( aOrdinal, settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + + // Items are destroyed in destructor when resetting array + CleanupStack::Pop( settingItem ); + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsSettingItemArray::AddBinarySettingItemL +// ----------------------------------------------------------------------------- +// +void CEapTtlsSettingItemArray::AddBinarySettingItemL( + TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue ) + { + CAknSettingItem* settingItem = new( ELeave ) + CAknBinaryPopupSettingItem( 0, aModifiedValue ); + CleanupStack::PushL( settingItem ); + + HBufC* itemTitle = CEikonEnv::Static()->AllocReadResourceLC( + aTitleResourceId ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResourceId, EAknCtPopupSettingList, + NULL, aAssociatedResourceId ); + iArray->AppendL( settingItem ); + CleanupStack::PopAndDestroy( itemTitle ); + CleanupStack::Pop( settingItem ); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUiView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUiView.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1901 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 EAP TTLS UI settings dialog +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include "EapTtlsUiView.h" +#include "EapTtlsUi.hrh" +#include +#include +#include +#include "EapTtlsUiSettingArray.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +// CONSTANTS +// UID of general settings app, in which help texts are included +const TUid KHelpUidPlugin = { 0x100058EC }; + +static const TInt KSettingArrayGranularity = 4; +static const TInt KSuiteArrayGranularity = 5; +static const TInt KMaxLengthOfEapLine = 270; +static const TInt KCertificateArrayGranularity = 5; +static const TInt KMaxLengthOfSuiteName = 255; +static const TInt KEapTtlsId = 21; + +_LIT( KNameSeparator, " " ); +_LIT( KEmptyString, "" ); +const TUint KFirstElement = 0; +const TUint KSecondElement = 1; +const TUint KMinEnabledCount = 1; + +/* This is the maximum length of a certificate's full name, includes +label, primary and secondary names */ +const TUint32 KMaxFullCertLabelLength = KMaxCertLabelLength + 2 * + KMaxNameLength + 1; // 1 is for separator. + +// MODULE DATA STRUCTURES +enum TPageIds + { + ESettingsPage = 0, + EEapTypePage, + ECipherSuitePage + }; + +enum TSettingIds + { + EUserCertificateItem = 0, + ECaCertificateItem, + EUsernameInUseItem, + EUsernameItem, + ERealmInUseItem, + ERealmItem + }; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::CEapTtlsUiDialog +// ----------------------------------------------------------------------------- +// +CEapTtlsUiDialog::CEapTtlsUiDialog( CEapTlsPeapUiConnection* aConnection, + TIndexType aIndexType, TInt aIndex, + TInt& aButtonId ) +: CAknDialog(), + iConnection( aConnection ), + iIndexType( aIndexType ), + iIndex( aIndex ), + iButtonId( &aButtonId ), + iIsUIConstructionCompleted( EFalse ), + iExiting( EFalse ) + { + } + + +// --------------------------------------------------------- +// CEapTtlsUiDialog::ConstructAndRunLD +// --------------------------------------------------------- +// +TInt CEapTtlsUiDialog::ConstructAndRunLD( TInt aResourceId ) + { + CleanupStack::PushL( this ); + + iSettingArray = CEapTtlsSettingItemArray::NewL(); + + User::LeaveIfError( iConnection->Connect() ); + + // Basic data + iDataConnection = iConnection->GetDataConnection(); + if ( iDataConnection == 0 ) + { + User::Leave( KErrNoMemory ); + } + User::LeaveIfError( iDataConnection->Open() ); + User::LeaveIfError( iDataConnection->GetData( &iUiData ) ); + + // Cipher suites + iCipherSuites = iConnection->GetCipherSuiteConnection(); + if ( iCipherSuites == 0 ) + { + User::Leave( KErrNoMemory ); + } + + User::LeaveIfError( iCipherSuites->Open() ); + User::LeaveIfError( iCipherSuites->GetCipherSuites( &iUiCipherSuites ) ); + + iCipherSuitesViewArray = new( ELeave ) CDesCArrayFlat( + KSuiteArrayGranularity ); + //EAP types + iEapTypes = iConnection->GetEapTypeConnection(); + if ( iEapTypes == 0 ) + { + User::Leave( KErrNoMemory ); + } + User::LeaveIfError( iEapTypes->Open() ); + User::LeaveIfError( iEapTypes->GetEapTypes( &iUiEapTypes ) ); + if ( iUiEapTypes->Count() == 0 ) + { + CreateEapTypeDataBaseL(); + } + + iEapTypeViewArray = new( ELeave ) CDesCArrayFlat( + KSettingArrayGranularity ); + + FeatureManager::InitializeLibL(); + + ConstructL( R_TTLS_MENUBAR ); + + // ExecuteLD will PushL( this ), so we have to Pop it... + CleanupStack::Pop( this ); // this + + return CAknDialog::ExecuteLD( aResourceId ); + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::OfferKeyEventL +// ----------------------------------------------------------------------------- +// +TKeyResponse CEapTtlsUiDialog::OfferKeyEventL( const TKeyEvent& aKeyEvent, + TEventCode aType ) + { + TKeyResponse result( EKeyWasNotConsumed ); + + // gently handle impatient users + if ( !iIsUIConstructionCompleted ) + { + return CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + + TInt pageId = ActivePageId(); + if ( aType == EEventKey && pageId == KEAPTTLSCIPHERPAGE ) + { + TInt indexBefore = iCipherSuiteListBox->CurrentItemIndex(); + + if ( aKeyEvent.iCode == EKeyEnter ) + { + if ( ( *iUiCipherSuites )[indexBefore].iIsEnabled ) + { + OkToExitL( ETtlsUiCmdDisable ); + } + else + { + OkToExitL( ETtlsUiCmdEnable ); + } + + result = EKeyWasConsumed; + } + else + { + result = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + + TInt indexAfter = iCipherSuiteListBox->CurrentItemIndex(); + + if ( indexBefore != indexAfter ) + { + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + if( ( *iUiCipherSuites )[ indexAfter ].iIsEnabled ) + { + cba.SetCommandSetL( R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_DISABLE ); + } + else + { + cba.SetCommandSetL( R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + } + + cba.DrawDeferred(); + } + } + else if ( aType == EEventKey && pageId == KEAPTTLSEAPPAGE ) + { + TInt indexBefore = iEapTypesListBox->CurrentItemIndex(); + + if ( aKeyEvent.iCode == EKeyEnter ) + { + if ( ( *iUiEapTypes )[indexBefore].iIsEnabled ) + { + OkToExitL( ETtlsUiCmdConfigure ); + } + else + { + OkToExitL( ETtlsUiCmdEnable ); + } + + result = EKeyWasConsumed; + } + else + { + result = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + + TInt indexAfter = iEapTypesListBox->CurrentItemIndex(); + + if ( indexBefore != indexAfter ) + { + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + if( ( *iUiEapTypes )[indexAfter].iIsEnabled ) + { + cba.SetCommandSetL( R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_CONFIGURE ); + } + else + { + cba.SetCommandSetL( R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + } + + cba.DrawDeferred(); + } + } + else + { + result = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + + return result; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::~CEapTtlsUiDialog +// ----------------------------------------------------------------------------- +// +CEapTtlsUiDialog::~CEapTtlsUiDialog() + { + if ( iSettingArray ) + { + iSettingArray->Array()->ResetAndDestroy(); + } + + delete iSettingArray; + + iSettingListBox = NULL; + + iDataConnection->Close(); + delete iDataConnection; + + iCipherSuitesViewArray->Reset(); + delete iCipherSuitesViewArray; + + iEapTypeViewArray->Reset(); + delete iEapTypeViewArray; + + iCertificates->Close(); + delete iCertificates; + + iCipherSuites->Close(); + delete iCipherSuites; + + iEapTypes->Close(); + delete iEapTypes; + + iConnection->Close(); + + delete iPreviousText; + + FeatureManager::UnInitializeLib(); + } + + +// --------------------------------------------------------- +// CEapTtlsUiDialog::HandleListBoxEventL +// --------------------------------------------------------- +// +void CEapTtlsUiDialog::HandleListBoxEventL( CEikListBox* aListBox, + TListBoxEvent aEventType ) + { + switch ( aEventType ) + { + case EEventEnterKeyPressed: + case EEventItemSingleClicked: + { + if ( aListBox == iSettingListBox ) + { + OkToExitL( ETtlsUiCmdChange ); + } + + else if ( aListBox == iEapTypesListBox ) + { + TInt index = iEapTypesListBox->CurrentItemIndex(); + if ( iUiEapTypes->At( index ).iIsEnabled ) + { + ConfigureL(ETrue); + } + else + { + OkToExitL( ETtlsUiCmdEnable ); + } + } + + else if ( aListBox == iCipherSuiteListBox ) + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + if ( iUiCipherSuites->At( index ).iIsEnabled ) + { + OkToExitL( ETtlsUiCmdDisable ); + } + else + { + OkToExitL( ETtlsUiCmdEnable ); + } + } + + else + { + // Do nothing; we should never end up here + } + + break; + } + + case EEventItemActioned: + case EEventEditingStarted: + case EEventEditingStopped: + case EEventPenDownOnItem: + case EEventItemDraggingActioned: + { + break; + } + + default: + { + break; + }; + }; + } + + +// --------------------------------------------------------- +// CEapTtlsUiDialog::HandleDialogPageEventL +// --------------------------------------------------------- +// +void CEapTtlsUiDialog::HandleDialogPageEventL( TInt aEventID ) + { + CAknDialog::HandleDialogPageEventL( aEventID ); + if( iExiting ) + { + // Exit requested. + TryExitL( EAknCmdExit ); + } + } + + +// --------------------------------------------------------- +// CEapTtlsUiDialog::ConfigureL +// --------------------------------------------------------- +// +void CEapTtlsUiDialog::ConfigureL( TBool aQuick ) + { + RImplInfoPtrArray eapArray; + eapArray.Reset(); + REComSession::ListImplementationsL( KEapTypeInterfaceUid, + eapArray ); + TInt itemIndex = iEapTypesListBox->CurrentItemIndex(); + TInt eapIndex( 0 ); + for ( TInt i = 0; i < eapArray.Count(); ++i ) + { + CImplementationInformation* tempInfo = eapArray[i]; + if ( iUiEapTypes->At( itemIndex ).iEapType == + tempInfo->DataType() ) + { + eapIndex = i; + break; + } + } + + CEapType* eapType; + eapType = CEapType::NewL( eapArray[eapIndex]->DataType(), + iIndexType, iIndex ); + eapArray.ResetAndDestroy(); + eapType->SetTunnelingType( KEapTtlsId ); + CleanupStack::PushL( eapType ); + TInt buttonId = eapType->InvokeUiL(); + CleanupStack::PopAndDestroy( eapType ); + if ( buttonId == EAknCmdExit || buttonId == EEikCmdExit ) + { + if (aQuick == EFalse) + { + TryExitL( buttonId ); + } + else + { + iExiting = ETrue; + // Don't exit here. Framework command chain will + // cause a KERN-EXEC 3 panic. Handle the exit in + // HandleDialogPageEventL(). + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::PreLayoutDynInitL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::PreLayoutDynInitL() + { + // Change title + ChangeTitleL( ETrue ); + + iSettingListBox = static_cast( + ControlOrNull( ETtlsSettingsListbox ) ); + iSettingListBox->SetComponentsToInheritVisibility( ETrue ); + + iEapTypesListBox = static_cast( + ControlOrNull( ETtlsSettingsEapTypeListbox ) ); + iEapTypesListBox->SetComponentsToInheritVisibility( ETrue ); + + iCipherSuiteListBox = static_cast( + ControlOrNull( ETtlsSettingsCipherSuiteListbox ) ); + iCipherSuiteListBox->SetComponentsToInheritVisibility( ETrue ); + + // Get certificates before building the UI. + // Will continue when certificates are received + iCertificates = iConnection->GetCertificateConnection( this ); + User::LeaveIfError( iCertificates->Open() ); + iCertificates->GetCertificates( &iUiUserCertificates, &iUiCACertificates ); + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::CompleteReadCertificates +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::CompleteReadCertificates( const TInt aResult ) + { + if ( aResult == KErrNone ) // Certifiocates are received from core + { + TRAPD( err, CompleteUiConstructionL() ); + if ( err != KErrNone ) + { + TRAP_IGNORE( TryExitL( KErrCancel ) ); + } + } + else + { + TRAP_IGNORE( TryExitL( KErrCancel ) ); + } + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::CompleteUiConstructionL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::CompleteUiConstructionL() + { + // Initialize setting page + iSettingListBox = static_cast( + ControlOrNull( ETtlsSettingsListbox ) ); + iSettingListBox->SetMopParent( this ); + iSettingListBox->CreateScrollBarFrameL( ETrue ); + iSettingListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iSettingListBox->SetListBoxObserver( this ); + DrawSettingsListL(); + + // Initialize EAP types page + iEapTypesListBox = static_cast( + ControlOrNull( ETtlsSettingsEapTypeListbox ) ); + iEapTypesListBox->SetMopParent( this ); + iEapTypesListBox->CreateScrollBarFrameL( ETrue ); + iEapTypesListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iEapTypesListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iEapTypesListBox->SetListBoxObserver( this ); + + // Following deletes internal array created from resources. + // To prevent memory leak. + MDesCArray* internalArray1 = iEapTypesListBox->Model()->ItemTextArray(); + delete internalArray1; + + // Initialize cipher suites page + iCipherSuiteListBox = static_cast( + ControlOrNull( ETtlsSettingsCipherSuiteListbox ) ); + iCipherSuiteListBox->CreateScrollBarFrameL( ETrue ); + iCipherSuiteListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iCipherSuiteListBox->UpdateScrollBarsL(); + iCipherSuiteListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iCipherSuiteListBox->SetListBoxObserver( this ); + + //Following deletes internal array created from resources. + // To prevent memory leak. + MDesCArray* internalArray2 = iCipherSuiteListBox->Model()->ItemTextArray(); + delete internalArray2; + + SetEapIconsL(); + DrawEapListL( 0 ); + + SetCipherIconsL(); + DrawCipherSuitesL(); + + iIsUIConstructionCompleted = ETrue; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::PostLayoutDynInitL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::PostLayoutDynInitL() + { + TUid naviPaneUid; + naviPaneUid.iUid = EEikStatusPaneUidNavi; + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( naviPaneUid ); + if ( subPane.IsPresent() && subPane.IsAppOwned() ) + { + CAknNavigationControlContainer* naviPane = + static_cast( + statusPane->ControlL( naviPaneUid ) ); + CAknNavigationDecorator* naviDecorator = naviPane->ResourceDecorator(); + if ( naviDecorator ) + { + CAknTabGroup* tabGroup = static_cast( + naviDecorator->DecoratedControl() ); + tabGroup->SetActiveTabById( 0 ); + tabGroup->SetTabFixedWidthL( KTabWidthWithOneTab ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::ChangeTitleL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::ChangeTitleL( TBool aIsStarted ) + { + TUid titlePaneUid; + titlePaneUid.iUid = EEikStatusPaneUidTitle; + + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( titlePaneUid ); + + if ( subPane.IsPresent()&&subPane.IsAppOwned() ) + { + CAknTitlePane* titlePane = static_cast( + statusPane->ControlL( titlePaneUid ) ); + if ( aIsStarted ) + { + // Store previous application title text + const TDesC* prevText = titlePane->Text(); + iPreviousText = HBufC::NewL( prevText->Length() ); + iPreviousText->Des().Append( *prevText ); + TDesC* titleText = iEikonEnv->AllocReadResourceLC( + R_TTLS_SETTINGS_TITLE ); + titlePane->SetTextL( *titleText ); + CleanupStack::PopAndDestroy( titleText ); + } + else + { + // Set calling application title text back + titlePane->SetTextL( *iPreviousText ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CEapTtlsUiDialog::OkToExitL( TInt aButtonId ) + { + TBool ret( EFalse ); + switch ( aButtonId ) + { + case EEikBidOk: + { + if( iIsUIConstructionCompleted ) + { + TPageIds index = static_cast( ActivePageIndex() ); + if ( index == ESettingsPage ) + { + ShowSettingPageL( EFalse ); + } + else if ( index == EEapTypePage ) + { + ProcessCommandL( ETtlsUiCmdConfigure ); + } + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapTtlsUiDialog::OkToExitL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + case EAknSoftkeyOptions: + { + DisplayMenuL(); + break; + } + + case EAknSoftkeyBack: + case EAknCmdExit: + { + if( ( GetEnabledEapTypeCount() > KMinEnabledCount ) && + ( IsPlainMschapv2Enabled() || IsPapEnabled() ) ) + { + HBufC* stringLabel; + + if ( IsPlainMschapv2Enabled() ) + { + stringLabel = StringLoader::LoadL( + R_TTLS_INFO_PLAIN_MSCHAP_CANNOT_ENABLE_ALONG, + iEikonEnv ); + } + else + { + stringLabel = StringLoader::LoadL( + R_TTLS_INFO_PAP_CANNOT_ENABLE_ALONG, + iEikonEnv ); + } + CleanupStack::PushL( stringLabel ); + CAknInformationNote* dialog = new ( ELeave ) + CAknInformationNote( ETrue ); + dialog->ExecuteLD( *stringLabel ); + CleanupStack::PopAndDestroy( stringLabel ); + + // after showing the info note, EAP settings page + // must be shown + if( ActivePageId() == KEAPTTLSSETTINGSPAGE ) + { + TKeyEvent keyRight = + { + EKeyRightArrow, + EStdKeyRightArrow, + EModifierPureKeycode, + 0 + }; + CAknDialog::OfferKeyEventL + ( keyRight, + EEventKey ); + } + if( ActivePageId() == KEAPTTLSCIPHERPAGE ) + { + TKeyEvent keyLeft = + { + EKeyLeftArrow, + EStdKeyLeftArrow, + EModifierPureKeycode, + 0 + }; + CAknDialog::OfferKeyEventL + ( keyLeft, + EEventKey ); + } + + iExiting = EFalse; + ret = EFalse; + } + else + { + if( iIsUIConstructionCompleted ) + { + iDataConnection->Update(); + ChangeTitleL( EFalse ); + ret = ETrue; + } + } + break; + } + + case ETtlsUiCmdChange: + { + TPageIds index = static_cast( ActivePageIndex() ); + if ( index == ESettingsPage ) + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( EFalse ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapPeapUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + } + break; + } + + case ETtlsUiCmdConfigure: + case ETtlsUiCmdEnable: + case ETtlsUiCmdDisable: + { + ProcessCommandL( aButtonId ); + ret = EFalse; + break; + } + + default: + { + break; + } + } + + if ( ret ) + { + *iButtonId = aButtonId; + } + + return ret; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::DrawSettingsListL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::DrawSettingsListL() + { + iSettingArray->Array()->ResetAndDestroy(); + TInt ordinal = 0; + TInt activeUserCertificate = CheckActiveUserCertificate(); + TBuf aActiveuserCertificateName = KEmptyString(); + if ( activeUserCertificate != KErrNotFound ) + { + TBuf text; + GetFullCertLabelL( + iUiUserCertificates->At( activeUserCertificate ).iCertEntry, + text ); + aActiveuserCertificateName.Copy( text ); + } + else + { + TDesC* notDefinedText = iEikonEnv->AllocReadResourceLC( + R_TTLS_NOT_DEFINED ); + aActiveuserCertificateName.Copy( *notDefinedText ); + CleanupStack::PopAndDestroy( notDefinedText ); + } + + iSettingArray->AddTextItemL( aActiveuserCertificateName, + ETtlsSettingUserCert, + R_TTLS_USER_CERT_STRING, + R_TTLS_USERNAME_PAGE, + NULL, + ordinal++ ); + + TInt activeCaCertificate = CheckActiveCaCertificate(); + TBuf aActiveCaCertificateName = KEmptyString(); + if ( activeCaCertificate != KErrNotFound ) + { + TBuf text; + GetFullCertLabelL( + iUiCACertificates->At( activeCaCertificate ).iCertEntry, + text ); + aActiveCaCertificateName.Copy( text ); + } + else + { + TDesC* notDefinedText = iEikonEnv->AllocReadResourceLC( + R_TTLS_NOT_DEFINED ); + aActiveCaCertificateName.Copy( *notDefinedText ); + CleanupStack::PopAndDestroy( notDefinedText ); + } + + iSettingArray->AddTextItemL( aActiveCaCertificateName, + ETtlsSettingCaCert, + R_TTLS_CA_CERT_STRING, + R_TTLS_USERNAME_PAGE, + NULL, + ordinal++ ); + + iSettingArray->AddBinarySettingItemL( R_TTLS_DISPLAY_AUTOUSECONF_PAGE, + R_TTLS_USERNAME_INUSESTRING, + R_TTLS_USERNAME_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetUseManualUsername() ); + + iSettingArray->AddTextItemL( iUiData->GetManualUsername(), + ETtlsTabSheetSettingsUsername, + R_TTLS_USERNAME_STRING, + R_TTLS_USERNAME_PAGE, + NULL, + ordinal++ ); + + iSettingArray->AddBinarySettingItemL( R_TTLS_DISPLAY_AUTOUSECONF_PAGE, + R_TTLS_REALM_INUSESTRING, + R_TTLS_REALM_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetUseManualRealm() ); + + iSettingArray->AddTextItemL( iUiData->GetManualRealm(), + ETtlsTabSheetSettingsRealm, + R_TTLS_REALM_STRING, + R_TTLS_REALM_PAGE, + NULL, + ordinal++ ); + + iSettingArray->AddBinarySettingItemL( R_TTLS_DISPLAY_AUTOUSECONF_PAGE, + R_TTLS_TLS_PRIVACY_STRING, + R_TTLS_TLS_PRIVACY_AUTOUSECONF_TEXTS, + ordinal++, + *iUiData->GetTlsPrivacy() ); + + iSettingListBox->Model()->SetItemTextArray( iSettingArray->Array() ); + iSettingListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iSettingArray->Array()->RecalculateVisibleIndicesL(); + iSettingListBox->HandleItemAdditionL(); + iSettingListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::DynInitMenuPaneL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + CAknDialog::DynInitMenuPaneL( aResourceId, aMenuPane ); + + if ( aMenuPane && aResourceId == R_TTLS_MENU_PANE ) + { + if ( !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + + TPageIds index = static_cast( ActivePageIndex() ); + if ( index == ESettingsPage ) + { + aMenuPane->SetItemDimmed( ETtlsUiCmdEnable, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdDisable, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdConfigure, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdMoveUp, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdMoveDown, ETrue ); + } + else if ( index == EEapTypePage ) + { + aMenuPane->SetItemDimmed( ETtlsUiCmdChange, ETrue ); + + if ( iEapTypeViewArray->Count() > 0 ) + { + TInt currentIndex = iEapTypesListBox->CurrentItemIndex(); + TBool enabled = iUiEapTypes->At( currentIndex ).iIsEnabled; + + // Hide either "Enable" or "Disable", as appropriate. + aMenuPane->SetItemDimmed( ETtlsUiCmdEnable, enabled ); + aMenuPane->SetItemDimmed( ETtlsUiCmdDisable, !enabled ); + + // Don't display "Configure" for disabled items + aMenuPane->SetItemDimmed( ETtlsUiCmdConfigure, !enabled ); + + // Don't display "Raise priority" nor "Lower priority" for + // disabled items + aMenuPane->SetItemDimmed( ETtlsUiCmdMoveUp, !enabled ); + aMenuPane->SetItemDimmed( ETtlsUiCmdMoveDown, !enabled ); + + if ( enabled ) + { + if ( currentIndex == 0 ) + { + // Can't go higher than top. + aMenuPane->SetItemDimmed( ETtlsUiCmdMoveUp, ETrue ); + } + else if ( currentIndex == iEapTypeViewArray->Count()-1 || + ( currentIndex < iEapTypeViewArray->Count()-1 && + !iUiEapTypes->At( currentIndex + 1 ).iIsEnabled ) ) + { + // Can't go lower than the last enabled item + aMenuPane->SetItemDimmed( ETtlsUiCmdMoveDown, ETrue ); + } + } + + } + else + { + aMenuPane->SetItemDimmed( ETtlsUiCmdEnable, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdDisable, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdConfigure, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdMoveUp, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdMoveDown, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdChange, ETrue ); + } + } + else if ( index == ECipherSuitePage ) + { + aMenuPane->SetItemDimmed( ETtlsUiCmdConfigure, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdMoveUp, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdMoveDown, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdChange, ETrue ); + + if ( iCipherSuitesViewArray->Count() > 0 ) + { + TInt currIndex = iCipherSuiteListBox->CurrentItemIndex(); + TBool enabled = iUiCipherSuites->At( currIndex ).iIsEnabled; + + // Hide either "Enable" or "Disable", as appropriate. + aMenuPane->SetItemDimmed( ETtlsUiCmdEnable, enabled ); + aMenuPane->SetItemDimmed( ETtlsUiCmdDisable, !enabled ); + } + else + { + aMenuPane->SetItemDimmed( ETtlsUiCmdEnable, ETrue ); + aMenuPane->SetItemDimmed( ETtlsUiCmdDisable, ETrue ); + } + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::ProcessCommandL( TInt aCommand ) + { + if ( MenuShowing() ) + { + HideMenu(); + } + + TPageIds pageIndex = static_cast( ActivePageIndex() ); + switch( aCommand ) + { + case EAknCmdExit: + { + TryExitL( aCommand ); + break; + } + + case EAknCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + iEikonEnv->EikAppUi()->AppHelpContextL() ); + break; + } + + case ETtlsUiCmdChange: + { + if ( pageIndex == ESettingsPage ) + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( ETrue ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapTtlsUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + } + break; + } + + case ETtlsUiCmdMoveUp: + { + if ( pageIndex == EEapTypePage ) + { + TInt cur = iEapTypesListBox->CurrentItemIndex(); + MoveEapTypeL( cur, cur - 1 ); + } + break; + } + + case ETtlsUiCmdMoveDown: + { + if ( pageIndex == EEapTypePage ) + { + TInt cur = iEapTypesListBox->CurrentItemIndex(); + MoveEapTypeL( cur, cur + 1 ); + } + break; + } + + case ETtlsUiCmdEnable: + { + if ( pageIndex == ECipherSuitePage ) + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + iUiCipherSuites->At( index ).iIsEnabled = ETrue; + iCipherSuites->Update(); + DrawCipherSuitesL(); + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + cba.SetCommandSetL( R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_DISABLE ); + cba.DrawDeferred(); + } + else if ( pageIndex == EEapTypePage ) + { + TInt cur = iEapTypesListBox->CurrentItemIndex(); + iUiEapTypes->At( cur ).iIsEnabled = ETrue; + + iEapTypes->Update(); + + // enabling moves item to the top of the list + MoveEapTypeL( cur, 0 ); + + // load the new CBA from resource + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + cba.SetCommandSetL( R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_CONFIGURE ); + cba.DrawDeferred(); + } + break; + } + + case ETtlsUiCmdDisable: + { + if ( pageIndex == ECipherSuitePage ) + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + iUiCipherSuites->At( index ).iIsEnabled = EFalse; + iCipherSuites->Update(); + DrawCipherSuitesL(); + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + cba.SetCommandSetL( R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + cba.DrawDeferred(); + } + else if ( pageIndex == EEapTypePage ) + { + TInt itemIndex = iEapTypesListBox->CurrentItemIndex(); + + if( GetEnabledEapTypeCount() > KMinEnabledCount ) + { + // disabling moves item just after the last enabled one, + // so find that position + TInt next = itemIndex; + + while ( next < iUiEapTypes->Count() - 1 && + iUiEapTypes->At( next ).iIsEnabled ) + { + ++next; + } + + if ( next > itemIndex && + !iUiEapTypes->At( next ).iIsEnabled ) + { + --next; + } + + + iUiEapTypes->At( itemIndex ).iIsEnabled = EFalse; + + // move item if needed + MoveEapTypeL( itemIndex, next ); + iEapTypes->Update(); + + // Highlight follows movement. + //iEapTypesListBox->SetCurrentItemIndex( next ); + + // load the new CBA from resource + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + cba.SetCommandSetL( + R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + cba.DrawDeferred(); + } + else + { + HBufC* stringLabel; + stringLabel = StringLoader::LoadL( + R_TTLS_INFO_CANNOT_DISABLE_ALL_EAP_PLUGINS, + iEikonEnv ); + CleanupStack::PushL( stringLabel ); + CAknInformationNote* dialog = new ( ELeave ) + CAknInformationNote( ETrue ); + dialog->ExecuteLD( *stringLabel ); + CleanupStack::PopAndDestroy( stringLabel ); + } + } + break; + } + + case ETtlsUiCmdConfigure: + { + if ( pageIndex == EEapTypePage ) + { + ConfigureL(EFalse); + } + break; + } + + default: + { + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::PageChangedL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::PageChangedL( TInt aPageId ) + { + if ( !iIsUIConstructionCompleted ) + { + return; + } + + if ( aPageId == KEAPTTLSSETTINGSPAGE ) + { + if (iSettingListBox->ScrollBarFrame()) + { + iSettingListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(ETrue); + } + if (iEapTypesListBox->ScrollBarFrame()) + { + iEapTypesListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + if (iCipherSuiteListBox->ScrollBarFrame()) + { + iCipherSuiteListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + } + else if ( aPageId == KEAPTTLSEAPPAGE ) + { + if (iSettingListBox->ScrollBarFrame()) + { + iSettingListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + if (iEapTypesListBox->ScrollBarFrame()) + { + iEapTypesListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(ETrue); + } + if (iCipherSuiteListBox->ScrollBarFrame()) + { + iCipherSuiteListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + } + else if ( aPageId == KEAPTTLSCIPHERPAGE ) + { + if (iSettingListBox->ScrollBarFrame()) + { + iSettingListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + if (iEapTypesListBox->ScrollBarFrame()) + { + iEapTypesListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(EFalse); + } + if (iCipherSuiteListBox->ScrollBarFrame()) + { + iCipherSuiteListBox->ScrollBarFrame()->ComponentControl(0)->MakeVisible(ETrue); + } + } + + CEikButtonGroupContainer& cba = ButtonGroupContainer(); + if( aPageId == KEAPTTLSSETTINGSPAGE ) + { + cba.SetCommandSetL( R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_EDIT ); + } + else if( aPageId == KEAPTTLSEAPPAGE ) + { + cba.SetCommandSetL( R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_CONFIGURE ); + } + else if( aPageId == KEAPTTLSCIPHERPAGE ) + { + TInt index = iCipherSuiteListBox->CurrentItemIndex(); + if( ( *iUiCipherSuites )[ index ].iIsEnabled ) + { + cba.SetCommandSetL( R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_DISABLE ); + } + else + { + cba.SetCommandSetL( R_TTLS_UI_SOFTKEYS_OPTIONS_BACK_ENABLE ); + } + } + cba.DrawDeferred(); + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::ShowSettingPageL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::ShowSettingPageL( TInt aCalledFromMenu ) + { + TInt index = iSettingListBox->CurrentItemIndex(); + if ( index == EUserCertificateItem ) + { + TInt activeUserCertificate = CheckActiveUserCertificate(); + CDesCArrayFlat* tempArray = new( ELeave )CDesCArrayFlat( + KCertificateArrayGranularity ); + CleanupStack::PushL( tempArray ); + + TDesC* noneText = iEikonEnv->AllocReadResourceLC( + R_TTLS_NONE_SELECTION ); + tempArray->InsertL( 0, *noneText ); + CleanupStack::PopAndDestroy( noneText ); + + for ( TInt i = 0; i < iUiUserCertificates->Count() ; i++ ) + { + TEapTlsPeapUiCertificate certificate = + iUiUserCertificates->At( i ); + SCertEntry entry = certificate.iCertEntry; + TBuf text; + GetFullCertLabelL( entry, text); + tempArray->InsertL( i+1, text ); + } + TInt selected( 0 ); + if ( activeUserCertificate == KErrNotFound ) + { + selected = ShowRadioButtonSettingPageL( R_TTLS_USER_CERT_STRING, + tempArray, 0 ); + } + else + { + selected = ShowRadioButtonSettingPageL( R_TTLS_USER_CERT_STRING, + tempArray, + activeUserCertificate+1 ); + //Plus 1 cause we added 'none' selection + } + + CleanupStack::PopAndDestroy( tempArray ); + UserCertificateHouseKeeping( selected ); + iCertificates->Update(); + DrawSettingsListL(); // List must be drawn again at this stage + } + else if ( index == ECaCertificateItem ) + { + TInt activeCaCertificate = CheckActiveCaCertificate(); + + CDesCArrayFlat* tempArray = new( ELeave )CDesCArrayFlat( + KCertificateArrayGranularity ); + CleanupStack::PushL( tempArray ); + + TDesC* noneText = iEikonEnv->AllocReadResourceLC( + R_TTLS_NONE_SELECTION ); + tempArray->InsertL( 0, *noneText ); + CleanupStack::PopAndDestroy( noneText ); + + for ( TInt i = 0; i < iUiCACertificates->Count(); i++ ) + { + TEapTlsPeapUiCertificate certificate = iUiCACertificates->At( i ); + SCertEntry entry = certificate.iCertEntry; + TBuf text; + GetFullCertLabelL( entry, text ); + tempArray->InsertL( i+1, text ); + } + + TInt selected( 0 ); + if ( activeCaCertificate == KErrNotFound ) + { + selected = ShowRadioButtonSettingPageL( R_TTLS_CA_CERT_STRING, + tempArray, 0 ); + } + else + { + selected = ShowRadioButtonSettingPageL( R_TTLS_CA_CERT_STRING, + tempArray, + activeCaCertificate+1 ); + //Plus 1 cause we added 'none' selection + } + CleanupStack::PopAndDestroy( tempArray ); + CaCertificateHouseKeeping( selected ); + iCertificates->Update(); + DrawSettingsListL(); // List must be drawn again at this stage + } + else + { + CAknSettingItem* item = iSettingArray->Array()->At( index ); + item->EditItemL( aCalledFromMenu ); + item->StoreL(); + } + + DrawNow(); + } + + +// ----------------------------------------------------------------------------- +// CEapPeapUiDialog::MoveEapTypeL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::MoveEapTypeL( TInt aOldPos, TInt aNewPos ) + { + TEapTlsPeapUiEapType originalUpper = iUiEapTypes->At( aOldPos ); + iUiEapTypes->Delete( aOldPos ); + iUiEapTypes->InsertL( aNewPos, originalUpper ); + iUiEapTypes->Compress(); // Might not be needed + iEapTypes->Update(); + DrawEapListL( aNewPos ); + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::DrawEapListL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::DrawEapListL( TInt aWantedIndex ) + { + iEapTypeViewArray->Reset(); + RImplInfoPtrArray eapArray; + eapArray.Reset(); + + REComSession::ListImplementationsL( KEapTypeInterfaceUid, eapArray ); + for ( TInt i = 0; i < iUiEapTypes->Count(); i++ ) + { + TBuf tempLine; + + if ( iUiEapTypes->At( i ).iIsEnabled ) + { + _LIT( KNumTab, "%d\t" ); + tempLine.AppendFormat( KNumTab, i+1 ); + } + else + { + _LIT( KTab, "\t" ); + tempLine.Append( KTab ); + } + + for ( TInt index = 0; index < eapArray.Count(); index++ ) + { + if ( eapArray[index]->DataType() == iUiEapTypes->At( i ).iEapType ) + { + tempLine.Append( eapArray[index]->DisplayName() ); + break; + } + } + + if ( iUiEapTypes->At( i ).iIsEnabled ) + { // Add mark icon to indicate that the eap type is enabled + _LIT( KTab0, "\t0" ); + tempLine.Append( KTab0 ); + } + + iEapTypeViewArray->InsertL( i, tempLine ); + } + + eapArray.ResetAndDestroy(); + iEapTypesListBox->Model()->SetItemTextArray( iEapTypeViewArray ); + iEapTypesListBox->HandleItemAdditionL(); + iEapTypesListBox->SetCurrentItemIndex( aWantedIndex ); + iEapTypesListBox->DrawDeferred(); + iEapTypesListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::ShowRadioButtonSettingPageL +// ----------------------------------------------------------------------------- +// +TInt CEapTtlsUiDialog::ShowRadioButtonSettingPageL( TInt aTitle, + CDesCArrayFlat* aValues, + TInt aCurrentItem ) + { + // title of the dialog + HBufC* title = iCoeEnv->AllocReadResourceLC( aTitle ); + + // We have everything to create dialog + CAknRadioButtonSettingPage* dlg = new( ELeave )CAknRadioButtonSettingPage( + R_RADIO_BUTTON_SETTING_PAGE, + aCurrentItem, + aValues ); + CleanupStack::PushL( dlg ); + dlg->SetSettingTextL( *title ); + CleanupStack::Pop( dlg ); + dlg->ExecuteLD( CAknSettingPage::EUpdateWhenChanged ); + CleanupStack::PopAndDestroy( title ); // title + // index must be re-turned upside down, because options list is upside down + return aCurrentItem; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::DrawCipherSuitesL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::DrawCipherSuitesL() + { + iCipherSuitesViewArray->Reset(); + TInt listCount( 0 ); + TBuf temp; + for ( TInt i = 0; i < iUiCipherSuites->Count(); i++ ) + { + temp.Zero(); + _LIT( KTab, "\t" ); + temp.Append( KTab ); + + TEapTlsPeapUiCipherSuite suite = iUiCipherSuites->At( i ); + TUint32 suiteId = suite.iCipherSuite; + + switch( suiteId ) + { + case 0x0004: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TTLS_SUITE_RSARC4MD5 ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0005: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TTLS_SUITE_RSARC4SHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x000a: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TTLS_SUITE_RSA3DESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0016: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TTLS_SUITE_DHERSA3DESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0013: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TTLS_SUITE_DHEDSS3DESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x002F: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TTLS_SUITE_RSAAESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0032: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TTLS_SUITE_DHERSAAESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + case 0x0033: + { + HBufC* suite = iCoeEnv->AllocReadResourceLC( + R_TTLS_SUITE_DHEDSSAESSHA ); + temp.Append( *suite ); + CleanupStack::PopAndDestroy( suite ); + break; + } + + default: + { + temp.Append( KEmptyString ); + break; + } + } + + if ( iUiCipherSuites->At( i ).iIsEnabled ) + { // Add mark icon to indicate that the suite is enabled + _LIT( KTab0, "\t0" ); + temp.Append( KTab0 ); + } + + iCipherSuitesViewArray->InsertL( listCount, temp ); + listCount++; + } + + iCipherSuiteListBox->Model()->SetItemTextArray( iCipherSuitesViewArray ); + iCipherSuiteListBox->HandleItemAdditionL(); + iCipherSuiteListBox->DrawDeferred(); + iCipherSuiteListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::CheckActiveUserCertificate +// ----------------------------------------------------------------------------- +// +TInt CEapTtlsUiDialog::CheckActiveUserCertificate() + { + for ( TInt i = 0; i < iUiUserCertificates->Count(); i++ ) + { + if ( iUiUserCertificates->At( i ).iIsEnabled ) + { + return i; + } + } + + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::CheckActiveCaCertificate +// ----------------------------------------------------------------------------- +// +TInt CEapTtlsUiDialog::CheckActiveCaCertificate() + { + for ( TInt i = 0; i < iUiCACertificates->Count(); i++ ) + { + if ( iUiCACertificates->At( i ).iIsEnabled ) + { + return i; + } + } + + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::UserCertificateHouseKeeping +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::UserCertificateHouseKeeping( TInt aSelected ) + { + for ( TInt i = 0; i < iUiUserCertificates->Count(); i++ ) + { + iUiUserCertificates->At( i ).iIsEnabled = EFalse; + } + + if ( aSelected != 0 ) // Zero index is none + { + iUiUserCertificates->At( aSelected-1 ).iIsEnabled = ETrue; + } + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::CaCertificateHouseKeeping +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::CaCertificateHouseKeeping( TInt aSelected ) + { + for ( TInt i = 0; i < iUiCACertificates->Count(); i++ ) + { + iUiCACertificates->At( i ).iIsEnabled = EFalse; + } + + if ( aSelected != 0 ) // Zero index is none + { + iUiCACertificates->At( aSelected-1 ).iIsEnabled = ETrue; + } + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::CreateEapTypeDataBaseL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::CreateEapTypeDataBaseL() + { + RImplInfoPtrArray eapArray; + eapArray.Reset(); + + REComSession::ListImplementationsL( KEapTypeInterfaceUid, eapArray ); + TInt allowedInTtlsCount( 0 ); + for ( TInt i = 0; i < eapArray.Count(); i++ ) + { + if ( !CEapType::IsDisallowedInsideTTLS(*eapArray[i]) ) + { + CImplementationInformation* info = eapArray[i]; + TEapTlsPeapUiEapType tempEapType; + tempEapType.iEapType = info->DataType(); + + // BINARY RESOURCE DATA + + // [FE] [00 00 00] [TEapType_bigendian] + // OR + // [FE] [FF FF FF] [MSCHAPv2_bigendian] + + _LIT8( KExpEapFirstQuad, "\xFE\0\0\0" ); + TPtrC8 firstQuad( tempEapType.iEapType.Ptr(), 4 ); + // TUint32 dataType = BigEndian::Get32( tempEapType.iEapType.Ptr()+4 ); + TUint32 dataType = ( tempEapType.iEapType[4] << 24 ) | + ( tempEapType.iEapType[5] << 16 ) | + ( tempEapType.iEapType[6] << 8 ) | + tempEapType.iEapType[7]; + + + if ( !firstQuad.Compare( KExpEapFirstQuad ) && + ( dataType == EAPSettings::EEapSim || + dataType == EAPSettings::EEapAka ) ) + { + tempEapType.iIsEnabled = ETrue; + iUiEapTypes->InsertL( KFirstElement, tempEapType ); + } + else + { + tempEapType.iIsEnabled = EFalse; + iUiEapTypes->InsertL( allowedInTtlsCount, tempEapType ); + } + + allowedInTtlsCount++; + } + } + + __ASSERT_DEBUG( iUiEapTypes->Count() >= 2, User::Panic( _L("EAP-SIM/AKA missing"), 1) ); + + // Check if EAP-SIM and EAP-AKA are in correct order + + // BINARY RESOURCE DATA + const TDesC8& firstEap = iUiEapTypes->At( KFirstElement ).iEapType; + const TDesC8& secondEap = iUiEapTypes->At( KSecondElement ).iEapType; + + TUint32 dataTypeFirst = ( firstEap[4] << 24 ) | + ( firstEap[5] << 16 ) | + ( firstEap[6] << 8 ) | + firstEap[7]; + TUint32 dataTypeSecond = ( secondEap[4] << 24 ) | + ( secondEap[5] << 16 ) | + ( secondEap[6] << 8 ) | + secondEap[7]; + + // If not, switch them + if ( dataTypeFirst == EAPSettings::EEapAka && + dataTypeSecond == EAPSettings::EEapSim ) + { + TEapTlsPeapUiEapType tempEapType = iUiEapTypes->At( KFirstElement ); + iUiEapTypes->Delete( KFirstElement ); + iUiEapTypes->InsertL( KSecondElement, tempEapType ); + } + + iEapTypes->Update(); + eapArray.ResetAndDestroy(); + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::SetCipherIconsL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::SetCipherIconsL() + { + CArrayPtr< CGulIcon >* icons = new( ELeave ) CAknIconArray( 1 ); + CleanupStack::PushL( icons ); + + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + + CGulIcon* icon = CGulIcon::NewLC(); + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + AknsUtils::CreateColorIconL( skinInstance, + KAknsIIDQgnIndiMarkedAdd, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG13, + bitmap, + mask, + AknIconUtils::AvkonIconFileName(), + EMbmAvkonQgn_indi_marked_add, + EMbmAvkonQgn_indi_marked_add_mask, + KRgbBlack ); + icon->SetBitmap( bitmap ); + icon->SetMask( mask ); + icons->AppendL( icon ); + + CleanupStack::Pop( icon ); + CleanupStack::Pop( icons ); // icons + + iCipherSuiteListBox->ItemDrawer()->ColumnData()->SetIconArray( icons ); + + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::SetEapIconsL +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::SetEapIconsL() + { + CArrayPtr< CGulIcon >* icons = new( ELeave ) CAknIconArray( 1 ); + CleanupStack::PushL( icons ); + + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + + CGulIcon* icon = CGulIcon::NewLC(); + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + AknsUtils::CreateColorIconL( skinInstance, + KAknsIIDQgnIndiMarkedAdd, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG13, + bitmap, + mask, + AknIconUtils::AvkonIconFileName(), + EMbmAvkonQgn_indi_marked_add, + EMbmAvkonQgn_indi_marked_add_mask, + KRgbBlack ); + icon->SetBitmap( bitmap ); + icon->SetMask( mask ); + icons->AppendL( icon ); + + CleanupStack::Pop( icon ); + CleanupStack::Pop( icons ); // icons + + iEapTypesListBox->ItemDrawer()->ColumnData()->SetIconArray( icons ); + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::GetEnabledEapTypeCount +// ----------------------------------------------------------------------------- +// +TUint CEapTtlsUiDialog::GetEnabledEapTypeCount() + { + TUint itemCount( 0 ); + for( TInt i( 0 ); i < iUiEapTypes->Count(); ++i ) + { + if( iUiEapTypes->At( i ).iIsEnabled ) + { + ++itemCount; + } + } + return itemCount; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::IsPlainMschapv2Enabled +// ----------------------------------------------------------------------------- +// +TBool CEapTtlsUiDialog::IsPlainMschapv2Enabled() + { + TBool isEnabled( EFalse ); + for( TUint i( 0 ); i < iUiEapTypes->Count(); ++i ) + { + // was: _LIT8( KPlainMsChapV2ExpandedId, "\xFE\xFF\xFF\xFF\0\0\0\x1A" ); + // workaround: + _LIT8( KPlainMsChapV2ExpandedId, "\xFE\xFF\xFF\xFF\0\0\0\x63" ); + + const TDesC8& currEap = iUiEapTypes->At( i ).iEapType; + + if ( !currEap.Compare( KPlainMsChapV2ExpandedId ) ) + { + isEnabled = iUiEapTypes->At( i ).iIsEnabled; + break; + } + + } + return isEnabled; + } + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::IsPapEnabled +// ----------------------------------------------------------------------------- +// +TBool CEapTtlsUiDialog::IsPapEnabled() + { + TBool isEnabled( EFalse ); + for( TUint i( 0 ); i < iUiEapTypes->Count(); ++i ) + { + _LIT8( KPapExpandedId, "\xFE\xFF\xFF\xFF\0\0\0\x62" ); + const TDesC8& currEap = iUiEapTypes->At( i ).iEapType; + if ( !currEap.Compare( KPapExpandedId ) ) + { + isEnabled = iUiEapTypes->At( i ).iIsEnabled; + break; + } + } + return isEnabled; + } + + +// ----------------------------------------------------------------------------- +// CEapTtlsUiDialog::GetHelpContext +// ----------------------------------------------------------------------------- +// +void CEapTtlsUiDialog::GetHelpContext( TCoeHelpContext& aContext ) const + { + aContext.iMajor = KHelpUidPlugin; + TPageIds index = static_cast( ActivePageIndex() ); + switch ( index ) + { + case EEapTypePage: + { + aContext.iContext = KSET_HLP_WLAN_EAP_TTLS_TYPES; + break; + } + + case ECipherSuitePage: + { + aContext.iContext = KSET_HLP_WLAN_EAP_TTLS_SUITES; + break; + } + + default: + { + aContext.iContext = KSET_HLP_WLAN_EAP_TTLS_SETT; + break; + } + } + } + + +void CEapTtlsUiDialog::GetFullCertLabelL( const SCertEntry& aCert, + TDes& aFullLabel ) + { + TInt length = 0; + + // For label. + length += aCert.iLabel.Length(); + + // For separator between label and primary name. + length += KNameSeparator.iTypeLength; + + // For primary name. + length += aCert.iPrimaryName.Length(); + + if ( !( aCert.iLabel.Length() ) ) + { + // For secondary name. + length += aCert.iSecondaryName.Length(); + } + + if( length > aFullLabel.MaxLength() ) + { +#if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CEapTtlsUiDialog::GetFullCertLabelL - ERROR! Length Mismatch in Certificate's full name\n") ); +#endif + } + + HBufC* label = HBufC::NewL( length ); + label->Des().Append( aCert.iLabel ); + + label->Des().Append( KNameSeparator ); + label->Des().Append( aCert.iPrimaryName ); + + if ( !( aCert.iLabel.Length() ) ) + { + // Secondary name, only if no label. Certificate manager does the same way. + label->Des().Append( aCert.iSecondaryName ); + } + + aFullLabel.Copy( label->Des().Left( aFullLabel.MaxLength() ) ); + + delete label; + label = NULL; + } + + +// End of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/bwinscw/eapfastnotifdlgu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/bwinscw/eapfastnotifdlgu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,4 @@ +EXPORTS + ?ImplementationGroupProxy@@YAPBUTImplementationProxy@@AAH@Z @ 1 NONAME ; struct TImplementationProxy const * ImplementationGroupProxy(int &) + ?NotifierArray@@YAPAV?$CArrayPtr@VMEikSrvNotifierBase2@@@@XZ @ 2 NONAME ; class CArrayPtr * NotifierArray(void) + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/bwinscw/gtcnotifdlgu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/bwinscw/gtcnotifdlgu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?NotifierArray@@YAPAV?$CArrayPtr@VMEikSrvNotifierBase2@@@@XZ @ 1 NONAME ; class CArrayPtr * NotifierArray(void) + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/bwinscw/leapnotifdlgu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/bwinscw/leapnotifdlgu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?NotifierArray@@YAPAV?$CArrayPtr@VMEikSrvNotifierBase2@@@@XZ @ 1 NONAME ; class CArrayPtr * NotifierArray(void) + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/bwinscw/mschapv2notifdlgu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/bwinscw/mschapv2notifdlgu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?NotifierArray@@YAPAV?$CArrayPtr@VMEikSrvNotifierBase2@@@@XZ @ 1 NONAME ; class CArrayPtr * NotifierArray(void) + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/bwinscw/papnotifdlgu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/bwinscw/papnotifdlgu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?NotifierArray@@YAPAV?$CArrayPtr@VMEikSrvNotifierBase2@@@@XZ @ 1 NONAME ; class CArrayPtr * NotifierArray(void) + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/eabi/eapfastnotifdlgu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/eabi/eapfastnotifdlgu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,10 @@ +EXPORTS + _Z24ImplementationGroupProxyRi @ 1 NONAME + _Z13NotifierArrayv @ 2 NONAME + _ZTI19CEapFastPacPwDialog @ 3 NONAME ; ## + _ZTI20CEapFastDialogPlugin @ 4 NONAME ; ## + _ZTI21CEapFastPacFileDialog @ 5 NONAME ; ## + _ZTV19CEapFastPacPwDialog @ 6 NONAME ; ## + _ZTV20CEapFastDialogPlugin @ 7 NONAME ; ## + _ZTV21CEapFastPacFileDialog @ 8 NONAME ; ## + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/eabi/gtcnotifdlgu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/eabi/gtcnotifdlgu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,9 @@ +EXPORTS + _Z13NotifierArrayv @ 1 NONAME + _ZTI16CGtcDialogPlugin @ 2 NONAME ; ## + _ZTI23CGTCResponseQueryDialog @ 3 NONAME ; ## + _ZTI24CGTCMessageDisplayDialog @ 4 NONAME ; ## + _ZTV16CGtcDialogPlugin @ 5 NONAME ; ## + _ZTV23CGTCResponseQueryDialog @ 6 NONAME ; ## + _ZTV24CGTCMessageDisplayDialog @ 7 NONAME ; ## + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/eabi/leapnotifdlgu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/eabi/leapnotifdlgu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,7 @@ +EXPORTS + _Z13NotifierArrayv @ 1 NONAME + _ZTI11CLeapDialog @ 2 NONAME ; ## + _ZTI17CLeapDialogPlugin @ 3 NONAME ; ## + _ZTV11CLeapDialog @ 4 NONAME ; ## + _ZTV17CLeapDialogPlugin @ 5 NONAME ; ## + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/eabi/mschapv2notifdlgu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/eabi/mschapv2notifdlgu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,7 @@ +EXPORTS + _Z13NotifierArrayv @ 1 NONAME + _ZTI15CMsChapv2Dialog @ 2 NONAME ; ## + _ZTI21CMsChapv2DialogPlugin @ 3 NONAME ; ## + _ZTV15CMsChapv2Dialog @ 4 NONAME ; ## + _ZTV21CMsChapv2DialogPlugin @ 5 NONAME ; ## + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/eabi/papnotifdlgu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/eabi/papnotifdlgu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,11 @@ +EXPORTS + _Z13NotifierArrayv @ 1 NONAME + _ZTI14CPapAuthDialog @ 2 NONAME ; ## + _ZTI21CPapNotifDialogPlugin @ 3 NONAME ; ## + _ZTI22CPapChallengeMsgDialog @ 4 NONAME ; ## + _ZTI24CPapChallengeReplyDialog @ 5 NONAME ; ## + _ZTV14CPapAuthDialog @ 6 NONAME ; ## + _ZTV21CPapNotifDialogPlugin @ 7 NONAME ; ## + _ZTV22CPapChallengeMsgDialog @ 8 NONAME ; ## + _ZTV24CPapChallengeReplyDialog @ 9 NONAME ; ## + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/eapnotifwrapper/data/2000cf2e.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/eapnotifwrapper/data/2000cf2e.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP Notifier wrapper resource file +* +*/ + +#include +#include + +RESOURCE REGISTRY_INFO theInfo +{ + dll_uid = 0x2000cf2e; + interfaces = + { + INTERFACE_INFO + { + interface_uid = KUikonUidPluginInterfaceNotifiers; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = 0x2000cf2f; + version_no = 1; + display_name = "TTNOTIFY2V2 EAP notifier wrapper plugin"; + default_data = "TTNOTIFY2V2"; + opaque_data = "0"; + } + }; + } + }; +} diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/eapnotifwrapper/inc/eapnotifierdialoguiddefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/eapnotifwrapper/inc/eapnotifierdialoguiddefs.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of the UIDs used by Connection Dialogs +* +*/ + + + +#ifndef __EAPNOTIFIERDIALOGUIDDEFS_H__ +#define __EAPNOTIFIERDIALOGUIDDEFS_H__ + +// INCLUDES +#include + + +// CONSTANTS + +// UIDs for EAP notifier plugins + +// ID of EAP-GTC dialog +const TUid KUidGtcDialog = { 0x101f8e7f }; + +// ID of EAP-MSCHAPv2 dialog +const TUid KUidMsChapv2Dialog = { 0x101f8e69 }; + +// ID of PAP dialog +const TUid KUidPapDialog = { 0x200159A9 }; + +#ifdef FF_WLAN_EXTENSIONS +// ID of EAP-LEAP dialog +const TUid KUidLeapDialog = { 0x101f8ea9 }; +#endif + +#endif // __EAPNOTIFIERDIALOGUIDDEFS_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/eapnotifwrapper/src/eapnotifwrapper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/eapnotifwrapper/src/eapnotifwrapper.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,168 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 ecom plugin +* +*/ + + +// INCLUDE FILES +#include "eapnotifierdialoguiddefs.h" + +#include +#include // link against aknnotifierwrapper.lib + + +// CONSTANTS +const TInt KMyPriority = MEikSrvNotifierBase2::ENotifierPriorityLow; +const TInt KArrayGranularity = 4; + + +// --------------------------------------------------------- +// CleanupArray() +// --------------------------------------------------------- +// +void CleanupArray( TAny* aArray ) + { + CArrayPtrFlat* + subjects = static_cast*>( aArray ); + TInt lastInd = subjects->Count()-1; + for ( TInt i = lastInd; i >= 0; i-- ) + { + subjects->At( i )->Release(); + } + + delete subjects; + } + + +// --------------------------------------------------------- +// DoCreateNotifierArrayL() +// --------------------------------------------------------- +// +CArrayPtr* DoCreateNotifierArrayL() + { + CArrayPtrFlat* subjects = + new ( ELeave )CArrayPtrFlat( KArrayGranularity ); + + CleanupStack::PushL( TCleanupItem( CleanupArray, subjects ) ); + + // Create Wrappers + CAknCommonNotifierWrapper* master = NULL; + + // EAP-MSCHAPv2 + _LIT( KMsChapv2NotifierPluginName, "mschapv2notifdlg.dll" ); + master = CAknCommonNotifierWrapper::NewL( KUidMsChapv2Dialog, + KUidMsChapv2Dialog, + KMyPriority, + KMsChapv2NotifierPluginName, + 1 ); + + CleanupStack::PushL( master ); + subjects->AppendL( master ); + CleanupStack::Pop( master ); + + + + // EAP-GTC + _LIT( KGtcNotifierPluginName, "gtcnotifdlg.dll" ); + + // Session owning notifier(if default implementation is enough) + master = CAknCommonNotifierWrapper::NewL( KUidGtcDialog, + KUidGtcDialog, + KMyPriority, + KGtcNotifierPluginName, + 1 ); // we don't use synch reply + + CleanupStack::PushL( master ); + subjects->AppendL( master ); + CleanupStack::Pop( master ); + + + // PAP + _LIT( KPapNotifierPluginName, "papnotifdlg.dll" ); + master = CAknCommonNotifierWrapper::NewL( KUidPapDialog, + KUidPapDialog, + KMyPriority, + KPapNotifierPluginName, + 1 ); + + CleanupStack::PushL( master ); + subjects->AppendL( master ); + CleanupStack::Pop( master ); + + + +#ifdef FF_WLAN_EXTENSIONS + + // EAP-LEAP + _LIT( KLeapNotifierPluginName, "leapnotifdlg.dll" ); + master = CAknCommonNotifierWrapper::NewL( KUidLeapDialog, + KUidLeapDialog, + KMyPriority, + KLeapNotifierPluginName, + 1 ); + + CleanupStack::PushL( master ); + subjects->AppendL( master ); + CleanupStack::Pop( master ); + +#endif + + CleanupStack::Pop(); // array cleanup + + return subjects; + } + + +// --------------------------------------------------------- +// NotifierArray() +// --------------------------------------------------------- +// +CArrayPtr* NotifierArray() + // old Lib main entry point + { + CArrayPtr* array = 0; + TRAP_IGNORE( array = DoCreateNotifierArrayL() ); + return array; + } + + +// --------------------------------------------------------- +// ImplementationTable +// --------------------------------------------------------- +// +const TImplementationProxy ImplementationTable[] = + { +#ifdef __EABI__ + {{0x2000cf2f}, ( TFuncPtr )NotifierArray} +#else + {{0x2000cf2f}, NotifierArray} +#endif + }; + +// --------------------------------------------------------- +// ImplementationGroupProxy +// entry point +// --------------------------------------------------------- +// +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( + TInt& aTableCount ) + { + aTableCount = sizeof( ImplementationTable ) / + sizeof( TImplementationProxy ) ; + return ImplementationTable; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/EapAkaUi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/EapAkaUi.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP AKA UI Project mmp file +* +*/ + + +#include +#include + + +TARGET eapakaui.lib +TARGETTYPE lib +UID 0x1000008d 0x102072A5 + + +SOURCEPATH ../EapAka/ConfigUi/src + +SOURCE EapAkaUi.cpp +SOURCE EapAkaUiView.cpp +SOURCE EapAkaUiSettingArray.cpp + + +USERINCLUDE ../EapAka/ConfigUi/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE +APP_LAYER_SYSTEMINCLUDE + +// Resource files +START RESOURCE ../data/EapAkaUi.rss + +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS + +END + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/EapGtcUi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/EapGtcUi.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP GTC UI Project mmp file +* +*/ + + +#include +#include + + +TARGET eapgtcui.lib +TARGETTYPE lib +UID 0x1000008d 0x102072A9 + + +SOURCEPATH ../EapGtc/ConfigUi/src + +SOURCE EapGtcUi.cpp +SOURCE EapGtcUiView.cpp +SOURCE EapGtcUiSettingArray.cpp + + +USERINCLUDE ../EapGtc/ConfigUi/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE +APP_LAYER_SYSTEMINCLUDE + + +// Resource files +START RESOURCE ../data/EapGtcUi.rss + +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS + +END + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/EapMschapv2Ui.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/EapMschapv2Ui.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP MsChapV2 UI Project mmp file +* +*/ + + +#include +#include + + +TARGET eapmschapv2ui.lib +TARGETTYPE lib +UID 0x1000008d 0x102072A8 + + +SOURCEPATH ../EapMschapv2/ConfigUi/src + +SOURCE EapMschapv2Ui.cpp +SOURCE EapMschapv2UiView.cpp +SOURCE EapMschapv2UiSettingArray.cpp + + +USERINCLUDE ../EapMschapv2/ConfigUi/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE +APP_LAYER_SYSTEMINCLUDE + + +// Resource files +START RESOURCE ../data/EapMschapv2Ui.rss + +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS + +END + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/EapPeapUi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/EapPeapUi.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP PEAP UI Project mmp file +* +*/ + + +#include +#include + +TARGET eappeapui.lib +TARGETTYPE lib +UID 0x1000008d 0x102072AA + + +SOURCEPATH ../EapPeap/ConfigUi/src + +SOURCE EapPeapUi.cpp +SOURCE EapPeapUiView.cpp +SOURCE EapPeapUiSettingArray.cpp + + +USERINCLUDE ../EapPeap/ConfigUi/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE +APP_LAYER_SYSTEMINCLUDE + +// Resource files +START RESOURCE ../data/EapPeapUi.rss + +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS + +END + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/EapPluginConfig.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/EapPluginConfig.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,79 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP Plugin Configuration UI Project mmp file +* +*/ + + +#include +#include + + +TARGET eappluginconfig.dll +TARGETTYPE PLUGIN +UID 0x10009D8D 0x102072BB +CAPABILITY CAP_ECOM_PLUGIN +VENDORID VID_DEFAULT + + +SOURCEPATH ../EapPluginConfig/src + +SOURCE EAPPluginConfiguration.cpp +SOURCE EAPPlugInConfigurationDlg.cpp +SOURCE EAPPlugInConfigurationModel.cpp +SOURCE EAPPluginList.cpp +SOURCE EAPPluginConfigurationProxy.cpp + + +USERINCLUDE ../EapPluginConfig/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE +APP_LAYER_SYSTEMINCLUDE + + +START RESOURCE ../data/EAPPluginConfigRes.rss + +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS + +END // RESOURCE + + +START RESOURCE ../data/102072bb.rss +TARGET eappluginconfig.rsc +TARGETPATH ECOM_RESOURCE_DIR +LANGUAGE_IDS + +END // RESOURCE + + +LIBRARY featmgr.lib +LIBRARY euser.lib +LIBRARY ecom.lib +LIBRARY AknSkins.lib +LIBRARY AknIcon.lib +LIBRARY CommonEngine.lib +LIBRARY HLPLCH.lib // For Series 60 help +LIBRARY eikcoctl.lib +LIBRARY eikdlg.lib +LIBRARY eikcore.lib +LIBRARY cone.lib +LIBRARY avkon.lib +LIBRARY bafl.lib +LIBRARY egul.lib + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/EapSimUi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/EapSimUi.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP LEAP UI Project mmp file +* +*/ + + +#include +#include + + +TARGET eapsimui.lib +TARGETTYPE lib +UID 0x1000008d 0x102072A6 + +SOURCEPATH ../EapSim/ConfigUi/src + +SOURCE EapSimUi.cpp +SOURCE EapSimUiView.cpp +SOURCE EapSimUiSettingArray.cpp + + +USERINCLUDE ../EapSim/ConfigUi/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE +APP_LAYER_SYSTEMINCLUDE + +// Resource files +START RESOURCE ../data/EapSimUi.rss + +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS + +END + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/EapTlsUi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/EapTlsUi.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP TLS UI Project mmp file +* +*/ + + +#include +#include + +TARGET eaptlsui.lib +TARGETTYPE lib +UID 0x1000008d 0x102072AB + + +SOURCEPATH ../EapTls/ConfigUi/src + +SOURCE EapTlsUi.cpp +SOURCE EapTlsUiView.cpp +SOURCE EapTlsUiSettingArray.cpp + + +USERINCLUDE ../EapTls/ConfigUi/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE +APP_LAYER_SYSTEMINCLUDE + +// Resource files +START RESOURCE ../data/EapTlsUi.rss + +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS + +END + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/EapTtlsUi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/EapTtlsUi.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: EAP TTLS UI Project mmp file +* +*/ + + +#include +#include + + +TARGET eapttlsui.lib +TARGETTYPE lib +UID 0x1000008d 0x10101219 + + +SOURCEPATH ../EapTtls/ConfigUi/src + +SOURCE EapTtlsUi.cpp +SOURCE EapTtlsUiView.cpp +SOURCE EapTtlsUiSettingArray.cpp + + +USERINCLUDE ../EapTtls/ConfigUi/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE +APP_LAYER_SYSTEMINCLUDE + + +// Resource files +START RESOURCE ../data/EapTtlsUi.rss + +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS + +END + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/GtcNotifDlg.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/GtcNotifDlg.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is project specification file for the GtcNotifDlg +* +*/ + + +#include +#include + +TARGET gtcnotifdlg.dll +TARGETTYPE DLL +UID 0x101FDFAE 0x102072AE +CAPABILITY CAP_GENERAL_DLL +VENDORID VID_DEFAULT + + +SOURCEPATH ../EapGtc/NotifierUi/src + +SOURCE GtcNotifDlgPlugin.cpp +SOURCE GTCResponseQueryDialog.cpp +SOURCE GTCMessageDisplayDialog.cpp + + +USERINCLUDE ../EapGtc/NotifierUi/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE + + +START RESOURCE ../data/GtcNotifDlgUi.rss + +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS + +END + + +#if defined(ARMCC) + DEFFILE ../eabi/gtcnotifdlg.def +#elif defined( WINSCW ) + DEFFILE ../bwinscw/gtcnotifdlg.def +#elif defined( WINS ) + DEFFILE ../bwins/gtcnotifdlg.def +#else + DEFFILE ../bmarm/gtcnotifdlg.def +#endif + + +LIBRARY euser.lib eikdlg.lib eiksrv.lib cone.lib commdb.lib eikcore.lib +LIBRARY eikcoctl.lib bafl.lib +LIBRARY avkon.lib +LIBRARY AknSkins.lib +LIBRARY charconv.lib +LIBRARY commonengine.lib +LIBRARY AknNotify.lib + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/MsChapv2NotifDlg.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/MsChapv2NotifDlg.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is project specification file for the MsChapv2NotifDlg +* +*/ + + +#include +#include + +TARGET mschapv2notifdlg.dll +TARGETTYPE DLL +UID 0x101FDFAE 0x102072B2 +CAPABILITY CAP_GENERAL_DLL +VENDORID VID_DEFAULT + + +SOURCEPATH ../EapMschapv2/NotifierUi/src + +SOURCE MsChapv2NotifDlgPlugin.cpp +SOURCE MsChapv2NotifDialog.cpp + + +USERINCLUDE ../EapMschapv2/NotifierUi/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE + + +START RESOURCE ../data/MsChapv2NotifDlgUi.rss +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS +END + + +#if defined(ARMCC) + DEFFILE ../eabi/mschapv2notifdlg.def +#elif defined( WINSCW ) + DEFFILE ../bwinscw/mschapv2notifdlg.def +#elif defined( WINS ) + DEFFILE ../bwins/mschapv2notifdlg.def +#else + DEFFILE ../bmarm/mschapv2notifdlg.def +#endif + + +LIBRARY euser.lib eikdlg.lib eiksrv.lib cone.lib commdb.lib eikcore.lib +LIBRARY eikcoctl.lib bafl.lib +LIBRARY avkon.lib +LIBRARY AknSkins.lib +LIBRARY charconv.lib +LIBRARY commonengine.lib +LIBRARY AknNotify.lib + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This file provides the information required for building theWLAN EAP Settings UI. +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS +// export iby files +../rom/WlanEapSettingsUi.iby CORE_MW_LAYER_IBY_EXPORT_PATH(WlanEapSettingsUi.iby) +../rom/WlanEapSettingsUiResources.iby LANGUAGE_MW_LAYER_IBY_EXPORT_PATH(WlanEapSettingsUiResources.iby) + +// export localised loc file +../loc/wlaneapsettingsui.loc MW_LAYER_LOC_EXPORT_PATH(wlaneapsettingsui.loc) +../EapAka/ConfigUi/loc/eapakaui.loc MW_LAYER_LOC_EXPORT_PATH(eapakaui.loc) +../EapGtc/ConfigUi/loc/eapgtcui.loc MW_LAYER_LOC_EXPORT_PATH(eapgtcui.loc) +../EapGtc/NotifierUi/loc/gtcnotifdlg.loc MW_LAYER_LOC_EXPORT_PATH(gtcnotifdlg.loc) +../EapMschapv2/ConfigUi/loc/eapmschapv2ui.loc MW_LAYER_LOC_EXPORT_PATH(eapmschapv2ui.loc) +../EapMschapv2/NotifierUi/loc/mschapv2notifdlg.loc MW_LAYER_LOC_EXPORT_PATH(mschapv2notifdlg.loc) +../EapPeap/ConfigUi/loc/eappeapui.loc MW_LAYER_LOC_EXPORT_PATH(eappeapui.loc) +../EapSim/ConfigUi/loc/eapsimui.loc MW_LAYER_LOC_EXPORT_PATH(eapsimui.loc) +../EapTls/ConfigUi/loc/eaptlsui.loc MW_LAYER_LOC_EXPORT_PATH(eaptlsui.loc) +../EapTtls/ConfigUi/loc/eapttlsui.loc MW_LAYER_LOC_EXPORT_PATH(eapttlsui.loc) +../pap/configui/loc/papui.loc MW_LAYER_LOC_EXPORT_PATH(papui.loc) +../pap/notifierui/loc/papnotifdlg.loc MW_LAYER_LOC_EXPORT_PATH(papnotifdlg.loc) + +PRJ_MMPFILES + +// Settings dialogs +EapSimUi.mmp +EapTlsUi.mmp +EapPeapUi.mmp +EapTtlsUi.mmp +EapMschapv2Ui.mmp +EapGtcUi.mmp +EapAkaUi.mmp +papui.mmp + +// Notifiers components +MsChapv2NotifDlg.mmp +GtcNotifDlg.mmp +papnotifdlg.mmp + + +// Notifier wrapper +eapnotifwrapper.mmp + +// Access Point UI interface module +EapPluginConfig.mmp + +PRJ_TESTMMPFILES + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/eapnotifwrapper.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/eapnotifwrapper.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is project specification file for the eapnotifwrapper +* +*/ + +#include +#include + +TARGET eapnotifwrapper.dll +TARGETTYPE PLUGIN +UID 0x10009D8D 0x2000CF2E +VENDORID VID_DEFAULT +CAPABILITY CAP_ECOM_PLUGIN + +LANG SC + +SOURCEPATH ../eapnotifwrapper/src +SOURCE eapnotifwrapper.cpp + +USERINCLUDE ../eapnotifwrapper/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE + +START RESOURCE ../data/2000cf2e.rss +TARGET eapnotifwrapper.rsc +TARGETPATH ECOM_RESOURCE_DIR +END + + +LIBRARY ecom.lib +LIBRARY aknnotifierwrapper.lib +LIBRARY euser.lib + +DEBUGLIBRARY flogger.lib +DEBUGLIBRARY efsrv.lib +DEBUGLIBRARY cone.lib + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/papnotifdlg.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/papnotifdlg.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project specification file for pap/notifierui +* +*/ + + +#include +#include + +TARGET papnotifdlg.dll +TARGETTYPE DLL +UID 0x101FDFAE 0x200159AA +CAPABILITY CAP_GENERAL_DLL +VENDORID VID_DEFAULT + + +SOURCEPATH ../pap/notifierui/src + +SOURCE papnotifdlgplugin.cpp +SOURCE papauthdialog.cpp +SOURCE papchallengemsgdialog.cpp +SOURCE papchallengereplydialog.cpp + + +USERINCLUDE ../pap/notifierui/inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE + + +START RESOURCE ../data/papnotifdlgui.rss +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS +END + + +#if defined(ARMCC) + DEFFILE ../eabi/papnotifdlg.def +#elif defined( WINSCW ) + DEFFILE ../bwinscw/papnotifdlg.def +#elif defined( WINS ) + DEFFILE ../bwins/papnotifdlg.def +#else + DEFFILE ../bmarm/papnotifdlg.def +#endif + + + +LIBRARY euser.lib eikdlg.lib eiksrv.lib cone.lib commdb.lib eikcore.lib +LIBRARY eikcoctl.lib bafl.lib +LIBRARY avkon.lib +LIBRARY AknSkins.lib +LIBRARY charconv.lib +LIBRARY commonengine.lib +LIBRARY AknNotify.lib + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/group/papui.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/group/papui.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Project specification file for pap/configui +* +*/ + + +#include +#include + + +TARGET papui.lib +TARGETTYPE lib +UID 0x1000008d 0x200159AB + +SOURCEPATH ../pap/configui/src + +SOURCE papui.cpp +SOURCE papuisettingarray.cpp +SOURCE papuiview.cpp +SOURCE papuipwsettingitem.cpp + +USERINCLUDE ../pap/configui/inc + + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE +APP_LAYER_SYSTEMINCLUDE + +// Resource files +START RESOURCE ../data/papui.rss + +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS + +END + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/loc/wlaneapsettingsui.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/loc/wlaneapsettingsui.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,422 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Common UI strings for WLAN EAP Plugins +* +*/ + + + +// LOCALISATION STRINGS + + +//d:Command in options menu. Open configuration settings. +//l:list_single_pane_t1_cp2 +//w: +//r:3.1 +// +#define qtn_wlan_options_eap_plugin_configure "Configure" + + +//d:Command in options menu. Enables a plugin. +//l:list_single_pane_t1_cp2 +//w: +//r:3.1 +// +#define qtn_wlan_options_eap_plugin_enable "Enable" + + +//d:Command in options menu. Disables a plugin. +//l:list_single_pane_t1_cp2 +//w: +//r:3.1 +// +#define qtn_wlan_options_eap_plugin_disable "Disable" + + +//d:MSK text. Open configuration settings. +//l:control_pane_t3/opt7 +//w: +//r:3.2 +// +#define qtn_msk_wlan_eap_configure "Configure" + + +//d:MSK text. Enables a cipher suite. +//l:control_pane_t3/opt7 +//w: +//r:3.2 +// +#define qtn_msk_wlan_eap_cs_enable "Enable" + + +//d:MSK text. Disables a cipher suite. +//l:control_pane_t3/opt7 +//w: +//r:3.2 +// +#define qtn_msk_wlan_eap_cs_disable "Disable" + + +//d:Options list item, command. Selected plugin is moved up one row in a +//d:numbered EAP type list, where list order represents the priority. +//l:list_single_pane_t1_cp2 +//w: +//r:3.1 +// +#define qtn_wlan_options_eap_plugin_priority_up "Raise priority" + + +//d:Options list item, command. Selected plugin is moved down one row in a +//d:numbered EAP type list, where list order represents the priority. +//l:list_single_pane_t1_cp2 +//w: +//r:3.1 +// +#define qtn_wlan_options_eap_plugin_priority_down "Lower priority" + + +//d:Info note to the user when he is trying to disable all the EAP plugins +//l:popup_note_window +//w: +//r:3.1 +// +#define qtn_wlan_info_cannot_disable_all_eap_plugins "At least one EAP plug-in has to be enabled" + + +//d:The setting item for user name entry +//l:list_setting_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_username "User name" + + +//d:The setting item that specifies what kind of user name is in use. +//d:Possible options are "From SIM" +//d:(qtn_wlan_eap_sett_username_inuse_from_sim), "From certificate" +//d:(qtn_wlan_eap_sett_username_inuse_from_cert) or "User-configured" +//d:(qtn_wlan_eap_sett_username_inuse_user) +//l:list_setting_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_username_inuse "User name in use" + + +//d:One of the setting item values for qtn_wlan_eap_sett_username_inuse +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_username_inuse_from_sim "From SIM" + + +//d:One of the setting item values for qtn_wlan_eap_sett_username_inuse +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_username_inuse_from_cert "From certificate" + + +//d:One of the setting item values for qtn_wlan_eap_sett_username_inuse +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_username_inuse_user "User-configured" + + +//d:The setting item is for password promt +//l:list_setting_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_password "Password" + + +//d:The setting item where the user can choose if he should be prompted for the +//d:password or not. Possible options are "Yes" +//d:(qtn_wlan_eap_sett_passprompt_on) or "No" +//d:(qtn_wlan_eap_sett_passprompt_off). +//l:list_setting_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_passprompt "Prompt password" + + +//d:One of the setting item values for qtn_wlan_eap_sett_passprompt +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_passprompt_on "Yes" + + +//d:One of the setting item values for qtn_wlan_eap_sett_passprompt +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_passprompt_off "No" + + +//d:The setting item for Realm entry +//l:list_setting_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_realm "Realm" + + +//d:The setting item that specifies what kind of realm is in use. +//d:Possible options are "From SIM" (qtn_wlan_eap_sett_realm_inuse_from_sim), +//d:"From certificate" (qtn_wlan_eap_sett_realm_inuse_from_cert) or +//d:"User-configured" (qtn_wlan_eap_sett_realm_inuse_user). +//l:list_setting_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_realm_inuse "Realm in use" + + +//d:One of the setting item values for qtn_wlan_eap_sett_realm_inuse +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_realm_inuse_from_sim "From SIM" + + +//d:One of the setting item values for qtn_wlan_eap_sett_realm_inuse +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_realm_inuse_from_cert "From certificate" + + +//d:One of the setting item values for qtn_wlan_eap_sett_realm_inuse +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_realm_inuse_user "User-configured" + + +//d:The setting item for user certificate entry +//d:Possible options are "(not defined)" (qtn_wlan_eap_cert_not_defined), +//d:"None" (qtn_wlan_eap_cert_none_selection), or one of the installed user +//d:certificates. +//l:list_setting_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_user_certificate "User certificate" + + +//d:The setting item for CA certificate entry. +//d:Possible options are "(not defined)" (qtn_wlan_eap_cert_not_defined), +//d:"None" (qtn_wlan_eap_cert_none_selection), or one of the installed user +//d:certificates. +//l:list_setting_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_sett_ca_certificate "CA certificate" + + +//d:Not defined text to qtn_wlan_eap_sett_user_certificate and +//d:qtn_wlan_eap_sett_ca_certificate setting items in case +//d:no certificate has been selected. +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_cert_not_defined "(not defined)" + + +//d:One of the setting item values for qtn_wlan_eap_sett_user_certificate and +//d:qtn_wlan_eap_sett_ca_certificate. +//l:list_set_graphic_pane_t1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_cert_none_selection "None" + + +//d:Text in the tab for Settings page. +//l:tabs_2_active_pane_t1/opt1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_tab_settings "Settings" + + +//d:Text in the tab for EAP type selection page +//l:tabs_2_active_pane_t1/opt1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_tab_eap_types "EAP types" + + +//d:Text in the tab for Cipher suites selection page +//l:tabs_2_active_pane_t1/opt1 +//w: +//r:3.1 +// +#define qtn_wlan_eap_tab_cipher_suites "Cipher suites" + + +//d:Cipher suite type text in list control +//l:list_single_number_pane_t1/opt2 +//w: +//r:3.1 +// +#define qtn_wlan_eap_cipher_rsarc4md5 "RSA,RC4,MD5" + + +//d:Cipher suite type text in list control +//l:list_single_number_pane_t1/opt2 +//w: +//r:3.1 +// +#define qtn_wlan_eap_cipher_rsarc4sha "RSA,RC4,SHA" + + +//d:Cipher suite type text in list control +//l:list_single_number_pane_t1/opt2 +//w: +//r:3.1 +// +#define qtn_wlan_eap_cipher_rsa3dessha "RSA,3DES,SHA" + + +//d:Cipher suite type text in list control +//l:list_single_number_pane_t1/opt2 +//w: +//r:3.1 +// +#define qtn_wlan_eap_cipher_dhersa3dessha "DHE-RSA,3DES,SHA" + + +//d:Cipher suite type text in list control +//l:list_single_number_pane_t1/opt2 +//w: +//r:3.1 +// +#define qtn_wlan_eap_cipher_dhedss3dessha "DHE-DSS,3DES,SHA" + + +//d:Cipher suite type text in list control +//l:list_single_number_pane_t1/opt2 +//w: +//r:3.1 +// +#define qtn_wlan_eap_cipher_rsaaessha "RSA,AES,SHA" + + +//d:Cipher suite type text in list control +//l:list_single_number_pane_t1/opt2 +//w: +//r:3.1 +// +#define qtn_wlan_eap_cipher_dhersaaessha "DHE-RSA,AES,SHA" + + +//d:Cipher suite type text in list control +//l:list_single_number_pane_t1/opt2 +//w: +//r:3.1 +// +#define qtn_wlan_eap_cipher_dhedssaessha "DHE-DSS,AES,SHA" + + +//d:The setting item that specifies if TLS privacy is used or not. +//d:Possible options are "On" +//d:(qtn_wlan_eap_sett_tls_privacy_on) or "Off" +//d:(qtn_wlan_eap_sett_tls_privacy_off) +//l:list_setting_pane_t1 +//w: +//r:3.2 +// +#define qtn_wlan_eap_sett_tls_privacy "TLS privacy" + + +//d:One of the setting item values for qtn_wlan_eap_sett_tls_privacy +//l:list_set_graphic_pane_t1 +//w: +//r:3.2 +// +#define qtn_wlan_eap_sett_tls_privacy_on "On" + +//d:One of the setting item values for qtn_wlan_eap_sett_tls_privacy +//l:list_set_graphic_pane_t1 +//w: +//r:3.2 +// +#define qtn_wlan_eap_sett_tls_privacy_off "Off" + + +//d:Information note for user when passwords do not match +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_wlan_eap_info_passwords_do_not_match "Passwords do not match, try again" + + +//d:Error note for user when password is incorrect +//l:popup_note_window +//w: +//r:3.2 +// +#define qtn_wlan_eap_error_incorrect_password "Incorrect password" + + +//d:The popup query for user to create a PAC store password +//l:popup_query_data_window +//w: +//r:3.2 +// +#define qtn_wlan_eap_fast_prmpt_create_pac_password "Create password for the encrypted PAC store:" + + +//d:The popup query for user to verify a PAC store password +//l:popup_query_data_window +//w: +//r:3.2 +// +#define qtn_wlan_eap_fast_prmpt_verify_password "Verify password:" + + +//d:The popup query for user to set a PAC store password +//l:popup_query_data_window +//w: +//r:3.2 +// +#define qtn_wlan_eap_fast_prmpt_pac_password "PAC store password:" + +//d:Default value text for a username setting item whose value has not yet been set. +//d:Used for the username setting qtn_wlan_eap_sett_username +//l:list_set_graphic_pane_t1 +//w: +//r:5.0.1 +// +#define qtn_wlan_eap_sett_username_not_defined "(not defined)" + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/configui/data/papui.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/configui/data/papui.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,236 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: PAP UI resource file +* +*/ + + +// RESOURCE IDENTIFIER +NAME PAPC + +// INCLUDES +#include +#include "papui.hrh" // Enums for these resources +#include // Localisation file +#include +#include +#include +#include +#include +#include + + +// CONSTANTS + +#define ESecUiQueryFlags (EGeneralQueryFlags | EEikDialogFlagNotifyEsc | EEikDialogFlagWait) + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + + +RESOURCE TBUF16 { buf=""; } + + +RESOURCE CBA r_pap_ui_softkeys_options_back_edit + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EPapUiCmdChange; txt = qtn_msk_change; } + }; + } + +RESOURCE DIALOG r_pap_setting_dialog + { +/* flags = EEikDialogFlagFillAppClientRect | + EEikDialogFlagCbaButtons | + EEikDialogFlagWait | + EEikDialogFlagNotifyEsc; */ + + flags = EAknDialogSelectionList | EEikDialogFlagWait; + buttons = r_pap_ui_softkeys_options_back_edit; + items = + { + DLG_LINE + { + id = EPapSettingsListBox; + type = EAknCtSettingListBox; + control = LISTBOX + { + flags = EAknListBoxMenuList; + }; + } + }; + } + + + +RESOURCE AVKON_SETTING_PAGE r_pap_username_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label= qtn_wlan_eap_sett_username; + type = EEikCtEdwin; + editor_resource_id = r_pap_username_editor; + } + +RESOURCE EDWIN r_pap_username_editor + { + width = 9; + lines = 5; + maxlength = KPapUsernameMaxLength; + allowed_input_modes = EAknEditorTextInputMode | EAknEditorNumericInputMode; + default_input_mode = EAknEditorTextInputMode; + default_case = EAknEditorLowerCase; + avkon_flags = EAknEditorFlagLatinInputModesOnly; + flags = EEikEdwinAutoSelection | EEikEdwinNoLineOrParaBreaks; + } + +RESOURCE AVKON_SETTING_PAGE r_pap_password_popup_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_password; + type = EAknCtPopupSettingList; + editor_resource_id = r_pap_setting_enumerated_popup; + } + +RESOURCE POPUP_SETTING_LIST r_pap_setting_enumerated_popup + { + flags = EAknPopupSettingListFlagInitialised; + } + + +RESOURCE AVKON_POPUP_SETTING_TEXTS r_pap_password_prompt_choices + { + setting_texts_resource = r_pap_prompt_choices_resource; + popped_up_texts_resource = r_pap_prompt_choices_texts_array; + } + +RESOURCE ARRAY r_pap_prompt_choices_resource + { + items= + { + AVKON_ENUMERATED_TEXT + { + value = 1; + text = qtn_wlan_eap_pap_sett_password_prompt; + }, + + AVKON_ENUMERATED_TEXT + { + value = 0; + text = qtn_wlan_eap_pap_sett_password_udef; + } + }; + } + +RESOURCE ARRAY r_pap_prompt_choices_texts_array + { + items= + { + LBUF { txt = qtn_wlan_eap_pap_sett_password_prompt; }, + LBUF { txt = qtn_wlan_eap_pap_sett_password_udef; } + }; + } + +RESOURCE AVKON_SETTING_PAGE r_pap_password_setting_page + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + label = qtn_wlan_eap_sett_password; + type = EEikCtSecretEd; + editor_resource_id = r_pap_setting_password; + } + + +RESOURCE SECRETED r_pap_setting_password + { + num_letters = KPapPasswordMaxLength; + } + +// No dialog, make this as another setting page, only that +// it is not visible when setting list is drawn. +// It can be referred to and opened with the item id defined in .hrh. +/*RESOURCE DIALOG r_pap_password_dialog + { + flags=ESecUiQueryFlags; + buttons=R_AVKON_SOFTKEYS_OK_CANCEL__OK; + items= + { + DLG_LINE + { + type=EAknCtQuery; + id=EGeneralQuery; + control= AVKON_DATA_QUERY + { + layout = ECodeLayout; + label = qtn_wlan_eap_sett_password; + control = SECRETED + { + num_letters = KPapPasswordMaxLength; + }; + }; + } + }; + } +*/ + +RESOURCE MENU_BAR r_pap_menubar + { + titles = + { + MENU_TITLE + { + menu_pane = r_pap_menu_pane; + txt = ""; + } + }; + } + + +RESOURCE MENU_PANE r_pap_menu_pane + { + items = + { + MENU_ITEM + { + command = EPapUiCmdChange; + txt = qtn_options_change; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = EAknCmdHelp; + txt = qtn_options_help; + }, + + MENU_ITEM + { + command = EAknCmdExit; + txt = qtn_options_exit; + } + }; + } + + +// Resource strings +RESOURCE TBUF r_pap_settings_title { buf = qtn_wlan_eap_pap_title; } +RESOURCE TBUF r_pap_username_not_defined { buf = qtn_wlan_eap_sett_username_not_defined; } +RESOURCE TBUF r_pap_define_username_info_note { buf = qtn_wlan_eap_pap_define_user_name; } +RESOURCE TBUF r_pap_username_setting_title { buf = qtn_wlan_eap_sett_username; } +RESOURCE TBUF r_pap_password_setting_title { buf = qtn_wlan_eap_sett_password; } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/configui/inc/papui.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/configui/inc/papui.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: PAP UI hrh file +* +*/ + + +#ifndef _PAPUI_HRH_ +#define _PAPUI_HRH_ + +#define KPapUsernameMaxLength 253 +#define KPapPasswordMaxLength 128 + +enum TPapUiMenuCommands + { + EPapUiCmdUndefined = 6000, + EPapUiCmdChange + }; + +enum TPapUiNotes + { + TPapUiGeneralError = 6100 + }; + +enum TPapUiLines + { + EPapSettingsListBox = 6200 + }; + +enum TPapSettingIds + { + EPapSettingUsernameSettingId=6300, + EPapSettingPassPromptSettingId, + EPapSettingPasswordSettingId + }; + +enum TPapSettingItemId + { + EPapSettingPageUserName=6400, + EPapSettingPagePasswordPrompt, + EPapSettingPagePassword + }; + +#endif //_PAPUI_HRH_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/configui/inc/papuipwsettingitem.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/configui/inc/papuipwsettingitem.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of PAP UI password setting item +* +*/ + + + +#ifndef _PAPUIPWSETTINGITEM_H_ +#define _PAPUIPWSETTINGITEM_H_ + +// INCLUDES +#include + +// FORWARD DECLARATIONS +class CPapSettingItemArray; + +// CLASS DECLARATION + +/** +* Password setting item class definition +*/ +class CPapUiPwSettingItem : public CAknPasswordSettingItem + { + public: + + CPapUiPwSettingItem( TInt aIdentifier, + enum TAknPasswordSettingItemMode aMode, + TDes &aPassword, + CPapSettingItemArray* aParent ); + + ~CPapUiPwSettingItem(); + + + public: // From CAknSettingItem + + /** + * Handles setting page events. + * @param aSettingPage The originating setting page. + * @param aEventType A code for the event. + */ + void HandleSettingPageEventL( + CAknSettingPage *aSettingPage, TAknSettingPageEvent aEventType ); + + public: // new + + /** + * Deletes the password. + */ + void DeletePasswordL(); + + + private: + + // Reference, not owned + CPapSettingItemArray* iParent; + }; + + +#endif // _PAPUIPWSETTINGITEM_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/configui/inc/papuisettingarray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/configui/inc/papuisettingarray.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of PAP UI settings array +* +*/ + + + +#ifndef _PAPUISETTINGARRAY_H_ +#define _PAPUISETTINGARRAY_H_ + +// INCLUDES +#include +#include "papui.hrh" + + +// CLASS DECLARATION + +/** +*/ +class CPapSettingItemArray : public CBase + { + public: + static CPapSettingItemArray* NewL(); + virtual ~CPapSettingItemArray(); + CAknSettingItem* Item( TPapSettingItemId aItem ); + CAknSettingItemArray* Array(); + void StoreSettingsL(); + void AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal ); + void AddBinarySettingItemL( TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue ); + void AddPasswordItemL( TDes& aPassword, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal ); + void PwItemCancelled( TBool aIsCancelled ); + TBool IsPwItemCancelled(); + + + protected: + CPapSettingItemArray(); + void ConstructL(); + + + private: + CEikonEnv* iEnv; + CAknSettingItemArray* iArray; + TBool iPwItemCancelled; + }; + +#endif // _PAPUISETTINGARRAY_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/configui/inc/papuiview.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/configui/inc/papuiview.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,127 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Header file of PAP UI setting dialog +* +*/ + + + +#ifndef _PAPUIVIEW_H_ +#define _PAPUIVIEW_H_ + +// INCLUDES +#include // AVKON components +#include // For changing status pane +#include +#include +#include +#include +#include +#include +#include "papui.hrh" +#include +#include +#include + +// FORWARD DECLARATIONS +class CAknSettingStyleListBox; +class CSettingsListBoxItemDrawer; +class CPapSettingItemArray; + + +// CLASS DECLARATION + +/** +* Settings dialog class definition +*/ +class CPapUiDialog : public CAknDialog, + public MEikListBoxObserver + { + public: + CPapUiDialog( CEapTlsPeapUiConnection* aConnection, + TInt& aButtonId ); + + ~CPapUiDialog(); + + /** + * Create and launch dialog. + * @param aResourceId The resource ID of the dialog to load. + * @return The ID of the button that closed the dialog + */ + TInt ConstructAndRunLD( TInt aResourceId ); + + + public: // From MEikListBoxObserver + + /** + * Handles list box events. + * @param aListBox The originating list box. + * @param aEventType A code for the event. + */ + void HandleListBoxEventL( CEikListBox* aListBox, TListBoxEvent aEventType ); + + + protected: + void PreLayoutDynInitL(); + TBool OkToExitL( TInt aButtonId ); + void ProcessCommandL( TInt aCommand ); + + private: + void ChangeTitleL( TBool aIsStarted ); + void DrawSettingsListL(); + void ShowSettingPageL( TInt aCalledFromMenu ); + void ShowUsernameSettingPageL(); + void ShowPasswordSettingPageL(); + void GetHelpContext( TCoeHelpContext& aContext ) const; + + /** + * Initialize menu pane. + * @param aResourceId Menu pane resource id. + * @param CEikMenuPane Menu pane. + */ + void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ); + + /** + * Copy the setting data to the eapol db data pointer. + */ + void UpdateEapolData(); + + + private: + CEapTlsPeapUiConnection* iConnection; + CEapTlsPeapUiDataConnection* iDataConnection; + CEapTlsPeapUiTlsPeapData* iUiData; + CPapSettingItemArray* iSettingArray; + CAknSettingStyleListBox* iSettingListBox; + CAknNavigationControlContainer* iNaviPane; + CAknNavigationDecorator* iNaviDecorator; + HBufC* iPreviousText; + TInt* iButtonId; + + // Temporary UI data as shown on the Settings UI + TBuf iSettingUsername; + TBool iSettingPwPrompt; + TBuf iSettingPassword; + + + // Tells the status of UI construction. TRUE if UI construction is completed. + TBool iIsUIConstructionCompleted; + + TBool iUsernameCancelled; + }; + + +#endif // _PAPUIVIEW_H_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/configui/loc/papui.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/configui/loc/papui.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI strings for WLAN PAP configuration settings +* +*/ + + + +// LOCALISATION STRINGS + + +//d:UI title for main view +//l:title_pane_t2/opt9 +//w: +//r:5.0.1 +// +#define qtn_wlan_eap_pap_title "PAP settings" + + +//d:One of the setting item values for qtn_wlan_eap_pap_sett_password +//l:list_set_graphic_pane_t1 +//w: +//r:5.0.1 +// +#define qtn_wlan_eap_pap_sett_password_prompt "Prompt" + + +//d:One of the setting item values for qtn_wlan_eap_pap_sett_password +//l:list_set_graphic_pane_t1 +//w: +//r:5.0.1 +// +#define qtn_wlan_eap_pap_sett_password_udef "User defined" + +//d:Information note when user accepts a password but +//d: the user name is undefined +//l:popup_note_window +//w: +//r:5.0.1 +// +#define qtn_wlan_eap_pap_define_user_name "Please define a user name" + + + + + + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/configui/src/papui.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/configui/src/papui.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,137 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 PAP UI class +* +*/ + + + +// INCLUDE FILES +#include +#include +#include "papuiview.h" +#include +#include +#include +#include + + +// CONSTANTS +_LIT( KDriveZ, "z:" ); // ROM folder +_LIT( KResourceFileName, "papui.rsc" ); + + +// CLASS DECLARATION +class TResourceFileCleanupItem + { + public: + CCoeEnv* iCoeEnv; + TInt iResourceFileOffset; + }; + + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CleanupResourceFile +// ----------------------------------------------------------------------------- +// +static void CleanupResourceFile( TAny* aObject ) + { + TResourceFileCleanupItem* item = + REINTERPRET_CAST( TResourceFileCleanupItem*, aObject ); + item->iCoeEnv->DeleteResourceFile( item->iResourceFileOffset ); + delete item; + } + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPapUi::CPapUi +// ----------------------------------------------------------------------------- +// +CPapUi::CPapUi( CEapTlsPeapUiConnection* aConnection ) +: iConnection( aConnection ) + { + } + + +// ----------------------------------------------------------------------------- +// CPapUi::NewL +// ----------------------------------------------------------------------------- +// +CPapUi* CPapUi::NewL( CEapTlsPeapUiConnection* aConnection ) + { + CPapUi* self = new( ELeave ) CPapUi( aConnection ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CPapUi::ConstructL +// ----------------------------------------------------------------------------- +// +void CPapUi::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CPapUi::~CPapUi +// ----------------------------------------------------------------------------- +// +CPapUi::~CPapUi() + { + } + + +// ----------------------------------------------------------------------------- +// CPapUi::InvokeUiL +// ----------------------------------------------------------------------------- +// +TInt CPapUi::InvokeUiL() + { + TFileName fileName; + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + CCoeEnv* coeEnv = CCoeEnv::Static(); + + BaflUtils::NearestLanguageFile( coeEnv->FsSession(), fileName ); + + TResourceFileCleanupItem* item = new( ELeave ) TResourceFileCleanupItem; + + item->iCoeEnv = coeEnv; + CleanupStack::PushL( TCleanupItem( CleanupResourceFile, item ) ); + + item->iResourceFileOffset = coeEnv->AddResourceFileL( fileName ); + + TInt buttonId; + CPapUiDialog* settingsDlg = new( ELeave ) CPapUiDialog( + iConnection, buttonId ); + + settingsDlg->ConstructAndRunLD( R_PAP_SETTING_DIALOG ); + + CleanupStack::PopAndDestroy(); // Resource file + + return buttonId; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/configui/src/papuipwsettingitem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/configui/src/papuipwsettingitem.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 PAP UI password setting item +* +*/ + + + +// INCLUDE FILES +#include "papuipwsettingitem.h" +#include "papuisettingarray.h" +#include + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPapUiPwSettingItem::CPapUiPwSettingItem +// ----------------------------------------------------------------------------- +// +CPapUiPwSettingItem::CPapUiPwSettingItem( TInt aIdentifier, + enum TAknPasswordSettingItemMode aMode, + TDes &aPassword, + CPapSettingItemArray* aParent ) + : CAknPasswordSettingItem( aIdentifier, aMode, aPassword ), + iParent ( aParent ) + { + } + + + +// ----------------------------------------------------------------------------- +// CPapUiPwSettingItem::~CPapUiPwSettingItem +// ----------------------------------------------------------------------------- +// +CPapUiPwSettingItem::~CPapUiPwSettingItem() + { + } + + +// --------------------------------------------------------- +// CPapUiPwSettingItem::HandleSettingPageEventL +// --------------------------------------------------------- +// +void CPapUiPwSettingItem::HandleSettingPageEventL( + CAknSettingPage * /*aSettingPage*/, TAknSettingPageEvent aEventType ) + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CPapUiPwSettingItem::HandleSettingPageEventL, event = %d"), + aEventType ); + #endif + + switch ( aEventType ) + { + case EEventSettingCancelled: + { + iParent->PwItemCancelled( ETrue ); + break; + } + + case EEventSettingChanged: + case EEventSettingOked: + { + iParent->PwItemCancelled( EFalse ); + break; + } + + default: + { + break; + }; + }; + } + +// --------------------------------------------------------- +// CPapUiPwSettingItem::DeletePasswordL +// --------------------------------------------------------- +// +void CPapUiPwSettingItem::DeletePasswordL() + { + TPtr ptr = InternalTextPtr(); + ptr.Copy( KNullDesC ); + StoreL(); + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/configui/src/papuisettingarray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/configui/src/papuisettingarray.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,245 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 PAP UI settings array +* +*/ + + + +// INCLUDE FILES +#include "papuisettingarray.h" +#include "papui.hrh" +#include "papuipwsettingitem.h" +#include +#include +#include + +// CONSTANTS +_LIT( KEmptyPassword, "****" ); + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPapSettingItemArray::CPapSettingItemArray +// ----------------------------------------------------------------------------- +// +CPapSettingItemArray::CPapSettingItemArray() + { + iEnv = CEikonEnv::Static(); + } + + +// ----------------------------------------------------------------------------- +// CPapSettingItemArray::NewL +// ----------------------------------------------------------------------------- +// +CPapSettingItemArray* CPapSettingItemArray::NewL() + { + CPapSettingItemArray* self = new( ELeave ) CPapSettingItemArray(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); // self + return self; + } + + +// ----------------------------------------------------------------------------- +// CPapSettingItemArray::ConstructL +// ----------------------------------------------------------------------------- +// +void CPapSettingItemArray::ConstructL() + { + iArray = new( ELeave ) CAknSettingItemArray( 2, EFalse, 0 ); + } + + +// ----------------------------------------------------------------------------- +// CPapSettingItemArray::~CPapSettingItemArray +// ----------------------------------------------------------------------------- +// +CPapSettingItemArray::~CPapSettingItemArray() + { + if( iArray ) + { + // ResetAndDestroy() + iArray->ResetAndDestroy(); + } + delete iArray; + iArray = NULL; + } + + +// ----------------------------------------------------------------------------- +// CPapSettingItemArray::Item +// ----------------------------------------------------------------------------- +// +CAknSettingItem* CPapSettingItemArray::Item( TPapSettingItemId aId ) + { + for( TInt i = 0; i < iArray->Count(); i++ ) + { + if( iArray->At( i )->Identifier() == aId ) + { + return iArray->At( i ); + } + } + + __ASSERT_DEBUG( EFalse, User::Invariant() ); + return NULL; + } + + +// ----------------------------------------------------------------------------- +// CEapFastSettingItemArray::Array +// ----------------------------------------------------------------------------- +// +CAknSettingItemArray* CPapSettingItemArray::Array() + { + return iArray; + } + + +// ----------------------------------------------------------------------------- +// CPapSettingItemArray::StoreSettingsL +// ----------------------------------------------------------------------------- +// +void CPapSettingItemArray::StoreSettingsL() + { + // Do what SettingItemList::StoreSettings would do. + for( TInt i( 0 ); i < iArray->Count(); ++i ) + { + iArray->At( i )->StoreL(); + } + } + + +// ----------------------------------------------------------------------------- +// CPapSettingItemArray::AddTextItemL +// ----------------------------------------------------------------------------- +// +void CPapSettingItemArray::AddTextItemL( TDes& aBuffer, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal) + { + // Create new setting item + CAknTextSettingItem* settingItem = + new( ELeave ) CAknTextSettingItem( aId, aBuffer ); + CleanupStack::PushL( settingItem ); + + HBufC* usernameNotDefinedText = iEnv->AllocReadResourceLC( + R_PAP_USERNAME_NOT_DEFINED ); + settingItem->SetEmptyItemTextL( *usernameNotDefinedText ); + CleanupStack::PopAndDestroy( usernameNotDefinedText ); + + settingItem->SetSettingPageFlags( + CAknTextSettingPage::EZeroLengthNotOffered ); + + // Construct setting item with parametrized values + HBufC* itemTitle = iEnv->AllocReadResourceLC( aTitleResource ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResource, EAknCtPopupSettingList, + NULL, aAssociatedResource ); + + // Append item to settingitem-array + iArray->InsertL( aOrdinal, settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + // Items are destroyed in destructor when resetting array + CleanupStack::Pop( settingItem ); + } + + +// ----------------------------------------------------------------------------- +// CPapSettingItemArray::AddBinarySettingItemL +// ----------------------------------------------------------------------------- +// +void CPapSettingItemArray::AddBinarySettingItemL( + TInt aSettingPageResourceId, + TInt aTitleResourceId, + TInt aAssociatedResourceId, + TInt aOrdinal, + TBool& aModifiedValue ) + { + CAknSettingItem* settingItem = new ( ELeave ) + CAknBinaryPopupSettingItem( 0, aModifiedValue ); + CleanupStack::PushL( settingItem ); + + HBufC* itemTitle = iEnv->AllocReadResourceLC( aTitleResourceId ); + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResourceId, EAknCtPopupSettingList, + NULL, aAssociatedResourceId ); + iArray->AppendL( settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + CleanupStack::Pop( settingItem ); + } + +// ----------------------------------------------------------------------------- +// CPapSettingItemArray::AddPasswordItemL +// ----------------------------------------------------------------------------- +// +void CPapSettingItemArray::AddPasswordItemL( TDes& aPassword, + TInt aId, + TInt aTitleResource, + TInt aSettingPageResource, + TInt aAssociatedResource, + TInt aOrdinal ) + { + // Create new setting item + CPapUiPwSettingItem* settingItem = new( ELeave ) CPapUiPwSettingItem( aId, + CAknPasswordSettingItem::EAlpha, + aPassword, this ); + CleanupStack::PushL( settingItem ); + settingItem->SetEmptyItemTextL( KEmptyPassword ); + + settingItem->SetSettingPageFlags( + CAknTextSettingPage::EZeroLengthAllowed ); + + // Construct setting item with parametrized values + HBufC* itemTitle = iEnv->AllocReadResourceLC( aTitleResource ); + + + settingItem->ConstructL( EFalse, aOrdinal, *itemTitle, NULL, + aSettingPageResource, EAknCtPopupSettingList, + NULL, aAssociatedResource ); + + // Append item to settingitem-array + iArray->InsertL( aOrdinal, settingItem ); + + CleanupStack::PopAndDestroy( itemTitle ); + CleanupStack::Pop( settingItem ); + } + +// ----------------------------------------------------------------------------- +// CPapSettingItemArray::PwItemCancelled +// ----------------------------------------------------------------------------- +// +void CPapSettingItemArray::PwItemCancelled( TBool aIsCancelled ) + { + iPwItemCancelled = aIsCancelled; + } + +// ----------------------------------------------------------------------------- +// CPapSettingItemArray::IsPwItemCancelled +// ----------------------------------------------------------------------------- +// +TBool CPapSettingItemArray::IsPwItemCancelled() + { + return iPwItemCancelled; + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/configui/src/papuiview.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/configui/src/papuiview.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,647 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 PAP UI settings dialog +* +*/ + + + +// INCLUDE FILES +#include "papuiview.h" +#include "papuisettingarray.h" +#include "papuipwsettingitem.h" +#include "papui.hrh" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// CONSTANTS +// UID of general settings app, in which help texts are included +const TUid KHelpUidPlugin = { 0x100058EC }; + +// MODULE DATA STRUCTURES +enum TSettingIds + { + EUsernameItem=0, + EPasswordPromptItem, + EPasswordItem + }; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPapUiDialog::CPapUiDialog +// ----------------------------------------------------------------------------- +// +CPapUiDialog::CPapUiDialog( CEapTlsPeapUiConnection* aConnection, + TInt& aButtonId ) +: CAknDialog(), + iConnection( aConnection ), + iNaviPane( 0 ), + iNaviDecorator( 0 ), + iButtonId( &aButtonId ), + iSettingPwPrompt( ETrue ), + iIsUIConstructionCompleted( EFalse ), + iUsernameCancelled( EFalse ) + { + } + + +// --------------------------------------------------------- +// CPapUiDialog::ConstructAndRunLD +// --------------------------------------------------------- +// +TInt CPapUiDialog::ConstructAndRunLD( TInt aResourceId ) + { + CleanupStack::PushL( this ); + + iSettingArray = CPapSettingItemArray::NewL(); + + User::LeaveIfError( iConnection->Connect() ); + + // Basic data + iDataConnection = iConnection->GetDataConnection(); + if ( iDataConnection == 0 ) + { + User::Leave( KErrNoMemory ); + } + User::LeaveIfError( iDataConnection->Open() ); + User::LeaveIfError( iDataConnection->GetData( &iUiData ) ); + + //Copy the eapol UI data to the temporary data shown on the setting UI + iSettingUsername.Copy( iUiData->GetPapUserName() ); + iSettingPwPrompt = *( iUiData->GetPapPasswordPrompt() ); + iSettingPassword.Copy( iUiData->GetPapPassword() ); + + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("When read from eapol, iSettingUsername = %S"), &iSettingUsername ); + RDebug::Print(_L("When read from eapol, iSettingPwPrompt = %d"), iSettingPwPrompt ); + RDebug::Print(_L("When read from eapol, iSettingPassword = %S"), &iSettingPassword ); + #endif + + FeatureManager::InitializeLibL(); + + ConstructL( R_PAP_MENUBAR ); + + // ExecuteLD will PushL( this ), so we have to Pop it first... + CleanupStack::Pop( this ); + + return CAknDialog::ExecuteLD( aResourceId ); + } + + +// ----------------------------------------------------------------------------- +// CPapUiDialog::~CPapUiDialog +// ----------------------------------------------------------------------------- +// +CPapUiDialog::~CPapUiDialog() + { + + delete iNaviDecorator; + + if ( iSettingArray ) + { + iSettingArray->Array()->ResetAndDestroy(); + delete iSettingArray; + } + + iSettingListBox = NULL; + + if ( iDataConnection ) + { + iDataConnection->Close(); + delete iDataConnection; + } + + if ( iConnection ) + { + iConnection->Close(); + } + + delete iPreviousText; + + FeatureManager::UnInitializeLib(); + } + + +// --------------------------------------------------------- +// CPapUiDialog::HandleListBoxEventL +// --------------------------------------------------------- +// +void CPapUiDialog::HandleListBoxEventL( CEikListBox* /*aListBox*/, + TListBoxEvent aEventType ) + { + switch ( aEventType ) + { + case EEventEnterKeyPressed: + case EEventItemSingleClicked: + { + OkToExitL( EPapUiCmdChange ); + break; + } + + case EEventItemActioned: + case EEventEditingStarted: + case EEventEditingStopped: + case EEventPenDownOnItem: + case EEventItemDraggingActioned: + { + break; + } + + default: + { + break; + }; + }; + } + + +// ----------------------------------------------------------------------------- +// CPapUiDialog::PreLayoutDynInitL +// ----------------------------------------------------------------------------- +// +void CPapUiDialog::PreLayoutDynInitL() + { + ChangeTitleL( ETrue ); + + TUid naviPaneUid; + naviPaneUid.iUid = EEikStatusPaneUidNavi; + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( naviPaneUid ); + if ( subPane.IsPresent()&&subPane.IsAppOwned() ) + { + iNaviPane = static_cast( + statusPane->ControlL( naviPaneUid ) ); + + // Set empty text to hide tabs. + iNaviDecorator = iNaviPane->CreateNavigationLabelL( KNullDesC ); + iNaviPane->PushL( *iNaviDecorator ); + } + + + // Initialize setting page + iSettingListBox = static_cast( + ControlOrNull( EPapSettingsListBox ) ); + iSettingListBox->SetMopParent( this ); + iSettingListBox->CreateScrollBarFrameL( ETrue ); + iSettingListBox->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + iSettingListBox->SetListBoxObserver( this ); + DrawSettingsListL(); + + iIsUIConstructionCompleted = ETrue; + + } + + +// ----------------------------------------------------------------------------- +// CPapUiDialog::ChangeTitleL +// ----------------------------------------------------------------------------- +// +void CPapUiDialog::ChangeTitleL( TBool aIsStarted ) + { + TUid titlePaneUid; + titlePaneUid.iUid = EEikStatusPaneUidTitle; + + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CEikStatusPaneBase::TPaneCapabilities subPane = + statusPane->PaneCapabilities( titlePaneUid ); + + if ( subPane.IsPresent() && subPane.IsAppOwned() ) + { + CAknTitlePane* titlePane = static_cast( + statusPane->ControlL( titlePaneUid) ); + if ( aIsStarted ) + { + // Store previous application title text + const TDesC* prevText = titlePane->Text(); + iPreviousText = HBufC::NewL( prevText->Length() ); + iPreviousText->Des().Append( *prevText ); + TDesC* titleText = iEikonEnv->AllocReadResourceLC( + R_PAP_SETTINGS_TITLE ); + titlePane->SetTextL( *titleText ); + CleanupStack::PopAndDestroy( titleText ); + } + else + { + // Set calling application title text back + titlePane->SetTextL( *iPreviousText ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CPapUiDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CPapUiDialog::OkToExitL( TInt aButtonId ) + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CPapUiDialog::OkToExitL") ); + #endif + + TBool ret( EFalse ); + switch ( aButtonId ) + { + case EEikBidOk: + { + if( iIsUIConstructionCompleted ) + { + if ( iSettingListBox->IsFocused() ) + { + ShowSettingPageL( EFalse ); + } + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CPapUiDialog::OkToExitL - UI not ready - Ignoring key press.\n") ); + #endif + } + + break; + } + + case EAknSoftkeyOptions: + { + DisplayMenuL(); + break; + } + + case EAknSoftkeyBack: + case EAknCmdExit: + { + UpdateEapolData(); + ChangeTitleL( EFalse ); + ret = ETrue; + break; + } + + case EPapUiCmdChange: + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( EFalse ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CPapUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + + break; + } + + default: + { + break; + } + } + + if ( ret ) + { + *iButtonId = aButtonId; + } + + return ret; + } + + +// ----------------------------------------------------------------------------- +// CPapUiDialog::DrawSettingsListL +// ----------------------------------------------------------------------------- +// +void CPapUiDialog::DrawSettingsListL() + { + iSettingArray->Array()->ResetAndDestroy(); + TInt ordinal = 0; + + // --------------------------------------------------------------- + // Username setting item. If the username has never been set, + // shows "(not defined)", otherwise shows the username. + iSettingArray->AddTextItemL( iSettingUsername, + EPapSettingPageUserName, + R_PAP_USERNAME_SETTING_TITLE, + R_PAP_USERNAME_PAGE, + NULL, + ordinal++ ); + + // --------------------------------------------------------------- + // Password prompt setting item. Radio buttons Prompt/User defined. + iSettingArray->AddBinarySettingItemL( R_PAP_PASSWORD_POPUP_PAGE, + R_PAP_PASSWORD_SETTING_TITLE, + R_PAP_PASSWORD_PROMPT_CHOICES, + ordinal++, + iSettingPwPrompt ); + + // --------------------------------------------------------------- + // Password setting item. Never visible in the setting list, but the + // setting page opens when the user selects "User defined" in the + // password prompt setting item. + iSettingArray->AddPasswordItemL( iSettingPassword, + EPapSettingPagePassword, + R_PAP_PASSWORD_SETTING_TITLE, + R_PAP_PASSWORD_SETTING_PAGE, + NULL, + ordinal++ ); + + // Set the last item hidden + CAknSettingItem* item = iSettingArray->Array()->At( EPasswordItem ); + item->SetHidden( ETrue ); + + + iSettingListBox->Model()->SetItemTextArray( iSettingArray->Array() ); + iSettingListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + iSettingArray->Array()->RecalculateVisibleIndicesL(); + iSettingListBox->HandleItemAdditionL(); + iSettingListBox->UpdateScrollBarsL(); + } + + +// ----------------------------------------------------------------------------- +// CPapUiDialog::DynInitMenuPaneL +// ----------------------------------------------------------------------------- +// +void CPapUiDialog::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + CAknDialog::DynInitMenuPaneL( aResourceId, aMenuPane ); + + if ( aResourceId == R_PAP_MENU_PANE ) + { + if ( aMenuPane && !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + + } + } + +// ----------------------------------------------------------------------------- +// CPapUiDialog::UpdateEapolData +// ----------------------------------------------------------------------------- +// +void CPapUiDialog::UpdateEapolData() + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CPapUiDialog::UpdateEapolData") ); + RDebug::Print(_L("Saving username: %S"), &iSettingUsername ); + RDebug::Print(_L("Saving pwprompt: %d"), iSettingPwPrompt ); + RDebug::Print(_L("Saving password: %S"), &iSettingPassword ); + #endif + + // username + if ( iSettingUsername.Length() ) + { + ( iUiData->GetPapUserName() ).Copy( iSettingUsername ); + } + + + // pwprompt + *( iUiData->GetPapPasswordPrompt() ) = iSettingPwPrompt; + + // password + ( iUiData->GetPapPassword() ).Copy( iSettingPassword ); + + iDataConnection->Update(); + } + + +// ----------------------------------------------------------------------------- +// CPapUiDialog::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CPapUiDialog::ProcessCommandL( TInt aCommand ) + { + if ( MenuShowing() ) + { + HideMenu(); + } + + switch( aCommand ) + { + case EAknCmdExit: + { + TryExitL( aCommand ); + break; + } + + case EAknCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + iEikonEnv->EikAppUi()->AppHelpContextL() ); + break; + } + + case EPapUiCmdChange: + { + if( iIsUIConstructionCompleted ) + { + ShowSettingPageL( ETrue ); + } + else + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CPapUiDialog::ProcessCommandL - UI not ready - Ignoring key press.\n") ); + #endif + } + break; + } + + default: + { + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CPapUiDialog::ShowSettingPageL +// ----------------------------------------------------------------------------- +// +void CPapUiDialog::ShowSettingPageL( TInt aCalledFromMenu ) + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CPapUiDialog::ShowSettingPageL") ); + #endif + + TInt index = iSettingListBox->CurrentItemIndex(); + + if ( index == EUsernameItem ) + { + ShowUsernameSettingPageL(); + } + + else if ( index == EPasswordPromptItem ) + { + // The previous value is needed for comparison, + // after the user has done the editing + TBool oldChoice = iSettingPwPrompt; + + // Show the radio button page and let the user edit + CAknSettingItem* item = iSettingArray->Array()->At( index ); + item->EditItemL( aCalledFromMenu ); + item->StoreL(); + + // Check the new value + TBool newChoice = iSettingPwPrompt; + + // Prompt -> User defined + if ( oldChoice && !newChoice ) + { + // Ask to set a password + ShowPasswordSettingPageL(); + + // If the password item was cancelled, + // or if username was prompted and cancelled, + // restore "Prompt" for the password prompt setting + if ( iSettingArray->IsPwItemCancelled() || iUsernameCancelled ) + { + // Toggle the setting back to Prompt without showing the page + item->EditItemL( EFalse ); + item->StoreL(); + } + } + + // User defined -> User defined + else if ( !oldChoice && !newChoice ) + { + // Ask to set a new password + ShowPasswordSettingPageL(); + } + + // Prompt -> Prompt + else if ( oldChoice && newChoice ) + { + // Do nothing + } + + // User defined -> Prompt + else if ( !oldChoice && newChoice ) + { + // Remove the password + CPapUiPwSettingItem* pwItem = + static_cast< CPapUiPwSettingItem* >( + iSettingArray->Array()->At( EPasswordItem ) ); + pwItem->DeletePasswordL(); + + } + + else + { + // It shouldn't be possible to end up here + } + + } + + else + { + // shouldn't end up here + } + + DrawNow(); + } + +// ----------------------------------------------------------------------------- +// CPapUiDialog::ShowUsernameSettingPageL +// ----------------------------------------------------------------------------- +// +void CPapUiDialog::ShowUsernameSettingPageL() + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CPapUiDialog::ShowUsernameSettingPageL") ); + #endif + + iUsernameCancelled = EFalse; + + CAknSettingItem* item = iSettingArray->Array()->At( EUsernameItem ); + item->EditItemL( EFalse ); + item->StoreL(); + } + +// ----------------------------------------------------------------------------- +// CPapUiDialog::ShowPasswordSettingPageL +// ----------------------------------------------------------------------------- +// +void CPapUiDialog::ShowPasswordSettingPageL() + { + #if defined(_DEBUG) || defined(DEBUG) + RDebug::Print(_L("CPapUiDialog::ShowPasswordSettingPageL") ); + #endif + + CAknSettingItem* item = iSettingArray->Array()->At( EPasswordItem ); + + item->EditItemL( EFalse ); + item->StoreL(); + DrawNow(); + + // If password is set, then username must also be defined + if ( !iSettingUsername.Length() && !iSettingArray->IsPwItemCancelled() ) + { + // Show an info note about missing username + HBufC* message = NULL; + message = StringLoader::LoadLC( R_PAP_DEFINE_USERNAME_INFO_NOTE ); + CAknInformationNote* note = new( ELeave ) CAknInformationNote( ETrue ); + note->ExecuteLD( *message ); + CleanupStack::PopAndDestroy( message ); + + ShowUsernameSettingPageL(); + + // If the username is still empty, it can only mean that the user has + // cancelled the operation -> remove the temporarily accepted password + if ( !iSettingUsername.Length() ) + { + iUsernameCancelled = ETrue; + // Remove the password + CPapUiPwSettingItem* pwItem = + static_cast< CPapUiPwSettingItem* >( + iSettingArray->Array()->At( EPasswordItem ) ); + pwItem->DeletePasswordL(); + } + } + + } + +// ----------------------------------------------------------------------------- +// CPapUiDialog::GetHelpContext +// ----------------------------------------------------------------------------- +// +void CPapUiDialog::GetHelpContext( TCoeHelpContext& aContext ) const + { + aContext.iMajor = KHelpUidPlugin; + aContext.iContext = KSET_HLP_WLAN_EAP_PAP; + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/notifierui/data/papnotifdlgui.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/notifierui/data/papnotifdlgui.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,152 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Resource file of PapNotifDlg +* +*/ + + + +// RESOURCE IDENTIFIER +NAME PAPN + + +// INCLUDES +#include +#include +#include +#include +#include +#include + +#include +#include "papnotifui.hrh" + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + +RESOURCE DIALOG r_papnotif_username_password_query + { + flags = EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar | + EEikDialogFlagCbaButtons|EEikDialogFlagNotifyEsc; + buttons = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + items = + { + DLG_LINE + { + type = EAknCtMultilineQuery; + id = EMultilineFirstLine; + control = AVERELL_DATA_QUERY + { + layout = EMultiDataFirstEdwin; + label = qtn_wlan_eap_pap_notif_username; + control = EDWIN + { + flags = 0; + width = 5; + lines = 1; + maxlength = KPapUsernameMaxLength; + default_case = EAknEditorLowerCase; + allowed_case_modes = EAknEditorAllCaseModes; + allowed_input_modes = EAknEditorAlphaInputMode | + EAknEditorNumericInputMode | + EAknEditorPredictiveInputMode; + default_input_mode = EAknEditorPredictiveInputMode; + }; + }; + }, + + DLG_LINE + { + type = EAknCtMultilineQuery; + id = EMultilineSecondLine; + control = AVERELL_DATA_QUERY + { + layout = EMultiDataSecondSecEd; + label = qtn_wlan_eap_pap_notif_password; + control = SECRETED + { + num_letters = KPapPasswordMaxLength; + }; + }; + } + }; + } + +RESOURCE CBA r_papnotif_softkeys_ok___select + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOk; txt = text_softkey_ok; }, + CBA_BUTTON { }, + CBA_BUTTON { id = EAknSoftkeyOk; txt = qtn_msk_select; } + }; + } + + +RESOURCE DIALOG r_pap_challenge_message_query + { + flags = EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar | + EEikDialogFlagCbaButtons | EEikDialogFlagNotifyEsc; + buttons = r_papnotif_softkeys_ok___select; + items = + { + DLG_LINE + { + type = EAknCtPopupHeadingPane; + id = EAknMessageQueryHeaderId; + control = AVKON_HEADING + { + label = qtn_wlan_eap_pap_notif_message; + }; + }, + + DLG_LINE + { + type = EAknCtMessageQuery; + id = EAknMessageQueryContentId; + control = AVKON_MESSAGE_QUERY + { + }; + } + }; + } + +RESOURCE DIALOG r_pap_challenge_reply_query + { + flags = EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar | + EEikDialogFlagCbaButtons | EEikDialogFlagNotifyEsc; + buttons = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + items = + { + DLG_LINE + { + type = EAknCtQuery; + id = EGeneralQuery; + control= AVKON_DATA_QUERY + { + layout = ECodeLayout; + label = qtn_wlan_eap_pap_notif_response; + control = SECRETED + { + num_letters = KPapPasswordMaxLength; + }; + }; + } + }; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/notifierui/inc/papauthdialog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/notifierui/inc/papauthdialog.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of authentication query dialog class of PapNotifDialog. +* +*/ + + + +#ifndef __PAPAUTHDIALOG_H__ +#define __PAPAUTHDIALOG_H__ + +// INCLUDES +#include +#include +#include +#include +#include +#include "papnotifdlgplugin.h" + + +// CLASS DECLARATION + +/** +*/ +class CPapAuthDialog : public CAknMultiLineDataQueryDialog + { + protected: + CPapAuthDialog( CPapNotifDialogPlugin* aPlugin ); + void ConstructL(); + + public: + static CPapAuthDialog* NewL( TDes& aUsername, TDes& aPassword, + CPapNotifDialogPlugin* aPlugin ); + ~CPapAuthDialog(); + + private: + virtual TBool OkToExitL( TInt aButtonId ); + void HandleResourceChange( TInt aType ); + + private: + CPapNotifDialogPlugin* iPlugin; // Pointer to the notifier plugin + + }; + +#endif // __PAPAUTHDIALOG_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/notifierui/inc/papchallengemsgdialog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/notifierui/inc/papchallengemsgdialog.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of PAP Challenge Message Display Dialog +* +*/ + + + +#ifndef __PAPCHALLENGEMSGDIALOG_H__ +#define __PAPCHALLENGEMSGDIALOG_H__ + +// INCLUDES +#include + + +class CPapChallengeMsgDialog : public CAknMessageQueryDialog + { + public: + static CPapChallengeMsgDialog* NewL( const TDesC& aMessage, + CPapNotifDialogPlugin* aPlugin ); + ~CPapChallengeMsgDialog(); + + private: + CPapChallengeMsgDialog( CPapNotifDialogPlugin* aPlugin ); + + virtual TBool OkToExitL( TInt aButtonId ); + void HandleResourceChange( TInt aType ); + + private: + CPapNotifDialogPlugin* iPlugin; // Pointer to the notifier plugin + }; + +#endif // __PAPCHALLENGEMSGDIALOG_H__ diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/notifierui/inc/papchallengereplydialog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/notifierui/inc/papchallengereplydialog.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of PAP Challenge Reply Dialog +* +*/ + + + +#ifndef __PAPCHALLENGEREPLYDIALOG_H__ +#define __PAPCHALLENGEREPLYDIALOG_H__ + +// INCLUDES +#include + + +class CPapChallengeReplyDialog : public CAknTextQueryDialog + { + public: + static CPapChallengeReplyDialog* NewL( TDes& aResponse, + CPapNotifDialogPlugin* aPlugin ); + ~CPapChallengeReplyDialog(); + + private: + CPapChallengeReplyDialog( TDes& aResponse, + CPapNotifDialogPlugin* aPlugin ); + + virtual TBool OkToExitL( TInt aButtonId ); + void HandleResourceChange( TInt aType ); + + private: + CPapNotifDialogPlugin* iPlugin; // Pointer to the notifier plugin + }; + + +#endif // __PAPCHALLENGEREPLYDIALOG_H__ + +// End of File \ No newline at end of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/notifierui/inc/papnotifdlgplugin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/notifierui/inc/papnotifdlgplugin.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of PAP Notif Dialog Plugin +* +*/ + + + +#ifndef __PAPNOTIFDLGPLUGIN_H__ +#define __PAPNOTIFDLGPLUGIN_H__ + + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// CONSTANTS + +// UIDs for dialogs + +// ID of PAP username & password dialog +const TUid KUidPapDialog = { 0x200159A9 }; + +// Channel used for screen +const TUid KScreenOutputChannel = { 0x00000123 }; + +// Number of dialogs in this plugin +const TInt KPluginGranularity = 1; + +// ROM folder +_LIT( KDriveZ, "z:" ); + +// RSC file name. +_LIT( KResourceFileName, "papnotifdlgui.rsc" ); + + +// GLOBAL FUNCTIONS + +/** +* Array of connection dialog plugins. +* @return A CArray of MEikSrvNotifierBase2 based classes. +*/ +IMPORT_C CArrayPtr< MEikSrvNotifierBase2 >* NotifierArray(); + + +// CLASS DECLARATION + +class CPapAuthDialog; +class CPapChallengeMsgDialog; +class CPapChallengeReplyDialog; + +/** + * PAP notifier dialog plugin class + */ +class CPapNotifDialogPlugin : public CBase, + public MEikSrvNotifierBase2 + { + public: + static CPapNotifDialogPlugin* NewL(); + + ~CPapNotifDialogPlugin(); + + TNotifierInfo RegisterL(); + TNotifierInfo Info() const; + + TPtrC8 StartL( const TDesC8& aBuffer ); + void StartL( const TDesC8& aBuffer, TInt aReplySlot, + const RMessagePtr2& aMessage ); + + TPtrC8 UpdateL( const TDesC8& aBuffer ); + void Cancel(); + void CompleteL( TInt aStatus ); + void Release(); + + public: // new + + TDes& Username(); + TDes& Password(); + + void SetAuthDlgDismissed(); + void SetChallengeMsgDismissed(); + void SetChallengeReplyDismissed(); + + protected: + CPapNotifDialogPlugin(); + + void ConstructL(); + + protected: + TNotifierInfo iInfo; // Notifier info + RMessagePtr2 iMessage; // Message + TInt iReplySlot; // Reply slot + TBool iCancelled; // ETrue if dialog cancelled + + private: + + TInt iResource; // Resource + + TPapUiNotifierInfo* iDataPtr; + TPckg* iDataPckgPtr; + + CPapAuthDialog* iPapAuthDialog; + CPapChallengeMsgDialog* iPapChallengeMsgDialog; + CPapChallengeReplyDialog*iPapChallengeReplyDialog; + + TUint iChallengeSize; + + TBool iAuthDlgDismissed; + TBool iChallengeMsgDismissed; + TBool iChallengeReplyDismissed; + + }; + + +#endif // __PAPNOTIFDLGPLUGIN_H__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/notifierui/inc/papnotifui.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/notifierui/inc/papnotifui.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: PAP Notifier UI hrh file +* +*/ + + +#ifndef _PAPNOTIFUI_HRH_ +#define _PAPNOTIFUI_HRH_ + +#define KPapUsernameMaxLength 253 +#define KPapPasswordMaxLength 128 + + + +#endif //_PAPNOTIFUI_HRH_ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/notifierui/loc/papnotifdlg.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/notifierui/loc/papnotifdlg.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: UI strings for WLAN PAP Notifier +* +*/ + + + +// LOCALISATION STRINGS + + +//d:Username query string. +//l:popup_query_data_code_window_t4/opt2 +//w: +//r:5.0.1 +// +#define qtn_wlan_eap_pap_notif_username "PAP user name:" + + +//d:Password query string. +//l:popup_query_data_code_window_t4/opt2 +//w: +//r:5.0.1 +// +#define qtn_wlan_eap_pap_notif_password "Password:" + +//d:Message query string for PAP challenge/response. +//l:heading_pane_t1 +//w: +//r:5.0.1 +// +#define qtn_wlan_eap_pap_notif_message "PAP challenge:" + +//d:User reply query string for PAP challenge/response. +//l:popup_query_data_window_t3/opt2 +//w: +//r:5.0.1 +// +#define qtn_wlan_eap_pap_notif_response "PAP reply:" + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/notifierui/src/papauthdialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/notifierui/src/papauthdialog.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,134 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 authentication query dialog class of Pap Notifier +* +*/ + + + +// INCLUDE FILES +#include +#include "papnotifdlgplugin.h" +#include "papauthdialog.h" + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPapAuthDialog::CPapAuthDialog +// ----------------------------------------------------------------------------- +// +CPapAuthDialog::CPapAuthDialog( CPapNotifDialogPlugin* aPlugin ) + : CAknMultiLineDataQueryDialog( ENoTone ), + iPlugin( aPlugin ) + { + } + + +// ----------------------------------------------------------------------------- +// CPapAuthDialog::NewL +// ----------------------------------------------------------------------------- +// +CPapAuthDialog* CPapAuthDialog::NewL( TDes& aUsername, TDes& aPassword, + CPapNotifDialogPlugin* aPlugin ) + { + CPapAuthDialog* self = new( ELeave ) CPapAuthDialog( aPlugin ); + CleanupStack::PushL( self ); + if ( aUsername.Length() ) + { + self->SetDataL( aUsername, aPassword ); + } + + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CPapAuthDialog::ConstructL +// ----------------------------------------------------------------------------- +// +void CPapAuthDialog::ConstructL() + { + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapAuthDialog::ConstructL") ); + #endif + } + + +// ----------------------------------------------------------------------------- +// CPapAuthDialog::~CPapAuthDialog +// ----------------------------------------------------------------------------- +// +CPapAuthDialog::~CPapAuthDialog() + { + } + + +// ----------------------------------------------------------------------------- +// CPapAuthDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CPapAuthDialog::OkToExitL( TInt aButtonId ) + { + if ( CAknMultiLineDataQueryDialog::OkToExitL( aButtonId ) ) + { + if ( aButtonId == EAknSoftkeyOk ) + { + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapAuthDialog::OkToExitL, softkey OK") ); + #endif + + // save the user entries to be sent back to eapol + CAknMultilineQueryControl* firstControl = FirstControl(); + firstControl->GetText( iPlugin->Username() ); + + CAknMultilineQueryControl* secondControl = SecondControl(); + secondControl->GetText( iPlugin->Password() ); + + iPlugin->SetAuthDlgDismissed(); + iPlugin->CompleteL( KErrNone ); + return( ETrue ); + } + else + { + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapAuthDialog::OkToExitL, softkey Cancel") ); + #endif + + iPlugin->SetAuthDlgDismissed(); + iPlugin->CompleteL( KErrCancel ); + return( ETrue ); + } + } + + return( EFalse ); + } + + +// ----------------------------------------------------------------------------- +// CPapAuthDialog::HandleResourceChange +// ----------------------------------------------------------------------------- +// +void CPapAuthDialog::HandleResourceChange( TInt aType ) + { + CAknMultiLineDataQueryDialog::HandleResourceChange( aType ); + + if ( aType == KAknsMessageSkinChange ) + { + } + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/notifierui/src/papchallengemsgdialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/notifierui/src/papchallengemsgdialog.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,110 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 PAP Challenge Message Display Dialog +* +*/ + + +// INCLUDE FILES +#include "papnotifdlgplugin.h" +#include "papchallengemsgdialog.h" + + +// ----------------------------------------------------------------------------- +// CPapChallengeMsgDialog::CPapChallengeMsgDialog +// ----------------------------------------------------------------------------- +// +CPapChallengeMsgDialog::CPapChallengeMsgDialog( CPapNotifDialogPlugin* aPlugin ) +: CAknMessageQueryDialog( ENoTone ), + iPlugin( aPlugin ) + { + } + + +// ----------------------------------------------------------------------------- +// CPapChallengeMsgDialog::~CPapChallengeMsgDialog +// ----------------------------------------------------------------------------- +// +CPapChallengeMsgDialog::~CPapChallengeMsgDialog() + { + } + + +// ----------------------------------------------------------------------------- +// CPapChallengeMsgDialog::NewL +// ----------------------------------------------------------------------------- +// +CPapChallengeMsgDialog* CPapChallengeMsgDialog::NewL( const TDesC& aMessage, + CPapNotifDialogPlugin* aPlugin ) + { + CPapChallengeMsgDialog* self = new( ELeave ) CPapChallengeMsgDialog( aPlugin ); + + CleanupStack::PushL( self ); + if ( aMessage.Length() ) + { + self->SetMessageTextL( aMessage ); + } + + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CPapChallengeMsgDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CPapChallengeMsgDialog::OkToExitL( TInt aButtonId ) + { + if ( CAknMessageQueryDialog::OkToExitL( aButtonId ) ) + { + if ( aButtonId == EAknSoftkeyOk ) + { + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapChallengeMsgDialog::OkToExitL, softkey OK") ); + #endif + iPlugin->SetChallengeMsgDismissed(); + iPlugin->CompleteL( KErrNone ); + } + else + { + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapChallengeMsgDialog::OkToExitL, softkey Cancel") ); + #endif + // Some cancel. + iPlugin->SetChallengeMsgDismissed(); + iPlugin->CompleteL( KErrCancel ); + } + + return( ETrue ); + } + + return( EFalse ); + } + + +// ----------------------------------------------------------------------------- +// CPapChallengeMsgDialog::HandleResourceChange +// ----------------------------------------------------------------------------- +// +void CPapChallengeMsgDialog::HandleResourceChange( TInt aType ) + { + CAknMessageQueryDialog::HandleResourceChange( aType ); + if ( aType == KAknsMessageSkinChange ) + { + } + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/notifierui/src/papchallengereplydialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/notifierui/src/papchallengereplydialog.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,99 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 PAP Challenge Reply Dialog +* +*/ + + + +// INCLUDE FILES +#include "papnotifdlgplugin.h" +#include "papchallengereplydialog.h" + + +// ----------------------------------------------------------------------------- +// CPapChallengeReplyDialog::CPapChallengeReplyDialog +// ----------------------------------------------------------------------------- +// +CPapChallengeReplyDialog::CPapChallengeReplyDialog( TDes& aResponse, + CPapNotifDialogPlugin* aPlugin ) +: CAknTextQueryDialog( aResponse ), + iPlugin( aPlugin ) + { + } + + +// ----------------------------------------------------------------------------- +// CPapChallengeReplyDialog::~CPapChallengeReplyDialog +// ----------------------------------------------------------------------------- +// +CPapChallengeReplyDialog::~CPapChallengeReplyDialog() + { + } + + +// ----------------------------------------------------------------------------- +// CPapChallengeReplyDialog::NewL +// ----------------------------------------------------------------------------- +// +CPapChallengeReplyDialog* CPapChallengeReplyDialog::NewL( TDes& aResponse, + CPapNotifDialogPlugin* aPlugin ) + { + CPapChallengeReplyDialog* self = new( ELeave ) CPapChallengeReplyDialog( + aResponse, aPlugin ); + return self; +} + + +// ----------------------------------------------------------------------------- +// CPapChallengeReplyDialog::OkToExitL +// ----------------------------------------------------------------------------- +// +TBool CPapChallengeReplyDialog::OkToExitL( TInt aButtonId ) + { + if ( CAknTextQueryDialog::OkToExitL( aButtonId ) ) + { + if ( aButtonId==EAknSoftkeyOk ) + { + iPlugin->SetChallengeReplyDismissed(); + iPlugin->CompleteL( KErrNone ); + } + else + { + // Everything else is for cancel. + iPlugin->SetChallengeReplyDismissed(); + iPlugin->CompleteL( KErrCancel ); + } + + return( ETrue ); + } + + return( EFalse ); + } + + +// ----------------------------------------------------------------------------- +// CPapChallengeReplyDialog::HandleResourceChange +// ----------------------------------------------------------------------------- +// +void CPapChallengeReplyDialog::HandleResourceChange( TInt aType ) + { + CAknTextQueryDialog::HandleResourceChange( aType ); + if ( aType == KAknsMessageSkinChange ) + { + } + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/pap/notifierui/src/papnotifdlgplugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/pap/notifierui/src/papnotifdlgplugin.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,487 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 PapNotifDlg dialog plugin. +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include + +#include // For RProperty +#include // For KPSUidUikon and KUikGlobalNotesAllowed. + +#include +#include "papnotifdlgplugin.h" +#include "papauthdialog.h" +#include "papchallengemsgdialog.h" +#include "papchallengereplydialog.h" + +// CONSTANTS +//static const TUint KUtf8UnicodeRatio = 2; + +// ================= OTHER EXPORTED FUNCTIONS ============== + +// ----------------------------------------------------------------------------- +// CreateNotifiersL +// ----------------------------------------------------------------------------- +// +LOCAL_C void CreateNotifiersL( CArrayPtrFlat< MEikSrvNotifierBase2 >* aNotifiers ) + { + MEikSrvNotifierBase2 *serNotify; + serNotify = CPapNotifDialogPlugin::NewL(); + CleanupStack::PushL( serNotify ); + aNotifiers->AppendL( serNotify ); + CleanupStack::Pop( serNotify ); + } + + +// ----------------------------------------------------------------------------- +// NotifierArray +// ----------------------------------------------------------------------------- +// +EXPORT_C CArrayPtr< MEikSrvNotifierBase2 >* NotifierArray() + { + // NotifierArray() can't leave + CArrayPtrFlat< MEikSrvNotifierBase2 >* array = + new CArrayPtrFlat< MEikSrvNotifierBase2 >( KPluginGranularity ); + + if ( array ) + { + TRAPD( err, CreateNotifiersL( array ) ); + + if( err ) + { + TInt count = array->Count(); + + while( count-- ) + { + ( *array )[ count ]->Release(); + } + + delete array; + array = NULL; + } + } + + return( array ); + } + + +////////////////////////////////////////////////////////////// +// PAP dialog plugin +///////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::CPapNotifDialogPlugin +// ----------------------------------------------------------------------------- +// +CPapNotifDialogPlugin::CPapNotifDialogPlugin() +: iCancelled( EFalse ), + iAuthDlgDismissed( EFalse ), + iChallengeMsgDismissed( EFalse ), + iChallengeReplyDismissed( EFalse ) + { + iManager = NULL; + } + + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::~CPapNotifDialogPlugin +// ----------------------------------------------------------------------------- +// +CPapNotifDialogPlugin::~CPapNotifDialogPlugin() + { + CCoeEnv::Static()->DeleteResourceFile( iResource ); + + if ( !iAuthDlgDismissed ) + { + delete iPapAuthDialog; + } + + if ( !iChallengeMsgDismissed ) + { + delete iPapChallengeMsgDialog; + } + + if ( !iChallengeReplyDismissed ) + { + delete iPapChallengeReplyDialog; + } + + } + + + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::RegisterL +// ----------------------------------------------------------------------------- +// +CPapNotifDialogPlugin::TNotifierInfo CPapNotifDialogPlugin::RegisterL() + { + iInfo.iUid = KUidPapDialog; + iInfo.iPriority = ENotifierPriorityHigh; + iInfo.iChannel = KUidPapDialog; + return iInfo; + } + + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::NewL +// ----------------------------------------------------------------------------- +// +CPapNotifDialogPlugin* CPapNotifDialogPlugin::NewL() + { + CPapNotifDialogPlugin* self = new( ELeave ) CPapNotifDialogPlugin(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::ConstructL +// ----------------------------------------------------------------------------- +// +void CPapNotifDialogPlugin::ConstructL() + { + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapNotifDialogPlugin::ConstructL") ); + #endif + + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + BaflUtils::NearestLanguageFile( CCoeEnv::Static()->FsSession(), fileName ); + iResource = CCoeEnv::Static()->AddResourceFileL( fileName ); + } + + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::StartL +// ----------------------------------------------------------------------------- +// +TPtrC8 CPapNotifDialogPlugin::StartL( const TDesC8& /*aBuffer*/ ) + { + return KNullDesC8().Ptr(); + } + + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::StartL +// ----------------------------------------------------------------------------- +// +void CPapNotifDialogPlugin::StartL( const TDesC8& aBuffer, + TInt aReplySlot, + const RMessagePtr2& aMessage ) + { + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapNotifDialogPlugin::StartL") ); + #endif + + iCancelled = EFalse; + iReplySlot = aReplySlot; + iMessage = aMessage; + + // This object gets constructed only once but + // can get called many times. + // So initialize everything here. + iAuthDlgDismissed = EFalse; + iChallengeMsgDismissed = EFalse; + iChallengeReplyDismissed = EFalse; + iPapAuthDialog = NULL; + iPapChallengeMsgDialog = NULL; + iPapChallengeReplyDialog = NULL; + iDataPtr = NULL; + iDataPckgPtr = NULL; + + // We are about to display the password prompt. + // Since this part of the code can be executed during the bootup, check if + // the UI has really started up to display notes/dialogs. + TInt notesAllowed = 0; + TInt error = RProperty::Get( KPSUidUikon, KUikGlobalNotesAllowed, + notesAllowed ); + + // The above call can return error. Ignore the error. What we care is + // if notesAllowed has turned to 1 from 0. + if ( notesAllowed ) + { + iDataPtr = new( ELeave ) TPapUiNotifierInfo; + iDataPckgPtr = new( ELeave ) TPckg( *iDataPtr ); + iDataPckgPtr->Copy( aBuffer ); + + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapNotifDialogPlugin::StartL, state = %d"), iDataPtr->iState ); + #endif + + switch ( iDataPtr->iState ) + { + case TPapUiNotifierInfo::EPapUiNotifierAuthQueryDialog: + { + iPapAuthDialog = CPapAuthDialog::NewL( + iDataPtr->iUsrPwdInfo.iUserName, + iDataPtr->iUsrPwdInfo.iPassword, + this ); + + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapNotifDialogPlugin::StartL, executing auth dialog") ); + #endif + + iPapAuthDialog->ExecuteLD( R_PAPNOTIF_USERNAME_PASSWORD_QUERY ); + + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapNotifDialogPlugin::StartL, auth dialog executed") ); + #endif + + break; + } + + case TPapUiNotifierInfo::EPapUiNotifierPapChallengeSize: + { + iChallengeSize = iDataPtr->iSrvChallengeSize; + break; + } + + case TPapUiNotifierInfo::EPapUiNotifierPapChallengeMsgDialog: + { + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapNotifDialogPlugin::StartL, chal msg dialog start") ); + #endif + + HBufC16* challengetext = HBufC16::NewLC( KMaxPapChallengeLength ); + TPtr16 text = challengetext->Des(); + text.Copy( iDataPtr->iPapChallenge ); + + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapNotifDialogPlugin::StartL, create chal msg dialog") ); + #endif + + iPapChallengeMsgDialog = CPapChallengeMsgDialog::NewL( text, + this ); + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapNotifDialogPlugin::StartL, executing chal msg dialog") ); + #endif + + iPapChallengeMsgDialog->ExecuteLD( R_PAP_CHALLENGE_MESSAGE_QUERY ); + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapNotifDialogPlugin::StartL, chal msg dialog executed") ); + #endif + + CleanupStack::PopAndDestroy( challengetext ); + + break; + } + + case TPapUiNotifierInfo::EPapUiNotifierPapChallengeReplyQueryDialog: + { + // construct and show the challenge reply dialog, + // save the reply in the password field + iPapChallengeReplyDialog = CPapChallengeReplyDialog::NewL( + iDataPtr->iUsrPwdInfo.iPassword, this ); + iPapChallengeReplyDialog->ExecuteLD( R_PAP_CHALLENGE_REPLY_QUERY); + + break; + } + + default: + { + break; + } + + } + + } + + // In case if the notes are not allowed, this message gets completed when + // EAPOL time out occurs and a subsequent call to cancel + } + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::UpdateL +// ----------------------------------------------------------------------------- +// +TPtrC8 CPapNotifDialogPlugin::UpdateL( const TDesC8& /*aBuffer*/ ) + { + return KNullDesC8().Ptr(); + } + + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::Cancel +// ----------------------------------------------------------------------------- +// +void CPapNotifDialogPlugin::Cancel() + { + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapNotifDialogPlugin::Cancel") ); + #endif + + if ( !iCancelled ) + { + iCancelled = ETrue; + + if ( !iMessage.IsNull() ) + { + iMessage.Complete( KErrCancel ); + } + + if ( !iAuthDlgDismissed && iPapAuthDialog ) + { + iAuthDlgDismissed = ETrue; + delete iPapAuthDialog; + iPapAuthDialog = NULL; + } + + if ( !iChallengeMsgDismissed && iPapChallengeMsgDialog ) + { + iChallengeMsgDismissed = ETrue; + delete iPapChallengeMsgDialog; + iPapChallengeMsgDialog = NULL; + } + + if ( !iChallengeReplyDismissed && iPapChallengeReplyDialog ) + { + iChallengeReplyDismissed = ETrue; + delete iPapChallengeReplyDialog; + iPapChallengeReplyDialog = NULL; + } + + } + + if ( iDataPtr ) + { + delete iDataPtr; + iDataPtr = NULL; + } + + if ( iDataPckgPtr ) + { + delete iDataPckgPtr; + iDataPckgPtr = NULL; + } + } + + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::CompleteL +// ----------------------------------------------------------------------------- +// +void CPapNotifDialogPlugin::CompleteL( TInt aStatus ) + { + #if defined( _DEBUG ) || defined( DEBUG ) + RDebug::Print(_L("CPapNotifDialogPlugin::CompleteL") ); + #endif + + if ( aStatus == KErrNone && !iMessage.IsNull() ) + { + iMessage.WriteL( iReplySlot, *iDataPckgPtr ); + } + + iCancelled = ETrue; + + if ( !iMessage.IsNull() ) + { + iMessage.Complete( aStatus ); + } + + if ( iDataPtr ) + { + delete iDataPtr; + iDataPtr = NULL; + } + + if ( iDataPckgPtr ) + { + delete iDataPckgPtr; + iDataPckgPtr = NULL; + } + } + + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::Release +// ----------------------------------------------------------------------------- +// +void CPapNotifDialogPlugin::Release() + { + delete this; + } + + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::Info +// ----------------------------------------------------------------------------- +// +CPapNotifDialogPlugin::TNotifierInfo CPapNotifDialogPlugin::Info() const + { + return iInfo; + } + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::Username +// ----------------------------------------------------------------------------- +// +TDes& CPapNotifDialogPlugin::Username() + { + return ( iDataPtr->iUsrPwdInfo.iUserName ) ; + } + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::Password +// ----------------------------------------------------------------------------- +// +TDes& CPapNotifDialogPlugin::Password() + { + return ( iDataPtr->iUsrPwdInfo.iPassword ) ; + } + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::SetAuthDlgDismissed +// ----------------------------------------------------------------------------- +// +void CPapNotifDialogPlugin::SetAuthDlgDismissed() + { + iAuthDlgDismissed = ETrue; + } + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::SetChallengeMsgDismissed +// ----------------------------------------------------------------------------- +// +void CPapNotifDialogPlugin::SetChallengeMsgDismissed() + { + iChallengeMsgDismissed = ETrue; + } + +// ----------------------------------------------------------------------------- +// CPapNotifDialogPlugin::SetChallengeReplyDismissed +// ----------------------------------------------------------------------------- +// +void CPapNotifDialogPlugin::SetChallengeReplyDismissed() + { + iChallengeReplyDismissed = ETrue; + } + + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/rom/WlanEapSettingsUi.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/rom/WlanEapSettingsUi.iby Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Image description file for project WLAN EAP Settings UI +* +*/ + + + +#ifndef __WLANEAPSETTINGSUI_IBY__ +#define __WLANEAPSETTINGSUI_IBY__ + +#include + +#ifdef __PROTOCOL_WLAN + +ECOM_PLUGIN( eapnotifwrapper.dll,2000cf2e.rsc ) + +#ifdef FF_WLAN_EXTENSIONS +file=ABI_DIR\BUILD_DIR\leapnotifdlg.dll SHARED_LIB_DIR\leapnotifdlg.dll +ECOM_PLUGIN( eapfastnotifdlg.dll,200100a5.rsc ) +#endif // FF_WLAN_EXTENSIONS + +file=ABI_DIR\BUILD_DIR\mschapv2notifdlg.dll SHARED_LIB_DIR\mschapv2notifdlg.dll +file=ABI_DIR\BUILD_DIR\gtcnotifdlg.dll SHARED_LIB_DIR\gtcnotifdlg.dll + +file=ABI_DIR\BUILD_DIR\papnotifdlg.dll SHARED_LIB_DIR\papnotifdlg.dll + +ECOM_PLUGIN( EapPluginConfig.dll,102072bb.rsc ) + +#endif // __PROTOCOL_WLAN + +#endif // __WLANEAPSETTINGSUI_IBY__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wlaneapsettingsui/rom/WlanEapSettingsUiResources.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wlaneapsettingsui/rom/WlanEapSettingsUiResources.iby Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Image description file for project WlanEapSettingsUi +* +*/ + + + +#ifndef __WLANEAPSETTINGSUIRESOURCES_IBY__ +#define __WLANEAPSETTINGSUIRESOURCES_IBY__ + +#include + +#ifdef __PROTOCOL_WLAN + +DATA=DATAZ_\RESOURCE_FILES_DIR\EapSimUi.rsc RESOURCE_FILES_DIR\EapSimUi.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\EapAkaUi.rsc RESOURCE_FILES_DIR\EapAkaUi.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\EapMschapv2Ui.rsc RESOURCE_FILES_DIR\EapMschapv2Ui.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\EapTlsUi.rsc RESOURCE_FILES_DIR\EapTlsUi.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\EapPeapUi.rsc RESOURCE_FILES_DIR\EapPeapUi.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\EapTtlsUi.rsc RESOURCE_FILES_DIR\EapTtlsUi.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\EapGtcUi.rsc RESOURCE_FILES_DIR\EapGtcUi.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\papui.rsc RESOURCE_FILES_DIR\papui.rsc + +#ifdef FF_WLAN_EXTENSIONS +DATA=DATAZ_\RESOURCE_FILES_DIR\EapLeapUi.rsc RESOURCE_FILES_DIR\EapLeapUi.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\LeapNotifDlgUi.rsc RESOURCE_FILES_DIR\LeapNotifDlgUi.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\eapfastui.rsc RESOURCE_FILES_DIR\eapfastui.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\eapfastnotifdlgui.rsc RESOURCE_FILES_DIR\eapfastnotifdlgui.rsc +#endif // FF_WLAN_EXTENSIONS + +DATA=DATAZ_\RESOURCE_FILES_DIR\MsChapv2NotifDlgUi.rsc RESOURCE_FILES_DIR\MsChapv2NotifDlgUi.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\GtcNotifDlgUi.rsc RESOURCE_FILES_DIR\GtcNotifDlgUi.rsc +DATA=DATAZ_\RESOURCE_FILES_DIR\papnotifdlgui.rsc RESOURCE_FILES_DIR\papnotifdlgui.rsc + +// For the EAPPluginConfig module +DATA=DATAZ_\RESOURCE_FILES_DIR\EapPluginConfigRes.rsc RESOURCE_FILES_DIR\EapPluginConfigRes.rsc + +#endif // __PROTOCOL_WLAN + +#endif // __WLANEAPSETTINGSUIRESOURCES_IBY__ + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/Rom/WPASecuritySettingsUI.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/Rom/WPASecuritySettingsUI.iby Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Image description file for project WPASecuritySettingsUI +* +*/ + + + +#ifndef __WPASECURITYSETTINGSUI_IBY__ +#define __WPASECURITYSETTINGSUI_IBY__ + + +FILE=ABI_DIR\BUILD_DIR\WPASecuritySettingsUI.dll SHARED_LIB_DIR\WPASecuritySettingsUI.dll + + +#endif diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/Rom/WPASecuritySettingsUIResources.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/Rom/WPASecuritySettingsUIResources.iby Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Image description file for project WPASecuritySettingsUI +* +*/ + + + +#ifndef __WPASECURITYSETTINGSUIRESOURCES_IBY__ +#define __WPASECURITYSETTINGSUIRESOURCES_IBY__ + + +DATA=DATAZ_\RESOURCE_FILES_DIR\WPASecuritySettingsUI.rsc RESOURCE_FILES_DIR\WPASecuritySettingsUI.rsc + + +#endif \ No newline at end of file diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/bwinscw/WPASecuritySettingsUI_EKA2_ALRu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/bwinscw/WPASecuritySettingsUI_EKA2_ALRu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,17 @@ +EXPORTS + ??1CWPASecuritySettings@@UAE@XZ @ 1 NONAME ; CWPASecuritySettings::~CWPASecuritySettings(void) + ??1CWPASecuritySettingsUi@@UAE@XZ @ 2 NONAME ; CWPASecuritySettingsUi::~CWPASecuritySettingsUi(void) + ?Cvt@CWPASecuritySettingsUi@@SAHXZ @ 3 NONAME ; int CWPASecuritySettingsUi::Cvt(void) + ?DeleteL@CWPASecuritySettings@@QBEXK@Z @ 4 NONAME ; void CWPASecuritySettings::DeleteL(unsigned long) const + ?EditL@CWPASecuritySettings@@QAEHAAVCWPASecuritySettingsUi@@ABVTDesC16@@@Z @ 5 NONAME ; int CWPASecuritySettings::EditL(class CWPASecuritySettingsUi &, class TDesC16 const &) + ?IsValid@CWPASecuritySettings@@QBEHXZ @ 6 NONAME ; int CWPASecuritySettings::IsValid(void) const + ?LoadL@CWPASecuritySettings@@QAEXKAAVCCommsDatabase@@@Z @ 7 NONAME ; void CWPASecuritySettings::LoadL(unsigned long, class CCommsDatabase &) + ?NewL@CWPASecuritySettings@@SAPAV1@W4TSecurityMode@@@Z @ 8 NONAME ; class CWPASecuritySettings * CWPASecuritySettings::NewL(enum TSecurityMode) + ?NewL@CWPASecuritySettingsUi@@SAPAV1@AAVCEikonEnv@@@Z @ 9 NONAME ; class CWPASecuritySettingsUi * CWPASecuritySettingsUi::NewL(class CEikonEnv &) + ?SaveL@CWPASecuritySettings@@QBEXKAAVCCommsDatabase@@W4TTypeOfSaving@@K@Z @ 10 NONAME ; void CWPASecuritySettings::SaveL(unsigned long, class CCommsDatabase &, enum TTypeOfSaving, unsigned long) const + ?SetWPAPreSharedKey@CWPASecuritySettings@@QAEHABVTDesC16@@@Z @ 11 NONAME ; int CWPASecuritySettings::SetWPAPreSharedKey(class TDesC16 const &) + ?LoadL@CWPASecuritySettings@@QAEXKAAVCMDBSession@CommsDat@@@Z @ 12 NONAME ; void CWPASecuritySettings::LoadL(unsigned long, class CommsDat::CMDBSession &) + ?SaveL@CWPASecuritySettings@@QBEXKAAVCMDBSession@CommsDat@@W4TTypeOfSaving@@K@Z @ 13 NONAME ; void CWPASecuritySettings::SaveL(unsigned long, class CommsDat::CMDBSession &, enum TTypeOfSaving, unsigned long) const + ?SetWPADisabledEAPPlugin@CWPASecuritySettings@@QAEHABVTDesC8@@@Z @ 14 NONAME ; int CWPASecuritySettings::SetWPADisabledEAPPlugin(class TDesC8 const &) + ?SetWPAEnabledEAPPlugin@CWPASecuritySettings@@QAEHABVTDesC8@@@Z @ 15 NONAME ; int CWPASecuritySettings::SetWPAEnabledEAPPlugin(class TDesC8 const &) + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/data/WPASecuritySettingsUI.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/data/WPASecuritySettingsUI.rss Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,312 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This file contains all the resources for the WPA Security Settings UI. +* +*/ + + +// RESOURCE IDENTIFIER +NAME AWAS // 4 letter ID + +// INCLUDES +#include +#include +#include +#include + +#include "WPASecuritySettingsUI.hrh" +#include + + +// RESOURCE DEFINITIONS + +RESOURCE RSS_SIGNATURE { } + +RESOURCE TBUF { buf="WPASecuritySettings"; } + + +//---------------------------------------------------- +// +// r_wpa_security_settings_menubar +// Menubar +// +//---------------------------------------------------- +// +RESOURCE MENU_BAR r_wpa_security_settings_menubar + { + titles= + { + MENU_TITLE + { + menu_pane = r_wpa_security_settings_menu; + } + }; + } + + + +//---------------------------------------------------- +// +// r_wpa_security_settings_menu +// The Options menu +// +//---------------------------------------------------- +// +RESOURCE MENU_PANE r_wpa_security_settings_menu + { + items= + { + MENU_ITEM + { + command = EWpaSelCmdChange; + txt = qtn_set_options_change; + flags = EEikMenuItemAction; + }, + + MENU_ITEM + { + command = EAknCmdHelp; + txt = qtn_options_help; + }, + + MENU_ITEM + { + command = EAknCmdExit; + txt = qtn_options_exit; + } + }; + } + + + +//---------------------------------------------------- +// +// r_wpasettings_pane_softkeys_options_back_edit +// WPA Security Settings softkeys +// +//---------------------------------------------------- +// +RESOURCE CBA r_wpasettings_pane_softkeys_options_back_edit + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; }, + CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; }, + CBA_BUTTON { id = EWpaSelCmdChange; txt = qtn_msk_change; } + }; + } + + + +//---------------------------------------------------- +// +// r_wpasettings_dialog +// WPA Security Settings main dialog +// +//---------------------------------------------------- +// +RESOURCE DIALOG r_wpasettings_dialog + { + flags = EEikDialogFlagWait | EEikDialogFlagNoDrag | + EEikDialogFlagNoTitleBar | EEikDialogFlagFillAppClientRect | + EEikDialogFlagCbaButtons; + + buttons = r_wpasettings_pane_softkeys_options_back_edit; + + items = + { + DLG_LINE + { + type = EAknCtSettingListBox; + id = KWpaMainSettingsListboxId; + control = LISTBOX + { + flags = EAknListBoxSelectionList; + }; + } + }; + } + + +//---------------------------------------------------- +// +// r_setting_app_edwin_key_data +// Window to enter key data +// +//---------------------------------------------------- +// +RESOURCE EDWIN r_setting_app_edwin_key_data + { + avkon_flags = EAknEditorFlagNoT9; + allowed_input_modes = EAknEditorTextInputMode | + EAknEditorNumericInputMode | + EAknEditorHalfWidthTextInputMode; + default_case = EAknEditorLowerCase; + maxlength = EMaxLengthOfPreSharedKey; + lines = 8; + } + + +//---------------------------------------------------- +// +// r_text_setting_page_key_data +// Setting page for entering key data +// +//---------------------------------------------------- +// +RESOURCE AVKON_SETTING_PAGE r_text_setting_page_key_data + { + softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + number= EAknSettingPageNoOrdinalDisplayed; + label= qtn_wlan_sett_preshared_key; + type = EEikCtEdwin; + editor_resource_id = r_setting_app_edwin_key_data; + } + + + +//---------------------------------------------------- +// +// r_setting_app_listbox +// Listbox for setting page +// +//---------------------------------------------------- +// +RESOURCE LISTBOX r_setting_app_listbox + { + flags = EEikListBoxMultipleSelection; + } + + + +//---------------------------------------------------- +// +// r_wpasettings_pane_softkeys_ok_cancel_select +// WEP Security Settings softkeys +// +//---------------------------------------------------- +// +RESOURCE CBA r_wpasettings_pane_softkeys_ok_cancel_select + { + buttons = + { + CBA_BUTTON { id = EAknSoftkeyOk; txt = text_softkey_ok; }, + CBA_BUTTON { id = EAknSoftkeyCancel; txt = text_softkey_cancel; }, + CBA_BUTTON { id = EAknSoftkeyOk; txt = qtn_msk_select; } + }; + } + + + +//---------------------------------------------------- +// +// r_radio_button_setting_page +// Setting page with radio buttons +// +//---------------------------------------------------- +// +RESOURCE AVKON_SETTING_PAGE r_radio_button_setting_page + { + number = EAknSettingPageNoOrdinalDisplayed; + softkey_resource = r_wpasettings_pane_softkeys_ok_cancel_select; + type = EAknSetListBox; + editor_resource_id= r_setting_app_listbox; + } + + + +//---------------------------------------------------- +// +// r_wpa_sec_sett_conf_query +// ConfirmationQuery dialog +// +//---------------------------------------------------- +// +RESOURCE DIALOG r_wpa_sec_sett_conf_query + { + flags = EGeneralQueryFlags; + buttons = R_AVKON_SOFTKEYS_YES_NO__YES; + items = + { + DLG_LINE + { + type = EAknCtQuery; + id = EGeneralQuery; + control = AVKON_CONFIRMATION_QUERY + { + layout = EConfirmationQueryLayout; + }; + } + }; + } + + + + +RESOURCE TBUF r_wpa_mode + { + buf = qtn_wlan_sett_wpa_mode; + } + +RESOURCE TBUF r_wpa_eap_config + { + buf = qtn_wlan_sett_eap_plugin_config; + } + +RESOURCE TBUF r_wpa_tkip_cipher + { + buf = qtn_wlan_sett_allow_tkip; + } + +RESOURCE TBUF r_wpa_mode_eap + { + buf = qtn_wlan_sett_wpa_mode_eap; + } + +RESOURCE TBUF r_wpa_mode_preshared_key + { + buf = qtn_wlan_sett_wpa_mode_preshared_key; + } + +RESOURCE TBUF r_wpa_cipher_allowed + { + buf = qtn_wlan_sett_tkip_allowed; + } + +RESOURCE TBUF r_wpa_cipher_not_allowed + { + buf = qtn_wlan_sett_tkip_not_allowed; + } + +RESOURCE TBUF r_wpa_preshared_key_must_be_defined + { + buf = qtn_selec_setting_compulsory; + } + +RESOURCE TBUF r_info_preshared_key_too_short + { + buf = qtn_wlan_info_preshared_key_too_short; + } + +RESOURCE TBUF r_info_preshared_key_not_hex + { + buf = qtn_wlan_info_preshared_key_not_hex; + } + +RESOURCE TBUF r_wpa_preshared_keydata_missing + { + buf = qtn_wlan_quest_preshared_key_data_missing; + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/eabi/WPASecuritySettingsUI_EKA2_ALRu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/eabi/WPASecuritySettingsUI_EKA2_ALRu.def Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,21 @@ +EXPORTS + _ZN20CWPASecuritySettings4NewLE13TSecurityMode @ 1 NONAME + _ZN20CWPASecuritySettings5EditLER22CWPASecuritySettingsUiRK7TDesC16 @ 2 NONAME + _ZN20CWPASecuritySettings5LoadLEmR14CCommsDatabase @ 3 NONAME + _ZN20CWPASecuritySettingsD0Ev @ 4 NONAME + _ZN20CWPASecuritySettingsD1Ev @ 5 NONAME + _ZN20CWPASecuritySettingsD2Ev @ 6 NONAME + _ZN22CWPASecuritySettingsUi3CvtEv @ 7 NONAME + _ZN22CWPASecuritySettingsUi4NewLER9CEikonEnv @ 8 NONAME + _ZN22CWPASecuritySettingsUiD0Ev @ 9 NONAME + _ZN22CWPASecuritySettingsUiD1Ev @ 10 NONAME + _ZN22CWPASecuritySettingsUiD2Ev @ 11 NONAME + _ZNK20CWPASecuritySettings5SaveLEmR14CCommsDatabase13TTypeOfSavingm @ 12 NONAME + _ZNK20CWPASecuritySettings7DeleteLEm @ 13 NONAME + _ZNK20CWPASecuritySettings7IsValidEv @ 14 NONAME + _ZN20CWPASecuritySettings18SetWPAPreSharedKeyERK7TDesC16 @ 15 NONAME + _ZN20CWPASecuritySettings5LoadLEmRN8CommsDat11CMDBSessionE @ 16 NONAME + _ZNK20CWPASecuritySettings5SaveLEmRN8CommsDat11CMDBSessionE13TTypeOfSavingm @ 17 NONAME + _ZN20CWPASecuritySettings22SetWPAEnabledEAPPluginERK6TDesC8 @ 18 NONAME + _ZN20CWPASecuritySettings23SetWPADisabledEAPPluginERK6TDesC8 @ 19 NONAME + diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/group/WPASecuritySettingsUI.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/group/WPASecuritySettingsUI.mmp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is project specification file for the WPASecuritySettingsUI. +* +*/ + + +#include +#include + +TARGET WPASecuritySettingsUI.dll +TARGETTYPE DLL + +CAPABILITY CAP_GENERAL_DLL +VENDORID VID_DEFAULT + + +START RESOURCE ../data/WPASecuritySettingsUI.rss +HEADER +TARGETPATH RESOURCE_FILES_DIR +LANGUAGE_IDS +END // RESOURCE + + +SOURCEPATH ../src + +SOURCE WPASecuritySettings.cpp +SOURCE WPASecuritySettingsImpl.cpp +SOURCE WPASecuritySettingsUI.cpp +SOURCE WPASecuritySettingsUiImpl.cpp +SOURCE WPASecuritySettingsDlg.cpp +SOURCE WPASecuritySettingsUiPanic.cpp + +// Component specific internal headers +USERINCLUDE ../inc + +//Macro to /epoc32 headers +MW_LAYER_SYSTEMINCLUDE +APP_LAYER_SYSTEMINCLUDE + +LIBRARY FeatMgr.lib +LIBRARY hlplch.lib +LIBRARY euser.lib +LIBRARY cone.lib +LIBRARY eikcore.lib +LIBRARY eikcoctl.lib +LIBRARY avkon.lib +LIBRARY eikdlg.lib +LIBRARY bafl.lib +LIBRARY commonengine.lib +LIBRARY commdb.lib +LIBRARY ecom.lib +LIBRARY commsdat.lib + +DEBUGLIBRARY flogger.lib + +#if defined(ARMCC) + DEFFILE ../eabi/WPASecuritySettingsUI_EKA2_ALR.def +#elif defined( WINSCW ) + DEFFILE ../bwinscw/WPASecuritySettingsUI_EKA2_ALR.def +#endif + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/group/bld.inf Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This file provides the information required for building the whole of a WPASecuritySettingsUI. +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +// export iby files +../Rom/WPASecuritySettingsUI.iby CORE_MW_LAYER_IBY_EXPORT_PATH(WPASecuritySettingsUI.iby) +../Rom/WPASecuritySettingsUIResources.iby LANGUAGE_MW_LAYER_IBY_EXPORT_PATH(WPASecuritySettingsUIResources.iby) + +// export localised loc file +../loc/wpasecuritysettingsui.loc MW_LAYER_LOC_EXPORT_PATH(wpasecuritysettingsui.loc) + + +PRJ_MMPFILES +./WPASecuritySettingsUI.mmp + + +PRJ_TESTMMPFILES + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/inc/SecuritySettingsLogger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/inc/SecuritySettingsLogger.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,152 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Logger utility. +* +*/ + + +#ifndef SECURITYSETTINGSLOGGER_H +#define SECURITYSETTINGSLOGGER_H + + +// INCLUDES + +#include +#include +#include + + +#ifdef _DEBUG +#define __SEC_SETT_LOG__ +#endif // _DEBUG + + +#ifdef __SEC_SETT_LOG__ + +// CONSTANTS + +// SecuritySettingsLogger logging directory. +_LIT( KSecSettLogDir, "TestSecSett" ); +// SecSett log file name. +_LIT( KSecSettLogFile, "SecSett.log" ); +// Format string: enter function. +_LIT( KSecSettLogEnterFn, "-> %S" ); +// Format string: leave function. +_LIT( KSecSettLogLeaveFn, "<- %S" ); +// Format string: time. +_LIT( KSecSettLogTimeFormatString, "%H:%T:%S:%*C2" ); +// Format string: timestamp. +_LIT( KSecSettLogTimeStampFormatString, "%S %S" ); + +// DEFINES + +// Write log: enter function. +#define CLOG_ENTERFN( a ) \ + { \ + _LIT( temp, a ); \ + RFileLogger::WriteFormat \ + ( \ + KSecSettLogDir, \ + KSecSettLogFile, \ + EFileLoggingModeAppend, \ + KSecSettLogEnterFn, \ + &temp \ + ); \ + } + +// Write log: leave function. +#define CLOG_LEAVEFN( a ) \ + { \ + _LIT( temp, a ); \ + RFileLogger::WriteFormat \ + ( \ + KSecSettLogDir, \ + KSecSettLogFile, \ + EFileLoggingModeAppend, \ + KSecSettLogLeaveFn, \ + &temp \ + ); \ + } + +// Write log: string 'a'. +#define CLOG_WRITE( a ) \ + { \ + _LIT( temp, a ); \ + RFileLogger::Write \ + ( \ + KSecSettLogDir, \ + KSecSettLogFile, \ + EFileLoggingModeAppend, \ + temp \ + ); \ + } + +// Write log: formatted. +#define CLOG_WRITE_FORMAT( a, b ) \ + { \ + _LIT( temp, a ); \ + RFileLogger::WriteFormat \ + ( \ + KSecSettLogDir, \ + KSecSettLogFile, \ + EFileLoggingModeAppend, \ + temp, \ + b \ + ); \ + } + +// Write log: timestamp. +#define CLOG_WRITE_TIMESTAMP( a ) \ + { \ + _LIT( temp, a ); \ + TTime time; \ + time.HomeTime(); \ + TBuf<32> timeBuf; \ + TRAPD( err, time.FormatL( timeBuf, KSecSettLogTimeFormatString ) ); \ + if ( !err ) \ + { \ + RFileLogger::WriteFormat \ + ( \ + KSecSettLogDir, \ + KSecSettLogFile, \ + EFileLoggingModeAppend, \ + KSecSettLogTimeStampFormatString, \ + &temp, \ + &timeBuf \ + ); \ + } \ + } + +#else // not defined __SEC_SETT_LOG__ + +// DEFINES + +// Empty definition (disable log). +#define CLOG_ENTERFN( a ) + +// Empty definition (disable log). +#define CLOG_LEAVEFN( a ) + +// Empty definition (disable log). +#define CLOG_WRITE( a ) + +// Empty definition (disable log). +#define CLOG_WRITE_FORMAT( a, b ) + +// Empty definition (disable log). +#define CLOG_WRITE_TIMESTAMP( a ) + +#endif // __SEC_SETT_LOG__ + +#endif diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsDefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsDefs.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Definitions. +* +*/ + + +#ifndef WPASECURITYSETTINGSDEFS_H +#define WPASECURITYSETTINGSDEFS_H + + +// CONSTANTS + + +// UID of application containing help texts (General Settings). +LOCAL_D const TUid KWPASecuritySettingsUiHelpMajor = { 0x100058EC }; + + +#endif // WPASECURITYSETTINGSDEFS_H diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsDlg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsDlg.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,304 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declares dialog. +* +*/ + + +#ifndef WPA_SECURITY_SETTINGS_DLG_H +#define WPA_SECURITY_SETTINGS_DLG_H + + +// ENUMERATIONS + +// Members to be showed in the setting pages +enum TWpaMember + { + EWpaMode, // WPA mode + EWpaEapConfig, // EAP Plugin configuration + EWpaWpa2Only, // Wpa2 only mode + EWpaPreSharedKey // Pre-shared key + }; + + +// INCLUDES +#include +#include +#include +#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#else +#include +#include +#endif +#include "WPASecuritySettingsImpl.h" + +// FORWARD DECLARATIONS +class CAknTitlePane; +class CWPASecuritySettingsImpl; +class CEAPPluginConfigurationIf; + + +// CLASS DECLARATION +/** +* CWPASecuritySettingsDlg dialog class +*/ +NONSHARABLE_CLASS( CWPASecuritySettingsDlg ) : public CAknDialog, + public MEikListBoxObserver + { + + public: // Constructors and destructor + + /** + * Create and launch dialog. + * @param aSecuritySettings Security settings + * @param aTitle Title of the dialog + * @return The ID of the button that closed the dialog + */ + TInt ConstructAndRunLD( CWPASecuritySettingsImpl* aSecuritySettings, + const TDesC& aTitle ); + + + /** + * Two-phase construction. + * @param aEventStore A reference to hold the events happened + * @param aIapId Id of the IAP. + * @param aPlugin The EAP Configuration plugin. + * @return The constructed CWPASecuritySettingsDlg object. + */ + static CWPASecuritySettingsDlg* NewL( TInt& aEventStore, + const TUint32 aIapId, + CEAPPluginConfigurationIf* aPlugin ); + + /** + * Destructor. + */ + ~CWPASecuritySettingsDlg(); + + + protected: + /** + * Constructor. + * @param aEventStore A reference to hold the events happened + * @param aIapId Id of the IAP. + * @param aPlugin The EAP Configuration plugin. + */ + CWPASecuritySettingsDlg( TInt& aEventStore, const TUint32 aIapId, + CEAPPluginConfigurationIf* aPlugin ); + + + public: // Functions from base classes + /** + * Handle key events. + * @param aKeyEvent: key event + * @param aType: type of event + * @return The key response, if it was consumed or not. + */ + TKeyResponse OfferKeyEventL( const TKeyEvent& aKeyEvent, + TEventCode aType ); + + private: // Functions from base classes + + /** + * This function is called by the dialog framework before the dialog is + * sized and laid out. + */ + virtual void PreLayoutDynInitL(); + + + /** + * Handles a dialog button press for the specified button + * @param aButtonId The ID of the button that was activated. + * @return ETrue to validate and exit the dialog, + * EFalse to keep the dialog active + */ + TBool OkToExitL( TInt aButtonId ); + + + /** + * Processes user commands. + * @param aCommandId ID of the command to respond to. + */ + virtual void ProcessCommandL( TInt aCommandId ); + + + /** + * Handles list box events. + * @param aListBox The originating list box. + * @param aEventType A code for the event. + */ + void HandleListBoxEventL( CEikListBox* aListBox, + TListBoxEvent aEventType ); + + /** + * Get help context. + * @param aContext Help context is returned here. + */ + void GetHelpContext( TCoeHelpContext& aContext ) const; + + /** + * Initialize menu pane. + * @param aResourceId Menu pane resource id. + * @param CEikMenuPane Menu pane. + */ + void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ); + + + protected: // New functions + + /** + * Handles listbox data change + */ + void HandleListboxDataChangeL(); + + + /** + * Fills up the listbox with data + * @param aItemArray Array where to add the elements + * @param arr Array to be used as list elements + * @param aRes Array of resource IDs to be used for the + * elements of arr + */ + void FillListWithDataL( CDesCArrayFlat& aItemArray, + const TWpaMember& arr, const TInt* aRes ); + + + /** + * Updates one 'textual' listbox item for the given member + * @param aMember Value specifying which member has to be added to + * the list + * @param aRes Resource ID for the 'title text' for this member + * @param aPos The current position of the item in the list + */ + void UpdateTextualListBoxItemL( TWpaMember aMember, TInt aRes, + TInt aPos ); + + + /** + * Creates one 'textual' listbox item for the given member + * @param aMember Value specifying which member has to be added to + * the list + * @param aRes Resource ID for the 'title text' for this member + * @return The created listbox item text. + */ + HBufC* CreateTextualListBoxItemL( TWpaMember aMember, TInt aRes ); + + + /** + * Changes one setting. The setting, which is + * highlighted as current in the listbox is changed. + * @param aQuick ETrue if the setting is "two-choices", and can be + * automatically changed, without showing the list of + * elements + */ + void ChangeSettingsL( TBool aQuick ); + + + /** + * Shows a popup setting page (radio buttons) for the given member + * @param aDataMember The member which needs to be changed + * @return A boolean indicating whether the current setting + * has been changed or not. + */ + TBool ShowPopupSettingPageL( TWpaMember aDataMember ); + + + /** + * Shows a popup text setting page for the given member + * @return A boolean indicating whether the current setting + * has been changed or not. + */ + TBool ShowPopupTextSettingPageL(); + + + /** + * Fills up a pop-up radio button setting page with the currently + * valid and available choices for the given member. + * @param aData The member whose new setting is needed + * @param aCurrvalue The current value of the setting + * @return An array of choices for the given member, pushed to the + * CleanupStack. + */ + CDesCArrayFlat* FillPopupSettingPageLC( TWpaMember aData, + TInt& aCurrvalue ); + + + /** + * Updates the given member's data with the new setting from the setting + * page. + * @param aData The member to update + * @param aCurrvalue The new value + * @return A boolean indicating if the value is actually changed + */ + TBool UpdateFromPopupSettingPage( TWpaMember aData, TBool aCurrvalue ); + + + /** + * Cleanup for the iEapConfigActive semaphore flag + * @since S60 5.0 + * @param aPtr Pointer to this class + */ + static void ResetEapConfigFlag( TAny* aPtr ); + + /** + * @see CEikDialog + */ + void HandleDialogPageEventL( TInt aEventID ); + + private: //data + + // Stores the name of the connection, to be showed as the title. + TBuf iConnectionName; + + // Title pane. Not owned. + CAknTitlePane* iTitlePane; + + // Pointer to the old title. Owned. + HBufC* iOldTitleText; + + // Owned through resources, destroyed automatically by the dialog. + CAknSettingStyleListBox* iList; + + // Array of the items. Not owned. + CDesCArrayFlat* iItemArray; + + // Fields of the main view. Not owned. + TWpaMember* iFieldsMain; + + // Titles of the main view. Not owned. + TInt* iTitlesMain; + + // Pointer to the WPA Security Settings. Not owned. + CWPASecuritySettingsImpl* iSecuritySettings; + + // To hold the events. Not owned. + TInt* iEventStore; + + // The Id of the AP. + TUint32 iIapId; + + // The EAP Configuration plugin. Not owned. + CEAPPluginConfigurationIf* iPlugin; + + // Indicates whether the EAP plugin configuration is active + TBool iEapConfigActive; + + TBuf8 iEnabledPluginList; + TBuf8 iDisabledPluginList; + }; + + +#endif // WPA_SECURITY_SETTINGS_DLG_H + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsImpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsImpl.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,302 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of class CWPASecuritySettingsImpl. +* +*/ + + +#ifndef WPASECURITYSETTINGSIMPL_H +#define WPASECURITYSETTINGSIMPL_H + +// INCLUDES +#include +#include + +#include + +#include +using namespace CommsDat; + + + +// CONST DECLARATIONS +#define KWLANEAPLISTLENGTH 1024 // Max length of the EAP Plugin list + + +// FORWARD DECLARATIONS +class CCommsDatabase; +class CEAPPluginConfigurationIf; + +// CLASS DECLARATION + +/** +* WPA Security Settings. +* Implementation behind proxy class CWPASecuritySettings. +*/ +NONSHARABLE_CLASS( CWPASecuritySettingsImpl ) : public CBase + { + + public: // Constructors and destructor + + /** + * Two-phased constructor. Leaves on failure. + * @param aSecurityMode The chosen security mode. It can be + * ESecurityMode8021x or ESecurityModeWpa + * @return The constructed CWPASecuritySettings object. + */ + static CWPASecuritySettingsImpl* NewL( TSecurityMode aSecurityMode ); + + /** + * Destructor. + */ + virtual ~CWPASecuritySettingsImpl(); + + + protected: // Constructors + + /** + * Constructor. + * @param aSecurityMode The chosen security mode. It can be + * ESecurityMode8021x or ESecurityModeWpa + */ + CWPASecuritySettingsImpl( TSecurityMode aSecurityMode ); + + /** + * Second-phase constructor. + */ + void ConstructL(); + + + public: // New methods + + /** + * Load from database. + * @param aIapId Wlan Service Table Id of the IAP to be loaded + * @param aCommsDb Comms database. + */ + void LoadL( TUint32 aIapId, CCommsDatabase& aCommsDb ); + + + /** + * Save to database. + * @param aIapId Wlan Service Table Id of the IAP to be saved + * @param aCommsDb Comms database. + * @param aTypeOfSaving Tells what kind of AP we are going to save: it + * can be ESavingEditedAP, ESavingBrandNewAP, or + * ESavingNewAPAsACopy + * @param aOldIapId The old Id of the IAP; it is used to save the EAP + * configuration, only when aIsNewAP is ETrue + */ + void SaveL( TUint32 aIapId, CCommsDatabase& aCommsDb, + TTypeOfSaving aTypeOfSaving, TUint32 aOldIapId ); + + + /** + * Delete from database. It actually just removes EAP Configuration. + * @param aIapId Id of the IAP to be saved + */ + void DeleteL( TUint32 aIapId ); + + + /** + * Tells if the settings are valid and can be saved + * @return ETrue if all the compulsory settings have been entered + */ + TBool IsValid(); + + + /** + * Sets the Pre-shared key + * @param aPreSharedKey The key to be set + * @return KErrNone if successful, or an error code + */ + TInt SetWPAPreSharedKey( const TDesC& aPreSharedKey ); + + /** + * Gets the type of Security set. + * @return The security mode in use. It can be ESecurityMode8021x or + * ESecurityModeWpa + */ + inline TSecurityMode SecurityMode() const; + + + /** + * Tells if Pre-shared key is in use or not + * @return ETrue if Pre-shared key is in use + */ + inline TBool WPAMode() const; + + + /** + * Sets the use of Pre-shared key. + * @param aWPAMode ETrue if pre-shared key is in use + */ + inline void SetWPAMode( const TBool aWPAMode ); + + + /** + * Tells if it is WPA2 Only mode + * @return ETrue if it is WPA2 Only mode + */ + inline TBool Wpa2Only() const; + + + /** + * Sets the WPA2 Only mode enabling variable + * @param aAllowed ETrue if WPA2 Only mode is enabled + */ + inline void SetWpa2Only( const TBool aAllowed ); + + + /** + * Returns the Pre-shared key + * @return The pre-shared key + */ + inline TDes8* WPAPreSharedKey(); + + + /** + * Sets the Pre-shared key + * @param aPreSharedKey The key to be set + */ + inline void SetWPAPreSharedKey( const TDesC8& aPreSharedKey ); + + + /** + * Returns the content of the WlanEapList column of WLANServiceTable + * @return The content string + */ + inline TDes* WPAEAPPlugin(); + + /** + * Returns the content of the WlanEnabledEapList column of + * WLANServiceTable + * @return The content string. Ownership not passed! + */ + inline HBufC8* WPAEnabledEAPPlugin(); + + /** + * Returns the content of the WlanDisabledEapList column of + * WLANServiceTable + * @return The content string. Ownership not passed! + */ + inline HBufC8* WPADisabledEAPPlugin(); + + /** + * Sets the content of the WlanEapList column of WLANServiceTable + * @param aPluginList The content string to be set + */ + inline void SetWPAEAPPlugin( const TDes& aPluginList ); + + /** + * Sets the content of the WlanEnabledEapList column of WLANServiceTable + * (for expanded EAP types) + * @param aEnabledPluginList Enumeration of enabled plugins + * @return KErrNone if successful, or an error code + */ + TInt SetWPAEnabledEAPPlugin( const TDesC8& aEnabledPluginList ); + + /** + * Sets the content of the WlanDisabledEapList column of WLANServiceTable + * (for expanded EAP types) + * @param aDisabledPluginList Enumeration of disabled plugins + * @return KErrNone if successful, or an error code + */ + TInt SetWPADisabledEAPPlugin( const TDesC8& aDisabledPluginList ); + + /** + * Sets the Id of the AP + * @param aIapId The Id to be set + */ + inline void SetIapId( const TUint32 aIapId ); + + /** + * Returns the Id of the AP + * @return The Id + */ + inline const TUint32 IapId(); + + /** + * Returns the pointer to the EAP Configuration plugin + * @return The EAP Configuration plugin + */ + inline CEAPPluginConfigurationIf* Plugin(); + + /** + * Load from database. + * @param aIapId Wlan Service Table Id of the IAP to be loaded + * @param aSession CommsDat session. + */ + void LoadL( TUint32 aIapId, CMDBSession& aSession ); + + + /** + * Save to database. + * @param aIapId Wlan Service Table Id of the IAP to be saved + * @param aSession CommsDat session. + * @param aTypeOfSaving Tells what kind of AP we are going to save: it + * can be ESavingEditedAP, ESavingBrandNewAP, or + * ESavingNewAPAsACopy + * @param aOldIapId The old Id of the IAP; it is used to save the EAP + * configuration, only when aIsNewAP is ETrue + */ + void SaveL( TUint32 aIapId, CMDBSession& aSession, + TTypeOfSaving aTypeOfSaving, TUint32 aOldIapId ); + + private: + /** + * Checks whether the given string is a valid PSK + * @since S60 5.0 + * @param aPsk The string to be checked + * @return ETrue if the string is a valid PSK, EFalse otherwise. + */ + TBool IsValidPsk( const TDesC8& aPsk ); + + private: // Data + + // Security mode in use + TSecurityMode iSecurityMode; + + // Pre-shared key in use or not + TBool iWPAMode; + + // The content of the WlanEapList column of WLANServiceTable + TBuf iWPAEAPPlugin; + + // The pre-shared key + TBuf8 iWPAPreSharedKey; + + // The content of the WlanEnabledEapList column of WLANServiceTable. + // Owned. + HBufC8 *iWPAEnabledEAPPlugin; + + // The content of the WlanDisabledEapList column of WLANServiceTable. + // Owned. + HBufC8 *iWPADisabledEAPPlugin; + + // WPA2 Only mode enabled or not + TBool iWpa2Only; + + // The Id of the AP. + TUint32 iIapId; + + // The EAP Configuration plugin. Owned. + CEAPPluginConfigurationIf* iPlugin; + }; + +// Include inline functions +#include "WPASecuritySettingsImpl.inl" + + +#endif diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsImpl.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsImpl.inl Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,168 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: CWPASecuritySettingsImpl inline functions +* +*/ + + + +#ifndef WPASECURITYSETTINGSIMPL_INL +#define WPASECURITYSETTINGSIMPL_INL + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::SecurityMode +// --------------------------------------------------------- +// +inline TSecurityMode CWPASecuritySettingsImpl::SecurityMode() const + { + return iSecurityMode; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::WPAMode +// --------------------------------------------------------- +// +inline TBool CWPASecuritySettingsImpl::WPAMode() const + { + return iWPAMode; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::Wpa2Only +// --------------------------------------------------------- +// +inline TBool CWPASecuritySettingsImpl::Wpa2Only() const + { + return iWpa2Only; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::WPAPreSharedKey +// --------------------------------------------------------- +// +inline TDes8* CWPASecuritySettingsImpl::WPAPreSharedKey() + { + return &iWPAPreSharedKey; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::WPAEAPPlugin +// --------------------------------------------------------- +// +inline TDes* CWPASecuritySettingsImpl::WPAEAPPlugin() + { + return &iWPAEAPPlugin; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::WPAEnabledEAPPlugin +// --------------------------------------------------------- +// +inline HBufC8* CWPASecuritySettingsImpl::WPAEnabledEAPPlugin() + { + return iWPAEnabledEAPPlugin; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::WPADisabledEAPPlugin +// --------------------------------------------------------- +// +inline HBufC8* CWPASecuritySettingsImpl::WPADisabledEAPPlugin() + { + return iWPADisabledEAPPlugin; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::SetWPAMode +// --------------------------------------------------------- +// +inline void CWPASecuritySettingsImpl::SetWPAMode( const TBool aWPAMode ) + { + iWPAMode = aWPAMode; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::SetWpa2Only +// --------------------------------------------------------- +// +inline void CWPASecuritySettingsImpl::SetWpa2Only( const TBool aWpa2Only ) + { + iWpa2Only = aWpa2Only; + } + + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::SetWPAPreSharedKey +// --------------------------------------------------------- +// +inline void CWPASecuritySettingsImpl::SetWPAPreSharedKey( + const TDesC8& aWPAPreSharedKey ) + { + iWPAPreSharedKey = aWPAPreSharedKey; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::SetIapId +// --------------------------------------------------------- +// +void CWPASecuritySettingsImpl::SetIapId( const TUint32 aIapId ) + { + iIapId = aIapId; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::IapId +// --------------------------------------------------------- +// +const TUint32 CWPASecuritySettingsImpl::IapId() + { + return iIapId; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::SetWPAEAPPlugin +// --------------------------------------------------------- +// +void CWPASecuritySettingsImpl::SetWPAEAPPlugin( const TDes& aPluginList ) + { + iWPAEAPPlugin.Copy( aPluginList ); + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::Plugin +// --------------------------------------------------------- +// +CEAPPluginConfigurationIf* CWPASecuritySettingsImpl::Plugin() + { + return iPlugin; + } + + +#endif + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsUI.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsUI.hrh Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This file contains declarations for resources of WPASecuritySettingsUI. The file can be included in C++ or resource file. +* +*/ + + +#ifndef WPASecuritySettingsUI_HRH +#define WPASecuritySettingsUI_HRH + + +// Menu command IDs +enum TWpaSelectorMenuCommands + { + EWpaSelCmdChange = 2468 + }; + + +// dialog line IDs +enum TWpaSelectorDllDlgLineId + { + KWpaMainSettingsListboxId = 3 + }; + + + + +// The minimum length of PreSharedKey in ASCII encoding +#define EMinLengthOfPreSharedKeyAscii 8 + +// The maximum length of PreSharedKey in ASCII encoding +#define EMaxLengthOfPreSharedKeyAscii 63 + +// The required length of PreSharedKey in hexadecimal digits +#define ELengthOfPreSharedKeyHex 64 + +// The maximum number of bytes occupied by the PSK +#define EMaxLengthOfPreSharedKey ELengthOfPreSharedKeyHex + + +#endif // WPASecuritySettingsUI_HRH + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsUiImpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsUiImpl.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Declaration of class CWPASecuritySettingsUiImpl. +* +*/ + + +#ifndef WPASECURITYSETTINGSUIIMPL_H +#define WPASECURITYSETTINGSUIIMPL_H + +// INCLUDES + +#include + + +// FORWARD DECLARATIONS + +class CEikonEnv; +class CWPASecuritySettings; +class CWPASecuritySettingsUiImpl; +class CWPASecuritySettingsImpl; + + +// CLASS DECLARATION + +/** +* WPA Security Settings UI implementation (behind proxy class +* CWPASecuritySettingsUi) +*/ +NONSHARABLE_CLASS( CWPASecuritySettingsUiImpl ) : public CBase + { + + public: // Constructors and destructor + + /** + * Two-phased constructor. Leaves on failure. + * @param aEikEnv Eikon environment. + * @return The constructed CWPASecuritySettingsUiImpl object. + */ + static CWPASecuritySettingsUiImpl* NewL( CEikonEnv& aEikEnv ); + + /** + * Destructor. + */ + virtual ~CWPASecuritySettingsUiImpl(); + + protected: // Constructors + + /** + * Constructor. + * @param aEikEnv Eikon environment. + */ + CWPASecuritySettingsUiImpl( CEikonEnv& aEikEnv ); + + /** + * Second-phase constructor. + */ + void ConstructL(); + + public: // New methods + + /** + * Edit the settings. + * @param aSettings Settings to edit. + * @param aTitle Title Pane text to display during edit. + * @return Exit code. Value from CWPASecuritySettings::TEvent bits + * combined. + */ + TInt EditL( CWPASecuritySettingsImpl& aSettings, const TDesC& aTitle ); + + + private: // Data + + // To hold the events + TInt iEventStore; + + // Resource file offset. + TInt iResOffset; + + // Eikon environment. Not owned. + CEikonEnv* iEikEnv; + }; + +#endif diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsUiPanic.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/inc/WPASecuritySettingsUiPanic.h Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Panic function and codes. +* +*/ + + +#ifndef WPASECURITYSETTINGSUIPANIC_H +#define WPASECURITYSETTINGSUIPANIC_H + +// TYPES + +/** +* Panic reasons for WPA Security Settings UI. +*/ +enum TWpaSecuritySettingsPanicCodes + { + EUnknownCase, + ETableNotFound + }; + + +// FUNCTION DECLARATIONS + +/** +* Panic the thread. +* @param aReason Reason for the panic. +*/ +void Panic( TWpaSecuritySettingsPanicCodes aPanic ); + +#endif diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/loc/wpasecuritysettingsui.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/loc/wpasecuritysettingsui.loc Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,125 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: This is a localisation file for WPASecuritySettingsUI A .loc file is the one and only place where the logical strings to be localised are defined. +* +*/ + + + +// LOCALISATION STRINGS + + +//d:Command in options menu. +//d:Modifies the currently selected item. +//l:list_single_pane_t1_cp2 +//w: +//r:3.0 +// +#define qtn_set_options_change "Change" + + +//d:First element of the Selection List +//l:list_setting_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wpa_mode "WPA/WPA2 mode" + + +//d:Possible second element of the Selection List +//l:list_setting_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_eap_plugin_config "EAP plug-in configuration" + + +//d:Possible second element of the Selection List +//l:list_setting_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_preshared_key "Pre-shared key" + + +//d:Third element of the Selection List +//l:list_setting_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_allow_tkip "WPA2-only mode" + + +//d:Setting item for the first element of the Selection List +//d:(qtn_wlan_sett_wpa_mode) +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wpa_mode_eap "EAP" + + +//d:Setting item for the first element of the Selection List +//d:(qtn_wlan_sett_wpa_mode) +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_wpa_mode_preshared_key "Pre-shared key" + + +//d:Setting item for the third element of the Selection List +//d:(qtn_wlan_sett_allow_tkip) +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_tkip_allowed "No" + + +//d:Setting item for the third element of the Selection List +//d:(qtn_wlan_sett_allow_tkip) +//l:list_set_graphic_pane_t1 +//w: +//r:3.0 +// +#define qtn_wlan_sett_tkip_not_allowed "Yes" + + +//d:Information note for the user when the entered key is too short +//l:popup_snote_single_text_window +//w: +//r:3.0 +// +#define qtn_wlan_info_preshared_key_too_short "Key must be at least 8 characters long" + + +//d:Information note for the user when the entered key is not hexadecimal +//l:popup_snote_single_text_window +//w: +//r:5.0 +// +#define qtn_wlan_info_preshared_key_not_hex "Invalid characters in pre-shared key. 64-digit key must be in hexadecimal format." + + +//d:Confirmation query showed to the user when not all compulsory data have +//d:been entered +//l:popup_note_window +//w: +//r:3.0 +// +#define qtn_wlan_quest_preshared_key_data_missing "Pre-shared key data is compulsory. Security settings will not be saved. Continue?" + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettings.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettings.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,168 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWPASecuritySettings. +* +*/ + + +// INCLUDE FILES + +#include "WPASecuritySettingsImpl.h" +#include "WPASecuritySettingsUiImpl.h" + +#include + + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWPASecuritySettings::NewL +// --------------------------------------------------------- +// +EXPORT_C CWPASecuritySettings* CWPASecuritySettings::NewL( + TSecurityMode aSecurityMode ) + { + CWPASecuritySettings* settings = new ( ELeave ) CWPASecuritySettings(); + CleanupStack::PushL( settings ); + settings->iImpl = CWPASecuritySettingsImpl::NewL( aSecurityMode ); + CleanupStack::Pop( settings ); + return settings; + } + + +// --------------------------------------------------------- +// CWPASecuritySettings::~CWPASecuritySettings +// --------------------------------------------------------- +// +EXPORT_C CWPASecuritySettings::~CWPASecuritySettings() + { + delete iImpl; + } + + +// --------------------------------------------------------- +// CWPASecuritySettings::LoadL +// --------------------------------------------------------- +// +EXPORT_C void CWPASecuritySettings::LoadL( TUint32 aIapId, + CCommsDatabase& aCommsDb ) + { + iImpl->LoadL( aIapId, aCommsDb ); + iImpl->SetIapId( aIapId ); + } + + +// --------------------------------------------------------- +// CWPASecuritySettings::SaveL +// --------------------------------------------------------- +// +EXPORT_C void CWPASecuritySettings::SaveL( TUint32 aIapId, + CCommsDatabase& aCommsDb, + TTypeOfSaving aTypeOfSaving, + TUint32 aOldIapId ) const + { + iImpl->SaveL( aIapId, aCommsDb, aTypeOfSaving, aOldIapId ); + } + + +// --------------------------------------------------------- +// CWPASecuritySettings::EditL +// --------------------------------------------------------- +// +EXPORT_C TInt CWPASecuritySettings::EditL( CWPASecuritySettingsUi& aUi, + const TDesC& aTitle ) + { + return aUi.iImpl->EditL( *iImpl, aTitle ); + } + + +// --------------------------------------------------------- +// CWPASecuritySettings::DeleteL +// --------------------------------------------------------- +// +EXPORT_C void CWPASecuritySettings::DeleteL( TUint32 aIapId ) const + { + iImpl->DeleteL( aIapId ); + } + + +// --------------------------------------------------------- +// CWPASecuritySettings::IsValid +// --------------------------------------------------------- +// +EXPORT_C TBool CWPASecuritySettings::IsValid() const + { + return iImpl->IsValid(); + } + + +// --------------------------------------------------------- +// CWPASecuritySettings::SetWPAPreSharedKey +// --------------------------------------------------------- +// +EXPORT_C TInt CWPASecuritySettings::SetWPAPreSharedKey( + const TDesC& aPreSharedKey ) + { + return iImpl->SetWPAPreSharedKey( aPreSharedKey ); + } + + +// --------------------------------------------------------- +// CWPASecuritySettings::LoadL +// --------------------------------------------------------- +// +EXPORT_C void CWPASecuritySettings::LoadL( TUint32 aIapId, + CMDBSession& aSession ) + { + iImpl->LoadL( aIapId, aSession ); + iImpl->SetIapId( aIapId ); + } + + +// --------------------------------------------------------- +// CWPASecuritySettings::SaveL +// --------------------------------------------------------- +// +EXPORT_C void CWPASecuritySettings::SaveL( TUint32 aIapId, + CMDBSession& aSession, + TTypeOfSaving aTypeOfSaving, + TUint32 aOldIapId ) const + { + iImpl->SaveL( aIapId, aSession, aTypeOfSaving, aOldIapId ); + } + + +// --------------------------------------------------------- +// CWPASecuritySettings::SaveL +// --------------------------------------------------------- +// +EXPORT_C TInt CWPASecuritySettings::SetWPAEnabledEAPPlugin( + const TDesC8& aEnabledPluginList ) + { + return iImpl->SetWPAEnabledEAPPlugin( aEnabledPluginList ); + } + +// --------------------------------------------------------- +// CWPASecuritySettings::SaveL +// --------------------------------------------------------- +// +EXPORT_C TInt CWPASecuritySettings::SetWPADisabledEAPPlugin( + const TDesC8& aDisabledPluginList ) + { + return iImpl->SetWPADisabledEAPPlugin( aDisabledPluginList ); + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsDlg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsDlg.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,1037 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 dialog. +* +*/ + + +// INCLUDE FILES +#include "WPASecuritySettingsDlg.h" +#include "WPASecuritySettingsUiPanic.h" + +#include "WPASecuritySettingsUI.hrh" + +#include "WPASecuritySettingsDefs.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + + +// CONSTANT DECLARATIONS + +// Number of fields of main view +LOCAL_D const TInt KNumOfFieldsMain = 3; + +// Menu List item format +_LIT( KTxtMenuListItemFormat, " \t%S\t\t" ); + +// Number of spaces and tabs in KTxtMenuListItemFormat string +LOCAL_D const TInt KSpaceAndTabsLength = 4; + + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::CWPASecuritySettingsDlg +// --------------------------------------------------------- +// +CWPASecuritySettingsDlg::CWPASecuritySettingsDlg( TInt& aEventStore, + const TUint32 aIapId, + CEAPPluginConfigurationIf* aPlugin ) +: iEventStore( &aEventStore ), + iIapId( aIapId ), + iPlugin( aPlugin ) + { + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::~CWPASecuritySettingsDlg +// --------------------------------------------------------- +// +CWPASecuritySettingsDlg::~CWPASecuritySettingsDlg() + { + if ( iTitlePane ) + { + // set old text back, if we have it... + if ( iOldTitleText ) + { + TRAP_IGNORE( iTitlePane->SetTextL( *iOldTitleText ) ); + delete iOldTitleText; + } + } + + FeatureManager::UnInitializeLib(); + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::NewL +// --------------------------------------------------------- +// +CWPASecuritySettingsDlg* CWPASecuritySettingsDlg::NewL( TInt& aEventStore, + const TUint32 aIapId, + CEAPPluginConfigurationIf* aPlugin ) + { + CWPASecuritySettingsDlg* secSett = new ( ELeave )CWPASecuritySettingsDlg( + aEventStore, aIapId, aPlugin ); + return secSett; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::ConstructAndRunLD +// --------------------------------------------------------- +// +TInt CWPASecuritySettingsDlg::ConstructAndRunLD( + CWPASecuritySettingsImpl* aSecuritySettings, + const TDesC& aTitle ) + { + CleanupStack::PushL( this ); + + const TInt Titles_Wpa_Main[KNumOfFieldsMain+1] = + { + R_WPA_MODE, + R_WPA_EAP_CONFIG, + R_WPA_MODE_PRESHARED_KEY, + R_WPA_TKIP_CIPHER + }; + + const TInt Fields_Wpa_Main[KNumOfFieldsMain+1] = + { + EWpaMode, + EWpaEapConfig, + EWpaPreSharedKey, + EWpaWpa2Only + }; + + iSecuritySettings = aSecuritySettings; + iConnectionName = aTitle; + + iFieldsMain = ( TWpaMember* ) Fields_Wpa_Main; + iTitlesMain = MUTABLE_CAST( TInt*, Titles_Wpa_Main ); + + if ( !iSecuritySettings->WPAMode() && !iPlugin ) + { + iSecuritySettings->SetWPAMode( ETrue ); + *iEventStore |= CWPASecuritySettings::EModified; + } + + FeatureManager::InitializeLibL(); + + ConstructL( R_WPA_SECURITY_SETTINGS_MENUBAR ); + + // ExecuteLD will PushL( this ), so we have to Pop it... + CleanupStack::Pop( this ); // this + + return ExecuteLD( R_WPASETTINGS_DIALOG ); + } + + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::OkToExitL +// --------------------------------------------------------- +// +TBool CWPASecuritySettingsDlg::OkToExitL( TInt aButtonId ) + { + // Translate the button presses into commands for the appui & current + // view to handle + TBool retval( EFalse ); + if ( aButtonId == EAknSoftkeyOptions ) + { + DisplayMenuL(); + } + else if ( aButtonId == EEikCmdExit ) // ShutDown requested + { + *iEventStore |= CWPASecuritySettings::EShutDownReq; + retval = ETrue; + } + else if ( aButtonId == EAknSoftkeyBack || aButtonId == EAknCmdExit ) + { + if ( iSecuritySettings->WPAMode() ) + { + if ( iSecuritySettings->IsValid() ) + { + *iEventStore |= CWPASecuritySettings::EValid; + retval = ETrue; + } + else if ( aButtonId == EAknSoftkeyBack ) + { + HBufC* stringHolder = StringLoader::LoadL( + R_WPA_PRESHARED_KEYDATA_MISSING, iEikonEnv ); + CleanupStack::PushL( stringHolder ); + + CAknQueryDialog *queryDialog = new (ELeave) CAknQueryDialog(); + + queryDialog->PrepareLC( R_WPA_SEC_SETT_CONF_QUERY ); + queryDialog->SetPromptL( stringHolder->Des() ); + retval = queryDialog->RunLD(); + + CleanupStack::PopAndDestroy( stringHolder ); // stringHolder + } + else + { + retval = ETrue; + } + } + else + { + *iEventStore |= CWPASecuritySettings::EValid; + retval = ETrue; + } + + if ( aButtonId == EAknCmdExit ) + { + *iEventStore |= CWPASecuritySettings::EExitReq; + } + } + + else if( aButtonId == EWpaSelCmdChange ) + { + ChangeSettingsL( ETrue ); + retval = EFalse; // don't exit the dialog + } + + return retval; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::OfferKeyEventL +// --------------------------------------------------------- +// +TKeyResponse CWPASecuritySettingsDlg::OfferKeyEventL( + const TKeyEvent& aKeyEvent, TEventCode aType ) + { + TKeyResponse retval( EKeyWasNotConsumed ); + + // Only interested in standard key events + if ( aType == EEventKey ) + { + // If a menu is showing offer key events to it. + if ( CAknDialog::MenuShowing() ) + { + retval = CAknDialog::OfferKeyEventL( aKeyEvent, aType ); + } + else + { + if ( iList ) + { + // as list IS consuming, must handle because it IS the SHUTDOWN... + // or, a view switch is shutting us down... + if ( aKeyEvent.iCode == EKeyEscape ) + { + ProcessCommandL( EEikCmdExit ); + retval = EKeyWasConsumed; + } + else + { + retval = iList->OfferKeyEventL( aKeyEvent, aType ); + if ( *iEventStore & CWPASecuritySettings::EShutDownReq ) + { + ProcessCommandL( EEikCmdExit ); + } + else if ( *iEventStore & CWPASecuritySettings::EExitReq ) + { + ProcessCommandL( EAknCmdExit ); + } + } + } + else + { + if ( aKeyEvent.iCode == EKeyOK ) + { + ProcessCommandL( EWpaSelCmdChange ); + retval = EKeyWasConsumed; + } + } + } + } + + return retval; + } + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::HandleDialogPageEventL +// --------------------------------------------------------- +// +void CWPASecuritySettingsDlg::HandleDialogPageEventL( TInt aEventID ) + { + CAknDialog::HandleDialogPageEventL( aEventID ); + if( *iEventStore & CWPASecuritySettings::EExitReq ) + { + // Exit requested, exit with EAknCmdExit. + TryExitL( EAknCmdExit ); + } + + } + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::HandleListboxDataChangeL +// --------------------------------------------------------- +// +void CWPASecuritySettingsDlg::HandleListboxDataChangeL() + { + // fill up our new list with data + CDesCArrayFlat* itemArray = new ( ELeave ) CDesCArrayFlat( 4 ); + CleanupStack::PushL( itemArray ); + + FillListWithDataL( *itemArray, *iFieldsMain, iTitlesMain ); + + iList->Model()->SetItemTextArray( itemArray ); + + CleanupStack::Pop( itemArray ); // now it is owned by the LB, so pop it + iItemArray = itemArray; + + iList->HandleItemAdditionL(); + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::ProcessCommandL +// --------------------------------------------------------- +// +void CWPASecuritySettingsDlg::ProcessCommandL( TInt aCommandId ) + { + if ( MenuShowing() ) + { + HideMenu(); + } + + switch ( aCommandId ) + { + case EWpaSelCmdChange: + { + ChangeSettingsL( EFalse ); + break; + } + + case EAknCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + iEikonEnv->EikAppUi()->AppHelpContextL() ); + break; + } + + case EAknSoftkeyBack: + case EAknCmdExit: + case EEikCmdExit: + { + TryExitL( aCommandId ); + break; + } + + default: + { + // silently ignore it + break; + } + } + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::HandleListBoxEventL +// --------------------------------------------------------- +// +void CWPASecuritySettingsDlg::HandleListBoxEventL( CEikListBox* /*aListBox*/, + TListBoxEvent aEventType ) + { + switch ( aEventType ) + { + case EEventEnterKeyPressed: + case EEventItemSingleClicked: + { + ChangeSettingsL( ETrue ); + break; + } + + case EEventEditingStarted: + case EEventEditingStopped: + case EEventPenDownOnItem: + case EEventItemDraggingActioned: + { + break; + } + + default: + { + __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) ); + break; + }; + }; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::PreLayoutDynInitL() +// --------------------------------------------------------- +// +void CWPASecuritySettingsDlg::PreLayoutDynInitL() + { + // first get StatusPane + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + + // then get TitlePane + iTitlePane = ( CAknTitlePane* ) statusPane->ControlL( TUid::Uid( + EEikStatusPaneUidTitle ) ); + // if not already stored, store it for restoring + if ( !iOldTitleText ) + { + iOldTitleText = iTitlePane->Text()->AllocL(); + } + + // set new titlepane text + iTitlePane->SetTextL( iConnectionName ); + + iList = STATIC_CAST( CAknSettingStyleListBox*, + Control( KWpaMainSettingsListboxId ) ); + + iList->CreateScrollBarFrameL( ETrue ); + iList->ScrollBarFrame()->SetScrollBarVisibilityL + ( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto ); + + HandleListboxDataChangeL(); + + iList->SetCurrentItemIndex( 0 ); + iList->SetListBoxObserver( this ); + } + + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::DynInitMenuPaneL +// --------------------------------------------------------- +// +void CWPASecuritySettingsDlg::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + CAknDialog::DynInitMenuPaneL( aResourceId, aMenuPane ); + if ( aResourceId == R_WPA_SECURITY_SETTINGS_MENU ) + { + if ( aMenuPane && !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + } + } + + +//---------------------------------------------------------- +// CWPASecuritySettingsDlg::FillListWithDataL +//---------------------------------------------------------- +// +void CWPASecuritySettingsDlg::FillListWithDataL( CDesCArrayFlat& aItemArray, + const TWpaMember& arr, + const TInt* aRes ) + { + TWpaMember* wpaMember = MUTABLE_CAST( TWpaMember*, &arr ); + + TInt numOfFields = iSecuritySettings->SecurityMode() == ESecurityModeWpa ? + KNumOfFieldsMain : KNumOfFieldsMain-1; + + for( TInt i = 0; i < numOfFields; i++ ) + { + if ( *wpaMember == EWpaEapConfig && iSecuritySettings->WPAMode() ) + { + wpaMember++; + aRes++; + } + + if ( *wpaMember == EWpaEapConfig ) + { + // Define a heap descriptor to hold all the item text + // HBufC is non-modifiable + HBufC* title = iEikonEnv->AllocReadResourceLC( *aRes ); + + // Define a heap descriptor to hold all the item text + HBufC* itemText = HBufC::NewLC( title->Length() + + KSpaceAndTabsLength ); + + // Define a modifiable pointer descriptor to be able to append + // text to the non-modifiable heap descriptor itemText + TPtr itemTextPtr = itemText->Des(); + itemTextPtr.Format( KTxtMenuListItemFormat, title ); + + aItemArray.AppendL( *itemText ); + + CleanupStack::PopAndDestroy( 2, title ); // itemText, title + + wpaMember++; + aRes++; + } + else // EWpaMode, EWpaPreSharedKey, EWpaWpa2Only: + { + HBufC* itemText = CreateTextualListBoxItemL( *wpaMember, *aRes ); + CleanupStack::PushL( itemText ); + aItemArray.AppendL( itemText->Des() ); + CleanupStack::PopAndDestroy( itemText ); + } + + wpaMember++; + aRes++; + } + } + + +//---------------------------------------------------------- +// CWPASecuritySettingsDlg::UpdateTextualListBoxItemL +//---------------------------------------------------------- +// +void CWPASecuritySettingsDlg::UpdateTextualListBoxItemL( TWpaMember aMember, + TInt aRes, TInt aPos ) + { + HBufC* itemText; + HBufC* title; + + if ( aMember == EWpaEapConfig ) + { + title = iEikonEnv->AllocReadResourceLC( aRes ); + + // Define a heap descriptor to hold all the item text + itemText = HBufC::NewLC( title->Length() + KSpaceAndTabsLength ); + + // Define a modifiable pointer descriptor to be able to append + // text to the non-modifiable heap descriptor itemText + TPtr itemTextPtr = itemText->Des(); + itemTextPtr.Format( KTxtMenuListItemFormat, title ); + } + else + { + itemText = CreateTextualListBoxItemL( aMember, aRes ); + CleanupStack::PushL( itemText ); + } + + // first try to add, if Leaves, list will be untouched + iItemArray->InsertL( aPos, itemText->Des() ); + // if successful, previous item is scrolled up with one, + // so delete that one... + if ( ++aPos < iItemArray->MdcaCount() ) + { + iItemArray->Delete( aPos ); + } + + CleanupStack::PopAndDestroy( itemText ); + + if ( aMember == EWpaEapConfig ) + { + CleanupStack::PopAndDestroy( title ); // title + } + } + + +//---------------------------------------------------------- +// CWPASecuritySettingsDlg::CreateTextualListBoxItemL +//---------------------------------------------------------- +// +HBufC* CWPASecuritySettingsDlg::CreateTextualListBoxItemL( TWpaMember aMember, + TInt aRes ) + { + // Define a heap descriptor to hold all the item text + // HBufC is non-modifiable + HBufC* title = iEikonEnv->AllocReadResourceLC( aRes ); + + // both variables needed independently of the following conditions so I + // must declare them here... + HBufC16* value; + TUint32 valueResourceID; + + switch ( aMember ) + { + case EWpaMode: + { + valueResourceID = iSecuritySettings->WPAMode() ? + R_WPA_MODE_PRESHARED_KEY : R_WPA_MODE_EAP; + break; + } + + case EWpaWpa2Only: + { + valueResourceID = iSecuritySettings->Wpa2Only() ? + R_WPA_CIPHER_NOT_ALLOWED : R_WPA_CIPHER_ALLOWED; + break; + } + + case EWpaPreSharedKey: + { + valueResourceID = + iSecuritySettings->WPAPreSharedKey()->Length() == 0 ? + R_WPA_PRESHARED_KEY_MUST_BE_DEFINED : 0; + + break; + } + + default: + { + valueResourceID = 0; + break; + } + } + + _LIT( KStars, "****" ); + _LIT( KTxtListItemFormat, " \t%S\t\t%S" ); + _LIT( KTxtCompulsory, "\t*" ); + + if ( valueResourceID ) + { + // Read up value text from resource + value = iEikonEnv->AllocReadResourceLC( valueResourceID ); + } + else + { + value = HBufC::NewLC( KStars().Length() ); + value->Des().Copy( KStars ); + } + + // Define a heap descriptor to hold all the item text + // +4 for space and tab characters + TInt length = title->Length() + value->Length() + KSpaceAndTabsLength; + if ( aMember == EWpaPreSharedKey ) // Compulsory + { + length += KTxtCompulsory().Length(); + } + + HBufC* itemText = HBufC::NewLC( length ); + + // Define a modifiable pointer descriptor to be able to append text to the + // non-modifiable heap descriptor itemText + TPtr itemTextPtr = itemText->Des(); + itemTextPtr.Format( KTxtListItemFormat, title, value ); + if ( aMember == EWpaPreSharedKey ) // Compulsory + { + itemTextPtr.Append( KTxtCompulsory ); + } + CleanupStack::Pop( itemText ); // itemtext, + + CleanupStack::PopAndDestroy( 2 ); // title, value + + return itemText; + } + + + +//---------------------------------------------------------- +// CWPASecuritySettingsDlg::ShowPopupSettingPageL +//---------------------------------------------------------- +// +TBool CWPASecuritySettingsDlg::ShowPopupSettingPageL( TWpaMember aData ) + { + TInt currvalue( 0 ); + TBool retval( EFalse ); + CDesCArrayFlat* items = FillPopupSettingPageLC( aData, currvalue ); + + TInt attr_resid = aData == EWpaMode ? R_WPA_MODE : R_WPA_TKIP_CIPHER; + + HBufC* titlebuf = iEikonEnv->AllocReadResourceLC( attr_resid ); + CAknRadioButtonSettingPage* dlg = new ( ELeave )CAknRadioButtonSettingPage( + R_RADIO_BUTTON_SETTING_PAGE, currvalue, items ); + CleanupStack::PushL( dlg ); + TPtrC ptr( titlebuf->Des() ); + dlg->SetSettingTextL( ptr ); + CleanupStack::Pop( dlg ); // dlg + + if ( dlg->ExecuteLD( CAknSettingPage::EUpdateWhenAccepted ) ) + { + retval = UpdateFromPopupSettingPage( aData, ( TBool )currvalue ); + } + + CleanupStack::PopAndDestroy( titlebuf ); + CleanupStack::PopAndDestroy( items ); // items. It deletes also all + // elements in the array. + return retval; + } + + + +//---------------------------------------------------------- +// CWPASecuritySettingsDlg::ShowPopupTextSettingPageL +//---------------------------------------------------------- +// +TBool CWPASecuritySettingsDlg::ShowPopupTextSettingPageL() + { + TBool retval( EFalse ); + + HBufC16* bufKeyData = HBufC16::NewLC( EMaxLengthOfPreSharedKey ); + TPtr16 ptrKeyData( bufKeyData->Des() ); + + TBool showPage( ETrue ); + while ( showPage ) + { + CAknTextSettingPage* settingPage = + new( ELeave )CAknTextSettingPage( R_TEXT_SETTING_PAGE_KEY_DATA, + ptrKeyData, EAknSettingPageNoOrdinalDisplayed ); + + if ( settingPage->ExecuteLD( CAknSettingPage::EUpdateWhenAccepted ) ) + { + HBufC8* buf8 = HBufC8::NewLC( bufKeyData->Des().Length() ); + buf8->Des().Copy( bufKeyData->Des() ); + + if ( bufKeyData->Des().Length() < EMinLengthOfPreSharedKeyAscii ) + { + HBufC* stringLabel; + + stringLabel = StringLoader::LoadL( + R_INFO_PRESHARED_KEY_TOO_SHORT, + iEikonEnv ); + + CleanupStack::PushL( stringLabel ); + + CAknInformationNote* dialog = new ( ELeave ) + CAknInformationNote( ETrue ); + dialog->ExecuteLD( *stringLabel ); + + CleanupStack::PopAndDestroy( stringLabel ); // stringLabel + + ptrKeyData.Zero(); + } + else + { + if ( iSecuritySettings->SetWPAPreSharedKey( ptrKeyData ) != + KErrNone ) + { + HBufC* stringLabel; + stringLabel = StringLoader::LoadL( + R_INFO_PRESHARED_KEY_NOT_HEX ); + CleanupStack::PushL( stringLabel ); + + CAknInformationNote* dialog = new ( ELeave ) + CAknInformationNote( ETrue ); + + dialog->ExecuteLD( *stringLabel ); + CleanupStack::PopAndDestroy( stringLabel ); + } + else + { + retval = ETrue; + showPage = EFalse; + } + + } + + CleanupStack::PopAndDestroy( buf8 ); // buf8 + } + else + { + showPage = EFalse; + } + } + + CleanupStack::PopAndDestroy( bufKeyData ); // bufKeyData + + return retval; + } + + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::FillPopupSettingPageLC +// --------------------------------------------------------- +// +CDesCArrayFlat* CWPASecuritySettingsDlg::FillPopupSettingPageLC( + TWpaMember aData, + TInt& aCurrvalue ) + { + CDesCArrayFlat* items = new( ELeave)CDesCArrayFlat( 1 ); + CleanupStack::PushL( items ); + + if ( aData == EWpaMode ) + { + if ( iPlugin ) + { + aCurrvalue = iSecuritySettings->WPAMode(); + + items->AppendL( *iEikonEnv->AllocReadResourceLC( R_WPA_MODE_EAP ) ); + CleanupStack::PopAndDestroy(); + } + else + { + aCurrvalue = 0; + } + + items->AppendL( *iEikonEnv->AllocReadResourceLC( + R_WPA_MODE_PRESHARED_KEY ) ); + CleanupStack::PopAndDestroy(); + } + else // EWpaWpa2Only: + { + items->AppendL( *iEikonEnv->AllocReadResourceLC( + R_WPA_CIPHER_ALLOWED ) ); + CleanupStack::PopAndDestroy(); + items->AppendL( *iEikonEnv->AllocReadResourceLC( + R_WPA_CIPHER_NOT_ALLOWED ) ); + CleanupStack::PopAndDestroy(); + + aCurrvalue = iSecuritySettings->Wpa2Only(); + } + + return items; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::UpdateFromPopupSettingPage +// --------------------------------------------------------- +// +TBool CWPASecuritySettingsDlg::UpdateFromPopupSettingPage( TWpaMember aData, + TBool aCurrvalue ) + { + TBool retVal( EFalse ); + + if ( aData == EWpaMode ) + { + if ( !iPlugin ) + { + aCurrvalue = ETrue; + } + + if ( iSecuritySettings->WPAMode() != aCurrvalue ) + { + iSecuritySettings->SetWPAMode( aCurrvalue ); + retVal = ETrue; + } + } + else // EWpaWpa2Only: + { + if ( iSecuritySettings->Wpa2Only() != aCurrvalue ) + { + iSecuritySettings->SetWpa2Only( aCurrvalue ); + retVal = ETrue; + } + } + + return retVal; + } + + + + +//---------------------------------------------------------- +// CWPASecuritySettingsDlg::ChangeSettingsL +//---------------------------------------------------------- +// +void CWPASecuritySettingsDlg::ResetEapConfigFlag( TAny* aPtr ) + { + CWPASecuritySettingsDlg* self = + static_cast( aPtr ); + + self->iEapConfigActive = EFalse; + } + + +//---------------------------------------------------------- +// CWPASecuritySettingsDlg::ChangeSettingsL +//---------------------------------------------------------- +// +void CWPASecuritySettingsDlg::ChangeSettingsL( TBool aQuick ) + { + TInt itemIndex; + TInt shift; + + itemIndex = ( Max( iList->CurrentItemIndex(), 0 ) ); + + shift = ( itemIndex >= EWpaWpa2Only || + ( itemIndex == EWpaEapConfig && + iSecuritySettings->WPAMode() ) ) ? 1 : 0; + + TWpaMember* ptr = iFieldsMain + itemIndex + shift; + TInt* titPtr = iTitlesMain + itemIndex + shift; + + switch ( *ptr ) + { + case EWpaMode: + { // Pop-up setting item + TBool changed( ETrue ); + if ( aQuick ) + { + if ( iPlugin ) + { + iSecuritySettings->SetWPAMode( + !iSecuritySettings->WPAMode() ); + } + else + { + changed = EFalse; + } + } + else + { + changed = ShowPopupSettingPageL( EWpaMode ); + } + + if ( changed ) + { + UpdateTextualListBoxItemL( *ptr, *titPtr, itemIndex ); + *iEventStore |= CWPASecuritySettings::EModified; + + TInt shiftItem = iSecuritySettings->WPAMode() ? 2 : 1; + + ptr += shiftItem; + titPtr += shiftItem; + + UpdateTextualListBoxItemL( *ptr, *titPtr, itemIndex+1 ); + iList->SetCurrentItemIndexAndDraw( itemIndex+1 ); + } + break; + } + + case EWpaWpa2Only: + { // Setting item with two available values + TBool changed( ETrue ); + if ( aQuick ) + { + iSecuritySettings->SetWpa2Only( + !iSecuritySettings->Wpa2Only() ); + } + else + { + changed = ShowPopupSettingPageL( EWpaWpa2Only ); + } + + if ( changed ) + { + UpdateTextualListBoxItemL( *ptr, *titPtr, itemIndex ); + *iEventStore |= CWPASecuritySettings::EModified; + } + break; + } + + case EWpaPreSharedKey: + { // Text setting item + if ( ShowPopupTextSettingPageL() ) + { + UpdateTextualListBoxItemL( *ptr, *titPtr, itemIndex ); + *iEventStore |= CWPASecuritySettings::EModified; + } + break; + } + + case EWpaEapConfig: + { + if ( iPlugin && !iEapConfigActive ) + { + iEapConfigActive = ETrue; + CleanupStack::PushL( TCleanupItem( ResetEapConfigFlag, this ) ); + + + // using expanded EAP types + iEnabledPluginList = ( + iSecuritySettings->WPAEnabledEAPPlugin()? + (TDesC8&)*iSecuritySettings->WPAEnabledEAPPlugin(): + KNullDesC8 ); + + iDisabledPluginList = ( + iSecuritySettings->WPADisabledEAPPlugin()? + (TDesC8&)*iSecuritySettings->WPADisabledEAPPlugin(): + KNullDesC8 ); + + TInt buttonId = iPlugin->EAPPluginConfigurationL( + iEnabledPluginList, + iDisabledPluginList, + iIapId, + iConnectionName ); + + CleanupStack::PopAndDestroy( 1 ); // ResetEapConfigFlag + + if ( buttonId == EEikCmdExit ) // ShutDown requested + { + *iEventStore |= CWPASecuritySettings::EShutDownReq; + } + else if ( buttonId == EAknCmdExit ) + { + *iEventStore |= CWPASecuritySettings::EExitReq; + } + + if ( !iSecuritySettings->WPAEnabledEAPPlugin() || + iEnabledPluginList != + *iSecuritySettings->WPAEnabledEAPPlugin() ) + { + User::LeaveIfError( + iSecuritySettings->SetWPAEnabledEAPPlugin( + iEnabledPluginList ) ); + *iEventStore |= CWPASecuritySettings::EModified; + } + + if ( !iSecuritySettings->WPADisabledEAPPlugin() || + iDisabledPluginList != + *iSecuritySettings->WPADisabledEAPPlugin() ) + { + User::LeaveIfError( + iSecuritySettings->SetWPADisabledEAPPlugin( + iDisabledPluginList ) ); + *iEventStore |= CWPASecuritySettings::EModified; + } + + // If exiting from the menu, pass it on + if( buttonId == EAknCmdExit ) + { + if (aQuick == EFalse) + { + TryExitL( buttonId ); + } + // Don't exit here if aQuick==ETrue. + // Framework command chain will + // cause a KERN-EXEC 3 panic. Handle the exit in + // HandleDialogPageEventL(). + } + } + + return; + } + + + default: + { + __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) ); + break; + } + } + + iList->ScrollToMakeItemVisible( itemIndex ); + iList->SetCurrentItemIndexAndDraw( itemIndex ); + } + + + +// --------------------------------------------------------- +// CWPASecuritySettingsDlg::GetHelpContext +// --------------------------------------------------------- +// +void CWPASecuritySettingsDlg::GetHelpContext( TCoeHelpContext& aContext ) const + { + aContext.iMajor = KWPASecuritySettingsUiHelpMajor; + if ( iSecuritySettings->SecurityMode() == ESecurityModeWpa ) + { + aContext.iContext = KSET_HLP_WLAN_WPA_MAIN; + } + else // iSecuritySettings->SecurityMode() == ESecurityMode8021x + { + aContext.iContext = KSET_HLP_WLAN_8021X_MAIN; + } + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsImpl.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,805 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWPASecuritySettingsImpl. +* +*/ + + +// INCLUDE FILES + +#include "WPASecuritySettingsUiPanic.h" + +#include "WPASecuritySettingsUI.hrh" + +#include +#include +#include +#include "WPASecuritySettingsImpl.h" + +#include +#include +#include + + +// CONSTANTS +LOCAL_D const TUint32 KUidNone = 0; // Invalid id +LOCAL_D const TUint32 E8021X = 4; // 802.1X security mode +LOCAL_D const TUint32 EWpa = 8; // Wpa security mode +LOCAL_D const TUint32 EWpa2 = 16; // Wpa2 only security mode + +LOCAL_D const TUint32 KExpEapTypeLength = 8; // expanded EAP type length + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::NewL +// --------------------------------------------------------- +// +CWPASecuritySettingsImpl* CWPASecuritySettingsImpl::NewL( + TSecurityMode aSecurityMode ) + { + CWPASecuritySettingsImpl* settings = new ( ELeave ) + CWPASecuritySettingsImpl( aSecurityMode ); + CleanupStack::PushL( settings ); + settings->ConstructL(); + CleanupStack::Pop( settings ); + return settings; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::CWPASecuritySettingsImpl +// --------------------------------------------------------- +// +CWPASecuritySettingsImpl::CWPASecuritySettingsImpl( + TSecurityMode aSecurityMode ) +: iSecurityMode( aSecurityMode ), + iWPAMode( EFalse ), + iWpa2Only( EFalse ) + { + iWPAEAPPlugin.Zero(); + iWPAPreSharedKey.Zero(); + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::ConstructL +// --------------------------------------------------------- +// +void CWPASecuritySettingsImpl::ConstructL() + { + _LIT8( KMatchString, "EAPPConfig" ); + TRAPD( err, iPlugin = CEAPPluginConfigurationIf::NewL( KMatchString ) ); + if ( err != KErrNone && err != KEComErrNoInterfaceIdentified ) + { + User::Leave( err ); + } + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::~CWPASecuritySettingsImpl +// --------------------------------------------------------- +// +CWPASecuritySettingsImpl::~CWPASecuritySettingsImpl() + { + delete iWPAEnabledEAPPlugin; + delete iWPADisabledEAPPlugin; + delete iPlugin; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::LoadL +// --------------------------------------------------------- +// +void CWPASecuritySettingsImpl::LoadL( TUint32 aIapId, + CCommsDatabase& aCommsDb ) + { + if ( aIapId == KUidNone ) + { + return; + } + + CCommsDbTableView* wLanServiceTable; + + wLanServiceTable = aCommsDb.OpenViewMatchingUintLC( + TPtrC( WLAN_SERVICE ), TPtrC( WLAN_SERVICE_ID ), aIapId ); + + TInt errorCode = wLanServiceTable->GotoFirstRecord(); + if ( errorCode == KErrNone ) + { + // Get WPA Mode + TRAPD( err, wLanServiceTable->ReadUintL( TPtrC( WLAN_ENABLE_WPA_PSK ), + ( TUint32& ) iWPAMode ) ); + if ( err != KErrNone ) + { // do not leave if value is not present in table... + if ( err != KErrUnknown ) + User::Leave( err ); + } + + TUint32 secMode = 0; + // Get WPA2 Only Mode + TRAP( err, wLanServiceTable->ReadUintL( TPtrC( WLAN_SECURITY_MODE ), + secMode ) ); + if ( err != KErrNone ) + { // do not leave if value is not present in table... + if ( err != KErrUnknown ) + User::Leave( err ); + } + + iWpa2Only = secMode == EWpa2; + + // Get EAP list + iWPAEAPPlugin.Copy( *wLanServiceTable->ReadLongTextLC( + TPtrC( WLAN_EAPS ) ) ); + CleanupStack::PopAndDestroy(); + + if ( !iWPAEAPPlugin.Length() ) + { + // no data found in the old column, use the new ones + + // enabled EAP types + HBufC *data = wLanServiceTable->ReadLongTextLC( + TPtrC( WLAN_ENABLED_EAPS ) ); + + TPtrC8 reint( reinterpret_cast( data->Ptr() ), + data->Size() ); + + delete iWPAEnabledEAPPlugin; iWPAEnabledEAPPlugin = NULL; + iWPAEnabledEAPPlugin = reint.AllocL(); + + CleanupStack::PopAndDestroy( data ); + + + // 2. disabled EAP types + data = wLanServiceTable->ReadLongTextLC( + TPtrC( WLAN_DISABLED_EAPS ) ); + + reint.Set( reinterpret_cast( data->Ptr() ), + data->Size() ); + + delete iWPADisabledEAPPlugin; iWPADisabledEAPPlugin = NULL; + iWPADisabledEAPPlugin = reint.AllocL(); + + CleanupStack::PopAndDestroy( data ); + } + else + { + // generate appropriate entries in the new enabled and disabled list, + // overwriting those values + + // count the + and - signs to determine the size of enabled and + // disabled descriptors + TLex lex( iWPAEAPPlugin ); + + TInt numPlus = 0; + TInt numMinus = 0; + TChar ch; + while ( !lex.Eos() ) + { + ch = lex.Get(); + if ( ch == '+' ) ++numPlus; + else if ( ch == '-' ) ++numMinus; + } + + // each entry consumes 8 bytes in binary format + delete iWPAEnabledEAPPlugin; iWPAEnabledEAPPlugin = NULL; + iWPAEnabledEAPPlugin = HBufC8::NewL( 8 * numPlus ); + + delete iWPADisabledEAPPlugin; iWPADisabledEAPPlugin = NULL; + iWPADisabledEAPPlugin = HBufC8::NewL( 8 * numMinus ); + + lex.Assign( iWPAEAPPlugin ); + + while ( !lex.Eos() ) + { + // beginning of implementation UID + TInt16 implUid = 0; + + if ( lex.Val( implUid ) != KErrNone || !implUid ) + { + // if the old string is corrupted, null out both lists + iWPAEnabledEAPPlugin->Des().Zero(); + iWPADisabledEAPPlugin->Des().Zero(); + break; + } + + // append it to the appropriate list ('+' enabled, '-' disabled) + _LIT8( KPadding, "\xFE\0\0\0\0\0\0" ); + _LIT8( KMsChapV2Padding, "\xFE\xFF\xFF\xFF\0\0\0"); + const TInt KPlainMsChapV2ImplUid = 99; + + if ( implUid > 0 ) + { + iWPAEnabledEAPPlugin->Des().Append( + Abs( implUid ) == KPlainMsChapV2ImplUid? + KMsChapV2Padding: KPadding ); + iWPAEnabledEAPPlugin->Des().Append( Abs( implUid ) ); + } + else if (implUid < 0 ) + { + iWPADisabledEAPPlugin->Des().Append( + Abs( implUid ) == KPlainMsChapV2ImplUid? + KMsChapV2Padding: KPadding ); + iWPADisabledEAPPlugin->Des().Append( Abs( implUid ) ); + } + + // swallow the delimiter (',') + lex.Get(); + } + + // finally, wipe old column data + iWPAEAPPlugin.Zero(); + } + + // Get PreShared Key + wLanServiceTable->ReadTextL( TPtrC( WLAN_WPA_PRE_SHARED_KEY ), + iWPAPreSharedKey ); + + if ( !IsValidPsk( iWPAPreSharedKey ) ) + { + // invalid key format + iWPAPreSharedKey.Zero(); + } + } + + CleanupStack::PopAndDestroy( wLanServiceTable ); // wLanServiceTable + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::SaveL +// --------------------------------------------------------- +// +void CWPASecuritySettingsImpl::SaveL( TUint32 aIapId, + CCommsDatabase& aCommsDb, + TTypeOfSaving aTypeOfSaving, + TUint32 aOldIapId ) + { + CCommsDbTableView* wLanServiceTable; + + // Caller MUST initiate a transaction, WE WILL NOT. + + wLanServiceTable = aCommsDb.OpenViewMatchingUintLC( + TPtrC( WLAN_SERVICE ), TPtrC( WLAN_SERVICE_ID ), aIapId ); + TInt errorCode = wLanServiceTable->GotoFirstRecord(); + + if ( errorCode == KErrNone ) + { + wLanServiceTable->UpdateRecord(); + } + else + { + TUint32 dummyUid( KUidNone ); + User::LeaveIfError( wLanServiceTable->InsertRecord( dummyUid ) ); + + // Save link to LAN service + wLanServiceTable->WriteUintL( TPtrC( WLAN_SERVICE_ID ), aIapId ); + } + + // Save WPA Mode + wLanServiceTable->WriteUintL( TPtrC( WLAN_ENABLE_WPA_PSK ), + ( TUint32& ) iWPAMode ); + + TUint32 secMode; + + if ( iSecurityMode == ESecurityMode8021x ) + { + secMode = E8021X; + } + else if ( iWpa2Only ) + { + secMode = EWpa2; + } + else + { + secMode = EWpa; + } + + // Save security mode + wLanServiceTable->WriteUintL( TPtrC( WLAN_SECURITY_MODE ), secMode ); + + // With expanded EAP types allowed we no longer need the old column + iWPAEAPPlugin.Zero(); + + // Save EAP list + wLanServiceTable->WriteLongTextL( TPtrC( WLAN_EAPS ), iWPAEAPPlugin ); + + + // Save the expanded EAPs + wLanServiceTable->WriteTextL( TPtrC( WLAN_ENABLED_EAPS ), + iWPAEnabledEAPPlugin? + (const TDesC8&)*iWPAEnabledEAPPlugin: + (const TDesC8&)KNullDesC8 ); + + wLanServiceTable->WriteTextL( TPtrC( WLAN_DISABLED_EAPS ), + iWPADisabledEAPPlugin? + (const TDesC8&)*iWPADisabledEAPPlugin: + (const TDesC8&)KNullDesC8 ); + // Save PreShared Key + wLanServiceTable->WriteTextL( TPtrC( WLAN_WPA_PRE_SHARED_KEY ), + iWPAPreSharedKey ); + + // Save PreShared Key Length + wLanServiceTable->WriteUintL( TPtrC( WLAN_WPA_KEY_LENGTH ), + iWPAPreSharedKey.Length() ); + + wLanServiceTable->PutRecordChanges(); + + if ( iPlugin ) + { + if ( aTypeOfSaving == ESavingBrandNewAP ) + { + iPlugin->ChangeIapIDL( aOldIapId, aIapId ); + } + else if ( aTypeOfSaving == ESavingNewAPAsACopy ) + { + iPlugin->CopySettingsL( aOldIapId, aIapId ); + } + } + + CleanupStack::PopAndDestroy( wLanServiceTable ); // wLanServiceTable + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::DeleteL +// --------------------------------------------------------- +// +void CWPASecuritySettingsImpl::DeleteL( TUint32 aIapId ) + { + if ( iPlugin ) + { + iPlugin->DeleteSettingsL( aIapId ); + } + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::IsValid +// --------------------------------------------------------- +// +TBool CWPASecuritySettingsImpl::IsValid() + { + TBool retval = ETrue; + if ( iWPAMode || !iPlugin ) + { + retval = IsValidPsk( iWPAPreSharedKey ); + } + + return retval; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::IsValidPsk +// --------------------------------------------------------- +// +TBool CWPASecuritySettingsImpl::IsValidPsk( const TDesC8& aPsk ) + { + TBool ret( EFalse ); + + TInt len = aPsk.Length(); + + ret = ( len >= EMinLengthOfPreSharedKeyAscii && + len <= EMaxLengthOfPreSharedKeyAscii ); + + if ( !ret && len == ELengthOfPreSharedKeyHex ) + { + // perhaps it is hex + ret = ETrue; + + for ( TInt i = 0; i < len; ++i ) + { + TChar ch( aPsk[i] ); + if ( !ch.IsHexDigit() ) + { + // got a bad character + ret = EFalse; + break; + } + } + } + + return ret; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::SetWPAPreSharedKey +// --------------------------------------------------------- +// +TInt CWPASecuritySettingsImpl::SetWPAPreSharedKey( + const TDesC& aPreSharedKey ) + { + TInt ret( KErrNone ); + + HBufC8* buf8 = HBufC8::New( aPreSharedKey.Length() ); + + if ( buf8 ) + { + TPtr8 pskPtr( buf8->Des() ); + pskPtr.Copy( aPreSharedKey ); + + if ( IsValidPsk( pskPtr ) ) + { + SetWPAPreSharedKey( pskPtr ); + SetWPAMode( ETrue ); + } + else + { + ret = KErrArgument; + } + + delete buf8; + } + else + { + ret = KErrNoMemory; + } + + return ret; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::SetWPAEnabledEAPPlugin +// --------------------------------------------------------- +// +TInt CWPASecuritySettingsImpl::SetWPAEnabledEAPPlugin( + const TDesC8& aEnabledPluginList ) + { + delete iWPAEnabledEAPPlugin; iWPAEnabledEAPPlugin = NULL; + + if ( aEnabledPluginList.Length() % KExpEapTypeLength ) + { + // valid expanded EAP types occupy 8 bytes each + return KErrArgument; + } + + if ( aEnabledPluginList.Length() ) + { + iWPAEnabledEAPPlugin = aEnabledPluginList.Alloc(); + if ( !iWPAEnabledEAPPlugin ) + { + return KErrNoMemory; + } + } + + return KErrNone; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::SetWPADisabledEAPPlugin +// --------------------------------------------------------- +// +TInt CWPASecuritySettingsImpl::SetWPADisabledEAPPlugin( + const TDesC8& aDisabledPluginList ) + { + delete iWPADisabledEAPPlugin; iWPADisabledEAPPlugin = NULL; + + if ( aDisabledPluginList.Length() % KExpEapTypeLength ) + { + // valid expanded EAP types occupy 8 bytes each + return KErrArgument; + } + + if ( aDisabledPluginList.Length() ) + { + iWPADisabledEAPPlugin = aDisabledPluginList.Alloc(); + if ( !iWPADisabledEAPPlugin ) + { + return KErrNoMemory; + } + } + + return KErrNone; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::LoadL +// --------------------------------------------------------- +// +void CWPASecuritySettingsImpl::LoadL( TUint32 aIapId, + CMDBSession& aSession ) + { + if ( aIapId == KUidNone ) + { + return; + } + + // Load WLAN service table + // first get WLAN table id + CMDBGenericRecord* generic = static_cast + ( CCDRecordBase::RecordFactoryL( 0 ) ); + CleanupStack::PushL( generic ); + generic->InitializeL( TPtrC( WLAN_SERVICE ), NULL ); + generic->LoadL( aSession ); + TMDBElementId wlanTableId = generic->TableId(); + + CMDBField* sidField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanServiceId ) ); + + // prime with service id + *sidField = aIapId; + + if( generic->FindL( aSession) ) + { + // Get WPA mode + CMDBField* enableWpaPskField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanEnableWpaPsk ) ); + iWPAMode = *enableWpaPskField; + + // Get WPA2 Only Mode + CMDBField* secModeField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanSecMode ) ); + TUint32 secMode = *secModeField; + iWpa2Only = secMode == EWpa2; + + // Get EAP plugins + CMDBField* wlanEapsField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanEaps ) ); + iWPAEAPPlugin = *wlanEapsField; + + if ( !iWPAEAPPlugin.Length() ) + { + // no data found in the old column, use the new ones + + // enabled EAP types + CMDBField* wlanEnabledEapsField = + static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanEnabledEaps ) ); + + delete iWPAEnabledEAPPlugin; iWPAEnabledEAPPlugin = NULL; + iWPAEnabledEAPPlugin = + ( ( const TDesC8& ) *wlanEnabledEapsField ).AllocL(); + + + // disabled EAP types + CMDBField* wlanDisabledEapsField = + static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanDisabledEaps ) ); + + delete iWPADisabledEAPPlugin; iWPADisabledEAPPlugin = NULL; + iWPADisabledEAPPlugin = + ( ( const TDesC8& ) *wlanDisabledEapsField ).AllocL(); + + } + else + { + // generate appropriate entries in the new enabled and disabled list, + // overwriting those values + + // count the + and - signs to determine the size of enabled and + // disabled descriptors + TLex lex( iWPAEAPPlugin ); + + TInt numPlus = 0; + TInt numMinus = 0; + TChar ch; + while ( !lex.Eos() ) + { + ch = lex.Get(); + if ( ch == '+' ) ++numPlus; + else if ( ch == '-' ) ++numMinus; + } + + // each entry consumes 8 bytes in binary format + delete iWPAEnabledEAPPlugin; iWPAEnabledEAPPlugin = NULL; + iWPAEnabledEAPPlugin = HBufC8::NewL( 8 * numPlus ); + + delete iWPADisabledEAPPlugin; iWPADisabledEAPPlugin = NULL; + iWPADisabledEAPPlugin = HBufC8::NewL( 8 * numMinus ); + + lex.Assign( iWPAEAPPlugin ); + + while ( !lex.Eos() ) + { + // beginning of implementation UID + TInt16 implUid = 0; + + if ( lex.Val( implUid ) != KErrNone || !implUid ) + { + // if the old string is corrupted, null out both lists + iWPAEnabledEAPPlugin->Des().Zero(); + iWPADisabledEAPPlugin->Des().Zero(); + break; + } + + // append it to the appropriate list ('+' enabled, '-' disabled) + _LIT8( KPadding, "\xFE\0\0\0\0\0\0" ); + _LIT8( KMsChapV2Padding, "\xFE\xFF\xFF\xFF\0\0\0"); + const TInt KPlainMsChapV2ImplUid = 99; + + if ( implUid > 0 ) + { + iWPAEnabledEAPPlugin->Des().Append( + Abs( implUid ) == KPlainMsChapV2ImplUid? + KMsChapV2Padding: KPadding ); + iWPAEnabledEAPPlugin->Des().Append( Abs( implUid ) ); + } + else if (implUid < 0 ) + { + iWPADisabledEAPPlugin->Des().Append( + Abs( implUid ) == KPlainMsChapV2ImplUid? + KMsChapV2Padding: KPadding ); + iWPADisabledEAPPlugin->Des().Append( Abs( implUid ) ); + } + + // swallow the delimiter (',') + lex.Get(); + } + + // finally, wipe old column data + iWPAEAPPlugin.Zero(); + } + + // GetWPA preshared key + CMDBField* wpaPskField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWpaPreSharedKey ) ); + iWPAPreSharedKey = *wpaPskField; + + if ( !IsValidPsk( iWPAPreSharedKey ) ) + { + // invalid key format + iWPAPreSharedKey.Zero(); + } + } + + CleanupStack::PopAndDestroy( generic ); + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsImpl::SaveL +// --------------------------------------------------------- +// +void CWPASecuritySettingsImpl::SaveL( TUint32 aIapId, + CMDBSession& aSession, + TTypeOfSaving aTypeOfSaving, + TUint32 aOldIapId ) + { + const TInt KRetryWait = 100000; // Wait time between retries in TTimeIntervalMicroSeconds32 + const TInt KRetryCount = 50; // Max retry count + + // Load WLAN service table + // first get WLAN table id + CMDBGenericRecord* generic = static_cast + ( CCDRecordBase::RecordFactoryL( 0 ) ); + CleanupStack::PushL( generic ); + generic->InitializeL( TPtrC( WLAN_SERVICE ), NULL ); + generic->LoadL( aSession ); + TMDBElementId wlanTableId = generic->TableId(); + + CMDBField* sidField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanServiceId ) ); + + // prime with service id + *sidField = aIapId; + + TBool found = generic->FindL( aSession); + + // If loading failed, WLAN service record will be + // created and StoreL()-d, otherwise, ModifyL() + + // Set WPA mode + CMDBField* enableWpaPskField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanEnableWpaPsk ) ); + enableWpaPskField->SetL( iWPAMode ); + + // Set security mode + TUint32 secMode; + if ( iSecurityMode == ESecurityMode8021x ) + { + secMode = E8021X; + } + else if ( iWpa2Only ) + { + secMode = EWpa2; + } + else + { + secMode = EWpa; + } + CMDBField* secModeField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanSecMode ) ); + secModeField->SetL( secMode ); + + // Save EAP list + CMDBField* wlanEapsField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanEaps ) ); + + // when using the expanded EAP types, wipe out data in the old column + iWPAEAPPlugin.Zero(); + + wlanEapsField->SetL( iWPAEAPPlugin ); + + // Save the expanded EAPs + CMDBField* wlanEnabledEapsField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanEnabledEaps ) ); + wlanEnabledEapsField->SetL( iWPAEnabledEAPPlugin? + (const TDesC8&)*iWPAEnabledEAPPlugin: + (const TDesC8&)KNullDesC8 ); + + + CMDBField* wlanDisabledEapsField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanDisabledEaps ) ); + wlanDisabledEapsField->SetL( iWPADisabledEAPPlugin? + (const TDesC8&)*iWPADisabledEAPPlugin: + (const TDesC8&)KNullDesC8 ); + + // Save PreShared Key + CMDBField* wpaPskField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWpaPreSharedKey ) ); + wpaPskField->SetL( iWPAPreSharedKey ); + + // Save PreShared Key length + CMDBField* keyLengthField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWpaKeyLength ) ); + keyLengthField->SetL( iWPAPreSharedKey.Length() ); + + TInt error( KErrNone ); + + // Saving changes + for ( TInt i( 0 ); i < KRetryCount; i++ ) + { + + // If table existed modify it + if( found ) + { + TRAP( error, generic->ModifyL( aSession ) ); + } + + // Otherwise store a new record + else + { + generic->SetRecordId( KCDNewRecordRequest ); + TRAP( error, generic->StoreL( aSession ) ); + } + + // If operation failed with KErrLocked, we'll retry. + if ( KErrLocked == error ) + { + User::After( KRetryWait ); + } + + // Otherwise break the retry loop. + else + { + break; + } + } + + // If the save operation failed, leave now. + User::LeaveIfError( error ); + + CleanupStack::PopAndDestroy( generic ); + + if ( iPlugin ) + { + if ( aTypeOfSaving == ESavingBrandNewAP ) + { + iPlugin->ChangeIapIDL( aOldIapId, aIapId ); + } + else if ( aTypeOfSaving == ESavingNewAPAsACopy ) + { + iPlugin->CopySettingsL( aOldIapId, aIapId ); + } + } + } + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsUI.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsUI.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWPASecuritySettingsUi. +* +*/ + + +// INCLUDE FILES +#include "WPASecuritySettingsUiImpl.h" + +#include + + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWPASecuritySettingsUi::NewLC +// --------------------------------------------------------- +// +EXPORT_C CWPASecuritySettingsUi* CWPASecuritySettingsUi::NewL( + CEikonEnv& aEikEnv ) + { + CWPASecuritySettingsUi* secSett = new( ELeave )CWPASecuritySettingsUi; + CleanupStack::PushL( secSett ); + secSett->iImpl = CWPASecuritySettingsUiImpl::NewL( aEikEnv ); + CleanupStack::Pop( secSett ); // secSett + return secSett; + } + + + +// --------------------------------------------------------- +// CWPASecuritySettingsUi::~CWPASecuritySettingsUi +// --------------------------------------------------------- +// +EXPORT_C CWPASecuritySettingsUi::~CWPASecuritySettingsUi() + { + delete iImpl; + } + + + +// --------------------------------------------------------- +// CWPASecuritySettingsUi::Cvt() +// --------------------------------------------------------- +// +EXPORT_C TInt CWPASecuritySettingsUi::Cvt() + { + return KErrNone; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsUiImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsUiImpl.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,115 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 class CWPASecuritySettingsUiImpl. +* +*/ + + +// INCLUDE FILES +#include "WPASecuritySettingsUiImpl.h" +#include "WPASecuritySettingsDlg.h" +#include "WPASecuritySettingsImpl.h" + +#include +#include + +#include + + +// CONSTANTS +_LIT( KDriveZ, "z:" ); // ROM folder +_LIT( KResourceFileName, "WPASecuritySettingsUI.rsc" ); // RSC file name. + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CWPASecuritySettingsUiImpl::NewL +// --------------------------------------------------------- +// +CWPASecuritySettingsUiImpl* CWPASecuritySettingsUiImpl::NewL( + CEikonEnv& aEikEnv ) + { + CWPASecuritySettingsUiImpl* uiImpl = + new( ELeave ) CWPASecuritySettingsUiImpl( aEikEnv ); + CleanupStack::PushL( uiImpl ); + uiImpl->ConstructL(); + CleanupStack::Pop( uiImpl ); // uiImpl + return uiImpl; + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsUiImpl::CWPASecuritySettingsUiImpl +// --------------------------------------------------------- +// +CWPASecuritySettingsUiImpl::CWPASecuritySettingsUiImpl( CEikonEnv& aEikEnv ) +: iEventStore( ENone ), + iEikEnv( &aEikEnv ) + { + } + + +// --------------------------------------------------------- +// CWPASecuritySettingsUiImpl::~CWPASecuritySettingsUiImpl +// --------------------------------------------------------- +// +CWPASecuritySettingsUiImpl::~CWPASecuritySettingsUiImpl() + { + if ( iResOffset ) + { + iEikEnv->DeleteResourceFile( iResOffset ); + } + } + + + +// --------------------------------------------------------- +// CWPASecuritySettingsUiImpl::ConstructL +// --------------------------------------------------------- +// +void CWPASecuritySettingsUiImpl::ConstructL() + { + TFileName fileName; + + fileName.Append( KDriveZ ); + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KResourceFileName ); + + BaflUtils::NearestLanguageFile( iEikEnv->FsSession(), fileName ); + iResOffset = iEikEnv->AddResourceFileL( fileName ); + } + + + +// --------------------------------------------------------- +// CWPASecuritySettingsUiImpl::EditL +// --------------------------------------------------------- +// +TInt CWPASecuritySettingsUiImpl::EditL( CWPASecuritySettingsImpl& aSettings, + const TDesC& aTitle ) + { + iEventStore = ENone; + + CWPASecuritySettingsDlg* secSettDlg = + CWPASecuritySettingsDlg::NewL( iEventStore, + aSettings.IapId(), + aSettings.Plugin() ); + secSettDlg->ConstructAndRunLD( &aSettings, aTitle ); + + return iEventStore; + } + + +// End of File diff -r 000000000000 -r c8830336c852 wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsUiPanic.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsUiPanic.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 panic function. +* +*/ + + +// INCLUDE FILES + +#include "WPASecuritySettingsUiPanic.h" + +#include + + +// ================= LOCAL FUNCTIONS ======================= + +// --------------------------------------------------------- +// Panic() +// --------------------------------------------------------- +// +void Panic( TWpaSecuritySettingsPanicCodes aPanic ) + { + _LIT( kWpaSet, "WPASecuritySettingsUi" ); + User::Panic( kWpaSet, aPanic ); + } + + +// End of File